@@ -2,8 +2,12 @@ package atlasproject
22
33import (
44 "context"
5+ "encoding/json"
6+ "fmt"
57 "reflect"
68
9+ "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/customresource"
10+
711 "go.mongodb.org/atlas/mongodbatlas"
812
913 v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
@@ -12,19 +16,37 @@ import (
1216 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/toptr"
1317)
1418
15- func ensureAuditing (ctx * workflow.Context , projectID string , project * v1.AtlasProject ) workflow.Result {
16- result := createOrDeleteAuditing (ctx , projectID , project )
19+ func ensureAuditing (ctx context.Context , workflowCtx * workflow.Context , project * v1.AtlasProject , protected bool ) workflow.Result {
20+ canReconcile , err := canAuditingReconcile (ctx , workflowCtx .Client , protected , project )
21+ if err != nil {
22+ result := workflow .Terminate (workflow .Internal , fmt .Sprintf ("unable to resolve ownership for deletion protection: %s" , err ))
23+ workflowCtx .SetConditionFromResult (status .AuditingReadyType , result )
24+
25+ return result
26+ }
27+
28+ if ! canReconcile {
29+ result := workflow .Terminate (
30+ workflow .AtlasDeletionProtection ,
31+ "unable to reconcile Auditing due to deletion protection being enabled. see https://dochub.mongodb.org/core/ako-deletion-protection for further information" ,
32+ )
33+ workflowCtx .SetConditionFromResult (status .AuditingReadyType , result )
34+
35+ return result
36+ }
37+
38+ result := createOrDeleteAuditing (workflowCtx , project .ID (), project )
1739 if ! result .IsOk () {
18- ctx .SetConditionFromResult (status .AuditingReadyType , result )
40+ workflowCtx .SetConditionFromResult (status .AuditingReadyType , result )
1941 return result
2042 }
2143
2244 if isAuditingEmpty (project .Spec .Auditing ) {
23- ctx .UnsetCondition (status .AuditingReadyType )
45+ workflowCtx .UnsetCondition (status .AuditingReadyType )
2446 return workflow .OK ()
2547 }
2648
27- ctx .SetConditionTrue (status .AuditingReadyType )
49+ workflowCtx .SetConditionTrue (status .AuditingReadyType )
2850 return workflow .OK ()
2951}
3052
@@ -59,12 +81,24 @@ func auditingInSync(atlas *mongodbatlas.Auditing, spec *v1.Auditing) bool {
5981 return true
6082 }
6183
62- if isAuditingEmpty (atlas ) || isAuditingEmpty (spec ) {
63- return false
84+ specAsAtlas := & mongodbatlas.Auditing {
85+ AuditAuthorizationSuccess : toptr .MakePtr (false ),
86+ Enabled : toptr .MakePtr (false ),
87+ }
88+
89+ if ! isAuditingEmpty (spec ) {
90+ specAsAtlas = spec .ToAtlas ()
91+ }
92+
93+ if isAuditingEmpty (atlas ) {
94+ atlas = & mongodbatlas.Auditing {
95+ AuditAuthorizationSuccess : toptr .MakePtr (false ),
96+ Enabled : toptr .MakePtr (false ),
97+ }
6498 }
6599
66- specAsAtlas := spec .ToAtlas ()
67100 removeConfigurationType (atlas )
101+
68102 return reflect .DeepEqual (atlas , specAsAtlas )
69103}
70104
@@ -85,3 +119,29 @@ func patchAuditing(ctx *workflow.Context, projectID string, auditing *mongodbatl
85119 _ , _ , err := ctx .Client .Auditing .Configure (context .Background (), projectID , auditing )
86120 return err
87121}
122+
123+ func canAuditingReconcile (ctx context.Context , atlasClient mongodbatlas.Client , protected bool , akoProject * v1.AtlasProject ) (bool , error ) {
124+ if ! protected {
125+ return true , nil
126+ }
127+
128+ latestConfig := & v1.AtlasProjectSpec {}
129+ latestConfigString , ok := akoProject .Annotations [customresource .AnnotationLastAppliedConfiguration ]
130+ if ok {
131+ if err := json .Unmarshal ([]byte (latestConfigString ), latestConfig ); err != nil {
132+ return false , err
133+ }
134+ }
135+
136+ auditing , _ , err := atlasClient .Auditing .Get (ctx , akoProject .ID ())
137+ if err != nil {
138+ return false , err
139+ }
140+
141+ if isAuditingEmpty (auditing ) {
142+ return true , nil
143+ }
144+
145+ return auditingInSync (auditing , latestConfig .Auditing ) ||
146+ auditingInSync (auditing , akoProject .Spec .Auditing ), nil
147+ }
0 commit comments