diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fc56c0da..6506fd62 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @gen1us2k @recharte @oksana-grishchenko @michal-kralik +* @recharte @oksana-grishchenko @michal-kralik diff --git a/.github/workflows/rc_create.yml b/.github/workflows/rc_create.yml index 9862ff91..080b1dd8 100644 --- a/.github/workflows/rc_create.yml +++ b/.github/workflows/rc_create.yml @@ -111,7 +111,7 @@ jobs: git push origin $RC_BRANCH # update tag refs in scripts - sed -i "s/dev-latest/$VERSION/g" deploy/quickstart-k8s.yaml + sed -i "s/0.0.0/$VERSION/g" deploy/quickstart-k8s.yaml # configure userdata for commits git config --global user.email "everest-ci@percona.com" diff --git a/api/database_cluster.go b/api/database_cluster.go index 88733b70..5a5e1930 100644 --- a/api/database_cluster.go +++ b/api/database_cluster.go @@ -103,8 +103,8 @@ func (e *EverestServer) GetDatabaseClusterCredentials(ctx echo.Context, name str response.Username = pointer.ToString("root") response.Password = pointer.ToString(string(secret.Data["root"])) case everestv1alpha1.DatabaseEnginePSMDB: - response.Username = pointer.ToString(string(secret.Data["MONGODB_USER_ADMIN_USER"])) - response.Password = pointer.ToString(string(secret.Data["MONGODB_USER_ADMIN_PASSWORD"])) + response.Username = pointer.ToString(string(secret.Data["MONGODB_DATABASE_ADMIN_USER"])) + response.Password = pointer.ToString(string(secret.Data["MONGODB_DATABASE_ADMIN_PASSWORD"])) case everestv1alpha1.DatabaseEnginePostgresql: response.Username = pointer.ToString("postgres") response.Password = pointer.ToString(string(secret.Data["password"])) diff --git a/api/everest-server.gen.go b/api/everest-server.gen.go index 98b3a4f0..1addc1e1 100644 --- a/api/everest-server.gen.go +++ b/api/everest-server.gen.go @@ -142,7 +142,7 @@ type DatabaseCluster struct { // Pitr PITR is the configuration of the point in time recovery Pitr *struct { // BackupStorageName BackupStorageName is the name of the BackupStorage where the PITR is enabled - BackupStorageName string `json:"backupStorageName"` + BackupStorageName *string `json:"backupStorageName,omitempty"` // Enabled Enabled is a flag to enable PITR Enabled bool `json:"enabled"` @@ -289,6 +289,9 @@ type DatabaseCluster struct { // Status DatabaseClusterStatus defines the observed state of DatabaseCluster. Status *struct { + // ActiveStorage ActiveStorage is the storage used in cluster (psmdb only) + ActiveStorage *string `json:"activeStorage,omitempty"` + // Hostname Hostname is the hostname where the cluster can be reached Hostname *string `json:"hostname,omitempty"` @@ -1876,137 +1879,137 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/validation.go b/api/validation.go index a8141883..f8b3cc8c 100644 --- a/api/validation.go +++ b/api/validation.go @@ -18,12 +18,12 @@ package api import ( "bytes" "context" - "encoding/base64" "encoding/json" "errors" "fmt" "net/url" "regexp" + "time" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/aws/aws-sdk-go/aws" @@ -45,6 +45,7 @@ const ( pxcDeploymentName = "percona-xtradb-cluster-operator" psmdbDeploymentName = "percona-server-mongodb-operator" pgDeploymentName = "percona-postgresql-operator" + dateFormat = "2006-01-02T15:04:05Z" ) var ( @@ -52,23 +53,32 @@ var ( minCPUQuantity = resource.MustParse("600m") //nolint:gochecknoglobals minMemQuantity = resource.MustParse("512M") //nolint:gochecknoglobals - errDBCEmptyMetadata = errors.New("databaseCluster's Metadata should not be empty") - errDBCNameEmpty = errors.New("databaseCluster's metadata.name should not be empty") - errDBCNameWrongFormat = errors.New("databaseCluster's metadata.name should be a string") - errNotEnoughMemory = fmt.Errorf("memory limits should be above %s", minMemQuantity.String()) - errInt64NotSupported = errors.New("specifying resources using int64 data type is not supported. Please use string format for that") - errNotEnoughCPU = fmt.Errorf("CPU limits should be above %s", minCPUQuantity.String()) - errNotEnoughDiskSize = fmt.Errorf("storage size should be above %s", minStorageQuantity.String()) - errUnsupportedPXCProxy = errors.New("you can use either HAProxy or Proxy SQL for PXC clusters") - errUnsupportedPGProxy = errors.New("you can use only PGBouncer as a proxy type for Postgres clusters") - errUnsupportedPSMDBProxy = errors.New("you can use only Mongos as a proxy type for MongoDB clusters") - errNoSchedules = errors.New("please specify at least one backup schedule") - errNoNameInSchedule = errors.New("'name' field for the backup schedules cannot be empty") - errScheduleNoBackupStorageName = errors.New("'backupStorageName' field cannot be empty when schedule is enabled") - errPitrNoBackupStorageName = errors.New("'backupStorageName' field cannot be empty when pitr is enabled") - errNoResourceDefined = errors.New("please specify resource limits for the cluster") - errPitrUploadInterval = errors.New("'uploadIntervalSec' should be more than 0") - errPitrS3Only = errors.New("point-in-time recovery only supported for s3 compatible storages") + errDBCEmptyMetadata = errors.New("databaseCluster's Metadata should not be empty") + errDBCNameEmpty = errors.New("databaseCluster's metadata.name should not be empty") + errDBCNameWrongFormat = errors.New("databaseCluster's metadata.name should be a string") + errNotEnoughMemory = fmt.Errorf("memory limits should be above %s", minMemQuantity.String()) + errInt64NotSupported = errors.New("specifying resources using int64 data type is not supported. Please use string format for that") + errNotEnoughCPU = fmt.Errorf("CPU limits should be above %s", minCPUQuantity.String()) + errNotEnoughDiskSize = fmt.Errorf("storage size should be above %s", minStorageQuantity.String()) + errUnsupportedPXCProxy = errors.New("you can use either HAProxy or Proxy SQL for PXC clusters") + errUnsupportedPGProxy = errors.New("you can use only PGBouncer as a proxy type for Postgres clusters") + errUnsupportedPSMDBProxy = errors.New("you can use only Mongos as a proxy type for MongoDB clusters") + errNoSchedules = errors.New("please specify at least one backup schedule") + errNoNameInSchedule = errors.New("'name' field for the backup schedules cannot be empty") + errScheduleNoBackupStorageName = errors.New("'backupStorageName' field cannot be empty when schedule is enabled") + errPitrNoBackupStorageName = errors.New("'backupStorageName' field cannot be empty when pitr is enabled") + errNoResourceDefined = errors.New("please specify resource limits for the cluster") + errPitrUploadInterval = errors.New("'uploadIntervalSec' should be more than 0") + errPXCPitrS3Only = errors.New("point-in-time recovery only supported for s3 compatible storages") + errPSMDBMultipleStorages = errors.New("can't use more than one backup storage for PSMDB clusters") + errPSMDBViolateActiveStorage = errors.New("can't change the active storage for PSMDB clusters") + errDataSourceConfig = errors.New("either DBClusterBackupName or BackupSource must be specified in the DataSource field") + errDataSourceNoPitrDateSpecified = errors.New("pitr Date must be specified for type Date") + errDataSourceWrongDateFormat = errors.New("failed to parse .Spec.DataSource.Pitr.Date as 2006-01-02T15:04:05Z") + errDataSourceNoBackupStorageName = errors.New("'backupStorageName' should be specified in .Spec.DataSource.BackupSource") + errDataSourceNoPath = errors.New("'path' should be specified in .Spec.DataSource.BackupSource") + errIncorrectDataSourceStruct = errors.New("incorrect data source struct") + errUnsupportedPitrType = errors.New("the given point-in-time recovery type is not supported") //nolint:gochecknoglobals operatorEngine = map[everestv1alpha1.EngineType]string{ everestv1alpha1.DatabaseEnginePXC: pxcDeploymentName, @@ -244,7 +254,7 @@ func azureAccess(ctx context.Context, l *zap.SugaredLogger, accountName, account return nil } -func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.BackupStorage, secret *corev1.Secret, l *zap.SugaredLogger) (*UpdateBackupStorageParams, error) { //nolint:cyclop +func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.BackupStorage, secret *corev1.Secret, l *zap.SugaredLogger) (*UpdateBackupStorageParams, error) { var params UpdateBackupStorageParams if err := ctx.Bind(¶ms); err != nil { return nil, err @@ -256,19 +266,11 @@ func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.Ba return nil, err } } - accessKeyData, err := base64.StdEncoding.DecodeString(string(secret.Data["AWS_ACCESS_KEY_ID"])) - if err != nil { - return nil, err - } - accessKey := string(accessKeyData) + accessKey := string(secret.Data["AWS_ACCESS_KEY_ID"]) if params.AccessKey != nil { accessKey = *params.AccessKey } - secretKeyData, err := base64.StdEncoding.DecodeString(string(secret.Data["AWS_SECRET_ACCESS_KEY"])) - if err != nil { - return nil, err - } - secretKey := string(secretKeyData) + secretKey := string(secret.Data["AWS_SECRET_ACCESS_KEY"]) if params.SecretKey != nil { secretKey = *params.SecretKey } @@ -416,7 +418,7 @@ func validateCreateDatabaseClusterRequest(dbc DatabaseCluster) error { return validateRFC1035(strName, "metadata.name") } -func (e *EverestServer) validateDatabaseClusterCR(ctx echo.Context, databaseCluster *DatabaseCluster) error { +func (e *EverestServer) validateDatabaseClusterCR(ctx echo.Context, databaseCluster *DatabaseCluster) error { //nolint:cyclop if err := validateCreateDatabaseClusterRequest(*databaseCluster); err != nil { return err } @@ -449,34 +451,69 @@ func (e *EverestServer) validateDatabaseClusterCR(ctx echo.Context, databaseClus return err } - if err = e.validateBackupStoragesFor(ctx.Request().Context(), databaseCluster); err != nil { + if err = validateBackupStoragesFor(ctx.Request().Context(), databaseCluster, e.validateBackupStoragesAccess); err != nil { return err } + if databaseCluster.Spec.DataSource != nil { + if err := validateDBDataSource(databaseCluster); err != nil { + return err + } + } + return validateResourceLimits(databaseCluster) } -func (e *EverestServer) validateBackupStoragesFor(ctx context.Context, databaseCluster *DatabaseCluster) error { +func validateBackupStoragesFor( //nolint:cyclop + ctx context.Context, + databaseCluster *DatabaseCluster, + validateBackupStorageAccessFunc func(context.Context, string) (*everestv1alpha1.BackupStorage, error), +) error { if databaseCluster.Spec.Backup == nil { return nil } + storages := make(map[string]bool) if databaseCluster.Spec.Backup.Schedules != nil { for _, schedule := range *databaseCluster.Spec.Backup.Schedules { - _, err := e.validateBackupStoragesAccess(ctx, schedule.BackupStorageName) + _, err := validateBackupStorageAccessFunc(ctx, schedule.BackupStorageName) if err != nil { return err } + storages[schedule.BackupStorageName] = true } } - if databaseCluster.Spec.Backup.Pitr != nil && databaseCluster.Spec.Backup.Pitr.Enabled { - storage, err := e.validateBackupStoragesAccess(ctx, databaseCluster.Spec.Backup.Pitr.BackupStorageName) + if databaseCluster.Spec.Engine.Type == DatabaseClusterSpecEngineType(everestv1alpha1.DatabaseEnginePSMDB) { + // attempt to configure more than one storage for psmdb + if len(storages) > 1 { + return errPSMDBMultipleStorages + } + // attempt to use a storage other than the active one + if databaseCluster.Status != nil { + activeStorage := databaseCluster.Status.ActiveStorage + for name := range storages { + if activeStorage != nil && *activeStorage != "" && name != *activeStorage { + return errPSMDBViolateActiveStorage + } + } + } + } + + if databaseCluster.Spec.Backup.Pitr == nil || !databaseCluster.Spec.Backup.Pitr.Enabled { + return nil + } + + if databaseCluster.Spec.Engine.Type == DatabaseClusterSpecEngineType(everestv1alpha1.DatabaseEnginePXC) { + if databaseCluster.Spec.Backup.Pitr.BackupStorageName == nil || *databaseCluster.Spec.Backup.Pitr.BackupStorageName == "" { + return errPitrNoBackupStorageName + } + storage, err := validateBackupStorageAccessFunc(ctx, *databaseCluster.Spec.Backup.Pitr.BackupStorageName) if err != nil { return err } // pxc only supports s3 for pitr - if databaseCluster.Spec.Engine.Type == DatabaseClusterSpecEngineType(everestv1alpha1.DatabaseEnginePXC) && storage.Spec.Type != everestv1alpha1.BackupStorageTypeS3 { - return errPitrS3Only + if storage.Spec.Type != everestv1alpha1.BackupStorageTypeS3 { + return errPXCPitrS3Only } } @@ -568,7 +605,8 @@ func validatePitrSpec(cluster *DatabaseCluster) error { return nil } - if cluster.Spec.Backup.Pitr.BackupStorageName == "" { + if cluster.Spec.Engine.Type == DatabaseClusterSpecEngineType(everestv1alpha1.DatabaseEnginePXC) && + (cluster.Spec.Backup.Pitr.BackupStorageName == nil || *cluster.Spec.Backup.Pitr.BackupStorageName == "") { return errPitrNoBackupStorageName } @@ -592,6 +630,64 @@ func validateResourceLimits(cluster *DatabaseCluster) error { return validateStorageSize(cluster) } +func validateDBDataSource(db *DatabaseCluster) error { + bytes, err := json.Marshal(db.Spec.DataSource) + if err != nil { + return errIncorrectDataSourceStruct + } + return validateCommonDataSourceStruct(bytes) +} + +func validateRestoreDataSource(restore *DatabaseClusterRestore) error { + bytes, err := json.Marshal(restore.Spec.DataSource) + if err != nil { + return errIncorrectDataSourceStruct + } + return validateCommonDataSourceStruct(bytes) +} + +func validateCommonDataSourceStruct(data []byte) error { + // marshal and unmarshal to use the same validation func to validate DataSource for both db and restore + ds := &dataSourceStruct{} + err := json.Unmarshal(data, ds) + if err != nil { + return errIncorrectDataSourceStruct + } + return validateDataSource(*ds) +} + +func validateDataSource(dataSource dataSourceStruct) error { + if (dataSource.DbClusterBackupName == nil && dataSource.BackupSource == nil) || + (dataSource.DbClusterBackupName != nil && *dataSource.DbClusterBackupName != "" && dataSource.BackupSource != nil) { + return errDataSourceConfig + } + + if dataSource.BackupSource != nil { + if dataSource.BackupSource.BackupStorageName == "" { + return errDataSourceNoBackupStorageName + } + + if dataSource.BackupSource.Path == "" { + return errDataSourceNoPath + } + } + + if dataSource.Pitr != nil { //nolint:nestif + if dataSource.Pitr.Type == nil || *dataSource.Pitr.Type == string(DatabaseClusterSpecDataSourcePitrTypeDate) { + if dataSource.Pitr.Date == nil { + return errDataSourceNoPitrDateSpecified + } + + if _, err := time.Parse(dateFormat, *dataSource.Pitr.Date); err != nil { + return errDataSourceWrongDateFormat + } + } else { + return errUnsupportedPitrType + } + } + return nil +} + func ensureNonEmptyResources(cluster *DatabaseCluster) error { if cluster.Spec.Engine.Resources == nil { return errNoResourceDefined @@ -702,7 +798,7 @@ func validateDatabaseClusterBackup(ctx context.Context, backup *DatabaseClusterB if b.Spec.DBClusterName == "" { return errors.New(".spec.dbClusterName cannot be empty") } - _, err = kubeClient.GetDatabaseCluster(ctx, b.Spec.DBClusterName) + db, err := kubeClient.GetDatabaseCluster(ctx, b.Spec.DBClusterName) if err != nil { if k8serrors.IsNotFound(err) { return fmt.Errorf("database cluster %s does not exist", b.Spec.DBClusterName) @@ -716,6 +812,12 @@ func validateDatabaseClusterBackup(ctx context.Context, backup *DatabaseClusterB } return err } + + if db.Spec.Engine.Type == everestv1alpha1.DatabaseEnginePSMDB { + if db.Status.ActiveStorage != "" && db.Status.ActiveStorage != b.Spec.BackupStorageName { + return errPSMDBViolateActiveStorage + } + } return nil } @@ -761,5 +863,20 @@ func validateDatabaseClusterRestore(ctx context.Context, restore *DatabaseCluste } return err } + if err = validateRestoreDataSource(restore); err != nil { + return err + } return err } + +type dataSourceStruct struct { + BackupSource *struct { + BackupStorageName string `json:"backupStorageName"` + Path string `json:"path"` + } `json:"backupSource,omitempty"` + DbClusterBackupName *string `json:"dbClusterBackupName,omitempty"` //nolint:stylecheck + Pitr *struct { + Date *string `json:"date,omitempty"` + Type *string `json:"type,omitempty"` + } `json:"pitr,omitempty"` +} diff --git a/api/validation_test.go b/api/validation_test.go index 6d9728a0..4990f94b 100644 --- a/api/validation_test.go +++ b/api/validation_test.go @@ -15,6 +15,7 @@ package api import ( + "context" "encoding/json" "errors" "testing" @@ -384,7 +385,7 @@ func TestValidateVersion(t *testing.T) { } } -func TestValidateBackupSpec(t *testing.T) { //nolint:dupl +func TestValidateBackupSpec(t *testing.T) { t.Parallel() cases := []struct { name string @@ -439,7 +440,79 @@ func TestValidateBackupSpec(t *testing.T) { //nolint:dupl } } -func TestValidatePitrSpec(t *testing.T) { //nolint:dupl +func TestValidateBackupStoragesFor(t *testing.T) { + t.Parallel() + cases := []struct { + name string + cluster []byte + storage []byte + err error + }{ + { + name: "errPSMDBMultipleStorages", + cluster: []byte(`{"spec": {"backup": {"enabled": true, "schedules": [{"enabled": true, "name": "name", "backupStorageName": "storage1"}, {"enabled": true, "name": "name2", "backupStorageName": "storage2"}]}, "engine": {"type": "psmdb"}}}`), + storage: []byte(`{"spec": {"type": "s3"}}`), + err: errPSMDBMultipleStorages, + }, + { + name: "errPSMDBViolateActiveStorage", + cluster: []byte(`{"status": {"activeStorage": "storage1"}, "spec": {"backup": {"enabled": true, "schedules": [{"enabled": true, "name": "otherName", "backupStorageName": "storage2"}]}, "engine": {"type": "psmdb"}}}`), + storage: []byte(`{"spec": {"type": "s3"}}`), + err: errPSMDBViolateActiveStorage, + }, + { + name: "no errPSMDBViolateActiveStorage", + cluster: []byte(`{"status": {"activeStorage": ""}, "spec": {"backup": {"enabled": true, "schedules": [{"enabled": true, "name": "otherName", "backupStorageName": "storage2"}]}, "engine": {"type": "psmdb"}}}`), + storage: []byte(`{"spec": {"type": "s3"}}`), + err: nil, + }, + { + name: "errPXCPitrS3Only", + cluster: []byte(`{"status":{},"spec": {"backup": {"enabled": true, "pitr": {"enabled": true, "backupStorageName": "storage"}, "schedules": [{"enabled": true, "name": "otherName", "backupStorageName": "storage"}]}, "engine": {"type": "pxc"}}}`), + storage: []byte(`{"spec": {"type": "azure"}}`), + err: errPXCPitrS3Only, + }, + { + name: "errPitrNoBackupStorageName", + cluster: []byte(`{"status":{},"spec": {"backup": {"enabled": true, "pitr": {"enabled": true}, "schedules": [{"enabled": true, "name": "otherName", "backupStorageName": "storage"}]}, "engine": {"type": "pxc"}}}`), + storage: []byte(`{"spec": {"type": "s3"}}`), + err: errPitrNoBackupStorageName, + }, + { + name: "valid", + cluster: []byte(`{"status":{},"spec": {"backup": {"enabled": true, "pitr": {"enabled": true, "backupStorageName": "storage2"}, "schedules": [{"enabled": true, "name": "otherName", "backupStorageName": "storage"}]}, "engine": {"type": "pxc"}}}`), + storage: []byte(`{"spec": {"type": "s3"}}`), + err: nil, + }, + } + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + cluster := &DatabaseCluster{} + err := json.Unmarshal(tc.cluster, cluster) + require.NoError(t, err) + + storage := &everestv1alpha1.BackupStorage{} + err = json.Unmarshal(tc.storage, storage) + require.NoError(t, err) + + err = validateBackupStoragesFor( + context.Background(), + cluster, + func(ctx context.Context, s string) (*everestv1alpha1.BackupStorage, error) { return storage, nil }, + ) + if tc.err == nil { + require.NoError(t, err) + return + } + require.Error(t, err) + assert.Equal(t, err.Error(), tc.err.Error()) + }) + } +} + +func TestValidatePitrSpec(t *testing.T) { t.Parallel() cases := []struct { @@ -463,10 +536,20 @@ func TestValidatePitrSpec(t *testing.T) { //nolint:dupl err: nil, }, { - name: "no backup storage", - cluster: []byte(`{"spec": {"backup": {"enabled": true, "pitr": {"enabled": true}}}}`), + name: "no backup storage pxc", + cluster: []byte(`{"spec": {"backup": {"enabled": true, "pitr": {"enabled": true}}, "engine": {"type": "pxc"}}}`), err: errPitrNoBackupStorageName, }, + { + name: "no backup storage psmdb", + cluster: []byte(`{"spec": {"backup": {"enabled": true, "pitr": {"enabled": true}}, "engine": {"type": "psmdb"}}}`), + err: nil, + }, + { + name: "no backup storage pg", + cluster: []byte(`{"spec": {"backup": {"enabled": true, "pitr": {"enabled": true}}, "engine": {"type": "postgresql"}}}`), + err: nil, + }, { name: "zero upload interval", cluster: []byte(`{"spec": {"backup": {"enabled": true, "pitr": {"enabled": true, "backupStorageName": "name", "uploadIntervalSec": 0}}}}`), @@ -490,6 +573,7 @@ func TestValidatePitrSpec(t *testing.T) { //nolint:dupl require.NoError(t, err) return } + require.Error(t, err) assert.Equal(t, err.Error(), tc.err.Error()) }) } @@ -565,6 +649,73 @@ func TestValidateResourceLimits(t *testing.T) { require.NoError(t, err) return } + require.Error(t, err) + assert.Equal(t, err.Error(), tc.err.Error()) + }) + } +} + +func TestValidateDataSource(t *testing.T) { + t.Parallel() + cases := []struct { + name string + cluster []byte + err error + }{ + { + name: "err none of the data source specified", + cluster: []byte(`{}`), + err: errDataSourceConfig, + }, + { + name: "err both of the data source specified", + cluster: []byte(`{"dbClusterBackupName":"some-backup", "backupSource": {"backupStorageName":"some-name","path":"some-path"}}`), + err: errDataSourceConfig, + }, + { + name: "err no date in pitr", + cluster: []byte(`{"dbClusterBackupName":"some-backup","pitr":{}}`), + err: errDataSourceNoPitrDateSpecified, + }, + { + name: "wrong pitr date format", + cluster: []byte(`{"dbClusterBackupName":"some-backup","pitr":{"date":"2006-06-07 14:06:07"}}`), + err: errDataSourceWrongDateFormat, + }, + { + name: "wrong pitr date format", + cluster: []byte(`{"dbClusterBackupName":"some-backup","pitr":{"date":""}}`), + err: errDataSourceWrongDateFormat, + }, + { + name: "correct minimal", + cluster: []byte(`{"dbClusterBackupName":"some-backup","pitr":{"date":"2006-06-07T14:06:07Z"}}`), + err: nil, + }, + { + name: "correct with pitr type", + cluster: []byte(`{"dbClusterBackupName":"some-backup","pitr":{"type":"date","date":"2006-06-07T14:06:07Z"}}`), + err: nil, + }, + { + name: "unsupported pitr type", + cluster: []byte(`{"backupSource":{"backupStorageName":"some-name","path":"some-path"},"pitr":{"type":"latest"}}`), + err: errUnsupportedPitrType, + }, + } + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + dsDB := &dataSourceStruct{} + err := json.Unmarshal(tc.cluster, dsDB) + require.NoError(t, err) + err = validateDataSource(*dsDB) + if tc.err == nil { + require.NoError(t, err) + return + } + require.Error(t, err) assert.Equal(t, err.Error(), tc.err.Error()) }) } diff --git a/client/everest-client.gen.go b/client/everest-client.gen.go index e40a25a1..431934a0 100644 --- a/client/everest-client.gen.go +++ b/client/everest-client.gen.go @@ -143,7 +143,7 @@ type DatabaseCluster struct { // Pitr PITR is the configuration of the point in time recovery Pitr *struct { // BackupStorageName BackupStorageName is the name of the BackupStorage where the PITR is enabled - BackupStorageName string `json:"backupStorageName"` + BackupStorageName *string `json:"backupStorageName,omitempty"` // Enabled Enabled is a flag to enable PITR Enabled bool `json:"enabled"` @@ -290,6 +290,9 @@ type DatabaseCluster struct { // Status DatabaseClusterStatus defines the observed state of DatabaseCluster. Status *struct { + // ActiveStorage ActiveStorage is the storage used in cluster (psmdb only) + ActiveStorage *string `json:"activeStorage,omitempty"` + // Hostname Hostname is the hostname where the cluster can be reached Hostname *string `json:"hostname,omitempty"` @@ -5868,137 +5871,137 @@ func ParseVersionInfoResponse(rsp *http.Response) (*VersionInfoResponse, error) // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/docs/spec/openapi.yml b/docs/spec/openapi.yml index 34c62f8b..509caa16 100644 --- a/docs/spec/openapi.yml +++ b/docs/spec/openapi.yml @@ -1660,7 +1660,6 @@ components: description: UploadIntervalSec number of seconds between the binlogs uploads type: integer required: - - backupStorageName - enabled type: object schedules: @@ -1898,6 +1897,9 @@ components: status: description: DatabaseClusterStatus defines the observed state of DatabaseCluster. properties: + activeStorage: + description: ActiveStorage is the storage used in cluster (psmdb only) + type: string hostname: description: Hostname is the hostname where the cluster can be reached type: string diff --git a/go.mod b/go.mod index 8d9d8a19..c4396a80 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,10 @@ require ( github.com/labstack/echo/v4 v4.11.3 github.com/oapi-codegen/echo-middleware v1.0.1 github.com/oapi-codegen/runtime v1.1.0 - github.com/percona/everest-operator v0.6.0-dev1.0.20231228161448-9554994bae64 + github.com/percona/everest-operator v0.6.0-dev1.0.20240125150540-298621412982 github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.16.0 + golang.org/x/crypto v0.17.0 k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 k8s.io/cli-runtime v0.29.0 @@ -32,6 +32,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.7.0 // indirect github.com/flosch/pongo2/v6 v6.0.0 // indirect github.com/go-errors/errors v1.5.0 // indirect github.com/go-ini/ini v1.67.0 // indirect @@ -75,13 +76,14 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901 // indirect - github.com/percona/percona-postgresql-operator v0.0.0-20230629061704-21f8d7d89b98 // indirect + github.com/percona/percona-postgresql-operator v0.0.0-20231220140959-ad5eef722609 // indirect github.com/percona/percona-server-mongodb-operator v1.15.0 // indirect github.com/percona/percona-xtradb-cluster-operator v1.13.0 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/ugorji/go/codec v1.2.12 // indirect @@ -93,6 +95,8 @@ require ( github.com/xlab/treeprint v1.2.0 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect go.mongodb.org/mongo-driver v1.12.1 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.13.0 // indirect @@ -116,5 +120,5 @@ require ( sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/mcs-api v0.1.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 5799b134..787cab16 100644 --- a/go.sum +++ b/go.sum @@ -108,8 +108,8 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= +github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU= github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU= @@ -135,6 +135,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= @@ -420,12 +422,12 @@ github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8P github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/percona/everest-operator v0.6.0-dev1.0.20231228161448-9554994bae64 h1:b7out0+6TFYcVwRCwdbVOhuljt6UMiyAx83dwaXQ/eY= -github.com/percona/everest-operator v0.6.0-dev1.0.20231228161448-9554994bae64/go.mod h1:ZO6jpaEcsJLoCRXAu53sZB/HQKaHEOe7o2jEKKg6YWc= +github.com/percona/everest-operator v0.6.0-dev1.0.20240125150540-298621412982 h1:rb3XM3Ce544WoX1Z41E7R0sL4KFEuidn0fYRhHen6Lg= +github.com/percona/everest-operator v0.6.0-dev1.0.20240125150540-298621412982/go.mod h1:o84NcJlAImYMpKK9+PIjS4V8SSREt1uZOqNhHt5qXMg= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901 h1:BDgsZRCjEuxl2/z4yWBqB0s8d20shuIDks7/RVdZiLs= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901/go.mod h1:fZRCMpUqkWlLVdRKqqaj001LoVP2eo6F0ZhoMPeXDng= -github.com/percona/percona-postgresql-operator v0.0.0-20230629061704-21f8d7d89b98 h1:TBc6YKTrJm8rg1Z43vXLMniyi7hwMZqBaGdKN/fbXLI= -github.com/percona/percona-postgresql-operator v0.0.0-20230629061704-21f8d7d89b98/go.mod h1:Wbw7DyZtHKWJpy2kELRuRTlG9dW0CVAn8faT7POBjC4= +github.com/percona/percona-postgresql-operator v0.0.0-20231220140959-ad5eef722609 h1:+UOK4gcHrRgqjo4smgfwT7/0apF6PhAJdQIdAV4ub/M= +github.com/percona/percona-postgresql-operator v0.0.0-20231220140959-ad5eef722609/go.mod h1:znzhtSTF6moUOGNPzVpgfFEMaqIe/ijTSHY8BNDkiEA= github.com/percona/percona-server-mongodb-operator v1.15.0 h1:pcP9GMi9f05VFi8e/TQifBrR+cvOkYMiv1xAftkESBs= github.com/percona/percona-server-mongodb-operator v1.15.0/go.mod h1:D4HOWd6TXRg3kfJ3sgm1LkbMe0QheueGtGCyiUflwlE= github.com/percona/percona-xtradb-cluster-operator v1.13.0 h1:KhXkjK3hRCLdEtbcuc9ynKiY7fJ1IxRqZTLgd6R6xz0= @@ -479,6 +481,8 @@ github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NF 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= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -554,6 +558,14 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -579,9 +591,11 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -778,8 +792,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -843,5 +857,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+s sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/kubernetes/monitoring_config.go b/pkg/kubernetes/monitoring_config.go index 2d7d5b62..ee0faa28 100644 --- a/pkg/kubernetes/monitoring_config.go +++ b/pkg/kubernetes/monitoring_config.go @@ -21,6 +21,7 @@ import ( "errors" everestv1alpha1 "github.com/percona/everest-operator/api/v1alpha1" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -87,6 +88,9 @@ func (k *Kubernetes) IsMonitoringConfigUsed(ctx context.Context, monitoringConfi func (k *Kubernetes) isMonitoringConfigUsedByVMAgent(ctx context.Context, name string) (bool, error) { vmAgents, err := k.ListVMAgents() if err != nil { + if errors.Is(err, &meta.NoKindMatchError{}) { + return false, nil + } return false, errors.Join(err, errors.New("could not list VM agents in Kubernetes")) } secretNames := make([]string, 0, len(vmAgents.Items))