diff --git a/backend/src/apiserver/client/sql.go b/backend/src/apiserver/client/sql.go index c4d44d61ae6..026ef056190 100644 --- a/backend/src/apiserver/client/sql.go +++ b/backend/src/apiserver/client/sql.go @@ -15,13 +15,22 @@ package client import ( + "bytes" "fmt" "github.com/go-sql-driver/mysql" ) -func CreateMySQLConfig(user, password string, mysqlServiceHost string, - mysqlServicePort string, dbName string, mysqlGroupConcatMaxLen string, mysqlExtraParams map[string]string, +const ( + MYSQL_TEXT_FORMAT string = "longtext not null" + MYSQL_EXIST_ERROR string = "database exists" + + PGX_TEXT_FORMAT string = "text" + PGX_EXIST_ERROR string = "already exists" +) + +func CreateMySQLConfig(user, password, mysqlServiceHost, mysqlServicePort, + dbName, mysqlGroupConcatMaxLen string, mysqlExtraParams map[string]string, ) *mysql.Config { params := map[string]string{ "charset": "utf8", @@ -44,3 +53,26 @@ func CreateMySQLConfig(user, password string, mysqlServiceHost string, AllowNativePasswords: true, } } + +func CreatePostgreSQLConfig(user, password, postgresHost, dbName string, postgresPort uint16, +) string { + var b bytes.Buffer + if dbName != "" { + fmt.Fprintf(&b, "database=%s ", dbName) + } + if user != "" { + fmt.Fprintf(&b, "user=%s ", user) + } + if password != "" { + fmt.Fprintf(&b, "password=%s ", password) + } + if postgresHost != "" { + fmt.Fprintf(&b, "host=%s ", postgresHost) + } + if postgresPort != 0 { + fmt.Fprintf(&b, "port=%d ", postgresPort) + } + fmt.Fprint(&b, "sslmode=disable") + + return b.String() +} diff --git a/backend/src/apiserver/client_manager.go b/backend/src/apiserver/client_manager/client_manager.go similarity index 63% rename from backend/src/apiserver/client_manager.go rename to backend/src/apiserver/client_manager/client_manager.go index a02dcf53c00..ec247be375b 100644 --- a/backend/src/apiserver/client_manager.go +++ b/backend/src/apiserver/client_manager/client_manager.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Kubeflow Authors +// Copyright 2018-2023 The Kubeflow Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,15 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +package clientmanager import ( "database/sql" "fmt" "os" + "strings" "time" "github.com/cenkalti/backoff" + "github.com/go-sql-driver/mysql" "github.com/golang/glog" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" @@ -35,25 +37,33 @@ import ( ) const ( - minioServiceHost = "MINIO_SERVICE_SERVICE_HOST" - minioServicePort = "MINIO_SERVICE_SERVICE_PORT" - minioServiceRegion = "MINIO_SERVICE_REGION" - minioServiceSecure = "MINIO_SERVICE_SECURE" - pipelineBucketName = "MINIO_PIPELINE_BUCKET_NAME" - pipelinePath = "MINIO_PIPELINE_PATH" - mysqlServiceHost = "DBConfig.Host" - mysqlServicePort = "DBConfig.Port" - mysqlUser = "DBConfig.User" - mysqlPassword = "DBConfig.Password" - mysqlDBName = "DBConfig.DBName" - mysqlGroupConcatMaxLen = "DBConfig.GroupConcatMaxLen" - mysqlExtraParams = "DBConfig.ExtraParams" - archiveLogFileName = "ARCHIVE_CONFIG_LOG_FILE_NAME" - archiveLogPathPrefix = "ARCHIVE_CONFIG_LOG_PATH_PREFIX" - dbConMaxLifeTime = "DBConfig.ConMaxLifeTime" - - visualizationServiceHost = "ML_PIPELINE_VISUALIZATIONSERVER_SERVICE_HOST" - visualizationServicePort = "ML_PIPELINE_VISUALIZATIONSERVER_SERVICE_PORT" + minioServiceHost = "MINIO_SERVICE_SERVICE_HOST" + minioServicePort = "MINIO_SERVICE_SERVICE_PORT" + minioServiceRegion = "MINIO_SERVICE_REGION" + minioServiceSecure = "MINIO_SERVICE_SECURE" + pipelineBucketName = "MINIO_PIPELINE_BUCKET_NAME" + pipelinePath = "MINIO_PIPELINE_PATH" + + mysqlServiceHost = "DBConfig.MySQLConfig.Host" + mysqlServicePort = "DBConfig.MySQLConfig.Port" + mysqlUser = "DBConfig.MySQLConfig.User" + mysqlPassword = "DBConfig.MySQLConfig.Password" + mysqlDBName = "DBConfig.MySQLConfig.DBName" + mysqlGroupConcatMaxLen = "DBConfig.MySQLConfig.GroupConcatMaxLen" + mysqlExtraParams = "DBConfig.MySQLConfig.ExtraParams" + + postgresHost = "DBConfig.PostgreSQLConfig.Host" + postgresPort = "DBConfig.PostgreSQLConfig.Port" + postgresUser = "DBConfig.PostgreSQLConfig.User" + postgresPassword = "DBConfig.PostgreSQLConfig.Password" + postgresDBName = "DBConfig.PostgreSQLConfig.DBName" + + archiveLogFileName = "ARCHIVE_CONFIG_LOG_FILE_NAME" + archiveLogPathPrefix = "ARCHIVE_CONFIG_LOG_PATH_PREFIX" + dbConMaxLifeTime = "DBConfig.ConMaxLifeTime" + + VisualizationServiceHost = "ML_PIPELINE_VISUALIZATIONSERVER_SERVICE_HOST" + VisualizationServicePort = "ML_PIPELINE_VISUALIZATIONSERVER_SERVICE_PORT" initConnectionTimeout = "InitConnectionTimeout" @@ -158,7 +168,7 @@ func (c *ClientManager) Authenticators() []auth.Authenticator { func (c *ClientManager) init() { glog.Info("Initializing client manager") - db := initDBClient(common.GetDurationConfig(initConnectionTimeout)) + db := InitDBClient(common.GetDurationConfig(initConnectionTimeout)) db.SetConnMaxLifetime(common.GetDurationConfig(dbConMaxLifeTime)) // time @@ -208,16 +218,12 @@ func (c *ClientManager) Close() { c.db.Close() } -func initDBClient(initConnectionTimeout time.Duration) *storage.DB { - driverName := common.GetStringConfig("DBConfig.DriverName") - var arg string - - switch driverName { - case "mysql": - arg = initMysql(driverName, initConnectionTimeout) - default: - glog.Fatalf("Driver %v is not supported", driverName) - } +func InitDBClient(initConnectionTimeout time.Duration) *storage.DB { + // Allowed driverName values: + // 1) To use MySQL, use `mysql` + // 2) To use PostgreSQL, use `pgx` + driverName := common.GetStringConfig("DBDriverName") + arg := initDBDriver(driverName, initConnectionTimeout) // db is safe for concurrent use by multiple goroutines // and maintains its own pool of idle connections. @@ -250,8 +256,18 @@ func initDBClient(initConnectionTimeout time.Duration) *storage.DB { &model.ResourceReference{}, ) - if response.Error != nil { - glog.Fatalf("Failed to initialize the databases.") + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to initialize the databases. Error: %s", response.Error) + } + + var textFormat string + switch driverName { + case "mysql": + textFormat = client.MYSQL_TEXT_FORMAT + case "pgx": + textFormat = client.PGX_TEXT_FORMAT + default: + glog.Fatalf("Unsupported database driver %s, please use `mysql` for MySQL, or `pgx` for PostgreSQL.", driverName) } response = db.Model(&model.Experiment{}).RemoveIndex("Name") @@ -264,50 +280,71 @@ func initDBClient(initConnectionTimeout time.Duration) *storage.DB { glog.Fatalf("Failed to drop unique key on pipeline name. Error: %s", response.Error) } - response = db.Model(&model.ResourceReference{}).ModifyColumn("Payload", "longtext not null") + response = db.Model(&model.ResourceReference{}).ModifyColumn("Payload", textFormat) if response.Error != nil { glog.Fatalf("Failed to update the resource reference payload type. Error: %s", response.Error) } response = db.Model(&model.Run{}).AddIndex("experimentuuid_createatinsec", "ExperimentUUID", "CreatedAtInSec") - if response.Error != nil { + if ignoreAlreadyExistError(driverName, response.Error) != nil { glog.Fatalf("Failed to create index experimentuuid_createatinsec on run_details. Error: %s", response.Error) } response = db.Model(&model.Run{}).AddIndex("experimentuuid_conditions_finishedatinsec", "ExperimentUUID", "Conditions", "FinishedAtInSec") - if response.Error != nil { + if ignoreAlreadyExistError(driverName, response.Error) != nil { glog.Fatalf("Failed to create index experimentuuid_conditions_finishedatinsec on run_details. Error: %s", response.Error) } response = db.Model(&model.Run{}).AddIndex("namespace_createatinsec", "Namespace", "CreatedAtInSec") - if response.Error != nil { + if ignoreAlreadyExistError(driverName, response.Error) != nil { glog.Fatalf("Failed to create index namespace_createatinsec on run_details. Error: %s", response.Error) } response = db.Model(&model.Run{}).AddIndex("namespace_conditions_finishedatinsec", "Namespace", "Conditions", "FinishedAtInSec") - if response.Error != nil { + if ignoreAlreadyExistError(driverName, response.Error) != nil { glog.Fatalf("Failed to create index namespace_conditions_finishedatinsec on run_details. Error: %s", response.Error) } response = db.Model(&model.Pipeline{}).AddUniqueIndex("name_namespace_index", "Name", "Namespace") - if response.Error != nil { + if ignoreAlreadyExistError(driverName, response.Error) != nil { glog.Fatalf("Failed to create index name_namespace_index on run_details. Error: %s", response.Error) } - response = db.Model(&model.RunMetric{}). - AddForeignKey("RunUUID", "run_details(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* update */) - if response.Error != nil { - glog.Fatalf("Failed to create a foreign key for RunID in run_metrics table. Error: %s", response.Error) - } - response = db.Model(&model.PipelineVersion{}). - AddForeignKey("PipelineId", "pipelines(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* update */) - if response.Error != nil { - glog.Fatalf("Failed to create a foreign key for PipelineId in pipeline_versions table. Error: %s", response.Error) - } - response = db.Model(&model.Task{}). - AddForeignKey("RunUUID", "run_details(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* update */) - if response.Error != nil { - glog.Fatalf("Failed to create a foreign key for RunUUID in task table. Error: %s", response.Error) + switch driverName { + case "pgx": + response = db.Model(&model.RunMetric{}). + AddForeignKey("\"RunUUID\"", "run_details(\"UUID\")", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for RunUUID in run_metrics table. Error: %s", response.Error) + } + response = db.Model(&model.PipelineVersion{}). + AddForeignKey("\"PipelineId\"", "pipelines(\"UUID\")", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for PipelineId in pipeline_versions table. Error: %s", response.Error) + } + response = db.Model(&model.Task{}). + AddForeignKey("\"RunUUID\"", "run_details(\"UUID\")", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for RunUUID in task table. Error: %s", response.Error) + } + case "mysql": + response = db.Model(&model.RunMetric{}). + AddForeignKey("RunUUID", "run_details(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for RunUUID in run_metrics table. Error: %s", response.Error) + } + response = db.Model(&model.PipelineVersion{}). + AddForeignKey("PipelineId", "pipelines(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for PipelineId in pipeline_versions table. Error: %s", response.Error) + } + response = db.Model(&model.Task{}). + AddForeignKey("RunUUID", "run_details(UUID)", "CASCADE" /* onDelete */, "CASCADE" /* onUpdate */) + if ignoreAlreadyExistError(driverName, response.Error) != nil { + glog.Fatalf("Failed to create a foreign key for RunUUID in task table. Error: %s", response.Error) + } + default: + glog.Fatalf("Driver %v is not supported, use \"mysql\" for MySQL, or \"pgx\" for PostgreSQL", driverName) } // Data backfill for pipeline_versions if this is the first time for @@ -320,44 +357,66 @@ func initDBClient(initConnectionTimeout time.Duration) *storage.DB { glog.Fatalf("Failed to backfill experiment UUID in run_details table: %s", err) } - response = db.Model(&model.Pipeline{}).ModifyColumn("Description", "longtext not null") + response = db.Model(&model.Pipeline{}).ModifyColumn("Description", textFormat) if response.Error != nil { glog.Fatalf("Failed to update pipeline description type. Error: %s", response.Error) } - // If the old unique index idx_pipeline_version_uuid_name on pipeline_versions exists, remove it. - rows, err := db.Raw(`show index from pipeline_versions where Key_name='idx_pipeline_version_uuid_name'`).Rows() - if err != nil { - glog.Fatalf("Failed to query pipeline_version table's indices. Error: %s", err) - } - if err := rows.Err(); err != nil { - glog.Fatalf("Failed to query pipeline_version table's indices. Error: %s", err) - } - if rows.Next() { - db.Exec(`drop index idx_pipeline_version_uuid_name on pipeline_versions`) + // Because PostgreSQL was supported later, there's no need to delete the relic index + if driverName == "mysql" { + // If the old unique index idx_pipeline_version_uuid_name on pipeline_versions exists, remove it. + rows, err := db.Raw(`show index from pipeline_versions where Key_name='idx_pipeline_version_uuid_name'`).Rows() + if err != nil { + glog.Fatalf("Failed to query pipeline_version table's indices. Error: %s", err) + } + if err := rows.Err(); err != nil { + glog.Fatalf("Failed to query pipeline_version table's indices. Error: %s", err) + } + if rows.Next() { + db.Exec(`drop index idx_pipeline_version_uuid_name on pipeline_versions`) + } + defer rows.Close() } - defer rows.Close() return storage.NewDB(db.DB(), storage.NewMySQLDialect()) } -// Initialize the connection string for connecting to Mysql database -// Format would be something like root@tcp(ip:port)/dbname?charset=utf8&loc=Local&parseTime=True. -func initMysql(driverName string, initConnectionTimeout time.Duration) string { - mysqlConfig := client.CreateMySQLConfig( - common.GetStringConfigWithDefault(mysqlUser, "root"), - common.GetStringConfigWithDefault(mysqlPassword, ""), - common.GetStringConfigWithDefault(mysqlServiceHost, "mysql"), - common.GetStringConfigWithDefault(mysqlServicePort, "3306"), - "", - common.GetStringConfigWithDefault(mysqlGroupConcatMaxLen, "1024"), - common.GetMapConfig(mysqlExtraParams), - ) +// Initializes Database driver. Use `driverName` to indicate which type of DB to use: +// 1) "mysql" for MySQL +// 2) "pgx" for PostgreSQL +func initDBDriver(driverName string, initConnectionTimeout time.Duration) string { + var sqlConfig, dbName string + var mysqlConfig *mysql.Config + switch driverName { + case "mysql": + mysqlConfig = client.CreateMySQLConfig( + common.GetStringConfigWithDefault(mysqlUser, "root"), + common.GetStringConfigWithDefault(mysqlPassword, ""), + common.GetStringConfigWithDefault(mysqlServiceHost, "mysql"), + common.GetStringConfigWithDefault(mysqlServicePort, "3306"), + "", + common.GetStringConfigWithDefault(mysqlGroupConcatMaxLen, "1024"), + common.GetMapConfig(mysqlExtraParams), + ) + sqlConfig = mysqlConfig.FormatDSN() + dbName = common.GetStringConfig(mysqlDBName) + case "pgx": + sqlConfig = client.CreatePostgreSQLConfig( + common.GetStringConfigWithDefault(postgresUser, "user"), + common.GetStringConfigWithDefault(postgresPassword, "password"), + common.GetStringConfigWithDefault(postgresHost, "postgresql"), + "postgres", + uint16(common.GetIntConfigWithDefault(postgresPort, 5432)), + ) + dbName = common.GetStringConfig(postgresDBName) + default: + glog.Fatalf("Driver %v is not supported, use \"mysql\" for MySQL, or \"pgx\" for PostgreSQL", driverName) + } var db *sql.DB var err error operation := func() error { - db, err = sql.Open(driverName, mysqlConfig.FormatDSN()) + db, err = sql.Open(driverName, sqlConfig) if err != nil { return err } @@ -365,7 +424,6 @@ func initMysql(driverName string, initConnectionTimeout time.Duration) string { } b := backoff.NewExponentialBackOff() b.MaxElapsedTime = initConnectionTimeout - // err = backoff.Retry(operation, b) err = backoff.RetryNotify(operation, b, func(e error, duration time.Duration) { glog.Errorf("%v", e) }) @@ -374,10 +432,9 @@ func initMysql(driverName string, initConnectionTimeout time.Duration) string { util.TerminateIfError(err) // Create database if not exist - dbName := common.GetStringConfig(mysqlDBName) operation = func() error { - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName)) - if err != nil { + _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", dbName)) + if ignoreAlreadyExistError(driverName, err) != nil { return err } return nil @@ -387,13 +444,30 @@ func initMysql(driverName string, initConnectionTimeout time.Duration) string { err = backoff.Retry(operation, b) util.TerminateIfError(err) - mysqlConfig.DBName = dbName - // When updating, return rows matched instead of rows affected. This counts rows that are being - // set as the same values as before. If updating using a primary key and rows matched is 0, then - // it means this row is not found. - // Config reference: https://github.com/go-sql-driver/mysql#clientfoundrows - mysqlConfig.ClientFoundRows = true - return mysqlConfig.FormatDSN() + + switch driverName { + case "mysql": + mysqlConfig.DBName = dbName + // When updating, return rows matched instead of rows affected. This counts rows that are being + // set as the same values as before. If updating using a primary key and rows matched is 0, then + // it means this row is not found. + // Config reference: https://github.com/go-sql-driver/mysql#clientfoundrows + mysqlConfig.ClientFoundRows = true + sqlConfig = mysqlConfig.FormatDSN() + case "pgx": + // Note: postgreSQL does not have the option `ClientFoundRows` + // Config reference: https://www.postgresql.org/docs/current/libpq-connect.html + sqlConfig = client.CreatePostgreSQLConfig( + common.GetStringConfigWithDefault(postgresUser, "root"), + common.GetStringConfigWithDefault(postgresPassword, ""), + common.GetStringConfigWithDefault(postgresHost, "postgresql"), + dbName, + uint16(common.GetIntConfigWithDefault(postgresPort, 5432)), + ) + default: + glog.Fatalf("Driver %v is not supported, use \"mysql\" for MySQL, or \"pgx\" for PostgreSQL", driverName) + } + return sqlConfig } func initMinioClient(initConnectionTimeout time.Duration) storage.ObjectStoreInterface { @@ -448,8 +522,8 @@ func initLogArchive() (logArchive archive.LogArchiveInterface) { return } -// newClientManager creates and Init a new instance of ClientManager. -func newClientManager() ClientManager { +// NewClientManager creates and Init a new instance of ClientManager. +func NewClientManager() ClientManager { clientManager := ClientManager{} clientManager.init() @@ -489,7 +563,7 @@ func initPipelineVersionsFromPipelines(db *gorm.DB) { func backfillExperimentIDToRunTable(db *gorm.DB) error { // check if there is any row in the run table has experiment ID being empty - rows, err := db.CommonDB().Query(`SELECT ExperimentUUID FROM run_details WHERE ExperimentUUID = '' LIMIT 1`) + rows, err := db.CommonDB().Query("SELECT \"ExperimentUUID\" FROM run_details WHERE \"ExperimentUUID\" = '' LIMIT 1") if err != nil { return err } @@ -516,3 +590,15 @@ func backfillExperimentIDToRunTable(db *gorm.DB) error { `) return err } + +// Returns the same error, if it's not "already exists" related. +// Otherwise, return nil. +func ignoreAlreadyExistError(driverName string, err error) error { + if driverName == "pgx" && err != nil && strings.Contains(err.Error(), client.PGX_EXIST_ERROR) { + return nil + } + if driverName == "mysql" && err != nil && strings.Contains(err.Error(), client.MYSQL_EXIST_ERROR) { + return nil + } + return err +} diff --git a/backend/src/apiserver/config/config.json b/backend/src/apiserver/config/config.json index e27bab65f6c..251d22a3870 100644 --- a/backend/src/apiserver/config/config.json +++ b/backend/src/apiserver/config/config.json @@ -1,10 +1,13 @@ { "DBConfig": { - "DriverName": "mysql", - "DataSourceName": "", - "DBName": "mlpipeline", - "GroupConcatMaxLen": "4194304", - "ConMaxLifeTime": "120s" + "MySQLConfig": { + "DataSourceName": "", + "DBName": "mlpipeline", + "GroupConcatMaxLen": "4194304" + }, + "PostgreSQLConfig": { + "DBName": "mlpipeline" + } }, "ObjectStoreConfig": { "AccessKey": "minio", @@ -12,6 +15,8 @@ "BucketName": "mlpipeline", "PipelinePath": "pipelines" }, + "DBDriverName": "mysql", + "ConMaxLifeTime": "120s", "ARCHIVE_CONFIG_LOG_FILE_NAME": "main.log", "ARCHIVE_CONFIG_LOG_PATH_PREFIX": "/artifacts", "InitConnectionTimeout": "6m", diff --git a/backend/src/apiserver/main.go b/backend/src/apiserver/main.go index 4efab33d562..276a39ee1b5 100644 --- a/backend/src/apiserver/main.go +++ b/backend/src/apiserver/main.go @@ -35,6 +35,7 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/runtime" apiv1beta1 "github.com/kubeflow/pipelines/backend/api/v1beta1/go_client" apiv2beta1 "github.com/kubeflow/pipelines/backend/api/v2beta1/go_client" + cm "github.com/kubeflow/pipelines/backend/src/apiserver/client_manager" "github.com/kubeflow/pipelines/backend/src/apiserver/common" "github.com/kubeflow/pipelines/backend/src/apiserver/model" "github.com/kubeflow/pipelines/backend/src/apiserver/resource" @@ -59,7 +60,7 @@ func main() { flag.Parse() initConfig() - clientManager := newClientManager() + clientManager := cm.NewClientManager() resourceManager := resource.NewResourceManager( &clientManager, ) @@ -119,8 +120,8 @@ func startRpcServer(resourceManager *resource.ResourceManager) { s, server.NewVisualizationServer( resourceManager, - common.GetStringConfig(visualizationServiceHost), - common.GetStringConfig(visualizationServicePort), + common.GetStringConfig(cm.VisualizationServiceHost), + common.GetStringConfig(cm.VisualizationServicePort), )) apiv1beta1.RegisterAuthServiceServer(s, server.NewAuthServer(resourceManager)) diff --git a/backend/test/integration/README.md b/backend/test/integration/README.md index ee6e5109717..d87a3303105 100644 --- a/backend/test/integration/README.md +++ b/backend/test/integration/README.md @@ -5,7 +5,22 @@ ### How to run +The default integration test will test the default Database, MySQL. + 1. Configure kubectl to connect to your kfp cluster. 2. Run the following for all integration tests: `NAMESPACE= ./run_tests_locally.sh`. 3. Or run the following to select certain tests: `NAMESPACE= ./run_tests_locally.sh -testify.m Job`. Reference: https://stackoverflow.com/a/43312451 + +### Run database tests with PostgreSQL + +To run this test, you need to first deploy the PostgreSQL images on your Kubernetes cluster. For how to deploy, +see [instructions here](../../../manifests/kustomize/third-party/postgresql/README.md). + +When testing against postgreSQL, all integration tests with MySQL will be disabled. Use an argument `postgres` to run +test against a PostgreSQL database: +``` +NAMESPACE= ./run_tests_locally.sh postgres +``` + + diff --git a/backend/test/integration/db_test.go b/backend/test/integration/db_test.go new file mode 100644 index 00000000000..be65889effc --- /dev/null +++ b/backend/test/integration/db_test.go @@ -0,0 +1,79 @@ +// Copyright 2023 The Kubeflow Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package integration + +import ( + "testing" + "time" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + _ "github.com/jackc/pgx/v5/stdlib" + cm "github.com/kubeflow/pipelines/backend/src/apiserver/client_manager" +) + +type DBTestSuite struct { + suite.Suite +} + +// Skip if it's not integration test running. +func (s *DBTestSuite) SetupTest() { + if !*runIntegrationTests { + s.T().SkipNow() + return + } +} + +// Test MySQL initializes correctly +func (s *DBTestSuite) TestInitDBClient_MySQL() { + if *runPostgreSQLTests { + s.T().SkipNow() + return + } + t := s.T() + viper.Set("DBDriverName", "mysql") + viper.Set("DBConfig.MySQLConfig.DBName", "mlpipeline") + // The default port-forwarding IP address that test uses is different compared to production + if *localTest { + viper.Set("DBConfig.MySQLConfig.Host", "localhost") + } + duration, _ := time.ParseDuration("1m") + db := cm.InitDBClient(duration) + assert.NotNil(t, db) +} + +// Test PostgreSQL initializes correctly +func (s *DBTestSuite) TestInitDBClient_PostgreSQL() { + if !*runPostgreSQLTests { + s.T().SkipNow() + return + } + t := s.T() + viper.Set("DBDriverName", "pgx") + viper.Set("DBConfig.PostgreSQLConfig.DBName", "mlpipeline") + // The default port-forwarding IP address that test uses is different compared to production + viper.Set("DBConfig.PostgreSQLConfig.Host", "127.0.0.3") + viper.Set("DBConfig.PostgreSQLConfig.User", "user") + viper.Set("DBConfig.PostgreSQLConfig.Password", "password") + duration, _ := time.ParseDuration("1m") + db := cm.InitDBClient(duration) + assert.NotNil(t, db) +} + +func TestDB(t *testing.T) { + suite.Run(t, new(DBTestSuite)) +} diff --git a/backend/test/integration/flags.go b/backend/test/integration/flags.go index 7585d2d75c6..95af0e0d559 100644 --- a/backend/test/integration/flags.go +++ b/backend/test/integration/flags.go @@ -24,6 +24,8 @@ var ( initializeTimeout = flag.Duration("initializeTimeout", 2*time.Minute, "Duration to wait for test initialization") runIntegrationTests = flag.Bool("runIntegrationTests", false, "Whether to also run integration tests that call the service") runUpgradeTests = flag.Bool("runUpgradeTests", false, "Whether to run upgrade tests") + runPostgreSQLTests = flag.Bool("runPostgreSQLTests", false, "Run integration test with PostgreSQL") + localTest = flag.Bool("localTest", false, "Run integration test locally") ) /** diff --git a/backend/test/integration/run_tests_locally.sh b/backend/test/integration/run_tests_locally.sh index 8dfe095e006..371ad83f4e2 100755 --- a/backend/test/integration/run_tests_locally.sh +++ b/backend/test/integration/run_tests_locally.sh @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -ex if [ -z "${NAMESPACE}" ]; then echo "NAMESPACE env var is not provided, please set it to your KFP namespace" @@ -32,7 +32,26 @@ case "$response" in ;; esac +function cleanup() { + echo "killing kubectl port forward before exit" + kill "$PORT_FORWARD_PID" +} +trap cleanup EXIT + echo "Starting integration tests..." -command="go test -v ./... -namespace ${NAMESPACE} -args -runIntegrationTests=true -isDevMode=true" -echo $command "$@" + +if [ "$1" == "postgres" ]; then + echo "Starting PostgreSQL DB port forwarding..." + kubectl -n "$NAMESPACE" port-forward svc/postgres-service 5432:5432 --address="127.0.0.3" & PORT_FORWARD_PID=$! + # wait for kubectl port forward + sleep 10 + command="go test -v ./... -namespace ${NAMESPACE} -args -runIntegrationTests=true -isDevMode=true -runPostgreSQLTests=true -localTest=true" +else + echo "Starting MySQL DB port forwarding..." + kubectl -n "$NAMESPACE" port-forward svc/mysql 3306:3306 --address=localhost & PORT_FORWARD_PID=$! + # wait for kubectl port forward + sleep 10 + command="go test -v ./... -namespace ${NAMESPACE} -args -runIntegrationTests=true -isDevMode=true -localTest=true" +fi + $command "$@" diff --git a/backend/third_party_licenses/apiserver.csv b/backend/third_party_licenses/apiserver.csv index 2e2bb84ee43..ef4893cbb1e 100644 --- a/backend/third_party_licenses/apiserver.csv +++ b/backend/third_party_licenses/apiserver.csv @@ -104,12 +104,12 @@ github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1. go.mongodb.org/mongo-driver,https://github.com/mongodb/mongo-go-driver/blob/v1.8.2/LICENSE,Apache-2.0 go.opencensus.io,https://github.com/census-instrumentation/opencensus-go/blob/v0.23.0/LICENSE,Apache-2.0 gocloud.dev,https://github.com/google/go-cloud/blob/v0.22.0/LICENSE,Apache-2.0 -golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/86341886:LICENSE,BSD-3-Clause -golang.org/x/net,https://cs.opensource.google/go/x/net/+/27dd8689:LICENSE,BSD-3-Clause +golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.9.0:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/d3ed0bb2:LICENSE,BSD-3-Clause -golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/a9b59b02:LICENSE,BSD-3-Clause -golang.org/x/term,https://cs.opensource.google/go/x/term/+/03fcf44c:LICENSE,BSD-3-Clause -golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.3.7:LICENSE,BSD-3-Clause +golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/90d013bb:LICENSE,BSD-3-Clause golang.org/x/xerrors,https://cs.opensource.google/go/x/xerrors/+/5ec99f83:LICENSE,BSD-3-Clause google.golang.org/api,https://github.com/googleapis/google-api-go-client/blob/v0.70.0/LICENSE,BSD-3-Clause diff --git a/backend/third_party_licenses/cache_server.csv b/backend/third_party_licenses/cache_server.csv index a920b3116c9..20d1fe62beb 100644 --- a/backend/third_party_licenses/cache_server.csv +++ b/backend/third_party_licenses/cache_server.csv @@ -71,12 +71,12 @@ github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3- github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE,MIT github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1.2.1/LICENSE,MIT go.mongodb.org/mongo-driver,https://github.com/mongodb/mongo-go-driver/blob/v1.8.2/LICENSE,Apache-2.0 -golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/86341886:LICENSE,BSD-3-Clause -golang.org/x/net,https://cs.opensource.google/go/x/net/+/27dd8689:LICENSE,BSD-3-Clause +golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.9.0:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/d3ed0bb2:LICENSE,BSD-3-Clause -golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/a9b59b02:LICENSE,BSD-3-Clause -golang.org/x/term,https://cs.opensource.google/go/x/term/+/03fcf44c:LICENSE,BSD-3-Clause -golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.3.7:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/90d013bb:LICENSE,BSD-3-Clause google.golang.org/genproto,https://github.com/googleapis/go-genproto/blob/1973136f34c6/LICENSE,Apache-2.0 google.golang.org/grpc,https://github.com/grpc/grpc-go/blob/v1.44.0/LICENSE,Apache-2.0 diff --git a/backend/third_party_licenses/persistence_agent.csv b/backend/third_party_licenses/persistence_agent.csv index edaf797e877..102c483cbd3 100644 --- a/backend/third_party_licenses/persistence_agent.csv +++ b/backend/third_party_licenses/persistence_agent.csv @@ -75,12 +75,12 @@ github.com/subosito/gotenv,https://github.com/subosito/gotenv/blob/v1.2.0/LICENS github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE,MIT github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1.2.1/LICENSE,MIT go.mongodb.org/mongo-driver,https://github.com/mongodb/mongo-go-driver/blob/v1.8.2/LICENSE,Apache-2.0 -golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/86341886:LICENSE,BSD-3-Clause -golang.org/x/net,https://cs.opensource.google/go/x/net/+/27dd8689:LICENSE,BSD-3-Clause +golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.9.0:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/d3ed0bb2:LICENSE,BSD-3-Clause -golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/a9b59b02:LICENSE,BSD-3-Clause -golang.org/x/term,https://cs.opensource.google/go/x/term/+/03fcf44c:LICENSE,BSD-3-Clause -golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.3.7:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/90d013bb:LICENSE,BSD-3-Clause google.golang.org/genproto,https://github.com/googleapis/go-genproto/blob/1973136f34c6/LICENSE,Apache-2.0 google.golang.org/grpc,https://github.com/grpc/grpc-go/blob/v1.44.0/LICENSE,Apache-2.0 diff --git a/backend/third_party_licenses/swf.csv b/backend/third_party_licenses/swf.csv index da73199a710..54d644960ff 100644 --- a/backend/third_party_licenses/swf.csv +++ b/backend/third_party_licenses/swf.csv @@ -77,12 +77,12 @@ github.com/subosito/gotenv,https://github.com/subosito/gotenv/blob/v1.2.0/LICENS github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE,MIT github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1.2.1/LICENSE,MIT go.mongodb.org/mongo-driver,https://github.com/mongodb/mongo-go-driver/blob/v1.8.2/LICENSE,Apache-2.0 -golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/86341886:LICENSE,BSD-3-Clause -golang.org/x/net,https://cs.opensource.google/go/x/net/+/27dd8689:LICENSE,BSD-3-Clause +golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.9.0:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/d3ed0bb2:LICENSE,BSD-3-Clause -golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/a9b59b02:LICENSE,BSD-3-Clause -golang.org/x/term,https://cs.opensource.google/go/x/term/+/03fcf44c:LICENSE,BSD-3-Clause -golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.3.7:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/90d013bb:LICENSE,BSD-3-Clause google.golang.org/genproto,https://github.com/googleapis/go-genproto/blob/1973136f34c6/LICENSE,Apache-2.0 google.golang.org/grpc,https://github.com/grpc/grpc-go/blob/v1.44.0/LICENSE,Apache-2.0 diff --git a/backend/third_party_licenses/viewer.csv b/backend/third_party_licenses/viewer.csv index 678302087b0..f6589f7589b 100644 --- a/backend/third_party_licenses/viewer.csv +++ b/backend/third_party_licenses/viewer.csv @@ -35,11 +35,11 @@ github.com/prometheus/common,https://github.com/prometheus/common/blob/v0.32.1/L github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg,https://github.com/prometheus/common/blob/v0.32.1/internal/bitbucket.org/ww/goautoneg/README.txt,BSD-3-Clause github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/v0.7.3/LICENSE,Apache-2.0 github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3-Clause -golang.org/x/net,https://cs.opensource.google/go/x/net/+/27dd8689:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/d3ed0bb2:LICENSE,BSD-3-Clause -golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/a9b59b02:LICENSE,BSD-3-Clause -golang.org/x/term,https://cs.opensource.google/go/x/term/+/03fcf44c:LICENSE,BSD-3-Clause -golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.3.7:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.8.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/90d013bb:LICENSE,BSD-3-Clause gomodules.xyz/jsonpatch/v2,https://github.com/gomodules/jsonpatch/blob/v2.2.0/v2/LICENSE,Apache-2.0 google.golang.org/protobuf,https://github.com/protocolbuffers/protobuf-go/blob/v1.27.1/LICENSE,BSD-3-Clause diff --git a/go.mod b/go.mod index c0aed537fe2..d88deba061c 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/jackc/pgx/v5 v5.4.2 github.com/jinzhu/gorm v1.9.1 github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.4 // indirect @@ -41,9 +42,9 @@ require ( github.com/robfig/cron v1.2.0 github.com/sirupsen/logrus v1.8.1 github.com/spf13/viper v1.10.1 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.1 gocloud.dev v0.22.0 - golang.org/x/net v0.0.0-20220225172249-27dd8689420f + golang.org/x/net v0.10.0 google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 google.golang.org/grpc v1.44.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 diff --git a/go.sum b/go.sum index 7c0e71a44da..70508caa624 100644 --- a/go.sum +++ b/go.sum @@ -834,6 +834,13 @@ github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itchyny/gojq v0.12.6/go.mod h1:ZHrkfu7A+RbZLy5J1/JKpS4poEqrzItSTGDItqsfP0A= github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.4.2 h1:u1gmGDwbdRUZiwisBm/Ky2M14uQyUP65bG8+20nnyrg= +github.com/jackc/pgx/v5 v5.4.2/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk= github.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= @@ -1257,6 +1264,8 @@ github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1Sd github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1264,8 +1273,11 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stripe/stripe-go v70.15.0+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -1332,6 +1344,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1445,8 +1458,9 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1492,8 +1506,10 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1570,8 +1586,11 @@ golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1605,8 +1624,10 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1722,13 +1743,19 @@ golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1738,8 +1765,10 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1835,8 +1864,10 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/manifests/kustomize/third-party/postgresql/README.md b/manifests/kustomize/third-party/postgresql/README.md index 5096dddf308..c0c1cda4337 100644 --- a/manifests/kustomize/third-party/postgresql/README.md +++ b/manifests/kustomize/third-party/postgresql/README.md @@ -3,7 +3,7 @@ ```bash # In this folder of manifests/kustomize/third-party/postgresql rm -rf build -mkdir buidl +mkdir build kustomize build ./base -o build ``` @@ -11,5 +11,5 @@ kustomize build ./base -o build ```bash # In this folder of manifests/kustomize/third-party/postgresql -kubectl apply -f build +kubectl -n apply -f build ``` \ No newline at end of file diff --git a/manifests/kustomize/third-party/postgresql/base/kustomization.yaml b/manifests/kustomize/third-party/postgresql/base/kustomization.yaml index cc22ca5f7ef..e7951ef9f4a 100644 --- a/manifests/kustomize/third-party/postgresql/base/kustomization.yaml +++ b/manifests/kustomize/third-party/postgresql/base/kustomization.yaml @@ -5,4 +5,4 @@ resources: - pg-pvc.yaml - pg-service.yaml - pg-secret.yaml -- pg-serviceaccount.yaml \ No newline at end of file +- pg-serviceaccount.yaml diff --git a/manifests/kustomize/third-party/postgresql/base/pg-deployment.yaml b/manifests/kustomize/third-party/postgresql/base/pg-deployment.yaml index 9979be02381..bd0bf4baafb 100644 --- a/manifests/kustomize/third-party/postgresql/base/pg-deployment.yaml +++ b/manifests/kustomize/third-party/postgresql/base/pg-deployment.yaml @@ -1,14 +1,15 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: postgres-deployment + name: postgres labels: app: postgres spec: - replicas: 2 selector: matchLabels: app: postgres + strategy: + type: Recreate template: metadata: labels: @@ -33,10 +34,15 @@ spec: ports: - containerPort: 5432 name: postgres + readinessProbe: + exec: + command: ["psql", "-U", "user", "-d", "postgres", "-c", "SELECT 1"] + initialDelaySeconds: 15 + timeoutSeconds: 2 volumeMounts: - name: postgres-stateful-data mountPath: /var/lib/postgresql/data volumes: - name: postgres-stateful-data persistentVolumeClaim: - claimName: postgres-pvc \ No newline at end of file + claimName: postgres-pvc diff --git a/manifests/kustomize/third-party/postgresql/base/pg-service.yaml b/manifests/kustomize/third-party/postgresql/base/pg-service.yaml index 3e365fbdd43..002eff982db 100644 --- a/manifests/kustomize/third-party/postgresql/base/pg-service.yaml +++ b/manifests/kustomize/third-party/postgresql/base/pg-service.yaml @@ -6,7 +6,8 @@ metadata: app: postgres spec: ports: - - port: 5432 - type: LoadBalancer + - protocol: TCP + port: 5432 + targetPort: 5432 selector: - app: postgres \ No newline at end of file + app: postgres diff --git a/manifests/kustomize/third-party/postgresql/base/pg-serviceaccount.yaml b/manifests/kustomize/third-party/postgresql/base/pg-serviceaccount.yaml index 87dacc7a3db..4397c93c104 100644 --- a/manifests/kustomize/third-party/postgresql/base/pg-serviceaccount.yaml +++ b/manifests/kustomize/third-party/postgresql/base/pg-serviceaccount.yaml @@ -2,4 +2,3 @@ apiVersion: v1 kind: ServiceAccount metadata: name: postgresql -