Skip to content

Commit 4abc2ac

Browse files
committed
Mirror ConfigMaps and Secrets referenced in ScyllaDBCluster into remote datacenters
The ScyllaDBCluster controller has been extended with a new capability of mirroring the ConfigMaps and Secrets referenced by the ScyllaDBCluster, into remote datacenters. This improvement provides users with the convenience of managing the configuration of an entire cluster from a single centralized location. Note: any modifications made to the ConfigMaps or Secrets do not automatically initiate a rollout to apply those changes. A manual trigger is required to implement the updates - for example using `forceRedeploymentReason`.
1 parent 7260e3a commit 4abc2ac

File tree

11 files changed

+822
-0
lines changed

11 files changed

+822
-0
lines changed

helm/scylla-operator/templates/operator_remote.clusterrole_def.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ rules:
4747
- endpoints
4848
- namespaces
4949
- services
50+
- secrets
51+
- configmaps
5052
verbs:
5153
- create
5254
- delete

pkg/cmd/operator/operator.go

+60
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,18 @@ func (o *OperatorOptions) run(ctx context.Context, streams genericclioptions.IOS
325325
),
326326
)
327327

328+
remoteOperatorManagedResourcesOnlyInformer := remoteinformers.NewSharedInformerFactoryWithOptions[kubernetes.Interface](
329+
&o.clusterKubeClient,
330+
resyncPeriod,
331+
remoteinformers.WithTweakListOptions[kubernetes.Interface](
332+
func(options *metav1.ListOptions) {
333+
options.LabelSelector = labels.SelectorFromSet(map[string]string{
334+
"app.kubernetes.io/managed-by": naming.RemoteOperatorAppNameWithDomain,
335+
}).String()
336+
},
337+
),
338+
)
339+
328340
scyllaOperatorConfigInformers := scyllainformers.NewSharedInformerFactoryWithOptions(o.scyllaClient, resyncPeriod, scyllainformers.WithTweakListOptions(
329341
func(options *metav1.ListOptions) {
330342
options.FieldSelector = fields.OneTermEqualSelector("metadata.name", naming.SingletonName).String()
@@ -476,6 +488,8 @@ func (o *OperatorOptions) run(ctx context.Context, streams genericclioptions.IOS
476488
&o.clusterScyllaClient,
477489
scyllaInformers.Scylla().V1alpha1().ScyllaDBClusters(),
478490
scyllaInformers.Scylla().V1alpha1().ScyllaOperatorConfigs(),
491+
kubeInformers.Core().V1().ConfigMaps(),
492+
kubeInformers.Core().V1().Secrets(),
479493
remoteScyllaInformer.ForResource(&scyllav1alpha1.RemoteOwner{}, remoteinformers.ClusterListWatch[scyllaversionedclient.Interface]{
480494
ListFunc: func(client remoteclient.ClusterClientInterface[scyllaversionedclient.Interface], cluster, ns string) cache.ListFunc {
481495
return func(options metav1.ListOptions) (runtime.Object, error) {
@@ -616,6 +630,46 @@ func (o *OperatorOptions) run(ctx context.Context, streams genericclioptions.IOS
616630
}
617631
},
618632
}),
633+
remoteOperatorManagedResourcesOnlyInformer.ForResource(&corev1.ConfigMap{}, remoteinformers.ClusterListWatch[kubernetes.Interface]{
634+
ListFunc: func(client remoteclient.ClusterClientInterface[kubernetes.Interface], cluster, ns string) cache.ListFunc {
635+
return func(options metav1.ListOptions) (runtime.Object, error) {
636+
clusterClient, err := client.Cluster(cluster)
637+
if err != nil {
638+
return nil, err
639+
}
640+
return clusterClient.CoreV1().ConfigMaps(ns).List(ctx, options)
641+
}
642+
},
643+
WatchFunc: func(client remoteclient.ClusterClientInterface[kubernetes.Interface], cluster, ns string) cache.WatchFunc {
644+
return func(options metav1.ListOptions) (watch.Interface, error) {
645+
clusterClient, err := client.Cluster(cluster)
646+
if err != nil {
647+
return nil, err
648+
}
649+
return clusterClient.CoreV1().ConfigMaps(ns).Watch(ctx, options)
650+
}
651+
},
652+
}),
653+
remoteOperatorManagedResourcesOnlyInformer.ForResource(&corev1.Secret{}, remoteinformers.ClusterListWatch[kubernetes.Interface]{
654+
ListFunc: func(client remoteclient.ClusterClientInterface[kubernetes.Interface], cluster, ns string) cache.ListFunc {
655+
return func(options metav1.ListOptions) (runtime.Object, error) {
656+
clusterClient, err := client.Cluster(cluster)
657+
if err != nil {
658+
return nil, err
659+
}
660+
return clusterClient.CoreV1().Secrets(ns).List(ctx, options)
661+
}
662+
},
663+
WatchFunc: func(client remoteclient.ClusterClientInterface[kubernetes.Interface], cluster, ns string) cache.WatchFunc {
664+
return func(options metav1.ListOptions) (watch.Interface, error) {
665+
clusterClient, err := client.Cluster(cluster)
666+
if err != nil {
667+
return nil, err
668+
}
669+
return clusterClient.CoreV1().Secrets(ns).Watch(ctx, options)
670+
}
671+
},
672+
}),
619673
)
620674
if err != nil {
621675
return fmt.Errorf("can't create ScyllaDBCluster controller: %w", err)
@@ -672,6 +726,12 @@ func (o *OperatorOptions) run(ctx context.Context, streams genericclioptions.IOS
672726
remoteScyllaPodInformer.Start(ctx.Done())
673727
}()
674728

729+
wg.Add(1)
730+
go func() {
731+
defer wg.Done()
732+
remoteOperatorManagedResourcesOnlyInformer.Start(ctx.Done())
733+
}()
734+
675735
wg.Add(1)
676736
go func() {
677737
defer wg.Done()

pkg/controller/scylladbcluster/conditions.go

+4
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ const (
1515
remoteEndpointsControllerDegradedCondition = "RemoteEndpointsControllerDegraded"
1616
scyllaDBClusterFinalizerProgressingCondition = "ScyllaDBClusterFinalizerProgressing"
1717
scyllaDBClusterFinalizerDegradedCondition = "ScyllaDBClusterFinalizerDegraded"
18+
remoteConfigMapControllerProgressingCondition = "RemoteConfigMapControllerProgressing"
19+
remoteConfigMapControllerDegradedCondition = "RemoteConfigMapControllerDegraded"
20+
remoteSecretControllerProgressingCondition = "RemoteSecretControllerProgressing"
21+
remoteSecretControllerDegradedCondition = "RemoteSecretControllerDegraded"
1822
)

pkg/controller/scylladbcluster/controller.go

+80
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package scylladbcluster
33
import (
44
"context"
55
"fmt"
6+
corev1informers "k8s.io/client-go/informers/core/v1"
67
"sync"
78
"time"
89

@@ -54,6 +55,8 @@ type Controller struct {
5455

5556
scyllaDBClusterLister scyllav1alpha1listers.ScyllaDBClusterLister
5657
scyllaOperatorConfigLister scyllav1alpha1listers.ScyllaOperatorConfigLister
58+
configMapLister corev1listers.ConfigMapLister
59+
secretLister corev1listers.SecretLister
5760

5861
remoteRemoteOwnerLister remotelister.GenericClusterLister[scyllav1alpha1listers.RemoteOwnerLister]
5962
remoteScyllaDBDatacenterLister remotelister.GenericClusterLister[scyllav1alpha1listers.ScyllaDBDatacenterLister]
@@ -62,6 +65,8 @@ type Controller struct {
6265
remoteEndpointSliceLister remotelister.GenericClusterLister[discoveryv1listers.EndpointSliceLister]
6366
remoteEndpointsLister remotelister.GenericClusterLister[corev1listers.EndpointsLister]
6467
remotePodLister remotelister.GenericClusterLister[corev1listers.PodLister]
68+
remoteConfigMapLister remotelister.GenericClusterLister[corev1listers.ConfigMapLister]
69+
remoteSecretLister remotelister.GenericClusterLister[corev1listers.SecretLister]
6570

6671
cachesToSync []cache.InformerSynced
6772

@@ -78,13 +83,17 @@ func NewController(
7883
scyllaRemoteClient remoteclient.ClusterClientInterface[scyllaclient.Interface],
7984
scyllaDBClusterInformer scyllav1alpha1informers.ScyllaDBClusterInformer,
8085
scyllaOperatorConfigInformer scyllav1alpha1informers.ScyllaOperatorConfigInformer,
86+
configMapInformer corev1informers.ConfigMapInformer,
87+
secretInformer corev1informers.SecretInformer,
8188
remoteRemoteOwnerInformer remoteinformers.GenericClusterInformer,
8289
remoteScyllaDBDatacenterInformer remoteinformers.GenericClusterInformer,
8390
remoteNamespaceInformer remoteinformers.GenericClusterInformer,
8491
remoteServiceInformer remoteinformers.GenericClusterInformer,
8592
remoteEndpointSliceInformer remoteinformers.GenericClusterInformer,
8693
remoteEndpointsInformer remoteinformers.GenericClusterInformer,
8794
remotePodInformer remoteinformers.GenericClusterInformer,
95+
remoteConfigMapInformer remoteinformers.GenericClusterInformer,
96+
remoteSecretInformer remoteinformers.GenericClusterInformer,
8897
) (*Controller, error) {
8998
eventBroadcaster := record.NewBroadcaster()
9099
eventBroadcaster.StartStructuredLogging(0)
@@ -98,6 +107,8 @@ func NewController(
98107

99108
scyllaDBClusterLister: scyllaDBClusterInformer.Lister(),
100109
scyllaOperatorConfigLister: scyllaOperatorConfigInformer.Lister(),
110+
configMapLister: configMapInformer.Lister(),
111+
secretLister: secretInformer.Lister(),
101112

102113
remoteRemoteOwnerLister: remotelister.NewClusterLister(scyllav1alpha1listers.NewRemoteOwnerLister, remoteRemoteOwnerInformer.Indexer().Cluster),
103114
remoteScyllaDBDatacenterLister: remotelister.NewClusterLister(scyllav1alpha1listers.NewScyllaDBDatacenterLister, remoteScyllaDBDatacenterInformer.Indexer().Cluster),
@@ -106,16 +117,23 @@ func NewController(
106117
remoteEndpointSliceLister: remotelister.NewClusterLister(discoveryv1listers.NewEndpointSliceLister, remoteEndpointSliceInformer.Indexer().Cluster),
107118
remoteEndpointsLister: remotelister.NewClusterLister(corev1listers.NewEndpointsLister, remoteEndpointsInformer.Indexer().Cluster),
108119
remotePodLister: remotelister.NewClusterLister(corev1listers.NewPodLister, remotePodInformer.Indexer().Cluster),
120+
remoteConfigMapLister: remotelister.NewClusterLister(corev1listers.NewConfigMapLister, remoteConfigMapInformer.Indexer().Cluster),
121+
remoteSecretLister: remotelister.NewClusterLister(corev1listers.NewSecretLister, remoteSecretInformer.Indexer().Cluster),
109122

110123
cachesToSync: []cache.InformerSynced{
111124
scyllaDBClusterInformer.Informer().HasSynced,
125+
scyllaOperatorConfigInformer.Informer().HasSynced,
126+
configMapInformer.Informer().HasSynced,
127+
secretInformer.Informer().HasSynced,
112128
remoteRemoteOwnerInformer.Informer().HasSynced,
113129
remoteScyllaDBDatacenterInformer.Informer().HasSynced,
114130
remoteNamespaceInformer.Informer().HasSynced,
115131
remoteServiceInformer.Informer().HasSynced,
116132
remoteEndpointSliceInformer.Informer().HasSynced,
117133
remoteEndpointsInformer.Informer().HasSynced,
118134
remotePodInformer.Informer().HasSynced,
135+
remoteConfigMapInformer.Informer().HasSynced,
136+
remoteSecretInformer.Informer().HasSynced,
119137
},
120138

121139
eventRecorder: eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: "scylladbcluster-controller"}),
@@ -211,6 +229,22 @@ func NewController(
211229
},
212230
)
213231

232+
remoteConfigMapInformer.Informer().AddEventHandler(
233+
cache.ResourceEventHandlerFuncs{
234+
AddFunc: scc.addRemoteConfigMap,
235+
UpdateFunc: scc.updateRemoteConfigMap,
236+
DeleteFunc: scc.deleteRemoteConfigMap,
237+
},
238+
)
239+
240+
remoteSecretInformer.Informer().AddEventHandler(
241+
cache.ResourceEventHandlerFuncs{
242+
AddFunc: scc.addRemoteSecret,
243+
UpdateFunc: scc.updateRemoteSecret,
244+
DeleteFunc: scc.deleteRemoteSecret,
245+
},
246+
)
247+
214248
err = utilerrors.NewAggregate(errs)
215249
if err != nil {
216250
return nil, fmt.Errorf("can't register event handlers: %w", err)
@@ -540,3 +574,49 @@ func (scc *Controller) deleteRemotePod(obj interface{}) {
540574
scc.enqueueThroughParentLabel,
541575
)
542576
}
577+
578+
func (scc *Controller) addRemoteConfigMap(obj interface{}) {
579+
scc.handlers.HandleAdd(
580+
obj.(*corev1.ConfigMap),
581+
scc.enqueueThroughParentLabel,
582+
)
583+
}
584+
585+
func (scc *Controller) updateRemoteConfigMap(old, cur interface{}) {
586+
scc.handlers.HandleUpdate(
587+
old.(*corev1.ConfigMap),
588+
cur.(*corev1.ConfigMap),
589+
scc.enqueueThroughParentLabel,
590+
scc.deleteRemoteConfigMap,
591+
)
592+
}
593+
594+
func (scc *Controller) deleteRemoteConfigMap(obj interface{}) {
595+
scc.handlers.HandleDelete(
596+
obj,
597+
scc.enqueueThroughParentLabel,
598+
)
599+
}
600+
601+
func (scc *Controller) addRemoteSecret(obj interface{}) {
602+
scc.handlers.HandleAdd(
603+
obj.(*corev1.Secret),
604+
scc.enqueueThroughParentLabel,
605+
)
606+
}
607+
608+
func (scc *Controller) updateRemoteSecret(old, cur interface{}) {
609+
scc.handlers.HandleUpdate(
610+
old.(*corev1.Secret),
611+
cur.(*corev1.Secret),
612+
scc.enqueueThroughParentLabel,
613+
scc.deleteRemoteSecret,
614+
)
615+
}
616+
617+
func (scc *Controller) deleteRemoteSecret(obj interface{}) {
618+
scc.handlers.HandleDelete(
619+
obj,
620+
scc.enqueueThroughParentLabel,
621+
)
622+
}

0 commit comments

Comments
 (0)