Skip to content

Commit 1a2cad8

Browse files
authored
CLOUDP-244165: remove ResourceWatcher in AtlasProject (#1679)
* add atlasproject indexer * remove atlas teams resource watcher
1 parent 25cae10 commit 1a2cad8

File tree

10 files changed

+559
-124
lines changed

10 files changed

+559
-124
lines changed

pkg/controller/atlasproject/alert_configurations.go

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1"
1616
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common"
1717
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status"
18-
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/watch"
1918
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
2019
)
2120

@@ -51,62 +50,50 @@ func (r *AtlasProjectReconciler) ensureAlertConfigurations(service *workflow.Con
5150

5251
// This method reads secrets refs and fills the secret data for the related Notification
5352
func (r *AtlasProjectReconciler) readAlertConfigurationsSecretsData(project *akov2.AtlasProject, service *workflow.Context, alertConfigs []akov2.AlertConfiguration) error {
54-
resourcesToWatch := make([]watch.WatchedObject, 0)
5553
projectNs := project.Namespace
56-
defer func() {
57-
service.AddResourcesToWatch(resourcesToWatch...)
58-
r.Log.Debugf("watching alert configuration secrets: %v\r\n", r.DeprecatedResourceWatcher.WatchedResourcesSnapshot())
59-
}()
6054

6155
for i := 0; i < len(alertConfigs); i++ {
6256
ac := &alertConfigs[i]
6357
for j := 0; j < len(ac.Notifications); j++ {
6458
nf := &ac.Notifications[j]
6559
switch {
6660
case nf.APITokenRef.Name != "":
67-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.APITokenRef, projectNs, "APIToken")
68-
resourcesToWatch = append(resourcesToWatch, *res)
61+
token, err := readNotificationSecret(service.Context, r.Client, nf.APITokenRef, projectNs, "APIToken")
6962
if err != nil {
7063
return err
7164
}
7265
nf.SetAPIToken(token)
7366
case nf.DatadogAPIKeyRef.Name != "":
74-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.DatadogAPIKeyRef, projectNs, "DatadogAPIKey")
75-
resourcesToWatch = append(resourcesToWatch, *res)
67+
token, err := readNotificationSecret(service.Context, r.Client, nf.DatadogAPIKeyRef, projectNs, "DatadogAPIKey")
7668
if err != nil {
7769
return err
7870
}
7971
nf.SetDatadogAPIKey(token)
8072
case nf.FlowdockAPITokenRef.Name != "":
81-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.FlowdockAPITokenRef, projectNs, "FlowdockAPIToken")
82-
resourcesToWatch = append(resourcesToWatch, *res)
73+
token, err := readNotificationSecret(service.Context, r.Client, nf.FlowdockAPITokenRef, projectNs, "FlowdockAPIToken")
8374
if err != nil {
8475
return err
8576
}
8677
nf.SetFlowdockAPIToken(token)
8778
case nf.OpsGenieAPIKeyRef.Name != "":
88-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.OpsGenieAPIKeyRef, projectNs, "OpsGenieAPIKey")
89-
resourcesToWatch = append(resourcesToWatch, *res)
79+
token, err := readNotificationSecret(service.Context, r.Client, nf.OpsGenieAPIKeyRef, projectNs, "OpsGenieAPIKey")
9080
if err != nil {
9181
return err
9282
}
9383
nf.SetOpsGenieAPIKey(token)
9484
case nf.ServiceKeyRef.Name != "":
95-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.ServiceKeyRef, projectNs, "ServiceKey")
96-
resourcesToWatch = append(resourcesToWatch, *res)
85+
token, err := readNotificationSecret(service.Context, r.Client, nf.ServiceKeyRef, projectNs, "ServiceKey")
9786
if err != nil {
9887
return err
9988
}
10089
nf.SetServiceKey(token)
10190
case nf.VictorOpsSecretRef.Name != "":
102-
token, res, err := readNotificationSecret(service.Context, r.Client, nf.VictorOpsSecretRef, projectNs, "VictorOpsAPIKey")
103-
resourcesToWatch = append(resourcesToWatch, *res)
91+
token, err := readNotificationSecret(service.Context, r.Client, nf.VictorOpsSecretRef, projectNs, "VictorOpsAPIKey")
10492
if err != nil {
10593
return err
10694
}
10795
nf.SetVictorOpsAPIKey(token)
108-
token, res, err = readNotificationSecret(service.Context, r.Client, nf.VictorOpsSecretRef, projectNs, "VictorOpsRoutingKey")
109-
resourcesToWatch = append(resourcesToWatch, *res)
96+
token, err = readNotificationSecret(service.Context, r.Client, nf.VictorOpsSecretRef, projectNs, "VictorOpsRoutingKey")
11097
if err != nil {
11198
return err
11299
}
@@ -117,7 +104,7 @@ func (r *AtlasProjectReconciler) readAlertConfigurationsSecretsData(project *ako
117104
return nil
118105
}
119106

120-
func readNotificationSecret(ctx context.Context, kubeClient client.Client, res common.ResourceRefNamespaced, parentNamespace string, fieldName string) (string, *watch.WatchedObject, error) {
107+
func readNotificationSecret(ctx context.Context, kubeClient client.Client, res common.ResourceRefNamespaced, parentNamespace string, fieldName string) (string, error) {
121108
secret := &v1.Secret{}
122109
var ns string
123110
if res.Namespace == "" {
@@ -127,19 +114,18 @@ func readNotificationSecret(ctx context.Context, kubeClient client.Client, res c
127114
}
128115

129116
secretObj := client.ObjectKey{Name: res.Name, Namespace: ns}
130-
obj := &watch.WatchedObject{ResourceKind: "Secret", Resource: secretObj}
131117

132118
if err := kubeClient.Get(ctx, secretObj, secret); err != nil {
133-
return "", obj, err
119+
return "", err
134120
}
135121
val, exists := secret.Data[fieldName]
136122
switch {
137123
case !exists:
138-
return "", obj, fmt.Errorf("secret '%s/%s' doesn't contain '%s' parameter", ns, res.Name, fieldName)
124+
return "", fmt.Errorf("secret '%s/%s' doesn't contain '%s' parameter", ns, res.Name, fieldName)
139125
case len(val) == 0:
140-
return "", obj, fmt.Errorf("secret '%s/%s' contains an empty value for '%s' parameter", ns, res.Name, fieldName)
126+
return "", fmt.Errorf("secret '%s/%s' contains an empty value for '%s' parameter", ns, res.Name, fieldName)
141127
}
142-
return string(val), obj, nil
128+
return string(val), nil
143129
}
144130

145131
func syncAlertConfigurations(service *workflow.Context, groupID string, alertSpec []akov2.AlertConfiguration) workflow.Result {

pkg/controller/atlasproject/atlasproject_controller.go

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,13 @@ import (
4646
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/customresource"
4747
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/statushandler"
4848
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/validate"
49-
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/watch"
5049
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
5150
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/indexer"
5251
)
5352

5453
// AtlasProjectReconciler reconciles a AtlasProject object
5554
type AtlasProjectReconciler struct {
56-
Client client.Client
57-
watch.DeprecatedResourceWatcher
55+
Client client.Client
5856
Log *zap.SugaredLogger
5957
Scheme *runtime.Scheme
6058
GlobalPredicates []predicate.Predicate
@@ -107,16 +105,9 @@ func (r *AtlasProjectReconciler) Reconcile(ctx context.Context, req ctrl.Request
107105
workflowCtx := workflow.NewContext(log, conditions, ctx)
108106
log.Infow("-> Starting AtlasProject reconciliation", "spec", project.Spec)
109107

110-
if project.ConnectionSecretObjectKey() != nil {
111-
// Note, that we are not watching the global connection secret - seems there is no point in reconciling all
112-
// the projects once that secret is changed
113-
workflowCtx.AddResourcesToWatch(watch.WatchedObject{ResourceKind: "Secret", Resource: *project.ConnectionSecretObjectKey()})
114-
}
115-
116108
// This update will make sure the status is always updated in case of any errors or successful result
117109
defer func() {
118110
statushandler.Update(workflowCtx, r.Client, r.EventRecorder, project)
119-
r.EnsureMultiplesResourcesAreWatched(req.NamespacedName, log, workflowCtx.ListResourcesToWatch()...)
120111
}()
121112

122113
resourceVersionIsValid := customresource.ValidateResourceVersion(workflowCtx, project, r.Log)
@@ -386,11 +377,18 @@ func (r *AtlasProjectReconciler) SetupWithManager(mgr ctrl.Manager) error {
386377
return ctrl.NewControllerManagedBy(mgr).
387378
Named("AtlasProject").
388379
For(&akov2.AtlasProject{}, builder.WithPredicates(r.GlobalPredicates...)).
389-
Watches(&corev1.Secret{}, watch.NewSecretHandler(&r.DeprecatedResourceWatcher)).
390-
Watches(&akov2.AtlasTeam{}, watch.NewAtlasTeamHandler(&r.DeprecatedResourceWatcher)).
380+
Watches(
381+
&corev1.Secret{},
382+
handler.EnqueueRequestsFromMapFunc(newProjectsMapFunc[corev1.Secret](indexer.AtlasProjectBySecretsIndex, r.Client, r.Log)),
383+
).
384+
Watches(
385+
&akov2.AtlasTeam{},
386+
handler.EnqueueRequestsFromMapFunc(newProjectsMapFunc[akov2.AtlasTeam](indexer.AtlasProjectByTeamIndex, r.Client, r.Log)),
387+
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
388+
).
391389
Watches(
392390
&akov2.AtlasBackupCompliancePolicy{},
393-
handler.EnqueueRequestsFromMapFunc(r.findProjectsForBCP),
391+
handler.EnqueueRequestsFromMapFunc(newProjectsMapFunc[akov2.AtlasBackupCompliancePolicy](indexer.AtlasProjectByBackupCompliancePolicyIndex, r.Client, r.Log)),
394392
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
395393
).
396394
Complete(r)
@@ -404,51 +402,53 @@ func NewAtlasProjectReconciler(
404402
logger *zap.Logger,
405403
) *AtlasProjectReconciler {
406404
return &AtlasProjectReconciler{
407-
Scheme: mgr.GetScheme(),
408-
Client: mgr.GetClient(),
409-
EventRecorder: mgr.GetEventRecorderFor("AtlasProject"),
410-
DeprecatedResourceWatcher: watch.NewDeprecatedResourceWatcher(),
411-
GlobalPredicates: predicates,
412-
Log: logger.Named("controllers").Named("AtlasProject").Sugar(),
413-
AtlasProvider: atlasProvider,
414-
ObjectDeletionProtection: deletionProtection,
405+
Scheme: mgr.GetScheme(),
406+
Client: mgr.GetClient(),
407+
EventRecorder: mgr.GetEventRecorderFor("AtlasProject"),
408+
GlobalPredicates: predicates,
409+
Log: logger.Named("controllers").Named("AtlasProject").Sugar(),
410+
AtlasProvider: atlasProvider,
411+
ObjectDeletionProtection: deletionProtection,
415412
}
416413
}
417414

418-
func (r *AtlasProjectReconciler) findProjectsForBCP(ctx context.Context, obj client.Object) []reconcile.Request {
419-
bcp, ok := obj.(*akov2.AtlasBackupCompliancePolicy)
420-
if !ok {
421-
r.Log.Warnf("watching AtlasBackupCompliancePolicy but got %T", obj)
422-
return nil
423-
}
415+
func newProjectsMapFunc[T any](indexName string, kubeClient client.Client, logger *zap.SugaredLogger) handler.MapFunc {
416+
return func(ctx context.Context, obj client.Object) []reconcile.Request {
417+
_, ok := any(obj).(*T)
418+
if !ok {
419+
var watchedObject T
420+
logger.Warnf("watching %T but got %T", &watchedObject, obj)
421+
return nil
422+
}
424423

425-
projects := &akov2.AtlasProjectList{}
426-
listOpts := &client.ListOptions{
427-
FieldSelector: fields.OneTermEqualSelector(
428-
indexer.AtlasProjectByBackupCompliancePolicyIndex,
429-
client.ObjectKeyFromObject(bcp).String(),
430-
),
431-
}
432-
err := r.Client.List(ctx, projects, listOpts)
433-
if err != nil {
434-
r.Log.Errorf("failed to list Atlas projects: %e", err)
435-
return []reconcile.Request{}
436-
}
437-
438-
requests := make([]reconcile.Request, 0, len(projects.Items))
439-
for i := range projects.Items {
440-
item := projects.Items[i]
441-
requests = append(
442-
requests,
443-
reconcile.Request{
444-
NamespacedName: types.NamespacedName{
445-
Name: item.Name,
446-
Namespace: item.Namespace,
424+
projects := &akov2.AtlasProjectList{}
425+
listOpts := &client.ListOptions{
426+
FieldSelector: fields.OneTermEqualSelector(
427+
indexName,
428+
client.ObjectKeyFromObject(obj).String(),
429+
),
430+
}
431+
err := kubeClient.List(ctx, projects, listOpts)
432+
if err != nil {
433+
logger.Errorf("failed to list Atlas projects: %e", err)
434+
return []reconcile.Request{}
435+
}
436+
437+
requests := make([]reconcile.Request, 0, len(projects.Items))
438+
for i := range projects.Items {
439+
item := projects.Items[i]
440+
requests = append(
441+
requests,
442+
reconcile.Request{
443+
NamespacedName: types.NamespacedName{
444+
Name: item.Name,
445+
Namespace: item.Namespace,
446+
},
447447
},
448-
},
449-
)
448+
)
449+
}
450+
return requests
450451
}
451-
return requests
452452
}
453453

454454
// setCondition sets the condition from the result and logs the warnings

0 commit comments

Comments
 (0)