@@ -40,31 +40,31 @@ func (r *AtlasClusterReconciler) ensureClusterState(ctx *workflow.Context, proje
4040
4141 switch c .StateName {
4242 case "IDLE" :
43- if done , err := clusterMatchesSpec (ctx .Log , c , cluster .Spec ); err != nil {
43+ resultingCluster , err := mergedCluster (* c , cluster .Spec )
44+ if err != nil {
4445 return c , workflow .Terminate (workflow .Internal , err .Error ())
45- } else if done {
46- return c , workflow .OK ()
4746 }
4847
49- spec , err := cluster .Spec .Cluster ()
50- if err != nil {
51- return c , workflow .Terminate (workflow .Internal , err .Error ())
48+ if done := clustersEqual (ctx .Log , * c , resultingCluster ); done {
49+ return c , workflow .OK ()
5250 }
5351
5452 if cluster .Spec .Paused != nil {
5553 if c .Paused == nil || * c .Paused != * cluster .Spec .Paused {
5654 // paused is different from Atlas
5755 // we need to first send a special (un)pause request before reconciling everything else
58- spec = & mongodbatlas.Cluster {
56+ resultingCluster = mongodbatlas.Cluster {
5957 Paused : cluster .Spec .Paused ,
6058 }
6159 } else {
6260 // otherwise, don't send the paused field
63- spec .Paused = nil
61+ resultingCluster .Paused = nil
6462 }
6563 }
6664
67- c , _ , err = ctx .Client .Clusters .Update (context .Background (), project .Status .ID , cluster .Spec .Name , spec )
65+ resultingCluster = cleanupCluster (resultingCluster )
66+
67+ c , _ , err = ctx .Client .Clusters .Update (context .Background (), project .Status .ID , cluster .Spec .Name , & resultingCluster )
6868 if err != nil {
6969 return c , workflow .Terminate (workflow .ClusterNotUpdatedInAtlas , err .Error ())
7070 }
@@ -84,22 +84,49 @@ func (r *AtlasClusterReconciler) ensureClusterState(ctx *workflow.Context, proje
8484 }
8585}
8686
87- // clusterMatchesSpec will merge everything from the Spec into existing Cluster and use that to detect change.
88- // Direct comparison is not feasible because Atlas will set a lot of fields to default values, so we need to apply our changes on top of that.
89- func clusterMatchesSpec (log * zap.SugaredLogger , cluster * mongodbatlas.Cluster , spec mdbv1.AtlasClusterSpec ) (bool , error ) {
90- clusterMerged := mongodbatlas.Cluster {}
91- if err := compat .JSONCopy (& clusterMerged , cluster ); err != nil {
92- return false , err
87+ // cleanupCluster will unset some fields that cannot be changed via API or are deprecated.
88+ func cleanupCluster (cluster mongodbatlas.Cluster ) mongodbatlas.Cluster {
89+ cluster .ID = ""
90+ cluster .MongoDBVersion = ""
91+ cluster .MongoURI = ""
92+ cluster .MongoURIUpdated = ""
93+ cluster .MongoURIWithOptions = ""
94+ cluster .SrvAddress = ""
95+ cluster .StateName = ""
96+ cluster .ReplicationFactor = nil
97+ cluster .ReplicationSpec = nil
98+ cluster .ConnectionStrings = nil
99+ return cluster
100+ }
101+
102+ // mergedCluster will return the result of merging AtlasClusterSpec with Atlas Cluster
103+ func mergedCluster (cluster mongodbatlas.Cluster , spec mdbv1.AtlasClusterSpec ) (result mongodbatlas.Cluster , err error ) {
104+ if err = compat .JSONCopy (& result , cluster ); err != nil {
105+ return
106+ }
107+
108+ if err = compat .JSONCopy (& result , spec ); err != nil {
109+ return
93110 }
94111
95- if err := compat .JSONCopy (& clusterMerged , spec ); err != nil {
96- return false , err
112+ // TODO: might need to do this with other slices
113+ if err = compat .JSONSliceMerge (& result .ReplicationSpecs , cluster .ReplicationSpecs ); err != nil {
114+ return
97115 }
98116
99- d := cmp .Diff (* cluster , clusterMerged , cmpopts .EquateEmpty ())
117+ if err = compat .JSONSliceMerge (& result .ReplicationSpecs , spec .ReplicationSpecs ); err != nil {
118+ return
119+ }
120+
121+ return
122+ }
123+
124+ // clustersEqual compares two Atlas Clusters
125+ func clustersEqual (log * zap.SugaredLogger , clusterA mongodbatlas.Cluster , clusterB mongodbatlas.Cluster ) bool {
126+ d := cmp .Diff (clusterA , clusterB , cmpopts .EquateEmpty ())
100127 if d != "" {
101- log .Debugf ("Cluster differs from spec : %s" , d )
128+ log .Debugf ("Clusters are different : %s" , d )
102129 }
103130
104- return d == "" , nil
131+ return d == ""
105132}
0 commit comments