Skip to content

Commit da917e6

Browse files
authored
CLOUDP-66799: Added Types + Password Generation for tests (#111)
1 parent ccc8c53 commit da917e6

File tree

18 files changed

+232
-27
lines changed

18 files changed

+232
-27
lines changed

deploy/crds/mongodb.com_v1_mongodb_scram_cr.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ spec:
1010
authentication:
1111
enabled: true
1212
modes: ["SCRAM"]
13+
users:
14+
- name: my-user
15+
db: admin
16+
passwordSecretRef:
17+
name: my-user-password
18+
roles:
19+
- name: clusterAdmin
20+
db: admin
21+
- name: userAdminAnyDatabase
22+
db: admin

pkg/apis/mongodb/v1/mongodb_types.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,43 @@ type MongoDBSpec struct {
4040
// Security configures security features, such as TLS, and authentication settings for a deployment
4141
// +optional
4242
Security Security `json:"security"`
43+
44+
// Users specifies the MongoDB users that should be configured in your deployment
45+
// +required
46+
Users []MongoDBUser `json:"users"`
47+
}
48+
49+
type MongoDBUser struct {
50+
// Name is the username of the user
51+
Name string `json:"name"`
52+
53+
// DB is the database the user is stored in. Defaults to "admin"
54+
// +optional
55+
DB string `json:"db"`
56+
57+
// PasswordSecretRef is a reference to the secret containing this user's password
58+
PasswordSecretRef SecretKeyReference `json:"passwordSecretRef"`
59+
60+
// Roles is an array of roles assigned to this user
61+
Roles []Role `json:"roles"`
62+
}
63+
64+
// SecretKeyReference is a reference to the secret containing the user's password
65+
type SecretKeyReference struct {
66+
// Name is the name of the secret storing this user's password
67+
Name string `json:"name"`
68+
69+
// Key is the key in the secret storing this password. Defaults to "password"
70+
// +optional
71+
Key string `json:"key"`
72+
}
73+
74+
// Role is the database role this user should have
75+
type Role struct {
76+
// DB is the database the role can act on
77+
DB string `json:"db"`
78+
// Name is the name of the role
79+
Name string `json:"name"`
4380
}
4481

4582
type Security struct {
@@ -125,6 +162,17 @@ func (m MongoDB) MongoURI() string {
125162
return fmt.Sprintf("mongodb://%s", strings.Join(members, ","))
126163
}
127164

165+
// TODO: this is a temporary function which will be used in the e2e tests
166+
// which will be removed in the following PR to clean up our mongo client testing
167+
func (m MongoDB) SCRAMMongoURI(username, password string) string {
168+
members := make([]string, m.Spec.Members)
169+
clusterDomain := "svc.cluster.local" // TODO: make this configurable
170+
for i := 0; i < m.Spec.Members; i++ {
171+
members[i] = fmt.Sprintf("%s-%d.%s.%s.%s:%d", m.Name, i, m.ServiceName(), m.Namespace, clusterDomain, 27017)
172+
}
173+
return fmt.Sprintf("mongodb://%s:%s@%s/?authMechanism=SCRAM-SHA-256", username, password, strings.Join(members, ","))
174+
}
175+
128176
// ServiceName returns the name of the Service that should be created for
129177
// this resource
130178
func (m MongoDB) ServiceName() string {

pkg/authentication/scram/scram.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func EnsureAgentSecret(getUpdateCreator secret.GetUpdateCreator, secretNsName ty
3333
SetField(AgentPasswordKey, generatedPassword).
3434
SetField(AgentKeyfileKey, generatedContents).
3535
Build()
36-
return automationConfigModification(generatedPassword, generatedContents), getUpdateCreator.CreateSecret(s)
36+
return automationConfigModification(generatedPassword, generatedContents, []automationconfig.MongoDBUser{}), getUpdateCreator.CreateSecret(s)
3737
}
3838

3939
return automationconfig.NOOP(), err
@@ -50,5 +50,6 @@ func EnsureAgentSecret(getUpdateCreator secret.GetUpdateCreator, secretNsName ty
5050
return automationConfigModification(
5151
string(agentSecret.Data[AgentPasswordKey]),
5252
string(agentSecret.Data[AgentKeyfileKey]),
53+
[]automationconfig.MongoDBUser{},
5354
), getUpdateCreator.UpdateSecret(agentSecret)
5455
}

pkg/authentication/scram/scram_enabler.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ const (
1414
AgentKeyfileKey = "keyfile"
1515
)
1616

17-
func automationConfigModification(agentPassword, agentKeyFile string) automationconfig.Modification {
17+
func automationConfigModification(agentPassword, agentKeyFile string, users []automationconfig.MongoDBUser) automationconfig.Modification {
1818
return func(config *automationconfig.AutomationConfig) {
19-
enableAgentAuthentication(&config.Auth, agentPassword, agentKeyFile)
19+
enableAgentAuthentication(&config.Auth, agentPassword, agentKeyFile, users)
2020
enableDeploymentMechanisms(&config.Auth)
2121
}
2222
}
2323

24-
func enableAgentAuthentication(auth *automationconfig.Auth, agentPassword, agentKeyFileContents string) {
24+
func enableAgentAuthentication(auth *automationconfig.Auth, agentPassword, agentKeyFileContents string, users []automationconfig.MongoDBUser) {
2525
auth.Disabled = false
2626
auth.AuthoritativeSet = true
2727
auth.KeyFile = automationAgentKeyFilePathInContainer
@@ -42,6 +42,9 @@ func enableAgentAuthentication(auth *automationconfig.Auth, agentPassword, agent
4242
// the contents the keyfile should have, this file is owned and managed
4343
// by the agent
4444
auth.Key = agentKeyFileContents
45+
46+
// assign all the users that should be added to the deployment
47+
auth.Users = users
4548
}
4649

4750
func enableDeploymentMechanisms(auth *automationconfig.Auth) {

pkg/authentication/scram/scram_enabler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
)
99

1010
func TestScramAutomationConfig(t *testing.T) {
11-
modificationFunc := automationConfigModification("password", "keyfilecontents")
11+
modificationFunc := automationConfigModification("password", "keyfilecontents", []automationconfig.MongoDBUser{})
1212
config := automationconfig.AutomationConfig{}
1313

1414
t.Run("Authentication is correctly configured", func(t *testing.T) {

pkg/automationconfig/automation_config.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package automationconfig
22

3-
import "path"
3+
import (
4+
"path"
5+
6+
"github.com/mongodb/mongodb-kubernetes-operator/pkg/authentication/scramcredentials"
7+
)
48

59
const (
610
Mongod ProcessType = "mongod"
@@ -9,17 +13,21 @@ const (
913
)
1014

1115
type AutomationConfig struct {
12-
Version int `json:"version"`
13-
Processes []Process `json:"processes"`
14-
ReplicaSets []ReplicaSet `json:"replicaSets"`
15-
Auth Auth `json:"auth"`
16-
TLS TLS `json:"tls"`
17-
16+
Version int `json:"version"`
17+
Processes []Process `json:"processes"`
18+
ReplicaSets []ReplicaSet `json:"replicaSets"`
19+
Auth Auth `json:"auth"`
20+
TLS TLS `json:"tls"`
1821
Versions []MongoDbVersionConfig `json:"mongoDbVersions"`
1922
ToolsVersion ToolsVersion `json:"mongoDbToolsVersion"`
2023
Options Options `json:"options"`
2124
}
2225

26+
type Role struct {
27+
Role string `json:"role"`
28+
Database string `json:"db"`
29+
}
30+
2331
type Process struct {
2432
Name string `json:"name"`
2533
HostName string `json:"hostname"`
@@ -170,6 +178,18 @@ type Auth struct {
170178
AutoPwd string `json:"autoPwd,omitempty"`
171179
}
172180

181+
type MongoDBUser struct {
182+
Mechanisms []string `json:"mechanisms"`
183+
Roles []Role `json:"roles"`
184+
Username string `json:"user"`
185+
Database string `json:"db"`
186+
AuthenticationRestrictions []string `json:"authenticationRestrictions"`
187+
188+
// ScramShaCreds are generated by the operator.
189+
ScramSha256Creds *scramcredentials.ScramCreds `json:"scramSha256Creds"`
190+
ScramSha1Creds *scramcredentials.ScramCreds `json:"scramSha1Creds"`
191+
}
192+
173193
func disabledAuth() Auth {
174194
return Auth{
175195
Users: make([]MongoDBUser, 0),
@@ -180,9 +200,6 @@ func disabledAuth() Auth {
180200
}
181201
}
182202

183-
type MongoDBUser struct {
184-
}
185-
186203
type ClientCertificateMode string
187204

188205
const (

pkg/kube/secret/secret.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,14 @@ func CreateOrUpdate(getUpdateCreator GetUpdateCreator, secret corev1.Secret) err
9898
}
9999
return getUpdateCreator.UpdateSecret(newSecret)
100100
}
101+
102+
// HasAllKeys returns true if the provided secret contains an element for every
103+
// key provided. False if a single element is absent
104+
func HasAllKeys(secret corev1.Secret, keys ...string) bool {
105+
for _, key := range keys {
106+
if _, ok := secret.Data[key]; !ok {
107+
return false
108+
}
109+
}
110+
return true
111+
}

test/e2e/e2eutil.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ func waitForRuntimeObjectToExist(name string, retryInterval, timeout time.Durati
112112
})
113113
}
114114

115-
func NewTestMongoDB(name string) mdbv1.MongoDB {
116-
return mdbv1.MongoDB{
115+
func NewTestMongoDB(name string) (mdbv1.MongoDB, mdbv1.MongoDBUser) {
116+
mdb := mdbv1.MongoDB{
117117
ObjectMeta: metav1.ObjectMeta{
118118
Name: name,
119119
Namespace: f.Global.OperatorNamespace,
@@ -123,8 +123,44 @@ func NewTestMongoDB(name string) mdbv1.MongoDB {
123123
Type: "ReplicaSet",
124124
Version: "4.0.6",
125125
FeatureCompatibilityVersion: "4.0",
126+
Security: mdbv1.Security{
127+
Authentication: mdbv1.Authentication{
128+
Modes: []mdbv1.AuthMode{"SCRAM"},
129+
},
130+
},
131+
Users: []mdbv1.MongoDBUser{
132+
{
133+
Name: fmt.Sprintf("%s-user", name),
134+
DB: "admin",
135+
PasswordSecretRef: mdbv1.SecretKeyReference{
136+
Key: fmt.Sprintf("%s-password", name),
137+
Name: fmt.Sprintf("%s-password-secret", name),
138+
},
139+
Roles: []mdbv1.Role{
140+
// roles on testing db for general connectivity
141+
{
142+
DB: "testing",
143+
Name: "readWrite",
144+
},
145+
{
146+
DB: "testing",
147+
Name: "clusterAdmin",
148+
},
149+
// admin roles for reading FCV
150+
{
151+
DB: "admin",
152+
Name: "readWrite",
153+
},
154+
{
155+
DB: "admin",
156+
Name: "clusterAdmin",
157+
},
158+
},
159+
},
160+
},
126161
},
127162
}
163+
return mdb, mdb.Spec.Users[0]
128164
}
129165

130166
func NewTestTLSConfig(optional bool) mdbv1.TLS {

test/e2e/feature_compatibility_version/feature_compatibility_version_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ func TestFeatureCompatibilityVersion(t *testing.T) {
2222
defer ctx.Cleanup()
2323
}
2424

25-
mdb := e2eutil.NewTestMongoDB("mdb0")
25+
mdb, user := e2eutil.NewTestMongoDB("mdb0")
26+
27+
_, err := setup.GeneratePasswordForUser(user, ctx)
28+
if err != nil {
29+
t.Fatal(err)
30+
}
31+
2632
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
2733
t.Run("Basic tests", mongodbtests.BasicFunctionality(&mdb))
2834

test/e2e/feature_compatibility_version_upgrade/feature_compatibility_version_upgrade_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ func TestFeatureCompatibilityVersionUpgrade(t *testing.T) {
2424
defer ctx.Cleanup()
2525
}
2626

27-
mdb := e2eutil.NewTestMongoDB("mdb0")
27+
mdb, user := e2eutil.NewTestMongoDB("mdb0")
28+
29+
_, err := setup.GeneratePasswordForUser(user, ctx)
30+
if err != nil {
31+
t.Fatal(err)
32+
}
33+
2834
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
2935
t.Run("Basic tests", mongodbtests.BasicFunctionality(&mdb))
3036

0 commit comments

Comments
 (0)