Skip to content

Commit 85654e6

Browse files
vasilevpantonlisovenko
andauthored
Ensure secrets on cluster update (#171)
Co-authored-by: antonlisovenko <anton.lisovenko@mongodb.com>
1 parent 2e9abee commit 85654e6

File tree

20 files changed

+194
-74
lines changed

20 files changed

+194
-74
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ jobs:
174174
go version
175175
go get github.com/onsi/ginkgo/ginkgo && \
176176
go get github.com/onsi/gomega/...
177-
ginkgo --focus "${TEST_NAME}" -nodes=3 test/e2e/
177+
ginkgo --focus "${TEST_NAME}" -v -nodes=3 test/e2e/
178178
179179
- name: Upload operator logs
180180
if: ${{ failure() }}

pkg/api/v1/atlasdatabaseuser_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ func (p *AtlasDatabaseUser) WithName(name string) *AtlasDatabaseUser {
220220
p.Name = name
221221
return p
222222
}
223+
223224
func (p *AtlasDatabaseUser) WithAtlasUserName(name string) *AtlasDatabaseUser {
224225
p.Spec.Username = name
225226
return p
@@ -239,6 +240,7 @@ func (p *AtlasDatabaseUser) WithScope(scopeType ScopeType, name string) *AtlasDa
239240
p.Spec.Scopes = append(p.Spec.Scopes, ScopeSpec{Name: name, Type: scopeType})
240241
return p
241242
}
243+
242244
func (p *AtlasDatabaseUser) ClearScopes() *AtlasDatabaseUser {
243245
p.Spec.Scopes = make([]ScopeSpec, 0)
244246
return p

pkg/api/v1/project/ipaccesslist.go.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,22 @@ func (i IPAccessList) WithComment(comment string) IPAccessList {
4848
i.Comment = comment
4949
return i
5050
}
51+
5152
func (i IPAccessList) WithIP(ip string) IPAccessList {
5253
i.IPAddress = ip
5354
return i
5455
}
56+
5557
func (i IPAccessList) WithCIDR(cidr string) IPAccessList {
5658
i.CIDRBlock = cidr
5759
return i
5860
}
61+
5962
func (i IPAccessList) WithAWSGroup(group string) IPAccessList {
6063
i.AwsSecurityGroup = group
6164
return i
6265
}
66+
6367
func (i IPAccessList) WithDeleteAfterDate(date string) IPAccessList {
6468
i.DeleteAfterDate = date
6569
return i

pkg/api/v1/status/atlasdatabaseuser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ func AtlasDatabaseUserPasswordVersion(passwordVersion string) AtlasDatabaseUserS
1010
s.PasswordVersion = passwordVersion
1111
}
1212
}
13+
1314
func AtlasDatabaseUserNameOption(name string) AtlasDatabaseUserStatusOption {
1415
return func(s *AtlasDatabaseUserStatus) {
1516
s.UserName = name

pkg/api/v1/status/atlasproject.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ func AtlasProjectIDOption(id string) AtlasProjectStatusOption {
1212
s.ID = id
1313
}
1414
}
15+
1516
func AtlasProjectExpiredIPAccessOption(lists []project.IPAccessList) AtlasProjectStatusOption {
1617
return func(s *AtlasProjectStatus) {
1718
s.ExpiredIPAccessList = lists

pkg/api/v1/status/status.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type Common struct {
3838
func (c Common) GetConditions() []Condition {
3939
return c.Conditions
4040
}
41+
4142
func (c Common) GetObservedGeneration() int64 {
4243
return c.ObservedGeneration
4344
}

pkg/controller/atlascluster/atlascluster_controller.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ type AtlasClusterReconciler struct {
5858
// +kubebuilder:rbac:groups=atlas.mongodb.com,namespace=default,resources=atlasclusters/status,verbs=get;update;patch
5959

6060
func (r *AtlasClusterReconciler) Reconcile(context context.Context, req ctrl.Request) (ctrl.Result, error) {
61-
// TODO use the context passed
62-
_ = context
6361
log := r.Log.With("atlascluster", req.NamespacedName)
6462

6563
cluster := &mdbv1.AtlasCluster{}
@@ -104,6 +102,11 @@ func (r *AtlasClusterReconciler) Reconcile(context context.Context, req ctrl.Req
104102
return result.ReconcileResult(), nil
105103
}
106104

105+
if csResult := ensureConnectionSecrets(ctx, r.Client, project, c); !csResult.IsOk() {
106+
ctx.SetConditionFromResult(status.ClusterReadyType, csResult)
107+
return csResult.ReconcileResult(), nil
108+
}
109+
107110
ctx.
108111
SetConditionTrue(status.ClusterReadyType).
109112
EnsureStatusOption(status.AtlasClusterMongoDBVersionOption(c.MongoDBVersion)).

pkg/controller/atlascluster/cluster.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ import (
99
"github.com/google/go-cmp/cmp/cmpopts"
1010
"go.mongodb.org/atlas/mongodbatlas"
1111
"go.uber.org/zap"
12+
v1 "k8s.io/api/core/v1"
13+
"sigs.k8s.io/controller-runtime/pkg/client"
1214

1315
mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
16+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status"
17+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/connectionsecret"
1418
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow"
1519
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/compat"
20+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/stringutil"
1621
)
1722

1823
func (r *AtlasClusterReconciler) ensureClusterState(ctx *workflow.Context, project *mdbv1.AtlasProject, cluster *mdbv1.AtlasCluster) (atlasCluster *mongodbatlas.Cluster, _ workflow.Result) {
@@ -152,3 +157,50 @@ func ClustersEqual(log *zap.SugaredLogger, clusterAtlas mongodbatlas.Cluster, cl
152157

153158
return d == ""
154159
}
160+
161+
func ensureConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project *mdbv1.AtlasProject, cluster *mongodbatlas.Cluster) workflow.Result {
162+
databaseUsers := mdbv1.AtlasDatabaseUserList{}
163+
err := k8sClient.List(context.TODO(), &databaseUsers, client.InNamespace(project.Namespace))
164+
if err != nil {
165+
return workflow.Terminate(workflow.Internal, err.Error())
166+
}
167+
168+
for _, dbUser := range databaseUsers.Items {
169+
found := false
170+
for _, c := range dbUser.Status.Conditions {
171+
if c.Type == status.ReadyType && c.Status == v1.ConditionTrue {
172+
found = true
173+
break
174+
}
175+
}
176+
177+
if !found {
178+
ctx.Log.Debugw("AtlasDatabaseUser not ready - not creating connection secret", "user.name", dbUser.Name)
179+
continue
180+
}
181+
182+
scopes := dbUser.GetScopes(mdbv1.ClusterScopeType)
183+
if len(scopes) != 0 && !stringutil.Contains(scopes, cluster.Name) {
184+
continue
185+
}
186+
187+
password, err := dbUser.ReadPassword(k8sClient)
188+
if err != nil {
189+
return workflow.Terminate(workflow.ClusterConnectionSecretsNotCreated, err.Error())
190+
}
191+
192+
data := connectionsecret.ConnectionData{
193+
DBUserName: dbUser.Spec.Username,
194+
ConnURL: cluster.ConnectionStrings.Standard,
195+
SrvConnURL: cluster.ConnectionStrings.StandardSrv,
196+
Password: password,
197+
}
198+
199+
_, err = connectionsecret.Ensure(k8sClient, project.Namespace, project.Spec.Name, project.ID(), cluster.Name, data)
200+
if err != nil {
201+
return workflow.Terminate(workflow.ClusterConnectionSecretsNotCreated, err.Error())
202+
}
203+
}
204+
205+
return workflow.OK()
206+
}

pkg/controller/atlascluster/cluster_test.go

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,15 @@ func TestClusterMatchesSpec(t *testing.T) {
7979
t.Run("Clusters match when Atlas adds default ReplicationSpecs", func(t *testing.T) {
8080
atlasCluster, err := mdbv1.DefaultAWSCluster("test-ns", "project-name").Spec.Cluster()
8181
assert.NoError(t, err)
82-
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{{
83-
ID: "id",
84-
NumShards: int64ptr(1),
85-
ZoneName: "zone1",
86-
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
87-
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
82+
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{
83+
{
84+
ID: "id",
85+
NumShards: int64ptr(1),
86+
ZoneName: "zone1",
87+
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
88+
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
89+
},
90+
},
8891
}
8992
operatorCluster := mdbv1.DefaultAWSCluster("test-ns", "project-name")
9093
operatorCluster.Spec.ReplicationSpecs = []mdbv1.ReplicationSpec{{
@@ -101,12 +104,15 @@ func TestClusterMatchesSpec(t *testing.T) {
101104
t.Run("Clusters don't match when Atlas adds default ReplicationSpecs and Operator overrides something", func(t *testing.T) {
102105
atlasCluster, err := mdbv1.DefaultAWSCluster("test-ns", "project-name").Spec.Cluster()
103106
assert.NoError(t, err)
104-
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{{
105-
ID: "id",
106-
NumShards: int64ptr(1),
107-
ZoneName: "zone1",
108-
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
109-
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
107+
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{
108+
{
109+
ID: "id",
110+
NumShards: int64ptr(1),
111+
ZoneName: "zone1",
112+
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
113+
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
114+
},
115+
},
110116
}
111117
operatorCluster := mdbv1.DefaultAWSCluster("test-ns", "project-name")
112118
operatorCluster.Spec.ReplicationSpecs = []mdbv1.ReplicationSpec{{
@@ -117,12 +123,15 @@ func TestClusterMatchesSpec(t *testing.T) {
117123
merged, err := MergedCluster(*atlasCluster, operatorCluster.Spec)
118124
assert.NoError(t, err)
119125

120-
expectedReplicationSpecs := []mongodbatlas.ReplicationSpec{{
121-
ID: "id",
122-
NumShards: int64ptr(2),
123-
ZoneName: "zone5",
124-
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
125-
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
126+
expectedReplicationSpecs := []mongodbatlas.ReplicationSpec{
127+
{
128+
ID: "id",
129+
NumShards: int64ptr(2),
130+
ZoneName: "zone5",
131+
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
132+
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
133+
},
134+
},
126135
}
127136
assert.Equal(t, expectedReplicationSpecs, merged.ReplicationSpecs)
128137

@@ -167,6 +176,7 @@ func TestClusterMatchesSpec(t *testing.T) {
167176
assert.False(t, equal)
168177
})
169178
}
179+
170180
func int64ptr(i int64) *int64 {
171181
return &i
172182
}

pkg/controller/atlasdatabaseuser/connectionsecrets.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import (
1414
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/stringutil"
1515
)
1616

17-
// createOrUpdateConnectionSecrets
18-
func createOrUpdateConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project mdbv1.AtlasProject, dbUser mdbv1.AtlasDatabaseUser) workflow.Result {
17+
func CreateOrUpdateConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project mdbv1.AtlasProject, dbUser mdbv1.AtlasDatabaseUser) workflow.Result {
1918
clusters, _, err := ctx.Client.Clusters.List(context.Background(), project.ID(), &mongodbatlas.ListOptions{})
2019
if err != nil {
2120
return workflow.Terminate(workflow.DatabaseUserConnectionSecretsNotCreated, err.Error())

0 commit comments

Comments
 (0)