From a897f13dfcb3b150b93e837e26369b5f735189f6 Mon Sep 17 00:00:00 2001 From: Helder Santana Date: Thu, 28 Nov 2024 12:21:08 +0100 Subject: [PATCH 01/20] support export private endpoint custom resource --- go.mod | 2 +- go.sum | 2 ++ test/e2e/atlas/kubernetes_config_generate_test.go | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a87df4192f..67d9646e93 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/mholt/archives v0.0.0-20241207175349-5e373c52f8aa github.com/mongodb-forks/digest v1.1.0 github.com/mongodb-labs/cobra2snooty v0.18.2 - github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0 + github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.1-0.20241125102449-344dbce54e85 github.com/pelletier/go-toml v1.9.5 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/shirou/gopsutil/v4 v4.24.11 diff --git a/go.sum b/go.sum index 9cb30bd079..d1e8d84035 100644 --- a/go.sum +++ b/go.sum @@ -334,6 +334,8 @@ github.com/mongodb-labs/cobra2snooty v0.18.2 h1:qWpLCMWbQb5FSZ5ehiWN2URmieMJhQtQ github.com/mongodb-labs/cobra2snooty v0.18.2/go.mod h1:WnzqCFmx4f72Yj9dL/ulBUqcatfURGdKFf8DLT4h7zQ= github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0 h1:g4pJ13johhJ/oFyyZCXsUGCBNkaLqF1yPl5U6SVP86o= github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0/go.mod h1:qjGZXGzDL73pE9lbqT9SNoaMGi3gKFRuOxjFrPVIFJs= +github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.5.1-0.20241125102449-344dbce54e85 h1:KZDM7F80ELPvgTlVjJhT0tF9cwGzOxsQ7SbBSVQma0c= +github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.5.1-0.20241125102449-344dbce54e85/go.mod h1:PZNJBNKogrgra4TorvasJHE0A6R8COdCT5LVAx6whWw= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index b22652c986..299feb5846 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -163,6 +163,7 @@ func TestExportIndependentOrNot(t *testing.T) { testPrefix := "test-" generator.generateDBUser(testPrefix) generator.generateCluster() + generator.generateAWSPrivateEndpoint("eu-central-1") expectAlertConfigs := true dictionary := resources.AtlasNameToKubernetesName() credentialName := resources.NormalizeAtlasName(generator.projectName+credSuffixTest, dictionary) @@ -188,6 +189,7 @@ func TestExportIndependentOrNot(t *testing.T) { expected: []runtime.Object{ defaultTestProject(generator.projectName, "", expectedLabels, expectAlertConfigs, nil), defaultTestAtlasConnSecret(credentialName, ""), + expectedPrivateEndpoint, defaultTestUserWithID(generator.dbUser, generator.projectName, generator.projectID, "", credentialName), defaultM0TestClusterWithID( generator.clusterName, generator.clusterRegion, generator.projectName, generator.projectID, "", From c694546dc056963880dc958ecbd23a5222392c8d Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 4 Dec 2024 22:31:22 +0100 Subject: [PATCH 02/20] Added export of AtlasCustomRole CRs --- .../kubernetes/operator/config_exporter.go | 20 ++ internal/kubernetes/operator/features/crds.go | 2 + .../kubernetes/operator/features/validator.go | 2 +- .../operator/project/customroles.go | 107 ++++++++ .../operator/project/customroles_test.go | 256 ++++++++++++++++++ .../kubernetes/operator/project/project.go | 2 +- .../operator/project/project_test.go | 31 +-- 7 files changed, 393 insertions(+), 27 deletions(-) create mode 100644 internal/kubernetes/operator/project/customroles.go create mode 100644 internal/kubernetes/operator/project/customroles_test.go diff --git a/internal/kubernetes/operator/config_exporter.go b/internal/kubernetes/operator/config_exporter.go index 2d6350646e..5410947c0b 100644 --- a/internal/kubernetes/operator/config_exporter.go +++ b/internal/kubernetes/operator/config_exporter.go @@ -256,6 +256,26 @@ func (e *ConfigExporter) exportProject() ([]runtime.Object, string, error) { } } + // Independent custom roles (AtlasCustomRole CR) + if e.featureValidator.IsResourceSupported(features.ResourceAtlasCustomRole) { + roles, err := project.BuildCustomRoles(e.dataProvider, project.CustomRolesRequest{ + ProjectID: e.projectID, + ProjectName: projectData.Project.Name, + TargetNamespace: e.targetNamespace, + Version: e.operatorVersion, + Credentials: credentialsName, + IsIndependent: e.independentResources, + Dict: e.dictionaryForAtlasNames, + }) + if err != nil { + return nil, "", err + } + + for i := range len(roles) { + r = append(r, &roles[i]) + } + } + // DB users usersData, relatedSecrets, err := dbusers.BuildDBUsers( e.dataProvider, diff --git a/internal/kubernetes/operator/features/crds.go b/internal/kubernetes/operator/features/crds.go index 6d5eed556d..e477d5d6c0 100644 --- a/internal/kubernetes/operator/features/crds.go +++ b/internal/kubernetes/operator/features/crds.go @@ -42,6 +42,7 @@ const ( ResourceAtlasStreamConnection = "atlasstreamconnections" ResourceAtlasBackupCompliancePolicy = "atlasbackupcompliancepolicies" ResourceAtlasPrivateEndpoint = "atlasprivateendpoints" + ResourceAtlasCustomRole = "atlascustomroles" ) var ( @@ -92,6 +93,7 @@ var ( resource{ResourceAtlasStreamConnection, NopPatcher()}, resource{ResourceAtlasBackupCompliancePolicy, NopPatcher()}, resource{ResourceAtlasPrivateEndpoint, NopPatcher()}, + resource{ResourceAtlasCustomRole, NopPatcher()}, }, } ) diff --git a/internal/kubernetes/operator/features/validator.go b/internal/kubernetes/operator/features/validator.go index a94a996d26..4396862895 100644 --- a/internal/kubernetes/operator/features/validator.go +++ b/internal/kubernetes/operator/features/validator.go @@ -18,5 +18,5 @@ package features type FeatureValidator interface { IsResourceSupported(resourceName string) bool - FeatureExist(resourceName, version string) bool + FeatureExist(resourceName, path string) bool } diff --git a/internal/kubernetes/operator/project/customroles.go b/internal/kubernetes/operator/project/customroles.go new file mode 100644 index 0000000000..8488cca7f4 --- /dev/null +++ b/internal/kubernetes/operator/project/customroles.go @@ -0,0 +1,107 @@ +package project + +import ( + "fmt" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/features" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/resources" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/pointer" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/store" + akoapi "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api" + 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" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type CustomRolesRequest struct { + ProjectName string + ProjectID string + TargetNamespace string + Credentials string + Version string + IsIndependent bool + Dict map[string]string +} + +func BuildCustomRoles(provider store.DatabaseRoleLister, request CustomRolesRequest) ([]akov2.AtlasCustomRole, error) { + roles, err := provider.DatabaseRoles(request.ProjectID) + if err != nil { + return nil, err + } + if roles == nil { + return nil, nil + } + + result := make([]akov2.AtlasCustomRole, 0, len(roles)) + + for rIdx := range roles { + role := &roles[rIdx] + + inhRoles := make([]akov2.Role, 0, len(role.GetInheritedRoles())) + for _, rl := range role.GetInheritedRoles() { + inhRoles = append(inhRoles, akov2.Role{ + Name: rl.Role, + Database: rl.Db, + }) + } + + actions := make([]akov2.Action, 0, len(role.GetActions())) + for _, action := range role.GetActions() { + r := make([]akov2.Resource, 0, len(action.GetResources())) + for _, res := range action.GetResources() { + r = append(r, akov2.Resource{ + Cluster: pointer.Get(res.Cluster), + Database: pointer.Get(res.Db), + Collection: pointer.Get(res.Collection), + }) + } + actions = append(actions, akov2.Action{ + Name: action.Action, + Resources: r, + }) + } + + akoRole := akov2.AtlasCustomRole{ + TypeMeta: metav1.TypeMeta{ + Kind: "AtlasCustomRole", + APIVersion: "atlas.mongodb.com/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: resources.NormalizeAtlasName( + fmt.Sprintf("%s-custom-role-%s", + request.ProjectName, + role.RoleName), + request.Dict), + Namespace: request.TargetNamespace, + Labels: map[string]string{ + features.ResourceVersion: request.Version, + }, + }, + Spec: akov2.AtlasCustomRoleSpec{ + Role: akov2.CustomRole{ + Name: role.RoleName, + InheritedRoles: inhRoles, + Actions: actions, + }, + LocalCredentialHolder: akoapi.LocalCredentialHolder{ + ConnectionSecret: &akoapi.LocalObjectReference{ + Name: resources.NormalizeAtlasName(request.Credentials, request.Dict), + }, + }, + }, + Status: akov2status.AtlasCustomRoleStatus{ + Common: akoapi.Common{Conditions: []akoapi.Condition{}}, + }, + } + if request.IsIndependent { + akoRole.Spec.ExternalProjectIDRef = &akov2.ExternalProjectReference{ID: request.ProjectID} + } else { + akoRole.Spec.ProjectRef = &akov2common.ResourceRefNamespaced{ + Name: request.ProjectName, + Namespace: request.TargetNamespace, + } + } + result = append(result) + } + return result, nil +} diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go new file mode 100644 index 0000000000..b09a535740 --- /dev/null +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -0,0 +1,256 @@ +package project + +import ( + "errors" + "fmt" + "github.com/golang/mock/gomock" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/features" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/resources" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/mocks" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/pointer" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/store" + 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" + "go.mongodb.org/atlas-sdk/v20241113001/admin" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "testing" +) + +func TestBuildCustomRoles(t *testing.T) { + projectID := "pid-1" + projectName := "p-1" + targetNamespace := "n-1" + credentialName := "creds" + type args struct { + provider store.DatabaseRoleLister + request CustomRolesRequest + } + tests := []struct { + name string + args args + rolesInAtlas []admin.UserCustomDBRole + errInAtlas error + want []akov2.AtlasCustomRole + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Should return err if provider return error", + args: args{ + request: CustomRolesRequest{ + ProjectName: projectName, + ProjectID: projectID, + TargetNamespace: targetNamespace, + Credentials: credentialName, + Version: "v2.6.0", + IsIndependent: false, + Dict: resources.AtlasNameToKubernetesName(), + }, + }, + errInAtlas: errors.New("no roles found"), + want: nil, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + { + name: "Should return nil if provider returned empty list of custom roles", + args: args{ + request: CustomRolesRequest{ + ProjectName: projectName, + ProjectID: projectID, + TargetNamespace: targetNamespace, + Credentials: credentialName, + Version: "v2.6.0", + IsIndependent: false, + Dict: resources.AtlasNameToKubernetesName(), + }, + }, + rolesInAtlas: nil, + errInAtlas: nil, + want: nil, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return false + }, + }, + { + name: "Should return AKO custom roles if provider returned custom roles", + args: args{ + request: CustomRolesRequest{ + ProjectName: projectName, + ProjectID: projectID, + TargetNamespace: targetNamespace, + Credentials: credentialName, + Version: "v2.6.0", + IsIndependent: false, + Dict: resources.AtlasNameToKubernetesName(), + }, + }, + rolesInAtlas: []admin.UserCustomDBRole{ + { + Actions: &([]admin.DatabasePrivilegeAction{ + { + Action: "test", + Resources: &([]admin.DatabasePermittedNamespaceResource{ + { + Cluster: false, + Collection: "c-1", + Db: "d-1", + }, + }), + }, + }), + InheritedRoles: &([]admin.DatabaseInheritedRole{ + { + Db: "d-1", + Role: "ADMIN", + }, + }), + RoleName: "r-1", + }, + }, + errInAtlas: nil, + want: []akov2.AtlasCustomRole{ + { + TypeMeta: metav1.TypeMeta{ + Kind: "AtlasCustomRole", + APIVersion: "atlas.mongodb.com/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-custom-role-r-1", projectName), + Namespace: targetNamespace, + Labels: map[string]string{ + features.ResourceVersion: "v2.6.0", + }, + }, + Spec: akov2.AtlasCustomRoleSpec{ + Role: akov2.CustomRole{ + Name: "r-1", + InheritedRoles: []akov2.Role{ + { + Name: "ADMIN", + Database: "d-1", + }, + }, + Actions: []akov2.Action{ + { + Name: "test", + Resources: []akov2.Resource{ + { + Cluster: pointer.Get(false), + Database: pointer.Get("d-1"), + Collection: pointer.Get("c-1"), + }, + }, + }, + }, + }, + ProjectRef: &akov2common.ResourceRefNamespaced{ + Name: projectName, + Namespace: targetNamespace, + }, + }, + Status: akov2status.AtlasCustomRoleStatus{}, + }, + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return false + }, + }, + { + name: "Should return AKO custom roles if provider returned custom roles, as independent", + args: args{ + request: CustomRolesRequest{ + ProjectName: projectName, + ProjectID: projectID, + TargetNamespace: targetNamespace, + Credentials: credentialName, + Version: "v2.6.0", + IsIndependent: true, + Dict: resources.AtlasNameToKubernetesName(), + }, + }, + rolesInAtlas: []admin.UserCustomDBRole{ + { + Actions: &([]admin.DatabasePrivilegeAction{ + { + Action: "test", + Resources: &([]admin.DatabasePermittedNamespaceResource{ + { + Cluster: false, + Collection: "c-1", + Db: "d-1", + }, + }), + }, + }), + InheritedRoles: &([]admin.DatabaseInheritedRole{ + { + Db: "d-1", + Role: "ADMIN", + }, + }), + RoleName: "r-1", + }, + }, + errInAtlas: nil, + want: []akov2.AtlasCustomRole{ + { + TypeMeta: metav1.TypeMeta{ + Kind: "AtlasCustomRole", + APIVersion: "atlas.mongodb.com/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-custom-role-r-1", projectName), + Namespace: targetNamespace, + Labels: map[string]string{ + features.ResourceVersion: "v2.6.0", + }, + }, + Spec: akov2.AtlasCustomRoleSpec{ + Role: akov2.CustomRole{ + Name: "r-1", + InheritedRoles: []akov2.Role{ + { + Name: "ADMIN", + Database: "d-1", + }, + }, + Actions: []akov2.Action{ + { + Name: "test", + Resources: []akov2.Resource{ + { + Cluster: pointer.Get(false), + Database: pointer.Get("d-1"), + Collection: pointer.Get("c-1"), + }, + }, + }, + }, + }, + ExternalProjectIDRef: &akov2.ExternalProjectReference{ID: projectID}, + }, + Status: akov2status.AtlasCustomRoleStatus{}, + }, + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return false + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := gomock.NewController(t) + crStore := mocks.NewMockOperatorProjectStore(c) + crStore.EXPECT().DatabaseRoles(projectID).Return(tt.rolesInAtlas, tt.errInAtlas) + + got, err := BuildCustomRoles(crStore, tt.args.request) + if !tt.wantErr(t, err, fmt.Sprintf("BuildCustomRoles(%v, %v)", tt.args.provider, tt.args.request)) { + return + } + assert.Equalf(t, tt.want, got, "BuildCustomRoles(%v, %v)", tt.args.provider, tt.args.request) + }) + } +} diff --git a/internal/kubernetes/operator/project/project.go b/internal/kubernetes/operator/project/project.go index b6754d6e2e..3c763e1964 100644 --- a/internal/kubernetes/operator/project/project.go +++ b/internal/kubernetes/operator/project/project.go @@ -183,7 +183,7 @@ func BuildAtlasProject(br *AtlasProjectBuildRequest) (*AtlasProjectResult, error result.Secrets = append(result.Secrets, s...) } - if br.Validator.FeatureExist(features.ResourceAtlasProject, featureCustomRoles) { + if br.Validator.FeatureExist(features.ResourceAtlasProject, featureCustomRoles) && !br.Validator.IsResourceSupported(features.ResourceAtlasCustomRole) { customRoles, ferr := buildCustomRoles(br.ProjectStore, br.ProjectID) if ferr != nil { return nil, ferr diff --git a/internal/kubernetes/operator/project/project_test.go b/internal/kubernetes/operator/project/project_test.go index b6bf8b9c0d..bd9ecf46a7 100644 --- a/internal/kubernetes/operator/project/project_test.go +++ b/internal/kubernetes/operator/project/project_test.go @@ -577,7 +577,7 @@ func TestBuildAtlasProject(t *testing.T) { }, }, }, - "Can convert Project entity with secrets data wit support for independent resource": { + "Can convert Project entity with secrets data with support for independent resource": { independentResource: true, privateEndpointMock: func(_ *mocks.MockOperatorProjectStore) {}, expectedProject: &akov2.AtlasProject{ @@ -682,29 +682,7 @@ func TestBuildAtlasProject(t *testing.T) { IsRealtimePerformancePanelEnabled: projectSettings.IsRealtimePerformancePanelEnabled, IsSchemaAdvisorEnabled: projectSettings.IsSchemaAdvisorEnabled, }, - CustomRoles: []akov2.CustomRole{ - { - Name: customRoles[0].RoleName, - InheritedRoles: []akov2.Role{ - { - Name: customRoles[0].GetInheritedRoles()[0].Role, - Database: customRoles[0].GetInheritedRoles()[0].Db, - }, - }, - Actions: []akov2.Action{ - { - Name: customRoles[0].GetActions()[0].Action, - Resources: []akov2.Resource{ - { - Cluster: &customRoles[0].GetActions()[0].GetResources()[0].Cluster, - Database: &customRoles[0].GetActions()[0].GetResources()[0].Db, - Collection: &customRoles[0].GetActions()[0].GetResources()[0].Collection, - }, - }, - }, - }, - }, - }, + CustomRoles: nil, Teams: []akov2.Team{ { TeamRef: akov2common.ResourceRefNamespaced{ @@ -744,12 +722,14 @@ func TestBuildAtlasProject(t *testing.T) { projectStore.EXPECT().ProjectSettings(projectID).Return(projectSettings, nil) projectStore.EXPECT().Auditing(projectID).Return(auditing, nil) projectStore.EXPECT().AlertConfigurations(listAlterOpt).Return(alertConfigResult, nil) - projectStore.EXPECT().DatabaseRoles(projectID).Return(customRoles, nil) projectStore.EXPECT().ProjectTeams(projectID, nil).Return(projectTeams, nil) projectStore.EXPECT().TeamByID(orgID, teamID).Return(teams, nil) projectStore.EXPECT().TeamUsers(orgID, teamID).Return(teamUsers, nil) projectStore.EXPECT().DescribeCompliancePolicy(projectID).Return(bcp, nil) tt.privateEndpointMock(projectStore) + if !tt.independentResource { + projectStore.EXPECT().DatabaseRoles(projectID).Return(customRoles, nil) + } featureValidator.EXPECT().FeatureExist(features.ResourceAtlasProject, featureAccessLists).Return(true) featureValidator.EXPECT().FeatureExist(features.ResourceAtlasProject, featureMaintenanceWindows).Return(true) @@ -765,6 +745,7 @@ func TestBuildAtlasProject(t *testing.T) { featureValidator.EXPECT().FeatureExist(features.ResourceAtlasProject, featureTeams).Return(true) featureValidator.EXPECT().FeatureExist(features.ResourceAtlasProject, featureBCP).Return(true) featureValidator.EXPECT().IsResourceSupported(features.ResourceAtlasPrivateEndpoint).Return(tt.independentResource) + featureValidator.EXPECT().IsResourceSupported(features.ResourceAtlasCustomRole).Return(tt.independentResource) projectResult, err := BuildAtlasProject(&AtlasProjectBuildRequest{ ProjectStore: projectStore, From 6c492cd2150e594c0a71f7ff4d6eb0afabf98e90 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Fri, 20 Dec 2024 22:30:25 +0100 Subject: [PATCH 03/20] Fixed gomod --- go.mod | 4 ++-- go.sum | 2 -- internal/kubernetes/operator/project/customroles.go | 11 +++++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 67d9646e93..5c3fc6c754 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/mholt/archives v0.0.0-20241207175349-5e373c52f8aa github.com/mongodb-forks/digest v1.1.0 github.com/mongodb-labs/cobra2snooty v0.18.2 - github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.1-0.20241125102449-344dbce54e85 + github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0 github.com/pelletier/go-toml v1.9.5 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/shirou/gopsutil/v4 v4.24.11 @@ -42,6 +42,7 @@ require ( github.com/tangzero/inflector v1.0.0 go.mongodb.org/atlas v0.37.0 go.mongodb.org/atlas-sdk/v20240530005 v20240530005.0.0 + go.mongodb.org/atlas-sdk/v20241113001 v20241113001.0.0 go.mongodb.org/atlas-sdk/v20241113004 v20241113004.0.0 go.mongodb.org/mongo-driver v1.17.1 go.opentelemetry.io/otel v1.33.0 @@ -169,7 +170,6 @@ require ( github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.mongodb.org/atlas-sdk/v20231115008 v20231115008.5.0 // indirect - go.mongodb.org/atlas-sdk/v20241113001 v20241113001.0.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect diff --git a/go.sum b/go.sum index d1e8d84035..9cb30bd079 100644 --- a/go.sum +++ b/go.sum @@ -334,8 +334,6 @@ github.com/mongodb-labs/cobra2snooty v0.18.2 h1:qWpLCMWbQb5FSZ5ehiWN2URmieMJhQtQ github.com/mongodb-labs/cobra2snooty v0.18.2/go.mod h1:WnzqCFmx4f72Yj9dL/ulBUqcatfURGdKFf8DLT4h7zQ= github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0 h1:g4pJ13johhJ/oFyyZCXsUGCBNkaLqF1yPl5U6SVP86o= github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.6.0/go.mod h1:qjGZXGzDL73pE9lbqT9SNoaMGi3gKFRuOxjFrPVIFJs= -github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.5.1-0.20241125102449-344dbce54e85 h1:KZDM7F80ELPvgTlVjJhT0tF9cwGzOxsQ7SbBSVQma0c= -github.com/mongodb/mongodb-atlas-kubernetes/v2 v2.5.1-0.20241125102449-344dbce54e85/go.mod h1:PZNJBNKogrgra4TorvasJHE0A6R8COdCT5LVAx6whWw= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= diff --git a/internal/kubernetes/operator/project/customroles.go b/internal/kubernetes/operator/project/customroles.go index 8488cca7f4..f991297ea4 100644 --- a/internal/kubernetes/operator/project/customroles.go +++ b/internal/kubernetes/operator/project/customroles.go @@ -94,14 +94,21 @@ func BuildCustomRoles(provider store.DatabaseRoleLister, request CustomRolesRequ }, } if request.IsIndependent { - akoRole.Spec.ExternalProjectIDRef = &akov2.ExternalProjectReference{ID: request.ProjectID} + akoRole.Spec.ExternalProjectIDRef = &akov2.ExternalProjectReference{ + ID: request.ProjectID, + } + akoRole.Spec.LocalCredentialHolder = akoapi.LocalCredentialHolder{ + ConnectionSecret: &akoapi.LocalObjectReference{ + Name: resources.NormalizeAtlasName(request.Credentials, request.Dict), + }, + } } else { akoRole.Spec.ProjectRef = &akov2common.ResourceRefNamespaced{ Name: request.ProjectName, Namespace: request.TargetNamespace, } } - result = append(result) + result = append(result, akoRole) } return result, nil } From 176ec77edfb95ef1b2ff5753f0321c8c28fb689a Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Fri, 20 Dec 2024 22:31:29 +0100 Subject: [PATCH 04/20] Fixed local creds --- internal/kubernetes/operator/project/customroles.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/kubernetes/operator/project/customroles.go b/internal/kubernetes/operator/project/customroles.go index f991297ea4..6792d8635f 100644 --- a/internal/kubernetes/operator/project/customroles.go +++ b/internal/kubernetes/operator/project/customroles.go @@ -83,11 +83,6 @@ func BuildCustomRoles(provider store.DatabaseRoleLister, request CustomRolesRequ InheritedRoles: inhRoles, Actions: actions, }, - LocalCredentialHolder: akoapi.LocalCredentialHolder{ - ConnectionSecret: &akoapi.LocalObjectReference{ - Name: resources.NormalizeAtlasName(request.Credentials, request.Dict), - }, - }, }, Status: akov2status.AtlasCustomRoleStatus{ Common: akoapi.Common{Conditions: []akoapi.Condition{}}, From c76539aae39fa0aed0cfca82d7b49c62dd96749f Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Fri, 20 Dec 2024 23:12:47 +0100 Subject: [PATCH 05/20] Fixed package naming --- build/ci/library_owners.json | 123 +++++++++--------- go.mod | 2 +- .../operator/project/customroles_test.go | 20 +-- 3 files changed, 73 insertions(+), 72 deletions(-) diff --git a/build/ci/library_owners.json b/build/ci/library_owners.json index c4513c83ae..98b47dd684 100644 --- a/build/ci/library_owners.json +++ b/build/ci/library_owners.json @@ -1,63 +1,64 @@ { - "cloud.google.com/go/kms": "apix-2", - "github.com/AlecAivazis/survey/v2": "apix-2", - "github.com/Azure/azure-sdk-for-go/sdk/azcore": "apix-2", - "github.com/Azure/azure-sdk-for-go/sdk/azidentity": "apix-2", - "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys": "apix-2", - "github.com/Masterminds/semver/v3": "apix-2", - "github.com/PaesslerAG/jsonpath": "apix-2", - "github.com/aws/aws-sdk-go-v2": "apix-2", - "github.com/aws/aws-sdk-go-v2/config": "apix-2", - "github.com/aws/aws-sdk-go-v2/credentials": "apix-2", - "github.com/aws/aws-sdk-go-v2/service/kms": "apix-2", - "github.com/briandowns/spinner": "apix-2", - "github.com/evergreen-ci/shrub": "apix-2", - "github.com/go-test/deep": "apix-2", - "github.com/golang-jwt/jwt/v4": "apix-2", - "github.com/golang/mock": "apix-2", - "github.com/google/go-github/v61": "apix-2", - "github.com/google/uuid": "atlas_kubernetes_team", - "github.com/klauspost/compress": "apix-2", - "github.com/mattn/go-isatty": "apix-2", - "github.com/mongodb-forks/digest": "apix-2", - "github.com/mongodb-labs/cobra2snooty": "apix-2", - "github.com/pelletier/go-toml": "apix-2", - "github.com/Netflix/go-expect": "apix-2", - "github.com/creack/pty": "apix-2", - "github.com/hinshun/vt10x": "apix-2", - "github.com/pkg/browser": "apix-2", - "github.com/spf13/afero": "apix-2", - "github.com/spf13/cobra": "apix-2", - "github.com/spf13/pflag": "apix-2", - "github.com/spf13/viper": "apix-2", - "github.com/stretchr/testify": "apix-2", - "github.com/tangzero/inflector": "apix-2", - "go.mongodb.org/atlas": "apix-2", - "go.mongodb.org/atlas-sdk/v20241113004": "apix-2", - "go.mongodb.org/atlas-sdk/v20240530005": "apix-2", - "go.mongodb.org/mongo-driver": "apix-2", - "golang.org/x/sys": "apix-2", - "golang.org/x/tools": "apix-2", - "google.golang.org/api": "apix-2", - "google.golang.org/protobuf": "apix-2", - "golang.org/x/mod": "apix-2", - "gopkg.in/yaml.v3": "apix-2", - "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", - "sigs.k8s.io/controller-runtime": "atlas_kubernetes_team", - "sigs.k8s.io/kind": "atlas_kubernetes_team", - "golang.org/x/exp": "atlas_kubernetes_team", - "github.com/denisbrodbeck/machineid": "apix-2", - "github.com/shirou/gopsutil/v4": "apix-2", - "go.opentelemetry.io/otel": "apix-2", - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc": "apix-2", - "go.opentelemetry.io/otel/sdk": "apix-2", - "go.opentelemetry.io/otel/trace": "apix-2", - "google.golang.org/grpc": "apix-2", - "github.com/mholt/archives": "apix-2" + "cloud.google.com/go/kms": "apix-2", + "github.com/AlecAivazis/survey/v2": "apix-2", + "github.com/Azure/azure-sdk-for-go/sdk/azcore": "apix-2", + "github.com/Azure/azure-sdk-for-go/sdk/azidentity": "apix-2", + "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys": "apix-2", + "github.com/Masterminds/semver/v3": "apix-2", + "github.com/PaesslerAG/jsonpath": "apix-2", + "github.com/aws/aws-sdk-go-v2": "apix-2", + "github.com/aws/aws-sdk-go-v2/config": "apix-2", + "github.com/aws/aws-sdk-go-v2/credentials": "apix-2", + "github.com/aws/aws-sdk-go-v2/service/kms": "apix-2", + "github.com/briandowns/spinner": "apix-2", + "github.com/evergreen-ci/shrub": "apix-2", + "github.com/go-test/deep": "apix-2", + "github.com/golang-jwt/jwt/v4": "apix-2", + "github.com/golang/mock": "apix-2", + "github.com/google/go-github/v61": "apix-2", + "github.com/google/uuid": "atlas_kubernetes_team", + "github.com/klauspost/compress": "apix-2", + "github.com/mattn/go-isatty": "apix-2", + "github.com/mongodb-forks/digest": "apix-2", + "github.com/mongodb-labs/cobra2snooty": "apix-2", + "github.com/pelletier/go-toml": "apix-2", + "github.com/Netflix/go-expect": "apix-2", + "github.com/creack/pty": "apix-2", + "github.com/hinshun/vt10x": "apix-2", + "github.com/pkg/browser": "apix-2", + "github.com/spf13/afero": "apix-2", + "github.com/spf13/cobra": "apix-2", + "github.com/spf13/pflag": "apix-2", + "github.com/spf13/viper": "apix-2", + "github.com/stretchr/testify": "apix-2", + "github.com/tangzero/inflector": "apix-2", + "go.mongodb.org/atlas": "apix-2", + "go.mongodb.org/atlas-sdk/v20241113004": "apix-2", + "go.mongodb.org/atlas-sdk/v20240530005": "apix-2", + "go.mongodb.org/atlas-sdk/v20241113001": "apix-2", + "go.mongodb.org/mongo-driver": "apix-2", + "golang.org/x/sys": "apix-2", + "golang.org/x/tools": "apix-2", + "google.golang.org/api": "apix-2", + "google.golang.org/protobuf": "apix-2", + "golang.org/x/mod": "apix-2", + "gopkg.in/yaml.v3": "apix-2", + "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", + "sigs.k8s.io/controller-runtime": "atlas_kubernetes_team", + "sigs.k8s.io/kind": "atlas_kubernetes_team", + "golang.org/x/exp": "atlas_kubernetes_team", + "github.com/denisbrodbeck/machineid": "apix-2", + "github.com/shirou/gopsutil/v4": "apix-2", + "go.opentelemetry.io/otel": "apix-2", + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc": "apix-2", + "go.opentelemetry.io/otel/sdk": "apix-2", + "go.opentelemetry.io/otel/trace": "apix-2", + "google.golang.org/grpc": "apix-2", + "github.com/mholt/archives": "apix-2" } diff --git a/go.mod b/go.mod index 5c3fc6c754..a87df4192f 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,6 @@ require ( github.com/tangzero/inflector v1.0.0 go.mongodb.org/atlas v0.37.0 go.mongodb.org/atlas-sdk/v20240530005 v20240530005.0.0 - go.mongodb.org/atlas-sdk/v20241113001 v20241113001.0.0 go.mongodb.org/atlas-sdk/v20241113004 v20241113004.0.0 go.mongodb.org/mongo-driver v1.17.1 go.opentelemetry.io/otel v1.33.0 @@ -170,6 +169,7 @@ require ( github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.mongodb.org/atlas-sdk/v20231115008 v20231115008.5.0 // indirect + go.mongodb.org/atlas-sdk/v20241113001 v20241113001.0.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go index b09a535740..441acf3c32 100644 --- a/internal/kubernetes/operator/project/customroles_test.go +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -13,7 +13,7 @@ import ( 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" - "go.mongodb.org/atlas-sdk/v20241113001/admin" + atlasv2 "go.mongodb.org/atlas-sdk/v20241113004/admin" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" ) @@ -30,7 +30,7 @@ func TestBuildCustomRoles(t *testing.T) { tests := []struct { name string args args - rolesInAtlas []admin.UserCustomDBRole + rolesInAtlas []atlasv2.UserCustomDBRole errInAtlas error want []akov2.AtlasCustomRole wantErr assert.ErrorAssertionFunc @@ -87,12 +87,12 @@ func TestBuildCustomRoles(t *testing.T) { Dict: resources.AtlasNameToKubernetesName(), }, }, - rolesInAtlas: []admin.UserCustomDBRole{ + rolesInAtlas: []atlasv2.UserCustomDBRole{ { - Actions: &([]admin.DatabasePrivilegeAction{ + Actions: &([]atlasv2.DatabasePrivilegeAction{ { Action: "test", - Resources: &([]admin.DatabasePermittedNamespaceResource{ + Resources: &([]atlasv2.DatabasePermittedNamespaceResource{ { Cluster: false, Collection: "c-1", @@ -101,7 +101,7 @@ func TestBuildCustomRoles(t *testing.T) { }), }, }), - InheritedRoles: &([]admin.DatabaseInheritedRole{ + InheritedRoles: &([]atlasv2.DatabaseInheritedRole{ { Db: "d-1", Role: "ADMIN", @@ -171,12 +171,12 @@ func TestBuildCustomRoles(t *testing.T) { Dict: resources.AtlasNameToKubernetesName(), }, }, - rolesInAtlas: []admin.UserCustomDBRole{ + rolesInAtlas: []atlasv2.UserCustomDBRole{ { - Actions: &([]admin.DatabasePrivilegeAction{ + Actions: &([]atlasv2.DatabasePrivilegeAction{ { Action: "test", - Resources: &([]admin.DatabasePermittedNamespaceResource{ + Resources: &([]atlasv2.DatabasePermittedNamespaceResource{ { Cluster: false, Collection: "c-1", @@ -185,7 +185,7 @@ func TestBuildCustomRoles(t *testing.T) { }), }, }), - InheritedRoles: &([]admin.DatabaseInheritedRole{ + InheritedRoles: &([]atlasv2.DatabaseInheritedRole{ { Db: "d-1", Role: "ADMIN", From 312b39f45f15953b2f900b0cab407268706f3ee6 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 23 Dec 2024 15:22:01 +0100 Subject: [PATCH 06/20] Removed merged leftovers --- test/e2e/atlas/kubernetes_config_generate_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 299feb5846..b22652c986 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -163,7 +163,6 @@ func TestExportIndependentOrNot(t *testing.T) { testPrefix := "test-" generator.generateDBUser(testPrefix) generator.generateCluster() - generator.generateAWSPrivateEndpoint("eu-central-1") expectAlertConfigs := true dictionary := resources.AtlasNameToKubernetesName() credentialName := resources.NormalizeAtlasName(generator.projectName+credSuffixTest, dictionary) @@ -189,7 +188,6 @@ func TestExportIndependentOrNot(t *testing.T) { expected: []runtime.Object{ defaultTestProject(generator.projectName, "", expectedLabels, expectAlertConfigs, nil), defaultTestAtlasConnSecret(credentialName, ""), - expectedPrivateEndpoint, defaultTestUserWithID(generator.dbUser, generator.projectName, generator.projectID, "", credentialName), defaultM0TestClusterWithID( generator.clusterName, generator.clusterRegion, generator.projectName, generator.projectID, "", From bf39b761c43389d318322bcd00081a5d6a67d10a Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 23 Dec 2024 15:25:36 +0100 Subject: [PATCH 07/20] Added missing licences --- .../kubernetes/operator/project/customroles.go | 14 ++++++++++++++ .../operator/project/customroles_test.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/kubernetes/operator/project/customroles.go b/internal/kubernetes/operator/project/customroles.go index 6792d8635f..b2f65777fb 100644 --- a/internal/kubernetes/operator/project/customroles.go +++ b/internal/kubernetes/operator/project/customroles.go @@ -1,3 +1,17 @@ +// Copyright 2024 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package project import ( diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go index 441acf3c32..7a8afbdcca 100644 --- a/internal/kubernetes/operator/project/customroles_test.go +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -1,3 +1,17 @@ +// Copyright 2024 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package project import ( From d8cac4e7d426ff53bd47001b4dc9da3e2ea6b74f Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 23 Dec 2024 15:36:09 +0100 Subject: [PATCH 08/20] Fix linter --- internal/kubernetes/operator/config_exporter.go | 1 + .../kubernetes/operator/project/customroles.go | 1 + .../operator/project/customroles_test.go | 15 ++++++++------- internal/kubernetes/operator/project/project.go | 1 + 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/internal/kubernetes/operator/config_exporter.go b/internal/kubernetes/operator/config_exporter.go index 5410947c0b..ef1c047e84 100644 --- a/internal/kubernetes/operator/config_exporter.go +++ b/internal/kubernetes/operator/config_exporter.go @@ -124,6 +124,7 @@ func (e *ConfigExporter) WithIndependentResources(enabled bool) *ConfigExporter return e } +//nolint:gocyclo func (e *ConfigExporter) Run() (string, error) { // TODO: Add REST to OPERATOR entities matcher output := bytes.NewBufferString(yamlSeparator) diff --git a/internal/kubernetes/operator/project/customroles.go b/internal/kubernetes/operator/project/customroles.go index b2f65777fb..b36760c7b2 100644 --- a/internal/kubernetes/operator/project/customroles.go +++ b/internal/kubernetes/operator/project/customroles.go @@ -16,6 +16,7 @@ package project import ( "fmt" + "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/resources" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/pointer" diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go index 7a8afbdcca..508a88361b 100644 --- a/internal/kubernetes/operator/project/customroles_test.go +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -17,6 +17,8 @@ package project import ( "errors" "fmt" + "testing" + "github.com/golang/mock/gomock" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/features" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/kubernetes/operator/resources" @@ -29,7 +31,6 @@ import ( "github.com/stretchr/testify/assert" atlasv2 "go.mongodb.org/atlas-sdk/v20241113004/admin" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" ) func TestBuildCustomRoles(t *testing.T) { @@ -64,7 +65,7 @@ func TestBuildCustomRoles(t *testing.T) { }, errInAtlas: errors.New("no roles found"), want: nil, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + wantErr: func(t assert.TestingT, err error, i ...any) bool { return true }, }, @@ -84,7 +85,7 @@ func TestBuildCustomRoles(t *testing.T) { rolesInAtlas: nil, errInAtlas: nil, want: nil, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + wantErr: func(t assert.TestingT, err error, i ...any) bool { return false }, }, @@ -132,7 +133,7 @@ func TestBuildCustomRoles(t *testing.T) { APIVersion: "atlas.mongodb.com/v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-custom-role-r-1", projectName), + Name: projectName + "%-custom-role-r-1", Namespace: targetNamespace, Labels: map[string]string{ features.ResourceVersion: "v2.6.0", @@ -168,7 +169,7 @@ func TestBuildCustomRoles(t *testing.T) { Status: akov2status.AtlasCustomRoleStatus{}, }, }, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + wantErr: func(t assert.TestingT, err error, i ...any) bool { return false }, }, @@ -216,7 +217,7 @@ func TestBuildCustomRoles(t *testing.T) { APIVersion: "atlas.mongodb.com/v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-custom-role-r-1", projectName), + Name: projectName + "%-custom-role-r-1", Namespace: targetNamespace, Labels: map[string]string{ features.ResourceVersion: "v2.6.0", @@ -249,7 +250,7 @@ func TestBuildCustomRoles(t *testing.T) { Status: akov2status.AtlasCustomRoleStatus{}, }, }, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + wantErr: func(t assert.TestingT, err error, i ...any) bool { return false }, }, diff --git a/internal/kubernetes/operator/project/project.go b/internal/kubernetes/operator/project/project.go index 3c763e1964..9142e9856c 100644 --- a/internal/kubernetes/operator/project/project.go +++ b/internal/kubernetes/operator/project/project.go @@ -275,6 +275,7 @@ func BuildProjectNamedConnectionSecret(credsProvider store.CredentialsGetter, na return secret } +//nolint:revive func buildCustomRoles(crProvider store.DatabaseRoleLister, projectID string) ([]akov2.CustomRole, error) { dbRoles, err := crProvider.DatabaseRoles(projectID) if err != nil { From c2bc67500aeba1a0013e2cdc0b8d4bf094558d5a Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 23 Dec 2024 15:45:45 +0100 Subject: [PATCH 09/20] Fixed linter again --- internal/kubernetes/operator/config_exporter.go | 3 +-- internal/kubernetes/operator/project/customroles_test.go | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/kubernetes/operator/config_exporter.go b/internal/kubernetes/operator/config_exporter.go index ef1c047e84..f28ad519dc 100644 --- a/internal/kubernetes/operator/config_exporter.go +++ b/internal/kubernetes/operator/config_exporter.go @@ -123,8 +123,6 @@ func (e *ConfigExporter) WithIndependentResources(enabled bool) *ConfigExporter e.independentResources = enabled return e } - -//nolint:gocyclo func (e *ConfigExporter) Run() (string, error) { // TODO: Add REST to OPERATOR entities matcher output := bytes.NewBufferString(yamlSeparator) @@ -185,6 +183,7 @@ func (e *ConfigExporter) Run() (string, error) { return output.String(), nil } +// nolint:gocyclo func (e *ConfigExporter) exportProject() ([]runtime.Object, string, error) { atlasProject, err := e.dataProvider.Project(e.projectID) if err != nil { diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go index 508a88361b..64c78e087a 100644 --- a/internal/kubernetes/operator/project/customroles_test.go +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -65,7 +65,7 @@ func TestBuildCustomRoles(t *testing.T) { }, errInAtlas: errors.New("no roles found"), want: nil, - wantErr: func(t assert.TestingT, err error, i ...any) bool { + wantErr: func(_ assert.TestingT, err error, i ...any) bool { return true }, }, @@ -85,7 +85,7 @@ func TestBuildCustomRoles(t *testing.T) { rolesInAtlas: nil, errInAtlas: nil, want: nil, - wantErr: func(t assert.TestingT, err error, i ...any) bool { + wantErr: func(_ assert.TestingT, err error, i ...any) bool { return false }, }, @@ -169,7 +169,7 @@ func TestBuildCustomRoles(t *testing.T) { Status: akov2status.AtlasCustomRoleStatus{}, }, }, - wantErr: func(t assert.TestingT, err error, i ...any) bool { + wantErr: func(_ assert.TestingT, err error, i ...any) bool { return false }, }, From 952c7465b5aa16a8e4c870b27ff7262909072d4a Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Mon, 23 Dec 2024 15:50:11 +0100 Subject: [PATCH 10/20] Disabled linter for unit-test --- internal/kubernetes/operator/config_exporter.go | 2 +- internal/kubernetes/operator/project/customroles_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/kubernetes/operator/config_exporter.go b/internal/kubernetes/operator/config_exporter.go index f28ad519dc..c4cf7336eb 100644 --- a/internal/kubernetes/operator/config_exporter.go +++ b/internal/kubernetes/operator/config_exporter.go @@ -183,7 +183,7 @@ func (e *ConfigExporter) Run() (string, error) { return output.String(), nil } -// nolint:gocyclo +//nolint:gocyclo func (e *ConfigExporter) exportProject() ([]runtime.Object, string, error) { atlasProject, err := e.dataProvider.Project(e.projectID) if err != nil { diff --git a/internal/kubernetes/operator/project/customroles_test.go b/internal/kubernetes/operator/project/customroles_test.go index 64c78e087a..593b0eadc6 100644 --- a/internal/kubernetes/operator/project/customroles_test.go +++ b/internal/kubernetes/operator/project/customroles_test.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//nolint:all package project import ( From 6df7f8c8f59dfb8f32b5ee7da0c3b4724a418a1c Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Tue, 24 Dec 2024 16:19:46 +0100 Subject: [PATCH 11/20] Fixed e2e test --- .../atlas/kubernetes_config_generate_test.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index b22652c986..93c8ba913f 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1087,10 +1087,51 @@ func TestProjectWithCustomRole(t *testing.T) { objects, err = getK8SEntities(resp) require.NoError(t, err, "should not fail on decode") require.NotEmpty(t, objects) + expectedProject.Spec.CustomRoles = nil + verifyCustomRoles(t, objects, []akov2.AtlasCustomRole{ + { + TypeMeta: metav1.TypeMeta{ + Kind: "AtlasCustomRole", + APIVersion: "atlas.mongodb.com/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), + }, + Spec: akov2.AtlasCustomRoleSpec{ + Role: akov2.CustomRole{ + Name: "test-role", + Actions: []akov2.Action{ + { + Name: "FIND", + Resources: []akov2.Resource{ + { + Database: pointer.Get("test-db "), + Collection: pointer.Get(""), + Cluster: pointer.Get(false), + }, + }, + }, + }, + }, + }, + Status: akov2status.AtlasCustomRoleStatus{}, + }, + }) checkProject(t, objects, expectedProject) }) } +func verifyCustomRoles(t *testing.T, objects []runtime.Object, expectedRoles []akov2.AtlasCustomRole) { + var roles []*akov2.CustomRole + for i := range objects { + d, ok := objects[i].(*akov2.AtlasCustomRole) + if ok { + roles = append(roles, d) + } + } + assert.ElementsMatch(t, expectedRoles, roles) +} + func TestProjectWithIntegration(t *testing.T) { s := InitialSetup(t) cliPath := s.cliPath From ca2e75604f2c07a875e327aab4cb55fdfbd28430 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Tue, 24 Dec 2024 16:27:25 +0100 Subject: [PATCH 12/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 93c8ba913f..04126c682e 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1122,7 +1122,7 @@ func TestProjectWithCustomRole(t *testing.T) { } func verifyCustomRoles(t *testing.T, objects []runtime.Object, expectedRoles []akov2.AtlasCustomRole) { - var roles []*akov2.CustomRole + var roles []*akov2.AtlasCustomRole for i := range objects { d, ok := objects[i].(*akov2.AtlasCustomRole) if ok { From 9d6e396765a0a4a437a22410ab0e9ffc59c89a99 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Tue, 24 Dec 2024 16:32:28 +0100 Subject: [PATCH 13/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 04126c682e..ad2cb300af 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1122,6 +1122,7 @@ func TestProjectWithCustomRole(t *testing.T) { } func verifyCustomRoles(t *testing.T, objects []runtime.Object, expectedRoles []akov2.AtlasCustomRole) { + t.Helper() var roles []*akov2.AtlasCustomRole for i := range objects { d, ok := objects[i].(*akov2.AtlasCustomRole) From a964f90604656e69210d3756253061ed21160603 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Tue, 24 Dec 2024 23:14:38 +0100 Subject: [PATCH 14/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index ad2cb300af..063994a3b4 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1095,7 +1095,8 @@ func TestProjectWithCustomRole(t *testing.T) { APIVersion: "atlas.mongodb.com/v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), resources.AtlasNameToKubernetesName()), + Namespace: expectedProject.Namespace, }, Spec: akov2.AtlasCustomRoleSpec{ Role: akov2.CustomRole{ From dd5e0a58efad96467223c88b7c9c89ebbfc28afa Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 25 Dec 2024 18:29:18 +0100 Subject: [PATCH 15/20] Fixed e2e test --- .../atlas/kubernetes_config_generate_test.go | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 063994a3b4..e1d5516218 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1088,50 +1088,50 @@ func TestProjectWithCustomRole(t *testing.T) { require.NoError(t, err, "should not fail on decode") require.NotEmpty(t, objects) expectedProject.Spec.CustomRoles = nil - verifyCustomRoles(t, objects, []akov2.AtlasCustomRole{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "AtlasCustomRole", - APIVersion: "atlas.mongodb.com/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), resources.AtlasNameToKubernetesName()), - Namespace: expectedProject.Namespace, - }, - Spec: akov2.AtlasCustomRoleSpec{ - Role: akov2.CustomRole{ - Name: "test-role", - Actions: []akov2.Action{ - { - Name: "FIND", - Resources: []akov2.Resource{ - { - Database: pointer.Get("test-db "), - Collection: pointer.Get(""), - Cluster: pointer.Get(false), - }, + verifyCustomRole(t, objects, akov2.AtlasCustomRole{ + TypeMeta: metav1.TypeMeta{ + Kind: "AtlasCustomRole", + APIVersion: "atlas.mongodb.com/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), resources.AtlasNameToKubernetesName()), + Namespace: expectedProject.Namespace, + }, + Spec: akov2.AtlasCustomRoleSpec{ + Role: akov2.CustomRole{ + Name: "test-role", + Actions: []akov2.Action{ + { + Name: "FIND", + Resources: []akov2.Resource{ + { + Database: pointer.Get("test-db"), + Collection: pointer.Get(""), + Cluster: pointer.Get(false), }, }, }, }, }, - Status: akov2status.AtlasCustomRoleStatus{}, }, - }) + Status: akov2status.AtlasCustomRoleStatus{}, + }, + ) checkProject(t, objects, expectedProject) }) } -func verifyCustomRoles(t *testing.T, objects []runtime.Object, expectedRoles []akov2.AtlasCustomRole) { +func verifyCustomRole(t *testing.T, objects []runtime.Object, expectedRole akov2.AtlasCustomRole) { t.Helper() - var roles []*akov2.AtlasCustomRole + var role *akov2.AtlasCustomRole for i := range objects { d, ok := objects[i].(*akov2.AtlasCustomRole) if ok { - roles = append(roles, d) + role = d + break } } - assert.ElementsMatch(t, expectedRoles, roles) + assert.Equal(t, &role, expectedRole) } func TestProjectWithIntegration(t *testing.T) { From 0c69652d163d010b3b05bc930e524c8a29c75938 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 25 Dec 2024 18:50:56 +0100 Subject: [PATCH 16/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index e1d5516218..1cee7d347b 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1131,7 +1131,7 @@ func verifyCustomRole(t *testing.T, objects []runtime.Object, expectedRole akov2 break } } - assert.Equal(t, &role, expectedRole) + assert.Equal(t, expectedRole, &role) } func TestProjectWithIntegration(t *testing.T) { From 124563021ae60405ea7336220b53db95cff110a3 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 25 Dec 2024 22:24:51 +0100 Subject: [PATCH 17/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 1cee7d347b..8976ce31cf 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1088,7 +1088,7 @@ func TestProjectWithCustomRole(t *testing.T) { require.NoError(t, err, "should not fail on decode") require.NotEmpty(t, objects) expectedProject.Spec.CustomRoles = nil - verifyCustomRole(t, objects, akov2.AtlasCustomRole{ + verifyCustomRole(t, objects, &akov2.AtlasCustomRole{ TypeMeta: metav1.TypeMeta{ Kind: "AtlasCustomRole", APIVersion: "atlas.mongodb.com/v1", @@ -1121,7 +1121,7 @@ func TestProjectWithCustomRole(t *testing.T) { }) } -func verifyCustomRole(t *testing.T, objects []runtime.Object, expectedRole akov2.AtlasCustomRole) { +func verifyCustomRole(t *testing.T, objects []runtime.Object, expectedRole *akov2.AtlasCustomRole) { t.Helper() var role *akov2.AtlasCustomRole for i := range objects { @@ -1131,7 +1131,7 @@ func verifyCustomRole(t *testing.T, objects []runtime.Object, expectedRole akov2 break } } - assert.Equal(t, expectedRole, &role) + assert.Equal(t, expectedRole, role) } func TestProjectWithIntegration(t *testing.T) { From abc9da5d59d79908a04dbcc80760266d14995fd1 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Wed, 25 Dec 2024 23:06:06 +0100 Subject: [PATCH 18/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 8976ce31cf..f89c3839cc 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1042,7 +1042,7 @@ func TestProjectWithCustomRole(t *testing.T) { Name: "FIND", Resources: []akov2.Resource{ { - Database: pointer.Get("test-db "), + Database: pointer.Get("test-db"), Collection: pointer.Get(""), Cluster: pointer.Get(false), }, @@ -1096,8 +1096,15 @@ func TestProjectWithCustomRole(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: resources.NormalizeAtlasName(fmt.Sprintf("%s-custom-role-%s", expectedProject.Name, newCustomRole.Name), resources.AtlasNameToKubernetesName()), Namespace: expectedProject.Namespace, + Labels: map[string]string{ + "mongodb.com/atlas-resource-version": features.LatestOperatorMajorVersion, + }, }, Spec: akov2.AtlasCustomRoleSpec{ + ProjectRef: &akov2common.ResourceRefNamespaced{ + Name: expectedProject.Name, + Namespace: expectedProject.Namespace, + } Role: akov2.CustomRole{ Name: "test-role", Actions: []akov2.Action{ @@ -1114,7 +1121,9 @@ func TestProjectWithCustomRole(t *testing.T) { }, }, }, - Status: akov2status.AtlasCustomRoleStatus{}, + Status: akov2status.AtlasCustomRoleStatus{ + Conditions: []akoapi.Condition{}, + }, }, ) checkProject(t, objects, expectedProject) From af01aa8a6df0a0b64fdeaf104761e45e938e4139 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Thu, 26 Dec 2024 09:55:13 +0100 Subject: [PATCH 19/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index f89c3839cc..9768710719 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1104,7 +1104,7 @@ func TestProjectWithCustomRole(t *testing.T) { ProjectRef: &akov2common.ResourceRefNamespaced{ Name: expectedProject.Name, Namespace: expectedProject.Namespace, - } + }, Role: akov2.CustomRole{ Name: "test-role", Actions: []akov2.Action{ From 065ca220d247149bebf9743882d78b06e5bc2035 Mon Sep 17 00:00:00 2001 From: Igor Karpukhin Date: Thu, 26 Dec 2024 10:36:21 +0100 Subject: [PATCH 20/20] Fixed e2e test --- test/e2e/atlas/kubernetes_config_generate_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/atlas/kubernetes_config_generate_test.go b/test/e2e/atlas/kubernetes_config_generate_test.go index 9768710719..25e28e1875 100644 --- a/test/e2e/atlas/kubernetes_config_generate_test.go +++ b/test/e2e/atlas/kubernetes_config_generate_test.go @@ -1122,7 +1122,9 @@ func TestProjectWithCustomRole(t *testing.T) { }, }, Status: akov2status.AtlasCustomRoleStatus{ - Conditions: []akoapi.Condition{}, + Common: akoapi.Common{ + Conditions: []akoapi.Condition{}, + }, }, }, )