From 5ae50850806eb90305d3d97f6dd7b53e4431b182 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 10 Jul 2023 16:09:07 +0100 Subject: [PATCH 01/60] Resource tagging feature for deployment added without limitations and testing --- pkg/api/v1/atlasdeployment_types.go | 35 +++++++++++--- pkg/api/v1/zz_generated.deepcopy.go | 48 +++++++++++++++++++ .../atlasdeployment_controller.go | 3 +- pkg/controller/atlasdeployment/deployment.go | 1 + 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index 856329681f..aaebbd0e4d 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -119,6 +119,11 @@ type DeploymentSpec struct { // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9-]*$ Name string `json:"name"` + // Custom resource for categorizing deployments. + // +kubebuilder:validation:MaxItems=50 + // +optional + Tags []*TagSpec `json:"tags,omitempty"` + // Positive integer that specifies the number of shards to deploy for a sharded deployment. // The parameter is required if replicationSpecs are configured // +kubebuilder:validation:Minimum=1 @@ -163,12 +168,16 @@ type AdvancedDeploymentSpec struct { // After Atlas creates the deployment, you can't change its name. // Can only contain ASCII letters, numbers, and hyphens. // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9-]*$ - Name string `json:"name,omitempty"` - Paused *bool `json:"paused,omitempty"` - PitEnabled *bool `json:"pitEnabled,omitempty"` - ReplicationSpecs []*AdvancedReplicationSpec `json:"replicationSpecs,omitempty"` - RootCertType string `json:"rootCertType,omitempty"` - VersionReleaseSystem string `json:"versionReleaseSystem,omitempty"` + Name string `json:"name,omitempty"` + Paused *bool `json:"paused,omitempty"` + PitEnabled *bool `json:"pitEnabled,omitempty"` + ReplicationSpecs []*AdvancedReplicationSpec `json:"replicationSpecs,omitempty"` + RootCertType string `json:"rootCertType,omitempty"` + // Custom resource for categorizing deployments. + // +kubebuilder:validation:MaxItems=50 + // +optional + Tags []*TagSpec `json:"tags,omitempty"` + VersionReleaseSystem string `json:"versionReleaseSystem,omitempty"` // +optional CustomZoneMapping []CustomZoneMapping `json:"customZoneMapping,omitempty"` // +optional @@ -204,6 +213,10 @@ type ServerlessSpec struct { // Can only contain ASCII letters, numbers, and hyphens. // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9-]*$ Name string `json:"name"` + // Key-value pairs for resource tagging. + // +kubebuilder:validation:MaxItems=50 + // +optional + Tags []*TagSpec `json:"tags,omitempty"` // Configuration for the provisioned hosts on which MongoDB runs. The available options are specific to the cloud service provider. ProviderSettings *ProviderSettingsSpec `json:"providerSettings"` @@ -216,6 +229,16 @@ type BiConnector struct { ReadPreference string `json:"readPreference,omitempty"` } +// TagSpec holds a key-value pair for resource tagging on this deployment. +type TagSpec struct { + // +kubebuilder:validation:MaxLength:=255 + // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9@_.+-]*$ + Key string `json:"key,omitempty"` + // +kubebuilder:validation:MaxLength:=255 + // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9@_.+-]*$ + Value string `json:"value,omitempty"` +} + // ConnectionStrings configuration for applications use to connect to this deployment. type ConnectionStrings struct { Standard string `json:"standard,omitempty"` diff --git a/pkg/api/v1/zz_generated.deepcopy.go b/pkg/api/v1/zz_generated.deepcopy.go index e9496821a6..b67c4a2ff8 100644 --- a/pkg/api/v1/zz_generated.deepcopy.go +++ b/pkg/api/v1/zz_generated.deepcopy.go @@ -125,6 +125,17 @@ func (in *AdvancedDeploymentSpec) DeepCopyInto(out *AdvancedDeploymentSpec) { } } } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]*TagSpec, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(TagSpec) + **out = **in + } + } + } if in.CustomZoneMapping != nil { in, out := &in.CustomZoneMapping, &out.CustomZoneMapping *out = make([]CustomZoneMapping, len(*in)) @@ -1381,6 +1392,17 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = make([]common.LabelSpec, len(*in)) copy(*out, *in) } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]*TagSpec, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(TagSpec) + **out = **in + } + } + } if in.NumShards != nil { in, out := &in.NumShards, &out.NumShards *out = new(int) @@ -1975,6 +1997,17 @@ func (in *ServerlessPrivateEndpoint) DeepCopy() *ServerlessPrivateEndpoint { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerlessSpec) DeepCopyInto(out *ServerlessSpec) { *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]*TagSpec, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(TagSpec) + **out = **in + } + } + } if in.ProviderSettings != nil { in, out := &in.ProviderSettings, &out.ProviderSettings *out = new(ProviderSettingsSpec) @@ -2071,6 +2104,21 @@ func (in *Store) DeepCopy() *Store { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TagSpec) DeepCopyInto(out *TagSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TagSpec. +func (in *TagSpec) DeepCopy() *TagSpec { + if in == nil { + return nil + } + out := new(TagSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Team) DeepCopyInto(out *Team) { *out = *in diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 063dcf64a0..255c985b71 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -88,6 +88,8 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. return result.ReconcileResult(), nil } + log.Infow(fmt.Sprintf("--->>> DEBUG --->>> Tags: %v >>>>>", deployment.Spec.DeploymentSpec.Tags)) + if shouldSkip := customresource.ReconciliationShouldBeSkipped(deployment); shouldSkip { log.Infow(fmt.Sprintf("-> Skipping AtlasDeployment reconciliation as annotation %s=%s", customresource.ReconciliationPolicyAnnotation, customresource.ReconciliationPolicySkip), "spec", deployment.Spec) if !deployment.GetDeletionTimestamp().IsZero() { @@ -203,7 +205,6 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. return result.ReconcileResult(), nil } } - return workflow.OK().ReconcileResult(), nil } diff --git a/pkg/controller/atlasdeployment/deployment.go b/pkg/controller/atlasdeployment/deployment.go index 1e0222eeee..8fba14136f 100644 --- a/pkg/controller/atlasdeployment/deployment.go +++ b/pkg/controller/atlasdeployment/deployment.go @@ -28,6 +28,7 @@ func ConvertLegacyDeployment(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { Labels: legacy.Labels, MongoDBMajorVersion: legacy.MongoDBMajorVersion, Name: legacy.Name, + Tags: legacy.Tags, Paused: legacy.Paused, PitEnabled: legacy.PitEnabled, ReplicationSpecs: replicationSpecs, From cdf940b248382208f4716db60d7f7b96d6760170 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 17 Jul 2023 10:39:10 +0100 Subject: [PATCH 02/60] Adding support for tagging Serverless instance and applying key-value limitations, including function 'uniqueKey' --- pkg/api/v1/atlasdeployment_types.go | 22 ++++++++++----- .../atlasdeployment_controller.go | 28 +++++++++++++++++-- .../atlasdeployment/serverless_deployment.go | 5 ++++ 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index aaebbd0e4d..6632394e97 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -213,14 +213,20 @@ type ServerlessSpec struct { // Can only contain ASCII letters, numbers, and hyphens. // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9-]*$ Name string `json:"name"` + // Configuration for the provisioned hosts on which MongoDB runs. The available options are specific to the cloud service provider. + ProviderSettings *ProviderSettingsSpec `json:"providerSettings"` + PrivateEndpoints []ServerlessPrivateEndpoint `json:"privateEndpoints,omitempty"` // Key-value pairs for resource tagging. // +kubebuilder:validation:MaxItems=50 // +optional Tags []*TagSpec `json:"tags,omitempty"` - // Configuration for the provisioned hosts on which MongoDB runs. The available options are specific to the cloud service provider. - ProviderSettings *ProviderSettingsSpec `json:"providerSettings"` +} - PrivateEndpoints []ServerlessPrivateEndpoint `json:"privateEndpoints,omitempty"` +// ServerlessToAtlas converts the ServerlessSpec to native Atlas client Cluster format. +func (s *ServerlessSpec) ServerlessToAtlas() (*mongodbatlas.Cluster, error) { + result := &mongodbatlas.Cluster{} + err := compat.JSONCopy(result, s) + return result, err } // BiConnector specifies BI Connector for Atlas configuration on this deployment. @@ -232,11 +238,13 @@ type BiConnector struct { // TagSpec holds a key-value pair for resource tagging on this deployment. type TagSpec struct { // +kubebuilder:validation:MaxLength:=255 - // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9@_.+-]*$ - Key string `json:"key,omitempty"` + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9 @_.+`;`-]*$ + Key string `json:"key"` // +kubebuilder:validation:MaxLength:=255 - // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9@_.+-]*$ - Value string `json:"value,omitempty"` + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9@_.+`;`-]*$ + Value string `json:"value"` } // ConnectionStrings configuration for applications use to connect to this deployment. diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 255c985b71..239303d108 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -88,8 +88,6 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. return result.ReconcileResult(), nil } - log.Infow(fmt.Sprintf("--->>> DEBUG --->>> Tags: %v >>>>>", deployment.Spec.DeploymentSpec.Tags)) - if shouldSkip := customresource.ReconciliationShouldBeSkipped(deployment); shouldSkip { log.Infow(fmt.Sprintf("-> Skipping AtlasDeployment reconciliation as annotation %s=%s", customresource.ReconciliationPolicyAnnotation, customresource.ReconciliationPolicySkip), "spec", deployment.Spec) if !deployment.GetDeletionTimestamp().IsZero() { @@ -193,6 +191,12 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. deployment.Spec.DeploymentSpec = nil } + if err := uniqueKey(&deployment.Spec); err != nil { + result := workflow.Terminate(workflow.Internal, err.Error()) + log.Errorw("failed to validate tags", "error", err) + return result.ReconcileResult(), nil + } + handleDeployment := r.selectDeploymentHandler(deployment) if result, _ := handleDeployment(ctx, project, deployment, req); !result.IsOk() { ctx.SetConditionFromResult(status.DeploymentReadyType, result) @@ -478,3 +482,23 @@ func (r *AtlasDeploymentReconciler) removeDeletionFinalizer(context context.Cont } type deploymentHandlerFunc func(ctx *workflow.Context, project *mdbv1.AtlasProject, deployment *mdbv1.AtlasDeployment, req reconcile.Request) (workflow.Result, error) + +// Parse through tags and verfiy that all keys are unique. Return error otherwise. +func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { + store := make(map[string]string) + var arrTags []*mdbv1.TagSpec + + if deploymentSpec.AdvancedDeploymentSpec != nil { + arrTags = deploymentSpec.AdvancedDeploymentSpec.Tags + } else { + arrTags = deploymentSpec.ServerlessSpec.Tags + } + for _, currTag := range arrTags { + if store[currTag.Key] == "" { + store[currTag.Key] = currTag.Value + } else { + return errors.New("Duplicate keys found in tags. This is forbidden.") + } + } + return nil +} diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 42dbc6bfaf..9d4be1a313 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -24,6 +24,10 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr return atlasDeployment, workflow.Terminate(workflow.DeploymentNotCreatedInAtlas, err.Error()) } + atlasDeployment, err = serverlessSpec.ServerlessToAtlas() + if err != nil { + return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) + } ctx.Log.Infof("Serverless Instance %s doesn't exist in Atlas - creating", serverlessSpec.Name) atlasDeployment, _, err = ctx.Client.ServerlessInstances.Create(context.Background(), project.Status.ID, &mongodbatlas.ServerlessCreateRequestParams{ Name: serverlessSpec.Name, @@ -32,6 +36,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr ProviderName: string(serverlessSpec.ProviderSettings.ProviderName), RegionName: serverlessSpec.ProviderSettings.RegionName, }, + Tag: atlasDeployment.Tags, }) if err != nil { return atlasDeployment, workflow.Terminate(workflow.DeploymentNotCreatedInAtlas, err.Error()) From 02e5f052395a8069677ff2e3ff503f61d41fd6ae Mon Sep 17 00:00:00 2001 From: cveticm Date: Tue, 18 Jul 2023 11:21:15 +0100 Subject: [PATCH 03/60] Adding updating for serverless and minor changes to comments --- .../atlasdeployment/atlasdeployment_controller.go | 2 +- .../atlasdeployment/serverless_deployment.go | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 239303d108..36427b72b8 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -483,7 +483,7 @@ func (r *AtlasDeploymentReconciler) removeDeletionFinalizer(context context.Cont type deploymentHandlerFunc func(ctx *workflow.Context, project *mdbv1.AtlasProject, deployment *mdbv1.AtlasDeployment, req reconcile.Request) (workflow.Result, error) -// Parse through tags and verfiy that all keys are unique. Return error otherwise. +// Parse through tags and verfiy that all keys are unique. Return error on duplicate key. func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { store := make(map[string]string) var arrTags []*mdbv1.TagSpec diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 9d4be1a313..826c5bb164 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -45,6 +45,17 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr switch atlasDeployment.StateName { case status.StateIDLE: + atlasDeployment, err := serverlessSpec.ServerlessToAtlas() + if err != nil { + return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) + } + atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ + ServerlessBackupOptions: atlasDeployment.ServerlessBackupOptions, + Tag: atlasDeployment.Tags, + }) + if err != nil { + return atlasDeployment, workflow.Terminate(workflow.DeploymentNotUpdatedInAtlas, err.Error()) + } result := ensureServerlessPrivateEndpoints(ctx, project.ID(), serverlessSpec, atlasDeployment.Name) return atlasDeployment, result case status.StateCREATING: From 173db4df7f9866e6553021824b255aef48b2f996 Mon Sep 17 00:00:00 2001 From: cveticm Date: Tue, 18 Jul 2023 11:23:00 +0100 Subject: [PATCH 04/60] Adding resource tagging for deployment tests and removing tags from excluded field in atlasdeployment_type_test --- pkg/api/v1/atlasdeployment_types_test.go | 2 +- test/int/deployment_test.go | 46 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/pkg/api/v1/atlasdeployment_types_test.go b/pkg/api/v1/atlasdeployment_types_test.go index 34655b6237..61c29c1406 100644 --- a/pkg/api/v1/atlasdeployment_types_test.go +++ b/pkg/api/v1/atlasdeployment_types_test.go @@ -55,7 +55,7 @@ func init() { excludedClusterFieldsTheirs["createDate"] = true excludedClusterFieldsTheirs["versionReleaseSystem"] = true excludedClusterFieldsTheirs["serverlessBackupOptions"] = true - excludedClusterFieldsTheirs["tags"] = true + // excludedClusterFieldsTheirs["tags"] = true } func TestCompatibility(t *testing.T) { diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index ab63dbe72a..34df50dd61 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -585,6 +585,31 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { checkAtlasState() }) + // *** + By("Updating the Deployment tags", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + Expect(c.Tags).To(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + }) + }) + + By("Updating the Deployment tags with a duplicate key", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + Expect(c.Tags).NotTo(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + }) + // TODO: revert back + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState() + }) + // *** + By("Updating the Deployment backups settings", func() { createdDeployment.Spec.DeploymentSpec.ProviderBackupEnabled = boolptr(true) performUpdate(20 * time.Minute) @@ -1026,6 +1051,27 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { doServerlessDeploymentStatusChecks() }) + + By("Updating the Instance tags", func() { + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doServerlessDeploymentStatusChecks() + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) + Expect(atlasDeployment.Tags).To(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + }) + + By("Updating the Deployment tags with a duplicate key", func() { + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + performUpdate(20 * time.Minute) + doServerlessDeploymentStatusChecks() + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) + Expect(atlasDeployment.Tags).NotTo(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState() + }) }) }) From 50fc8047a3cac5f07ab391ccb4f02dbb3f491067 Mon Sep 17 00:00:00 2001 From: cveticm Date: Tue, 18 Jul 2023 11:29:50 +0100 Subject: [PATCH 05/60] cleaning comments --- test/int/deployment_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 34df50dd61..ae4b7339d8 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -585,7 +585,6 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { checkAtlasState() }) - // *** By("Updating the Deployment tags", func() { createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} performUpdate(20 * time.Minute) @@ -602,13 +601,11 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { Expect(c.Tags).NotTo(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) }) - // TODO: revert back createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} performUpdate(20 * time.Minute) doDeploymentStatusChecks() checkAtlasState() }) - // *** By("Updating the Deployment backups settings", func() { createdDeployment.Spec.DeploymentSpec.ProviderBackupEnabled = boolptr(true) From c7f12965fb0a3894c3a41346f37f97d03303742a Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Tue, 18 Jul 2023 14:53:49 +0100 Subject: [PATCH 06/60] Update atlasdeployment_controller.go --- pkg/controller/atlasdeployment/atlasdeployment_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 36427b72b8..aaa05c9740 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -497,7 +497,7 @@ func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { if store[currTag.Key] == "" { store[currTag.Key] = currTag.Value } else { - return errors.New("Duplicate keys found in tags. This is forbidden.") + return errors.New("Duplicate keys found in tags. This is forbidden") } } return nil From a632a795206623b80265f48b8ee1d7b5600224fd Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 24 Jul 2023 17:48:15 +0100 Subject: [PATCH 07/60] fix for test --- pkg/api/v1/atlasdeployment_types.go | 4 +- pkg/api/v1/atlasdeployment_types_test.go | 1 - .../atlasdeployment_controller.go | 11 +- test/int/deployment_test.go | 102 +++++------------- 4 files changed, 36 insertions(+), 82 deletions(-) diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index 6632394e97..7267f64b3f 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -119,7 +119,7 @@ type DeploymentSpec struct { // +kubebuilder:validation:Pattern:=^[a-zA-Z0-9][a-zA-Z0-9-]*$ Name string `json:"name"` - // Custom resource for categorizing deployments. + // Key-value pairs for resource tagging. // +kubebuilder:validation:MaxItems=50 // +optional Tags []*TagSpec `json:"tags,omitempty"` @@ -173,7 +173,7 @@ type AdvancedDeploymentSpec struct { PitEnabled *bool `json:"pitEnabled,omitempty"` ReplicationSpecs []*AdvancedReplicationSpec `json:"replicationSpecs,omitempty"` RootCertType string `json:"rootCertType,omitempty"` - // Custom resource for categorizing deployments. + // Key-value pairs for resource tagging. // +kubebuilder:validation:MaxItems=50 // +optional Tags []*TagSpec `json:"tags,omitempty"` diff --git a/pkg/api/v1/atlasdeployment_types_test.go b/pkg/api/v1/atlasdeployment_types_test.go index 61c29c1406..b84947e70e 100644 --- a/pkg/api/v1/atlasdeployment_types_test.go +++ b/pkg/api/v1/atlasdeployment_types_test.go @@ -55,7 +55,6 @@ func init() { excludedClusterFieldsTheirs["createDate"] = true excludedClusterFieldsTheirs["versionReleaseSystem"] = true excludedClusterFieldsTheirs["serverlessBackupOptions"] = true - // excludedClusterFieldsTheirs["tags"] = true } func TestCompatibility(t *testing.T) { diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 36427b72b8..d6bedc91e6 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -191,9 +191,9 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. deployment.Spec.DeploymentSpec = nil } - if err := uniqueKey(&deployment.Spec); err != nil { - result := workflow.Terminate(workflow.Internal, err.Error()) + if result, err := uniqueKey(&deployment.Spec); !result.IsOk() { log.Errorw("failed to validate tags", "error", err) + ctx.SetConditionFromResult(status.DeploymentReadyType, result) return result.ReconcileResult(), nil } @@ -484,7 +484,7 @@ func (r *AtlasDeploymentReconciler) removeDeletionFinalizer(context context.Cont type deploymentHandlerFunc func(ctx *workflow.Context, project *mdbv1.AtlasProject, deployment *mdbv1.AtlasDeployment, req reconcile.Request) (workflow.Result, error) // Parse through tags and verfiy that all keys are unique. Return error on duplicate key. -func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { +func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) (workflow.Result, error) { store := make(map[string]string) var arrTags []*mdbv1.TagSpec @@ -497,8 +497,9 @@ func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { if store[currTag.Key] == "" { store[currTag.Key] = currTag.Value } else { - return errors.New("Duplicate keys found in tags. This is forbidden.") + err := errors.New("duplicate keys found in tags, this is forbidden") + return workflow.Terminate(workflow.Internal, err.Error()), err } } - return nil + return workflow.OK(), nil } diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index ae4b7339d8..a5cbdbd9c5 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "net/http" + "reflect" "strconv" "time" @@ -518,55 +519,9 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create/Update the cluster", func() { - It("Should fail, then be fixed (GCP)", func() { - createdDeployment = mdbv1.DefaultGCPDeployment(namespace.Name, createdProject.Name).WithAtlasName("") + FDescribe("Create/Update the cluster", func() { - By(fmt.Sprintf("Trying to create the Deployment %s with invalid parameters", kube.ObjectKeyFromObject(createdDeployment)), func() { - err := k8sClient.Create(context.Background(), createdDeployment) - Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(MatchRegexp("is invalid: spec.deploymentSpec.name")) - }) - - By("Creating the fixed deployment", func() { - createdDeployment.Spec.DeploymentSpec.Name = "fixed-deployment" - performCreate(createdDeployment, 30*time.Minute) - - doDeploymentStatusChecks() - checkAtlasState() - }) - }) - - It("Should Success (AWS) with enabled autoscaling", func() { - createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) - createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) - createdDeployment.Spec.DeploymentSpec.AutoScaling = &mdbv1.AutoScalingSpec{ - DiskGBEnabled: boolptr(true), - } - - By(fmt.Sprintf("Creating the Deployment %s with autoscaling", kube.ObjectKeyFromObject(createdDeployment)), func() { - performCreate(createdDeployment, 30*time.Minute) - - doDeploymentStatusChecks() - checkAtlasState() - }) - - By("Decreasing the Deployment disk size should not take effect", func() { - // prevDiskSize := *createdDeployment.Spec.DeploymentSpec.DiskSizeGB - createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(14) - performUpdate(30 * time.Minute) - - doDeploymentStatusChecks() - checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { - // Expect(*c.DiskSizeGB).To(BeEquivalentTo(prevDiskSize)) // todo: find out if this should still work for advanced clusters - - // check whether https://github.com/mongodb/go-client-mongodb-atlas/issues/140 is fixed - Expect(c.DiskSizeGB).To(BeAssignableToTypeOf(float64ptr(0)), "DiskSizeGB is no longer a *float64, please check the spec!") - }) - }) - }) - - It("Should Succeed (AWS)", func() { + FIt("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -578,33 +533,24 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { checkAtlasState() }) - By("Updating the Deployment labels", func() { - createdDeployment.Spec.DeploymentSpec.Labels = []common.LabelSpec{{Key: "int-test", Value: "true"}} - performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState() - }) - - By("Updating the Deployment tags", func() { - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { - Expect(c.Tags).To(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) - }) - }) - + // will keep trying to deploy and run into erro. maybe we need to add some Eventually statment?? By("Updating the Deployment tags with a duplicate key", func() { createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) + Eventually(func() bool { + return testutil.CheckCondition( + k8sClient, + createdDeployment, + status. + FalseCondition(status.DeploymentReadyType), + ) + }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) + lastGeneration++ + + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { - Expect(c.Tags).NotTo(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) - }) - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState() }) By("Updating the Deployment backups settings", func() { @@ -1054,7 +1000,11 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate(20 * time.Minute) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) - Expect(atlasDeployment.Tags).To(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeTrue()) + } + //Expect(reflect.DeepEqual(atlasDeployment.Tags, createdDeployment.Spec.ServerlessSpec.Tags)).To(BeTrue()) }) By("Updating the Deployment tags with a duplicate key", func() { @@ -1062,7 +1012,11 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate(20 * time.Minute) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) - Expect(atlasDeployment.Tags).NotTo(Equal(createdDeployment.Spec.DeploymentSpec.Tags)) + for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeFalse()) + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeFalse()) + } + //Expect(reflect.DeepEqual(atlasDeployment.Tags, createdDeployment.Spec.ServerlessSpec.Tags)).To(BeFalse()) createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} performUpdate(20 * time.Minute) From 6bf8b41cd99474c5d87b2eebbb989e754a7717ec Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 24 Jul 2023 18:11:17 +0100 Subject: [PATCH 08/60] Fix --- test/int/deployment_test.go | 99 ++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index a5cbdbd9c5..e0a501444e 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -519,9 +519,55 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create/Update the cluster", func() { + Describe("Create/Update the cluster", func() { + It("Should fail, then be fixed (GCP)", func() { + createdDeployment = mdbv1.DefaultGCPDeployment(namespace.Name, createdProject.Name).WithAtlasName("") + + By(fmt.Sprintf("Trying to create the Deployment %s with invalid parameters", kube.ObjectKeyFromObject(createdDeployment)), func() { + err := k8sClient.Create(context.Background(), createdDeployment) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(MatchRegexp("is invalid: spec.deploymentSpec.name")) + }) + + By("Creating the fixed deployment", func() { + createdDeployment.Spec.DeploymentSpec.Name = "fixed-deployment" + performCreate(createdDeployment, 30*time.Minute) + + doDeploymentStatusChecks() + checkAtlasState() + }) + }) + + It("Should Success (AWS) with enabled autoscaling", func() { + createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) + createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) + createdDeployment.Spec.DeploymentSpec.AutoScaling = &mdbv1.AutoScalingSpec{ + DiskGBEnabled: boolptr(true), + } + + By(fmt.Sprintf("Creating the Deployment %s with autoscaling", kube.ObjectKeyFromObject(createdDeployment)), func() { + performCreate(createdDeployment, 30*time.Minute) + + doDeploymentStatusChecks() + checkAtlasState() + }) + + By("Decreasing the Deployment disk size should not take effect", func() { + // prevDiskSize := *createdDeployment.Spec.DeploymentSpec.DiskSizeGB + createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(14) + performUpdate(30 * time.Minute) + + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + // Expect(*c.DiskSizeGB).To(BeEquivalentTo(prevDiskSize)) // todo: find out if this should still work for advanced clusters + + // check whether https://github.com/mongodb/go-client-mongodb-atlas/issues/140 is fixed + Expect(c.DiskSizeGB).To(BeAssignableToTypeOf(float64ptr(0)), "DiskSizeGB is no longer a *float64, please check the spec!") + }) + }) + }) - FIt("Should Succeed (AWS)", func() { + It("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -533,7 +579,25 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { checkAtlasState() }) - // will keep trying to deploy and run into erro. maybe we need to add some Eventually statment?? + By("Updating the Deployment labels", func() { + createdDeployment.Spec.DeploymentSpec.Labels = []common.LabelSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState() + }) + + By("Updating the Deployment tags", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { + Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) + } + }) + }) + By("Updating the Deployment tags with a duplicate key", func() { createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} Eventually(func(g Gomega) { @@ -548,7 +612,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { ) }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) lastGeneration++ - + // Removing tags for next tests createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} performUpdate(20 * time.Minute) }) @@ -1004,24 +1068,25 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeTrue()) Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeTrue()) } - //Expect(reflect.DeepEqual(atlasDeployment.Tags, createdDeployment.Spec.ServerlessSpec.Tags)).To(BeTrue()) }) By("Updating the Deployment tags with a duplicate key", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) + Eventually(func() bool { + return testutil.CheckCondition( + k8sClient, + createdDeployment, + status. + FalseCondition(status.DeploymentReadyType), + ) + }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) + lastGeneration++ + // Removing tags for next tests + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} performUpdate(20 * time.Minute) - doServerlessDeploymentStatusChecks() - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) - for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeFalse()) - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeFalse()) - } - //Expect(reflect.DeepEqual(atlasDeployment.Tags, createdDeployment.Spec.ServerlessSpec.Tags)).To(BeFalse()) - - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState() }) }) }) From d47a04eef5552fd6d2eb58ce250ccb9696df8158 Mon Sep 17 00:00:00 2001 From: cveticm Date: Tue, 25 Jul 2023 15:49:00 +0100 Subject: [PATCH 09/60] Test issue --- test/int/deployment_test.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index e0a501444e..59d0ea6fd4 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1049,19 +1049,30 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { performCreate(createdDeployment, 30*time.Minute) - + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) + fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment.Status, atlasDeployment.StateName) + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) + g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) + s := []byte(fmt.Sprintf("CREATEDEPLOYMENT NOW : %v ATLASDEPLOYMENT NOW : %v", createdDeployment.Status, atlasDeployment.StateName)) + GinkgoWriter.Write(s) + }).WithPolling(10 * time.Second).WithTimeout(5 * time.Minute).Should(Succeed()) doServerlessDeploymentStatusChecks() }) By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} performUpdate(20 * time.Minute) + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) + g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) + }).WithPolling(10 * time.Second).WithTimeout(5 * time.Minute).Should(Succeed()) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { From 61122f79466bf940c3b0619da199fbd035b315bf Mon Sep 17 00:00:00 2001 From: cveticm Date: Wed, 26 Jul 2023 14:25:52 +0100 Subject: [PATCH 10/60] Partial test fixes --- .../atlasdeployment_controller.go | 9 +++--- .../atlasdeployment/serverless_deployment.go | 26 +++++++++++----- test/int/deployment_test.go | 30 ++++++++----------- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index d6bedc91e6..b26bcc11ec 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -191,8 +191,9 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. deployment.Spec.DeploymentSpec = nil } - if result, err := uniqueKey(&deployment.Spec); !result.IsOk() { + if err := uniqueKey(&deployment.Spec); err != nil { log.Errorw("failed to validate tags", "error", err) + result := workflow.Terminate(workflow.Internal, err.Error()) ctx.SetConditionFromResult(status.DeploymentReadyType, result) return result.ReconcileResult(), nil } @@ -484,7 +485,7 @@ func (r *AtlasDeploymentReconciler) removeDeletionFinalizer(context context.Cont type deploymentHandlerFunc func(ctx *workflow.Context, project *mdbv1.AtlasProject, deployment *mdbv1.AtlasDeployment, req reconcile.Request) (workflow.Result, error) // Parse through tags and verfiy that all keys are unique. Return error on duplicate key. -func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) (workflow.Result, error) { +func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { store := make(map[string]string) var arrTags []*mdbv1.TagSpec @@ -498,8 +499,8 @@ func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) (workflow.Result, erro store[currTag.Key] = currTag.Value } else { err := errors.New("duplicate keys found in tags, this is forbidden") - return workflow.Terminate(workflow.Internal, err.Error()), err + return err } } - return workflow.OK(), nil + return nil } diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 826c5bb164..0b68236d23 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "reflect" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" @@ -45,19 +46,30 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr switch atlasDeployment.StateName { case status.StateIDLE: - atlasDeployment, err := serverlessSpec.ServerlessToAtlas() + convertedDeployment, err := serverlessSpec.ServerlessToAtlas() if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } - atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ - ServerlessBackupOptions: atlasDeployment.ServerlessBackupOptions, - Tag: atlasDeployment.Tags, - }) - if err != nil { - return atlasDeployment, workflow.Terminate(workflow.DeploymentNotUpdatedInAtlas, err.Error()) + fmt.Println("TAGS >>> operator:", convertedDeployment.Tags, " \n atlas", atlasDeployment.Tags) + if convertedDeployment.Tags == nil { + convertedDeployment.Tags = []*mongodbatlas.Tag{} + } + if (reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags)) != true /* TODO : add || if backupOptions aren't equal */ { + + fmt.Println(reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags)) + + atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ + ServerlessBackupOptions: convertedDeployment.ServerlessBackupOptions, + Tag: convertedDeployment.Tags, + }) + if err != nil { + return atlasDeployment, workflow.Terminate(workflow.DeploymentNotUpdatedInAtlas, err.Error()) + } + return atlasDeployment, workflow.InProgress(workflow.DeploymentUpdating, "deployment is updating") } result := ensureServerlessPrivateEndpoints(ctx, project.ID(), serverlessSpec, atlasDeployment.Name) return atlasDeployment, result + case status.StateCREATING: return atlasDeployment, workflow.InProgress(workflow.DeploymentCreating, "deployment is provisioning") diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 59d0ea6fd4..65b09de6a8 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -575,6 +575,13 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By(fmt.Sprintf("Creating the Deployment %s", kube.ObjectKeyFromObject(createdDeployment)), func() { performCreate(createdDeployment, 30*time.Minute) + /// + atlasDeployment, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) + fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment, atlasDeployment.StateName) + Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) + fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment, atlasDeployment.StateName) + /// + doDeploymentStatusChecks() checkAtlasState() }) @@ -1052,32 +1059,21 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) - By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { performCreate(createdDeployment, 30*time.Minute) - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) - fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment.Status, atlasDeployment.StateName) - Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) - g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) - s := []byte(fmt.Sprintf("CREATEDEPLOYMENT NOW : %v ATLASDEPLOYMENT NOW : %v", createdDeployment.Status, atlasDeployment.StateName)) - GinkgoWriter.Write(s) - }).WithPolling(10 * time.Second).WithTimeout(5 * time.Minute).Should(Succeed()) doServerlessDeploymentStatusChecks() }) By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} performUpdate(20 * time.Minute) - Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) - g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) - }).WithPolling(10 * time.Second).WithTimeout(5 * time.Minute).Should(Succeed()) doServerlessDeploymentStatusChecks() - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Name) - for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeTrue()) + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + if createdDeployment != nil { + for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeTrue()) + } } }) From 81a49f6e10774c8c2e4b90365406ef4bc37eed8c Mon Sep 17 00:00:00 2001 From: cveticm Date: Wed, 26 Jul 2023 17:55:01 +0100 Subject: [PATCH 11/60] Test fixes --- pkg/api/v1/atlasdeployment_types.go | 2 +- .../atlasdeployment/serverless_deployment.go | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index 7267f64b3f..1d1dfbd672 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -219,7 +219,7 @@ type ServerlessSpec struct { // Key-value pairs for resource tagging. // +kubebuilder:validation:MaxItems=50 // +optional - Tags []*TagSpec `json:"tags,omitempty"` + Tags []*TagSpec `json:"tags"` } // ServerlessToAtlas converts the ServerlessSpec to native Atlas client Cluster format. diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 0b68236d23..ff0f9a8209 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -50,17 +50,13 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } - fmt.Println("TAGS >>> operator:", convertedDeployment.Tags, " \n atlas", atlasDeployment.Tags) if convertedDeployment.Tags == nil { convertedDeployment.Tags = []*mongodbatlas.Tag{} } - if (reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags)) != true /* TODO : add || if backupOptions aren't equal */ { - - fmt.Println(reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags)) - + if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) /* || !reflect.DeepEqual(convertedDeployment.ServerlessBackupOptions, atlasDeployment.ServerlessBackupOptions) */ { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ - ServerlessBackupOptions: convertedDeployment.ServerlessBackupOptions, - Tag: convertedDeployment.Tags, + // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled + Tag: convertedDeployment.Tags, }) if err != nil { return atlasDeployment, workflow.Terminate(workflow.DeploymentNotUpdatedInAtlas, err.Error()) From eb513dc569519be19734999e2cae1c2df4b42b72 Mon Sep 17 00:00:00 2001 From: cveticm Date: Thu, 27 Jul 2023 10:40:38 +0100 Subject: [PATCH 12/60] Test fixes --- pkg/controller/atlasdeployment/serverless_deployment.go | 2 +- test/int/deployment_test.go | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index ff0f9a8209..0fa982e2dd 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -53,7 +53,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr if convertedDeployment.Tags == nil { convertedDeployment.Tags = []*mongodbatlas.Tag{} } - if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) /* || !reflect.DeepEqual(convertedDeployment.ServerlessBackupOptions, atlasDeployment.ServerlessBackupOptions) */ { + if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled Tag: convertedDeployment.Tags, diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 65b09de6a8..36cc20fd66 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -575,13 +575,6 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By(fmt.Sprintf("Creating the Deployment %s", kube.ObjectKeyFromObject(createdDeployment)), func() { performCreate(createdDeployment, 30*time.Minute) - /// - atlasDeployment, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) - fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment, atlasDeployment.StateName) - Expect(k8sClient.Get(context.Background(), kube.ObjectKeyFromObject(createdDeployment), createdDeployment)).To(Succeed()) - fmt.Printf("CREATEDEPLOYMENT : %v ATLASDEPLOYMENT : %v", createdDeployment, atlasDeployment.StateName) - /// - doDeploymentStatusChecks() checkAtlasState() }) From d5416e6062bb74fa74b7da447913f3ad7eef0487 Mon Sep 17 00:00:00 2001 From: cveticm Date: Thu, 27 Jul 2023 10:50:05 +0100 Subject: [PATCH 13/60] Test fixes --- test/int/deployment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 36cc20fd66..b3e57f814b 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1049,7 +1049,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create serverless instance", func() { + Describe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { From 0e87a28f8447c63e60db28798af0457b2fee0360 Mon Sep 17 00:00:00 2001 From: cveticm Date: Thu, 27 Jul 2023 14:24:37 +0100 Subject: [PATCH 14/60] Fix tests to work with new serverless tag type --- pkg/controller/atlasdeployment/serverless_deployment.go | 8 +++++++- test/int/deployment_test.go | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 0fa982e2dd..df447c90e8 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -44,14 +44,20 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr } } + // dep, _ := json.Marshal(atlasDeployment) + // fmt.Println("DEBUG >>>>>> atlasdepl >> ", string(dep)) + switch atlasDeployment.StateName { case status.StateIDLE: convertedDeployment, err := serverlessSpec.ServerlessToAtlas() if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } + fmt.Println("TAGS >>> operator:", convertedDeployment.Tags, " \n atlas", atlasDeployment.Tags) if convertedDeployment.Tags == nil { - convertedDeployment.Tags = []*mongodbatlas.Tag{} + // fmt.Println("Converting nil tags to empty array") + p := &[]*mongodbatlas.Tag{} + convertedDeployment.Tags = p } if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index b3e57f814b..17c676e7c1 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1049,7 +1049,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { @@ -1064,8 +1064,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual(atlasDeployment.Tags[i].Value, tag.Value)).To(BeTrue()) + Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) } } }) From 95655f178a76c90ec79378eaa4665e9d9d9c8d51 Mon Sep 17 00:00:00 2001 From: cveticm Date: Thu, 27 Jul 2023 14:25:54 +0100 Subject: [PATCH 15/60] Fix tests to work with new serverless tag type --- pkg/controller/atlasdeployment/serverless_deployment.go | 5 ----- test/int/deployment_test.go | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index df447c90e8..349353c7fa 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -44,18 +44,13 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr } } - // dep, _ := json.Marshal(atlasDeployment) - // fmt.Println("DEBUG >>>>>> atlasdepl >> ", string(dep)) - switch atlasDeployment.StateName { case status.StateIDLE: convertedDeployment, err := serverlessSpec.ServerlessToAtlas() if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } - fmt.Println("TAGS >>> operator:", convertedDeployment.Tags, " \n atlas", atlasDeployment.Tags) if convertedDeployment.Tags == nil { - // fmt.Println("Converting nil tags to empty array") p := &[]*mongodbatlas.Tag{} convertedDeployment.Tags = p } diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 17c676e7c1..38bc35600a 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1084,7 +1084,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { ) }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) lastGeneration++ - // Removing tags for next tests + // Removing tags createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} performUpdate(20 * time.Minute) }) From 84b98195fe46d4016e60871f869eb15accc7697d Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:25:17 +0100 Subject: [PATCH 16/60] Fix --- pkg/controller/atlasdeployment/serverless_deployment.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 349353c7fa..34a45c277c 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -51,8 +51,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } if convertedDeployment.Tags == nil { - p := &[]*mongodbatlas.Tag{} - convertedDeployment.Tags = p + convertedDeployment.Tags = &[]*mongodbatlas.Tag{} } if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ From 2bf27bb921da224530cc98ead39dc349a669b9e1 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 28 Jul 2023 09:33:17 +0100 Subject: [PATCH 17/60] Updating dependencies --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2599e889b8..59dac624f9 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pborman/uuid v1.2.1 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.4 - go.mongodb.org/atlas v0.29.0 + go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 go.mongodb.org/mongo-driver v1.12.0 go.uber.org/zap v1.24.0 golang.org/x/sync v0.3.0 diff --git a/go.sum b/go.sum index 1d239501fe..3502160256 100644 --- a/go.sum +++ b/go.sum @@ -317,6 +317,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= @@ -397,8 +398,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/atlas v0.29.0 h1:vBo4Qe8u2GKn8ZEiw8vLCv8lmxryhea6kUWY0ZJL8OU= -go.mongodb.org/atlas v0.29.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= +go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 h1:TYDMrtvWYAaB1erASHtbl+IXTAqgK8xe3ACgtqgXgQg= +go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= From 74eb6cdc9665450112495d9090c3e971e793fb7e Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 28 Jul 2023 09:52:37 +0100 Subject: [PATCH 18/60] Changing variable name due to dependency change --- pkg/api/v1/status/cloud_provider_access.go | 2 +- pkg/controller/atlasproject/cloud_provider_access.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/api/v1/status/cloud_provider_access.go b/pkg/api/v1/status/cloud_provider_access.go index d4a38edbde..04dfd85b75 100644 --- a/pkg/api/v1/status/cloud_provider_access.go +++ b/pkg/api/v1/status/cloud_provider_access.go @@ -56,7 +56,7 @@ func (c *CloudProviderAccessRole) FailedToAuthorise(errorMessage string) { c.ErrorMessage = errorMessage } -func (c *CloudProviderAccessRole) Update(role mongodbatlas.AWSIAMRole, isEmptyArn bool) { +func (c *CloudProviderAccessRole) Update(role mongodbatlas.CloudProviderAccessRole, isEmptyArn bool) { c.RoleID = role.RoleID c.AtlasAssumedRoleExternalID = role.AtlasAssumedRoleExternalID c.AtlasAWSAccountArn = role.AtlasAWSAccountARN diff --git a/pkg/controller/atlasproject/cloud_provider_access.go b/pkg/controller/atlasproject/cloud_provider_access.go index 12d6782ac2..49968f2018 100644 --- a/pkg/controller/atlasproject/cloud_provider_access.go +++ b/pkg/controller/atlasproject/cloud_provider_access.go @@ -109,7 +109,7 @@ func ensureCloudProviderAccessStatus(statusMap map[v1.CloudProviderAccessRole]st return workflow.OK(), status.CloudProviderAccessReadyType } -func updateAccessRoles(toUpdate []mongodbatlas.AWSIAMRole, specToStatus map[v1.CloudProviderAccessRole]status.CloudProviderAccessRole) { +func updateAccessRoles(toUpdate []mongodbatlas.CloudProviderAccessRole, specToStatus map[v1.CloudProviderAccessRole]status.CloudProviderAccessRole) { for _, role := range toUpdate { for spec, roleStatus := range specToStatus { if role.RoleID == roleStatus.RoleID { @@ -212,7 +212,7 @@ func checkStatuses(specs []v1.CloudProviderAccessRole, statuses []status.CloudPr type accessRoleDiff struct { toCreate []v1.CloudProviderAccessRole - toUpdate []mongodbatlas.AWSIAMRole + toUpdate []mongodbatlas.CloudProviderAccessRole toDelete map[string]string // roleId -> providerName } From 13afe65e4e57d1f051ae11fef61ef88db3217526 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Fri, 28 Jul 2023 13:06:28 +0100 Subject: [PATCH 19/60] Fix --- test/int/deployment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 38bc35600a..021843c128 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1049,7 +1049,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create serverless instance", func() { + Describe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { From a8d854c1cb6bed7952c881189cf4a430637fd216 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Fri, 28 Jul 2023 13:40:29 +0100 Subject: [PATCH 20/60] Testing for fix --- test/int/deployment_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 021843c128..4fe8046e79 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1049,7 +1049,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { @@ -1059,7 +1059,9 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration) performUpdate(20 * time.Minute) + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { From 5c8ee259afb0bdf7c78d8bfd6e730d57b1a25b32 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Fri, 28 Jul 2023 13:52:17 +0100 Subject: [PATCH 21/60] Testing for fix --- test/int/deployment_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 4fe8046e79..45ad7c374d 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1059,9 +1059,9 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration) + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration) + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { From eccabb9ac4d8c3116be5fcf8015dadeede8ca412 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Fri, 28 Jul 2023 15:50:04 +0100 Subject: [PATCH 22/60] Testing for fix --- test/int/deployment_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 45ad7c374d..d87f0d5b77 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1061,6 +1061,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) + time.Sleep(10 * time.Second) GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) From 9dd3fa867557e388890f6a8605a07f2b0a70c2e3 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:09:41 +0100 Subject: [PATCH 23/60] Testing for fix --- test/int/deployment_test.go | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index d87f0d5b77..ec33f6a391 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -153,23 +153,25 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { doServerlessDeploymentStatusChecks := func() { By("Checking observed Serverless state", func() { - atlasDeployment, _, err := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) - Expect(err).ToNot(HaveOccurred()) - - Expect(createdDeployment.Status.ConnectionStrings).NotTo(BeNil()) - Expect(createdDeployment.Status.ConnectionStrings.Standard).To(Equal(atlasDeployment.ConnectionStrings.Standard)) - Expect(createdDeployment.Status.ConnectionStrings.StandardSrv).To(Equal(atlasDeployment.ConnectionStrings.StandardSrv)) - Expect(createdDeployment.Status.MongoDBVersion).To(Not(BeEmpty())) - Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) - Expect(createdDeployment.Status.Conditions).To(HaveLen(4)) - Expect(createdDeployment.Status.Conditions).To(ConsistOf(testutil.MatchConditions( - status.TrueCondition(status.DeploymentReadyType), - status.TrueCondition(status.ReadyType), - status.TrueCondition(status.ValidationSucceeded), - status.TrueCondition(status.ResourceVersionStatus), - ))) - Expect(createdDeployment.Status.ObservedGeneration).To(Equal(createdDeployment.Generation)) - Expect(createdDeployment.Status.ObservedGeneration).To(Equal(lastGeneration + 1)) + Eventually(func(g Gomega) { + atlasDeployment, _, err := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) + g.Expect(err).ToNot(HaveOccurred()) + + g.Expect(createdDeployment.Status.ConnectionStrings).NotTo(BeNil()) + g.Expect(createdDeployment.Status.ConnectionStrings.Standard).To(Equal(atlasDeployment.ConnectionStrings.Standard)) + g.Expect(createdDeployment.Status.ConnectionStrings.StandardSrv).To(Equal(atlasDeployment.ConnectionStrings.StandardSrv)) + g.Expect(createdDeployment.Status.MongoDBVersion).To(Not(BeEmpty())) + g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) + g.Expect(createdDeployment.Status.Conditions).To(HaveLen(4)) + g.Expect(createdDeployment.Status.Conditions).To(ConsistOf(testutil.MatchConditions( + status.TrueCondition(status.DeploymentReadyType), + status.TrueCondition(status.ReadyType), + status.TrueCondition(status.ValidationSucceeded), + status.TrueCondition(status.ResourceVersionStatus), + ))) + g.Expect(createdDeployment.Status.ObservedGeneration).To(Equal(createdDeployment.Generation)) + g.Expect(createdDeployment.Status.ObservedGeneration).To(Equal(lastGeneration + 1)) + }).WithTimeout(10 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) }) } From a841ff6d7c2a4999753d55ac3d2e2c2b0384e514 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 28 Jul 2023 17:46:13 +0100 Subject: [PATCH 24/60] Testing for fix --- test/int/deployment_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index ec33f6a391..49f3393564 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1065,7 +1065,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate(20 * time.Minute) time.Sleep(10 * time.Second) GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) - doServerlessDeploymentStatusChecks() + // doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { @@ -1091,7 +1091,10 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { lastGeneration++ // Removing tags createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) + time.Sleep(10 * time.Second) + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) }) }) }) From 5918e97ee32dd128f2d8607c7cf6095455926bd4 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 28 Jul 2023 18:41:06 +0100 Subject: [PATCH 25/60] Testing for fix --- test/int/deployment_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 49f3393564..a1408cded4 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1051,11 +1051,13 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create serverless instance", func() { + Describe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performCreate(createdDeployment, 30*time.Minute) + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() }) @@ -1065,7 +1067,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate(20 * time.Minute) time.Sleep(10 * time.Second) GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) - // doServerlessDeploymentStatusChecks() + doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { From bab073dbe9754f8052f731041ce36f1a0d9ce881 Mon Sep 17 00:00:00 2001 From: cveticm Date: Sun, 30 Jul 2023 22:23:07 +0100 Subject: [PATCH 26/60] Testing for fixes --- test/int/deployment_test.go | 60 +++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index a1408cded4..cb02a8ac0d 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -590,34 +590,43 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Deployment tags", func() { createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - doDeploymentStatusChecks() - checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { - for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { - Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) - } - }) + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + if (lastGeneration + 1) != createdDeployment.Status.ObservedGeneration { + lastGeneration-- + GinkgoWriter.Println("SKIPPING doDeploymnetStatusChecK!!!!") + } else { + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { + Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) + } + }) + } + current, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.ID(), createdDeployment.GetDeploymentName()) + GinkgoWriter.Println("ATLAS DEPL TAGS >>> ", current.Tags) }) - By("Updating the Deployment tags with a duplicate key", func() { - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} - Eventually(func(g Gomega) { - g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) - }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) - Eventually(func() bool { - return testutil.CheckCondition( - k8sClient, - createdDeployment, - status. - FalseCondition(status.DeploymentReadyType), - ) - }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) - lastGeneration++ - // Removing tags for next tests - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} - performUpdate(20 * time.Minute) - }) + // By("Updating the Deployment tags with a duplicate key", func() { + // createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + // Eventually(func(g Gomega) { + // g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + // }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) + // Eventually(func() bool { + // return testutil.CheckCondition( + // k8sClient, + // createdDeployment, + // status. + // FalseCondition(status.DeploymentReadyType), + // ) + // }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) + // lastGeneration++ + // // Removing tags for next tests + // createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} + // performUpdate(20 * time.Minute) + // }) By("Updating the Deployment backups settings", func() { createdDeployment.Spec.DeploymentSpec.ProviderBackupEnabled = boolptr(true) @@ -1065,7 +1074,6 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - time.Sleep(10 * time.Second) GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) From d89ffb499c9164c0bce0ca674bf2ba0a6aca34fa Mon Sep 17 00:00:00 2001 From: cveticm Date: Sun, 30 Jul 2023 22:31:11 +0100 Subject: [PATCH 27/60] Testing for fixes --- test/int/deployment_test.go | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index cb02a8ac0d..08b2453897 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -153,25 +153,23 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { doServerlessDeploymentStatusChecks := func() { By("Checking observed Serverless state", func() { - Eventually(func(g Gomega) { - atlasDeployment, _, err := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) - g.Expect(err).ToNot(HaveOccurred()) - - g.Expect(createdDeployment.Status.ConnectionStrings).NotTo(BeNil()) - g.Expect(createdDeployment.Status.ConnectionStrings.Standard).To(Equal(atlasDeployment.ConnectionStrings.Standard)) - g.Expect(createdDeployment.Status.ConnectionStrings.StandardSrv).To(Equal(atlasDeployment.ConnectionStrings.StandardSrv)) - g.Expect(createdDeployment.Status.MongoDBVersion).To(Not(BeEmpty())) - g.Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) - g.Expect(createdDeployment.Status.Conditions).To(HaveLen(4)) - g.Expect(createdDeployment.Status.Conditions).To(ConsistOf(testutil.MatchConditions( - status.TrueCondition(status.DeploymentReadyType), - status.TrueCondition(status.ReadyType), - status.TrueCondition(status.ValidationSucceeded), - status.TrueCondition(status.ResourceVersionStatus), - ))) - g.Expect(createdDeployment.Status.ObservedGeneration).To(Equal(createdDeployment.Generation)) - g.Expect(createdDeployment.Status.ObservedGeneration).To(Equal(lastGeneration + 1)) - }).WithTimeout(10 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) + atlasDeployment, _, err := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) + Expect(err).ToNot(HaveOccurred()) + + Expect(createdDeployment.Status.ConnectionStrings).NotTo(BeNil()) + Expect(createdDeployment.Status.ConnectionStrings.Standard).To(Equal(atlasDeployment.ConnectionStrings.Standard)) + Expect(createdDeployment.Status.ConnectionStrings.StandardSrv).To(Equal(atlasDeployment.ConnectionStrings.StandardSrv)) + Expect(createdDeployment.Status.MongoDBVersion).To(Not(BeEmpty())) + Expect(createdDeployment.Status.StateName).To(Equal("IDLE")) + Expect(createdDeployment.Status.Conditions).To(HaveLen(4)) + Expect(createdDeployment.Status.Conditions).To(ConsistOf(testutil.MatchConditions( + status.TrueCondition(status.DeploymentReadyType), + status.TrueCondition(status.ReadyType), + status.TrueCondition(status.ValidationSucceeded), + status.TrueCondition(status.ResourceVersionStatus), + ))) + Expect(createdDeployment.Status.ObservedGeneration).To(Equal(createdDeployment.Generation)) + Expect(createdDeployment.Status.ObservedGeneration).To(Equal(lastGeneration + 1)) }) } From 281cd4fba674c0c31dce701144a5072b18fac2c9 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 12:47:46 +0100 Subject: [PATCH 28/60] Testing fixes --- test/int/deployment_test.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 08b2453897..170bfd33d0 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -2,6 +2,7 @@ package int import ( "context" + "encoding/json" "errors" "fmt" "net/http" @@ -242,6 +243,9 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate := func(timeout time.Duration) { Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + j, _ := json.MarshalIndent(createdDeployment, "", " ") + GinkgoWriter.Println(">>>", j) + Eventually(func(g Gomega) bool { return testutil.CheckCondition(k8sClient, createdDeployment, status.TrueCondition(status.ReadyType), validateDeploymentUpdatingFunc(g)) }).WithTimeout(timeout).WithPolling(interval).Should(BeTrue()) @@ -1058,21 +1062,21 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performCreate(createdDeployment, 30*time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() }) By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { @@ -1081,6 +1085,10 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) } } + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + performUpdate(20 * time.Minute) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + }) By("Updating the Deployment tags with a duplicate key", func() { From dae759d479b1654a22c6e815b9ef44241db31bb7 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 12:47:46 +0100 Subject: [PATCH 29/60] Testing fixes --- test/int/deployment_test.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 08b2453897..170bfd33d0 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -2,6 +2,7 @@ package int import ( "context" + "encoding/json" "errors" "fmt" "net/http" @@ -242,6 +243,9 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate := func(timeout time.Duration) { Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + j, _ := json.MarshalIndent(createdDeployment, "", " ") + GinkgoWriter.Println(">>>", j) + Eventually(func(g Gomega) bool { return testutil.CheckCondition(k8sClient, createdDeployment, status.TrueCondition(status.ReadyType), validateDeploymentUpdatingFunc(g)) }).WithTimeout(timeout).WithPolling(interval).Should(BeTrue()) @@ -1058,21 +1062,21 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performCreate(createdDeployment, 30*time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() }) By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { @@ -1081,6 +1085,10 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) } } + GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + performUpdate(20 * time.Minute) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + }) By("Updating the Deployment tags with a duplicate key", func() { From e3bc2f3c71a8d06716614be3b1cff712f37a6bc3 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 13:38:00 +0100 Subject: [PATCH 30/60] Testing fixes --- test/int/deployment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 170bfd33d0..ce9d4c674b 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -244,7 +244,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) j, _ := json.MarshalIndent(createdDeployment, "", " ") - GinkgoWriter.Println(">>>", j) + GinkgoWriter.Println(">>>", string(j)) Eventually(func(g Gomega) bool { return testutil.CheckCondition(k8sClient, createdDeployment, status.TrueCondition(status.ReadyType), validateDeploymentUpdatingFunc(g)) From e6c5c6ddc327b3a1a128c8f182bd83e4f8c630da Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 13:46:41 +0100 Subject: [PATCH 31/60] Testing fixes --- test/int/deployment_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index ce9d4c674b..34ad69530d 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1075,10 +1075,14 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) - performUpdate(20 * time.Minute) + //performUpdate(20 * time.Minute) + Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + j, _ := json.MarshalIndent(atlasDeployment, "", " ") + GinkgoWriter.Println(">>>", string(j)) GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + //atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Key, tag.Key)).To(BeTrue()) From ae29cb52225de611ae06474a6c760fe12c75446e Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 13:51:19 +0100 Subject: [PATCH 32/60] Testing fixes --- test/int/deployment_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 34ad69530d..dd1b55c921 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1080,6 +1080,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) j, _ := json.MarshalIndent(atlasDeployment, "", " ") GinkgoWriter.Println(">>>", string(j)) + lastGeneration++ GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() //atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) From 98cd3a32c146885dabf523e4f78c9d5364869ce5 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 13:57:37 +0100 Subject: [PATCH 33/60] Testing fixes --- test/int/deployment_test.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index dd1b55c921..2aae72edde 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -571,7 +571,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - It("Should Succeed (AWS)", func() { + FIt("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -585,7 +585,15 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Deployment labels", func() { createdDeployment.Spec.DeploymentSpec.Labels = []common.LabelSpec{{Key: "int-test", Value: "true"}} - performUpdate(20 * time.Minute) + + GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + j, _ := json.MarshalIndent(atlasDeployment, "", " ") + GinkgoWriter.Println(">>>", string(j)) + lastGeneration++ + GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) + doDeploymentStatusChecks() checkAtlasState() }) @@ -1062,13 +1070,11 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create serverless instance", func() { + Describe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { - GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performCreate(createdDeployment, 30*time.Minute) - GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() }) From 4ccb7f51a69f139611165f6a0ecd5f1ec00eb989 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 14:17:35 +0100 Subject: [PATCH 34/60] Testing fixes --- test/int/deployment_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 2aae72edde..8abe196238 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -588,7 +588,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + GinkgoWriter.Println("updating done") + atlasDeployment, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) j, _ := json.MarshalIndent(atlasDeployment, "", " ") GinkgoWriter.Println(">>>", string(j)) lastGeneration++ From 052eb951bca3e3a96af70ed220e254c3509bf916 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 31 Jul 2023 16:13:58 +0200 Subject: [PATCH 35/60] Testing fixes --- test/int/deployment_test.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 8abe196238..bedcb21458 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -571,7 +571,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FIt("Should Succeed (AWS)", func() { + It("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -1071,7 +1071,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - Describe("Create serverless instance", func() { + FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { @@ -1082,15 +1082,17 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) - //performUpdate(20 * time.Minute) - Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + performUpdate(20 * time.Minute) + + j, _ := json.MarshalIndent(createdDeployment, "", " ") + GinkgoWriter.Println("OPERATOR STATE >>>", string(j)) + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) - j, _ := json.MarshalIndent(atlasDeployment, "", " ") - GinkgoWriter.Println(">>>", string(j)) - lastGeneration++ + j, _ = json.MarshalIndent(atlasDeployment, "", " ") + GinkgoWriter.Println("ATLAS STATE >>>", string(j)) + GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() - //atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Key, tag.Key)).To(BeTrue()) From 54a35f0b18b8d9a243bfefadf4bab92a199ec4a9 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 31 Jul 2023 16:35:30 +0200 Subject: [PATCH 36/60] Testing fixes --- test/int/deployment_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index bedcb21458..a5bbb03436 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1081,7 +1081,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) + at, _ := json.MarshalIndent(createdDeployment.Spec.ServerlessSpec.Tags, "", " ") + GinkgoWriter.Println("ATLAS TAGS BEFORE UPDATE: ", string(at)) performUpdate(20 * time.Minute) j, _ := json.MarshalIndent(createdDeployment, "", " ") @@ -1091,7 +1092,6 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { j, _ = json.MarshalIndent(atlasDeployment, "", " ") GinkgoWriter.Println("ATLAS STATE >>>", string(j)) - GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) doServerlessDeploymentStatusChecks() if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { @@ -1099,10 +1099,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) } } - GinkgoWriter.Println("LASTGENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - GinkgoWriter.Println("LASTGENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) - }) By("Updating the Deployment tags with a duplicate key", func() { From d2fd07d0e16f8c9399546b6f3fe2a574c2170483 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 15:52:18 +0100 Subject: [PATCH 37/60] Testing for fixes --- .../atlas.mongodb.com_atlasdeployments.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/config/crd/bases/atlas.mongodb.com_atlasdeployments.yaml b/config/crd/bases/atlas.mongodb.com_atlasdeployments.yaml index 34bc5199ea..2d339cc7ba 100644 --- a/config/crd/bases/atlas.mongodb.com_atlasdeployments.yaml +++ b/config/crd/bases/atlas.mongodb.com_atlasdeployments.yaml @@ -231,6 +231,28 @@ spec: type: array rootCertType: type: string + tags: + description: Key-value pairs for resource tagging. + items: + description: TagSpec holds a key-value pair for resource tagging + on this deployment. + properties: + key: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9 @_.+`;`-]*$ + type: string + value: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9@_.+`;`-]*$ + type: string + required: + - key + - value + type: object + maxItems: 50 + type: array versionReleaseSystem: type: string type: object @@ -574,6 +596,28 @@ spec: type: string type: object type: array + tags: + description: Key-value pairs for resource tagging. + items: + description: TagSpec holds a key-value pair for resource tagging + on this deployment. + properties: + key: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9 @_.+`;`-]*$ + type: string + value: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9@_.+`;`-]*$ + type: string + required: + - key + - value + type: object + maxItems: 50 + type: array required: - name - providerSettings @@ -747,6 +791,28 @@ spec: required: - providerName type: object + tags: + description: Key-value pairs for resource tagging. + items: + description: TagSpec holds a key-value pair for resource tagging + on this deployment. + properties: + key: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9 @_.+`;`-]*$ + type: string + value: + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9@_.+`;`-]*$ + type: string + required: + - key + - value + type: object + maxItems: 50 + type: array required: - name - providerSettings From 3bd70419ced21b8264d9258115bd3cfe0c6005c8 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 16:05:47 +0100 Subject: [PATCH 38/60] Testing for fixes --- test/int/deployment_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index a5bbb03436..c05f8164d8 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -1074,6 +1074,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { FDescribe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} By(fmt.Sprintf("Creating the Serverless Instance %s", kube.ObjectKeyFromObject(createdDeployment)), func() { performCreate(createdDeployment, 30*time.Minute) doServerlessDeploymentStatusChecks() From 3be95acedf0935e79d4cc8d6cf583445a5fdf219 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 16:16:40 +0100 Subject: [PATCH 39/60] Testing for fixes --- test/int/deployment_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index c05f8164d8..fa38f9e6f1 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -571,7 +571,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - It("Should Succeed (AWS)", func() { + FIt("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -1071,7 +1071,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FDescribe("Create serverless instance", func() { + Describe("Create serverless instance", func() { It("Should Succeed", func() { createdDeployment = mdbv1.NewDefaultAWSServerlessInstance(namespace.Name, createdProject.Name) createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} From f361a0b88566c9bbfc9b8763c7b6b327bfd80cf4 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 16:18:30 +0100 Subject: [PATCH 40/60] Testing for fixes --- test/int/deployment_test.go | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index fa38f9e6f1..2d66c4b35e 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -585,37 +585,21 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Deployment labels", func() { createdDeployment.Spec.DeploymentSpec.Labels = []common.LabelSpec{{Key: "int-test", Value: "true"}} - - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) - Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) - GinkgoWriter.Println("updating done") - atlasDeployment, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.Status.ID, createdDeployment.GetDeploymentName()) - j, _ := json.MarshalIndent(atlasDeployment, "", " ") - GinkgoWriter.Println(">>>", string(j)) - lastGeneration++ - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) - + performUpdate(20 * time.Minute) doDeploymentStatusChecks() checkAtlasState() }) By("Updating the Deployment tags", func() { createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) - if (lastGeneration + 1) != createdDeployment.Status.ObservedGeneration { - lastGeneration-- - GinkgoWriter.Println("SKIPPING doDeploymnetStatusChecK!!!!") - } else { - doDeploymentStatusChecks() - checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { - for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { - Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) - } - }) - } + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { + Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) + Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) + } + }) current, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.ID(), createdDeployment.GetDeploymentName()) GinkgoWriter.Println("ATLAS DEPL TAGS >>> ", current.Tags) }) From eab0d74e9c29761f6af492631dbba9d190c1fd0c Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 17:53:28 +0100 Subject: [PATCH 41/60] Fix --- test/int/deployment_test.go | 57 +++++++++++-------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 2d66c4b35e..49956ade9c 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -571,7 +571,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FIt("Should Succeed (AWS)", func() { + It("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -600,28 +600,21 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) } }) - current, _, _ := atlasClient.AdvancedClusters.Get(context.Background(), createdProject.ID(), createdDeployment.GetDeploymentName()) - GinkgoWriter.Println("ATLAS DEPL TAGS >>> ", current.Tags) }) - // By("Updating the Deployment tags with a duplicate key", func() { - // createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} - // Eventually(func(g Gomega) { - // g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) - // }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) - // Eventually(func() bool { - // return testutil.CheckCondition( - // k8sClient, - // createdDeployment, - // status. - // FalseCondition(status.DeploymentReadyType), - // ) - // }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) - // lastGeneration++ - // // Removing tags for next tests - // createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} - // performUpdate(20 * time.Minute) - // }) + By("Updating the Deployment tags with a duplicate key", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) + }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) + Eventually(func() bool { + return testutil.CheckCondition(k8sClient, createdDeployment, status.FalseCondition(status.DeploymentReadyType)) + }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) + lastGeneration++ + // Removing tags for next tests + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{} + performUpdate(20 * time.Minute) + }) By("Updating the Deployment backups settings", func() { createdDeployment.Spec.DeploymentSpec.ProviderBackupEnabled = boolptr(true) @@ -1066,25 +1059,15 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { By("Updating the Instance tags", func() { createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} - at, _ := json.MarshalIndent(createdDeployment.Spec.ServerlessSpec.Tags, "", " ") - GinkgoWriter.Println("ATLAS TAGS BEFORE UPDATE: ", string(at)) performUpdate(20 * time.Minute) - - j, _ := json.MarshalIndent(createdDeployment, "", " ") - GinkgoWriter.Println("OPERATOR STATE >>>", string(j)) - - atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) - j, _ = json.MarshalIndent(atlasDeployment, "", " ") - GinkgoWriter.Println("ATLAS STATE >>>", string(j)) - doServerlessDeploymentStatusChecks() + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Key, tag.Key)).To(BeTrue()) Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) } } - performUpdate(20 * time.Minute) }) By("Updating the Deployment tags with a duplicate key", func() { @@ -1093,20 +1076,12 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) Eventually(func() bool { - return testutil.CheckCondition( - k8sClient, - createdDeployment, - status. - FalseCondition(status.DeploymentReadyType), - ) + return testutil.CheckCondition(k8sClient, createdDeployment, status.FalseCondition(status.DeploymentReadyType)) }).WithTimeout(DeploymentUpdateTimeout).Should(BeTrue()) lastGeneration++ // Removing tags createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{} - GinkgoWriter.Println("GENERATION BEFORE ", lastGeneration, "OBSERVED BEFORE ", createdDeployment.Status.ObservedGeneration) performUpdate(20 * time.Minute) - time.Sleep(10 * time.Second) - GinkgoWriter.Println("GENERATION AFTER ", lastGeneration, "OBSERVED AFTER ", createdDeployment.Status.ObservedGeneration) }) }) }) From ea8088a80e6b298e45c5cced2a59418b8f6e9544 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 18:12:12 +0100 Subject: [PATCH 42/60] Fix --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index cad9c9046c..6aba955221 100644 --- a/go.sum +++ b/go.sum @@ -394,8 +394,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 h1:TYDMrtvWYAaB1erASHtbl+IXTAqgK8xe3ACgtqgXgQg= -go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= +go.mongodb.org/atlas v0.32.0 h1:6uHwus8Bz+h1Ax75Pf3qo3kWCwnaUYav+SxSMU2RGiQ= +go.mongodb.org/atlas v0.32.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= From 0755ab199574fd16842dda3487244d37d2c473c4 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 18:15:34 +0100 Subject: [PATCH 43/60] Fix --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5fbbec30db..da92a0d0ea 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/pborman/uuid v1.2.1 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.4 - go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 + go.mongodb.org/atlas v0.32.0 go.mongodb.org/mongo-driver v1.12.0 go.uber.org/zap v1.24.0 golang.org/x/sync v0.3.0 From 72155fc1dc56fddb7f6f5510892486163d4e3f7e Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 18:21:27 +0100 Subject: [PATCH 44/60] Fix --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index da92a0d0ea..5fbbec30db 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/pborman/uuid v1.2.1 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.4 - go.mongodb.org/atlas v0.32.0 + go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 go.mongodb.org/mongo-driver v1.12.0 go.uber.org/zap v1.24.0 golang.org/x/sync v0.3.0 diff --git a/go.sum b/go.sum index 6aba955221..cad9c9046c 100644 --- a/go.sum +++ b/go.sum @@ -394,8 +394,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/atlas v0.32.0 h1:6uHwus8Bz+h1Ax75Pf3qo3kWCwnaUYav+SxSMU2RGiQ= -go.mongodb.org/atlas v0.32.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= +go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 h1:TYDMrtvWYAaB1erASHtbl+IXTAqgK8xe3ACgtqgXgQg= +go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= From 7fd9a19776f33be8666121c0d56bd075ffefb13e Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 31 Jul 2023 19:09:37 +0100 Subject: [PATCH 45/60] Fix --- go.mod | 2 +- go.sum | 4 ++-- pkg/controller/atlasproject/cloud_provider_access.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 5fbbec30db..da92a0d0ea 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/pborman/uuid v1.2.1 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.4 - go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 + go.mongodb.org/atlas v0.32.0 go.mongodb.org/mongo-driver v1.12.0 go.uber.org/zap v1.24.0 golang.org/x/sync v0.3.0 diff --git a/go.sum b/go.sum index cad9c9046c..6aba955221 100644 --- a/go.sum +++ b/go.sum @@ -394,8 +394,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3 h1:TYDMrtvWYAaB1erASHtbl+IXTAqgK8xe3ACgtqgXgQg= -go.mongodb.org/atlas v0.31.1-0.20230727145348-380bffa66ef3/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= +go.mongodb.org/atlas v0.32.0 h1:6uHwus8Bz+h1Ax75Pf3qo3kWCwnaUYav+SxSMU2RGiQ= +go.mongodb.org/atlas v0.32.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg= go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= diff --git a/pkg/controller/atlasproject/cloud_provider_access.go b/pkg/controller/atlasproject/cloud_provider_access.go index 49968f2018..5acefe3d6f 100644 --- a/pkg/controller/atlasproject/cloud_provider_access.go +++ b/pkg/controller/atlasproject/cloud_provider_access.go @@ -70,9 +70,9 @@ func syncProviderAccessStatus(ctx context.Context, customContext *workflow.Conte func tryToAuthorize(ctx context.Context, access mongodbatlas.CloudProviderAccessService, logger *zap.SugaredLogger, statusMap map[v1.CloudProviderAccessRole]status.CloudProviderAccessRole, groupID string) { for spec, roleStatus := range statusMap { if roleStatus.Status == status.StatusCreated { - request := mongodbatlas.CloudProviderAuthorizationRequest{ + request := mongodbatlas.CloudProviderAccessRoleRequest{ ProviderName: spec.ProviderName, - IAMAssumedRoleARN: spec.IamAssumedRoleArn, + IAMAssumedRoleARN: &spec.IamAssumedRoleArn, } role, _, err := access.AuthorizeRole(ctx, groupID, roleStatus.RoleID, &request) if err != nil { From 1444e58131b42db4117b966fbe058e48e1c425d3 Mon Sep 17 00:00:00 2001 From: cveticm Date: Wed, 2 Aug 2023 12:38:47 +0100 Subject: [PATCH 46/60] Fixes from review --- pkg/api/v1/atlasdeployment_types.go | 2 +- .../atlasdeployment_controller_test.go | 49 +++++++++++++++++++ .../atlasdeployment/serverless_deployment.go | 16 +++++- .../serverless_deployment_test.go | 31 ++++++++++++ test/int/deployment_test.go | 14 ++---- 5 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 pkg/controller/atlasdeployment/atlasdeployment_controller_test.go create mode 100644 pkg/controller/atlasdeployment/serverless_deployment_test.go diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index 1d1dfbd672..7267f64b3f 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -219,7 +219,7 @@ type ServerlessSpec struct { // Key-value pairs for resource tagging. // +kubebuilder:validation:MaxItems=50 // +optional - Tags []*TagSpec `json:"tags"` + Tags []*TagSpec `json:"tags,omitempty"` } // ServerlessToAtlas converts the ServerlessSpec to native Atlas client Cluster format. diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go new file mode 100644 index 0000000000..0938f599b5 --- /dev/null +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go @@ -0,0 +1,49 @@ +package atlasdeployment + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" +) + +func TestUniqueKey(t *testing.T) { + //var deploymentSpec *mdbv1.AtlasDeploymentSpec + t.Run("Test duplicates in Advanced Deployment", func(t *testing.T) { + deploymentSpec := &mdbv1.AtlasDeploymentSpec{ + AdvancedDeploymentSpec: &mdbv1.AdvancedDeploymentSpec{ + Tags: []*mdbv1.TagSpec{{Key: "foo", Value: "true"}, {Key: "foo", Value: "false"}}, + }, + } + err := uniqueKey(deploymentSpec) + assert.Error(t, err) + }) + t.Run("Test no duplicates in Advanced Deployment", func(t *testing.T) { + deploymentSpec := &mdbv1.AtlasDeploymentSpec{ + AdvancedDeploymentSpec: &mdbv1.AdvancedDeploymentSpec{ + Tags: []*mdbv1.TagSpec{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}, {Key: "foobar", Value: "false"}}, + }, + } + err := uniqueKey(deploymentSpec) + assert.NoError(t, err) + }) + t.Run("Test duplicates in Serverless Instance", func(t *testing.T) { + deploymentSpec := &mdbv1.AtlasDeploymentSpec{ + ServerlessSpec: &mdbv1.ServerlessSpec{ + Tags: []*mdbv1.TagSpec{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}, {Key: "foo", Value: "false"}}, + }, + } + err := uniqueKey(deploymentSpec) + assert.Error(t, err) + }) + t.Run("Test no duplicates in Serverless Instance", func(t *testing.T) { + deploymentSpec := &mdbv1.AtlasDeploymentSpec{ + ServerlessSpec: &mdbv1.ServerlessSpec{ + Tags: []*mdbv1.TagSpec{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}, + }, + } + err := uniqueKey(deploymentSpec) + assert.NoError(t, err) + }) +} diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 34a45c277c..833aabb4fb 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "net/http" - "reflect" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" @@ -53,7 +52,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr if convertedDeployment.Tags == nil { convertedDeployment.Tags = &[]*mongodbatlas.Tag{} } - if !reflect.DeepEqual(convertedDeployment.Tags, atlasDeployment.Tags) { + if !isEqual(atlasDeployment, convertedDeployment) { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled Tag: convertedDeployment.Tags, @@ -78,3 +77,16 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr return atlasDeployment, workflow.Terminate(workflow.Internal, fmt.Sprintf("unknown deployment state %q", atlasDeployment.StateName)) } } + +func isEqual(a *mongodbatlas.Cluster, c *mongodbatlas.Cluster) bool { + // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled + if len(*a.Tags) == len(*c.Tags) { + for i, aTags := range *a.Tags { + if aTags.Key != (*c.Tags)[i].Key || aTags.Value != (*c.Tags)[i].Value { + return false + } + } + return true + } + return false +} diff --git a/pkg/controller/atlasdeployment/serverless_deployment_test.go b/pkg/controller/atlasdeployment/serverless_deployment_test.go new file mode 100644 index 0000000000..1f969111a4 --- /dev/null +++ b/pkg/controller/atlasdeployment/serverless_deployment_test.go @@ -0,0 +1,31 @@ +package atlasdeployment + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.mongodb.org/atlas/mongodbatlas" +) + +func TestIsEqual(t *testing.T) { + //var k8sCluster *mongodbatlas.Cluster + //var atlasCluster *mongodbatlas.Cluster + t.Run("Test tags are equal and in same order", func(t *testing.T) { + k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} + atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} + areEqual := isEqual(atlasCluster, k8sCluster) + assert.True(t, areEqual, "Deployments should be equal") + }) + t.Run("Test tags are different lengths", func(t *testing.T) { + k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}, {Key: "foobar", Value: "true"}}} + atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} + areEqual := isEqual(atlasCluster, k8sCluster) + assert.False(t, areEqual, "Deployments should not be equal") + }) + t.Run("Test tags are equal and in wrong order", func(t *testing.T) { + k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "bar", Value: "false"}, {Key: "foo", Value: "true"}}} + atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} + areEqual := isEqual(atlasCluster, k8sCluster) + assert.False(t, areEqual, "Deployments should not be equal") + }) +} diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 49956ade9c..1a869c2492 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -2,11 +2,9 @@ package int import ( "context" - "encoding/json" "errors" "fmt" "net/http" - "reflect" "strconv" "time" @@ -242,10 +240,6 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { performUpdate := func(timeout time.Duration) { Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) - - j, _ := json.MarshalIndent(createdDeployment, "", " ") - GinkgoWriter.Println(">>>", string(j)) - Eventually(func(g Gomega) bool { return testutil.CheckCondition(k8sClient, createdDeployment, status.TrueCondition(status.ReadyType), validateDeploymentUpdatingFunc(g)) }).WithTimeout(timeout).WithPolling(interval).Should(BeTrue()) @@ -596,8 +590,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { doDeploymentStatusChecks() checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { - Expect(reflect.DeepEqual(c.Tags[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual(c.Tags[i].Value, tag.Value)).To(BeTrue()) + Expect(c.Tags[i].Key == tag.Key).To(BeTrue()) + Expect(c.Tags[i].Value == tag.Value).To(BeTrue()) } }) }) @@ -1064,8 +1058,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) if createdDeployment != nil { for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { - Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Key, tag.Key)).To(BeTrue()) - Expect(reflect.DeepEqual((*atlasDeployment.Tags)[i].Value, tag.Value)).To(BeTrue()) + Expect((*atlasDeployment.Tags)[i].Key == tag.Key).To(BeTrue()) + Expect((*atlasDeployment.Tags)[i].Value == tag.Value).To(BeTrue()) } } }) From 09f1af6c3d6581e752761455b13d9e8a2142f822 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 4 Aug 2023 10:16:07 +0100 Subject: [PATCH 47/60] Improved tag testing and isEqual edited and renamed to isTagsEqual --- .../atlasdeployment/serverless_deployment.go | 11 +++--- .../serverless_deployment_test.go | 14 ++----- test/int/deployment_test.go | 39 +++++++++++++++---- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index 833aabb4fb..a6879b576a 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -52,7 +52,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr if convertedDeployment.Tags == nil { convertedDeployment.Tags = &[]*mongodbatlas.Tag{} } - if !isEqual(atlasDeployment, convertedDeployment) { + if !isTagsEqual(*(atlasDeployment.Tags), *(convertedDeployment.Tags)) { atlasDeployment, _, err = ctx.Client.ServerlessInstances.Update(context.Background(), project.Status.ID, serverlessSpec.Name, &mongodbatlas.ServerlessUpdateRequestParams{ // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled Tag: convertedDeployment.Tags, @@ -78,11 +78,10 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr } } -func isEqual(a *mongodbatlas.Cluster, c *mongodbatlas.Cluster) bool { - // TODO: include ServerlessBackupOptions and TerminationProtectionEnabled - if len(*a.Tags) == len(*c.Tags) { - for i, aTags := range *a.Tags { - if aTags.Key != (*c.Tags)[i].Key || aTags.Value != (*c.Tags)[i].Value { +func isTagsEqual(a []*mongodbatlas.Tag, c []*mongodbatlas.Tag) bool { + if len(a) == len(c) { + for i, aTags := range a { + if aTags.Key != (c)[i].Key || aTags.Value != (c)[i].Value { return false } } diff --git a/pkg/controller/atlasdeployment/serverless_deployment_test.go b/pkg/controller/atlasdeployment/serverless_deployment_test.go index 1f969111a4..c061058bb8 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment_test.go +++ b/pkg/controller/atlasdeployment/serverless_deployment_test.go @@ -7,25 +7,17 @@ import ( "go.mongodb.org/atlas/mongodbatlas" ) -func TestIsEqual(t *testing.T) { - //var k8sCluster *mongodbatlas.Cluster - //var atlasCluster *mongodbatlas.Cluster +func TestIsTagsEqual(t *testing.T) { t.Run("Test tags are equal and in same order", func(t *testing.T) { k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} - areEqual := isEqual(atlasCluster, k8sCluster) + areEqual := isTagsEqual(*(atlasCluster.Tags), *(k8sCluster.Tags)) assert.True(t, areEqual, "Deployments should be equal") }) t.Run("Test tags are different lengths", func(t *testing.T) { k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}, {Key: "foobar", Value: "true"}}} atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} - areEqual := isEqual(atlasCluster, k8sCluster) - assert.False(t, areEqual, "Deployments should not be equal") - }) - t.Run("Test tags are equal and in wrong order", func(t *testing.T) { - k8sCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "bar", Value: "false"}, {Key: "foo", Value: "true"}}} - atlasCluster := &mongodbatlas.Cluster{Tags: &[]*mongodbatlas.Tag{{Key: "foo", Value: "true"}, {Key: "bar", Value: "false"}}} - areEqual := isEqual(atlasCluster, k8sCluster) + areEqual := isTagsEqual(*(atlasCluster.Tags), *(k8sCluster.Tags)) assert.False(t, areEqual, "Deployments should not be equal") }) } diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 1a869c2492..4dea6b677a 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -565,7 +565,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - It("Should Succeed (AWS)", func() { + FIt("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() @@ -585,7 +585,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) By("Updating the Deployment tags", func() { - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "test-1", Value: "value-1"}, {Key: "test-2", Value: "value-2"}} performUpdate(20 * time.Minute) doDeploymentStatusChecks() checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { @@ -596,8 +596,20 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - By("Updating the Deployment tags with a duplicate key", func() { - createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + By("Updating the order of Deployment tags", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "test-2", Value: "value-2"}, {Key: "test-1", Value: "value-1"}} + performUpdate(20 * time.Minute) + doDeploymentStatusChecks() + checkAtlasState(func(c *mongodbatlas.AdvancedCluster) { + for i, tag := range createdDeployment.Spec.DeploymentSpec.Tags { + Expect(c.Tags[i].Key == tag.Key).To(BeTrue()) + Expect(c.Tags[i].Value == tag.Value).To(BeTrue()) + } + }) + }) + + By("Updating the Deployment tags with a duplicate key and removing all tags", func() { + createdDeployment.Spec.DeploymentSpec.Tags = []*mdbv1.TagSpec{{Key: "test-1", Value: "value-1"}, {Key: "test-1", Value: "value-2"}} Eventually(func(g Gomega) { g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) @@ -1052,7 +1064,20 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) By("Updating the Instance tags", func() { - createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}} + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "test-1", Value: "value-1"}, {Key: "test-2", Value: "value-2"}} + performUpdate(20 * time.Minute) + doServerlessDeploymentStatusChecks() + atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) + if createdDeployment != nil { + for i, tag := range createdDeployment.Spec.ServerlessSpec.Tags { + Expect((*atlasDeployment.Tags)[i].Key == tag.Key).To(BeTrue()) + Expect((*atlasDeployment.Tags)[i].Value == tag.Value).To(BeTrue()) + } + } + }) + + By("Updating the order of Instance tags", func() { + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "test-2", Value: "value-2"}, {Key: "test-1", Value: "value-1"}} performUpdate(20 * time.Minute) doServerlessDeploymentStatusChecks() atlasDeployment, _, _ := atlasClient.ServerlessInstances.Get(context.Background(), createdProject.Status.ID, createdDeployment.Spec.ServerlessSpec.Name) @@ -1064,8 +1089,8 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { } }) - By("Updating the Deployment tags with a duplicate key", func() { - createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "int-test", Value: "true"}, {Key: "int-test", Value: "false"}} + By("Updating the Instance tags with a duplicate key and removing all tags", func() { + createdDeployment.Spec.ServerlessSpec.Tags = []*mdbv1.TagSpec{{Key: "test-1", Value: "value-1"}, {Key: "test-1", Value: "value-2"}} Eventually(func(g Gomega) { g.Expect(k8sClient.Update(context.Background(), createdDeployment)).To(Succeed()) }).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed()) From 490cdfa78e93ae837a02c4bda76c5bb2b64d1aca Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 4 Aug 2023 10:19:06 +0100 Subject: [PATCH 48/60] Fix --- test/int/deployment_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/int/deployment_test.go b/test/int/deployment_test.go index 4dea6b677a..9983e89ee4 100644 --- a/test/int/deployment_test.go +++ b/test/int/deployment_test.go @@ -565,7 +565,7 @@ var _ = Describe("AtlasDeployment", Label("int", "AtlasDeployment"), func() { }) }) - FIt("Should Succeed (AWS)", func() { + It("Should Succeed (AWS)", func() { createdDeployment = mdbv1.DefaultAWSDeployment(namespace.Name, createdProject.Name) createdDeployment.Spec.DeploymentSpec.DiskSizeGB = intptr(20) createdDeployment = createdDeployment.WithAutoscalingDisabled() From 22a452ebe0cdada1fdeeda46b0cc0627c6dc7865 Mon Sep 17 00:00:00 2001 From: cveticm Date: Tue, 8 Aug 2023 15:33:50 +0100 Subject: [PATCH 49/60] Removing comment --- .../atlasdeployment/atlasdeployment_controller_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go index 0938f599b5..26fd2654cb 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go @@ -9,7 +9,6 @@ import ( ) func TestUniqueKey(t *testing.T) { - //var deploymentSpec *mdbv1.AtlasDeploymentSpec t.Run("Test duplicates in Advanced Deployment", func(t *testing.T) { deploymentSpec := &mdbv1.AtlasDeploymentSpec{ AdvancedDeploymentSpec: &mdbv1.AdvancedDeploymentSpec{ From a0b34f5b9bf577f76609d92622842b62565e47b9 Mon Sep 17 00:00:00 2001 From: cveticm <119604954+cveticm@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:41:03 +0100 Subject: [PATCH 50/60] Fix --- .../atlasdeployment/atlasdeployment_controller_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go index 0938f599b5..26fd2654cb 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go @@ -9,7 +9,6 @@ import ( ) func TestUniqueKey(t *testing.T) { - //var deploymentSpec *mdbv1.AtlasDeploymentSpec t.Run("Test duplicates in Advanced Deployment", func(t *testing.T) { deploymentSpec := &mdbv1.AtlasDeploymentSpec{ AdvancedDeploymentSpec: &mdbv1.AdvancedDeploymentSpec{ From ffe77057fb16db8a26ed5931590aa99b0d190bac Mon Sep 17 00:00:00 2001 From: Roo Thorp Date: Wed, 9 Aug 2023 10:33:21 +0100 Subject: [PATCH 51/60] CLOUDP-153003: Encryption at Rest Tests for GCP & Azure (#1035) --- .github/workflows/test-e2e.yml | 6 +- go.mod | 4 + go.sum | 7 + pkg/api/v1/encryption_at_rest.go | 1 + .../atlasproject/encryption_at_rest.go | 4 +- .../atlasproject/encryption_at_rest_test.go | 8 +- test/e2e/actions/cloud/aws.go | 141 ++++++- test/e2e/actions/cloud/azure.go | 65 +++- test/e2e/actions/cloud/gcp.go | 76 +++- test/e2e/api/aws/aws.go | 354 ------------------ test/e2e/encryption_at_rest_test.go | 93 ++++- 11 files changed, 352 insertions(+), 407 deletions(-) delete mode 100644 test/e2e/api/aws/aws.go diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 93d54d24d9..5536e9c3ab 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -223,11 +223,11 @@ jobs: AWS_ACCOUNT_ARN_LIST: ${{ secrets.AWS_ACCOUNT_ARN_LIST }} AWS_KMS_KEY_ID: ${{ secrets.AWS_KMS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_NEW_TEST }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET_NEW_TEST }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - GCP_SA_CRED: ${{ secrets.GCP_SA_CRED }} + GCP_SA_CRED: ${{ secrets.GCP_SA_CRED_NEW_TEST }} DATADOG_KEY: ${{ secrets.DATADOG_KEY }} run: | helm version diff --git a/go.mod b/go.mod index 628ba013da..921865ca76 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module github.com/mongodb/mongodb-atlas-kubernetes go 1.20 require ( + cloud.google.com/go/kms v1.12.1 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 github.com/Azure/go-autorest/autorest v0.11.29 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 @@ -36,9 +38,11 @@ require ( ) require ( + cloud.google.com/go/iam v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/s2a-go v0.1.4 // indirect diff --git a/go.sum b/go.sum index 51587fe846..5f2a2a7a80 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,10 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94= +cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= +cloud.google.com/go/kms v1.12.1 h1:xZmZuwy2cwzsocmKDOPu4BL7umg8QXagQx6fKVmf45U= +cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -45,6 +49,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9Orh github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0 h1:8d4U82r7ItT1Es91x3eUcAQweih36KWvUha8AZ9X0Rs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0/go.mod h1:/1bkGperHinQbAHMWivoec/Ucu6//iXo6jn5mhmqCVU= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 h1:bWh0Z2rOEDfB/ywv/l0iHN1JgyazE6kW/aIA89+CEK0= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1/go.mod h1:Bzf34hhAE9NSxailk8xVeLEZbUjOXcC+GnU1mMKdhLw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU= @@ -90,6 +96,7 @@ github.com/aws/aws-sdk-go v1.44.318 h1:Yl66rpbQHFUbxe9JBKLcvOvRivhVgP6+zH0b9KzAR github.com/aws/aws-sdk-go v1.44.318/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/pkg/api/v1/encryption_at_rest.go b/pkg/api/v1/encryption_at_rest.go index 4751c26226..13c4ba5cbc 100644 --- a/pkg/api/v1/encryption_at_rest.go +++ b/pkg/api/v1/encryption_at_rest.go @@ -94,5 +94,6 @@ func (az AzureKeyVault) ToAtlas() mongodbatlas.AzureKeyVault { KeyVaultName: az.KeyVaultName, KeyIdentifier: az.KeyIdentifier, TenantID: az.TenantID, + Secret: az.Secret, } } diff --git a/pkg/controller/atlasproject/encryption_at_rest.go b/pkg/controller/atlasproject/encryption_at_rest.go index 495c5445ae..646ba28186 100644 --- a/pkg/controller/atlasproject/encryption_at_rest.go +++ b/pkg/controller/atlasproject/encryption_at_rest.go @@ -103,14 +103,16 @@ func readAndFillGoogleSecret(kubeClient client.Client, parentNs string, gkms *md } func readAndFillAzureSecret(kubeClient client.Client, parentNs string, azureVault *mdbv1.AzureKeyVault) (*watch.WatchedObject, error) { - fieldData, watchObj, err := readSecretData(kubeClient, azureVault.SecretRef, parentNs, "ClientID", "AzureEnvironment", "SubscriptionID", "ResourceGroupName", "KeyVaultName", "KeyIdentifier") + fieldData, watchObj, err := readSecretData(kubeClient, azureVault.SecretRef, parentNs, "ClientID", "Secret", "AzureEnvironment", "SubscriptionID", "ResourceGroupName", "KeyVaultName", "KeyIdentifier", "TenantID") if err != nil { return watchObj, err } azureVault.ClientID = fieldData["ClientID"] + azureVault.Secret = fieldData["Secret"] azureVault.AzureEnvironment = fieldData["AzureEnvironment"] azureVault.SubscriptionID = fieldData["SubscriptionID"] + azureVault.TenantID = fieldData["TenantID"] azureVault.ResourceGroupName = fieldData["ResourceGroupName"] azureVault.KeyVaultName = fieldData["KeyVaultName"] azureVault.KeyIdentifier = fieldData["KeyIdentifier"] diff --git a/pkg/controller/atlasproject/encryption_at_rest_test.go b/pkg/controller/atlasproject/encryption_at_rest_test.go index 28f73969c1..b04b694900 100644 --- a/pkg/controller/atlasproject/encryption_at_rest_test.go +++ b/pkg/controller/atlasproject/encryption_at_rest_test.go @@ -211,8 +211,10 @@ func TestReadEncryptionAtRestSecrets(t *testing.T) { t.Run("Azure with correct secret data", func(t *testing.T) { secretData := map[string][]byte{ "ClientID": []byte("testClientID"), + "Secret": []byte("testClientSecret"), "AzureEnvironment": []byte("testAzureEnvironment"), "SubscriptionID": []byte("testSubscriptionID"), + "TenantID": []byte("testTenantID"), "ResourceGroupName": []byte("testResourceGroupName"), "KeyVaultName": []byte("testKeyVaultName"), "KeyIdentifier": []byte("testKeyIdentifier"), @@ -226,7 +228,7 @@ func TestReadEncryptionAtRestSecrets(t *testing.T) { APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "gcp-secret", + Name: "azure-secret", Namespace: "test", }, }, @@ -238,7 +240,7 @@ func TestReadEncryptionAtRestSecrets(t *testing.T) { AzureKeyVault: mdbv1.AzureKeyVault{ Enabled: toptr.MakePtr(true), SecretRef: common.ResourceRefNamespaced{ - Name: "gcp-secret", + Name: "azure-secret", }, }, } @@ -247,8 +249,10 @@ func TestReadEncryptionAtRestSecrets(t *testing.T) { assert.Nil(t, err) assert.Equal(t, string(secretData["ClientID"]), encRest.AzureKeyVault.ClientID) + assert.Equal(t, string(secretData["Secret"]), encRest.AzureKeyVault.Secret) assert.Equal(t, string(secretData["AzureEnvironment"]), encRest.AzureKeyVault.AzureEnvironment) assert.Equal(t, string(secretData["SubscriptionID"]), encRest.AzureKeyVault.SubscriptionID) + assert.Equal(t, string(secretData["TenantID"]), encRest.AzureKeyVault.TenantID) assert.Equal(t, string(secretData["ResourceGroupName"]), encRest.AzureKeyVault.ResourceGroupName) assert.Equal(t, string(secretData["KeyVaultName"]), encRest.AzureKeyVault.KeyVaultName) assert.Equal(t, string(secretData["KeyIdentifier"]), encRest.AzureKeyVault.KeyIdentifier) diff --git a/test/e2e/actions/cloud/aws.go b/test/e2e/actions/cloud/aws.go index 8436d7e942..f7d7ca804c 100644 --- a/test/e2e/actions/cloud/aws.go +++ b/test/e2e/actions/cloud/aws.go @@ -1,16 +1,22 @@ package cloud import ( + "encoding/json" + "errors" "fmt" + "os" + "strings" + "github.com/aws/aws-sdk-go/aws" aws_sdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/kms" "github.com/aws/aws-sdk-go/service/sts" "github.com/onsi/ginkgo/v2/dsl/core" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" - "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/api/aws" + "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/config" ) type AwsAction struct { @@ -25,13 +31,136 @@ type awsNetwork struct { Subnets []*string } -func NewAwsAction() *AwsAction { - return new(AwsAction) +type principal struct { + AWS []string `json:"AWS,omitempty"` } -func (awsAction *AwsAction) CreateKMS(region, atlasAccountArn, assumedRoleArn string) (key string, err error) { - session := aws.SessionAWS(region) - return session.GetCustomerMasterKeyID(atlasAccountArn, assumedRoleArn) +type kmsPolicy struct { + Version string `json:"Version"` + Statement []statement `json:"Statement"` +} + +type statement struct { + Sid string `json:"Sid"` + Effect string `json:"Effect"` + Principal principal `json:"Principal"` + Action []string `json:"Action"` + Resource string `json:"Resource"` +} + +func (a *AwsAction) CreateKMS(region, atlasAccountArn, assumedRoleArn string) (key string, err error) { + a.t.Helper() + + kmsClient := kms.New(a.session, aws.NewConfig().WithRegion(config.AWSRegionUS)) + + keyId, adminARNs, err := getKeyIDAndAdminARNs() + if err != nil { + return "", err + } + + policyString, err := rolePolicyString(atlasAccountArn, assumedRoleArn, adminARNs) + if err != nil { + return "", err + } + + policyInput := &kms.PutKeyPolicyInput{ + KeyId: &keyId, + PolicyName: aws_sdk.String("default"), + Policy: aws_sdk.String(policyString), + } + + _, err = kmsClient.PutKeyPolicy(policyInput) + if err != nil { + return "", err + } + + return keyId, nil +} + +func getKeyIDAndAdminARNs() (keyID string, adminARNs []string, err error) { + keyID = os.Getenv("AWS_KMS_KEY_ID") + if keyID == "" { + err = errors.New("AWS_KMS_KEY_ID secret is empty") + return + } + adminArnString := os.Getenv("AWS_ACCOUNT_ARN_LIST") + if adminArnString == "" { + err = errors.New("AWS_ACCOUNT_ARN_LIST secret is empty") + return + } + + adminARNs = strings.Split(adminArnString, ",") + if len(adminARNs) == 0 { + err = errors.New("AWS_ACCOUNT_ARN_LIST wasn't parsed properly, please separate accounts via a comma") + return + } + + return keyID, adminARNs, nil +} + +func rolePolicyString(atlasAccountARN, assumedRoleARN string, adminARNs []string) (string, error) { + policy := defaultKMSPolicy(atlasAccountARN, assumedRoleARN, adminARNs) + byteStr, err := json.Marshal(policy) + if err != nil { + return "", err + } + return string(byteStr), nil +} + +func defaultKMSPolicy(atlasAccountArn, assumedRoleArn string, adminARNs []string) kmsPolicy { + return kmsPolicy{ + Version: "2012-10-17", + Statement: []statement{ + { + Sid: "Enable IAM User Permissions", + Effect: "Allow", + Principal: principal{ + AWS: []string{atlasAccountArn}, + }, + Action: []string{"kms:*"}, + Resource: "*", + }, + { + Sid: "Allow access for Key Administrators", + Effect: "Allow", + Principal: principal{ + AWS: adminARNs, + }, + Action: []string{ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:TagResource", + "kms:UntagResource", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + }, + Resource: "*", + }, + { + Sid: "Allow use of the key", + Effect: "Allow", + Principal: principal{ + AWS: []string{assumedRoleArn}, + }, + Action: []string{ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey", + }, + Resource: "*", + }, + }, + } } func (a *AwsAction) GetAccountID() (string, error) { diff --git a/test/e2e/actions/cloud/azure.go b/test/e2e/actions/cloud/azure.go index c84af42b97..2791d2b02d 100644 --- a/test/e2e/actions/cloud/azure.go +++ b/test/e2e/actions/cloud/azure.go @@ -8,18 +8,25 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2" "github.com/onsi/ginkgo/v2/dsl/core" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" ) +const ( + AzureKeyVaultName = "ako-kms-test" +) + type AzureAction struct { t core.GinkgoTInterface resourceGroupName string network *azureNetwork + credentials *azidentity.DefaultAzureCredential - resourceFactory *armnetwork.ClientFactory + networkResourceFactory *armnetwork.ClientFactory + keyVaultResourceFactory *armkeyvault.ClientFactory } type azureNetwork struct { @@ -102,7 +109,7 @@ func (a *AzureAction) CreatePrivateEndpoint(vpcName, subnetName, endpointName, s } }) - networkClient := a.resourceFactory.NewPrivateEndpointsClient() + networkClient := a.networkResourceFactory.NewPrivateEndpointsClient() op, err := networkClient.BeginCreateOrUpdate( ctx, a.resourceGroupName, @@ -146,7 +153,7 @@ func (a *AzureAction) CreatePrivateEndpoint(vpcName, subnetName, endpointName, s func (a *AzureAction) GetPrivateEndpoint(endpointName string) (*armnetwork.PrivateEndpoint, error) { a.t.Helper() - networkClient := a.resourceFactory.NewPrivateEndpointsClient() + networkClient := a.networkResourceFactory.NewPrivateEndpointsClient() pe, err := networkClient.Get( context.Background(), a.resourceGroupName, @@ -163,7 +170,7 @@ func (a *AzureAction) GetPrivateEndpoint(endpointName string) (*armnetwork.Priva func (a *AzureAction) GetInterface(name string) (*armnetwork.Interface, error) { a.t.Helper() - interfaceClient := a.resourceFactory.NewInterfacesClient() + interfaceClient := a.networkResourceFactory.NewInterfacesClient() i, err := interfaceClient.Get( context.Background(), a.resourceGroupName, @@ -180,7 +187,7 @@ func (a *AzureAction) GetInterface(name string) (*armnetwork.Interface, error) { func (a *AzureAction) findVpc(ctx context.Context, vpcName string) (*armnetwork.VirtualNetwork, error) { a.t.Helper() - vpcClient := a.resourceFactory.NewVirtualNetworksClient() + vpcClient := a.networkResourceFactory.NewVirtualNetworksClient() vpc, err := vpcClient.Get(ctx, a.resourceGroupName, vpcName, nil) if err != nil { @@ -196,7 +203,7 @@ func (a *AzureAction) findVpc(ctx context.Context, vpcName string) (*armnetwork. func (a *AzureAction) createVpcWithSubnets(ctx context.Context, vpcName, cidr, region string, subnets map[string]string) (*armnetwork.VirtualNetwork, error) { a.t.Helper() - vpcClient := a.resourceFactory.NewVirtualNetworksClient() + vpcClient := a.networkResourceFactory.NewVirtualNetworksClient() subnetsSpec := make([]*armnetwork.Subnet, 0, len(subnets)) for name, ipRange := range subnets { @@ -245,7 +252,7 @@ func (a *AzureAction) createVpcWithSubnets(ctx context.Context, vpcName, cidr, r func (a *AzureAction) deleteVpc(ctx context.Context, vpcName string) error { a.t.Helper() - vpcClient := a.resourceFactory.NewVirtualNetworksClient() + vpcClient := a.networkResourceFactory.NewVirtualNetworksClient() op, err := vpcClient.BeginDelete( ctx, @@ -264,7 +271,7 @@ func (a *AzureAction) deleteVpc(ctx context.Context, vpcName string) error { func (a *AzureAction) createSubnet(ctx context.Context, vpcName, subnetName, ipRange string) (*armnetwork.Subnet, error) { a.t.Helper() - subnetClient := a.resourceFactory.NewSubnetsClient() + subnetClient := a.networkResourceFactory.NewSubnetsClient() op, err := subnetClient.BeginCreateOrUpdate( ctx, @@ -293,7 +300,7 @@ func (a *AzureAction) createSubnet(ctx context.Context, vpcName, subnetName, ipR func (a *AzureAction) deleteSubnet(ctx context.Context, vpcName, subnetName string) error { a.t.Helper() - subnetClient := a.resourceFactory.NewSubnetsClient() + subnetClient := a.networkResourceFactory.NewSubnetsClient() op, err := subnetClient.BeginDelete( ctx, @@ -313,7 +320,7 @@ func (a *AzureAction) deleteSubnet(ctx context.Context, vpcName, subnetName stri func (a *AzureAction) disableSubnetPENetworkPolicy(ctx context.Context, vpcName, subnetName string) (*armnetwork.Subnet, error) { a.t.Helper() - subnetClient := a.resourceFactory.NewSubnetsClient() + subnetClient := a.networkResourceFactory.NewSubnetsClient() subnet, ok := a.network.Subnets[subnetName] if !ok { @@ -343,7 +350,7 @@ func (a *AzureAction) disableSubnetPENetworkPolicy(ctx context.Context, vpcName, func (a *AzureAction) enableSubnetPENetworkPolicy(ctx context.Context, vpcName, subnetName string) (*armnetwork.Subnet, error) { a.t.Helper() - subnetClient := a.resourceFactory.NewSubnetsClient() + subnetClient := a.networkResourceFactory.NewSubnetsClient() subnet, ok := a.network.Subnets[subnetName] if !ok { @@ -373,7 +380,7 @@ func (a *AzureAction) enableSubnetPENetworkPolicy(ctx context.Context, vpcName, func (a *AzureAction) deletePrivateEndpoint(ctx context.Context, endpointName string) error { a.t.Helper() - networkClient := a.resourceFactory.NewPrivateEndpointsClient() + networkClient := a.networkResourceFactory.NewPrivateEndpointsClient() op, err := networkClient.BeginDelete( ctx, a.resourceGroupName, @@ -392,6 +399,25 @@ func (a *AzureAction) deletePrivateEndpoint(ctx context.Context, endpointName st return nil } +func (a *AzureAction) CreateKeyVault(keyName string) (string, error) { + a.t.Helper() + + ctx := context.Background() + + params := armkeyvault.KeyCreateParameters{ + Properties: &armkeyvault.KeyProperties{ + Kty: toptr.MakePtr(armkeyvault.JSONWebKeyTypeRSA), + }, + } + + r, err := a.keyVaultResourceFactory.NewKeysClient().CreateIfNotExist(ctx, a.resourceGroupName, AzureKeyVaultName, keyName, params, nil) + if err != nil { + return "", err + } + + return *r.Properties.KeyURIWithVersion, nil +} + func NewAzureAction(t core.GinkgoTInterface, subscriptionID, resourceGroupName string) (*AzureAction, error) { t.Helper() @@ -400,14 +426,21 @@ func NewAzureAction(t core.GinkgoTInterface, subscriptionID, resourceGroupName s return nil, err } - factory, err := armnetwork.NewClientFactory(subscriptionID, cred, nil) + networkFactory, err := armnetwork.NewClientFactory(subscriptionID, cred, nil) + if err != nil { + return nil, err + } + + vaultFactory, err := armkeyvault.NewClientFactory(subscriptionID, cred, nil) if err != nil { return nil, err } return &AzureAction{ - t: t, - resourceGroupName: resourceGroupName, - resourceFactory: factory, + t: t, + resourceGroupName: resourceGroupName, + networkResourceFactory: networkFactory, + keyVaultResourceFactory: vaultFactory, + credentials: cred, }, err } diff --git a/test/e2e/actions/cloud/gcp.go b/test/e2e/actions/cloud/gcp.go index 5db1ca4b39..06e8776c77 100644 --- a/test/e2e/actions/cloud/gcp.go +++ b/test/e2e/actions/cloud/gcp.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "time" "google.golang.org/api/googleapi" @@ -17,6 +18,9 @@ import ( compute "cloud.google.com/go/compute/apiv1" "cloud.google.com/go/compute/apiv1/computepb" + + kms "cloud.google.com/go/kms/apiv1" + "cloud.google.com/go/kms/apiv1/kmspb" ) type GCPAction struct { @@ -24,10 +28,11 @@ type GCPAction struct { projectID string network *gcpNetwork - networkClient *compute.NetworksClient - subnetClient *compute.SubnetworksClient - addressClient *compute.AddressesClient - forwardRuleClient *compute.ForwardingRulesClient + networkClient *compute.NetworksClient + subnetClient *compute.SubnetworksClient + addressClient *compute.AddressesClient + forwardRuleClient *compute.ForwardingRulesClient + keyManagementClient *kms.KeyManagementClient } type gcpNetwork struct { @@ -40,6 +45,7 @@ const ( GoogleProjectID = "atlasoperator" // Google Cloud Project ID googleConnectPrefix = "ao" // Private Service Connect Endpoint Prefix gcpSubnetIPMask = "10.0.0.%d" + googleKeyName = "projects/atlasoperator/locations/global/keyRings/atlas-operator-test-key-ring/cryptoKeys/encryption-at-rest-test-key" ) func (a *GCPAction) InitNetwork(vpcName, region string, subnets map[string]string, cleanup bool) (string, error) { @@ -459,6 +465,54 @@ func (a *GCPAction) deleteVPCPeering(ctx context.Context, vpcName, peerName stri return nil } +func (a *GCPAction) CreateKMS() (string, error) { + a.t.Helper() + + ctx := context.Background() + + result, err := a.keyManagementClient.CreateCryptoKeyVersion(ctx, &kmspb.CreateCryptoKeyVersionRequest{ + Parent: googleKeyName, + }) + if err != nil { + return "", err + } + + a.t.Cleanup(func() { + err = a.deleteKMS(ctx, result.Name) + if err != nil { + a.t.Error(err) + } + }) + + ver := strings.Split(result.Name, "/") + keyVersion := ver[len(ver)-1] + + _, err = a.keyManagementClient.UpdateCryptoKeyPrimaryVersion(ctx, &kmspb.UpdateCryptoKeyPrimaryVersionRequest{ + Name: googleKeyName, + CryptoKeyVersionId: keyVersion, + }) + if err != nil { + return "", err + } + + return result.Name, nil +} + +func (a *GCPAction) deleteKMS(ctx context.Context, keyName string) error { + a.t.Helper() + + req := &kmspb.DestroyCryptoKeyVersionRequest{ + Name: keyName, + } + + _, err := a.keyManagementClient.DestroyCryptoKeyVersion(ctx, req) + if err != nil { + return err + } + + return nil +} + func NewGCPAction(t core.GinkgoTInterface, projectID string) (*GCPAction, error) { t.Helper() @@ -484,13 +538,19 @@ func NewGCPAction(t core.GinkgoTInterface, projectID string) (*GCPAction, error) return nil, err } + keyManagementClient, err := kms.NewKeyManagementClient(ctx) + if err != nil { + return nil, err + } + return &GCPAction{ t: t, projectID: projectID, - networkClient: networkClient, - subnetClient: subnetClient, - addressClient: addressClient, - forwardRuleClient: forwardRuleClient, + networkClient: networkClient, + subnetClient: subnetClient, + addressClient: addressClient, + forwardRuleClient: forwardRuleClient, + keyManagementClient: keyManagementClient, }, nil } diff --git a/test/e2e/api/aws/aws.go b/test/e2e/api/aws/aws.go deleted file mode 100644 index a98564315c..0000000000 --- a/test/e2e/api/aws/aws.go +++ /dev/null @@ -1,354 +0,0 @@ -package aws - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "strings" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - - "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/config" - - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/kms" -) - -type sessionAWS struct { - ec2 *ec2.EC2 - kms *kms.KMS -} - -func SessionAWS(region string) sessionAWS { - session, err := session.NewSession(&aws.Config{ - Region: aws.String(region), - }) - if err != nil { - fmt.Println(err) - } - svc := ec2.New(session) - kms := kms.New(session) - return sessionAWS{svc, kms} -} - -func (s sessionAWS) GetVPCID() (string, error) { - input := &ec2.DescribeVpcsInput{ - Filters: []*ec2.Filter{{ - Name: aws.String("tag:Name"), - Values: []*string{ - aws.String(config.TagName), - }, - }}, - } - result, err := s.ec2.DescribeVpcs(input) - if err != nil { - return "", getError(err) - } - if len(result.Vpcs) < 1 { - return "", errors.New("can not find VPC") - } - fmt.Println(result) - return *result.Vpcs[0].VpcId, nil -} - -func (s sessionAWS) CreateVPC(testID string) (string, error) { - input := &ec2.CreateVpcInput{ - AmazonProvidedIpv6CidrBlock: aws.Bool(false), - CidrBlock: aws.String("10.0.0.0/24"), - TagSpecifications: []*ec2.TagSpecification{{ - ResourceType: aws.String(ec2.ResourceTypeVpc), - Tags: []*ec2.Tag{ - {Key: aws.String("Name"), Value: aws.String(config.TagName)}, - {Key: aws.String("Test"), Value: aws.String(testID)}, - }, - }}, - } - result, err := s.ec2.CreateVpc(input) - if err != nil { - return "", getError(err) - } - fmt.Println(result) - return *result.Vpc.VpcId, nil -} - -func (s sessionAWS) DescribeVPCStatus(vpcID string) (string, error) { - input := &ec2.DescribeVpcsInput{ - DryRun: aws.Bool(false), - VpcIds: []*string{aws.String(vpcID)}, - } - result, err := s.ec2.DescribeVpcs(input) - if err != nil { - return "", getError(err) - } - return *result.Vpcs[0].State, nil -} - -func (s sessionAWS) DeleteVPC(vpcID string) error { - input := &ec2.DeleteVpcInput{ - DryRun: aws.Bool(false), - VpcId: aws.String(vpcID), - } - _, err := s.ec2.DeleteVpc(input) - if err != nil { - return getError(err) - } - return nil -} - -func (s sessionAWS) GetOrCreateSubnetIDForVpc(vpcID string) (string, error) { - input := &ec2.DescribeSubnetsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("vpc-id"), - Values: []*string{ - aws.String(vpcID), - }, - }, - }, - } - - result, err := s.ec2.DescribeSubnets(input) - if err != nil { - return "", getError(err) - } - - if len(result.Subnets) > 0 { - return *result.Subnets[0].SubnetId, nil - } - - return s.CreateSubnet(vpcID, "10.0.0.0/24", "pe-aws-test") -} - -func (s sessionAWS) CreateSubnet(vpcID, cidr, testID string) (string, error) { - input := &ec2.CreateSubnetInput{ - CidrBlock: aws.String(cidr), - TagSpecifications: []*ec2.TagSpecification{{ - ResourceType: aws.String(ec2.ResourceTypeSubnet), - Tags: []*ec2.Tag{ - {Key: aws.String("Name"), Value: aws.String(config.TagName)}, - {Key: aws.String("Test"), Value: aws.String(testID)}, - }, - }}, - VpcId: aws.String(vpcID), - } - result, err := s.ec2.CreateSubnet(input) - if err != nil { - return "", getError(err) - } - fmt.Println(result) - return *result.Subnet.SubnetId, nil -} - -func (s sessionAWS) DescribeSubnetStatus(subnetID string) (string, error) { - input := &ec2.DescribeSubnetsInput{ - SubnetIds: []*string{aws.String(subnetID)}, - } - result, err := s.ec2.DescribeSubnets(input) - if err != nil { - return "", getError(err) - } - return *result.Subnets[0].State, nil -} - -func (s sessionAWS) DeleteSubnet(subnetID string) error { - input := &ec2.DeleteSubnetInput{ - SubnetId: aws.String(subnetID), - } - _, err := s.ec2.DeleteSubnet(input) - if err != nil { - return getError(err) - } - return nil -} - -func (s sessionAWS) CreatePrivateEndpoint(vpcID, subnetID, serviceName, testID string) (string, error) { - input := &ec2.CreateVpcEndpointInput{ - ServiceName: aws.String(serviceName), - SubnetIds: []*string{aws.String(subnetID)}, - TagSpecifications: []*ec2.TagSpecification{{ - ResourceType: aws.String(ec2.ResourceTypeVpcEndpoint), - Tags: []*ec2.Tag{ - {Key: aws.String("Name"), Value: aws.String(config.TagName)}, - {Key: aws.String("Test"), Value: aws.String(testID)}, - {Key: aws.String(config.TagForTestKey), Value: aws.String(config.TagForTestValue)}, - }, - }}, - VpcEndpointType: aws.String("Interface"), - VpcId: aws.String(vpcID), - } - result, err := s.ec2.CreateVpcEndpoint(input) - if err != nil { - return "", getError(err) - } - fmt.Println(result) - return *result.VpcEndpoint.VpcEndpointId, nil -} - -func (s sessionAWS) DescribePrivateEndpointStatus(endpointID string) (string, error) { - input := &ec2.DescribeVpcEndpointsInput{ - VpcEndpointIds: []*string{aws.String(endpointID)}, - } - result, err := s.ec2.DescribeVpcEndpoints(input) - if err != nil { - return "", getError(err) - } - return *result.VpcEndpoints[0].State, nil -} - -func (s sessionAWS) DeletePrivateLink(endpointID string) error { - input := &ec2.DeleteVpcEndpointsInput{ - VpcEndpointIds: []*string{aws.String(endpointID)}, - } - _, err := s.ec2.DeleteVpcEndpoints(input) - if err != nil { - return getError(err) - } - return nil -} - -func getError(err error) error { - if aerr, ok := err.(awserr.Error); ok { //nolint - return aerr - } - return err -} - -func (s sessionAWS) GetFuncPrivateEndpointStatus(privateEndpointID string) func() string { - return func() string { - r, err := s.DescribePrivateEndpointStatus(privateEndpointID) - if err != nil { - return "" - } - return r - } -} - -func (s sessionAWS) GetCustomerMasterKeyID(atlasAccountArn, assumedRoleArn string) (keyId string, err error) { - keyId, adminARNs, err := getKeyIDAndAdminARNs() - if err != nil { - return "", err - } - - policyString, err := RolePolicyString(atlasAccountArn, assumedRoleArn, adminARNs) - if err != nil { - return "", err - } - - policyInput := &kms.PutKeyPolicyInput{ - KeyId: &keyId, - PolicyName: aws.String("default"), - Policy: aws.String(policyString), - } - _, err = s.kms.PutKeyPolicy(policyInput) - if err != nil { - return "", err - } - - return keyId, nil -} - -func getKeyIDAndAdminARNs() (keyID string, adminARNs []string, err error) { - keyID = os.Getenv("AWS_KMS_KEY_ID") - if keyID == "" { - err = errors.New("AWS_KMS_KEY_ID secret is empty") - return - } - adminArnString := os.Getenv("AWS_ACCOUNT_ARN_LIST") - if adminArnString == "" { - err = errors.New("AWS_ACCOUNT_ARN_LIST secret is empty") - return - } - - adminARNs = strings.Split(adminArnString, ",") - if len(adminARNs) == 0 { - err = errors.New("AWS_ACCOUNT_ARN_LIST wasn't parsed properly, please separate accounts via a comma") - return - } - - return keyID, adminARNs, nil -} - -func RolePolicyString(atlasAccountARN, assumedRoleARN string, adminARNs []string) (string, error) { - policy := defaultKMSPolicy(atlasAccountARN, assumedRoleARN, adminARNs) - byteStr, err := json.Marshal(policy) - if err != nil { - return "", err - } - return string(byteStr), nil -} - -func defaultKMSPolicy(atlasAccountArn, assumedRoleArn string, adminARNs []string) kmsPolicy { - return kmsPolicy{ - Version: "2012-10-17", - Statement: []statement{ - { - Sid: "Enable IAM User Permissions", - Effect: "Allow", - Principal: principal{ - AWS: []string{atlasAccountArn}, - }, - Action: []string{"kms:*"}, - Resource: "*", - }, - { - Sid: "Allow access for Key Administrators", - Effect: "Allow", - Principal: principal{ - AWS: adminARNs, - }, - Action: []string{ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:TagResource", - "kms:UntagResource", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion", - }, - Resource: "*", - }, - { - Sid: "Allow use of the key", - Effect: "Allow", - Principal: principal{ - AWS: []string{assumedRoleArn}, - }, - Action: []string{ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey", - }, - Resource: "*", - }, - }, - } -} - -type kmsPolicy struct { - Version string `json:"Version"` - Statement []statement `json:"Statement"` -} - -type statement struct { - Sid string `json:"Sid"` - Effect string `json:"Effect"` - Principal principal `json:"Principal"` - Action []string `json:"Action"` - Resource string `json:"Resource"` -} - -type principal struct { - AWS []string `json:"AWS,omitempty"` -} diff --git a/test/e2e/encryption_at_rest_test.go b/test/e2e/encryption_at_rest_test.go index d1c941e380..281af19a31 100644 --- a/test/e2e/encryption_at_rest_test.go +++ b/test/e2e/encryption_at_rest_test.go @@ -35,11 +35,21 @@ import ( "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/utils" ) +const ( + AzureClientID = "AZURE_CLIENT_ID" + KeyVaultName = "ako-kms-test" + AzureClientSecret = "AZURE_CLIENT_SECRET" //#nosec G101 -- False positive; this is the env var, not the secret itself + AzureEnvironment = "AZURE" + KeyName = "encryption-at-rest-test-key" +) + var _ = Describe("Encryption at REST test", Label("encryption-at-rest"), func() { var testData *model.TestDataProvider _ = BeforeEach(func() { checkUpAWSEnvironment() + checkUpAzureEnvironment() + checkNSetUpGCPEnvironment() }) _ = AfterEach(func() { @@ -64,7 +74,13 @@ var _ = Describe("Encryption at REST test", Label("encryption-at-rest"), func() func(test *model.TestDataProvider, encAtRest v1.EncryptionAtRest, roles []cloudaccess.Role) { testData = test actions.ProjectCreationFlow(test) - encryptionAtRestFlow(test, encAtRest, roles) + + if roles != nil { + cloudAccessRolesFlow(test, roles) + encAtRest.AwsKms.RoleID = test.Project.Status.CloudProviderAccessRoles[0].IamAssumedRoleArn + } + + encryptionAtRestFlow(test, encAtRest) }, Entry("Test[encryption-at-rest-aws]: Can add Encryption at Rest to AWS project", Label("encryption-at-rest-aws"), model.DataProvider( @@ -76,9 +92,7 @@ var _ = Describe("Encryption at REST test", Label("encryption-at-rest"), func() v1.EncryptionAtRest{ AwsKms: v1.AwsKms{ Enabled: toptr.MakePtr(true), - // CustomerMasterKeyID: "", - Region: "US_EAST_1", - Valid: toptr.MakePtr(true), + Region: "US_EAST_1", }, }, []cloudaccess.Role{ @@ -90,20 +104,54 @@ var _ = Describe("Encryption at REST test", Label("encryption-at-rest"), func() }, }, ), + Entry("Test[encryption-at-rest-azure]: Can add Encryption at Rest to Azure project", Label("encryption-at-rest-azure"), + model.DataProvider( + "encryption-at-rest-azure", + model.NewEmptyAtlasKeyType().UseDefaultFullAccess(), + 40000, + []func(*model.TestDataProvider){}, + ).WithProject(data.DefaultProject()), + v1.EncryptionAtRest{ + AzureKeyVault: v1.AzureKeyVault{ + AzureEnvironment: AzureEnvironment, + ClientID: os.Getenv(AzureClientID), + Enabled: toptr.MakePtr(true), + KeyVaultName: KeyVaultName, + ResourceGroupName: cloud.ResourceGroupName, + Secret: os.Getenv(AzureClientSecret), + TenantID: os.Getenv(DirectoryID), + SubscriptionID: os.Getenv(SubscriptionID), + }, + }, + nil, + ), + Entry("Test[encryption-at-rest-gcp]: Can add Encryption at Rest to GCP project", Label("encryption-at-rest-gcp"), + model.DataProvider( + "encryption-at-rest-gcp", + model.NewEmptyAtlasKeyType().UseDefaultFullAccess(), + 40000, + []func(*model.TestDataProvider){}, + ).WithProject(data.DefaultProject()), + v1.EncryptionAtRest{ + GoogleCloudKms: v1.GoogleCloudKms{ + Enabled: toptr.MakePtr(true), + ServiceAccountKey: os.Getenv("GCP_SA_CRED"), + }, + }, + nil, + ), ) }) -func encryptionAtRestFlow(userData *model.TestDataProvider, encAtRest v1.EncryptionAtRest, roles []cloudaccess.Role) { - By("Add cloud access role (AWS only)", func() { - cloudAccessRolesFlow(userData, roles) - }) - +func encryptionAtRestFlow(userData *model.TestDataProvider, encAtRest v1.EncryptionAtRest) { By("Create KMS", func() { Expect(userData.K8SClient.Get(userData.Context, types.NamespacedName{Name: userData.Project.Name, Namespace: userData.Resources.Namespace}, userData.Project)).Should(Succeed()) - Expect(len(userData.Project.Status.CloudProviderAccessRoles)).NotTo(Equal(0)) - aRole := userData.Project.Status.CloudProviderAccessRoles[0] + var aRole status.CloudProviderAccessRole + if len(userData.Project.Status.CloudProviderAccessRoles) > 0 { + aRole = userData.Project.Status.CloudProviderAccessRoles[0] + } fillKMSforAWS(&encAtRest, aRole.AtlasAWSAccountArn, aRole.IamAssumedRoleArn) fillVaultforAzure(&encAtRest) @@ -146,7 +194,8 @@ func fillKMSforAWS(encAtRest *v1.EncryptionAtRest, atlasAccountArn, assumedRoleA } Expect(encAtRest.AwsKms.Region).NotTo(Equal("")) - awsAction := cloud.NewAwsAction() + awsAction, err := cloud.NewAWSAction(GinkgoT()) + Expect(err).ToNot(HaveOccurred()) CustomerMasterKeyID, err := awsAction.CreateKMS(config.AWSRegionUS, atlasAccountArn, assumedRoleArn) Expect(err).ToNot(HaveOccurred()) Expect(CustomerMasterKeyID).NotTo(Equal("")) @@ -159,7 +208,13 @@ func fillVaultforAzure(encAtRest *v1.EncryptionAtRest) { return } - // todo: fill in + azAction, err := cloud.NewAzureAction(GinkgoT(), os.Getenv(SubscriptionID), cloud.ResourceGroupName) + Expect(err).ToNot(HaveOccurred()) + + keyID, err := azAction.CreateKeyVault(KeyName) + Expect(err).ToNot(HaveOccurred()) + + encAtRest.AzureKeyVault.KeyIdentifier = keyID } func fillKMSforGCP(encAtRest *v1.EncryptionAtRest) { @@ -167,7 +222,13 @@ func fillKMSforGCP(encAtRest *v1.EncryptionAtRest) { return } - // todo: fill in + gcpAction, err := cloud.NewGCPAction(GinkgoT(), cloud.GoogleProjectID) + Expect(err).ToNot(HaveOccurred()) + + keyID, err := gcpAction.CreateKMS() + Expect(err).ToNot(HaveOccurred()) + + encAtRest.GoogleCloudKms.KeyVersionResourceID = keyID } func removeAllEncryptionsSeparately(encAtRest *v1.EncryptionAtRest) { @@ -198,7 +259,7 @@ func checkIfEncryptionsAreDisabled(projectID string) (areEmpty bool, err error) return true, nil } -var _ = Describe("Encryption at rest AWS", Label("encryption-at-rest"), func() { +var _ = Describe("Encryption at rest AWS", Label("encryption-at-rest"), Ordered, func() { var testData *model.TestDataProvider _ = BeforeEach(func() { @@ -245,7 +306,6 @@ var _ = Describe("Encryption at rest AWS", Label("encryption-at-rest"), func() { AwsKms: v1.AwsKms{ Enabled: toptr.MakePtr(true), Region: "US_EAST_1", - Valid: toptr.MakePtr(true), }, } @@ -329,7 +389,6 @@ var _ = Describe("Encryption at rest AWS", Label("encryption-at-rest"), func() { encAtRest := v1.EncryptionAtRest{ AwsKms: v1.AwsKms{ Enabled: toptr.MakePtr(true), - Valid: toptr.MakePtr(true), }, } From 00050f2fe7e9661c17ac69acda92d23f27ec699b Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 9 Aug 2023 17:23:56 +0200 Subject: [PATCH 52/60] Fixed missing CRD changes for EaR secret refs (#1076) --- .../atlas.mongodb.com_atlasprojects.yaml | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/config/crd/bases/atlas.mongodb.com_atlasprojects.yaml b/config/crd/bases/atlas.mongodb.com_atlasprojects.yaml index 7d3765bb47..5b5ec7a00f 100644 --- a/config/crd/bases/atlas.mongodb.com_atlasprojects.yaml +++ b/config/crd/bases/atlas.mongodb.com_atlasprojects.yaml @@ -453,6 +453,20 @@ spec: type: string secretAccessKey: type: string + secretRef: + description: A reference to as Secret containing the AccessKeyID, + SecretAccessKey, CustomerMasterKey and RoleID fields + properties: + name: + description: Name is the name of the Kubernetes Resource + type: string + namespace: + description: Namespace is the namespace of the Kubernetes + Resource + type: string + required: + - name + type: object valid: type: boolean type: object @@ -475,6 +489,20 @@ spec: type: string secret: type: string + secretRef: + description: A reference to as Secret containing the SubscriptionID, + KeyVaultName, KeyIdentifier, Secret fields + properties: + name: + description: Name is the name of the Kubernetes Resource + type: string + namespace: + description: Namespace is the namespace of the Kubernetes + Resource + type: string + required: + - name + type: object subscriptionID: type: string tenantID: @@ -488,6 +516,20 @@ spec: type: boolean keyVersionResourceID: type: string + secretRef: + description: A reference to as Secret containing the ServiceAccountKey, + KeyVersionResourceID fields + properties: + name: + description: Name is the name of the Kubernetes Resource + type: string + namespace: + description: Namespace is the namespace of the Kubernetes + Resource + type: string + required: + - name + type: object serviceAccountKey: type: string type: object From 32cb2b7630c4dc646f727ccf3f348861c6a6a316 Mon Sep 17 00:00:00 2001 From: josvaz Date: Wed, 9 Aug 2023 19:43:29 +0200 Subject: [PATCH 53/60] Manually bump Atlas client to version 0.32 (#1077) --- go.mod | 1 - go.sum | 1 - test/e2e/api/atlas/atlas.go | 8 ++++---- test/e2e/encryption_at_rest_test.go | 2 +- test/e2e/integration_test.go | 6 +++--- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 921865ca76..724143ea66 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,6 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/s2a-go v0.1.4 // indirect diff --git a/go.sum b/go.sum index 5f2a2a7a80..f229b4c814 100644 --- a/go.sum +++ b/go.sum @@ -96,7 +96,6 @@ github.com/aws/aws-sdk-go v1.44.318 h1:Yl66rpbQHFUbxe9JBKLcvOvRivhVgP6+zH0b9KzAR github.com/aws/aws-sdk-go v1.44.318/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/test/e2e/api/atlas/atlas.go b/test/e2e/api/atlas/atlas.go index 95227a057b..b5e7b8a709 100644 --- a/test/e2e/api/atlas/atlas.go +++ b/test/e2e/api/atlas/atlas.go @@ -166,12 +166,12 @@ func ginkgoPrettyPrintf(obj interface{}, msg string, formatArgs ...interface{}) ginkgo.GinkgoWriter.Println(debug.PrettyString(obj)) } -func (a *Atlas) GetIntegrationbyType(projectId, iType string) (*mongodbatlas.ThirdPartyIntegration, error) { - integraion, _, err := a.Client.Integrations.Get(context.Background(), projectId, iType) +func (a *Atlas) GetIntegrationByType(projectId, iType string) (*mongodbatlas.ThirdPartyIntegration, error) { + integration, _, err := a.Client.Integrations.Get(context.Background(), projectId, iType) if err != nil { return nil, err } - return integraion, nil + return integration, nil } func (a *Atlas) GetUserByName(database, projectID, username string) (*mongodbatlas.DatabaseUser, error) { @@ -190,7 +190,7 @@ func (a *Atlas) DeleteGlobalKey(key mongodbatlas.APIKey) error { return nil } -func (a *Atlas) GetEncryptioAtRest(projectID string) (*mongodbatlas.EncryptionAtRest, error) { +func (a *Atlas) GetEncryptionAtRest(projectID string) (*mongodbatlas.EncryptionAtRest, error) { encryptionAtRest, _, err := a.Client.EncryptionsAtRest.Get(context.Background(), projectID) if err != nil { return nil, err diff --git a/test/e2e/encryption_at_rest_test.go b/test/e2e/encryption_at_rest_test.go index 281af19a31..964e3287f3 100644 --- a/test/e2e/encryption_at_rest_test.go +++ b/test/e2e/encryption_at_rest_test.go @@ -239,7 +239,7 @@ func removeAllEncryptionsSeparately(encAtRest *v1.EncryptionAtRest) { func checkIfEncryptionsAreDisabled(projectID string) (areEmpty bool, err error) { atlasClient := atlas.GetClientOrFail() - encryptionAtRest, err := atlasClient.GetEncryptioAtRest(projectID) + encryptionAtRest, err := atlasClient.GetEncryptionAtRest(projectID) if err != nil { return false, err } diff --git a/test/e2e/integration_test.go b/test/e2e/integration_test.go index ea456a3d41..cd9489b345 100644 --- a/test/e2e/integration_test.go +++ b/test/e2e/integration_test.go @@ -59,7 +59,7 @@ var _ = Describe("Configuration namespaced. Deploy deployment", Label("integrati func integrationCycle(data *model.TestDataProvider, key string) { integrationType := "DATADOG" - By("Deploy User Resouces", func() { + By("Deploy User Resources", func() { projectStatus := GetProjectIntegrationStatus(data) Expect(projectStatus).Should(BeEmpty()) }) @@ -94,7 +94,7 @@ func integrationCycle(data *model.TestDataProvider, key string) { Expect(err).ShouldNot(HaveOccurred()) - dog, err := atlasClient.GetIntegrationbyType(data.Project.ID(), integrationType) + dog, err := atlasClient.GetIntegrationByType(data.Project.ID(), integrationType) Expect(err).ShouldNot(HaveOccurred()) Expect(strings.HasSuffix(key, removeStarsFromString(dog.APIKey))).Should(BeTrue()) }) @@ -108,7 +108,7 @@ func integrationCycle(data *model.TestDataProvider, key string) { }) By("Delete integration check", func() { - integration, err := atlasClient.GetIntegrationbyType(data.Project.ID(), integrationType) + integration, err := atlasClient.GetIntegrationByType(data.Project.ID(), integrationType) Expect(err).Should(HaveOccurred()) Expect(integration).To(BeNil()) From 05aa2d3fef1b4fade98030d71f41a20fe0728efa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 22:42:59 +0200 Subject: [PATCH 54/60] Release 1.8.1 (#1078) --- .../mongodb-atlas-kubernetes.clusterserviceversion.yaml | 2 +- third_party_licenses.txt | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml b/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml index cacc2e5780..5ca60db1b9 100644 --- a/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml +++ b/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml @@ -576,4 +576,4 @@ spec: provider: name: MongoDB, Inc version: 1.8.1 - replaces: mongodb-atlas-kubernetes.v1.8.0 + replaces: mongodb-atlas-kubernetes.v1.8.1 diff --git a/third_party_licenses.txt b/third_party_licenses.txt index fe2ed39866..36d77348b6 100644 --- a/third_party_licenses.txt +++ b/third_party_licenses.txt @@ -35,10 +35,9 @@ github.com/prometheus/common,https://github.com/prometheus/common/blob/v0.37.0/L github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg,https://github.com/prometheus/common/blob/v0.37.0/internal/bitbucket.org/ww/goautoneg/README.txt,BSD-3-Clause github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/v0.8.0/LICENSE,Apache-2.0 github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3-Clause -go.mongodb.org/atlas/mongodbatlas,https://github.com/mongodb/go-client-mongodb-atlas/blob/v0.31.0/LICENSE,Apache-2.0 -go.uber.org/atomic,https://github.com/uber-go/atomic/blob/v1.9.0/LICENSE.txt,MIT -go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.7.0/LICENSE.txt,MIT -go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.24.0/LICENSE.txt,MIT +go.mongodb.org/atlas/mongodbatlas,https://github.com/mongodb/go-client-mongodb-atlas/blob/v0.32.0/LICENSE,Apache-2.0 +go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.10.0/LICENSE.txt,MIT +go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.25.0/LICENSE.txt,MIT golang.org/x/exp,https://cs.opensource.google/go/x/exp/+/2e198f4a:LICENSE,BSD-3-Clause golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.12.0:LICENSE,BSD-3-Clause golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/v0.10.0:LICENSE,BSD-3-Clause From 382ed43db462c64fcb23286e4c30d25dfd9763a5 Mon Sep 17 00:00:00 2001 From: Helder Santana Date: Thu, 10 Aug 2023 19:10:27 +0200 Subject: [PATCH 55/60] Fix renamed fields of CPA client (#1079) --- .../atlasproject/cloud_provider_access_test.go | 18 +++++++++--------- test/e2e/project_deletion_protection_test.go | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/controller/atlasproject/cloud_provider_access_test.go b/pkg/controller/atlasproject/cloud_provider_access_test.go index 3b4dd872f4..47058a883e 100644 --- a/pkg/controller/atlasproject/cloud_provider_access_test.go +++ b/pkg/controller/atlasproject/cloud_provider_access_test.go @@ -22,15 +22,15 @@ func (c *cloudProviderAccessClient) ListRoles(_ context.Context, projectID strin return c.ListRolesFunc(projectID) } -func (c *cloudProviderAccessClient) GetRole(_ context.Context, _ string, _ string) (*mongodbatlas.AWSIAMRole, *mongodbatlas.Response, error) { +func (c *cloudProviderAccessClient) GetRole(_ context.Context, _ string, _ string) (*mongodbatlas.CloudProviderAccessRole, *mongodbatlas.Response, error) { return nil, nil, nil } -func (c *cloudProviderAccessClient) CreateRole(_ context.Context, _ string, _ *mongodbatlas.CloudProviderAccessRoleRequest) (*mongodbatlas.AWSIAMRole, *mongodbatlas.Response, error) { +func (c *cloudProviderAccessClient) CreateRole(_ context.Context, _ string, _ *mongodbatlas.CloudProviderAccessRoleRequest) (*mongodbatlas.CloudProviderAccessRole, *mongodbatlas.Response, error) { return nil, nil, nil } -func (c *cloudProviderAccessClient) AuthorizeRole(_ context.Context, _ string, _ string, _ *mongodbatlas.CloudProviderAuthorizationRequest) (*mongodbatlas.AWSIAMRole, *mongodbatlas.Response, error) { +func (c *cloudProviderAccessClient) AuthorizeRole(_ context.Context, _ string, _ string, _ *mongodbatlas.CloudProviderAccessRoleRequest) (*mongodbatlas.CloudProviderAccessRole, *mongodbatlas.Response, error) { return nil, nil, nil } func (c *cloudProviderAccessClient) DeauthorizeRole(_ context.Context, _ *mongodbatlas.CloudProviderDeauthorizationRequest) (*mongodbatlas.Response, error) { @@ -73,7 +73,7 @@ func TestCanCloudProviderAccessReconcile(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{}, + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{}, }, nil, nil }, }, @@ -91,7 +91,7 @@ func TestCanCloudProviderAccessReconcile(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{ + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{ { ProviderName: "AWS", IAMAssumedRoleARN: "arn1", @@ -123,7 +123,7 @@ func TestCanCloudProviderAccessReconcile(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{ + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{ { ProviderName: "AWS", IAMAssumedRoleARN: "arn1", @@ -163,7 +163,7 @@ func TestCanCloudProviderAccessReconcile(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{ + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{ { ProviderName: "AWS", }, @@ -194,7 +194,7 @@ func TestCanCloudProviderAccessReconcile(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{ + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{ { ProviderName: "AWS", IAMAssumedRoleARN: "arn1", @@ -254,7 +254,7 @@ func TestEnsureCloudProviderAccess(t *testing.T) { CloudProviderAccess: &cloudProviderAccessClient{ ListRolesFunc: func(projectID string) (*mongodbatlas.CloudProviderAccessRoles, *mongodbatlas.Response, error) { return &mongodbatlas.CloudProviderAccessRoles{ - AWSIAMRoles: []mongodbatlas.AWSIAMRole{ + AWSIAMRoles: []mongodbatlas.CloudProviderAccessRole{ { ProviderName: "AWS", IAMAssumedRoleARN: "arn1", diff --git a/test/e2e/project_deletion_protection_test.go b/test/e2e/project_deletion_protection_test.go index 24618307d5..53158ee7a3 100644 --- a/test/e2e/project_deletion_protection_test.go +++ b/test/e2e/project_deletion_protection_test.go @@ -24,6 +24,7 @@ import ( "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/connectionsecret" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/testutil" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/actions" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/actions/cloud" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/actions/cloudaccess" @@ -122,9 +123,9 @@ var _ = Describe("Project Deletion Protection", Label("project", "deletion-prote ctx, projectID, cloudProvider.RoleID, - &mongodbatlas.CloudProviderAuthorizationRequest{ + &mongodbatlas.CloudProviderAccessRoleRequest{ ProviderName: "AWS", - IAMAssumedRoleARN: assumedRoleArn, + IAMAssumedRoleARN: toptr.MakePtr(assumedRoleArn), }, ) g.Expect(err).ToNot(HaveOccurred()) From f58fe9e2630e9214ca42ddc17e922db5dc3dbf42 Mon Sep 17 00:00:00 2001 From: Helder Santana Date: Fri, 11 Aug 2023 07:47:27 +0200 Subject: [PATCH 56/60] Fix Auditing comparison to avoid reconcile in every loop (#1081) --- pkg/api/v1/auditing.go | 18 ++- pkg/api/v1/zz_generated.deepcopy.go | 15 +-- pkg/controller/atlasproject/auditing_test.go | 122 +++++++++++++++++++ test/e2e/auditing_test.go | 5 +- 4 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 pkg/controller/atlasproject/auditing_test.go diff --git a/pkg/api/v1/auditing.go b/pkg/api/v1/auditing.go index 0b02b789ac..75dc085294 100644 --- a/pkg/api/v1/auditing.go +++ b/pkg/api/v1/auditing.go @@ -1,24 +1,30 @@ package v1 -import "go.mongodb.org/atlas/mongodbatlas" +import ( + "strings" + + "go.mongodb.org/atlas/mongodbatlas" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" +) // Auditing represents MongoDB Maintenance Windows type Auditing struct { // Indicates whether the auditing system captures successful authentication attempts for audit filters using the "atype" : "authCheck" auditing event. For more information, see auditAuthorizationSuccess // +optional - AuditAuthorizationSuccess *bool `json:"auditAuthorizationSuccess,omitempty"` + AuditAuthorizationSuccess bool `json:"auditAuthorizationSuccess,omitempty"` // JSON-formatted audit filter used by the project // +optional AuditFilter string `json:"auditFilter,omitempty"` // Denotes whether or not the project associated with the {GROUP-ID} has database auditing enabled. // +optional - Enabled *bool `json:"enabled,omitempty"` + Enabled bool `json:"enabled,omitempty"` } func (a Auditing) ToAtlas() *mongodbatlas.Auditing { return &mongodbatlas.Auditing{ - AuditAuthorizationSuccess: a.AuditAuthorizationSuccess, - AuditFilter: a.AuditFilter, - Enabled: a.Enabled, + AuditAuthorizationSuccess: toptr.MakePtr(a.AuditAuthorizationSuccess), + AuditFilter: strings.Trim(a.AuditFilter, "\n"), + Enabled: toptr.MakePtr(a.Enabled), } } diff --git a/pkg/api/v1/zz_generated.deepcopy.go b/pkg/api/v1/zz_generated.deepcopy.go index d0f1ff6819..03055b580b 100644 --- a/pkg/api/v1/zz_generated.deepcopy.go +++ b/pkg/api/v1/zz_generated.deepcopy.go @@ -14,9 +14,10 @@ a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 package v1 import ( + "k8s.io/apimachinery/pkg/runtime" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/project" - "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -824,7 +825,7 @@ func (in *AtlasProjectSpec) DeepCopyInto(out *AtlasProjectSpec) { if in.Auditing != nil { in, out := &in.Auditing, &out.Auditing *out = new(Auditing) - (*in).DeepCopyInto(*out) + **out = **in } if in.Settings != nil { in, out := &in.Settings, &out.Settings @@ -919,16 +920,6 @@ func (in *AtlasTeamList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auditing) DeepCopyInto(out *Auditing) { *out = *in - if in.AuditAuthorizationSuccess != nil { - in, out := &in.AuditAuthorizationSuccess, &out.AuditAuthorizationSuccess - *out = new(bool) - **out = **in - } - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auditing. diff --git a/pkg/controller/atlasproject/auditing_test.go b/pkg/controller/atlasproject/auditing_test.go new file mode 100644 index 0000000000..5ecd87ffbd --- /dev/null +++ b/pkg/controller/atlasproject/auditing_test.go @@ -0,0 +1,122 @@ +package atlasproject + +import ( + "testing" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + + "github.com/stretchr/testify/assert" + "go.mongodb.org/atlas/mongodbatlas" + + v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" +) + +func Test_auditingInSync(t *testing.T) { + type args struct { + atlas *mongodbatlas.Auditing + spec *v1.Auditing + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Atlas and Operator Auditing are empty", + args: args{ + atlas: nil, + spec: nil, + }, + want: true, + }, + { + name: "Atlas Auditing is empty and Operator doesn't", + args: args{ + atlas: nil, + spec: &v1.Auditing{Enabled: true}, + }, + want: false, + }, + { + name: "Operator Auditing is empty and Atlas doesn't", + args: args{ + atlas: &mongodbatlas.Auditing{Enabled: toptr.MakePtr(true)}, + spec: nil, + }, + want: false, + }, + { + name: "Operator Auditing has different config from Atlas", + args: args{ + atlas: &mongodbatlas.Auditing{ + AuditAuthorizationSuccess: toptr.MakePtr(false), + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + ConfigurationType: "ReadOnly", + Enabled: toptr.MakePtr(true), + }, + spec: &v1.Auditing{ + AuditAuthorizationSuccess: true, + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + Enabled: true, + }, + }, + want: false, + }, + { + name: "Operator Auditing has different config filter from Atlas", + args: args{ + atlas: &mongodbatlas.Auditing{ + AuditAuthorizationSuccess: toptr.MakePtr(false), + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + ConfigurationType: "ReadOnly", + Enabled: toptr.MakePtr(true), + }, + spec: &v1.Auditing{ + AuditAuthorizationSuccess: false, + AuditFilter: `{"atype":"authenticate","param":{"db":"admin","mechanism":"SCRAM-SHA-1"}}`, + Enabled: true, + }, + }, + want: false, + }, + { + name: "Operator Auditing are Equal", + args: args{ + atlas: &mongodbatlas.Auditing{ + AuditAuthorizationSuccess: toptr.MakePtr(false), + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + ConfigurationType: "ReadOnly", + Enabled: toptr.MakePtr(true), + }, + spec: &v1.Auditing{ + AuditAuthorizationSuccess: false, + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + Enabled: true, + }, + }, + want: true, + }, + { + name: "Operator Auditing are Equal when filter has newline in the end", + args: args{ + atlas: &mongodbatlas.Auditing{ + AuditAuthorizationSuccess: toptr.MakePtr(false), + AuditFilter: `{"atype":"authenticate","param":{"user":"auditReadOnly","db":"admin","mechanism":"SCRAM-SHA-1"}}`, + ConfigurationType: "ReadOnly", + Enabled: toptr.MakePtr(true), + }, + spec: &v1.Auditing{ + AuditAuthorizationSuccess: false, + AuditFilter: "{\"atype\":\"authenticate\",\"param\":{\"user\":\"auditReadOnly\",\"db\":\"admin\",\"mechanism\":\"SCRAM-SHA-1\"}}\n", + Enabled: true, + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, auditingInSync(tt.args.atlas, tt.args.spec), "auditingInSync(%v, %v)", tt.args.atlas, tt.args.spec) + }) + } +} diff --git a/test/e2e/auditing_test.go b/test/e2e/auditing_test.go index ef69d1dc66..dc2281e6a3 100644 --- a/test/e2e/auditing_test.go +++ b/test/e2e/auditing_test.go @@ -6,7 +6,6 @@ import ( v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/actions" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/data" "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/model" @@ -44,9 +43,9 @@ var _ = Describe("UserLogin", Label("auditing"), func() { []func(*model.TestDataProvider){}, ).WithProject(data.DefaultProject()), v1.Auditing{ - AuditAuthorizationSuccess: toptr.MakePtr(false), + AuditAuthorizationSuccess: false, AuditFilter: exampleFilter(), - Enabled: toptr.MakePtr(true), + Enabled: true, }, ), ) From 96a991467718de6c33eec59b3a893b2ea67d9e44 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 11 Aug 2023 09:12:08 +0100 Subject: [PATCH 57/60] Merge fix --- pkg/api/v1/atlasdeployment_types.go | 7 ------- .../atlasdeployment/atlasdeployment_controller.go | 2 +- pkg/controller/atlasdeployment/serverless_deployment.go | 4 ++-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/pkg/api/v1/atlasdeployment_types.go b/pkg/api/v1/atlasdeployment_types.go index fd28aa5837..e54dd2a702 100644 --- a/pkg/api/v1/atlasdeployment_types.go +++ b/pkg/api/v1/atlasdeployment_types.go @@ -222,13 +222,6 @@ type ServerlessSpec struct { Tags []*TagSpec `json:"tags,omitempty"` } -// ServerlessToAtlas converts the ServerlessSpec to native Atlas client Cluster format. -func (s *ServerlessSpec) ServerlessToAtlas() (*mongodbatlas.Cluster, error) { - result := &mongodbatlas.Cluster{} - err := compat.JSONCopy(result, s) - return result, err -} - // ToAtlas converts the ServerlessSpec to native Atlas client Cluster format. func (s *ServerlessSpec) ToAtlas() (*mongodbatlas.Cluster, error) { result := &mongodbatlas.Cluster{} diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 1efa3ce60a..77e7122945 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -689,7 +689,7 @@ func uniqueKey(deploymentSpec *mdbv1.AtlasDeploymentSpec) error { if store[currTag.Key] == "" { store[currTag.Key] = currTag.Value } else { - return errors.New("Duplicate keys found in tags. This is forbidden.") + return errors.New("duplicate keys found in tags, this is forbidden") } } return nil diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index a6879b576a..dab8a89bf2 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -24,7 +24,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr return atlasDeployment, workflow.Terminate(workflow.DeploymentNotCreatedInAtlas, err.Error()) } - atlasDeployment, err = serverlessSpec.ServerlessToAtlas() + atlasDeployment, err = serverlessSpec.ToAtlas() if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } @@ -45,7 +45,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr switch atlasDeployment.StateName { case status.StateIDLE: - convertedDeployment, err := serverlessSpec.ServerlessToAtlas() + convertedDeployment, err := serverlessSpec.ToAtlas() if err != nil { return atlasDeployment, workflow.Terminate(workflow.Internal, err.Error()) } From 57e14f0e71c14e87ecc8ff4a345a8abbf54efc55 Mon Sep 17 00:00:00 2001 From: cveticm Date: Fri, 11 Aug 2023 15:09:36 +0100 Subject: [PATCH 58/60] Fix on uniqueKey --- pkg/controller/atlasdeployment/atlasdeployment_controller.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller.go b/pkg/controller/atlasdeployment/atlasdeployment_controller.go index 77e7122945..2140805aeb 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller.go @@ -181,8 +181,9 @@ func (r *AtlasDeploymentReconciler) Reconcile(context context.Context, req ctrl. } if err := uniqueKey(&deployment.Spec); err != nil { - result := workflow.Terminate(workflow.Internal, err.Error()) log.Errorw("failed to validate tags", "error", err) + result := workflow.Terminate(workflow.Internal, err.Error()) + workflowCtx.SetConditionFromResult(status.DeploymentReadyType, result) return result.ReconcileResult(), nil } From a6f07931f973db529a22b2b2315f68cc113efec8 Mon Sep 17 00:00:00 2001 From: cveticm Date: Mon, 14 Aug 2023 17:52:14 +0100 Subject: [PATCH 59/60] Fix --- pkg/controller/atlasdeployment/serverless_deployment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/serverless_deployment.go b/pkg/controller/atlasdeployment/serverless_deployment.go index dab8a89bf2..45fe350c4e 100644 --- a/pkg/controller/atlasdeployment/serverless_deployment.go +++ b/pkg/controller/atlasdeployment/serverless_deployment.go @@ -81,7 +81,7 @@ func ensureServerlessInstanceState(ctx *workflow.Context, project *mdbv1.AtlasPr func isTagsEqual(a []*mongodbatlas.Tag, c []*mongodbatlas.Tag) bool { if len(a) == len(c) { for i, aTags := range a { - if aTags.Key != (c)[i].Key || aTags.Value != (c)[i].Value { + if aTags.Key != c[i].Key || aTags.Value != c[i].Value { return false } } From 442041042a496134ba9e6a7d0da23b5f4e2b7b9d Mon Sep 17 00:00:00 2001 From: cveticm Date: Wed, 23 Aug 2023 12:33:45 +0100 Subject: [PATCH 60/60] Fix lint error --- .../atlasdeployment/atlasdeployment_controller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go index 0205f7493b..59fb678fd9 100644 --- a/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go +++ b/pkg/controller/atlasdeployment/atlasdeployment_controller_test.go @@ -774,4 +774,4 @@ func TestUniqueKey(t *testing.T) { err := uniqueKey(deploymentSpec) assert.NoError(t, err) }) -} \ No newline at end of file +}