Skip to content

CLOUDP-314917 CLOUDP-314918 CLOUDP-314919 - Add ClusterMongoDBRole CRD #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jun 18, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .evergreen-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ tasks:
commands:
- func: "e2e_test"

- name: e2e_mongodb_custom_roles
tags: [ "patch-run" ]
commands:
- func: "e2e_test"

- name: e2e_replica_set_recovery
tags: [ "patch-run" ]
commands:
Expand Down Expand Up @@ -644,7 +649,7 @@ tasks:
commands:
- func: "e2e_test"

- name: e2e_replica_set_custom_roles
- name: e2e_replica_set_ldap_custom_roles
tags: [ "patch-run" ]
commands:
- func: "e2e_test"
Expand Down
3 changes: 2 additions & 1 deletion .evergreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ task_groups:
- e2e_replica_set_ldap_user_to_dn_mapping
# e2e_replica_set_ldap_agent_auth
- e2e_replica_set_ldap_agent_client_certs
- e2e_replica_set_custom_roles
- e2e_replica_set_ldap_custom_roles
- e2e_replica_set_update_roles_no_privileges
- e2e_replica_set_ldap_group_dn
- e2e_replica_set_ldap_group_dn_with_x509_agent
Expand Down Expand Up @@ -911,6 +911,7 @@ task_groups:
- e2e_tls_x509_configure_all_options_sc
- e2e_tls_x509_sc
- e2e_meko_mck_upgrade
- e2e_mongodb_custom_roles
- e2e_sharded_cluster_oidc_m2m_group
- e2e_sharded_cluster_oidc_m2m_user
- e2e_multi_cluster_oidc_m2m_group
Expand Down
22 changes: 18 additions & 4 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Code generated by tool. DO NOT EDIT.
# This file is used to track the info used to scaffold your project
# and allow the plugins properly work.
# More info: https://book.kubebuilder.io/reference/project-config.html
domain: mongodb.com
layout: go.kubebuilder.io/v3
layout:
- go.kubebuilder.io/v3
plugins:
manifests.sdk.operatorframework.io/v2: {}
scorecard.sdk.operatorframework.io/v2: {}
projectName: mongodb-kubernetes
repo: github.com/mongodb/mongodb-kubernetes
resources:
Expand Down Expand Up @@ -30,7 +38,13 @@ resources:
kind: MongoDBUser
path: github.com/mongodb/mongodb-kubernetes/api/v1
version: v1
- api:
crdVersion: v1
namespaced: false
controller: false
domain: mongodb.com
group: mongodb
kind: ClusterMongoDBRole
path: github.com/mongodb/mongodb-kubernetes/api/v1
version: v1
version: "3"
plugins:
manifests.sdk.operatorframework.io/v2: {}
scorecard.sdk.operatorframework.io/v2: {}
6 changes: 3 additions & 3 deletions api/v1/mdb/mongodb_roles_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func isValidCIDR(cidr string) bool {
return err == nil
}

func roleIsCorrectlyConfigured(role MongoDbRole, mdbVersion string) v1.ValidationResult {
func RoleIsCorrectlyConfigured(role MongoDBRole, mdbVersion string) v1.ValidationResult {
// Extensive validation of the roles attribute

if role.Role == "" {
Expand Down Expand Up @@ -305,10 +305,10 @@ func roleIsCorrectlyConfigured(role MongoDbRole, mdbVersion string) v1.Validatio
return v1.ValidationSuccess()
}

func rolesAttributeisCorrectlyConfigured(d DbCommonSpec) v1.ValidationResult {
func rolesAttributeIsCorrectlyConfigured(d DbCommonSpec) v1.ValidationResult {
// Validate every single entry and return error on the first one that fails validation
for _, role := range d.Security.Roles {
if res := roleIsCorrectlyConfigured(role, d.Version); res.Level == v1.ErrorLevel {
if res := RoleIsCorrectlyConfigured(role, d.Version); res.Level == v1.ErrorLevel {
return v1.ValidationError("Error validating role - %s", res.Msg)
}
}
Expand Down
24 changes: 21 additions & 3 deletions api/v1/mdb/mongodb_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,10 +742,16 @@ type SharedConnectionSpec struct {
CloudManagerConfig *PrivateCloudConfig `json:"cloudManager,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="!(has(self.roles) && has(self.roleRefs)) || !(self.roles.size() > 0 && self.roleRefs.size() > 0)",message="At most one of roles or roleRefs can be non-empty"
type Security struct {
TLSConfig *TLSConfig `json:"tls,omitempty"`
Authentication *Authentication `json:"authentication,omitempty"`
Roles []MongoDbRole `json:"roles,omitempty"`

// +optional
Roles []MongoDBRole `json:"roles,omitempty"`

// +optional
RoleRefs []MongoDBRoleRef `json:"roleRefs,omitempty"`

// +optional
CertificatesSecretsPrefix string `json:"certsSecretPrefix"`
Expand Down Expand Up @@ -973,7 +979,16 @@ type InheritedRole struct {
Role string `json:"role"`
}

type MongoDbRole struct {
type MongoDBRoleRef struct {
// +kubebuilder:validation:Required
Name string `json:"name"`

// +kubebuilder:validation:Enum=ClusterMongoDBRole
// +kubebuilder:validation:Required
Kind string `json:"kind"`
}

type MongoDBRole struct {
Role string `json:"role"`
AuthenticationRestrictions []AuthenticationRestriction `json:"authenticationRestrictions,omitempty"`
Db string `json:"db"`
Expand Down Expand Up @@ -1607,7 +1622,10 @@ func EnsureSecurity(sec *Security) *Security {
sec.TLSConfig = &TLSConfig{}
}
if sec.Roles == nil {
sec.Roles = make([]MongoDbRole, 0)
sec.Roles = make([]MongoDBRole, 0)
}
if sec.RoleRefs == nil {
sec.RoleRefs = make([]MongoDBRoleRef, 0)
}
return sec
}
Expand Down
2 changes: 1 addition & 1 deletion api/v1/mdb/mongodb_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ func CommonValidators(db DbCommonSpec) []func(d DbCommonSpec) v1.ValidationResul
deploymentsMustHaveAgentModeInAuthModes,
scramSha1AuthValidation,
ldapAuthRequiresEnterprise,
rolesAttributeisCorrectlyConfigured,
rolesAttributeIsCorrectlyConfigured,
agentModeIsSetIfMoreThanADeploymentAuthModeIsSet,
ldapGroupDnIsSetIfLdapAuthzIsEnabledAndAgentsAreExternal,
specWithExactlyOneSchema,
Expand Down
16 changes: 16 additions & 0 deletions api/v1/mdb/mongodbbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ func (b *MongoDBBuilder) SetSecurityTLSEnabled() *MongoDBBuilder {
return b
}

func (b *MongoDBBuilder) SetRoles(roles []MongoDBRole) *MongoDBBuilder {
if b.mdb.Spec.Security == nil {
b.mdb.Spec.Security = &Security{}
}
b.mdb.Spec.Security.Roles = roles
return b
}

func (b *MongoDBBuilder) SetRoleRefs(roleRefs []MongoDBRoleRef) *MongoDBBuilder {
if b.mdb.Spec.Security == nil {
b.mdb.Spec.Security = &Security{}
}
b.mdb.Spec.Security.RoleRefs = roleRefs
return b
}

func (b *MongoDBBuilder) SetLabels(labels map[string]string) *MongoDBBuilder {
b.mdb.Labels = labels
return b
Expand Down
74 changes: 47 additions & 27 deletions api/v1/mdb/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion api/v1/mdbmulti/mongodbmultibuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func DefaultMultiReplicaSetBuilder() *MultiReplicaSetBuilder {
Authentication: &mdbv1.Authentication{
Modes: []mdbv1.AuthMode{},
},
Roles: []mdbv1.MongoDbRole{},
Roles: []mdbv1.MongoDBRole{},
},
DuplicateServiceObjects: util.BooleanRef(false),
},
Expand All @@ -73,6 +73,14 @@ func (m *MultiReplicaSetBuilder) SetSecurity(s *mdbv1.Security) *MultiReplicaSet
return m
}

func (m *MultiReplicaSetBuilder) SetRoleRefs(roleRefs []mdbv1.MongoDBRoleRef) *MultiReplicaSetBuilder {
if m.Spec.Security == nil {
m.Spec.Security = &mdbv1.Security{}
}
m.Spec.Security.RoleRefs = roleRefs
return m
}

func (m *MultiReplicaSetBuilder) SetClusterSpecList(clusters []string) *MultiReplicaSetBuilder {
randFive, err := rand.Int(rand.Reader, big.NewInt(5))
if err != nil {
Expand Down
40 changes: 40 additions & 0 deletions api/v1/role/clustermongodbrole_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package role

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/mongodb/mongodb-kubernetes/api/v1"
mdbv1 "github.com/mongodb/mongodb-kubernetes/api/v1/mdb"
)

// ClusterMongoDBRoleSpec defines the desired state of ClusterMongoDBRole.
type ClusterMongoDBRoleSpec struct {
// +kubebuilder:pruning:PreserveUnknownFields
mdbv1.MongoDBRole `json:",inline"`
}

// +kubebuilder:object:root=true
// +k8s:openapi-gen=true
// +kubebuilder:resource:scope=Cluster,shortName=cmdbr
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The time since the MongoDB Custom Role resource was created."

// ClusterMongoDBRole is the Schema for the clustermongodbroles API.
type ClusterMongoDBRole struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ClusterMongoDBRoleSpec `json:"spec,omitempty"`
}

// +kubebuilder:object:root=true

// ClusterMongoDBRoleList contains a list of ClusterMongoDBRole.
type ClusterMongoDBRoleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterMongoDBRole `json:"items"`
}

func init() {
v1.SchemeBuilder.Register(&ClusterMongoDBRole{}, &ClusterMongoDBRoleList{})
}
4 changes: 4 additions & 0 deletions api/v1/role/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package role

// +k8s:deepcopy-gen=package
// +versionName=v1
20 changes: 20 additions & 0 deletions api/v1/role/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Package v1 contains API Schema definitions for the mongodb v1 API group
// +kubebuilder:object:generate=true
// +groupName=mongodb.com
package role

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects.
GroupVersion = schema.GroupVersion{Group: "mongodb.com", Version: "v1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
Loading