From 362420f62bdc1b7f4780504d17c3743a8e5f5d04 Mon Sep 17 00:00:00 2001 From: Silvan <27845747+adlerhurst@users.noreply.github.com> Date: Mon, 26 May 2025 08:20:14 +0200 Subject: [PATCH] feat: init migrations for transactional tables (#9946) # Which Problems Are Solved To start with transactional tables we need to setup the new `zitadel` schema in a way that does not rely on the event store later. # How the Problems Are Solved Setup step added which calls the function which executes the migrations. # Additional Changes none # Additional Context - closes #9933 --- backend/main.go | 8 ++-- backend/v3/domain/domain_test.go | 1 + .../database/dialect/postgres/config.go | 10 +++- .../storage/database/dialect/postgres/conn.go | 11 ++++- .../postgres/migration/001_instance_table.go | 16 +++++++ .../migration/001_instance_table/down.sql | 1 + .../migration/001_instance_table/up.sql | 6 +++ .../dialect/postgres/migration/doc.go | 13 +++++ .../dialect/postgres/migration/migrationgs.go | 33 +++++++++++++ .../storage/database/dialect/postgres/pool.go | 15 +++++- backend/v3/storage/database/migration.go | 8 ++++ .../storage/database/repository/user_test.go | 2 + cmd/setup/54.go | 38 +++++++++++++++ cmd/setup/setup.go | 3 ++ go.mod | 20 +++++--- go.sum | 48 ++++++++++--------- 16 files changed, 197 insertions(+), 36 deletions(-) create mode 100644 backend/v3/storage/database/dialect/postgres/migration/001_instance_table.go create mode 100644 backend/v3/storage/database/dialect/postgres/migration/001_instance_table/down.sql create mode 100644 backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql create mode 100644 backend/v3/storage/database/dialect/postgres/migration/doc.go create mode 100644 backend/v3/storage/database/dialect/postgres/migration/migrationgs.go create mode 100644 backend/v3/storage/database/migration.go create mode 100644 cmd/setup/54.go diff --git a/backend/main.go b/backend/main.go index bd786aaf78..97681df7ad 100644 --- a/backend/main.go +++ b/backend/main.go @@ -3,8 +3,8 @@ // to get an overview i would start in the api package. package main -import "github.com/zitadel/zitadel/backend/cmd" +// import "github.com/zitadel/zitadel/backend/cmd" -func main() { - cmd.Execute() -} +// func main() { +// cmd.Execute() +// } diff --git a/backend/v3/domain/domain_test.go b/backend/v3/domain/domain_test.go index dbb7084512..54d09eec89 100644 --- a/backend/v3/domain/domain_test.go +++ b/backend/v3/domain/domain_test.go @@ -21,6 +21,7 @@ import ( // These tests give an overview of how to use the domain package. func TestExample(t *testing.T) { + t.Skip("skip example test because it is not a real test") ctx := context.Background() ctrl := gomock.NewController(t) diff --git a/backend/v3/storage/database/dialect/postgres/config.go b/backend/v3/storage/database/dialect/postgres/config.go index 9862526106..630c603d14 100644 --- a/backend/v3/storage/database/dialect/postgres/config.go +++ b/backend/v3/storage/database/dialect/postgres/config.go @@ -19,6 +19,7 @@ var ( type Config struct { *pgxpool.Config + *pgxpool.Pool // Host string // Port int32 @@ -37,7 +38,7 @@ type Config struct { // Connect implements [database.Connector]. func (c *Config) Connect(ctx context.Context) (database.Pool, error) { - pool, err := pgxpool.NewWithConfig(ctx, c.Config) + pool, err := c.getPool(ctx) if err != nil { return nil, err } @@ -47,6 +48,13 @@ func (c *Config) Connect(ctx context.Context) (database.Pool, error) { return &pgxPool{pool}, nil } +func (c *Config) getPool(ctx context.Context) (*pgxpool.Pool, error) { + if c.Pool != nil { + return c.Pool, nil + } + return pgxpool.NewWithConfig(ctx, c.Config) +} + func NameMatcher(name string) bool { return slices.Contains([]string{"postgres", "pg"}, strings.ToLower(name)) } diff --git a/backend/v3/storage/database/dialect/postgres/conn.go b/backend/v3/storage/database/dialect/postgres/conn.go index 1ce061e2fb..5e5942680a 100644 --- a/backend/v3/storage/database/dialect/postgres/conn.go +++ b/backend/v3/storage/database/dialect/postgres/conn.go @@ -6,11 +6,15 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres/migration" ) type pgxConn struct{ *pgxpool.Conn } -var _ database.Client = (*pgxConn)(nil) +var ( + _ database.Client = (*pgxConn)(nil) + _ database.Migrator = (*pgxConn)(nil) +) // Release implements [database.Client]. func (c *pgxConn) Release(_ context.Context) error { @@ -46,3 +50,8 @@ func (c *pgxConn) Exec(ctx context.Context, sql string, args ...any) error { _, err := c.Conn.Exec(ctx, sql, args...) return err } + +// Migrate implements [database.Migrator]. +func (c *pgxConn) Migrate(ctx context.Context) error { + return migration.Migrate(ctx, c.Conn.Conn()) +} diff --git a/backend/v3/storage/database/dialect/postgres/migration/001_instance_table.go b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table.go new file mode 100644 index 0000000000..6e9f9b4c48 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table.go @@ -0,0 +1,16 @@ +package migration + +import ( + _ "embed" +) + +var ( + //go:embed 001_instance_table/up.sql + up001InstanceTable string + //go:embed 001_instance_table/down.sql + down001InstanceTable string +) + +func init() { + registerSQLMigration(1, up001InstanceTable, down001InstanceTable) +} diff --git a/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/down.sql b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/down.sql new file mode 100644 index 0000000000..e2fcd6b7c9 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/down.sql @@ -0,0 +1 @@ +DROP TABLE zitadel.instances; \ No newline at end of file diff --git a/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql new file mode 100644 index 0000000000..2b74202778 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/001_instance_table/up.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS zitadel.instances( + id VARCHAR(100) NOT NULL + , PRIMARY KEY (id) + + , name VARCHAR(100) NOT NULL +); \ No newline at end of file diff --git a/backend/v3/storage/database/dialect/postgres/migration/doc.go b/backend/v3/storage/database/dialect/postgres/migration/doc.go new file mode 100644 index 0000000000..306347a641 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/doc.go @@ -0,0 +1,13 @@ +// This package contains the migration logic for the PostgreSQL dialect. +// It uses the [github.com/jackc/tern/v2/migrate] package to handle the migration process. +// +// **Developer Note**: +// +// Each migration MUST be registered in an init function. +// Create a go file for each migration with the sequence of the migration as prefix and some descriptive name. +// The file name MUST be in the format _.go. +// Each migration SHOULD provide an up and down migration. +// Prefer to write SQL statements instead of funcs if it is reasonable. +// To keep the folder clean create a folder to store the sql files with the following format: _/{up/down}.sql. +// And use the go embed directive to embed the sql files. +package migration diff --git a/backend/v3/storage/database/dialect/postgres/migration/migrationgs.go b/backend/v3/storage/database/dialect/postgres/migration/migrationgs.go new file mode 100644 index 0000000000..96194a756e --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/migrationgs.go @@ -0,0 +1,33 @@ +package migration + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/tern/v2/migrate" +) + +var migrations []*migrate.Migration + +func Migrate(ctx context.Context, conn *pgx.Conn) error { + // we need to ensure that the schema exists before we can run the migration + // because creating the migrations table already required the schema + _, err := conn.Exec(ctx, "CREATE SCHEMA IF NOT EXISTS zitadel") + if err != nil { + return err + } + migrator, err := migrate.NewMigrator(ctx, conn, "zitadel.migrations") + if err != nil { + return err + } + migrator.Migrations = migrations + return migrator.Migrate(ctx) +} + +func registerSQLMigration(sequence int32, up, down string) { + migrations = append(migrations, &migrate.Migration{ + Sequence: sequence, + UpSQL: up, + DownSQL: down, + }) +} diff --git a/backend/v3/storage/database/dialect/postgres/pool.go b/backend/v3/storage/database/dialect/postgres/pool.go index bbfb421413..a8a416f362 100644 --- a/backend/v3/storage/database/dialect/postgres/pool.go +++ b/backend/v3/storage/database/dialect/postgres/pool.go @@ -6,11 +6,15 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres/migration" ) type pgxPool struct{ *pgxpool.Pool } -var _ database.Pool = (*pgxPool)(nil) +var ( + _ database.Pool = (*pgxPool)(nil) + _ database.Migrator = (*pgxPool)(nil) +) // Acquire implements [database.Pool]. func (c *pgxPool) Acquire(ctx context.Context) (database.Client, error) { @@ -55,3 +59,12 @@ func (c *pgxPool) Close(_ context.Context) error { c.Pool.Close() return nil } + +// Migrate implements [database.Migrator]. +func (c *pgxPool) Migrate(ctx context.Context) error { + client, err := c.Pool.Acquire(ctx) + if err != nil { + return err + } + return migration.Migrate(ctx, client.Conn()) +} diff --git a/backend/v3/storage/database/migration.go b/backend/v3/storage/database/migration.go new file mode 100644 index 0000000000..7aa1101148 --- /dev/null +++ b/backend/v3/storage/database/migration.go @@ -0,0 +1,8 @@ +package database + +import "context" + +type Migrator interface { + // Migrate executes migrations to setup the database. + Migrate(ctx context.Context) error +} diff --git a/backend/v3/storage/database/repository/user_test.go b/backend/v3/storage/database/repository/user_test.go index a1f7a8c7da..1953e48943 100644 --- a/backend/v3/storage/database/repository/user_test.go +++ b/backend/v3/storage/database/repository/user_test.go @@ -12,6 +12,7 @@ import ( ) func TestQueryUser(t *testing.T) { + t.Skip("tests are meant as examples and are not real tests") t.Run("User filters", func(t *testing.T) { client := dbmock.NewMockClient(gomock.NewController(t)) @@ -67,6 +68,7 @@ func TestArg(t *testing.T) { } func TestWriteUser(t *testing.T) { + t.Skip("tests are meant as examples and are not real tests") t.Run("update user", func(t *testing.T) { user := repository.UserRepository(nil) user.Human().Update(context.Background(), user.IDCondition("test"), user.SetUsername("test")) diff --git a/cmd/setup/54.go b/cmd/setup/54.go new file mode 100644 index 0000000000..a241937261 --- /dev/null +++ b/cmd/setup/54.go @@ -0,0 +1,38 @@ +package setup + +import ( + "context" + _ "embed" + + v3_db "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres" + "github.com/zitadel/zitadel/internal/database" + "github.com/zitadel/zitadel/internal/eventstore" +) + +type TransactionalTables struct { + dbClient *database.DB +} + +func (mig *TransactionalTables) Execute(ctx context.Context, _ eventstore.Event) error { + _, err := mig.dbClient.ExecContext(ctx, "CREATE SCHEMA IF NOT EXISTS zitadel") + if err != nil { + return err + } + + config := &postgres.Config{Pool: mig.dbClient.Pool} + pool, err := config.Connect(ctx) + if err != nil { + return err + } + + return pool.(v3_db.Migrator).Migrate(ctx) +} + +func (mig *TransactionalTables) String() string { + return "54_repeatable_transactional_tables" +} + +func (mig *TransactionalTables) Check(lastRun map[string]interface{}) bool { + return true +} diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go index f4df9fc71b..6043c38be4 100644 --- a/cmd/setup/setup.go +++ b/cmd/setup/setup.go @@ -289,6 +289,9 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string) &RiverMigrateRepeatable{ client: dbClient, }, + &TransactionalTables{ + dbClient: dbClient, + }, } for _, repeatableStep := range repeatableSteps { diff --git a/go.mod b/go.mod index 5943f8f85e..de0e8aa314 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/BurntSushi/toml v1.5.0 github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.27.0 - github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/squirrel v1.5.4 github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b github.com/alecthomas/participle/v2 v2.1.4 @@ -45,11 +44,11 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/improbable-eng/grpc-web v0.15.0 github.com/jackc/pgx/v5 v5.7.3 + github.com/jackc/tern/v2 v2.3.3 github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 github.com/jinzhu/gorm v1.9.16 github.com/k3a/html2text v1.2.1 github.com/lucasb-eyer/go-colorful v1.2.0 - github.com/manifoldco/promptui v0.9.0 github.com/minio/minio-go/v7 v7.0.88 github.com/mitchellh/mapstructure v1.5.0 github.com/muesli/gamut v0.3.1 @@ -89,12 +88,12 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.35.0 go.opentelemetry.io/otel/trace v1.35.0 go.uber.org/mock v0.5.0 - golang.org/x/crypto v0.36.0 + golang.org/x/crypto v0.37.0 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 golang.org/x/net v0.37.0 golang.org/x/oauth2 v0.28.0 - golang.org/x/sync v0.12.0 - golang.org/x/text v0.23.0 + golang.org/x/sync v0.13.0 + golang.org/x/text v0.24.0 google.golang.org/api v0.227.0 google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 google.golang.org/grpc v1.71.0 @@ -107,12 +106,15 @@ require ( cloud.google.com/go/auth v0.15.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect cloud.google.com/go/monitoring v1.24.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect - github.com/chzyer/readline v1.5.1 // indirect github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect github.com/crewjam/httperr v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -132,6 +134,7 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/lib/pq v1.10.9 // indirect @@ -139,12 +142,15 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/crc64nvme v1.0.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/riverqueue/river/rivershared v0.19.0 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -229,7 +235,7 @@ require ( github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/sys v0.31.0 + golang.org/x/sys v0.32.0 gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.11 // indirect diff --git a/go.sum b/go.sum index 646098db59..ff10718898 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ cloud.google.com/go/storage v1.51.0 h1:ZVZ11zCiD7b3k+cH5lQs/qcNaoSz3U9I0jgwVzqDl cloud.google.com/go/storage v1.51.0/go.mod h1:YEJfu/Ki3i5oHC/7jyTgsGZwdQ8P9hqMqvpi5kRKGgc= cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= @@ -44,8 +46,12 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= @@ -118,15 +124,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -443,6 +440,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= @@ -460,6 +459,8 @@ github.com/jackc/pgx/v5 v5.7.3 h1:PO1wNKj/bTAwxSJnO1Z4Ai8j4magtqg2SLNjEDzcXQo= github.com/jackc/pgx/v5 v5.7.3/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/tern/v2 v2.3.3 h1:d6QNRyjk9HttJtSF5pUB8UaXrHwCgEai3/yxYjgci/k= +github.com/jackc/tern/v2 v2.3.3/go.mod h1:0/9jqEreuC+ywjB7C5ta6Xkhl+HSaxFmCAggEDcp6v0= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52/go.mod h1:RDZ+4PR3mDOtTpVbI0qBE+rdhmtIrtbssiNn38/1OWA= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= @@ -541,8 +542,6 @@ github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275/go.mod github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -567,6 +566,8 @@ github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEp github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs= github.com/minio/minio-go/v7 v7.0.88/go.mod h1:33+O8h0tO7pCeCWwBVa07RhVVfB/3vS4kEX7rwYKmIg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -575,6 +576,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -721,6 +724,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -892,8 +897,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= @@ -981,8 +986,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1016,7 +1021,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1028,8 +1032,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1050,8 +1054,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=