Skip to content

feat: customize connection string secret annotations #1582

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

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
17 changes: 11 additions & 6 deletions api/v1/mongodbcommunity_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,10 @@ type MongoDBUser struct {
// +optional
ConnectionStringSecretNamespace string `json:"connectionStringSecretNamespace,omitempty"`

// ConnectionStringSecretAnnotations is the annotations of the secret object created by the operator which exposes the connection strings for the user.
// +optional
ConnectionStringSecretAnnotations map[string]string `json:"connectionStringSecretAnnotations,omitempty"`

// Additional options to be appended to the connection string.
// These options apply only to this user and will override any existing options in the resource.
// +kubebuilder:validation:Type=object
Expand Down Expand Up @@ -789,12 +793,13 @@ func (m *MongoDBCommunity) GetAuthUsers() []authtypes.User {
}

users[i] = authtypes.User{
Username: u.Name,
Database: u.DB,
Roles: roles,
ConnectionStringSecretName: u.GetConnectionStringSecretName(m.Name),
ConnectionStringSecretNamespace: u.GetConnectionStringSecretNamespace(m.Namespace),
ConnectionStringOptions: u.AdditionalConnectionStringConfig.Object,
Username: u.Name,
Database: u.DB,
Roles: roles,
ConnectionStringSecretName: u.GetConnectionStringSecretName(m.Name),
ConnectionStringSecretNamespace: u.GetConnectionStringSecretNamespace(m.Namespace),
ConnectionStringSecretAnnotations: u.ConnectionStringSecretAnnotations,
ConnectionStringOptions: u.AdditionalConnectionStringConfig.Object,
}

if u.DB != constants.ExternalDB {
Expand Down
7 changes: 7 additions & 0 deletions api/v1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,13 @@ spec:
nullable: true
type: object
x-kubernetes-preserve-unknown-fields: true
connectionStringSecretAnnotations:
additionalProperties:
type: string
description: ConnectionStringSecretAnnotations is the annotations
of the secret object created by the operator which exposes
the connection strings for the user.
type: object
connectionStringSecretName:
description: |-
ConnectionStringSecretName is the name of the secret object created by the operator which exposes the connection strings for the user.
Expand Down
1 change: 1 addition & 0 deletions controllers/mongodb_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func (r ReplicaSetReconciler) updateConnectionStringSecrets(ctx context.Context,
SetField("username", user.Username).
SetField("password", pwd).
SetOwnerReferences(mdb.GetOwnerReferences()).
SetAnnotations(user.ConnectionStringSecretAnnotations).
Build()

if err := secret.CreateOrUpdate(ctx, r.client, connectionStringSecret); err != nil {
Expand Down
1 change: 1 addition & 0 deletions docs/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ You cannot disable SCRAM authentication.
| `spec.users.roles` | array of objects | Configures roles assigned to the user. | Yes |
| `spec.users.roles.role.name` | string | Name of the role. Valid values are [built-in roles](https://www.mongodb.com/docs/manual/reference/built-in-roles/#built-in-roles) and [custom roles](deploy-configure.md#define-a-custom-database-role) that you have defined. | Yes |
| `spec.users.roles.role.db` | string | Database that the role applies to. | Yes |
| `spec.users.connectionStringSecretAnnotations` | object | Annotations of the secret object created by the operator which exposes the connection strings for the user. | No |

```yaml
---
Expand Down
3 changes: 3 additions & 0 deletions pkg/authentication/authtypes/authtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ type User struct {
// ConnectionStringSecretNamespace is the namespace of the secret object created by the operator which exposes the connection strings for the user.
ConnectionStringSecretNamespace string `json:"connectionStringSecretNamespace,omitempty"`

// ConnectionStringSecretAnnotations is the annotations of the secret object created by the operator which exposes the connection strings for the user.
ConnectionStringSecretAnnotations map[string]string

// ConnectionStringOptions contains connection string options for this user
// These options will be appended at the end of the connection string and
// will override any existing options from the resources.
Expand Down
7 changes: 7 additions & 0 deletions pkg/kube/secret/secret_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type builder struct {
labels map[string]string
name string
namespace string
annotations map[string]string
ownerReferences []metav1.OwnerReference
}

Expand All @@ -24,6 +25,11 @@ func (b *builder) SetNamespace(namespace string) *builder {
return b
}

func (b *builder) SetAnnotations(annotations map[string]string) *builder {
b.annotations = annotations
return b
}

func (b *builder) SetField(key, value string) *builder {
b.data[key] = []byte(value)
return b
Expand Down Expand Up @@ -72,6 +78,7 @@ func (b builder) Build() corev1.Secret {
Namespace: b.namespace,
OwnerReferences: b.ownerReferences,
Labels: b.labels,
Annotations: b.annotations,
},
Data: b.data,
Type: b.dataType,
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/mongodbtests/mongodbtests.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func ConnectionStringSecretsAreConfigured(ctx context.Context, mdb *mdbv1.MongoD

assert.NoError(t, err)
assertEqualOwnerReference(t, "Secret", secretNamespacedName, secret.GetOwnerReferences(), expectedOwnerReference)
containsMetadata(t, secret.ObjectMeta, map[string]string{}, user.ConnectionStringSecretAnnotations, "secret "+secretNamespacedName.Name)
}
}
}
Expand Down Expand Up @@ -684,6 +685,18 @@ func AddConnectionStringOptionToUser(ctx context.Context, mdb *mdbv1.MongoDBComm
}
}

func AddConnectionStringAnnotationsToUser(ctx context.Context, mdb *mdbv1.MongoDBCommunity, annotations map[string]string) func(t *testing.T) {
return func(t *testing.T) {
t.Logf("Adding %v to connection string annotations", annotations)
err := e2eutil.UpdateMongoDBResource(ctx, mdb, func(db *mdbv1.MongoDBCommunity) {
db.Spec.Users[0].ConnectionStringSecretAnnotations = annotations
})
if err != nil {
t.Fatal(err)
}
}
}

func StatefulSetContainerConditionIsTrue(ctx context.Context, mdb *mdbv1.MongoDBCommunity, containerName string, condition func(c corev1.Container) bool) func(*testing.T) {
return func(t *testing.T) {
sts := appsv1.StatefulSet{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,24 @@ func TestReplicaSetWithConnectionString(t *testing.T) {
tester.ConnectivityRejected(ctx, WithURI(mongodbtests.GetSrvConnectionStringForUser(ctx, mdb, scramUser))))
})

/**
Connection String Annotations options.
*/
t.Run("Connection String With Annotations", func(t *testing.T) {
t.Run("Resetting Connection String Options", mongodbtests.ResetConnectionStringOptions(ctx, &mdb))
t.Run("Test Add New Connection String Annotations to Resource", mongodbtests.AddConnectionStringAnnotationsToUser(ctx, &mdb, map[string]string{"mongodbcommunity.mongodb.com/test-annotation": "test-value"}))
t.Run("Test Secrets Are Updated", mongodbtests.MongoDBReachesRunningPhase(ctx, &mdb))

scramUser = mdb.GetAuthUsers()[0]
t.Run("Test Basic Connectivity", tester.ConnectivitySucceeds())
t.Run("Test SRV Connectivity", tester.ConnectivitySucceeds(WithURI(mdb.MongoSRVURI("")), WithoutTls(), WithReplicaSet(mdb.Name)))
t.Run("Test Basic Connectivity with generated connection string secret",
tester.ConnectivitySucceeds(WithURI(mongodbtests.GetConnectionStringForUser(ctx, mdb, scramUser))))
t.Run("Test SRV Connectivity with generated connection string secret",
tester.ConnectivitySucceeds(WithURI(mongodbtests.GetSrvConnectionStringForUser(ctx, mdb, scramUser))))

ownerRef := mdb.GetOwnerReferences()[0]
t.Run("Test Connection String Annotations are as expected", mongodbtests.ConnectionStringSecretsAreConfigured(ctx, &mdb, ownerRef))
})

}