From 4cc93527a9224032c7074ced61ea869f08be5c62 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Thu, 2 Nov 2023 23:38:13 +0530 Subject: [PATCH] fixing oldDB status issue --- api/v1/databaseclaim_types.go | 28 ++++- api/v1/zz_generated.deepcopy.go | 26 ++++- ...nce.atlas.infoblox.com_databaseclaims.yaml | 102 +----------------- controllers/databaseclaim_controller.go | 17 ++- controllers/databaseclaim_controller_test.go | 87 ++++++++++++++- ...nce.atlas.infoblox.com_databaseclaims.yaml | 102 +----------------- 6 files changed, 144 insertions(+), 218 deletions(-) diff --git a/api/v1/databaseclaim_types.go b/api/v1/databaseclaim_types.go index 6820f088..7e752b79 100644 --- a/api/v1/databaseclaim_types.go +++ b/api/v1/databaseclaim_types.go @@ -222,7 +222,30 @@ type DatabaseClaimStatus struct { //non empty denotes migration in progress, unless it is S_Completed MigrationState string `json:"migrationState,omitempty"` // tracks the DB which is migrated and not more operational - OldDB Status `json:"oldDB,omitempty"` + OldDB StatusForOldDB `json:"oldDB,omitempty"` +} + +type StatusForOldDB struct { + // Time the connection info was updated/created. + ConnectionInfo *DatabaseClaimConnectionInfo `json:"connectionInfo,omitempty"` + + // Version of the provisioned Database + DBVersion string `json:"dbversion,omitempty"` + + // The optional Shape values are arbitrary and help drive instance selection + Shape string `json:"shape,omitempty"` + + // Specifies the type of database to provision. Only postgres is supported. + Type DatabaseType `json:"type,omitempty"` + + // Time at the process of post migration actions initiated + PostMigrationActionStartedAt *metav1.Time `json:"postMigrationActionStartedAt,omitempty"` + + // DbState of the DB. inprogress, "", ready + DbState DbState `json:"DbState,omitempty"` + + // The optional MinStorageGB value requests the minimum database host storage capacity in GBytes + MinStorageGB int `json:"minStorageGB,omitempty"` } type Status struct { @@ -260,9 +283,6 @@ type Status struct { // This field used when claim is use-existing-db and attempting to migrate to newdb // +optional SourceDataFrom *SourceDataFrom `json:"sourceDataFrom,omitempty"` - - // Time at the process of post migration actions initiated - PostMigrationActionStartedAt *metav1.Time `json:"postMigrationActionStartedAt,omitempty"` } // DbState keeps track of state of the DB. diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 67a28a81..99fb3994 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -404,18 +404,38 @@ func (in *Status) DeepCopyInto(out *Status) { *out = new(SourceDataFrom) (*in).DeepCopyInto(*out) } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. +func (in *Status) DeepCopy() *Status { + if in == nil { + return nil + } + out := new(Status) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatusForOldDB) DeepCopyInto(out *StatusForOldDB) { + *out = *in + if in.ConnectionInfo != nil { + in, out := &in.ConnectionInfo, &out.ConnectionInfo + *out = new(DatabaseClaimConnectionInfo) + **out = **in + } if in.PostMigrationActionStartedAt != nil { in, out := &in.PostMigrationActionStartedAt, &out.PostMigrationActionStartedAt *out = (*in).DeepCopy() } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. -func (in *Status) DeepCopy() *Status { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusForOldDB. +func (in *StatusForOldDB) DeepCopy() *StatusForOldDB { if in == nil { return nil } - out := new(Status) + out := new(StatusForOldDB) in.DeepCopyInto(out) return out } diff --git a/config/crd/bases/persistance.atlas.infoblox.com_databaseclaims.yaml b/config/crd/bases/persistance.atlas.infoblox.com_databaseclaims.yaml index 7160c0b6..7f41fcc3 100644 --- a/config/crd/bases/persistance.atlas.infoblox.com_databaseclaims.yaml +++ b/config/crd/bases/persistance.atlas.infoblox.com_databaseclaims.yaml @@ -276,10 +276,6 @@ spec: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes type: integer - postMigrationActionStartedAt: - description: Time at the process of post migration actions initiated - format: date-time - type: string shape: description: The optional Shape values are arbitrary and help drive instance selection @@ -417,10 +413,6 @@ spec: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes type: integer - postMigrationActionStartedAt: - description: Time at the process of post migration actions initiated - format: date-time - type: string shape: description: The optional Shape values are arbitrary and help drive instance selection @@ -518,6 +510,7 @@ spec: description: DbState of the DB. inprogress, "", ready type: string connectionInfo: + description: Time the connection info was updated/created. properties: databaseName: type: string @@ -532,21 +525,9 @@ spec: userName: type: string type: object - connectionUpdatedAt: - description: Time the connection info was updated/created. - format: date-time - type: string - dbCreateAt: - description: Time the database was created - format: date-time - type: string dbversion: description: Version of the provisioned Database type: string - matchLabel: - description: The name of the label that was successfully matched - against the fragment key names in the db-controller configMap - type: string minStorageGB: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes @@ -559,91 +540,10 @@ spec: description: The optional Shape values are arbitrary and help drive instance selection type: string - sourceDataFrom: - description: SourceDataFrom specifies an existing database or - backup to use when initially provisioning the database. if the - dbclaim has already provisioned a database, this field is ignored - This field used when claim is use-existing-db and attempting - to migrate to newdb - properties: - database: - description: Database defines the connection information to - an existing db - properties: - dsn: - description: 'DSN is the connection string used to reach - the postgres database must have protocol specifier at - beginning (example: mysql:// postgres:// )' - type: string - secretRef: - description: 'SecretRef specifies a secret to use for - connecting to the postgresdb (should be master/root) - TODO: document/validate the secret format required' - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - required: - - dsn - type: object - s3: - description: S3 defines the location of a DB backup in an - S3 bucket - properties: - bucket: - type: string - prefix: - description: Prefix is the path prefix of the S3 bucket - within which the backup to restore is located. - type: string - region: - type: string - secretRef: - description: 'SecretRef specifies a secret to use for - connecting to the s3 bucket via AWS client TODO: document/validate - the secret format required' - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - sourceEngine: - description: SourceEngine is the engine used to create - the backup. - type: string - sourceEngineVersion: - description: 'SourceEngineVersion is the version of the - engine used to create the backup. Example: "5.7.30"' - type: string - required: - - bucket - - region - - sourceEngine - - sourceEngineVersion - type: object - type: - description: Type specifies the type of source - type: string - required: - - type - type: object type: description: Specifies the type of database to provision. Only postgres is supported. type: string - userUpdatedAt: - description: Time the user/password was updated/created - format: date-time - type: string - required: - - connectionInfo type: object type: object type: object diff --git a/controllers/databaseclaim_controller.go b/controllers/databaseclaim_controller.go index e4866bcc..b1569ed6 100644 --- a/controllers/databaseclaim_controller.go +++ b/controllers/databaseclaim_controller.go @@ -443,7 +443,7 @@ func (r *DatabaseClaimReconciler) updateStatus(ctx context.Context, dbClaim *per return r.manageError(ctx, dbClaim, err) } else if !canTag { logr.Info("Skipping post migration actions due to DB being used by other entities") - dbClaim.Status.OldDB = persistancev1.Status{} + dbClaim.Status.OldDB = persistancev1.StatusForOldDB{} return r.manageSuccess(ctx, dbClaim) } @@ -475,7 +475,7 @@ func (r *DatabaseClaimReconciler) updateStatus(ctx context.Context, dbClaim *per logr.Error(err, "Could not delete crossplane DBParamGroup/DBClusterParamGroup") } - dbClaim.Status.OldDB = persistancev1.Status{} + dbClaim.Status.OldDB = persistancev1.StatusForOldDB{} } else if time.Since(dbClaim.Status.OldDB.PostMigrationActionStartedAt.Time).Minutes() > 5 { // Lets keep the state of old as it is for defined time to wait and verify tags before actually deleting resources logr.Info("defined wait time is over to verify operational tags on AWS resources. Moving ahead to delete associated crossplane resources anyway") @@ -487,7 +487,7 @@ func (r *DatabaseClaimReconciler) updateStatus(ctx context.Context, dbClaim *per logr.Error(err, "Could not delete crossplane DBParamGroup/DBClusterParamGroup") } - dbClaim.Status.OldDB = persistancev1.Status{} + dbClaim.Status.OldDB = persistancev1.StatusForOldDB{} } return r.manageSuccess(ctx, dbClaim) @@ -845,7 +845,9 @@ loop: timenow := metav1.Now() - dbClaim.Status.OldDB = *dbClaim.Status.ActiveDB.DeepCopy() + dbClaim.Status.OldDB = persistancev1.StatusForOldDB{ConnectionInfo: &persistancev1.DatabaseClaimConnectionInfo{}} + //dbClaim.Status.OldDB = *dbClaim.Status.ActiveDB.DeepCopy() + MakeDeepCopyToOldDB(&dbClaim.Status.OldDB, &dbClaim.Status.ActiveDB) dbClaim.Status.OldDB.DbState = persistancev1.PostMigrationInProgress dbClaim.Status.OldDB.PostMigrationActionStartedAt = &timenow @@ -869,6 +871,13 @@ loop: return r.manageSuccess(ctx, dbClaim) } +func MakeDeepCopyToOldDB(to *persistancev1.StatusForOldDB, from *persistancev1.Status) { + to.ConnectionInfo = from.ConnectionInfo.DeepCopy() + to.DBVersion = from.DBVersion + to.Shape = from.Shape + to.Type = from.Type +} + func (r *DatabaseClaimReconciler) operationalTaggingForDbParamGroup(ctx context.Context, logr logr.Logger, dbParamGroupName string) { dbParameterGroup := &crossplanerds.DBParameterGroup{} diff --git a/controllers/databaseclaim_controller_test.go b/controllers/databaseclaim_controller_test.go index b39c18aa..4cb4f90d 100644 --- a/controllers/databaseclaim_controller_test.go +++ b/controllers/databaseclaim_controller_test.go @@ -1726,7 +1726,7 @@ func TestDatabaseClaimReconciler_getMode(t *testing.T) { ActiveDB: persistancev1.Status{ DbState: persistancev1.Ready, }, - OldDB: persistancev1.Status{ + OldDB: persistancev1.StatusForOldDB{ DbState: persistancev1.PostMigrationInProgress, Type: "aurora-postgres", DBVersion: "13.11", @@ -1766,7 +1766,7 @@ func TestDatabaseClaimReconciler_getMode(t *testing.T) { ActiveDB: persistancev1.Status{ DbState: persistancev1.Ready, }, - OldDB: persistancev1.Status{ + OldDB: persistancev1.StatusForOldDB{ DbState: persistancev1.PostMigrationInProgress, Type: "aurora-postgres", DBVersion: "13.11", @@ -1805,7 +1805,7 @@ func TestDatabaseClaimReconciler_getMode(t *testing.T) { ActiveDB: persistancev1.Status{ DbState: persistancev1.Ready, }, - OldDB: persistancev1.Status{ + OldDB: persistancev1.StatusForOldDB{ DbState: persistancev1.PostMigrationInProgress, Type: "aurora-postgres", DBVersion: "13.11", @@ -1845,7 +1845,7 @@ func TestDatabaseClaimReconciler_getMode(t *testing.T) { ActiveDB: persistancev1.Status{ DbState: persistancev1.Ready, }, - OldDB: persistancev1.Status{ + OldDB: persistancev1.StatusForOldDB{ DbState: persistancev1.PostMigrationInProgress, Type: "aurora-postgres", DBVersion: "13.11", @@ -1884,7 +1884,7 @@ func TestDatabaseClaimReconciler_getMode(t *testing.T) { ActiveDB: persistancev1.Status{ DbState: persistancev1.Ready, }, - OldDB: persistancev1.Status{ + OldDB: persistancev1.StatusForOldDB{ DbState: persistancev1.PostMigrationInProgress, Type: "aurora-postgres", DBVersion: "13.11", @@ -1979,6 +1979,83 @@ func TestDatabaseClaimReconciler_BackupPolicy(t *testing.T) { } } +func TestMakeDeepCopyToOldDB(t *testing.T) { + testSuite := []struct { + inputStatus *persistancev1.Status + expectedOldDbStatus *persistancev1.StatusForOldDB + }{ + { + inputStatus: &persistancev1.Status{ + ConnectionInfo: nil, + DBVersion: "v1", + Shape: "t2", + DbState: "ready", + Type: "11", + MinStorageGB: 0, + }, + expectedOldDbStatus: &persistancev1.StatusForOldDB{ + ConnectionInfo: nil, + DBVersion: "v1", + Shape: "t2", + Type: "11", + DbState: "ready", + MinStorageGB: 0, + }, + }, + { + inputStatus: &persistancev1.Status{ + ConnectionInfo: &persistancev1.DatabaseClaimConnectionInfo{}, + DBVersion: "v1", + Shape: "t2", + DbState: "ready", + Type: "11", + MinStorageGB: 0, + }, + expectedOldDbStatus: &persistancev1.StatusForOldDB{ + ConnectionInfo: &persistancev1.DatabaseClaimConnectionInfo{}, + DBVersion: "v1", + Shape: "t2", + Type: "11", + DbState: "ready", + MinStorageGB: 0, + }, + }, + { + inputStatus: &persistancev1.Status{ + ConnectionInfo: &persistancev1.DatabaseClaimConnectionInfo{ + Host: "host1", + }, + DBVersion: "v1", + Shape: "t2", + DbState: "ready", + Type: "11", + MinStorageGB: 0, + }, + expectedOldDbStatus: &persistancev1.StatusForOldDB{ + ConnectionInfo: &persistancev1.DatabaseClaimConnectionInfo{ + Host: "host1", + }, + DBVersion: "v1", + Shape: "t2", + Type: "11", + DbState: "ready", + MinStorageGB: 0, + }, + }, + } + + for _, test := range testSuite { + out := &persistancev1.StatusForOldDB{} + MakeDeepCopyToOldDB(out, test.inputStatus) + + assert.Equal(t, test.expectedOldDbStatus.DBVersion, out.DBVersion) + assert.Equal(t, test.expectedOldDbStatus.Shape, out.Shape) + assert.Equal(t, test.expectedOldDbStatus.Type, out.Type) + assert.Equal(t, test.expectedOldDbStatus.MinStorageGB, out.MinStorageGB) + assert.Equal(t, test.expectedOldDbStatus.ConnectionInfo, out.ConnectionInfo) + } +} + func Test_generateMasterPassword(t *testing.T) { tests := []struct { name string diff --git a/helm/db-controller-crds/crd/persistance.atlas.infoblox.com_databaseclaims.yaml b/helm/db-controller-crds/crd/persistance.atlas.infoblox.com_databaseclaims.yaml index 7160c0b6..7f41fcc3 100644 --- a/helm/db-controller-crds/crd/persistance.atlas.infoblox.com_databaseclaims.yaml +++ b/helm/db-controller-crds/crd/persistance.atlas.infoblox.com_databaseclaims.yaml @@ -276,10 +276,6 @@ spec: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes type: integer - postMigrationActionStartedAt: - description: Time at the process of post migration actions initiated - format: date-time - type: string shape: description: The optional Shape values are arbitrary and help drive instance selection @@ -417,10 +413,6 @@ spec: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes type: integer - postMigrationActionStartedAt: - description: Time at the process of post migration actions initiated - format: date-time - type: string shape: description: The optional Shape values are arbitrary and help drive instance selection @@ -518,6 +510,7 @@ spec: description: DbState of the DB. inprogress, "", ready type: string connectionInfo: + description: Time the connection info was updated/created. properties: databaseName: type: string @@ -532,21 +525,9 @@ spec: userName: type: string type: object - connectionUpdatedAt: - description: Time the connection info was updated/created. - format: date-time - type: string - dbCreateAt: - description: Time the database was created - format: date-time - type: string dbversion: description: Version of the provisioned Database type: string - matchLabel: - description: The name of the label that was successfully matched - against the fragment key names in the db-controller configMap - type: string minStorageGB: description: The optional MinStorageGB value requests the minimum database host storage capacity in GBytes @@ -559,91 +540,10 @@ spec: description: The optional Shape values are arbitrary and help drive instance selection type: string - sourceDataFrom: - description: SourceDataFrom specifies an existing database or - backup to use when initially provisioning the database. if the - dbclaim has already provisioned a database, this field is ignored - This field used when claim is use-existing-db and attempting - to migrate to newdb - properties: - database: - description: Database defines the connection information to - an existing db - properties: - dsn: - description: 'DSN is the connection string used to reach - the postgres database must have protocol specifier at - beginning (example: mysql:// postgres:// )' - type: string - secretRef: - description: 'SecretRef specifies a secret to use for - connecting to the postgresdb (should be master/root) - TODO: document/validate the secret format required' - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - required: - - dsn - type: object - s3: - description: S3 defines the location of a DB backup in an - S3 bucket - properties: - bucket: - type: string - prefix: - description: Prefix is the path prefix of the S3 bucket - within which the backup to restore is located. - type: string - region: - type: string - secretRef: - description: 'SecretRef specifies a secret to use for - connecting to the s3 bucket via AWS client TODO: document/validate - the secret format required' - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - sourceEngine: - description: SourceEngine is the engine used to create - the backup. - type: string - sourceEngineVersion: - description: 'SourceEngineVersion is the version of the - engine used to create the backup. Example: "5.7.30"' - type: string - required: - - bucket - - region - - sourceEngine - - sourceEngineVersion - type: object - type: - description: Type specifies the type of source - type: string - required: - - type - type: object type: description: Specifies the type of database to provision. Only postgres is supported. type: string - userUpdatedAt: - description: Time the user/password was updated/created - format: date-time - type: string - required: - - connectionInfo type: object type: object type: object