diff --git a/Makefile b/Makefile index 7157b361b1..90b9abfbf6 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ INTEGRATION_TAGS?=integration E2E_TAGS?=e2e E2E_TIMEOUT?=60m E2E_PARALLEL?=1 +E2E_EXTRA_ARGS?= export PATH := $(shell go env GOPATH)/bin:$(PATH) export PATH := ./bin:$(PATH) @@ -155,7 +156,7 @@ build-atlascli-debug: ## Generate a binary in ./bin for debugging atlascli e2e-test: build-all ## Run E2E tests @echo "==> Running E2E tests..." # the target assumes the MCLI_* environment variables are exported - $(TEST_CMD) -v -p 1 -parallel $(E2E_PARALLEL) -timeout $(E2E_TIMEOUT) -tags="$(E2E_TAGS)" ./test/e2e... + $(TEST_CMD) -v -p 1 -parallel $(E2E_PARALLEL) -timeout $(E2E_TIMEOUT) -tags="$(E2E_TAGS)" ./test/e2e... $(E2E_EXTRA_ARGS) .PHONY: integration-test integration-test: ## Run integration tests diff --git a/build/ci/library_owners.json b/build/ci/library_owners.json index d35d9806e6..92a7b0d111 100644 --- a/build/ci/library_owners.json +++ b/build/ci/library_owners.json @@ -45,9 +45,10 @@ "golang.org/x/mod": "mongocli", "gopkg.in/yaml.v3": "mongocli", "github.com/jba/templatecheck": "mongocli", - "github.com/mongodb/mongodb-atlas-kubernetes": "atlas_kubernetes_team", + "github.com/mongodb/mongodb-atlas-kubernetes/v2": "atlas_kubernetes_team", "k8s.io/api": "atlas_kubernetes_team", "k8s.io/apimachinery": "atlas_kubernetes_team", + "k8s.io/apiserver": "atlas_kubernetes_team", "k8s.io/client-go": "atlas_kubernetes_team", "k8s.io/apiextensions-apiserver": "atlas_kubernetes_team", "sigs.k8s.io/yaml": "atlas_kubernetes_team", diff --git a/docs/atlascli/command/atlas-kubernetes-config-generate.txt b/docs/atlascli/command/atlas-kubernetes-config-generate.txt index 3c8bfe1b95..20e14130b8 100644 --- a/docs/atlascli/command/atlas-kubernetes-config-generate.txt +++ b/docs/atlascli/command/atlas-kubernetes-config-generate.txt @@ -56,7 +56,7 @@ Options * - --operatorVersion - string - false - - Version of Atlas Kubernetes Operator to generate resources for. This value defaults to "1.9.0". + - Version of Atlas Kubernetes Operator to generate resources for. This value defaults to "2.0.0". * - --orgId - string - false diff --git a/go.mod b/go.mod index 0f5b23c3eb..b61eb57eaf 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/mattn/go-isatty v0.0.20 github.com/mongodb-forks/digest v1.0.5 github.com/mongodb-labs/cobra2snooty v0.17.0 - github.com/mongodb/mongodb-atlas-kubernetes v1.9.0 + github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.0.0 github.com/pelletier/go-toml v1.9.5 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/shirou/gopsutil/v3 v3.23.10 @@ -58,6 +58,7 @@ require ( k8s.io/api v0.26.4 k8s.io/apiextensions-apiserver v0.26.1 k8s.io/apimachinery v0.26.4 + k8s.io/apiserver v0.26.1 k8s.io/client-go v0.26.4 sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/kind v0.20.0 @@ -106,7 +107,7 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gemalto/flume v0.13.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect diff --git a/go.sum b/go.sum index 8d4b78c502..ad7f8e5f31 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,6 @@ github.com/evergreen-ci/shrub v0.0.0-20230905131908-6b01f04bb1d2 h1:46brusTyZ3O0 github.com/evergreen-ci/shrub v0.0.0-20230905131908-6b01f04bb1d2/go.mod h1:r6YQr77CR37LMhBdWcFrxqu5V+UhO+SYloHfd9vO1go= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -216,8 +214,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -424,18 +422,18 @@ github.com/mongodb-forks/digest v1.0.5 h1:EJu3wtLZcA0HCvsZpX5yuD193/sW9tHiNvrEM5 github.com/mongodb-forks/digest v1.0.5/go.mod h1:rb+EX8zotClD5Dj4NdgxnJXG9nwrlx3NWKJ8xttz1Dg= github.com/mongodb-labs/cobra2snooty v0.17.0 h1:Os4RpsIHViw2fT6Wk5d5cG/rItRS0c8Za8sKKhw3oc8= github.com/mongodb-labs/cobra2snooty v0.17.0/go.mod h1:TgFBJczSy1fdW6HY5ZGQfC9EOlhrD1ZJ9hWRldG5gTI= -github.com/mongodb/mongodb-atlas-kubernetes v1.9.0 h1:G0W00WwOMf00slHjQG5I6JhQPzN2zAjee1rQJxA9t+w= -github.com/mongodb/mongodb-atlas-kubernetes v1.9.0/go.mod h1:S7JpgyRq6Asp/PBNFWppwUTwao7EIFgFau3ltpt3rpA= +github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.0.0 h1:G44tdN++ZoAi6gTMQLPjpu56Ay0AV9BuRSOSwrNTO8s= +github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.0.0/go.mod h1:Ruj7U3GZaJuqQN64BgENOix5GW0PXuuzWV0zM87uKdo= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= -github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= +github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= +github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= @@ -983,6 +981,8 @@ k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66b k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs= k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/apiserver v0.26.1 h1:6vmnAqCDO194SVCPU3MU8NcDgSqsUA62tBUSWrFXhsc= +k8s.io/apiserver v0.26.1/go.mod h1:wr75z634Cv+sifswE9HlAo5FQ7UoUauIICRlOE+5dCg= k8s.io/client-go v0.26.4 h1:/7P/IbGBuT73A+G97trf44NTPSNqvuBREpOfdLbHvD4= k8s.io/client-go v0.26.4/go.mod h1:6qOItWm3EwxJdl/8p5t7FWtWUOwyMdA8N9ekbW4idpI= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= diff --git a/internal/kubernetes/kubectl.go b/internal/kubernetes/kubectl.go index 003dd3fc79..ddbc5debcd 100644 --- a/internal/kubernetes/kubectl.go +++ b/internal/kubernetes/kubectl.go @@ -20,7 +20,7 @@ import ( "fmt" "github.com/mongodb/mongodb-atlas-cli/internal/log" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" @@ -126,7 +126,7 @@ func (ctl *KubeCtl) setupClient(witContext string) error { return fmt.Errorf("unable to prepare client configuration: %w", err) } - err = akov1.AddToScheme(scheme.Scheme) + err = akov2.AddToScheme(scheme.Scheme) if err != nil { return err } diff --git a/internal/kubernetes/operator/config_apply.go b/internal/kubernetes/operator/config_apply.go index bc58c29113..94741e8b1b 100644 --- a/internal/kubernetes/operator/config_apply.go +++ b/internal/kubernetes/operator/config_apply.go @@ -20,7 +20,7 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/features" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -110,29 +110,29 @@ func sortResources(projectResources, deploymentResources []runtime.Object, versi sortedResources[0] = append(sortedResources[0], resource) } - if _, ok := resource.(*akov1.AtlasTeam); ok { + if _, ok := resource.(*akov2.AtlasTeam); ok { sortedResources[1] = append(sortedResources[1], resource) } - if _, ok := resource.(*akov1.AtlasProject); ok { + if _, ok := resource.(*akov2.AtlasProject); ok { sortedResources[2] = append(sortedResources[2], resource) } - if _, ok := resource.(*akov1.AtlasDatabaseUser); ok { + if _, ok := resource.(*akov2.AtlasDatabaseUser); ok { sortedResources[3] = append(sortedResources[3], resource) } } for _, resource := range deploymentResources { - if _, ok := resource.(*akov1.AtlasBackupPolicy); ok { + if _, ok := resource.(*akov2.AtlasBackupPolicy); ok { sortedResources[4] = append(sortedResources[4], resource) } - if _, ok := resource.(*akov1.AtlasBackupSchedule); ok { + if _, ok := resource.(*akov2.AtlasBackupSchedule); ok { sortedResources[5] = append(sortedResources[5], resource) } - if _, ok := resource.(*akov1.AtlasDeployment); ok { + if _, ok := resource.(*akov2.AtlasDeployment); ok { sortedResources[6] = append(sortedResources[6], resource) } } diff --git a/internal/kubernetes/operator/datafederation/datafederation.go b/internal/kubernetes/operator/datafederation/datafederation.go index ecd90d9716..551378a192 100644 --- a/internal/kubernetes/operator/datafederation/datafederation.go +++ b/internal/kubernetes/operator/datafederation/datafederation.go @@ -20,9 +20,9 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" "go.mongodb.org/atlas-sdk/v20231115002/admin" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -32,7 +32,7 @@ const ( DeletedState = "DELETED" ) -func BuildAtlasDataFederation(dataFederationStore atlas.DataFederationStore, dataFederationName, projectID, projectName, operatorVersion, targetNamespace string, dictionary map[string]string) (*atlasV1.AtlasDataFederation, error) { +func BuildAtlasDataFederation(dataFederationStore atlas.DataFederationStore, dataFederationName, projectID, projectName, operatorVersion, targetNamespace string, dictionary map[string]string) (*akov2.AtlasDataFederation, error) { dataFederation, err := dataFederationStore.DataFederation(projectID, dataFederationName) if err != nil { return nil, err @@ -40,7 +40,7 @@ func BuildAtlasDataFederation(dataFederationStore atlas.DataFederationStore, dat if !isDataFederationExportable(dataFederation) { return nil, nil } - atlasDataFederation := &atlasV1.AtlasDataFederation{ + atlasDataFederation := &akov2.AtlasDataFederation{ TypeMeta: v1.TypeMeta{ APIVersion: "atlas.mongodb.com/v1", Kind: "AtlasDataFederation", @@ -53,9 +53,9 @@ func BuildAtlasDataFederation(dataFederationStore atlas.DataFederationStore, dat }, }, Spec: getDataFederationSpec(dataFederation, targetNamespace, projectName), - Status: status.DataFederationStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.DataFederationStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -67,9 +67,9 @@ func isDataFederationExportable(dataFederation *admin.DataLakeTenant) bool { return state != DeletingState && state != DeletedState } -func getDataFederationSpec(dataFederationSpec *admin.DataLakeTenant, targetNamespace, projectName string) atlasV1.DataFederationSpec { - return atlasV1.DataFederationSpec{ - Project: common.ResourceRefNamespaced{Name: projectName, Namespace: targetNamespace}, +func getDataFederationSpec(dataFederationSpec *admin.DataLakeTenant, targetNamespace, projectName string) akov2.DataFederationSpec { + return akov2.DataFederationSpec{ + Project: akov2common.ResourceRefNamespaced{Name: projectName, Namespace: targetNamespace}, Name: dataFederationSpec.GetName(), CloudProviderConfig: getCloudProviderConfig(dataFederationSpec.CloudProviderConfig), DataProcessRegion: getDataProcessRegion(dataFederationSpec.DataProcessRegion), @@ -77,46 +77,46 @@ func getDataFederationSpec(dataFederationSpec *admin.DataLakeTenant, targetNames } } -func getCloudProviderConfig(cloudProviderConfig *admin.DataLakeCloudProviderConfig) *atlasV1.CloudProviderConfig { +func getCloudProviderConfig(cloudProviderConfig *admin.DataLakeCloudProviderConfig) *akov2.CloudProviderConfig { if cloudProviderConfig == nil { - return &atlasV1.CloudProviderConfig{} + return &akov2.CloudProviderConfig{} } - return &atlasV1.CloudProviderConfig{ - AWS: &atlasV1.AWSProviderConfig{ + return &akov2.CloudProviderConfig{ + AWS: &akov2.AWSProviderConfig{ RoleID: cloudProviderConfig.Aws.RoleId, TestS3Bucket: cloudProviderConfig.Aws.TestS3Bucket, }, } } -func getDataProcessRegion(dataProcessRegion *admin.DataLakeDataProcessRegion) *atlasV1.DataProcessRegion { +func getDataProcessRegion(dataProcessRegion *admin.DataLakeDataProcessRegion) *akov2.DataProcessRegion { if dataProcessRegion == nil { - return &atlasV1.DataProcessRegion{} + return &akov2.DataProcessRegion{} } - return &atlasV1.DataProcessRegion{ + return &akov2.DataProcessRegion{ CloudProvider: dataProcessRegion.CloudProvider, Region: dataProcessRegion.Region, } } -func getStorage(storage *admin.DataLakeStorage) *atlasV1.Storage { +func getStorage(storage *admin.DataLakeStorage) *akov2.Storage { if storage == nil { - return &atlasV1.Storage{} + return &akov2.Storage{} } - return &atlasV1.Storage{ + return &akov2.Storage{ Databases: getDatabases(storage.Databases), Stores: getStores(storage.Stores), } } -func getDatabases(database []admin.DataLakeDatabaseInstance) []atlasV1.Database { +func getDatabases(database []admin.DataLakeDatabaseInstance) []akov2.Database { if database == nil { - return []atlasV1.Database{} + return []akov2.Database{} } - result := make([]atlasV1.Database, 0, len(database)) + result := make([]akov2.Database, 0, len(database)) for _, obj := range database { - result = append(result, atlasV1.Database{ + result = append(result, akov2.Database{ Collections: getCollection(obj.GetCollections()), MaxWildcardCollections: obj.GetMaxWildcardCollections(), Name: obj.GetName(), @@ -126,14 +126,14 @@ func getDatabases(database []admin.DataLakeDatabaseInstance) []atlasV1.Database return result } -func getCollection(collections []admin.DataLakeDatabaseCollection) []atlasV1.Collection { +func getCollection(collections []admin.DataLakeDatabaseCollection) []akov2.Collection { if collections == nil { - return []atlasV1.Collection{} + return []akov2.Collection{} } - result := make([]atlasV1.Collection, 0, len(collections)) + result := make([]akov2.Collection, 0, len(collections)) for _, obj := range collections { - result = append(result, atlasV1.Collection{ + result = append(result, akov2.Collection{ DataSources: getDataSources(obj.GetDataSources()), Name: obj.GetName(), }) @@ -141,14 +141,14 @@ func getCollection(collections []admin.DataLakeDatabaseCollection) []atlasV1.Col return result } -func getDataSources(dataSources []admin.DataLakeDatabaseDataSourceSettings) []atlasV1.DataSource { +func getDataSources(dataSources []admin.DataLakeDatabaseDataSourceSettings) []akov2.DataSource { if dataSources == nil { - return []atlasV1.DataSource{} + return []akov2.DataSource{} } - result := make([]atlasV1.DataSource, 0, len(dataSources)) + result := make([]akov2.DataSource, 0, len(dataSources)) for _, obj := range dataSources { - result = append(result, atlasV1.DataSource{ + result = append(result, akov2.DataSource{ AllowInsecure: obj.GetAllowInsecure(), Collection: obj.GetCollection(), CollectionRegex: obj.GetCollectionRegex(), @@ -164,14 +164,14 @@ func getDataSources(dataSources []admin.DataLakeDatabaseDataSourceSettings) []at return result } -func getViews(views []admin.DataLakeApiBase) []atlasV1.View { +func getViews(views []admin.DataLakeApiBase) []akov2.View { if views == nil { - return []atlasV1.View{} + return []akov2.View{} } - result := make([]atlasV1.View, 0, len(views)) + result := make([]akov2.View, 0, len(views)) for _, obj := range views { - result = append(result, atlasV1.View{ + result = append(result, akov2.View{ Name: obj.GetName(), Pipeline: obj.GetPipeline(), Source: obj.GetSource(), @@ -180,14 +180,14 @@ func getViews(views []admin.DataLakeApiBase) []atlasV1.View { return result } -func getStores(stores []admin.DataLakeStoreSettings) []atlasV1.Store { +func getStores(stores []admin.DataLakeStoreSettings) []akov2.Store { if stores == nil { - return []atlasV1.Store{} + return []akov2.Store{} } - result := make([]atlasV1.Store, 0, len(stores)) + result := make([]akov2.Store, 0, len(stores)) for _, obj := range stores { - result = append(result, atlasV1.Store{ + result = append(result, akov2.Store{ Name: obj.GetName(), Provider: obj.Provider, AdditionalStorageClasses: obj.GetAdditionalStorageClasses(), diff --git a/internal/kubernetes/operator/datafederation/datafederation_test.go b/internal/kubernetes/operator/datafederation/datafederation_test.go index b9df214378..37b57dc76d 100644 --- a/internal/kubernetes/operator/datafederation/datafederation_test.go +++ b/internal/kubernetes/operator/datafederation/datafederation_test.go @@ -26,9 +26,9 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" mocks "github.com/mongodb/mongodb-atlas-cli/internal/mocks/atlas" "github.com/mongodb/mongodb-atlas-cli/internal/pointer" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" "go.mongodb.org/atlas-sdk/v20231115002/admin" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -112,7 +112,7 @@ func Test_BuildAtlasDataFederation(t *testing.T) { dataFederationStore.EXPECT().DataFederation(projectID, dataFederationName).Return(dataFederation, nil) - expected := &atlasV1.AtlasDataFederation{ + expected := &akov2.AtlasDataFederation{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDataFederation", APIVersion: "atlas.mongodb.com/v1", @@ -124,28 +124,28 @@ func Test_BuildAtlasDataFederation(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.DataFederationSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.DataFederationSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: projectName, Namespace: targetNamespace, }, Name: dataFederationName, - CloudProviderConfig: &atlasV1.CloudProviderConfig{ - AWS: &atlasV1.AWSProviderConfig{ + CloudProviderConfig: &akov2.CloudProviderConfig{ + AWS: &akov2.AWSProviderConfig{ RoleID: dataFederation.CloudProviderConfig.Aws.RoleId, TestS3Bucket: dataFederation.CloudProviderConfig.Aws.TestS3Bucket, }, }, - DataProcessRegion: &atlasV1.DataProcessRegion{ + DataProcessRegion: &akov2.DataProcessRegion{ CloudProvider: dataFederation.DataProcessRegion.CloudProvider, Region: dataFederation.DataProcessRegion.Region, }, - Storage: &atlasV1.Storage{ - Databases: []atlasV1.Database{ + Storage: &akov2.Storage{ + Databases: []akov2.Database{ { - Collections: []atlasV1.Collection{ + Collections: []akov2.Collection{ { - DataSources: []atlasV1.DataSource{ + DataSources: []akov2.DataSource{ { AllowInsecure: true, Collection: *dataFederation.Storage.Databases[0].Collections[0].DataSources[0].Collection, @@ -164,7 +164,7 @@ func Test_BuildAtlasDataFederation(t *testing.T) { }, MaxWildcardCollections: *dataFederation.Storage.Databases[0].MaxWildcardCollections, Name: *dataFederation.Storage.Databases[0].Name, - Views: []atlasV1.View{ + Views: []akov2.View{ { Name: *dataFederation.Storage.Databases[0].Views[0].Name, Pipeline: *dataFederation.Storage.Databases[0].Views[0].Pipeline, @@ -173,7 +173,7 @@ func Test_BuildAtlasDataFederation(t *testing.T) { }, }, }, - Stores: []atlasV1.Store{ + Stores: []akov2.Store{ { Name: *dataFederation.Storage.Stores[0].Name, Provider: dataFederation.Storage.Stores[0].Provider, @@ -188,9 +188,9 @@ func Test_BuildAtlasDataFederation(t *testing.T) { }, }, }, - Status: status.DataFederationStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.DataFederationStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } diff --git a/internal/kubernetes/operator/dbusers/dbusers.go b/internal/kubernetes/operator/dbusers/dbusers.go index e3e6872167..7cb87601b2 100644 --- a/internal/kubernetes/operator/dbusers/dbusers.go +++ b/internal/kubernetes/operator/dbusers/dbusers.go @@ -23,15 +23,15 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/secrets" "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, targetNamespace string, dictionary map[string]string, version string) ([]*atlasV1.AtlasDatabaseUser, []*corev1.Secret, error) { +func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, targetNamespace string, dictionary map[string]string, version string) ([]*akov2.AtlasDatabaseUser, []*corev1.Secret, error) { users, err := provider.DatabaseUsers(projectID, &atlas.ListOptions{}) if err != nil { return nil, nil, err @@ -41,7 +41,7 @@ func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, t return nil, nil, nil } - mappedUsers := map[string]*atlasV1.AtlasDatabaseUser{} + mappedUsers := map[string]*akov2.AtlasDatabaseUser{} relatedSecrets := make([]*corev1.Secret, 0, len(users.Results)) for i := range users.Results { @@ -55,7 +55,7 @@ func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, t } scopes := convertUserScopes(user) - mappedUsers[resourceName] = &atlasV1.AtlasDatabaseUser{ + mappedUsers[resourceName] = &akov2.AtlasDatabaseUser{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDatabaseUser", APIVersion: "atlas.mongodb.com/v1", @@ -67,8 +67,8 @@ func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, t features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasDatabaseUserSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDatabaseUserSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: targetNamespace, }, @@ -80,24 +80,24 @@ func BuildDBUsers(provider atlas.OperatorDBUsersStore, projectID, projectName, t Username: user.Username, X509Type: *user.X509Type, }, - Status: status.AtlasDatabaseUserStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDatabaseUserStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } if user.GetX509Type() != "MANAGED" { - secret := buildUserSecret(resourceName, targetNamespace, dictionary) + secret := buildUserSecret(resourceName, targetNamespace, projectID, projectName, dictionary) relatedSecrets = append(relatedSecrets, secret) - mappedUsers[resourceName].Spec.PasswordSecret = &common.ResourceRef{ + mappedUsers[resourceName].Spec.PasswordSecret = &akov2common.ResourceRef{ Name: resources.NormalizeAtlasName(secret.Name, dictionary), } } } - result := make([]*atlasV1.AtlasDatabaseUser, 0, len(users.Results)) + result := make([]*akov2.AtlasDatabaseUser, 0, len(users.Results)) for _, mappedUser := range mappedUsers { result = append(result, mappedUser) } @@ -112,31 +112,32 @@ func getDeleteAfterDate(user *atlasv2.CloudDatabaseUser) string { return "" } -func buildUserSecret(resourceName string, targetNamespace string, dictionary map[string]string) *corev1.Secret { - secret := secrets.NewAtlasSecret(resourceName, targetNamespace, map[string][]byte{ - secrets.PasswordField: []byte(""), - }, dictionary) +func buildUserSecret(resourceName, targetNamespace, projectID, projectName string, dictionary map[string]string) *corev1.Secret { + secret := secrets.NewAtlasSecretBuilder(resourceName, targetNamespace, dictionary). + WithData(map[string][]byte{secrets.PasswordField: []byte("")}). + WithProjectLabels(projectID, projectName). + Build() return secret } -func convertUserScopes(user *atlasv2.CloudDatabaseUser) []atlasV1.ScopeSpec { - result := make([]atlasV1.ScopeSpec, 0, len(user.Scopes)) +func convertUserScopes(user *atlasv2.CloudDatabaseUser) []akov2.ScopeSpec { + result := make([]akov2.ScopeSpec, 0, len(user.Scopes)) for _, scope := range user.Scopes { - result = append(result, atlasV1.ScopeSpec{ + result = append(result, akov2.ScopeSpec{ Name: scope.Name, - Type: atlasV1.ScopeType(scope.Type), + Type: akov2.ScopeType(scope.Type), }) } return result } -func convertUserRoles(user *atlasv2.CloudDatabaseUser) []atlasV1.RoleSpec { +func convertUserRoles(user *atlasv2.CloudDatabaseUser) []akov2.RoleSpec { if len(user.Roles) == 0 { return nil } - result := make([]atlasV1.RoleSpec, 0, len(user.Roles)) + result := make([]akov2.RoleSpec, 0, len(user.Roles)) for _, role := range user.Roles { - result = append(result, atlasV1.RoleSpec{ + result = append(result, akov2.RoleSpec{ RoleName: role.RoleName, DatabaseName: role.DatabaseName, CollectionName: pointer.GetOrDefault(role.CollectionName, ""), @@ -145,10 +146,10 @@ func convertUserRoles(user *atlasv2.CloudDatabaseUser) []atlasV1.RoleSpec { return result } -func convertUserLabels(user *atlasv2.CloudDatabaseUser) []common.LabelSpec { - result := make([]common.LabelSpec, 0, len(user.Labels)) +func convertUserLabels(user *atlasv2.CloudDatabaseUser) []akov2common.LabelSpec { + result := make([]akov2common.LabelSpec, 0, len(user.Labels)) for _, label := range user.Labels { - result = append(result, common.LabelSpec{ + result = append(result, akov2common.LabelSpec{ Key: *label.Key, Value: *label.Value, }) @@ -159,7 +160,7 @@ func convertUserLabels(user *atlasv2.CloudDatabaseUser) []common.LabelSpec { func suggestResourceName( projectName string, username string, - mappedDatabaseUsers map[string]*atlasV1.AtlasDatabaseUser, + mappedDatabaseUsers map[string]*akov2.AtlasDatabaseUser, dictionary map[string]string, ) string { resourceName := resources.NormalizeAtlasName(fmt.Sprintf("%s-%s", projectName, username), dictionary) diff --git a/internal/kubernetes/operator/dbusers/dbusers_test.go b/internal/kubernetes/operator/dbusers/dbusers_test.go index 37642dc7ea..ef045cea96 100644 --- a/internal/kubernetes/operator/dbusers/dbusers_test.go +++ b/internal/kubernetes/operator/dbusers/dbusers_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "github.com/go-test/deep" "github.com/golang/mock/gomock" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" @@ -31,9 +32,9 @@ import ( mocks "github.com/mongodb/mongodb-atlas-cli/internal/mocks/atlas" "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" "github.com/stretchr/testify/assert" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" corev1 "k8s.io/api/core/v1" @@ -53,7 +54,7 @@ func Test_convertUserLabels(t *testing.T) { }, } - expectedLabels := []common.LabelSpec{ + expectedLabels := []akov2common.LabelSpec{ { Key: "TestKey", Value: "TestValue", @@ -78,7 +79,7 @@ func Test_convertUserRoles(t *testing.T) { }, } - expectedRoles := []atlasV1.RoleSpec{ + expectedRoles := []akov2.RoleSpec{ { RoleName: "TestRole", DatabaseName: "TestDB", @@ -95,6 +96,7 @@ func Test_buildUserSecret(t *testing.T) { dictionary := resources.AtlasNameToKubernetesName() t.Run("Can build user secret WITHOUT credentials", func(t *testing.T) { projectName := "TestProject-1" + projectID := "123" atlasUser := &atlasv2.CloudDatabaseUser{ Password: pointer.Get("TestPassword"), Username: "TestName", @@ -109,7 +111,9 @@ func Test_buildUserSecret(t *testing.T) { Name: strings.ToLower(fmt.Sprintf("%s-%s", projectName, atlasUser.Username)), Namespace: "TestNamespace", Labels: map[string]string{ - secrets.TypeLabelKey: secrets.CredLabelVal, + secrets.TypeLabelKey: secrets.CredLabelVal, + secrets.ProjectIDLabelKey: resources.NormalizeAtlasName(projectID, dictionary), + secrets.ProjectNameLabelKey: resources.NormalizeAtlasName(projectName, dictionary), }, }, Data: map[string][]byte{ @@ -117,9 +121,9 @@ func Test_buildUserSecret(t *testing.T) { }, } - got := buildUserSecret(resources.NormalizeAtlasName(fmt.Sprintf("%s-%s", projectName, atlasUser.Username), dictionary), "TestNamespace", dictionary) - if !reflect.DeepEqual(got, expectedSecret) { - t.Errorf("buildUserSecret(); \r\n got:%v;s\r\n want:%v", got, expectedSecret) + got := buildUserSecret(resources.NormalizeAtlasName(fmt.Sprintf("%s-%s", projectName, atlasUser.Username), dictionary), "TestNamespace", projectID, projectName, dictionary) + if diff := deep.Equal(expectedSecret, got); diff != nil { + t.Fatalf("buildUserSecret() mismatch: %v", diff) } }) } @@ -176,7 +180,7 @@ func TestBuildDBUsers(t *testing.T) { t.Fatalf("%v", err) } - expectedUser := &atlasV1.AtlasDatabaseUser{ + expectedUser := &akov2.AtlasDatabaseUser{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDatabaseUser", APIVersion: "atlas.mongodb.com/v1", @@ -188,41 +192,41 @@ func TestBuildDBUsers(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasDatabaseUserSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDatabaseUserSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: targetNamespace, }, DatabaseName: user.DatabaseName, DeleteAfterDate: user.DeleteAfterDate.String(), - Labels: []common.LabelSpec{ + Labels: []akov2common.LabelSpec{ { Key: *user.Labels[0].Key, Value: *user.Labels[0].Value, }, }, - Roles: []atlasV1.RoleSpec{ + Roles: []akov2.RoleSpec{ { RoleName: user.Roles[0].RoleName, DatabaseName: user.Roles[0].DatabaseName, CollectionName: *user.Roles[0].CollectionName, }, }, - Scopes: []atlasV1.ScopeSpec{ + Scopes: []akov2.ScopeSpec{ { Name: user.Scopes[0].Name, - Type: atlasV1.ScopeType(user.Scopes[0].Type), + Type: akov2.ScopeType(user.Scopes[0].Type), }, }, - PasswordSecret: &common.ResourceRef{ + PasswordSecret: &akov2common.ResourceRef{ Name: relatedSecrets[0].Name, }, Username: user.Username, X509Type: *user.X509Type, }, - Status: status.AtlasDatabaseUserStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDatabaseUserStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -239,14 +243,16 @@ func TestBuildDBUsers(t *testing.T) { t.Fatalf("User result doesn't match.\r\nexpected: %v,\r\ngot: %v\r\n", string(ed), string(gd)) } - expectedSecret := secrets.NewAtlasSecret( + expectedSecret := secrets.NewAtlasSecretBuilder( fmt.Sprintf("%v-%v", projectName, user.Username), targetNamespace, - map[string][]byte{ - secrets.PasswordField: []byte(""), - }, dictionary) - if !reflect.DeepEqual(relatedSecrets[0], expectedSecret) { - t.Fatalf("Secret result doesn't match.\r\nexpected: %v\r\ngot %v\r\n", expectedSecret, relatedSecrets[0]) + dictionary, + ).WithData(map[string][]byte{ + secrets.PasswordField: []byte(""), + }).WithProjectLabels(projectID, projectName).Build() + + if diff := deep.Equal(relatedSecrets[0], expectedSecret); diff != nil { + t.Fatalf("Secret mismatch: %v", diff) } }) diff --git a/internal/kubernetes/operator/deployment/deployment.go b/internal/kubernetes/operator/deployment/deployment.go index 02c2c79423..52b3badcdd 100644 --- a/internal/kubernetes/operator/deployment/deployment.go +++ b/internal/kubernetes/operator/deployment/deployment.go @@ -22,10 +22,10 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2provider "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -35,15 +35,15 @@ const ( featureProcessArgs = "processArgs" featureBackupSchedule = "backupRef" featureServerlessPrivateEndpoints = "serverlessSpec.privateEndpoints" - featureGlobalDeployments = "advancedDeploymentSpec.customZoneMapping" + featureGlobalDeployments = "deploymentSpec.customZoneMapping" DeletingState = "DELETING" DeletedState = "DELETED" ) type AtlasDeploymentResult struct { - Deployment *atlasV1.AtlasDeployment - BackupSchedule *atlasV1.AtlasBackupSchedule - BackupPolicies []*atlasV1.AtlasBackupPolicy + Deployment *akov2.AtlasDeployment + BackupSchedule *akov2.AtlasBackupSchedule + BackupPolicies []*akov2.AtlasBackupPolicy } func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, validator features.FeatureValidator, projectID, projectName, clusterID, targetNamespace string, dictionary map[string]string, version string) (*AtlasDeploymentResult, error) { @@ -56,23 +56,23 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va return nil, nil } - var advancedSpec *atlasV1.AdvancedDeploymentSpec + var advancedSpec *akov2.AdvancedDeploymentSpec - convertBiConnector := func(biConnector *atlasv2.BiConnector) *atlasV1.BiConnectorSpec { + convertBiConnector := func(biConnector *atlasv2.BiConnector) *akov2.BiConnectorSpec { if biConnector == nil { return nil } - return &atlasV1.BiConnectorSpec{ + return &akov2.BiConnectorSpec{ Enabled: biConnector.Enabled, ReadPreference: biConnector.GetReadPreference(), } } - convertLabels := func(labels []atlasv2.ComponentLabel) []common.LabelSpec { - result := make([]common.LabelSpec, 0, len(labels)) + convertLabels := func(labels []atlasv2.ComponentLabel) []akov2common.LabelSpec { + result := make([]akov2common.LabelSpec, 0, len(labels)) for _, atlasLabel := range labels { - result = append(result, common.LabelSpec{ + result = append(result, akov2common.LabelSpec{ Key: atlasLabel.GetKey(), Value: atlasLabel.GetValue(), }) @@ -83,7 +83,7 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va replicationSpec := buildReplicationSpec(deployment.GetReplicationSpecs()) // TODO: DiskSizeGB field skipped on purpose. See https://jira.mongodb.org/browse/CLOUDP-146469 - advancedSpec = &atlasV1.AdvancedDeploymentSpec{ + advancedSpec = &akov2.AdvancedDeploymentSpec{ BackupEnabled: deployment.BackupEnabled, BiConnector: convertBiConnector(deployment.BiConnector), ClusterType: deployment.GetClusterType(), @@ -97,7 +97,7 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va VersionReleaseSystem: deployment.GetVersionReleaseSystem(), } - atlasDeployment := &atlasV1.AtlasDeployment{ + atlasDeployment := &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -109,19 +109,18 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: targetNamespace, }, - DeploymentSpec: nil, - AdvancedDeploymentSpec: advancedSpec, - ServerlessSpec: nil, - ProcessArgs: nil, + DeploymentSpec: advancedSpec, + ServerlessSpec: nil, + ProcessArgs: nil, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -141,7 +140,7 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va } if validator.FeatureExist(features.ResourceAtlasDeployment, featureBackupSchedule) { - var backupScheduleRef common.ResourceRefNamespaced + var backupScheduleRef akov2common.ResourceRefNamespaced backupSchedule, backupPolicies := buildBackups(deploymentStore, projectName, projectID, clusterID, targetNamespace, version, dictionary) if backupSchedule != nil { backupScheduleRef.Name = backupSchedule.Name @@ -164,12 +163,12 @@ func BuildAtlasAdvancedDeployment(deploymentStore atlas.OperatorClusterStore, va return deploymentResult, nil } -func buildGlobalDeployment(atlasRepSpec []atlasv2.ReplicationSpec, globalDeploymentProvider store.GlobalClusterDescriber, projectID, clusterID string) ([]atlasV1.CustomZoneMapping, []atlasV1.ManagedNamespace, error) { +func buildGlobalDeployment(atlasRepSpec []atlasv2.ReplicationSpec, globalDeploymentProvider store.GlobalClusterDescriber, projectID, clusterID string) ([]akov2.CustomZoneMapping, []akov2.ManagedNamespace, error) { globalCluster, err := globalDeploymentProvider.GlobalCluster(projectID, clusterID) if err != nil { return nil, nil, err } - var customZoneMapping []atlasV1.CustomZoneMapping + var customZoneMapping []akov2.CustomZoneMapping if globalCluster.CustomZoneMapping != nil { // create map ID -> Name for zones zoneMap := make(map[string]string, len(atlasRepSpec)) @@ -177,9 +176,9 @@ func buildGlobalDeployment(atlasRepSpec []atlasv2.ReplicationSpec, globalDeploym zoneMap[rc.GetId()] = rc.GetZoneName() } - customZoneMapping = make([]atlasV1.CustomZoneMapping, 0, len(globalCluster.GetCustomZoneMapping())) + customZoneMapping = make([]akov2.CustomZoneMapping, 0, len(globalCluster.GetCustomZoneMapping())) for location, zoneID := range globalCluster.GetCustomZoneMapping() { - customZoneMapping = append(customZoneMapping, atlasV1.CustomZoneMapping{ + customZoneMapping = append(customZoneMapping, akov2.CustomZoneMapping{ Zone: zoneMap[zoneID], Location: location, }) @@ -190,9 +189,9 @@ func buildGlobalDeployment(atlasRepSpec []atlasv2.ReplicationSpec, globalDeploym return customZoneMapping, nil, nil } - managedNamespace := make([]atlasV1.ManagedNamespace, len(globalCluster.ManagedNamespaces)) + managedNamespace := make([]akov2.ManagedNamespace, len(globalCluster.ManagedNamespaces)) for i, ns := range globalCluster.ManagedNamespaces { - managedNamespace[i] = atlasV1.ManagedNamespace{ + managedNamespace[i] = akov2.ManagedNamespace{ Db: ns.Db, Collection: ns.Collection, CustomShardKey: ns.CustomShardKey, @@ -205,14 +204,14 @@ func buildGlobalDeployment(atlasRepSpec []atlasv2.ReplicationSpec, globalDeploym return customZoneMapping, managedNamespace, nil } -func buildProcessArgs(configOptsProvider store.AtlasClusterConfigurationOptionsDescriber, projectID, clusterName string) (*atlasV1.ProcessArgs, error) { +func buildProcessArgs(configOptsProvider store.AtlasClusterConfigurationOptionsDescriber, projectID, clusterName string) (*akov2.ProcessArgs, error) { pArgs, err := configOptsProvider.AtlasClusterConfigurationOptions(projectID, clusterName) if err != nil { return nil, err } // TODO: OplogMinRetentionHours is not exported due to a bug https://jira.mongodb.org/browse/CLOUDP-146481 - return &atlasV1.ProcessArgs{ + return &akov2.ProcessArgs{ DefaultReadConcern: pArgs.GetDefaultReadConcern(), DefaultWriteConcern: pArgs.GetDefaultWriteConcern(), MinimumEnabledTLSProtocol: pArgs.GetMinimumEnabledTlsProtocol(), @@ -240,25 +239,25 @@ func isServerlessExportable(deployment *atlasv2.ServerlessInstanceDescription) b return true } -func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectID, clusterName, targetNamespace, version string, dictionary map[string]string) (*atlasV1.AtlasBackupSchedule, []*atlasV1.AtlasBackupPolicy) { +func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectID, clusterName, targetNamespace, version string, dictionary map[string]string) (*akov2.AtlasBackupSchedule, []*akov2.AtlasBackupPolicy) { bs, err := backupsProvider.DescribeSchedule(projectID, clusterName) if err != nil { return nil, nil } // Although we have a for loop here, there should be only one policy per schedule. See Atlas API implementation - policies := make([]*atlasV1.AtlasBackupPolicy, 0, len(bs.Policies)) + policies := make([]*akov2.AtlasBackupPolicy, 0, len(bs.Policies)) for _, p := range bs.Policies { - items := make([]atlasV1.AtlasBackupPolicyItem, 0, len(p.PolicyItems)) + items := make([]akov2.AtlasBackupPolicyItem, 0, len(p.PolicyItems)) for _, pItem := range p.PolicyItems { - items = append(items, atlasV1.AtlasBackupPolicyItem{ + items = append(items, akov2.AtlasBackupPolicyItem{ FrequencyType: pItem.FrequencyType, FrequencyInterval: pItem.FrequencyInterval, RetentionUnit: pItem.RetentionUnit, RetentionValue: pItem.RetentionValue, }) } - policies = append(policies, &atlasV1.AtlasBackupPolicy{ + policies = append(policies, &akov2.AtlasBackupPolicy{ TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupPolicy", APIVersion: "atlas.mongodb.com/v1", @@ -270,22 +269,22 @@ func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectI features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasBackupPolicySpec{ + Spec: akov2.AtlasBackupPolicySpec{ Items: items, }, - Status: status.BackupPolicyStatus{}, + Status: akov2status.BackupPolicyStatus{}, }) } - var export *atlasV1.AtlasBackupExportSpec + var export *akov2.AtlasBackupExportSpec if bs.Export != nil { - export = &atlasV1.AtlasBackupExportSpec{ + export = &akov2.AtlasBackupExportSpec{ ExportBucketID: bs.Export.GetExportBucketId(), FrequencyType: bs.Export.GetFrequencyType(), } } - schedule := &atlasV1.AtlasBackupSchedule{ + schedule := &akov2.AtlasBackupSchedule{ TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupSchedule", APIVersion: "atlas.mongodb.com/v1", @@ -297,10 +296,10 @@ func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectI features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasBackupScheduleSpec{ + Spec: akov2.AtlasBackupScheduleSpec{ AutoExportEnabled: pointer.GetOrDefault(bs.AutoExportEnabled, false), Export: export, - PolicyRef: common.ResourceRefNamespaced{ + PolicyRef: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(policies[0].Name, dictionary), Namespace: policies[0].Namespace, }, @@ -310,21 +309,20 @@ func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectI UpdateSnapshots: pointer.GetOrDefault(bs.UpdateSnapshots, false), UseOrgAndGroupNamesInExportPrefix: pointer.GetOrDefault(bs.UseOrgAndGroupNamesInExportPrefix, false), }, - Status: status.BackupScheduleStatus{}, + Status: akov2status.BackupScheduleStatus{}, } if len(bs.CopySettings) > 0 { - copySettings := make([]atlasV1.CopySetting, 0, len(bs.CopySettings)) + copySettings := make([]akov2.CopySetting, 0, len(bs.CopySettings)) for _, copySetting := range bs.CopySettings { copySettings = append( copySettings, - atlasV1.CopySetting{ - CloudProvider: copySetting.CloudProvider, - RegionName: copySetting.RegionName, - ReplicationSpecID: copySetting.ReplicationSpecId, - ShouldCopyOplogs: copySetting.ShouldCopyOplogs, - Frequencies: copySetting.Frequencies, + akov2.CopySetting{ + CloudProvider: copySetting.CloudProvider, + RegionName: copySetting.RegionName, + ShouldCopyOplogs: copySetting.ShouldCopyOplogs, + Frequencies: copySetting.Frequencies, }, ) } @@ -335,10 +333,10 @@ func buildBackups(backupsProvider store.ScheduleDescriber, projectName, projectI return schedule, policies } -func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.AdvancedReplicationSpec { - result := make([]*atlasV1.AdvancedReplicationSpec, 0, len(atlasRepSpec)) +func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*akov2.AdvancedReplicationSpec { + result := make([]*akov2.AdvancedReplicationSpec, 0, len(atlasRepSpec)) for _, rs := range atlasRepSpec { - replicationSpec := &atlasV1.AdvancedReplicationSpec{ + replicationSpec := &akov2.AdvancedReplicationSpec{ NumShards: rs.GetNumShards(), ZoneName: rs.GetZoneName(), RegionConfigs: nil, @@ -349,20 +347,20 @@ func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.Adv continue } - replicationSpec.RegionConfigs = make([]*atlasV1.AdvancedRegionConfig, 0, len(replicationSpec.RegionConfigs)) + replicationSpec.RegionConfigs = make([]*akov2.AdvancedRegionConfig, 0, len(replicationSpec.RegionConfigs)) for _, rc := range rs.RegionConfigs { - var analyticsSpecs *atlasV1.Specs + var analyticsSpecs *akov2.Specs if rc.AnalyticsSpecs != nil { - analyticsSpecs = &atlasV1.Specs{ + analyticsSpecs = &akov2.Specs{ DiskIOPS: pointer.Get(int64(rc.AnalyticsSpecs.GetDiskIOPS())), EbsVolumeType: rc.AnalyticsSpecs.GetEbsVolumeType(), InstanceSize: rc.AnalyticsSpecs.GetInstanceSize(), NodeCount: rc.AnalyticsSpecs.NodeCount, } } - var electableSpecs *atlasV1.Specs + var electableSpecs *akov2.Specs if rc.ElectableSpecs != nil { - electableSpecs = &atlasV1.Specs{ + electableSpecs = &akov2.Specs{ DiskIOPS: pointer.Get(int64(rc.ElectableSpecs.GetDiskIOPS())), EbsVolumeType: rc.ElectableSpecs.GetEbsVolumeType(), InstanceSize: rc.ElectableSpecs.GetInstanceSize(), @@ -370,9 +368,9 @@ func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.Adv } } - var readOnlySpecs *atlasV1.Specs + var readOnlySpecs *akov2.Specs if rc.ReadOnlySpecs != nil { - readOnlySpecs = &atlasV1.Specs{ + readOnlySpecs = &akov2.Specs{ DiskIOPS: pointer.Get(int64(rc.ReadOnlySpecs.GetDiskIOPS())), EbsVolumeType: rc.ReadOnlySpecs.GetEbsVolumeType(), InstanceSize: rc.ReadOnlySpecs.GetInstanceSize(), @@ -380,11 +378,11 @@ func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.Adv } } - var autoscalingSpec *atlasV1.AdvancedAutoScalingSpec + var autoscalingSpec *akov2.AdvancedAutoScalingSpec if rc.AutoScaling != nil { - var compute *atlasV1.ComputeSpec + var compute *akov2.ComputeSpec if rc.AutoScaling.Compute != nil { - compute = &atlasV1.ComputeSpec{ + compute = &akov2.ComputeSpec{ Enabled: rc.AutoScaling.Compute.Enabled, ScaleDownEnabled: rc.AutoScaling.Compute.ScaleDownEnabled, MinInstanceSize: rc.AutoScaling.Compute.GetMinInstanceSize(), @@ -392,16 +390,16 @@ func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.Adv } } - var diskGB *atlasV1.DiskGB + var diskGB *akov2.DiskGB if rc.AutoScaling.DiskGB != nil { - diskGB = &atlasV1.DiskGB{Enabled: rc.AutoScaling.DiskGB.Enabled} + diskGB = &akov2.DiskGB{Enabled: rc.AutoScaling.DiskGB.Enabled} } - autoscalingSpec = &atlasV1.AdvancedAutoScalingSpec{ + autoscalingSpec = &akov2.AdvancedAutoScalingSpec{ DiskGB: diskGB, Compute: compute, } } - replicationSpec.RegionConfigs = append(replicationSpec.RegionConfigs, &atlasV1.AdvancedRegionConfig{ + replicationSpec.RegionConfigs = append(replicationSpec.RegionConfigs, &akov2.AdvancedRegionConfig{ AnalyticsSpecs: analyticsSpecs, ElectableSpecs: electableSpecs, ReadOnlySpecs: readOnlySpecs, @@ -417,7 +415,7 @@ func buildReplicationSpec(atlasRepSpec []atlasv2.ReplicationSpec) []*atlasV1.Adv return result } -func BuildServerlessDeployments(deploymentStore atlas.OperatorClusterStore, validator features.FeatureValidator, projectID, projectName, clusterID, targetNamespace string, dictionary map[string]string, version string) (*atlasV1.AtlasDeployment, error) { +func BuildServerlessDeployments(deploymentStore atlas.OperatorClusterStore, validator features.FeatureValidator, projectID, projectName, clusterID, targetNamespace string, dictionary map[string]string, version string) (*akov2.AtlasDeployment, error) { deployment, err := deploymentStore.GetServerlessInstance(projectID, clusterID) if err != nil { return nil, err @@ -427,19 +425,19 @@ func BuildServerlessDeployments(deploymentStore atlas.OperatorClusterStore, vali return nil, nil } - providerSettings := &atlasV1.ProviderSettingsSpec{ + providerSettings := &akov2.ProviderSettingsSpec{ BackingProviderName: deployment.ProviderSettings.BackingProviderName, - ProviderName: provider.ProviderName(atlas.StringOrEmpty(deployment.ProviderSettings.ProviderName)), + ProviderName: akov2provider.ProviderName(atlas.StringOrEmpty(deployment.ProviderSettings.ProviderName)), RegionName: deployment.ProviderSettings.RegionName, } - serverlessSpec := &atlasV1.ServerlessSpec{ + serverlessSpec := &akov2.ServerlessSpec{ Name: atlas.StringOrEmpty(deployment.Name), ProviderSettings: providerSettings, } atlasName := fmt.Sprintf("%s-%s", projectName, atlas.StringOrEmpty(deployment.Name)) - atlasDeployment := &atlasV1.AtlasDeployment{ + atlasDeployment := &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -451,18 +449,18 @@ func BuildServerlessDeployments(deploymentStore atlas.OperatorClusterStore, vali features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: targetNamespace, }, - BackupScheduleRef: common.ResourceRefNamespaced{}, + BackupScheduleRef: akov2common.ResourceRefNamespaced{}, ServerlessSpec: serverlessSpec, ProcessArgs: nil, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -478,26 +476,26 @@ func BuildServerlessDeployments(deploymentStore atlas.OperatorClusterStore, vali return atlasDeployment, nil } -func buildServerlessPrivateEndpoints(deploymentStore store.ServerlessPrivateEndpointsLister, projectID, clusterName string) ([]atlasV1.ServerlessPrivateEndpoint, error) { +func buildServerlessPrivateEndpoints(deploymentStore store.ServerlessPrivateEndpointsLister, projectID, clusterName string) ([]akov2.ServerlessPrivateEndpoint, error) { endpoints, err := deploymentStore.ServerlessPrivateEndpoints(projectID, clusterName) if err != nil { return nil, err } - result := make([]atlasV1.ServerlessPrivateEndpoint, 0, len(endpoints)) + result := make([]akov2.ServerlessPrivateEndpoint, 0, len(endpoints)) for i := range endpoints { endpoint := endpoints[i] switch endpoint.GetProviderName() { case "AWS": - result = append(result, atlasV1.ServerlessPrivateEndpoint{ + result = append(result, akov2.ServerlessPrivateEndpoint{ Name: endpoint.GetComment(), CloudProviderEndpointID: endpoint.GetCloudProviderEndpointId(), PrivateEndpointIPAddress: "", }) case "AZURE": - result = append(result, atlasV1.ServerlessPrivateEndpoint{ + result = append(result, akov2.ServerlessPrivateEndpoint{ Name: endpoint.GetComment(), CloudProviderEndpointID: endpoint.GetCloudProviderEndpointId(), PrivateEndpointIPAddress: endpoint.GetPrivateEndpointIpAddress(), diff --git a/internal/kubernetes/operator/deployment/deployment_test.go b/internal/kubernetes/operator/deployment/deployment_test.go index a81a3a2298..b5c2dabdda 100644 --- a/internal/kubernetes/operator/deployment/deployment_test.go +++ b/internal/kubernetes/operator/deployment/deployment_test.go @@ -31,11 +31,11 @@ import ( atlasmocks "github.com/mongodb/mongodb-atlas-cli/internal/mocks/atlas" "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2provider "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -201,7 +201,7 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { clusterStore.EXPECT().GlobalCluster(projectName, clusterName).Return(globalCluster, nil) clusterStore.EXPECT().DescribeSchedule(projectName, clusterName).Return(backupSchedule, nil) - expectCluster := &atlasV1.AtlasDeployment{ + expectCluster := &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -213,21 +213,20 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: strings.ToLower(projectName), Namespace: targetNamespace, }, - DeploymentSpec: nil, - AdvancedDeploymentSpec: &atlasV1.AdvancedDeploymentSpec{ + DeploymentSpec: &akov2.AdvancedDeploymentSpec{ BackupEnabled: cluster.BackupEnabled, - CustomZoneMapping: []atlasV1.CustomZoneMapping{ + CustomZoneMapping: []akov2.CustomZoneMapping{ { Location: firstLocation, Zone: *cluster.ReplicationSpecs[0].ZoneName, }, }, - ManagedNamespaces: []atlasV1.ManagedNamespace{ + ManagedNamespaces: []akov2.ManagedNamespace{ { Db: managedNamespace[0].Db, Collection: managedNamespace[0].Collection, @@ -238,13 +237,13 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { PresplitHashedZones: managedNamespace[0].PresplitHashedZones, }, }, - BiConnector: &atlasV1.BiConnectorSpec{ + BiConnector: &akov2.BiConnectorSpec{ Enabled: cluster.BiConnector.Enabled, ReadPreference: *cluster.BiConnector.ReadPreference, }, ClusterType: *cluster.ClusterType, EncryptionAtRestProvider: *cluster.EncryptionAtRestProvider, - Labels: []common.LabelSpec{ + Labels: []akov2common.LabelSpec{ { Key: *cluster.Labels[0].Key, Value: *cluster.Labels[0].Value, @@ -253,33 +252,33 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { Name: clusterName, Paused: cluster.Paused, PitEnabled: cluster.PitEnabled, - ReplicationSpecs: []*atlasV1.AdvancedReplicationSpec{ + ReplicationSpecs: []*akov2.AdvancedReplicationSpec{ { NumShards: *cluster.ReplicationSpecs[0].NumShards, ZoneName: *cluster.ReplicationSpecs[0].ZoneName, - RegionConfigs: []*atlasV1.AdvancedRegionConfig{ + RegionConfigs: []*akov2.AdvancedRegionConfig{ { - AnalyticsSpecs: &atlasV1.Specs{ + AnalyticsSpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(*cluster.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs.DiskIOPS)), EbsVolumeType: *cluster.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs.EbsVolumeType, InstanceSize: *cluster.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs.InstanceSize, NodeCount: cluster.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs.NodeCount, }, - ElectableSpecs: &atlasV1.Specs{ + ElectableSpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(*cluster.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs.DiskIOPS)), EbsVolumeType: *cluster.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs.EbsVolumeType, InstanceSize: *cluster.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs.InstanceSize, NodeCount: cluster.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs.NodeCount, }, - ReadOnlySpecs: &atlasV1.Specs{ + ReadOnlySpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(*cluster.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs.DiskIOPS)), EbsVolumeType: *cluster.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs.EbsVolumeType, InstanceSize: *cluster.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs.InstanceSize, NodeCount: cluster.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs.NodeCount, }, - AutoScaling: &atlasV1.AdvancedAutoScalingSpec{ - DiskGB: &atlasV1.DiskGB{Enabled: cluster.ReplicationSpecs[0].RegionConfigs[0].AutoScaling.DiskGB.Enabled}, - Compute: &atlasV1.ComputeSpec{ + AutoScaling: &akov2.AdvancedAutoScalingSpec{ + DiskGB: &akov2.DiskGB{Enabled: cluster.ReplicationSpecs[0].RegionConfigs[0].AutoScaling.DiskGB.Enabled}, + Compute: &akov2.ComputeSpec{ Enabled: cluster.ReplicationSpecs[0].RegionConfigs[0].AutoScaling.Compute.Enabled, ScaleDownEnabled: cluster.ReplicationSpecs[0].RegionConfigs[0].AutoScaling.Compute.ScaleDownEnabled, MinInstanceSize: *cluster.ReplicationSpecs[0].RegionConfigs[0].AutoScaling.Compute.MinInstanceSize, @@ -296,12 +295,12 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { RootCertType: *cluster.RootCertType, VersionReleaseSystem: *cluster.VersionReleaseSystem, }, - BackupScheduleRef: common.ResourceRefNamespaced{ + BackupScheduleRef: akov2common.ResourceRefNamespaced{ Name: strings.ToLower(fmt.Sprintf("%s-%s-backupschedule", projectName, clusterName)), Namespace: targetNamespace, }, ServerlessSpec: nil, - ProcessArgs: &atlasV1.ProcessArgs{ + ProcessArgs: &akov2.ProcessArgs{ DefaultReadConcern: processArgs.GetDefaultReadConcern(), DefaultWriteConcern: processArgs.GetDefaultWriteConcern(), MinimumEnabledTLSProtocol: processArgs.GetMinimumEnabledTlsProtocol(), @@ -313,14 +312,14 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { SampleRefreshIntervalBIConnector: pointer.Get(int64(processArgs.GetSampleRefreshIntervalBIConnector())), }, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } - expectPolicies := []*atlasV1.AtlasBackupPolicy{ + expectPolicies := []*akov2.AtlasBackupPolicy{ { TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupPolicy", @@ -333,8 +332,8 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasBackupPolicySpec{ - Items: []atlasV1.AtlasBackupPolicyItem{ + Spec: akov2.AtlasBackupPolicySpec{ + Items: []akov2.AtlasBackupPolicyItem{ { FrequencyType: backupSchedule.Policies[0].PolicyItems[0].GetFrequencyType(), FrequencyInterval: backupSchedule.Policies[0].PolicyItems[0].GetFrequencyInterval(), @@ -343,11 +342,11 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { }, }, }, - Status: status.BackupPolicyStatus{}, + Status: akov2status.BackupPolicyStatus{}, }, } - expectSchedule := &atlasV1.AtlasBackupSchedule{ + expectSchedule := &akov2.AtlasBackupSchedule{ TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupSchedule", APIVersion: "atlas.mongodb.com/v1", @@ -359,13 +358,13 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasBackupScheduleSpec{ + Spec: akov2.AtlasBackupScheduleSpec{ AutoExportEnabled: *backupSchedule.AutoExportEnabled, - Export: &atlasV1.AtlasBackupExportSpec{ + Export: &akov2.AtlasBackupExportSpec{ ExportBucketID: backupSchedule.Export.GetExportBucketId(), FrequencyType: backupSchedule.Export.GetFrequencyType(), }, - PolicyRef: common.ResourceRefNamespaced{ + PolicyRef: akov2common.ResourceRefNamespaced{ Name: strings.ToLower(expectPolicies[0].Name), Namespace: expectPolicies[0].Namespace, }, @@ -374,17 +373,16 @@ func TestBuildAtlasAdvancedDeployment(t *testing.T) { RestoreWindowDays: int64(backupSchedule.GetRestoreWindowDays()), UpdateSnapshots: backupSchedule.GetUpdateSnapshots(), UseOrgAndGroupNamesInExportPrefix: backupSchedule.GetUseOrgAndGroupNamesInExportPrefix(), - CopySettings: []atlasV1.CopySetting{ + CopySettings: []akov2.CopySetting{ { - CloudProvider: pointer.Get("AWS"), - RegionName: pointer.Get("US_EAST_1"), - ReplicationSpecID: pointer.Get("123456"), - ShouldCopyOplogs: pointer.Get(false), - Frequencies: []string{"DAILY"}, + CloudProvider: pointer.Get("AWS"), + RegionName: pointer.Get("US_EAST_1"), + ShouldCopyOplogs: pointer.Get(false), + Frequencies: []string{"DAILY"}, }, }, }, - Status: status.BackupScheduleStatus{}, + Status: akov2status.BackupScheduleStatus{}, } expected := &AtlasDeploymentResult{ @@ -439,17 +437,17 @@ func TestBuildServerlessDeployments(t *testing.T) { } cluster := &atlasv2.ServerlessInstanceDescription{ - Id: toptr.MakePtr("TestClusterID"), - GroupId: toptr.MakePtr("TestGroupID"), - MongoDBVersion: toptr.MakePtr("5.0"), - Name: toptr.MakePtr(clusterName), - CreateDate: toptr.MakePtr(time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC)), + Id: akov2toptr.MakePtr("TestClusterID"), + GroupId: akov2toptr.MakePtr("TestGroupID"), + MongoDBVersion: akov2toptr.MakePtr("5.0"), + Name: akov2toptr.MakePtr(clusterName), + CreateDate: akov2toptr.MakePtr(time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC)), ProviderSettings: atlasv2.ServerlessProviderSettings{ BackingProviderName: "AWS", - ProviderName: toptr.MakePtr("AWS"), + ProviderName: akov2toptr.MakePtr("AWS"), RegionName: "US_EAST_1", }, - StateName: toptr.MakePtr(""), + StateName: akov2toptr.MakePtr(""), ServerlessBackupOptions: nil, ConnectionStrings: nil, Links: nil, @@ -458,7 +456,7 @@ func TestBuildServerlessDeployments(t *testing.T) { clusterStore.EXPECT().GetServerlessInstance(projectName, clusterName).Return(cluster, nil) clusterStore.EXPECT().ServerlessPrivateEndpoints(projectName, clusterName).Return(spe, nil) - expected := &atlasV1.AtlasDeployment{ + expected := &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -470,20 +468,20 @@ func TestBuildServerlessDeployments(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: strings.ToLower(projectName), Namespace: targetNamespace, }, - BackupScheduleRef: common.ResourceRefNamespaced{}, - ServerlessSpec: &atlasV1.ServerlessSpec{ + BackupScheduleRef: akov2common.ResourceRefNamespaced{}, + ServerlessSpec: &akov2.ServerlessSpec{ Name: atlas.StringOrEmpty(cluster.Name), - ProviderSettings: &atlasV1.ProviderSettingsSpec{ + ProviderSettings: &akov2.ProviderSettingsSpec{ BackingProviderName: cluster.ProviderSettings.BackingProviderName, - ProviderName: provider.ProviderName(atlas.StringOrEmpty(cluster.ProviderSettings.ProviderName)), + ProviderName: akov2provider.ProviderName(atlas.StringOrEmpty(cluster.ProviderSettings.ProviderName)), RegionName: cluster.ProviderSettings.RegionName, }, - PrivateEndpoints: []atlasV1.ServerlessPrivateEndpoint{ + PrivateEndpoints: []akov2.ServerlessPrivateEndpoint{ { Name: speComment, CloudProviderEndpointID: speCloudProviderEndpointID, @@ -493,9 +491,9 @@ func TestBuildServerlessDeployments(t *testing.T) { }, ProcessArgs: nil, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } diff --git a/internal/kubernetes/operator/features/crds.go b/internal/kubernetes/operator/features/crds.go index 3658f8edaf..df8b28ce09 100644 --- a/internal/kubernetes/operator/features/crds.go +++ b/internal/kubernetes/operator/features/crds.go @@ -25,7 +25,7 @@ import ( ) const ( - LatestOperatorMajorVersion = "1.9.0" + LatestOperatorMajorVersion = "2.0.0" maxDepth = 100 ResourceVersion = "app.kubernetes.io/version" ResourceAtlasProject = "atlasprojects" @@ -47,24 +47,7 @@ var ( ErrDocumentHasNoSpec = errors.New("document contains no Spec") versionsToResourcesMap = map[string][]string{ - "1.7.0": { - ResourceAtlasDatabaseUser, - ResourceAtlasProject, - ResourceAtlasDeployment, - ResourceAtlasBackupSchedule, - ResourceAtlasBackupPolicy, - ResourceAtlasTeam, - }, - "1.8.0": { - ResourceAtlasDatabaseUser, - ResourceAtlasProject, - ResourceAtlasDeployment, - ResourceAtlasBackupSchedule, - ResourceAtlasBackupPolicy, - ResourceAtlasTeam, - ResourceAtlasDataFederation, - }, - "1.9.0": { + "2.0.0": { ResourceAtlasDatabaseUser, ResourceAtlasProject, ResourceAtlasDeployment, diff --git a/internal/kubernetes/operator/features/crds_test.go b/internal/kubernetes/operator/features/crds_test.go index 9646a08aa4..6fa9a64705 100644 --- a/internal/kubernetes/operator/features/crds_test.go +++ b/internal/kubernetes/operator/features/crds_test.go @@ -273,9 +273,9 @@ func Test_CRDCompatibleVersion(t *testing.T) { }) t.Run("should return operator major version when it is less than supported CRD version", func(t *testing.T) { - crdVersion, err := semver.NewVersion(LatestOperatorMajorVersion) + latestOperatorSemver, err := semver.NewVersion(LatestOperatorMajorVersion) require.NoError(t, err) - operatorVersion := semver.New(crdVersion.Major(), crdVersion.Minor()-1, 2, "", "") + operatorVersion := semver.New(latestOperatorSemver.Major()-1, latestOperatorSemver.Minor(), 2, "", "") expected := fmt.Sprintf("%d.%d.0", operatorVersion.Major(), operatorVersion.Minor()) compatibleVersion, err := CRDCompatibleVersion(operatorVersion.String()) @@ -284,9 +284,9 @@ func Test_CRDCompatibleVersion(t *testing.T) { }) t.Run("should return operator major version when it is equal than supported CRD version", func(t *testing.T) { - crdVersion, err := semver.NewVersion(LatestOperatorMajorVersion) + latestOperatorSemver, err := semver.NewVersion(LatestOperatorMajorVersion) require.NoError(t, err) - operatorVersion := semver.New(crdVersion.Major(), crdVersion.Minor(), crdVersion.Patch(), "", "") + operatorVersion := semver.New(latestOperatorSemver.Major(), latestOperatorSemver.Minor(), latestOperatorSemver.Patch(), "", "") expected := fmt.Sprintf("%d.%d.0", operatorVersion.Major(), operatorVersion.Minor()) compatibleVersion, err := CRDCompatibleVersion(operatorVersion.String()) @@ -295,9 +295,9 @@ func Test_CRDCompatibleVersion(t *testing.T) { }) t.Run("should return CRD major version when it is less than operator version", func(t *testing.T) { - crdVersion, err := semver.NewVersion(LatestOperatorMajorVersion) + latestOperatorSemver, err := semver.NewVersion(LatestOperatorMajorVersion) require.NoError(t, err) - operatorVersion := semver.New(crdVersion.Major(), crdVersion.Minor()+1, 0, "", "") + operatorVersion := semver.New(latestOperatorSemver.Major(), latestOperatorSemver.Minor()+1, 0, "", "") compatibleVersion, err := CRDCompatibleVersion(operatorVersion.String()) require.NoError(t, err) diff --git a/internal/kubernetes/operator/install.go b/internal/kubernetes/operator/install.go index 78dd4f3ef7..dd583a2b5a 100644 --- a/internal/kubernetes/operator/install.go +++ b/internal/kubernetes/operator/install.go @@ -24,9 +24,9 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" "github.com/mongodb/mongodb-atlas-cli/internal/store" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" "go.mongodb.org/atlas-sdk/v20231115002/admin" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -140,8 +140,8 @@ func (i *Install) ensureProject(orgID, projectName string) (*admin.Group, error) Group: &admin.Group{ Name: projectName, OrgId: orgID, - RegionUsageRestrictions: toptr.MakePtr(""), - WithDefaultAlertsSettings: toptr.MakePtr(true), + RegionUsageRestrictions: akov2toptr.MakePtr(""), + WithDefaultAlertsSettings: akov2toptr.MakePtr(true), }, }) if err != nil { @@ -254,14 +254,14 @@ func (i *Install) importAtlasResources(orgID, apiKeyID string) error { } func (i *Install) ensureCredentialsAssignment(ctx context.Context) error { - projects := &akov1.AtlasProjectList{} + projects := &akov2.AtlasProjectList{} err := i.kubectl.List(ctx, projects, client.InNamespace(i.namespace)) if err != nil { return errors.New("failed to list projects") } for index := range projects.Items { - var connectionSecret *common.ResourceRefNamespaced + var connectionSecret *akov2common.ResourceRefNamespaced project := projects.Items[index] if i.projectName != "" { @@ -272,7 +272,7 @@ func (i *Install) ensureCredentialsAssignment(ctx context.Context) error { } } - connectionSecret = &common.ResourceRefNamespaced{ + connectionSecret = &akov2common.ResourceRefNamespaced{ Name: fmt.Sprintf(credentialsProjectScopedName, project.Name), Namespace: i.namespace, } diff --git a/internal/kubernetes/operator/project/project.go b/internal/kubernetes/operator/project/project.go index 2ea1b7c1e6..1832dfc6fd 100644 --- a/internal/kubernetes/operator/project/project.go +++ b/internal/kubernetes/operator/project/project.go @@ -25,15 +25,16 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - operatorProject "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/project" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2project "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/project" + akov2provider "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8snames "k8s.io/apiserver/pkg/storage/names" ) const ( @@ -68,9 +69,9 @@ var ( ) type AtlasProjectResult struct { - Project *atlasV1.AtlasProject + Project *akov2.AtlasProject Secrets []*corev1.Secret - Teams []*atlasV1.AtlasTeam + Teams []*akov2.AtlasTeam } func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator features.FeatureValidator, orgID, projectID, targetNamespace string, includeSecret bool, dictionary map[string]string, version string) (*AtlasProjectResult, error) { @@ -84,7 +85,7 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur return nil, ErrAtlasProject } - projectResult := &atlasV1.AtlasProject{ + projectResult := &akov2.AtlasProject{ TypeMeta: v1.TypeMeta{ Kind: "AtlasProject", APIVersion: "atlas.mongodb.com/v1", @@ -96,7 +97,7 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur features.ResourceVersion: version, }, }, - Spec: atlasV1.AtlasProjectSpec{ + Spec: akov2.AtlasProjectSpec{ Name: project.Name, ConnectionSecret: nil, ProjectIPAccessList: nil, @@ -115,9 +116,9 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur Teams: nil, RegionUsageRestrictions: atlas.StringOrEmpty(project.RegionUsageRestrictions), }, - Status: status.AtlasProjectStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasProjectStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -144,7 +145,7 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur projectResult.Spec.MaintenanceWindow = maintenanceWindows } - secretRef := &common.ResourceRefNamespaced{} + secretRef := &akov2common.ResourceRefNamespaced{} if includeSecret { secretRef.Name = resources.NormalizeAtlasName(fmt.Sprintf(credSecretFormat, project.Name), dictionary) } @@ -176,11 +177,12 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur } if validator.FeatureExist(features.ResourceAtlasProject, featureEncryptionAtRest) { - encryptionAtRest, ferr := buildEncryptionAtRest(projectStore, projectID) + encryptionAtRest, secrets, ferr := buildEncryptionAtRest(projectStore, projectID, project.Name, targetNamespace, dictionary) if ferr != nil { return nil, ferr } projectResult.Spec.EncryptionAtRest = encryptionAtRest + result.Secrets = append(result.Secrets, secrets...) } if validator.FeatureExist(features.ResourceAtlasProject, featureCloudProviderAccessRoles) { @@ -208,11 +210,12 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur } if validator.FeatureExist(features.ResourceAtlasProject, featureAlertConfiguration) { - alertConfigurations, ferr := buildAlertConfigurations(projectStore, projectID) + alertConfigurations, secrets, ferr := buildAlertConfigurations(projectStore, projectID, project.Name, targetNamespace, dictionary) if ferr != nil { return nil, ferr } projectResult.Spec.AlertConfigurations = alertConfigurations + result.Secrets = append(result.Secrets, secrets...) } if validator.FeatureExist(features.ResourceAtlasProject, featureCustomRoles) { @@ -236,12 +239,13 @@ func BuildAtlasProject(projectStore atlas.OperatorProjectStore, validator featur } func BuildProjectConnectionSecret(credsProvider store.CredentialsGetter, name, namespace, orgID string, includeCreds bool, dictionary map[string]string) *corev1.Secret { - secret := secrets.NewAtlasSecret(fmt.Sprintf("%s-credentials", name), namespace, map[string][]byte{ - secrets.CredOrgID: []byte(""), - secrets.CredPublicAPIKey: []byte(""), - secrets.CredPrivateAPIKey: []byte(""), - }, - dictionary) + secret := secrets.NewAtlasSecretBuilder(fmt.Sprintf("%s-credentials", name), namespace, dictionary). + WithData(map[string][]byte{ + secrets.CredOrgID: []byte(""), + secrets.CredPublicAPIKey: []byte(""), + secrets.CredPrivateAPIKey: []byte(""), + }). + Build() if includeCreds { secret.Data = map[string][]byte{ secrets.CredOrgID: []byte(orgID), @@ -252,7 +256,7 @@ func BuildProjectConnectionSecret(credsProvider store.CredentialsGetter, name, n return secret } -func buildCustomRoles(crProvider store.DatabaseRoleLister, projectID string) ([]atlasV1.CustomRole, error) { +func buildCustomRoles(crProvider store.DatabaseRoleLister, projectID string) ([]akov2.CustomRole, error) { dbRoles, err := crProvider.DatabaseRoles(projectID) if err != nil { return nil, err @@ -261,39 +265,39 @@ func buildCustomRoles(crProvider store.DatabaseRoleLister, projectID string) ([] return nil, nil } - result := make([]atlasV1.CustomRole, 0, len(dbRoles)) + result := make([]akov2.CustomRole, 0, len(dbRoles)) roles := dbRoles for rIdx := range roles { role := &roles[rIdx] - inhRoles := make([]atlasV1.Role, 0, len(role.InheritedRoles)) + inhRoles := make([]akov2.Role, 0, len(role.InheritedRoles)) for inhRIdx := range role.InheritedRoles { rl := &role.InheritedRoles[inhRIdx] - inhRoles = append(inhRoles, atlasV1.Role{ + inhRoles = append(inhRoles, akov2.Role{ Name: rl.Role, Database: rl.Db, }) } - actions := make([]atlasV1.Action, 0, len(role.Actions)) + actions := make([]akov2.Action, 0, len(role.Actions)) for aIdx := range role.Actions { action := &role.Actions[aIdx] - r := make([]atlasV1.Resource, 0, len(action.Resources)) + r := make([]akov2.Resource, 0, len(action.Resources)) for resIdx := range action.Resources { res := &action.Resources[resIdx] - r = append(r, atlasV1.Resource{ + r = append(r, akov2.Resource{ Cluster: &res.Cluster, Database: &res.Db, Collection: &res.Collection, }) } - actions = append(actions, atlasV1.Action{ + actions = append(actions, akov2.Action{ Name: action.Action, Resources: r, }) } - result = append(result, atlasV1.CustomRole{ + result = append(result, akov2.CustomRole{ Name: role.RoleName, InheritedRoles: inhRoles, Actions: actions, @@ -302,14 +306,14 @@ func buildCustomRoles(crProvider store.DatabaseRoleLister, projectID string) ([] return result, nil } -func buildAccessLists(accessListProvider atlas.ProjectIPAccessListLister, projectID string) ([]operatorProject.IPAccessList, error) { +func buildAccessLists(accessListProvider atlas.ProjectIPAccessListLister, projectID string) ([]akov2project.IPAccessList, error) { // pagination not required, max 200 entries can be configured via API accessLists, err := accessListProvider.ProjectIPAccessLists(projectID, &atlas.ListOptions{ItemsPerPage: MaxItems}) if err != nil { return nil, err } - result := make([]operatorProject.IPAccessList, 0, len(accessLists.Results)) + result := make([]akov2project.IPAccessList, 0, len(accessLists.Results)) for _, list := range accessLists.Results { if strings.HasSuffix(list.GetCidrBlock(), cidrException) && list.GetIpAddress() != "" { list.CidrBlock = pointer.Get("") @@ -318,7 +322,7 @@ func buildAccessLists(accessListProvider atlas.ProjectIPAccessListLister, projec if !list.GetDeleteAfterDate().IsZero() { deleteAfterDate = list.GetDeleteAfterDate().String() } - result = append(result, operatorProject.IPAccessList{ + result = append(result, akov2project.IPAccessList{ AwsSecurityGroup: list.GetAwsSecurityGroup(), CIDRBlock: list.GetCidrBlock(), Comment: list.GetComment(), @@ -329,13 +333,13 @@ func buildAccessLists(accessListProvider atlas.ProjectIPAccessListLister, projec return result, nil } -func buildMaintenanceWindows(mwProvider store.MaintenanceWindowDescriber, projectID string) (operatorProject.MaintenanceWindow, error) { +func buildMaintenanceWindows(mwProvider store.MaintenanceWindowDescriber, projectID string) (akov2project.MaintenanceWindow, error) { mw, err := mwProvider.MaintenanceWindow(projectID) if err != nil { - return operatorProject.MaintenanceWindow{}, err + return akov2project.MaintenanceWindow{}, err } - return operatorProject.MaintenanceWindow{ + return akov2project.MaintenanceWindow{ DayOfWeek: mw.DayOfWeek, HourOfDay: mw.HourOfDay, AutoDefer: pointer.GetOrDefault(mw.AutoDeferOnceEnabled, false), @@ -344,23 +348,26 @@ func buildMaintenanceWindows(mwProvider store.MaintenanceWindowDescriber, projec }, nil } -func buildIntegrations(intProvider store.IntegrationLister, projectID, targetNamespace string, includeSecrets bool, dictionary map[string]string) ([]operatorProject.Integration, []*corev1.Secret, error) { +func buildIntegrations(intProvider store.IntegrationLister, projectID, targetNamespace string, includeSecrets bool, dictionary map[string]string) ([]akov2project.Integration, []*corev1.Secret, error) { integrations, err := intProvider.Integrations(projectID) if err != nil { return nil, nil, err } - result := make([]operatorProject.Integration, 0, len(integrations.Results)) + result := make([]akov2project.Integration, 0, len(integrations.Results)) intSecrets := make([]*corev1.Secret, 0, len(integrations.Results)) for _, list := range integrations.Results { iType := list.GetType() - secret := secrets.NewAtlasSecret(fmt.Sprintf("%s-integration-%s", projectID, strings.ToLower(iType)), - targetNamespace, map[string][]byte{secrets.PasswordField: []byte("")}, dictionary) + secret := secrets.NewAtlasSecretBuilder( + fmt.Sprintf("%s-integration-%s", projectID, strings.ToLower(iType)), + targetNamespace, + dictionary, + ).WithData(map[string][]byte{secrets.PasswordField: []byte("")}).Build() - integration := operatorProject.Integration{ + integration := akov2project.Integration{ Type: iType, } - secretRef := common.ResourceRefNamespaced{ + secretRef := akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(secret.Name, dictionary), Namespace: targetNamespace, } @@ -414,9 +421,11 @@ func buildIntegrations(intProvider store.IntegrationLister, projectID, targetNam } if list.GetRoutingKey() != "" { // Secret with routing key - routingSecret := secrets.NewAtlasSecret(fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), + routingSecret := secrets.NewAtlasSecretBuilder( + fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), targetNamespace, - map[string][]byte{secrets.PasswordField: []byte(routingKeyData)}, dictionary) + dictionary, + ).WithData(map[string][]byte{secrets.PasswordField: []byte(routingKeyData)}).Build() intSecrets = append(intSecrets, routingSecret) } case newRelicIntegrationType: @@ -428,14 +437,16 @@ func buildIntegrations(intProvider store.IntegrationLister, projectID, targetNam writeToken = list.GetWriteToken() readToken = list.GetReadToken() } - writeTokenSecret := secrets.NewAtlasSecret(fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), + writeTokenSecret := secrets.NewAtlasSecretBuilder( + fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), targetNamespace, - map[string][]byte{secrets.PasswordField: []byte(writeToken)}, dictionary) - readTokenSecret := secrets.NewAtlasSecret(fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), + dictionary, + ).WithData(map[string][]byte{secrets.PasswordField: []byte(writeToken)}).Build() + readTokenSecret := secrets.NewAtlasSecretBuilder( + fmt.Sprintf("%s-integration-%s-routing-key", projectID, strings.ToLower(iType)), targetNamespace, - map[string][]byte{secrets.PasswordField: []byte(readToken)}, dictionary, - ) + ).WithData(map[string][]byte{secrets.PasswordField: []byte(readToken)}).Build() intSecrets = append(intSecrets, writeTokenSecret, readTokenSecret) } result = append(result, integration) @@ -445,21 +456,21 @@ func buildIntegrations(intProvider store.IntegrationLister, projectID, targetNam return result, intSecrets, nil } -func buildPrivateEndpoints(peProvider store.PrivateEndpointLister, projectID string) ([]atlasV1.PrivateEndpoint, error) { - var result []atlasV1.PrivateEndpoint - for _, cloudProvider := range []provider.ProviderName{provider.ProviderAWS, provider.ProviderGCP, provider.ProviderAzure} { +func buildPrivateEndpoints(peProvider store.PrivateEndpointLister, projectID string) ([]akov2.PrivateEndpoint, error) { + var result []akov2.PrivateEndpoint + for _, cloudProvider := range []akov2provider.ProviderName{akov2provider.ProviderAWS, akov2provider.ProviderGCP, akov2provider.ProviderAzure} { peList, err := peProvider.PrivateEndpoints(projectID, string(cloudProvider)) if err != nil { return nil, err } for i := range peList { pe := &peList[i] - result = append(result, atlasV1.PrivateEndpoint{ + result = append(result, akov2.PrivateEndpoint{ Provider: cloudProvider, IP: "", GCPProjectID: "", EndpointGroupName: "", - Endpoints: atlasV1.GCPEndpoints{}, + Endpoints: akov2.GCPEndpoints{}, ID: pe.GetId(), Region: pe.GetRegionName(), }) @@ -468,13 +479,13 @@ func buildPrivateEndpoints(peProvider store.PrivateEndpointLister, projectID str return result, nil } -func buildNetworkPeering(npProvider atlas.PeeringConnectionLister, projectID string) ([]atlasV1.NetworkPeer, error) { +func buildNetworkPeering(npProvider atlas.PeeringConnectionLister, projectID string) ([]akov2.NetworkPeer, error) { // pagination not required, max 25 entries per provider can be configured via API npListAWS, err := npProvider.PeeringConnections(projectID, &atlas.ContainersListOptions{ ListOptions: atlas.ListOptions{ ItemsPerPage: MaxItems, }, - ProviderName: string(provider.ProviderAWS), + ProviderName: string(akov2provider.ProviderAWS), }) if err != nil { return nil, fmt.Errorf("error getting network peering connections for AWS: %w", err) @@ -484,7 +495,7 @@ func buildNetworkPeering(npProvider atlas.PeeringConnectionLister, projectID str ListOptions: atlas.ListOptions{ ItemsPerPage: MaxItems, }, - ProviderName: string(provider.ProviderGCP), + ProviderName: string(akov2provider.ProviderGCP), }) if err != nil { return nil, fmt.Errorf("error getting network peering connections for GCP: %w", err) @@ -494,33 +505,33 @@ func buildNetworkPeering(npProvider atlas.PeeringConnectionLister, projectID str ListOptions: atlas.ListOptions{ ItemsPerPage: MaxItems, }, - ProviderName: string(provider.ProviderAzure), + ProviderName: string(akov2provider.ProviderAzure), }) if err != nil { return nil, fmt.Errorf("error getting network peering connections for Azure: %w", err) } - result := make([]atlasV1.NetworkPeer, 0, len(npListAWS)+len(npListGCP)+len(npListAzure)) + result := make([]akov2.NetworkPeer, 0, len(npListAWS)+len(npListGCP)+len(npListAzure)) for i := range npListAWS { np := npListAWS[i] - result = append(result, convertNetworkPeer(np, provider.ProviderAWS)) + result = append(result, convertNetworkPeer(np, akov2provider.ProviderAWS)) } for i := range npListGCP { np := npListGCP[i] - result = append(result, convertNetworkPeer(np, provider.ProviderGCP)) + result = append(result, convertNetworkPeer(np, akov2provider.ProviderGCP)) } for i := range npListAzure { np := npListAzure[i] - result = append(result, convertNetworkPeer(np, provider.ProviderAzure)) + result = append(result, convertNetworkPeer(np, akov2provider.ProviderAzure)) } return result, nil } -func convertNetworkPeer(np atlasv2.BaseNetworkPeeringConnectionSettings, providerName provider.ProviderName) atlasV1.NetworkPeer { +func convertNetworkPeer(np atlasv2.BaseNetworkPeeringConnectionSettings, providerName akov2provider.ProviderName) akov2.NetworkPeer { switch np.GetProviderName() { case "AWS": return convertAWSNetworkPeer(&np, providerName) @@ -529,12 +540,12 @@ func convertNetworkPeer(np atlasv2.BaseNetworkPeeringConnectionSettings, provide case "Azure": return convertAzureNetworkPeer(&np, providerName) default: - return atlasV1.NetworkPeer{} + return akov2.NetworkPeer{} } } -func convertAWSNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName provider.ProviderName) atlasV1.NetworkPeer { - return atlasV1.NetworkPeer{ +func convertAWSNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName akov2provider.ProviderName) akov2.NetworkPeer { + return akov2.NetworkPeer{ AccepterRegionName: np.GetAccepterRegionName(), AWSAccountID: np.GetAwsAccountId(), ContainerRegion: "", @@ -545,8 +556,8 @@ func convertAWSNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, pro } } -func convertAzureNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName provider.ProviderName) atlasV1.NetworkPeer { - return atlasV1.NetworkPeer{ +func convertAzureNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName akov2provider.ProviderName) akov2.NetworkPeer { + return akov2.NetworkPeer{ AzureDirectoryID: np.GetAzureDirectoryId(), AzureSubscriptionID: np.GetAzureSubscriptionId(), ContainerRegion: "", @@ -557,8 +568,8 @@ func convertAzureNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, p } } -func convertGCPNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName provider.ProviderName) atlasV1.NetworkPeer { - return atlasV1.NetworkPeer{ +func convertGCPNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, providerName akov2provider.ProviderName) akov2.NetworkPeer { + return akov2.NetworkPeer{ GCPProjectID: np.GetGcpProjectId(), ContainerRegion: "", ContainerID: np.ContainerId, @@ -567,51 +578,79 @@ func convertGCPNetworkPeer(np *atlasv2.BaseNetworkPeeringConnectionSettings, pro } } -func buildEncryptionAtRest(encProvider store.EncryptionAtRestDescriber, projectID string) (*atlasV1.EncryptionAtRest, error) { +func buildEncryptionAtRest(encProvider store.EncryptionAtRestDescriber, projectID, projectName, targetNamespace string, dictionary map[string]string) (*akov2.EncryptionAtRest, []*corev1.Secret, error) { data, err := encProvider.EncryptionAtRest(projectID) if err != nil { - return nil, err + return nil, nil, err } - return &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{ - Enabled: data.AwsKms.Enabled, - AccessKeyID: data.AwsKms.GetAccessKeyID(), - SecretAccessKey: data.AwsKms.GetSecretAccessKey(), - CustomerMasterKeyID: data.AwsKms.GetCustomerMasterKeyID(), - Region: data.AwsKms.GetRegion(), - RoleID: data.AwsKms.GetRoleId(), - Valid: data.AwsKms.Valid, + ref := &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + Enabled: data.AwsKms.Enabled, + Region: data.AwsKms.GetRegion(), + Valid: data.AwsKms.Valid, }, - AzureKeyVault: atlasV1.AzureKeyVault{ + AzureKeyVault: akov2.AzureKeyVault{ Enabled: data.AzureKeyVault.Enabled, ClientID: data.AzureKeyVault.GetClientID(), AzureEnvironment: data.AzureKeyVault.GetAzureEnvironment(), - SubscriptionID: data.AzureKeyVault.GetSubscriptionID(), ResourceGroupName: data.AzureKeyVault.GetResourceGroupName(), - KeyVaultName: data.AzureKeyVault.GetKeyVaultName(), - KeyIdentifier: data.AzureKeyVault.GetKeyIdentifier(), - Secret: data.AzureKeyVault.GetSecret(), TenantID: data.AzureKeyVault.GetTenantID(), }, - GoogleCloudKms: atlasV1.GoogleCloudKms{ - Enabled: data.GoogleCloudKms.Enabled, - ServiceAccountKey: data.GoogleCloudKms.GetServiceAccountKey(), - KeyVersionResourceID: data.GoogleCloudKms.GetKeyVersionResourceID(), + GoogleCloudKms: akov2.GoogleCloudKms{ + Enabled: data.GoogleCloudKms.Enabled, }, - }, nil + } + + var ss []*corev1.Secret + switch { + case data.AwsKms.Enabled != nil && *data.AwsKms.Enabled: + ref.AwsKms.SecretRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("aws-credentials-"), dictionary), + Namespace: targetNamespace, + } + + ss = append(ss, secrets.NewAtlasSecretBuilder(ref.AwsKms.SecretRef.Name, ref.AwsKms.SecretRef.Namespace, dictionary). + WithData(map[string][]byte{"CustomerMasterKeyID": []byte(""), "RoleID": []byte("")}). + WithProjectLabels(projectID, projectName). + Build()) + + case data.AzureKeyVault.Enabled != nil && *data.AzureKeyVault.Enabled: + ref.AzureKeyVault.SecretRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("azure-credentials-"), dictionary), + Namespace: targetNamespace, + } + + ss = append(ss, secrets.NewAtlasSecretBuilder(ref.AzureKeyVault.SecretRef.Name, ref.AzureKeyVault.SecretRef.Namespace, dictionary). + WithData(map[string][]byte{"SubscriptionID": []byte(""), "KeyVaultName": []byte(""), "KeyIdentifier": []byte(""), "Secret": []byte("")}). + WithProjectLabels(projectID, projectName). + Build()) + + case data.GoogleCloudKms.Enabled != nil && *data.GoogleCloudKms.Enabled: + ref.AzureKeyVault.SecretRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("gcp-credentials-"), dictionary), + Namespace: targetNamespace, + } + + ss = append(ss, secrets.NewAtlasSecretBuilder(ref.GoogleCloudKms.SecretRef.Name, ref.GoogleCloudKms.SecretRef.Namespace, dictionary). + WithData(map[string][]byte{"ServiceAccountKey": []byte(""), "KeyVersionResourceID": []byte("")}). + WithProjectLabels(projectID, projectName). + Build()) + } + + return ref, ss, nil } -func buildCloudProviderAccessRoles(cpaProvider store.CloudProviderAccessRoleLister, projectID string) ([]atlasV1.CloudProviderAccessRole, error) { +func buildCloudProviderAccessRoles(cpaProvider store.CloudProviderAccessRoleLister, projectID string) ([]akov2.CloudProviderAccessRole, error) { data, err := cpaProvider.CloudProviderAccessRoles(projectID) if err != nil { return nil, err } - result := make([]atlasV1.CloudProviderAccessRole, 0, len(data.AwsIamRoles)) + result := make([]akov2.CloudProviderAccessRole, 0, len(data.AwsIamRoles)) for i := range data.AwsIamRoles { cpa := &data.AwsIamRoles[i] - result = append(result, atlasV1.CloudProviderAccessRole{ + result = append(result, akov2.CloudProviderAccessRole{ ProviderName: cpa.ProviderName, IamAssumedRoleArn: cpa.GetIamAssumedRoleArn(), }) @@ -620,13 +659,13 @@ func buildCloudProviderAccessRoles(cpaProvider store.CloudProviderAccessRoleList return result, nil } -func buildProjectSettings(psProvider store.ProjectSettingsDescriber, projectID string) (*atlasV1.ProjectSettings, error) { +func buildProjectSettings(psProvider store.ProjectSettingsDescriber, projectID string) (*akov2.ProjectSettings, error) { data, err := psProvider.ProjectSettings(projectID) if err != nil { return nil, err } - return &atlasV1.ProjectSettings{ + return &akov2.ProjectSettings{ IsCollectDatabaseSpecificsStatisticsEnabled: data.IsCollectDatabaseSpecificsStatisticsEnabled, IsDataExplorerEnabled: data.IsDataExplorerEnabled, IsPerformanceAdvisorEnabled: data.IsPerformanceAdvisorEnabled, @@ -635,32 +674,32 @@ func buildProjectSettings(psProvider store.ProjectSettingsDescriber, projectID s }, nil } -func buildAuditing(auditingProvider store.AuditingDescriber, projectID string) (*atlasV1.Auditing, error) { +func buildAuditing(auditingProvider store.AuditingDescriber, projectID string) (*akov2.Auditing, error) { data, err := auditingProvider.Auditing(projectID) if err != nil { return nil, err } - return &atlasV1.Auditing{ + return &akov2.Auditing{ AuditAuthorizationSuccess: pointer.GetOrZero(data.AuditAuthorizationSuccess), AuditFilter: pointer.GetOrZero(data.AuditFilter), Enabled: pointer.GetOrZero(data.Enabled), }, nil } -func buildAlertConfigurations(acProvider atlas.AlertConfigurationLister, projectID string) ([]atlasV1.AlertConfiguration, error) { +func buildAlertConfigurations(acProvider atlas.AlertConfigurationLister, projectID, projectName, targetNamespace string, dictionary map[string]string) ([]akov2.AlertConfiguration, []*corev1.Secret, error) { data, err := acProvider.AlertConfigurations(&atlasv2.ListAlertConfigurationsApiParams{ GroupId: projectID, - ItemsPerPage: toptr.MakePtr(MaxItems), + ItemsPerPage: akov2toptr.MakePtr(MaxItems), }) if err != nil { - return nil, err + return nil, nil, err } - convertMatchers := func(atlasMatcher []map[string]interface{}) []atlasV1.Matcher { - var res []atlasV1.Matcher + convertMatchers := func(atlasMatcher []map[string]interface{}) []akov2.Matcher { + var res []akov2.Matcher for _, m := range atlasMatcher { - res = append(res, atlasV1.Matcher{ + res = append(res, akov2.Matcher{ FieldName: (m["FieldName"]).(string), Operator: (m["Operator"]).(string), Value: (m["Value"]).(string), @@ -669,11 +708,11 @@ func buildAlertConfigurations(acProvider atlas.AlertConfigurationLister, project return res } - convertMetricThreshold := func(atlasMT *atlasv2.ServerlessMetricThreshold) *atlasV1.MetricThreshold { + convertMetricThreshold := func(atlasMT *atlasv2.ServerlessMetricThreshold) *akov2.MetricThreshold { if atlasMT == nil { - return &atlasV1.MetricThreshold{} + return &akov2.MetricThreshold{} } - return &atlasV1.MetricThreshold{ + return &akov2.MetricThreshold{ MetricName: atlasMT.MetricName, Operator: atlas.StringOrEmpty(atlasMT.Operator), Threshold: fmt.Sprintf("%f", pointer.GetOrDefault(atlasMT.Threshold, 0.0)), @@ -682,62 +721,140 @@ func buildAlertConfigurations(acProvider atlas.AlertConfigurationLister, project } } - convertThreshold := func(atlasT *atlasv2.GreaterThanRawThreshold) *atlasV1.Threshold { + convertThreshold := func(atlasT *atlasv2.GreaterThanRawThreshold) *akov2.Threshold { if atlasT == nil { - return &atlasV1.Threshold{} + return &akov2.Threshold{} } - return &atlasV1.Threshold{ + return &akov2.Threshold{ Operator: atlas.StringOrEmpty(atlasT.Operator), Units: atlas.StringOrEmpty(atlasT.Units), Threshold: fmt.Sprintf("%d", pointer.GetOrDefault(atlasT.Threshold, 0)), } } + convertNotifications := func(atlasNotifications []atlasv2.AlertsNotificationRootForGroup) ([]akov2.Notification, []*corev1.Secret) { + var ( + akoNotifications []akov2.Notification + akoSecrets []*corev1.Secret + ) + + for _, atlasNotification := range atlasNotifications { + akoNotification := akov2.Notification{ + ChannelName: atlas.StringOrEmpty(atlasNotification.ChannelName), + DatadogRegion: atlas.StringOrEmpty(atlasNotification.DatadogRegion), + DelayMin: atlasNotification.DelayMin, + EmailAddress: atlas.StringOrEmpty(atlasNotification.EmailAddress), + EmailEnabled: atlasNotification.EmailEnabled, + IntervalMin: pointer.GetOrDefault(atlasNotification.IntervalMin, 0), + MobileNumber: atlas.StringOrEmpty(atlasNotification.MobileNumber), + OpsGenieRegion: atlas.StringOrEmpty(atlasNotification.OpsGenieRegion), + SMSEnabled: atlasNotification.SmsEnabled, + TeamID: atlas.StringOrEmpty(atlasNotification.TeamId), + TeamName: atlas.StringOrEmpty(atlasNotification.TeamName), + TypeName: atlas.StringOrEmpty(atlasNotification.TypeName), + Username: atlas.StringOrEmpty(atlasNotification.Username), + Roles: atlasNotification.Roles, + } - convertNotifications := func(atlasN []atlasv2.AlertsNotificationRootForGroup) []atlasV1.Notification { - var res []atlasV1.Notification - for _, n := range atlasN { - res = append(res, atlasV1.Notification{ - APIToken: atlas.StringOrEmpty(n.ApiToken), - ChannelName: atlas.StringOrEmpty(n.ChannelName), - DatadogAPIKey: atlas.StringOrEmpty(n.DatadogApiKey), - DatadogRegion: atlas.StringOrEmpty(n.DatadogRegion), - DelayMin: n.DelayMin, - EmailAddress: atlas.StringOrEmpty(n.EmailAddress), - EmailEnabled: n.EmailEnabled, - IntervalMin: pointer.GetOrDefault(n.IntervalMin, 0), - MobileNumber: atlas.StringOrEmpty(n.MobileNumber), - OpsGenieAPIKey: atlas.StringOrEmpty(n.OpsGenieApiKey), - OpsGenieRegion: atlas.StringOrEmpty(n.OpsGenieRegion), - ServiceKey: atlas.StringOrEmpty(n.ServiceKey), - SMSEnabled: n.SmsEnabled, - TeamID: atlas.StringOrEmpty(n.TeamId), - TeamName: atlas.StringOrEmpty(n.TeamName), - TypeName: atlas.StringOrEmpty(n.TypeName), - Username: atlas.StringOrEmpty(n.Username), - VictorOpsAPIKey: atlas.StringOrEmpty(n.VictorOpsApiKey), - VictorOpsRoutingKey: atlas.StringOrEmpty(n.VictorOpsRoutingKey), - Roles: n.Roles, - }) + if atlasNotification.TypeName != nil { + switch *atlasNotification.TypeName { + case pagerDutyIntegrationType: + akoNotification.ServiceKeyRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("service-key-"), dictionary), + Namespace: targetNamespace, + } + + akoSecrets = append(akoSecrets, + secrets.NewAtlasSecretBuilder(akoNotification.ServiceKeyRef.Name, akoNotification.ServiceKeyRef.Namespace, dictionary). + WithData(map[string][]byte{"ServiceKey": []byte("")}). + WithProjectLabels(projectID, projectName). + WithNotifierLabels(atlasNotification.NotifierId, pagerDutyIntegrationType). + Build()) + + case slackIntegrationType: + akoNotification.APITokenRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("api-token-"), dictionary), + Namespace: targetNamespace, + } + + akoSecrets = append(akoSecrets, + secrets.NewAtlasSecretBuilder(akoNotification.APITokenRef.Name, akoNotification.APITokenRef.Namespace, dictionary). + WithData(map[string][]byte{"APIToken": []byte("")}). + WithProjectLabels(projectID, projectName). + WithNotifierLabels(atlasNotification.NotifierId, slackIntegrationType). + Build()) + + case datadogIntegrationType: + akoNotification.DatadogAPIKeyRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("datadog-api-key-"), dictionary), + Namespace: targetNamespace, + } + + akoSecrets = append(akoSecrets, + secrets.NewAtlasSecretBuilder(akoNotification.DatadogAPIKeyRef.Name, akoNotification.DatadogAPIKeyRef.Namespace, dictionary). + WithData(map[string][]byte{"DatadogAPIKey": []byte("")}). + WithProjectLabels(projectID, projectName). + WithNotifierLabels(atlasNotification.NotifierId, datadogIntegrationType). + Build()) + + case opsGenieIntegrationType: + akoNotification.OpsGenieAPIKeyRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("ops-genie-api-key-"), dictionary), + Namespace: targetNamespace, + } + + akoSecrets = append(akoSecrets, + secrets.NewAtlasSecretBuilder(akoNotification.OpsGenieAPIKeyRef.Name, akoNotification.OpsGenieAPIKeyRef.Namespace, dictionary). + WithData(map[string][]byte{"OpsGenieAPIKey": []byte("")}). + WithProjectLabels(projectID, projectName). + WithNotifierLabels(atlasNotification.NotifierId, opsGenieIntegrationType). + Build()) + + case victorOpsIntegrationType: + akoNotification.VictorOpsSecretRef = akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(generateName("victor-ops-credentials-"), dictionary), + Namespace: targetNamespace, + } + + akoSecrets = append(akoSecrets, + secrets.NewAtlasSecretBuilder(akoNotification.VictorOpsSecretRef.Name, akoNotification.VictorOpsSecretRef.Namespace, dictionary). + WithData(map[string][]byte{"VictorOpsAPIKey": []byte(""), "VictorOpsRoutingKey": []byte("")}). + WithProjectLabels(projectID, projectName). + WithNotifierLabels(atlasNotification.NotifierId, victorOpsIntegrationType). + Build()) + } + } + + akoNotifications = append(akoNotifications, akoNotification) } - return res + + return akoNotifications, akoSecrets } - result := make([]atlasV1.AlertConfiguration, 0, len(data.Results)) - for _, alertConfig := range data.Results { - result = append(result, atlasV1.AlertConfiguration{ + secretResults := []*corev1.Secret{} + results := make([]akov2.AlertConfiguration, 0, len(data.Results)) + for i := range data.Results { + alertConfig := &data.Results[i] + + notifications, notificationSecrets := convertNotifications(alertConfig.Notifications) + secretResults = append(secretResults, notificationSecrets...) + + results = append(results, akov2.AlertConfiguration{ EventTypeName: atlas.StringOrEmpty(alertConfig.EventTypeName), Enabled: pointer.GetOrDefault(alertConfig.Enabled, false), Matchers: convertMatchers(alertConfig.Matchers), MetricThreshold: convertMetricThreshold(alertConfig.MetricThreshold), Threshold: convertThreshold(alertConfig.Threshold), - Notifications: convertNotifications(alertConfig.Notifications), + Notifications: notifications, }) } + return results, secretResults, nil +} - return result, nil +func generateName(base string) string { + return k8snames.SimpleNameGenerator.GenerateName(base) } -func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projectName, targetNamespace, version string, dictionary map[string]string) ([]atlasV1.Team, []*atlasV1.AtlasTeam, error) { +func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projectName, targetNamespace, version string, dictionary map[string]string) ([]akov2.Team, []*akov2.AtlasTeam, error) { projectTeams, err := teamsProvider.ProjectTeams(projectID) if err != nil { return nil, nil, err @@ -755,31 +872,31 @@ func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projec return result, nil } - convertRoleNames := func(input []string) []atlasV1.TeamRole { + convertRoleNames := func(input []string) []akov2.TeamRole { if len(input) == 0 { return nil } - result := make([]atlasV1.TeamRole, 0, len(input)) + result := make([]akov2.TeamRole, 0, len(input)) for i := range input { - result = append(result, atlasV1.TeamRole(input[i])) + result = append(result, akov2.TeamRole(input[i])) } return result } - convertUserNames := func(input []string) []atlasV1.TeamUser { + convertUserNames := func(input []string) []akov2.TeamUser { if len(input) == 0 { return nil } - result := make([]atlasV1.TeamUser, 0, len(input)) + result := make([]akov2.TeamUser, 0, len(input)) for i := range input { - result = append(result, atlasV1.TeamUser(input[i])) + result = append(result, akov2.TeamUser(input[i])) } return result } - teamsRefs := make([]atlasV1.Team, 0, len(projectTeams.Results)) - atlasTeamCRs := make([]*atlasV1.AtlasTeam, 0, len(projectTeams.Results)) + teamsRefs := make([]akov2.Team, 0, len(projectTeams.Results)) + atlasTeamCRs := make([]*akov2.AtlasTeam, 0, len(projectTeams.Results)) for i := range projectTeams.Results { teamRef := projectTeams.Results[i] @@ -793,8 +910,8 @@ func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projec teamName := atlas.StringOrEmpty(team.Name) crName := resources.NormalizeAtlasName(fmt.Sprintf("%s-team-%s", projectName, teamName), dictionary) - teamsRefs = append(teamsRefs, atlasV1.Team{ - TeamRef: common.ResourceRefNamespaced{ + teamsRefs = append(teamsRefs, akov2.Team{ + TeamRef: akov2common.ResourceRefNamespaced{ Name: crName, Namespace: targetNamespace, }, @@ -806,7 +923,7 @@ func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projec return nil, nil, err } - atlasTeamCRs = append(atlasTeamCRs, &atlasV1.AtlasTeam{ + atlasTeamCRs = append(atlasTeamCRs, &akov2.AtlasTeam{ TypeMeta: v1.TypeMeta{ Kind: "AtlasTeam", APIVersion: "atlas.mongodb.com/v1", @@ -818,13 +935,13 @@ func buildTeams(teamsProvider atlas.OperatorTeamsStore, orgID, projectID, projec features.ResourceVersion: version, }, }, - Spec: atlasV1.TeamSpec{ + Spec: akov2.TeamSpec{ Name: atlas.StringOrEmpty(team.Name), Usernames: convertUserNames(users), }, - Status: status.TeamStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.TeamStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, }) diff --git a/internal/kubernetes/operator/project/project_test.go b/internal/kubernetes/operator/project/project_test.go index 119db3e363..96292493f1 100644 --- a/internal/kubernetes/operator/project/project_test.go +++ b/internal/kubernetes/operator/project/project_test.go @@ -23,6 +23,7 @@ import ( "testing" "time" + "github.com/go-test/deep" "github.com/golang/mock/gomock" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" @@ -31,31 +32,33 @@ import ( atlasmocks "github.com/mongodb/mongodb-atlas-cli/internal/mocks/atlas" "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/store/atlas" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/project" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2project "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/project" + akov2provider "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" + "github.com/stretchr/testify/assert" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const orgID = "TestOrgID" -const projectID = "TestProjectID" -const teamID = "TestTeamID" -const resourceVersion = "x.y.z" +const ( + orgID = "TestOrgID" + projectID = "TestProjectID" + teamID = "TestTeamID" + resourceVersion = "x.y.z" + targetNamespace = "test-namespace" +) func TestBuildAtlasProject(t *testing.T) { ctl := gomock.NewController(t) projectStore := atlasmocks.NewMockOperatorProjectStore(ctl) featureValidator := mocks.NewMockFeatureValidator(ctl) t.Run("Can convert Project entity with secrets data", func(t *testing.T) { - targetNamespace := "test-namespace" - p := &atlasv2.Group{ - Id: toptr.MakePtr(projectID), + Id: akov2toptr.MakePtr(projectID), OrgId: orgID, Name: "TestProjectName", ClusterCount: 0, @@ -96,7 +99,7 @@ func TestBuildAtlasProject(t *testing.T) { CreatedDate: &createDate, FeatureUsages: nil, IamAssumedRoleArn: pointer.Get("TestRoleARN"), - ProviderName: string(provider.ProviderAWS), + ProviderName: string(akov2provider.ProviderAWS), RoleId: pointer.Get("TestRoleID"), }, }, @@ -139,7 +142,7 @@ func TestBuildAtlasProject(t *testing.T) { ContainerId: "TestContainerID", ErrorStateName: pointer.Get("TestErrStateName"), Id: pointer.Get("TestID"), - ProviderName: pointer.Get(string(provider.ProviderAWS)), + ProviderName: pointer.Get(string(akov2provider.ProviderAWS)), RouteTableCidrBlock: pointer.Get("0.0.0.0/0"), StatusName: pointer.Get("TestStatusName"), VpcId: pointer.Get("TestVPCID"), @@ -149,7 +152,7 @@ func TestBuildAtlasProject(t *testing.T) { privateAWSEndpoint := atlasv2.EndpointService{ Id: pointer.Get("TestID"), - CloudProvider: string(provider.ProviderAWS), + CloudProvider: string(akov2provider.ProviderAWS), RegionName: pointer.Get("US_WEST_2"), EndpointServiceName: nil, ErrorMessage: nil, @@ -184,7 +187,6 @@ func TestBuildAtlasProject(t *testing.T) { }, Notifications: []atlasv2.AlertsNotificationRootForGroup{ { - ApiToken: pointer.Get("TestAPIToken"), ChannelName: pointer.Get("TestChannelName"), DatadogApiKey: pointer.Get("TestDatadogAPIKey"), DatadogRegion: pointer.Get("TestDatadogRegion"), @@ -247,15 +249,15 @@ func TestBuildAtlasProject(t *testing.T) { Links: nil, Results: []atlasv2.TeamRole{ { - TeamId: toptr.MakePtr(teamID), - RoleNames: []string{string(atlasV1.TeamRoleClusterManager)}, + TeamId: akov2toptr.MakePtr(teamID), + RoleNames: []string{string(akov2.TeamRoleClusterManager)}, }, }, - TotalCount: toptr.MakePtr(1), + TotalCount: akov2toptr.MakePtr(1), } teams := &atlasv2.TeamResponse{ - Id: toptr.MakePtr(teamID), - Name: toptr.MakePtr("TestTeamName"), + Id: akov2toptr.MakePtr(teamID), + Name: akov2toptr.MakePtr("TestTeamName"), } teamUsers := &atlasv2.PaginatedApiAppUser{ @@ -263,11 +265,11 @@ func TestBuildAtlasProject(t *testing.T) { { EmailAddress: "testuser@mooooongodb.com", FirstName: "TestName", - Id: toptr.MakePtr("TestID"), + Id: akov2toptr.MakePtr("TestID"), LastName: "TestLastName", }, }, - TotalCount: toptr.MakePtr(1), + TotalCount: akov2toptr.MakePtr(1), } listOption := &atlas.ListOptions{ItemsPerPage: MaxItems} @@ -275,9 +277,9 @@ func TestBuildAtlasProject(t *testing.T) { GroupId: projectID, ItemsPerPage: &listOption.ItemsPerPage, } - containerListOptionAWS := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(provider.ProviderAWS)} - containerListOptionGCP := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(provider.ProviderGCP)} - containerListOptionAzure := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(provider.ProviderAzure)} + containerListOptionAWS := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(akov2provider.ProviderAWS)} + containerListOptionGCP := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(akov2provider.ProviderGCP)} + containerListOptionAzure := &atlas.ContainersListOptions{ListOptions: *listOption, ProviderName: string(akov2provider.ProviderAzure)} projectStore.EXPECT().Project(projectID).Return(p, nil) projectStore.EXPECT().ProjectIPAccessLists(projectID, listOption).Return(ipAccessLists, nil) projectStore.EXPECT().MaintenanceWindow(projectID).Return(mw, nil) @@ -285,9 +287,9 @@ func TestBuildAtlasProject(t *testing.T) { projectStore.EXPECT().PeeringConnections(projectID, containerListOptionAWS).Return(peeringConnections, nil) projectStore.EXPECT().PeeringConnections(projectID, containerListOptionGCP).Return(nil, nil) projectStore.EXPECT().PeeringConnections(projectID, containerListOptionAzure).Return(nil, nil) - projectStore.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderAWS)).Return(privateEndpoints, nil) - projectStore.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderGCP)).Return(nil, nil) - projectStore.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderAzure)).Return(nil, nil) + projectStore.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderAWS)).Return(privateEndpoints, nil) + projectStore.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderGCP)).Return(nil, nil) + projectStore.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderAzure)).Return(nil, nil) projectStore.EXPECT().EncryptionAtRest(projectID).Return(encryptionAtRest, nil) projectStore.EXPECT().CloudProviderAccessRoles(projectID).Return(cpas, nil) projectStore.EXPECT().ProjectSettings(projectID).Return(projectSettings, nil) @@ -320,43 +322,57 @@ func TestBuildAtlasProject(t *testing.T) { gotTeams := projectResult.Teams alertConfigs := alertConfigResult.Results - expectedThreshold := &atlasV1.Threshold{ + expectedThreshold := &akov2.Threshold{ Operator: atlas.StringOrEmpty(alertConfigs[0].Threshold.Operator), Units: atlas.StringOrEmpty(alertConfigs[0].Threshold.Units), Threshold: fmt.Sprintf("%d", pointer.GetOrDefault(alertConfigs[0].Threshold.Threshold, 0)), } - expectedMatchers := []atlasV1.Matcher{ + expectedMatchers := []akov2.Matcher{ { FieldName: (alertConfigs[0].Matchers[0]["FieldName"]).(string), Operator: (alertConfigs[0].Matchers[0]["Operator"]).(string), Value: (alertConfigs[0].Matchers[0]["Value"]).(string), }, } - expectedNotifications := []atlasV1.Notification{ + expectedNotifications := []akov2.Notification{ { - APIToken: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].ApiToken), - ChannelName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].ChannelName), - DatadogAPIKey: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].DatadogApiKey), - DatadogRegion: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].DatadogRegion), - DelayMin: alertConfigs[0].Notifications[0].DelayMin, - EmailAddress: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].EmailAddress), - EmailEnabled: alertConfigs[0].Notifications[0].EmailEnabled, - IntervalMin: pointer.GetOrDefault(alertConfigs[0].Notifications[0].IntervalMin, 0), - MobileNumber: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].MobileNumber), - OpsGenieAPIKey: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].OpsGenieApiKey), - OpsGenieRegion: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].OpsGenieRegion), - ServiceKey: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].ServiceKey), - SMSEnabled: alertConfigs[0].Notifications[0].SmsEnabled, - TeamID: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TeamId), - TeamName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TeamName), - TypeName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TypeName), - Username: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].Username), - VictorOpsAPIKey: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].VictorOpsApiKey), - VictorOpsRoutingKey: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].VictorOpsRoutingKey), - Roles: alertConfigs[0].Notifications[0].Roles, + APITokenRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.AlertConfigurations[0].Notifications[0].APITokenRef.Name, + Namespace: gotProject.Spec.AlertConfigurations[0].Notifications[0].APITokenRef.Namespace, + }, + ChannelName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].ChannelName), + DatadogRegion: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].DatadogRegion), + DatadogAPIKeyRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.AlertConfigurations[0].Notifications[0].DatadogAPIKeyRef.Name, + Namespace: gotProject.Spec.AlertConfigurations[0].Notifications[0].DatadogAPIKeyRef.Namespace, + }, + DelayMin: alertConfigs[0].Notifications[0].DelayMin, + EmailAddress: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].EmailAddress), + EmailEnabled: alertConfigs[0].Notifications[0].EmailEnabled, + IntervalMin: pointer.GetOrDefault(alertConfigs[0].Notifications[0].IntervalMin, 0), + MobileNumber: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].MobileNumber), + OpsGenieRegion: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].OpsGenieRegion), + OpsGenieAPIKeyRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.AlertConfigurations[0].Notifications[0].OpsGenieAPIKeyRef.Name, + Namespace: gotProject.Spec.AlertConfigurations[0].Notifications[0].OpsGenieAPIKeyRef.Namespace, + }, + ServiceKeyRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.AlertConfigurations[0].Notifications[0].ServiceKeyRef.Name, + Namespace: gotProject.Spec.AlertConfigurations[0].Notifications[0].ServiceKeyRef.Namespace, + }, + SMSEnabled: alertConfigs[0].Notifications[0].SmsEnabled, + TeamID: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TeamId), + TeamName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TeamName), + TypeName: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].TypeName), + Username: atlas.StringOrEmpty(alertConfigs[0].Notifications[0].Username), + Roles: alertConfigs[0].Notifications[0].Roles, + VictorOpsSecretRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.AlertConfigurations[0].Notifications[0].VictorOpsSecretRef.Name, + Namespace: gotProject.Spec.AlertConfigurations[0].Notifications[0].VictorOpsSecretRef.Namespace, + }, }, } - expectedMetricThreshold := &atlasV1.MetricThreshold{ + expectedMetricThreshold := &akov2.MetricThreshold{ MetricName: alertConfigs[0].MetricThreshold.MetricName, Operator: atlas.StringOrEmpty(alertConfigs[0].MetricThreshold.Operator), Threshold: fmt.Sprintf("%f", pointer.GetOrDefault(alertConfigs[0].MetricThreshold.Threshold, 0.0)), @@ -364,7 +380,7 @@ func TestBuildAtlasProject(t *testing.T) { Mode: atlas.StringOrEmpty(alertConfigs[0].MetricThreshold.Mode), } teamsName := atlas.StringOrEmpty(teams.Name) - expectedTeams := []*atlasV1.AtlasTeam{ + expectedTeams := []*akov2.AtlasTeam{ { TypeMeta: v1.TypeMeta{ Kind: "AtlasTeam", @@ -377,18 +393,18 @@ func TestBuildAtlasProject(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.TeamSpec{ + Spec: akov2.TeamSpec{ Name: teamsName, - Usernames: []atlasV1.TeamUser{atlasV1.TeamUser(teamUsers.Results[0].Username)}, + Usernames: []akov2.TeamUser{akov2.TeamUser(teamUsers.Results[0].Username)}, }, - Status: status.TeamStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.TeamStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, }, } - expectedProject := &atlasV1.AtlasProject{ + expectedProject := &akov2.AtlasProject{ TypeMeta: v1.TypeMeta{ Kind: "AtlasProject", APIVersion: "atlas.mongodb.com/v1", @@ -400,12 +416,12 @@ func TestBuildAtlasProject(t *testing.T) { features.ResourceVersion: resourceVersion, }, }, - Spec: atlasV1.AtlasProjectSpec{ + Spec: akov2.AtlasProjectSpec{ Name: p.Name, - ConnectionSecret: &common.ResourceRefNamespaced{ + ConnectionSecret: &akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(fmt.Sprintf(credSecretFormat, p.Name), dictionary), }, - ProjectIPAccessList: []project.IPAccessList{ + ProjectIPAccessList: []akov2project.IPAccessList{ { AwsSecurityGroup: ipAccessLists.Results[0].GetAwsSecurityGroup(), CIDRBlock: ipAccessLists.Results[0].GetCidrBlock(), @@ -414,31 +430,31 @@ func TestBuildAtlasProject(t *testing.T) { IPAddress: ipAccessLists.Results[0].GetIpAddress(), }, }, - MaintenanceWindow: project.MaintenanceWindow{ + MaintenanceWindow: akov2project.MaintenanceWindow{ DayOfWeek: mw.DayOfWeek, HourOfDay: mw.HourOfDay, AutoDefer: pointer.GetOrDefault(mw.AutoDeferOnceEnabled, false), StartASAP: pointer.GetOrDefault(mw.StartASAP, false), Defer: false, }, - PrivateEndpoints: []atlasV1.PrivateEndpoint{ + PrivateEndpoints: []akov2.PrivateEndpoint{ { - Provider: provider.ProviderAWS, + Provider: akov2provider.ProviderAWS, Region: *privateAWSEndpoint.RegionName, ID: *privateAWSEndpoint.Id, IP: "", GCPProjectID: "", EndpointGroupName: "", - Endpoints: atlasV1.GCPEndpoints{}, + Endpoints: akov2.GCPEndpoints{}, }, }, - CloudProviderAccessRoles: []atlasV1.CloudProviderAccessRole{ + CloudProviderAccessRoles: []akov2.CloudProviderAccessRole{ { ProviderName: cpas.AwsIamRoles[0].ProviderName, IamAssumedRoleArn: *cpas.AwsIamRoles[0].IamAssumedRoleArn, }, }, - AlertConfigurations: []atlasV1.AlertConfiguration{ + AlertConfigurations: []akov2.AlertConfiguration{ { Enabled: *alertConfigs[0].Enabled, EventTypeName: atlas.StringOrEmpty(alertConfigs[0].EventTypeName), @@ -449,24 +465,24 @@ func TestBuildAtlasProject(t *testing.T) { }, }, AlertConfigurationSyncEnabled: false, - NetworkPeers: []atlasV1.NetworkPeer{ + NetworkPeers: []akov2.NetworkPeer{ { AccepterRegionName: peeringConnectionAWS.GetAccepterRegionName(), ContainerRegion: "", AWSAccountID: peeringConnectionAWS.GetAwsAccountId(), ContainerID: peeringConnectionAWS.ContainerId, - ProviderName: provider.ProviderName(*peeringConnectionAWS.ProviderName), + ProviderName: akov2provider.ProviderName(*peeringConnectionAWS.ProviderName), RouteTableCIDRBlock: peeringConnectionAWS.GetRouteTableCidrBlock(), VpcID: peeringConnectionAWS.GetVpcId(), }, }, WithDefaultAlertsSettings: false, X509CertRef: nil, - Integrations: []project.Integration{ + Integrations: []akov2project.Integration{ { Type: thirdPartyIntegrations.Results[0].GetType(), UserName: thirdPartyIntegrations.Results[0].GetUsername(), - PasswordRef: common.ResourceRefNamespaced{ + PasswordRef: akov2common.ResourceRefNamespaced{ Name: fmt.Sprintf("%s-integration-%s", strings.ToLower(projectID), strings.ToLower(thirdPartyIntegrations.Results[0].GetType())), @@ -475,40 +491,52 @@ func TestBuildAtlasProject(t *testing.T) { ServiceDiscovery: thirdPartyIntegrations.Results[0].GetServiceDiscovery(), }, }, - EncryptionAtRest: &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{}, - AzureKeyVault: atlasV1.AzureKeyVault{}, - GoogleCloudKms: atlasV1.GoogleCloudKms{ - Enabled: encryptionAtRest.GoogleCloudKms.Enabled, - ServiceAccountKey: encryptionAtRest.GoogleCloudKms.GetServiceAccountKey(), - KeyVersionResourceID: encryptionAtRest.GoogleCloudKms.GetKeyVersionResourceID(), + EncryptionAtRest: &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.EncryptionAtRest.AwsKms.SecretRef.Name, + Namespace: gotProject.Spec.EncryptionAtRest.AwsKms.SecretRef.Namespace, + }, + }, + AzureKeyVault: akov2.AzureKeyVault{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.EncryptionAtRest.AzureKeyVault.SecretRef.Name, + Namespace: gotProject.Spec.EncryptionAtRest.AzureKeyVault.SecretRef.Namespace, + }, + }, + GoogleCloudKms: akov2.GoogleCloudKms{ + Enabled: encryptionAtRest.GoogleCloudKms.Enabled, + SecretRef: akov2common.ResourceRefNamespaced{ + Name: gotProject.Spec.EncryptionAtRest.GoogleCloudKms.SecretRef.Name, + Namespace: gotProject.Spec.EncryptionAtRest.GoogleCloudKms.SecretRef.Namespace, + }, }, }, - Auditing: &atlasV1.Auditing{ + Auditing: &akov2.Auditing{ AuditAuthorizationSuccess: pointer.GetOrZero(auditing.AuditAuthorizationSuccess), AuditFilter: pointer.GetOrZero(auditing.AuditFilter), Enabled: pointer.GetOrZero(auditing.Enabled), }, - Settings: &atlasV1.ProjectSettings{ + Settings: &akov2.ProjectSettings{ IsCollectDatabaseSpecificsStatisticsEnabled: projectSettings.IsCollectDatabaseSpecificsStatisticsEnabled, IsDataExplorerEnabled: projectSettings.IsDataExplorerEnabled, IsPerformanceAdvisorEnabled: projectSettings.IsPerformanceAdvisorEnabled, IsRealtimePerformancePanelEnabled: projectSettings.IsRealtimePerformancePanelEnabled, IsSchemaAdvisorEnabled: projectSettings.IsSchemaAdvisorEnabled, }, - CustomRoles: []atlasV1.CustomRole{ + CustomRoles: []akov2.CustomRole{ { Name: customRoles[0].RoleName, - InheritedRoles: []atlasV1.Role{ + InheritedRoles: []akov2.Role{ { Name: customRoles[0].InheritedRoles[0].Role, Database: customRoles[0].InheritedRoles[0].Db, }, }, - Actions: []atlasV1.Action{ + Actions: []akov2.Action{ { Name: customRoles[0].Actions[0].Action, - Resources: []atlasV1.Resource{ + Resources: []akov2.Resource{ { Cluster: &customRoles[0].Actions[0].Resources[0].Cluster, Database: &customRoles[0].Actions[0].Resources[0].Db, @@ -519,30 +547,25 @@ func TestBuildAtlasProject(t *testing.T) { }, }, }, - Teams: []atlasV1.Team{ + Teams: []akov2.Team{ { - TeamRef: common.ResourceRefNamespaced{ + TeamRef: akov2common.ResourceRefNamespaced{ Name: fmt.Sprintf("%s-team-%s", strings.ToLower(p.Name), strings.ToLower(teamsName)), Namespace: targetNamespace, }, - Roles: []atlasV1.TeamRole{atlasV1.TeamRole(projectTeams.Results[0].RoleNames[0])}, + Roles: []akov2.TeamRole{akov2.TeamRole(projectTeams.Results[0].RoleNames[0])}, }, }, }, - Status: status.AtlasProjectStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasProjectStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } - if !reflect.DeepEqual(expectedProject, gotProject) { - t.Fatalf("Project mismatch.\r\nexpected: %v\r\ngot: %v\r\n", expectedProject, gotProject) - } - - if !reflect.DeepEqual(expectedTeams, gotTeams) { - t.Fatalf("Teams mismatch.\r\nexpected: %v\r\ngot: %v\r\n", expectedTeams, gotTeams) - } + assert.Equal(t, expectedProject, gotProject) + assert.Equal(t, expectedTeams, gotTeams) }) } @@ -647,7 +670,7 @@ func Test_buildAccessLists(t *testing.T) { t.Errorf("%v", err) } - expected := []project.IPAccessList{ + expected := []akov2project.IPAccessList{ { AwsSecurityGroup: data.Results[0].GetAwsSecurityGroup(), CIDRBlock: data.Results[0].GetCidrBlock(), @@ -682,7 +705,7 @@ func Test_buildAuditing(t *testing.T) { t.Errorf("%v", err) } - expected := &atlasV1.Auditing{ + expected := &akov2.Auditing{ AuditAuthorizationSuccess: pointer.GetOrZero(data.AuditAuthorizationSuccess), AuditFilter: pointer.GetOrZero(data.AuditFilter), Enabled: pointer.GetOrZero(data.Enabled), @@ -708,7 +731,7 @@ func Test_buildCloudProviderAccessRoles(t *testing.T) { CreatedDate: &time.Time{}, FeatureUsages: nil, IamAssumedRoleArn: pointer.Get("TestAssumedRoleARN"), - ProviderName: string(provider.ProviderAWS), + ProviderName: string(akov2provider.ProviderAWS), RoleId: pointer.Get("TestRoleID"), }, }, @@ -721,7 +744,7 @@ func Test_buildCloudProviderAccessRoles(t *testing.T) { t.Errorf("%v", err) } - expected := []atlasV1.CloudProviderAccessRole{ + expected := []akov2.CloudProviderAccessRole{ { ProviderName: data.AwsIamRoles[0].ProviderName, IamAssumedRoleArn: *data.AwsIamRoles[0].IamAssumedRoleArn, @@ -738,6 +761,8 @@ func Test_buildEncryptionAtREST(t *testing.T) { ctl := gomock.NewController(t) dataProvider := mocks.NewMockEncryptionAtRestDescriber(ctl) + dictionary := resources.AtlasNameToKubernetesName() + testProjectName := "test-project" t.Run("Can convert Encryption at REST AWS", func(t *testing.T) { data := &atlasv2.EncryptionAtRest{ AwsKms: &atlasv2.AWSKMSConfiguration{ @@ -755,27 +780,36 @@ func Test_buildEncryptionAtREST(t *testing.T) { dataProvider.EXPECT().EncryptionAtRest(projectID).Return(data, nil) - got, err := buildEncryptionAtRest(dataProvider, projectID) + got, _, err := buildEncryptionAtRest(dataProvider, projectID, testProjectName, targetNamespace, dictionary) if err != nil { t.Errorf("%v", err) } - expected := &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{ - Enabled: data.AwsKms.Enabled, - AccessKeyID: data.AwsKms.GetAccessKeyID(), - SecretAccessKey: data.AwsKms.GetSecretAccessKey(), - CustomerMasterKeyID: data.AwsKms.GetCustomerMasterKeyID(), - Region: data.AwsKms.GetRegion(), - RoleID: data.AwsKms.GetRoleId(), - Valid: data.AwsKms.Valid, + expected := &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + Enabled: data.AwsKms.Enabled, + Region: data.AwsKms.GetRegion(), + Valid: data.AwsKms.Valid, + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AwsKms.SecretRef.Name, + Namespace: got.AwsKms.SecretRef.Namespace, + }, + }, + AzureKeyVault: akov2.AzureKeyVault{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AzureKeyVault.SecretRef.Name, + Namespace: got.AzureKeyVault.SecretRef.Namespace, + }, + }, + GoogleCloudKms: akov2.GoogleCloudKms{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.GoogleCloudKms.SecretRef.Name, + Namespace: got.GoogleCloudKms.SecretRef.Namespace, + }, }, - AzureKeyVault: atlasV1.AzureKeyVault{}, - GoogleCloudKms: atlasV1.GoogleCloudKms{}, } - - if !reflect.DeepEqual(expected, got) { - t.Fatalf("EncryptionAtREST mismatch.\r\nexpected: %v\r\ngot: %v\r\n", expected, got) + if diff := deep.Equal(expected, got); diff != nil { + t.Fatalf("EncryptionAtREST mismatch: %v", diff) } }) t.Run("Can convert Encryption at REST GCP", func(t *testing.T) { @@ -790,23 +824,35 @@ func Test_buildEncryptionAtREST(t *testing.T) { } dataProvider.EXPECT().EncryptionAtRest(projectID).Return(data, nil) - got, err := buildEncryptionAtRest(dataProvider, projectID) + got, _, err := buildEncryptionAtRest(dataProvider, projectID, testProjectName, targetNamespace, dictionary) if err != nil { t.Errorf("%v", err) } - expected := &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{}, - AzureKeyVault: atlasV1.AzureKeyVault{}, - GoogleCloudKms: atlasV1.GoogleCloudKms{ - Enabled: data.GoogleCloudKms.Enabled, - ServiceAccountKey: data.GoogleCloudKms.GetServiceAccountKey(), - KeyVersionResourceID: data.GoogleCloudKms.GetKeyVersionResourceID(), + expected := &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AwsKms.SecretRef.Name, + Namespace: got.AwsKms.SecretRef.Namespace, + }, + }, + AzureKeyVault: akov2.AzureKeyVault{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AzureKeyVault.SecretRef.Name, + Namespace: got.AzureKeyVault.SecretRef.Namespace, + }, + }, + GoogleCloudKms: akov2.GoogleCloudKms{ + Enabled: data.GoogleCloudKms.Enabled, + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.GoogleCloudKms.SecretRef.Name, + Namespace: got.GoogleCloudKms.SecretRef.Namespace, + }, }, } - if !reflect.DeepEqual(expected, got) { - t.Fatalf("EncryptionAtREST mismatch.\r\nexpected: %v\r\ngot: %v\r\n", expected, got) + if diff := deep.Equal(expected, got); diff != nil { + t.Fatalf("EncryptionAtREST mismatch: %v", diff) } }) t.Run("Can convert Encryption at REST Azure", func(t *testing.T) { @@ -827,29 +873,39 @@ func Test_buildEncryptionAtREST(t *testing.T) { } dataProvider.EXPECT().EncryptionAtRest(projectID).Return(&data, nil) - got, err := buildEncryptionAtRest(dataProvider, projectID) + got, _, err := buildEncryptionAtRest(dataProvider, projectID, testProjectName, targetNamespace, dictionary) if err != nil { t.Errorf("%v", err) } - expected := &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{}, - AzureKeyVault: atlasV1.AzureKeyVault{ + expected := &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AwsKms.SecretRef.Name, + Namespace: got.AwsKms.SecretRef.Namespace, + }, + }, + AzureKeyVault: akov2.AzureKeyVault{ Enabled: data.AzureKeyVault.Enabled, ClientID: data.AzureKeyVault.GetClientID(), AzureEnvironment: data.AzureKeyVault.GetAzureEnvironment(), - SubscriptionID: data.AzureKeyVault.GetSubscriptionID(), ResourceGroupName: data.AzureKeyVault.GetResourceGroupName(), - KeyVaultName: data.AzureKeyVault.GetKeyVaultName(), - KeyIdentifier: data.AzureKeyVault.GetKeyIdentifier(), - Secret: data.AzureKeyVault.GetSecret(), TenantID: data.AzureKeyVault.GetTenantID(), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.AzureKeyVault.SecretRef.Name, + Namespace: got.AzureKeyVault.SecretRef.Namespace, + }, + }, + GoogleCloudKms: akov2.GoogleCloudKms{ + SecretRef: akov2common.ResourceRefNamespaced{ + Name: got.GoogleCloudKms.SecretRef.Name, + Namespace: got.GoogleCloudKms.SecretRef.Namespace, + }, }, - GoogleCloudKms: atlasV1.GoogleCloudKms{}, } - if !reflect.DeepEqual(expected, got) { - t.Fatalf("EncryptionAtREST mismatch.\r\nexpected: %v\r\ngot: %v\r\n", expected, got) + if diff := deep.Equal(expected, got); diff != nil { + t.Fatalf("EncryptionAtREST mismatch: %v", diff) } }) } @@ -883,12 +939,12 @@ func Test_buildIntegrations(t *testing.T) { t.Fatalf("%v", err) } - expected := []project.Integration{ + expected := []akov2project.Integration{ { Type: ints.Results[0].GetType(), ServiceDiscovery: ints.Results[0].GetServiceDiscovery(), UserName: ints.Results[0].GetUsername(), - PasswordRef: common.ResourceRefNamespaced{ + PasswordRef: akov2common.ResourceRefNamespaced{ Name: fmt.Sprintf("%s-integration-%s", strings.ToLower(projectID), strings.ToLower(ints.Results[0].GetType())), @@ -948,12 +1004,12 @@ func Test_buildIntegrations(t *testing.T) { t.Fatalf("%v", err) } - expected := []project.Integration{ + expected := []akov2project.Integration{ { Type: ints.Results[0].GetType(), ServiceDiscovery: ints.Results[0].GetServiceDiscovery(), UserName: ints.Results[0].GetUsername(), - PasswordRef: common.ResourceRefNamespaced{ + PasswordRef: akov2common.ResourceRefNamespaced{ Name: fmt.Sprintf("%s-integration-%s", strings.ToLower(projectID), strings.ToLower(ints.Results[0].GetType())), @@ -1012,7 +1068,7 @@ func Test_buildMaintenanceWindows(t *testing.T) { t.Fatalf("%v", err) } - expected := project.MaintenanceWindow{ + expected := akov2project.MaintenanceWindow{ DayOfWeek: mw.DayOfWeek, HourOfDay: mw.HourOfDay, AutoDefer: *mw.AutoDeferOnceEnabled, @@ -1038,7 +1094,7 @@ func Test_buildNetworkPeering(t *testing.T) { ContainerId: "TestContainerID", ErrorStateName: pointer.Get("TestErrStateName"), Id: pointer.Get("TestID"), - ProviderName: pointer.Get(string(provider.ProviderAWS)), + ProviderName: pointer.Get(string(akov2provider.ProviderAWS)), RouteTableCidrBlock: pointer.Get("0.0.0.0/0"), StatusName: pointer.Get("TestStatusName"), VpcId: pointer.Get("TestVPCID"), @@ -1049,9 +1105,9 @@ func Test_buildNetworkPeering(t *testing.T) { } listOptions := atlas.ListOptions{ItemsPerPage: MaxItems} - containerListOptionAWS := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(provider.ProviderAWS)} - containerListOptionGCP := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(provider.ProviderGCP)} - containerListOptionAzure := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(provider.ProviderAzure)} + containerListOptionAWS := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(akov2provider.ProviderAWS)} + containerListOptionGCP := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(akov2provider.ProviderGCP)} + containerListOptionAzure := &atlas.ContainersListOptions{ListOptions: listOptions, ProviderName: string(akov2provider.ProviderAzure)} peerProvider.EXPECT().PeeringConnections(projectID, containerListOptionAWS).Return(peeringConnections, nil) peerProvider.EXPECT().PeeringConnections(projectID, containerListOptionGCP).Return(nil, nil) @@ -1062,13 +1118,13 @@ func Test_buildNetworkPeering(t *testing.T) { t.Fatalf("%v", err) } - expected := []atlasV1.NetworkPeer{ + expected := []akov2.NetworkPeer{ { AccepterRegionName: peeringConnectionAWS.GetAccepterRegionName(), ContainerRegion: "", AWSAccountID: peeringConnectionAWS.GetAwsAccountId(), ContainerID: peeringConnectionAWS.ContainerId, - ProviderName: provider.ProviderName(*peeringConnectionAWS.ProviderName), + ProviderName: akov2provider.ProviderName(*peeringConnectionAWS.ProviderName), RouteTableCIDRBlock: peeringConnectionAWS.GetRouteTableCidrBlock(), VpcID: peeringConnectionAWS.GetVpcId(), }, @@ -1085,7 +1141,7 @@ func Test_buildPrivateEndpoints(t *testing.T) { peProvider := mocks.NewMockPrivateEndpointLister(ctl) t.Run("Can convert PrivateEndpointConnection for AWS", func(t *testing.T) { - providerName := provider.ProviderAWS + providerName := akov2provider.ProviderAWS privateEndpoint := atlasv2.EndpointService{ Id: pointer.Get("1"), CloudProvider: string(providerName), @@ -1097,15 +1153,15 @@ func Test_buildPrivateEndpoints(t *testing.T) { } peProvider.EXPECT().PrivateEndpoints(projectID, string(providerName)).Return([]atlasv2.EndpointService{privateEndpoint}, nil) - peProvider.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderAzure)).Return(nil, nil) - peProvider.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderGCP)).Return(nil, nil) + peProvider.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderAzure)).Return(nil, nil) + peProvider.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderGCP)).Return(nil, nil) got, err := buildPrivateEndpoints(peProvider, projectID) if err != nil { t.Fatalf("%v", err) } - expected := []atlasV1.PrivateEndpoint{ + expected := []akov2.PrivateEndpoint{ { Provider: providerName, Region: *privateEndpoint.RegionName, @@ -1113,7 +1169,7 @@ func Test_buildPrivateEndpoints(t *testing.T) { IP: "", GCPProjectID: "", EndpointGroupName: "", - Endpoints: atlasV1.GCPEndpoints{}, + Endpoints: akov2.GCPEndpoints{}, }, } @@ -1123,7 +1179,7 @@ func Test_buildPrivateEndpoints(t *testing.T) { }) t.Run("Can convert PrivateEndpointConnection for Azure", func(t *testing.T) { - providerName := provider.ProviderAzure + providerName := akov2provider.ProviderAzure privateEndpoint := atlasv2.EndpointService{ Id: pointer.Get("1"), CloudProvider: string(providerName), @@ -1136,15 +1192,15 @@ func Test_buildPrivateEndpoints(t *testing.T) { } peProvider.EXPECT().PrivateEndpoints(projectID, string(providerName)).Return([]atlasv2.EndpointService{privateEndpoint}, nil) - peProvider.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderAWS)).Return(nil, nil) - peProvider.EXPECT().PrivateEndpoints(projectID, string(provider.ProviderGCP)).Return(nil, nil) + peProvider.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderAWS)).Return(nil, nil) + peProvider.EXPECT().PrivateEndpoints(projectID, string(akov2provider.ProviderGCP)).Return(nil, nil) got, err := buildPrivateEndpoints(peProvider, projectID) if err != nil { t.Fatalf("%v", err) } - expected := []atlasV1.PrivateEndpoint{ + expected := []akov2.PrivateEndpoint{ { Provider: providerName, Region: *privateEndpoint.RegionName, @@ -1152,7 +1208,7 @@ func Test_buildPrivateEndpoints(t *testing.T) { IP: "", GCPProjectID: "", EndpointGroupName: "", - Endpoints: atlasV1.GCPEndpoints{}, + Endpoints: akov2.GCPEndpoints{}, }, } @@ -1180,7 +1236,7 @@ func Test_buildProjectSettings(t *testing.T) { if err != nil { t.Fatalf("%v", err) } - expected := &atlasV1.ProjectSettings{ + expected := &akov2.ProjectSettings{ IsCollectDatabaseSpecificsStatisticsEnabled: projectSettings.IsCollectDatabaseSpecificsStatisticsEnabled, IsDataExplorerEnabled: projectSettings.IsDataExplorerEnabled, IsPerformanceAdvisorEnabled: projectSettings.IsPerformanceAdvisorEnabled, @@ -1225,19 +1281,19 @@ func Test_buildCustomRoles(t *testing.T) { rolesProvider.EXPECT().DatabaseRoles(projectID).Return(data, nil) role := data[0] - expected := []atlasV1.CustomRole{ + expected := []akov2.CustomRole{ { Name: role.RoleName, - InheritedRoles: []atlasV1.Role{ + InheritedRoles: []akov2.Role{ { Name: role.InheritedRoles[0].Role, Database: role.InheritedRoles[0].Db, }, }, - Actions: []atlasV1.Action{ + Actions: []akov2.Action{ { Name: role.Actions[0].Action, - Resources: []atlasV1.Resource{ + Resources: []akov2.Resource{ { Cluster: &role.Actions[0].Resources[0].Cluster, Database: &role.Actions[0].Resources[0].Db, diff --git a/internal/kubernetes/operator/secrets/secrets.go b/internal/kubernetes/operator/secrets/secrets.go index f63ff53eaf..380b3250ef 100644 --- a/internal/kubernetes/operator/secrets/secrets.go +++ b/internal/kubernetes/operator/secrets/secrets.go @@ -21,27 +21,69 @@ import ( ) const ( - TypeLabelKey = "atlas.mongodb.com/type" - CredLabelVal = "credentials" - PasswordField = "password" - CredPrivateAPIKey = "privateApiKey" - CredPublicAPIKey = "publicApiKey" - CredOrgID = "orgId" + TypeLabelKey = "atlas.mongodb.com/type" + ProjectIDLabelKey = "atlas.mongodb.com/project-id" + ProjectNameLabelKey = "atlas.mongodb.com/project-name" + NotifierIDLabelKey = "atlas.mongodb.com/notifier-id" + NotifierNameLabelKey = "atlas.mongodb.com/notifier-type-name" + CredLabelVal = "credentials" + PasswordField = "password" + CredPrivateAPIKey = "privateApiKey" + CredPublicAPIKey = "publicApiKey" + CredOrgID = "orgId" ) -func NewAtlasSecret(name, namespace string, data map[string][]byte, dictionary map[string]string) *corev1.Secret { - return &corev1.Secret{ - TypeMeta: v1.TypeMeta{ - Kind: "Secret", - APIVersion: "v1", - }, - ObjectMeta: v1.ObjectMeta{ - Name: resources.NormalizeAtlasName(name, dictionary), - Namespace: namespace, - Labels: map[string]string{ - TypeLabelKey: CredLabelVal, +type AtlasSecretBuilder func() (*corev1.Secret, map[string]string) + +func NewAtlasSecretBuilder(name, namespace string, dictionary map[string]string) AtlasSecretBuilder { + return AtlasSecretBuilder(func() (*corev1.Secret, map[string]string) { + secret := &corev1.Secret{ + TypeMeta: v1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: v1.ObjectMeta{ + Name: resources.NormalizeAtlasName(name, dictionary), + Namespace: namespace, + Labels: map[string]string{ + TypeLabelKey: CredLabelVal, + }, }, - }, - Data: data, - } + } + return secret, dictionary + }) +} + +func (a AtlasSecretBuilder) WithData(data map[string][]byte) AtlasSecretBuilder { + return AtlasSecretBuilder(func() (*corev1.Secret, map[string]string) { + s, d := a() + s.Data = data + return s, d + }) +} + +func (a AtlasSecretBuilder) WithProjectLabels(id, name string) AtlasSecretBuilder { + return AtlasSecretBuilder(func() (*corev1.Secret, map[string]string) { + s, d := a() + s.Labels[ProjectIDLabelKey] = resources.NormalizeAtlasName(id, d) + s.Labels[ProjectNameLabelKey] = resources.NormalizeAtlasName(name, d) + return s, d + }) +} + +func (a AtlasSecretBuilder) WithNotifierLabels(id *string, typeName string) AtlasSecretBuilder { + return AtlasSecretBuilder(func() (*corev1.Secret, map[string]string) { + s, d := a() + if id == nil { + return s, d + } + s.Labels[NotifierIDLabelKey] = resources.NormalizeAtlasName(*id, d) + s.Labels[NotifierNameLabelKey] = typeName // don't normalize type name, as it is already a short form + return s, d + }) +} + +func (a AtlasSecretBuilder) Build() *corev1.Secret { + secret, _ := a() + return secret } diff --git a/test/e2e/atlas/kubernetes_config_apply_test.go b/test/e2e/atlas/kubernetes_config_apply_test.go index d7534c5219..2ae74e04c5 100644 --- a/test/e2e/atlas/kubernetes_config_apply_test.go +++ b/test/e2e/atlas/kubernetes_config_apply_test.go @@ -24,11 +24,13 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/resources" "github.com/mongodb/mongodb-atlas-cli/test/e2e" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + apisv1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -67,10 +69,22 @@ func TestKubernetesConfigApply(t *testing.T) { operator.restoreOperator() }) + e2eNamespace := &corev1.Namespace{ + ObjectMeta: apisv1.ObjectMeta{ + Name: "e2e-autodetect-parameters", + }, + } + t.Logf("adding namespace %s", e2eNamespace) + require.NoError(t, operator.createK8sObject(e2eNamespace)) + g.t.Cleanup(func() { + req.NoError(operator.deleteK8sObject(e2eNamespace)) + }) + cmd := exec.Command(cliPath, "kubernetes", "config", "apply", + "--targetNamespace", "e2e-autodetect-parameters", "--projectId", g.projectID) cmd.Env = os.Environ() resp, err := cmd.CombinedOutput() @@ -89,10 +103,22 @@ func TestKubernetesConfigApply(t *testing.T) { operator.restoreOperatorImage() }) + e2eNamespace := &corev1.Namespace{ + ObjectMeta: apisv1.ObjectMeta{ + Name: "e2e-autodetect-operator-version", + }, + } + t.Logf("adding namespace %s", e2eNamespace) + require.NoError(t, operator.createK8sObject(e2eNamespace)) + g.t.Cleanup(func() { + req.NoError(operator.deleteK8sObject(e2eNamespace)) + }) + cmd := exec.Command(cliPath, "kubernetes", "config", "apply", + "--targetNamespace", "e2e-autodetect-operator-version", "--projectId", g.projectID) cmd.Env = os.Environ() resp, err := cmd.CombinedOutput() @@ -111,10 +137,22 @@ func TestKubernetesConfigApply(t *testing.T) { operator.startOperator() }) + e2eNamespace := &corev1.Namespace{ + ObjectMeta: apisv1.ObjectMeta{ + Name: "e2e-export-atlas-resource", + }, + } + t.Logf("adding namespace %s", e2eNamespace) + require.NoError(t, operator.createK8sObject(e2eNamespace)) + g.t.Cleanup(func() { + req.NoError(operator.deleteK8sObject(e2eNamespace)) + }) + cmd := exec.Command(cliPath, "kubernetes", "config", "apply", + "--targetNamespace", "e2e-export-atlas-resource", "--projectId", g.projectID) cmd.Env = os.Environ() resp, err := cmd.CombinedOutput() @@ -124,32 +162,31 @@ func TestKubernetesConfigApply(t *testing.T) { operator.cleanUpResources() }) - namespace := "mongodb-atlas-system" - akoProject := akov1.AtlasProject{} + akoProject := akov2.AtlasProject{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(g.projectName), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(g.projectName), Namespace: e2eNamespace.Name}, &akoProject, true, ) req.NoError(err) a.NotEmpty(akoProject.Spec.AlertConfigurations) akoProject.Spec.AlertConfigurations = nil - a.Equal(referenceExportedProject(g.projectName, g.teamName).Spec, akoProject.Spec) + a.Equal(referenceExportedProject(g.projectName, g.teamName, &akoProject).Spec, akoProject.Spec) // Assert Database User - akoDBUser := akov1.AtlasDatabaseUser{} + akoDBUser := akov2.AtlasDatabaseUser{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s", g.projectName, g.dbUser)), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s", g.projectName, g.dbUser)), Namespace: e2eNamespace.Name}, &akoDBUser, true, ) req.NoError(err) - a.Equal(referenceExportedDBUser(g.projectName, g.dbUser).Spec, akoDBUser.Spec) + a.Equal(referenceExportedDBUser(g.projectName, g.dbUser, e2eNamespace.Name).Spec, akoDBUser.Spec) // Assert Team - akoTeam := akov1.AtlasTeam{} + akoTeam := akov2.AtlasTeam{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-team-%s", g.projectName, g.teamName)), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-team-%s", g.projectName, g.teamName)), Namespace: e2eNamespace.Name}, &akoTeam, true, ) @@ -157,9 +194,9 @@ func TestKubernetesConfigApply(t *testing.T) { a.Equal(referenceExportedTeam(g.teamName, g.teamUser).Spec, akoTeam.Spec) // Assert Backup Policy - akoBkpPolicy := akov1.AtlasBackupPolicy{} + akoBkpPolicy := akov2.AtlasBackupPolicy{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s-backuppolicy", g.projectName, g.clusterName)), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s-backuppolicy", g.projectName, g.clusterName)), Namespace: e2eNamespace.Name}, &akoBkpPolicy, true, ) @@ -167,35 +204,34 @@ func TestKubernetesConfigApply(t *testing.T) { a.Equal(referenceExportedBackupPolicy().Spec, akoBkpPolicy.Spec) // Assert Backup Schedule - akoBkpSchedule := akov1.AtlasBackupSchedule{} + akoBkpSchedule := akov2.AtlasBackupSchedule{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s-backupschedule", g.projectName, g.clusterName)), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s-backupschedule", g.projectName, g.clusterName)), Namespace: e2eNamespace.Name}, &akoBkpSchedule, true, ) req.NoError(err) a.Equal( - referenceExportedBackupSchedule(g.projectName, g.clusterName, akoBkpSchedule.Spec.ReferenceHourOfDay, akoBkpSchedule.Spec.ReferenceMinuteOfHour).Spec, + referenceExportedBackupSchedule(g.projectName, g.clusterName, e2eNamespace.Name, akoBkpSchedule.Spec.ReferenceHourOfDay, akoBkpSchedule.Spec.ReferenceMinuteOfHour).Spec, akoBkpSchedule.Spec, ) // Assert Deployment - akoDeployment := akov1.AtlasDeployment{} + akoDeployment := akov2.AtlasDeployment{} err = operator.getK8sObject( - client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s", g.projectName, g.clusterName)), Namespace: namespace}, + client.ObjectKey{Name: prepareK8sName(fmt.Sprintf("%s-%s", g.projectName, g.clusterName)), Namespace: e2eNamespace.Name}, &akoDeployment, true, ) req.NoError(err) - a.Equal(referenceExportedDeployment(g.projectName, g.clusterName).Spec, akoDeployment.Spec) + a.Equal(referenceExportedDeployment(g.projectName, g.clusterName, e2eNamespace.Name).Spec, akoDeployment.Spec) }) } func setupAtlasResources(t *testing.T) *atlasE2ETestGenerator { t.Helper() - g := newAtlasE2ETestGenerator(t) - g.enableBackup = true + g := newAtlasE2ETestGeneratorWithBackup(t) g.generateProject("k8sConfigApply") g.generateCluster() g.generateTeam("k8sConfigApply") @@ -224,44 +260,56 @@ func setupAtlasResources(t *testing.T) *atlasE2ETestGenerator { return g } -func referenceExportedProject(projectName, teamName string) *akov1.AtlasProject { - return &akov1.AtlasProject{ - Spec: akov1.AtlasProjectSpec{ +func referenceExportedProject(projectName, teamName string, expectedProject *akov2.AtlasProject) *akov2.AtlasProject { + return &akov2.AtlasProject{ + Spec: akov2.AtlasProjectSpec{ Name: projectName, - ConnectionSecret: &common.ResourceRefNamespaced{ + ConnectionSecret: &akov2common.ResourceRefNamespaced{ Name: prepareK8sName(fmt.Sprintf("%s-credentials", projectName)), }, WithDefaultAlertsSettings: true, - Settings: &akov1.ProjectSettings{ - IsCollectDatabaseSpecificsStatisticsEnabled: toptr.MakePtr(true), - IsDataExplorerEnabled: toptr.MakePtr(true), - IsPerformanceAdvisorEnabled: toptr.MakePtr(true), - IsRealtimePerformancePanelEnabled: toptr.MakePtr(true), - IsSchemaAdvisorEnabled: toptr.MakePtr(true), + Settings: &akov2.ProjectSettings{ + IsCollectDatabaseSpecificsStatisticsEnabled: akov2toptr.MakePtr(true), + IsDataExplorerEnabled: akov2toptr.MakePtr(true), + IsPerformanceAdvisorEnabled: akov2toptr.MakePtr(true), + IsRealtimePerformancePanelEnabled: akov2toptr.MakePtr(true), + IsSchemaAdvisorEnabled: akov2toptr.MakePtr(true), }, - EncryptionAtRest: &akov1.EncryptionAtRest{ - AwsKms: akov1.AwsKms{ - Enabled: toptr.MakePtr(false), - Valid: toptr.MakePtr(false), + EncryptionAtRest: &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ + Enabled: akov2toptr.MakePtr(false), + Valid: akov2toptr.MakePtr(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: expectedProject.Spec.EncryptionAtRest.AwsKms.SecretRef.Name, + Namespace: expectedProject.Spec.EncryptionAtRest.AwsKms.SecretRef.Namespace, + }, }, - AzureKeyVault: akov1.AzureKeyVault{ - Enabled: toptr.MakePtr(false), + AzureKeyVault: akov2.AzureKeyVault{ + Enabled: akov2toptr.MakePtr(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: expectedProject.Spec.EncryptionAtRest.AzureKeyVault.SecretRef.Name, + Namespace: expectedProject.Spec.EncryptionAtRest.AzureKeyVault.SecretRef.Namespace, + }, }, - GoogleCloudKms: akov1.GoogleCloudKms{ - Enabled: toptr.MakePtr(false), + GoogleCloudKms: akov2.GoogleCloudKms{ + Enabled: akov2toptr.MakePtr(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: expectedProject.Spec.EncryptionAtRest.GoogleCloudKms.SecretRef.Name, + Namespace: expectedProject.Spec.EncryptionAtRest.GoogleCloudKms.SecretRef.Namespace, + }, }, }, - Auditing: &akov1.Auditing{ + Auditing: &akov2.Auditing{ AuditAuthorizationSuccess: false, Enabled: false, }, - Teams: []akov1.Team{ + Teams: []akov2.Team{ { - TeamRef: common.ResourceRefNamespaced{ - Namespace: "mongodb-atlas-system", + TeamRef: akov2common.ResourceRefNamespaced{ + Namespace: expectedProject.Namespace, Name: prepareK8sName(fmt.Sprintf("%s-team-%s", projectName, teamName)), }, - Roles: []akov1.TeamRole{ + Roles: []akov2.TeamRole{ "GROUP_OWNER", }, }, @@ -271,14 +319,14 @@ func referenceExportedProject(projectName, teamName string) *akov1.AtlasProject } } -func referenceExportedDBUser(projectName, dbUser string) *akov1.AtlasDatabaseUser { - return &akov1.AtlasDatabaseUser{ - Spec: akov1.AtlasDatabaseUserSpec{ - Project: common.ResourceRefNamespaced{ +func referenceExportedDBUser(projectName, dbUser, namespace string) *akov2.AtlasDatabaseUser { + return &akov2.AtlasDatabaseUser{ + Spec: akov2.AtlasDatabaseUserSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: prepareK8sName(projectName), - Namespace: "mongodb-atlas-system", + Namespace: namespace, }, - Roles: []akov1.RoleSpec{ + Roles: []akov2.RoleSpec{ { RoleName: "readAnyDatabase", DatabaseName: "admin", @@ -291,23 +339,23 @@ func referenceExportedDBUser(projectName, dbUser string) *akov1.AtlasDatabaseUse } } -func referenceExportedTeam(teamName, username string) *akov1.AtlasTeam { - return &akov1.AtlasTeam{ - Spec: akov1.TeamSpec{ +func referenceExportedTeam(teamName, username string) *akov2.AtlasTeam { + return &akov2.AtlasTeam{ + Spec: akov2.TeamSpec{ Name: teamName, - Usernames: []akov1.TeamUser{ - akov1.TeamUser(username), + Usernames: []akov2.TeamUser{ + akov2.TeamUser(username), }, }, } } -func referenceExportedBackupSchedule(projectName, clusterName string, refHour, refMin int64) *akov1.AtlasBackupSchedule { - return &akov1.AtlasBackupSchedule{ - Spec: akov1.AtlasBackupScheduleSpec{ - PolicyRef: common.ResourceRefNamespaced{ +func referenceExportedBackupSchedule(projectName, clusterName, namespace string, refHour, refMin int64) *akov2.AtlasBackupSchedule { + return &akov2.AtlasBackupSchedule{ + Spec: akov2.AtlasBackupScheduleSpec{ + PolicyRef: akov2common.ResourceRefNamespaced{ Name: prepareK8sName(fmt.Sprintf("%s-%s-backuppolicy", projectName, clusterName)), - Namespace: "mongodb-atlas-system", + Namespace: namespace, }, AutoExportEnabled: false, ReferenceHourOfDay: refHour, @@ -317,10 +365,10 @@ func referenceExportedBackupSchedule(projectName, clusterName string, refHour, r } } -func referenceExportedBackupPolicy() *akov1.AtlasBackupPolicy { - return &akov1.AtlasBackupPolicy{ - Spec: akov1.AtlasBackupPolicySpec{ - Items: []akov1.AtlasBackupPolicyItem{ +func referenceExportedBackupPolicy() *akov2.AtlasBackupPolicy { + return &akov2.AtlasBackupPolicy{ + Spec: akov2.AtlasBackupPolicySpec{ + Items: []akov2.AtlasBackupPolicyItem{ { FrequencyType: "hourly", FrequencyInterval: 6, @@ -350,68 +398,68 @@ func referenceExportedBackupPolicy() *akov1.AtlasBackupPolicy { } } -func referenceExportedDeployment(projectName, clusterName string) *akov1.AtlasDeployment { - return &akov1.AtlasDeployment{ - Spec: akov1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ +func referenceExportedDeployment(projectName, clusterName, namespace string) *akov2.AtlasDeployment { + return &akov2.AtlasDeployment{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: prepareK8sName(projectName), - Namespace: "mongodb-atlas-system", + Namespace: namespace, }, - BackupScheduleRef: common.ResourceRefNamespaced{ + BackupScheduleRef: akov2common.ResourceRefNamespaced{ Name: prepareK8sName(fmt.Sprintf("%s-%s-backupschedule", projectName, clusterName)), - Namespace: "mongodb-atlas-system", + Namespace: namespace, }, - AdvancedDeploymentSpec: &akov1.AdvancedDeploymentSpec{ + DeploymentSpec: &akov2.AdvancedDeploymentSpec{ Name: clusterName, - BackupEnabled: toptr.MakePtr(true), - BiConnector: &akov1.BiConnectorSpec{ - Enabled: toptr.MakePtr(false), + BackupEnabled: akov2toptr.MakePtr(true), + BiConnector: &akov2.BiConnectorSpec{ + Enabled: akov2toptr.MakePtr(false), ReadPreference: "secondary", }, ClusterType: "REPLICASET", EncryptionAtRestProvider: "NONE", - Labels: []common.LabelSpec{ + Labels: []akov2common.LabelSpec{ { Key: "Infrastructure Tool", Value: "Atlas CLI", }, }, - Paused: toptr.MakePtr(false), - PitEnabled: toptr.MakePtr(true), - ReplicationSpecs: []*akov1.AdvancedReplicationSpec{ + Paused: akov2toptr.MakePtr(false), + PitEnabled: akov2toptr.MakePtr(true), + ReplicationSpecs: []*akov2.AdvancedReplicationSpec{ { NumShards: 1, ZoneName: "Zone 1", - RegionConfigs: []*akov1.AdvancedRegionConfig{ + RegionConfigs: []*akov2.AdvancedRegionConfig{ { - AnalyticsSpecs: &akov1.Specs{ - DiskIOPS: toptr.MakePtr(int64(3000)), + AnalyticsSpecs: &akov2.Specs{ + DiskIOPS: akov2toptr.MakePtr(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: "M10", - NodeCount: toptr.MakePtr(0), + NodeCount: akov2toptr.MakePtr(0), }, - ElectableSpecs: &akov1.Specs{ - DiskIOPS: toptr.MakePtr(int64(3000)), + ElectableSpecs: &akov2.Specs{ + DiskIOPS: akov2toptr.MakePtr(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: "M10", - NodeCount: toptr.MakePtr(3), + NodeCount: akov2toptr.MakePtr(3), }, - ReadOnlySpecs: &akov1.Specs{ - DiskIOPS: toptr.MakePtr(int64(3000)), + ReadOnlySpecs: &akov2.Specs{ + DiskIOPS: akov2toptr.MakePtr(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: "M10", - NodeCount: toptr.MakePtr(0), + NodeCount: akov2toptr.MakePtr(0), }, - AutoScaling: &akov1.AdvancedAutoScalingSpec{ - DiskGB: &akov1.DiskGB{ - Enabled: toptr.MakePtr(false), + AutoScaling: &akov2.AdvancedAutoScalingSpec{ + DiskGB: &akov2.DiskGB{ + Enabled: akov2toptr.MakePtr(false), }, - Compute: &akov1.ComputeSpec{ - Enabled: toptr.MakePtr(false), - ScaleDownEnabled: toptr.MakePtr(false), + Compute: &akov2.ComputeSpec{ + Enabled: akov2toptr.MakePtr(false), + ScaleDownEnabled: akov2toptr.MakePtr(false), }, }, - Priority: toptr.MakePtr(7), + Priority: akov2toptr.MakePtr(7), ProviderName: "AWS", RegionName: "US_EAST_1", }, @@ -421,10 +469,10 @@ func referenceExportedDeployment(projectName, clusterName string) *akov1.AtlasDe RootCertType: "ISRGROOTX1", VersionReleaseSystem: "LTS", }, - ProcessArgs: &akov1.ProcessArgs{ + ProcessArgs: &akov2.ProcessArgs{ MinimumEnabledTLSProtocol: "TLS1_2", - JavascriptEnabled: toptr.MakePtr(true), - NoTableScan: toptr.MakePtr(false), + JavascriptEnabled: akov2toptr.MakePtr(true), + NoTableScan: akov2toptr.MakePtr(false), }, }, } diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 085d264d95..200b7c11e5 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -33,11 +33,11 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/internal/search" "github.com/mongodb/mongodb-atlas-cli/test/e2e" - atlasV1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/project" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2common "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common" + akov2project "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/project" + akov2provider "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" + akov2status "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" @@ -86,7 +86,7 @@ type KubernetesConfigGenerateProjectSuite struct { t *testing.T assertions *assert.Assertions generator *atlasE2ETestGenerator - expectedProject *atlasV1.AtlasProject + expectedProject *akov2.AtlasProject cliPath string } @@ -107,7 +107,7 @@ func InitialSetupWithTeam(t *testing.T) KubernetesConfigGenerateProjectSuite { s.assertions = assert.New(t) // always register atlas entities - require.NoError(t, atlasV1.AddToScheme(scheme.Scheme)) + require.NoError(t, akov2.AddToScheme(scheme.Scheme)) return s } @@ -127,7 +127,7 @@ func InitialSetup(t *testing.T) KubernetesConfigGenerateProjectSuite { s.assertions = assert.New(t) // always register atlas entities - require.NoError(t, atlasV1.AddToScheme(scheme.Scheme)) + require.NoError(t, akov2.AddToScheme(scheme.Scheme)) return s } @@ -229,28 +229,49 @@ func TestProjectWithNonDefaultSettings(t *testing.T) { } func TestProjectWithNonDefaultAlertConf(t *testing.T) { + dictionary := resources.AtlasNameToKubernetesName() s := InitialSetup(t) cliPath := s.cliPath generator := s.generator expectedProject := s.expectedProject assertions := s.assertions - newAlertConfig := atlasV1.AlertConfiguration{ - Threshold: &atlasV1.Threshold{}, - MetricThreshold: &atlasV1.MetricThreshold{}, + newAlertConfig := akov2.AlertConfiguration{ + Threshold: &akov2.Threshold{}, + MetricThreshold: &akov2.MetricThreshold{}, EventTypeName: eventTypeName, Enabled: true, - Notifications: []atlasV1.Notification{ + Notifications: []akov2.Notification{ { TypeName: group, IntervalMin: intervalMin, DelayMin: pointer.Get(delayMin), SMSEnabled: pointer.Get(false), EmailEnabled: pointer.Get(true), + APITokenRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-api-token-0", expectedProject.Name), dictionary), + Namespace: targetNamespace, + }, + DatadogAPIKeyRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-datadog-api-key-0", expectedProject.Name), dictionary), + Namespace: targetNamespace, + }, + OpsGenieAPIKeyRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-ops-genie-api-key-0", expectedProject.Name), dictionary), + Namespace: targetNamespace, + }, + ServiceKeyRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-service-key-0", expectedProject.Name), dictionary), + Namespace: targetNamespace, + }, + VictorOpsSecretRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-victor-ops-credentials-0", expectedProject.Name), dictionary), + Namespace: targetNamespace, + }, }, }, } - expectedProject.Spec.AlertConfigurations = []atlasV1.AlertConfiguration{ + expectedProject.Spec.AlertConfigurations = []akov2.AlertConfiguration{ newAlertConfig, } @@ -311,11 +332,11 @@ func TestProjectWithAccessList(t *testing.T) { assertions := s.assertions entry := "192.168.0.10" - newIPAccess := project.IPAccessList{ + newIPAccess := akov2project.IPAccessList{ IPAddress: entry, Comment: "test", } - expectedProject.Spec.ProjectIPAccessList = []project.IPAccessList{ + expectedProject.Spec.ProjectIPAccessList = []akov2project.IPAccessList{ newIPAccess, } @@ -367,10 +388,10 @@ func TestProjectWithAccessRole(t *testing.T) { expectedProject := s.expectedProject assertions := s.assertions - newIPAccess := atlasV1.CloudProviderAccessRole{ - ProviderName: string(provider.ProviderAWS), + newIPAccess := akov2.CloudProviderAccessRole{ + ProviderName: string(akov2provider.ProviderAWS), } - expectedProject.Spec.CloudProviderAccessRoles = []atlasV1.CloudProviderAccessRole{ + expectedProject.Spec.CloudProviderAccessRoles = []akov2.CloudProviderAccessRole{ newIPAccess, } @@ -420,12 +441,12 @@ func TestProjectWithCustomRole(t *testing.T) { expectedProject := s.expectedProject assertions := s.assertions - newCustomRole := atlasV1.CustomRole{ + newCustomRole := akov2.CustomRole{ Name: "test-role", - Actions: []atlasV1.Action{ + Actions: []akov2.Action{ { Name: "FIND", - Resources: []atlasV1.Resource{ + Resources: []akov2.Resource{ { Database: pointer.Get("test-db "), Collection: pointer.Get(""), @@ -435,7 +456,7 @@ func TestProjectWithCustomRole(t *testing.T) { }, }, } - expectedProject.Spec.CustomRoles = []atlasV1.CustomRole{ + expectedProject.Spec.CustomRoles = []akov2.CustomRole{ newCustomRole, } @@ -487,15 +508,15 @@ func TestProjectWithIntegration(t *testing.T) { assertions := s.assertions datadogKey := "00000000000000000000000000000012" - newIntegration := project.Integration{ + newIntegration := akov2project.Integration{ Type: datadogEntity, Region: "US", // it's a default value - APIKeyRef: common.ResourceRefNamespaced{ + APIKeyRef: akov2common.ResourceRefNamespaced{ Namespace: targetNamespace, Name: fmt.Sprintf("%s-integration-%s", generator.projectID, strings.ToLower(datadogEntity)), }, } - expectedProject.Spec.Integrations = []project.Integration{ + expectedProject.Spec.Integrations = []akov2project.Integration{ newIntegration, } @@ -551,7 +572,7 @@ func TestProjectWithMaintenanceWindow(t *testing.T) { expectedProject := s.expectedProject assertions := s.assertions - newMaintenanceWindow := project.MaintenanceWindow{ + newMaintenanceWindow := akov2project.MaintenanceWindow{ DayOfWeek: 1, HourOfDay: 1, } @@ -607,12 +628,12 @@ func TestProjectWithNetworkPeering(t *testing.T) { assertions := s.assertions atlasCidrBlock := "10.8.0.0/18" - networkPeer := atlasV1.NetworkPeer{ - ProviderName: provider.ProviderGCP, + networkPeer := akov2.NetworkPeer{ + ProviderName: akov2provider.ProviderGCP, NetworkName: "test-network", GCPProjectID: "test-project-gcp", } - expectedProject.Spec.NetworkPeers = []atlasV1.NetworkPeer{ + expectedProject.Spec.NetworkPeers = []akov2.NetworkPeer{ networkPeer, } @@ -676,11 +697,11 @@ func TestProjectWithPrivateEndpoint_Azure(t *testing.T) { assertions := s.assertions const region = "northeurope" - newPrivateEndpoint := atlasV1.PrivateEndpoint{ - Provider: provider.ProviderAzure, + newPrivateEndpoint := akov2.PrivateEndpoint{ + Provider: akov2provider.ProviderAzure, Region: "EUROPE_NORTH", } - expectedProject.Spec.PrivateEndpoints = []atlasV1.PrivateEndpoint{ + expectedProject.Spec.PrivateEndpoints = []akov2.PrivateEndpoint{ newPrivateEndpoint, } @@ -751,18 +772,18 @@ func TestProjectAndTeams(t *testing.T) { teamRole := "GROUP_OWNER" t.Run("Add team to project", func(t *testing.T) { - expectedTeam := referenceTeam(generator.teamName, targetNamespace, []atlasV1.TeamUser{ - atlasV1.TeamUser(generator.teamUser), + expectedTeam := referenceTeam(generator.teamName, targetNamespace, []akov2.TeamUser{ + akov2.TeamUser(generator.teamUser), }, generator.projectName, expectedLabels) - expectedProject.Spec.Teams = []atlasV1.Team{ + expectedProject.Spec.Teams = []akov2.Team{ { - TeamRef: common.ResourceRefNamespaced{ + TeamRef: akov2common.ResourceRefNamespaced{ Namespace: targetNamespace, Name: expectedTeam.Name, }, - Roles: []atlasV1.TeamRole{ - atlasV1.TeamRole(teamRole), + Roles: []akov2.TeamRole{ + akov2.TeamRole(teamRole), }, }, } @@ -806,7 +827,7 @@ func TestProjectAndTeams(t *testing.T) { checkProject(t, objects, expectedProject, assertions) t.Run("Team is created", func(t *testing.T) { for _, obj := range objects { - if team, ok := obj.(*atlasV1.AtlasTeam); ok { + if team, ok := obj.(*akov2.AtlasTeam); ok { assertions.Equal(expectedTeam, team) } } @@ -814,10 +835,10 @@ func TestProjectAndTeams(t *testing.T) { }) } -func referenceTeam(name, namespace string, users []atlasV1.TeamUser, projectName string, labels map[string]string) *atlasV1.AtlasTeam { +func referenceTeam(name, namespace string, users []akov2.TeamUser, projectName string, labels map[string]string) *akov2.AtlasTeam { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasTeam{ + return &akov2.AtlasTeam{ TypeMeta: v1.TypeMeta{ Kind: "AtlasTeam", APIVersion: "atlas.mongodb.com/v1", @@ -827,26 +848,26 @@ func referenceTeam(name, namespace string, users []atlasV1.TeamUser, projectName Namespace: namespace, Labels: labels, }, - Spec: atlasV1.TeamSpec{ + Spec: akov2.TeamSpec{ Name: name, Usernames: users, }, - Status: status.TeamStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.TeamStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } } -func checkProject(t *testing.T, output []runtime.Object, expected *atlasV1.AtlasProject, asserts *assert.Assertions) { +func checkProject(t *testing.T, output []runtime.Object, expected *akov2.AtlasProject, asserts *assert.Assertions) { t.Helper() t.Run("Project presents with expected data", func(t *testing.T) { found := false - var p *atlasV1.AtlasProject + var p *akov2.AtlasProject var ok bool for i := range output { - p, ok = output[i].(*atlasV1.AtlasProject) + p, ok = output[i].(*akov2.AtlasProject) if ok { found = true break @@ -855,13 +876,30 @@ func checkProject(t *testing.T, output []runtime.Object, expected *atlasV1.Atlas if !found { t.Fatal("AtlasProject is not found in results") } + + // secretref names are randomly generated so we can't determine those in forehand + expected.Spec.EncryptionAtRest.AwsKms = p.Spec.EncryptionAtRest.AwsKms + expected.Spec.EncryptionAtRest.GoogleCloudKms = p.Spec.EncryptionAtRest.GoogleCloudKms + expected.Spec.EncryptionAtRest.AzureKeyVault = p.Spec.EncryptionAtRest.AzureKeyVault + + for i := range p.Spec.AlertConfigurations { + alertConfig := &p.Spec.AlertConfigurations[i] + for j := range alertConfig.Notifications { + expected.Spec.AlertConfigurations[i].Notifications[j].APITokenRef = p.Spec.AlertConfigurations[i].Notifications[j].APITokenRef + expected.Spec.AlertConfigurations[i].Notifications[j].DatadogAPIKeyRef = p.Spec.AlertConfigurations[i].Notifications[j].DatadogAPIKeyRef + expected.Spec.AlertConfigurations[i].Notifications[j].OpsGenieAPIKeyRef = p.Spec.AlertConfigurations[i].Notifications[j].OpsGenieAPIKeyRef + expected.Spec.AlertConfigurations[i].Notifications[j].ServiceKeyRef = p.Spec.AlertConfigurations[i].Notifications[j].ServiceKeyRef + expected.Spec.AlertConfigurations[i].Notifications[j].VictorOpsSecretRef = p.Spec.AlertConfigurations[i].Notifications[j].VictorOpsSecretRef + } + } + asserts.Equal(expected, p) }) } -func referenceProject(name, namespace string, labels map[string]string) *atlasV1.AtlasProject { +func referenceProject(name, namespace string, labels map[string]string) *akov2.AtlasProject { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasProject{ + return &akov2.AtlasProject{ TypeMeta: v1.TypeMeta{ Kind: "AtlasProject", APIVersion: "atlas.mongodb.com/v1", @@ -871,46 +909,58 @@ func referenceProject(name, namespace string, labels map[string]string) *atlasV1 Namespace: namespace, Labels: labels, }, - Status: status.AtlasProjectStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasProjectStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, - Spec: atlasV1.AtlasProjectSpec{ + Spec: akov2.AtlasProjectSpec{ Name: name, - ConnectionSecret: &common.ResourceRefNamespaced{ + ConnectionSecret: &akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-credentials", name), dictionary), }, - Settings: &atlasV1.ProjectSettings{ + Settings: &akov2.ProjectSettings{ IsCollectDatabaseSpecificsStatisticsEnabled: pointer.Get(true), IsDataExplorerEnabled: pointer.Get(true), IsPerformanceAdvisorEnabled: pointer.Get(true), IsRealtimePerformancePanelEnabled: pointer.Get(true), IsSchemaAdvisorEnabled: pointer.Get(true), }, - Auditing: &atlasV1.Auditing{ + Auditing: &akov2.Auditing{ AuditAuthorizationSuccess: false, Enabled: false, }, - EncryptionAtRest: &atlasV1.EncryptionAtRest{ - AwsKms: atlasV1.AwsKms{ + EncryptionAtRest: &akov2.EncryptionAtRest{ + AwsKms: akov2.AwsKms{ Enabled: pointer.Get(false), Valid: pointer.Get(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-aws-credentials", name), dictionary), + Namespace: namespace, + }, }, - AzureKeyVault: atlasV1.AzureKeyVault{ + AzureKeyVault: akov2.AzureKeyVault{ Enabled: pointer.Get(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-azure-credentials", name), dictionary), + Namespace: namespace, + }, }, - GoogleCloudKms: atlasV1.GoogleCloudKms{ + GoogleCloudKms: akov2.GoogleCloudKms{ Enabled: pointer.Get(false), + SecretRef: akov2common.ResourceRefNamespaced{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-gcp-credentials", name), dictionary), + Namespace: namespace, + }, }, }, }, } } -func referenceAdvancedCluster(name, region, namespace, projectName string, labels map[string]string) *atlasV1.AtlasDeployment { +func referenceAdvancedCluster(name, region, namespace, projectName string, labels map[string]string) *akov2.AtlasDeployment { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasDeployment{ + return &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -920,25 +970,25 @@ func referenceAdvancedCluster(name, region, namespace, projectName string, label Namespace: namespace, Labels: labels, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: namespace, }, - BackupScheduleRef: common.ResourceRefNamespaced{ + BackupScheduleRef: akov2common.ResourceRefNamespaced{ Namespace: targetNamespace, Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-%s-backupschedule", projectName, name), dictionary), }, - AdvancedDeploymentSpec: &atlasV1.AdvancedDeploymentSpec{ + DeploymentSpec: &akov2.AdvancedDeploymentSpec{ BackupEnabled: pointer.Get(true), - BiConnector: &atlasV1.BiConnectorSpec{ + BiConnector: &akov2.BiConnectorSpec{ Enabled: pointer.Get(false), ReadPreference: "secondary", }, - ClusterType: string(atlasV1.TypeReplicaSet), + ClusterType: string(akov2.TypeReplicaSet), DiskSizeGB: nil, EncryptionAtRestProvider: "NONE", - Labels: []common.LabelSpec{ + Labels: []akov2common.LabelSpec{ { Key: "Infrastructure Tool", Value: "Atlas CLI", @@ -947,41 +997,41 @@ func referenceAdvancedCluster(name, region, namespace, projectName string, label Name: name, Paused: pointer.Get(false), PitEnabled: pointer.Get(true), - ReplicationSpecs: []*atlasV1.AdvancedReplicationSpec{ + ReplicationSpecs: []*akov2.AdvancedReplicationSpec{ { NumShards: 1, ZoneName: "Zone 1", - RegionConfigs: []*atlasV1.AdvancedRegionConfig{ + RegionConfigs: []*akov2.AdvancedRegionConfig{ { - AnalyticsSpecs: &atlasV1.Specs{ + AnalyticsSpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: e2eClusterTier, NodeCount: pointer.Get(0), }, - ElectableSpecs: &atlasV1.Specs{ + ElectableSpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: e2eClusterTier, NodeCount: pointer.Get(3), }, - ReadOnlySpecs: &atlasV1.Specs{ + ReadOnlySpecs: &akov2.Specs{ DiskIOPS: pointer.Get(int64(3000)), EbsVolumeType: "STANDARD", InstanceSize: e2eClusterTier, NodeCount: pointer.Get(0), }, - AutoScaling: &atlasV1.AdvancedAutoScalingSpec{ - DiskGB: &atlasV1.DiskGB{ + AutoScaling: &akov2.AdvancedAutoScalingSpec{ + DiskGB: &akov2.DiskGB{ Enabled: pointer.Get(false), }, - Compute: &atlasV1.ComputeSpec{ + Compute: &akov2.ComputeSpec{ Enabled: pointer.Get(false), ScaleDownEnabled: pointer.Get(false), }, }, Priority: pointer.Get(7), - ProviderName: string(provider.ProviderAWS), + ProviderName: string(akov2provider.ProviderAWS), RegionName: region, }, }, @@ -990,23 +1040,23 @@ func referenceAdvancedCluster(name, region, namespace, projectName string, label RootCertType: "ISRGROOTX1", VersionReleaseSystem: "LTS", }, - ProcessArgs: &atlasV1.ProcessArgs{ + ProcessArgs: &akov2.ProcessArgs{ MinimumEnabledTLSProtocol: "TLS1_2", JavascriptEnabled: pointer.Get(true), NoTableScan: pointer.Get(false), }, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } } -func referenceServerless(name, region, namespace, projectName string, labels map[string]string) *atlasV1.AtlasDeployment { +func referenceServerless(name, region, namespace, projectName string, labels map[string]string) *akov2.AtlasDeployment { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasDeployment{ + return &akov2.AtlasDeployment{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDeployment", APIVersion: "atlas.mongodb.com/v1", @@ -1016,91 +1066,103 @@ func referenceServerless(name, region, namespace, projectName string, labels map Namespace: namespace, Labels: labels, }, - Spec: atlasV1.AtlasDeploymentSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.AtlasDeploymentSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: namespace, }, - ServerlessSpec: &atlasV1.ServerlessSpec{ + ServerlessSpec: &akov2.ServerlessSpec{ Name: name, - ProviderSettings: &atlasV1.ProviderSettingsSpec{ - BackingProviderName: string(provider.ProviderAWS), - ProviderName: provider.ProviderServerless, + ProviderSettings: &akov2.ProviderSettingsSpec{ + BackingProviderName: string(akov2provider.ProviderAWS), + ProviderName: akov2provider.ProviderServerless, RegionName: region, }, }, }, - Status: status.AtlasDeploymentStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.AtlasDeploymentStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } } -func referenceSharedCluster(name, region, namespace, projectName string, labels map[string]string) *atlasV1.AtlasDeployment { +func referenceSharedCluster(name, region, namespace, projectName string, labels map[string]string) *akov2.AtlasDeployment { cluster := referenceAdvancedCluster(name, region, namespace, projectName, labels) - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs = &atlasV1.Specs{ + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ElectableSpecs = &akov2.Specs{ DiskIOPS: pointer.Get(int64(0)), InstanceSize: e2eSharedClusterTier, } - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs = nil - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs = nil - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].AutoScaling = nil - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].BackingProviderName = string(provider.ProviderAWS) - cluster.Spec.AdvancedDeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ProviderName = string(provider.ProviderTenant) - - cluster.Spec.AdvancedDeploymentSpec.PitEnabled = pointer.Get(false) - cluster.Spec.BackupScheduleRef = common.ResourceRefNamespaced{} + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ReadOnlySpecs = nil + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].AnalyticsSpecs = nil + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].AutoScaling = nil + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].BackingProviderName = string(akov2provider.ProviderAWS) + cluster.Spec.DeploymentSpec.ReplicationSpecs[0].RegionConfigs[0].ProviderName = string(akov2provider.ProviderTenant) + + cluster.Spec.DeploymentSpec.PitEnabled = pointer.Get(false) + cluster.Spec.BackupScheduleRef = akov2common.ResourceRefNamespaced{} return cluster } -func defaultMaintenanceWindowAlertConfigs() []atlasV1.AlertConfiguration { - ownerNotifications := []atlasV1.Notification{ - { - EmailEnabled: pointer.Get(true), - IntervalMin: 60, - DelayMin: pointer.Get(0), - SMSEnabled: pointer.Get(false), - TypeName: "GROUP", - Roles: []string{"GROUP_OWNER"}, - }, +func defaultMaintenanceWindowAlertConfigs() []akov2.AlertConfiguration { + ownerNotifications := func() []akov2.Notification { + return []akov2.Notification{ + { + EmailEnabled: pointer.Get(true), + IntervalMin: 60, + DelayMin: pointer.Get(0), + SMSEnabled: pointer.Get(false), + TypeName: "GROUP", + Roles: []string{"GROUP_OWNER"}, + }, + } } - return []atlasV1.AlertConfiguration{ + + return []akov2.AlertConfiguration{ { - Enabled: true, - EventTypeName: "MAINTENANCE_IN_ADVANCED", - Threshold: &atlasV1.Threshold{}, - Notifications: ownerNotifications, - MetricThreshold: &atlasV1.MetricThreshold{}, + Enabled: true, + EventTypeName: "MAINTENANCE_IN_ADVANCED", + Threshold: &akov2.Threshold{}, + Notifications: []akov2.Notification{ + { + EmailEnabled: pointer.Get(true), + IntervalMin: 60, + DelayMin: pointer.Get(0), + SMSEnabled: pointer.Get(false), + TypeName: "GROUP", + Roles: []string{"GROUP_OWNER"}, + }, + }, + MetricThreshold: &akov2.MetricThreshold{}, }, { Enabled: true, EventTypeName: "MAINTENANCE_STARTED", - Threshold: &atlasV1.Threshold{}, - Notifications: ownerNotifications, - MetricThreshold: &atlasV1.MetricThreshold{}, + Threshold: &akov2.Threshold{}, + Notifications: ownerNotifications(), + MetricThreshold: &akov2.MetricThreshold{}, }, { Enabled: true, EventTypeName: "MAINTENANCE_NO_LONGER_NEEDED", - Threshold: &atlasV1.Threshold{}, - Notifications: ownerNotifications, - MetricThreshold: &atlasV1.MetricThreshold{}, + Threshold: &akov2.Threshold{}, + Notifications: ownerNotifications(), + MetricThreshold: &akov2.MetricThreshold{}, }, { Enabled: true, EventTypeName: "MAINTENANCE_AUTO_DEFERRED", - Threshold: &atlasV1.Threshold{}, - Notifications: ownerNotifications, - MetricThreshold: &atlasV1.MetricThreshold{}, + Threshold: &akov2.Threshold{}, + Notifications: ownerNotifications(), + MetricThreshold: &akov2.MetricThreshold{}, }, } } -func referenceBackupSchedule(namespace, projectName, clusterName string, labels map[string]string) *atlasV1.AtlasBackupSchedule { +func referenceBackupSchedule(namespace, projectName, clusterName string, labels map[string]string) *akov2.AtlasBackupSchedule { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasBackupSchedule{ + return &akov2.AtlasBackupSchedule{ TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupSchedule", APIVersion: "atlas.mongodb.com/v1", @@ -1110,8 +1172,8 @@ func referenceBackupSchedule(namespace, projectName, clusterName string, labels Namespace: namespace, Labels: labels, }, - Spec: atlasV1.AtlasBackupScheduleSpec{ - PolicyRef: common.ResourceRefNamespaced{ + Spec: akov2.AtlasBackupScheduleSpec{ + PolicyRef: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-%s-backuppolicy", projectName, clusterName), dictionary), Namespace: namespace, }, @@ -1122,9 +1184,9 @@ func referenceBackupSchedule(namespace, projectName, clusterName string, labels } } -func referenceBackupPolicy(namespace, projectName, clusterName string, labels map[string]string) *atlasV1.AtlasBackupPolicy { +func referenceBackupPolicy(namespace, projectName, clusterName string, labels map[string]string) *akov2.AtlasBackupPolicy { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasBackupPolicy{ + return &akov2.AtlasBackupPolicy{ TypeMeta: v1.TypeMeta{ Kind: "AtlasBackupPolicy", APIVersion: "atlas.mongodb.com/v1", @@ -1134,8 +1196,8 @@ func referenceBackupPolicy(namespace, projectName, clusterName string, labels ma Namespace: namespace, Labels: labels, }, - Spec: atlasV1.AtlasBackupPolicySpec{ - Items: []atlasV1.AtlasBackupPolicyItem{ + Spec: akov2.AtlasBackupPolicySpec{ + Items: []akov2.AtlasBackupPolicyItem{ { FrequencyType: "hourly", FrequencyInterval: 6, @@ -1165,7 +1227,7 @@ func referenceBackupPolicy(namespace, projectName, clusterName string, labels ma } } -func checkClustersData(t *testing.T, deployments []*atlasV1.AtlasDeployment, clusterNames []string, region, namespace, projectName string) { +func checkClustersData(t *testing.T, deployments []*akov2.AtlasDeployment, clusterNames []string, region, namespace, projectName string) { t.Helper() assert.Len(t, deployments, len(clusterNames)) var entries []string @@ -1177,9 +1239,9 @@ func checkClustersData(t *testing.T, deployments []*atlasV1.AtlasDeployment, clu assert.Equal(t, expectedDeployment, deployment) entries = append(entries, name) } - } else if deployment.Spec.AdvancedDeploymentSpec != nil { - if ok := search.StringInSlice(clusterNames, deployment.Spec.AdvancedDeploymentSpec.Name); ok { - name := deployment.Spec.AdvancedDeploymentSpec.Name + } else if deployment.Spec.DeploymentSpec != nil { + if ok := search.StringInSlice(clusterNames, deployment.Spec.DeploymentSpec.Name); ok { + name := deployment.Spec.DeploymentSpec.Name expectedDeployment := referenceAdvancedCluster(name, region, namespace, projectName, expectedLabels) assert.Equal(t, expectedDeployment, deployment) entries = append(entries, name) @@ -1209,7 +1271,7 @@ func TestKubernetesConfigGenerate_ClustersWithBackup(t *testing.T) { require.NoError(t, err) // always register atlas entities - require.NoError(t, atlasV1.AddToScheme(scheme.Scheme)) + require.NoError(t, akov2.AddToScheme(scheme.Scheme)) t.Run("Update backup schedule", func(t *testing.T) { cmd := exec.Command(cliPath, @@ -1263,10 +1325,10 @@ func TestKubernetesConfigGenerate_ClustersWithBackup(t *testing.T) { t.Run("Deployment present with valid data", func(t *testing.T) { found := false - var deployment *atlasV1.AtlasDeployment + var deployment *akov2.AtlasDeployment var ok bool for i := range objects { - deployment, ok = objects[i].(*atlasV1.AtlasDeployment) + deployment, ok = objects[i].(*akov2.AtlasDeployment) if ok { found = true break @@ -1391,9 +1453,9 @@ func TestKubernetesConfigGenerate_ClustersWithBackup(t *testing.T) { }) } -func atlasBackupPolicy(objects []runtime.Object) (*atlasV1.AtlasBackupPolicy, bool) { +func atlasBackupPolicy(objects []runtime.Object) (*akov2.AtlasBackupPolicy, bool) { for i := range objects { - if policy, ok := objects[i].(*atlasV1.AtlasBackupPolicy); ok { + if policy, ok := objects[i].(*akov2.AtlasBackupPolicy); ok { return policy, ok } } @@ -1414,7 +1476,7 @@ func TestKubernetesConfigGenerateSharedCluster(t *testing.T) { require.NoError(t, err) // always register atlas entities - require.NoError(t, atlasV1.AddToScheme(scheme.Scheme)) + require.NoError(t, akov2.AddToScheme(scheme.Scheme)) t.Run("Generate valid resources of ONE project and TWO clusters without listing clusters", func(t *testing.T) { cmd := exec.Command(cliPath, @@ -1462,10 +1524,10 @@ func TestKubernetesConfigGenerateSharedCluster(t *testing.T) { }) } -func atlasDeployments(objects []runtime.Object) []*atlasV1.AtlasDeployment { - var ds []*atlasV1.AtlasDeployment +func atlasDeployments(objects []runtime.Object) []*akov2.AtlasDeployment { + var ds []*akov2.AtlasDeployment for i := range objects { - d, ok := objects[i].(*atlasV1.AtlasDeployment) + d, ok := objects[i].(*akov2.AtlasDeployment) if ok { ds = append(ds, d) } @@ -1473,9 +1535,9 @@ func atlasDeployments(objects []runtime.Object) []*atlasV1.AtlasDeployment { return ds } -func findAtlasProject(objects []runtime.Object) (*atlasV1.AtlasProject, bool) { +func findAtlasProject(objects []runtime.Object) (*akov2.AtlasProject, bool) { for i := range objects { - if p, ok := objects[i].(*atlasV1.AtlasProject); ok { + if p, ok := objects[i].(*akov2.AtlasProject); ok { return p, ok } } @@ -1491,18 +1553,18 @@ func findSecret(objects []runtime.Object) (*corev1.Secret, bool) { return nil, false } -func atlasBackupSchedule(objects []runtime.Object) (*atlasV1.AtlasBackupSchedule, bool) { +func atlasBackupSchedule(objects []runtime.Object) (*akov2.AtlasBackupSchedule, bool) { for i := range objects { - if schedule, ok := objects[i].(*atlasV1.AtlasBackupSchedule); ok { + if schedule, ok := objects[i].(*akov2.AtlasBackupSchedule); ok { return schedule, ok } } return nil, false } -func referenceDataFederation(name, namespace, projectName string, labels map[string]string) *atlasV1.AtlasDataFederation { +func referenceDataFederation(name, namespace, projectName string, labels map[string]string) *akov2.AtlasDataFederation { dictionary := resources.AtlasNameToKubernetesName() - return &atlasV1.AtlasDataFederation{ + return &akov2.AtlasDataFederation{ TypeMeta: v1.TypeMeta{ Kind: "AtlasDataFederation", APIVersion: "atlas.mongodb.com/v1", @@ -1512,25 +1574,25 @@ func referenceDataFederation(name, namespace, projectName string, labels map[str Namespace: namespace, Labels: labels, }, - Spec: atlasV1.DataFederationSpec{ - Project: common.ResourceRefNamespaced{ + Spec: akov2.DataFederationSpec{ + Project: akov2common.ResourceRefNamespaced{ Name: resources.NormalizeAtlasName(projectName, dictionary), Namespace: namespace, }, Name: name, - CloudProviderConfig: &atlasV1.CloudProviderConfig{}, - DataProcessRegion: &atlasV1.DataProcessRegion{ + CloudProviderConfig: &akov2.CloudProviderConfig{}, + DataProcessRegion: &akov2.DataProcessRegion{ CloudProvider: "AWS", Region: "DUBLIN_IRL", }, - Storage: &atlasV1.Storage{ + Storage: &akov2.Storage{ Databases: nil, Stores: nil, }, }, - Status: status.DataFederationStatus{ - Common: status.Common{ - Conditions: []status.Condition{}, + Status: akov2status.DataFederationStatus{ + Common: akov2status.Common{ + Conditions: []akov2status.Condition{}, }, }, } @@ -1552,7 +1614,7 @@ func TestKubernetesConfigGenerate_DataFederation(t *testing.T) { require.NoError(t, err) // always register atlas entities - require.NoError(t, atlasV1.AddToScheme(scheme.Scheme)) + require.NoError(t, akov2.AddToScheme(scheme.Scheme)) t.Run("Generate valid resources of ONE project and ONE data federation", func(t *testing.T) { cmd := exec.Command(cliPath, @@ -1587,10 +1649,10 @@ func TestKubernetesConfigGenerate_DataFederation(t *testing.T) { }) t.Run("Deployment present with valid data", func(t *testing.T) { found := false - var datafederation *atlasV1.AtlasDataFederation + var datafederation *akov2.AtlasDataFederation var ok bool for i := range objects { - datafederation, ok = objects[i].(*atlasV1.AtlasDataFederation) + datafederation, ok = objects[i].(*akov2.AtlasDataFederation) if ok { found = true break @@ -1675,10 +1737,10 @@ func TestKubernetesConfigGenerate_DataFederation(t *testing.T) { }) } -func atlasDataFederations(objects []runtime.Object) []*atlasV1.AtlasDataFederation { - var df []*atlasV1.AtlasDataFederation +func atlasDataFederations(objects []runtime.Object) []*akov2.AtlasDataFederation { + var df []*akov2.AtlasDataFederation for i := range objects { - d, ok := objects[i].(*atlasV1.AtlasDataFederation) + d, ok := objects[i].(*akov2.AtlasDataFederation) if ok { df = append(df, d) } @@ -1686,7 +1748,7 @@ func atlasDataFederations(objects []runtime.Object) []*atlasV1.AtlasDataFederati return df } -func checkDataFederationData(t *testing.T, dataFederations []*atlasV1.AtlasDataFederation, dataFedNames []string, namespace, projectName string) { +func checkDataFederationData(t *testing.T, dataFederations []*akov2.AtlasDataFederation, dataFedNames []string, namespace, projectName string) { t.Helper() assert.Len(t, dataFederations, len(dataFedNames)) var entries []string diff --git a/test/e2e/atlas/kubernetes_operator_install_test.go b/test/e2e/atlas/kubernetes_operator_install_test.go index 60dd42d542..95cc0df098 100644 --- a/test/e2e/atlas/kubernetes_operator_install_test.go +++ b/test/e2e/atlas/kubernetes_operator_install_test.go @@ -26,7 +26,7 @@ import ( "github.com/mongodb/mongodb-atlas-cli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/test/e2e" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" atlasv2 "go.mongodb.org/atlas-sdk/v20231115002/admin" @@ -206,7 +206,7 @@ func TestKubernetesOperatorInstall(t *testing.T) { checkK8sAtlasProject(t, operator, client.ObjectKey{Name: prepareK8sName(projectName), Namespace: operatorNamespace}) - akoProject := &akov1.AtlasProject{} + akoProject := &akov2.AtlasProject{} err = operator.getK8sObject( client.ObjectKey{Name: prepareK8sName(projectName), Namespace: operatorNamespace}, akoProject, @@ -291,10 +291,7 @@ func setupCluster(t *testing.T, name string, namespaces ...string) *operatorHelp }, } t.Logf("adding namespace %s", namespace) - err = operator.createK8sObject(operatorNamespace, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, operator.createK8sObject(operatorNamespace)) } return operator @@ -372,7 +369,7 @@ func checkK8sAtlasProject(t *testing.T, operator *operatorHelper, key client.Obj t.Helper() var ready bool - project := &akov1.AtlasProject{} + project := &akov2.AtlasProject{} for i := 0; i < maxAttempts; i++ { ready = true @@ -402,7 +399,7 @@ func checkK8sAtlasDeployment(t *testing.T, operator *operatorHelper, key client. t.Helper() var ready bool - deployment := &akov1.AtlasDeployment{} + deployment := &akov2.AtlasDeployment{} for i := 0; i < deploymentMaxAttempts; i++ { ready = true diff --git a/test/e2e/atlas/operator_helper_test.go b/test/e2e/atlas/operator_helper_test.go index 91febe7a51..e1600827ee 100644 --- a/test/e2e/atlas/operator_helper_test.go +++ b/test/e2e/atlas/operator_helper_test.go @@ -22,8 +22,9 @@ import ( "testing" "time" - akov1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr" + "github.com/mongodb/mongodb-atlas-cli/internal/pointer" + akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" + akov2toptr "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/util/toptr" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" @@ -50,7 +51,7 @@ func newOperatorHelper(t *testing.T) (*operatorHelper, error) { return nil, err } - err = akov1.AddToScheme(scheme.Scheme) + err = akov2.AddToScheme(scheme.Scheme) if err != nil { return nil, err } @@ -101,17 +102,8 @@ func (oh *operatorHelper) getK8sObject(key client.ObjectKey, object client.Objec return nil } -func (oh *operatorHelper) createK8sObject(object client.Object, track bool) error { - err := oh.k8sClient.Create(context.Background(), object, &client.CreateOptions{}) - if err != nil { - return err - } - - if track { - oh.resourcesTracked = append(oh.resourcesTracked, object) - } - - return nil +func (oh *operatorHelper) createK8sObject(object client.Object) error { + return oh.k8sClient.Create(context.Background(), object, &client.CreateOptions{}) } func (oh *operatorHelper) deleteK8sObject(object client.Object) error { @@ -167,7 +159,7 @@ func (oh *operatorHelper) stopOperator() { oh.t.Errorf("unable to retrieve operator deployment: %v", err) } - deployment.Spec.Replicas = toptr.MakePtr(int32(0)) + deployment.Spec.Replicas = pointer.Get[int32](0) err = oh.k8sClient.Update(context.Background(), &deployment, &client.UpdateOptions{}) if err != nil { @@ -186,7 +178,7 @@ func (oh *operatorHelper) startOperator() { oh.t.Errorf("unable to retrieve operator deployment: %v", err) } - deployment.Spec.Replicas = toptr.MakePtr(int32(1)) + deployment.Spec.Replicas = akov2toptr.MakePtr(int32(1)) err = oh.k8sClient.Update(context.Background(), &deployment, &client.UpdateOptions{}) if err != nil {