Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
go version
go get github.com/onsi/ginkgo/ginkgo && \
go get github.com/onsi/gomega/...
ginkgo --focus "${TEST_NAME}" -nodes=3 test/e2e/
ginkgo --focus "${TEST_NAME}" -v -nodes=3 test/e2e/

- name: Upload operator logs
if: ${{ failure() }}
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1/atlasdatabaseuser_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ func (p *AtlasDatabaseUser) WithName(name string) *AtlasDatabaseUser {
p.Name = name
return p
}

func (p *AtlasDatabaseUser) WithAtlasUserName(name string) *AtlasDatabaseUser {
p.Spec.Username = name
return p
Expand All @@ -239,6 +240,7 @@ func (p *AtlasDatabaseUser) WithScope(scopeType ScopeType, name string) *AtlasDa
p.Spec.Scopes = append(p.Spec.Scopes, ScopeSpec{Name: name, Type: scopeType})
return p
}

func (p *AtlasDatabaseUser) ClearScopes() *AtlasDatabaseUser {
p.Spec.Scopes = make([]ScopeSpec, 0)
return p
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/v1/project/ipaccesslist.go.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,22 @@ func (i IPAccessList) WithComment(comment string) IPAccessList {
i.Comment = comment
return i
}

func (i IPAccessList) WithIP(ip string) IPAccessList {
i.IPAddress = ip
return i
}

func (i IPAccessList) WithCIDR(cidr string) IPAccessList {
i.CIDRBlock = cidr
return i
}

func (i IPAccessList) WithAWSGroup(group string) IPAccessList {
i.AwsSecurityGroup = group
return i
}

func (i IPAccessList) WithDeleteAfterDate(date string) IPAccessList {
i.DeleteAfterDate = date
return i
Expand Down
1 change: 1 addition & 0 deletions pkg/api/v1/status/atlasdatabaseuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ func AtlasDatabaseUserPasswordVersion(passwordVersion string) AtlasDatabaseUserS
s.PasswordVersion = passwordVersion
}
}

func AtlasDatabaseUserNameOption(name string) AtlasDatabaseUserStatusOption {
return func(s *AtlasDatabaseUserStatus) {
s.UserName = name
Expand Down
1 change: 1 addition & 0 deletions pkg/api/v1/status/atlasproject.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func AtlasProjectIDOption(id string) AtlasProjectStatusOption {
s.ID = id
}
}

func AtlasProjectExpiredIPAccessOption(lists []project.IPAccessList) AtlasProjectStatusOption {
return func(s *AtlasProjectStatus) {
s.ExpiredIPAccessList = lists
Expand Down
1 change: 1 addition & 0 deletions pkg/api/v1/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Common struct {
func (c Common) GetConditions() []Condition {
return c.Conditions
}

func (c Common) GetObservedGeneration() int64 {
return c.ObservedGeneration
}
7 changes: 5 additions & 2 deletions pkg/controller/atlascluster/atlascluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ type AtlasClusterReconciler struct {
// +kubebuilder:rbac:groups=atlas.mongodb.com,namespace=default,resources=atlasclusters/status,verbs=get;update;patch

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

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

if csResult := ensureConnectionSecrets(ctx, r.Client, project, c); !csResult.IsOk() {
ctx.SetConditionFromResult(status.ClusterReadyType, csResult)
return csResult.ReconcileResult(), nil
}

ctx.
SetConditionTrue(status.ClusterReadyType).
EnsureStatusOption(status.AtlasClusterMongoDBVersionOption(c.MongoDBVersion)).
Expand Down
52 changes: 52 additions & 0 deletions pkg/controller/atlascluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
"go.mongodb.org/atlas/mongodbatlas"
"go.uber.org/zap"
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status"
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/connectionsecret"
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow"
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/compat"
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/stringutil"
)

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

return d == ""
}

func ensureConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project *mdbv1.AtlasProject, cluster *mongodbatlas.Cluster) workflow.Result {
databaseUsers := mdbv1.AtlasDatabaseUserList{}
err := k8sClient.List(context.TODO(), &databaseUsers, client.InNamespace(project.Namespace))
if err != nil {
return workflow.Terminate(workflow.Internal, err.Error())
}

for _, dbUser := range databaseUsers.Items {
found := false
for _, c := range dbUser.Status.Conditions {
if c.Type == status.ReadyType && c.Status == v1.ConditionTrue {
found = true
break
}
}

if !found {
ctx.Log.Debugw("AtlasDatabaseUser not ready - not creating connection secret", "user.name", dbUser.Name)
continue
}

scopes := dbUser.GetScopes(mdbv1.ClusterScopeType)
if len(scopes) != 0 && !stringutil.Contains(scopes, cluster.Name) {
continue
}

password, err := dbUser.ReadPassword(k8sClient)
if err != nil {
return workflow.Terminate(workflow.ClusterConnectionSecretsNotCreated, err.Error())
}

data := connectionsecret.ConnectionData{
DBUserName: dbUser.Spec.Username,
ConnURL: cluster.ConnectionStrings.Standard,
SrvConnURL: cluster.ConnectionStrings.StandardSrv,
Password: password,
}

_, err = connectionsecret.Ensure(k8sClient, project.Namespace, project.Spec.Name, project.ID(), cluster.Name, data)
if err != nil {
return workflow.Terminate(workflow.ClusterConnectionSecretsNotCreated, err.Error())
}
}

return workflow.OK()
}
46 changes: 28 additions & 18 deletions pkg/controller/atlascluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,15 @@ func TestClusterMatchesSpec(t *testing.T) {
t.Run("Clusters match when Atlas adds default ReplicationSpecs", func(t *testing.T) {
atlasCluster, err := mdbv1.DefaultAWSCluster("test-ns", "project-name").Spec.Cluster()
assert.NoError(t, err)
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{{
ID: "id",
NumShards: int64ptr(1),
ZoneName: "zone1",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{
{
ID: "id",
NumShards: int64ptr(1),
ZoneName: "zone1",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
},
},
}
operatorCluster := mdbv1.DefaultAWSCluster("test-ns", "project-name")
operatorCluster.Spec.ReplicationSpecs = []mdbv1.ReplicationSpec{{
Expand All @@ -101,12 +104,15 @@ func TestClusterMatchesSpec(t *testing.T) {
t.Run("Clusters don't match when Atlas adds default ReplicationSpecs and Operator overrides something", func(t *testing.T) {
atlasCluster, err := mdbv1.DefaultAWSCluster("test-ns", "project-name").Spec.Cluster()
assert.NoError(t, err)
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{{
ID: "id",
NumShards: int64ptr(1),
ZoneName: "zone1",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
atlasCluster.ReplicationSpecs = []mongodbatlas.ReplicationSpec{
{
ID: "id",
NumShards: int64ptr(1),
ZoneName: "zone1",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
},
},
}
operatorCluster := mdbv1.DefaultAWSCluster("test-ns", "project-name")
operatorCluster.Spec.ReplicationSpecs = []mdbv1.ReplicationSpec{{
Expand All @@ -117,12 +123,15 @@ func TestClusterMatchesSpec(t *testing.T) {
merged, err := MergedCluster(*atlasCluster, operatorCluster.Spec)
assert.NoError(t, err)

expectedReplicationSpecs := []mongodbatlas.ReplicationSpec{{
ID: "id",
NumShards: int64ptr(2),
ZoneName: "zone5",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)}}},
expectedReplicationSpecs := []mongodbatlas.ReplicationSpec{
{
ID: "id",
NumShards: int64ptr(2),
ZoneName: "zone5",
RegionsConfig: map[string]mongodbatlas.RegionsConfig{
"US_EAST": {AnalyticsNodes: int64ptr(0), ElectableNodes: int64ptr(3), Priority: int64ptr(7), ReadOnlyNodes: int64ptr(0)},
},
},
}
assert.Equal(t, expectedReplicationSpecs, merged.ReplicationSpecs)

Expand Down Expand Up @@ -167,6 +176,7 @@ func TestClusterMatchesSpec(t *testing.T) {
assert.False(t, equal)
})
}

func int64ptr(i int64) *int64 {
return &i
}
3 changes: 1 addition & 2 deletions pkg/controller/atlasdatabaseuser/connectionsecrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import (
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/stringutil"
)

// createOrUpdateConnectionSecrets
func createOrUpdateConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project mdbv1.AtlasProject, dbUser mdbv1.AtlasDatabaseUser) workflow.Result {
func CreateOrUpdateConnectionSecrets(ctx *workflow.Context, k8sClient client.Client, project mdbv1.AtlasProject, dbUser mdbv1.AtlasDatabaseUser) workflow.Result {
clusters, _, err := ctx.Client.Clusters.List(context.Background(), project.ID(), &mongodbatlas.ListOptions{})
if err != nil {
return workflow.Terminate(workflow.DatabaseUserConnectionSecretsNotCreated, err.Error())
Expand Down
3 changes: 2 additions & 1 deletion pkg/controller/atlasdatabaseuser/databaseuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (r *AtlasDatabaseUserReconciler) ensureDatabaseUser(ctx *workflow.Context,
return result
}

if result := createOrUpdateConnectionSecrets(ctx, r.Client, project, dbUser); !result.IsOk() {
if result := CreateOrUpdateConnectionSecrets(ctx, r.Client, project, dbUser); !result.IsOk() {
return result
}

Expand Down Expand Up @@ -131,6 +131,7 @@ func performUpdateInAtlas(ctx *workflow.Context, k8sClient client.Client, projec
// after the successful update we'll retry reconciliation so that clusters had a chance to start working
return retryAfterUpdate
}

return workflow.OK()
}

Expand Down
9 changes: 5 additions & 4 deletions pkg/controller/workflow/reason.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ const (

// Atlas Cluster reasons
const (
ClusterNotCreatedInAtlas ConditionReason = "ClusterNotCreatedInAtlas"
ClusterNotUpdatedInAtlas ConditionReason = "ClusterNotUpdatedInAtlas"
ClusterCreating ConditionReason = "ClusterCreating"
ClusterUpdating ConditionReason = "ClusterUpdating"
ClusterNotCreatedInAtlas ConditionReason = "ClusterNotCreatedInAtlas"
ClusterNotUpdatedInAtlas ConditionReason = "ClusterNotUpdatedInAtlas"
ClusterCreating ConditionReason = "ClusterCreating"
ClusterUpdating ConditionReason = "ClusterUpdating"
ClusterConnectionSecretsNotCreated ConditionReason = "ClusterConnectionSecretsNotCreated"
)

// Atlas Database User reasons
Expand Down
1 change: 1 addition & 0 deletions pkg/util/kube/kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func TestNormalizeIdentifier(t *testing.T) {
}
})
}

func TestNormalizeLabelValue(t *testing.T) {
t.Run("Valid Label Value", func(t *testing.T) {
successCases := []string{
Expand Down
1 change: 0 additions & 1 deletion test/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ func getMongoClient() (*mongo.Client, error) {

func getMongoCollection(DbName string, CollectionName string) (*mongo.Collection, error) {
client, err := getMongoClient()

if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/cli/kube/kubectl.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package kube

import (
"encoding/json"
"fmt"
"os"
"strings"

"encoding/json"

. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
Expand Down
4 changes: 1 addition & 3 deletions test/e2e/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ type testDataProvider struct {
}

var _ = Describe("[cluster-ns] Configuration namespaced. Deploy cluster", func() {

var data testDataProvider

var _ = AfterEach(func() {
_ = AfterEach(func() {
GinkgoWriter.Write([]byte("===============================================\n"))
GinkgoWriter.Write([]byte("Operator namespace: " + data.resources.Namespace + "\n"))
GinkgoWriter.Write([]byte("===============================================\n"))
Expand All @@ -47,7 +46,6 @@ var _ = Describe("[cluster-ns] Configuration namespaced. Deploy cluster", func()
} else {
Eventually(kube.DeleteNamespace(data.resources.Namespace)).Should(Say("deleted"), "Cant delete namespace after testing")
}

})

// TODO remove portGroup (nodePort for the app)
Expand Down
5 changes: 2 additions & 3 deletions test/e2e/operator_type_wide_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import (
)

var _ = Describe("[cluster-wide] Users (Norton and Nimnul) can work with one Cluster wide operator", func() {

var NortonSpec, NimnulSpec model.UserInputs
commonClusterName := "megacluster"

var _ = BeforeEach(func() {
_ = BeforeEach(func() {
By("User Install CRD, cluster wide Operator", func() {
Eventually(kube.Apply(ConfigAll)).Should(
Say("customresourcedefinition.apiextensions.k8s.io/atlasclusters.atlas.mongodb.com"),
Expand All @@ -31,7 +30,7 @@ var _ = Describe("[cluster-wide] Users (Norton and Nimnul) can work with one Clu
})
})

var _ = AfterEach(func() {
_ = AfterEach(func() {
By("Delete clusters", func() {
if CurrentGinkgoTestDescription().Failed {
GinkgoWriter.Write([]byte("Resources wasn't clean"))
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ package utils

import (
"encoding/json"
"os"

"io/ioutil"
"log"
"os"
"path/filepath"

yaml "gopkg.in/yaml.v3"
Expand Down
Loading