Skip to content

Commit bd4da86

Browse files
committed
reconcile clusters if external-dns config changes (requires controller-utils update)
1 parent f446293 commit bd4da86

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

internal/controllers/cluster/controller.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ import (
66
"maps"
77
"slices"
88
"strings"
9+
"sync"
910
"time"
1011

1112
corev1 "k8s.io/api/core/v1"
1213
rbacv1 "k8s.io/api/rbac/v1"
1314
apierrors "k8s.io/apimachinery/pkg/api/errors"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
"k8s.io/apimachinery/pkg/runtime/schema"
17+
"k8s.io/apimachinery/pkg/types"
1618
"k8s.io/client-go/tools/record"
1719
ctrl "sigs.k8s.io/controller-runtime"
20+
"sigs.k8s.io/controller-runtime/pkg/builder"
1821
"sigs.k8s.io/controller-runtime/pkg/client"
1922
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
23+
"sigs.k8s.io/controller-runtime/pkg/handler"
2024
"sigs.k8s.io/controller-runtime/pkg/predicate"
2125
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2226

@@ -41,13 +45,15 @@ import (
4145
)
4246

4347
const ControllerName = "DNSCluster"
44-
const defaultRequeueAfterDuration = 30 * time.Second
48+
const defaultRequeueAfterDuration = 1 * time.Minute
4549

4650
type ClusterReconciler struct {
4751
PlatformCluster *clusters.Cluster
4852
eventRecorder record.EventRecorder
4953
ProviderName string
5054
ProviderNamespace string
55+
KnownClusters map[types.NamespacedName]struct{}
56+
KnownClustersLock *sync.RWMutex
5157
}
5258

5359
func NewClusterReconciler(platformCluster *clusters.Cluster, recorder record.EventRecorder, providerName, providerNamespace string) *ClusterReconciler {
@@ -56,6 +62,8 @@ func NewClusterReconciler(platformCluster *clusters.Cluster, recorder record.Eve
5662
eventRecorder: recorder,
5763
ProviderName: providerName,
5864
ProviderNamespace: providerNamespace,
65+
KnownClusters: map[types.NamespacedName]struct{}{},
66+
KnownClustersLock: &sync.RWMutex{},
5967
}
6068
}
6169

@@ -90,6 +98,7 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req reconcile.Request
9098
if err := r.PlatformCluster.Client().Get(ctx, req.NamespacedName, c); err != nil {
9199
if apierrors.IsNotFound(err) {
92100
log.Info("Resource not found")
101+
r.removeKnownClusterRaw(req.Name, req.Namespace)
93102
return reconcile.Result{}, nil
94103
}
95104
return reconcile.Result{}, fmt.Errorf("unable to get resource '%s' from cluster: %w", req.String(), err)
@@ -178,6 +187,7 @@ func (r *ClusterReconciler) reconcile(ctx context.Context, c *clustersv1alpha1.C
178187
return rr
179188
}
180189
}
190+
r.addKnownCluster(c)
181191

182192
// get access to the Cluster
183193
accessMgr := accesslib.NewClusterAccessManager(r.PlatformCluster.Client(), strings.ToLower(ControllerName), c.Namespace)
@@ -270,6 +280,7 @@ func (r *ClusterReconciler) reconcile(ctx context.Context, c *clustersv1alpha1.C
270280
return rr
271281
}
272282
}
283+
r.removeKnownCluster(c)
273284

274285
rr.Message = "Successfully removed external-dns from Cluster"
275286
}
@@ -656,6 +667,34 @@ func clusterBasedResourceName(clusterName string) string {
656667
return ctrlutils.ShortenToXCharactersUnsafe(clusterName, ctrlutils.K8sMaxNameLength-len(suffix)) + suffix
657668
}
658669

670+
func (r *ClusterReconciler) addKnownCluster(c *clustersv1alpha1.Cluster) {
671+
nn := types.NamespacedName{Namespace: c.Namespace, Name: c.Name}
672+
r.KnownClustersLock.Lock()
673+
defer r.KnownClustersLock.Unlock()
674+
r.KnownClusters[nn] = struct{}{}
675+
}
676+
677+
func (r *ClusterReconciler) removeKnownCluster(c *clustersv1alpha1.Cluster) {
678+
r.removeKnownClusterRaw(c.Name, c.Namespace)
679+
}
680+
681+
func (r *ClusterReconciler) removeKnownClusterRaw(name, namespace string) {
682+
nn := types.NamespacedName{Namespace: namespace, Name: name}
683+
r.KnownClustersLock.Lock()
684+
defer r.KnownClustersLock.Unlock()
685+
delete(r.KnownClusters, nn)
686+
}
687+
688+
func (r *ClusterReconciler) listKnownClusters() []types.NamespacedName {
689+
r.KnownClustersLock.RLock()
690+
defer r.KnownClustersLock.RUnlock()
691+
result := make([]types.NamespacedName, 0, len(r.KnownClusters))
692+
for nn := range r.KnownClusters {
693+
result = append(result, nn)
694+
}
695+
return result
696+
}
697+
659698
// SetupWithManager sets up the controller with the Manager.
660699
func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
661700
return ctrl.NewControllerManagedBy(mgr).
@@ -672,5 +711,14 @@ func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
672711
ctrlutils.HasAnnotationPredicate(openmcpconst.OperationAnnotation, openmcpconst.OperationAnnotationValueIgnore),
673712
),
674713
)).
714+
// watch DNSServiceConfig resource and reconcile all Clusters that are known to have external-dns deployed if it changes
715+
Watches(&dnsv1alpha1.DNSServiceConfig{}, handler.EnqueueRequestsFromMapFunc(func(_ context.Context, _ client.Object) []ctrl.Request {
716+
return collections.ProjectSliceToSlice(r.listKnownClusters(), func(nn types.NamespacedName) ctrl.Request {
717+
return ctrl.Request{NamespacedName: nn}
718+
})
719+
}), builder.WithPredicates(predicate.And(
720+
predicate.GenerationChangedPredicate{},
721+
ctrlutils.ExactNamePredicate(r.ProviderName, r.ProviderNamespace),
722+
))).
675723
Complete(r)
676724
}

0 commit comments

Comments
 (0)