Skip to content

Commit 878e1a5

Browse files
committed
Namespace Management at Scale
1 parent df841cf commit 878e1a5

45 files changed

Lines changed: 1659 additions & 541 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NOTICE.txt

Lines changed: 396 additions & 396 deletions
Large diffs are not rendered by default.

cmd/manager/main.go

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
corev1 "k8s.io/api/core/v1"
2828
policyv1 "k8s.io/api/policy/v1"
2929
apierrors "k8s.io/apimachinery/pkg/api/errors"
30+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3031
"k8s.io/apimachinery/pkg/labels"
3132
"k8s.io/apimachinery/pkg/runtime/schema"
3233
"k8s.io/apimachinery/pkg/selection"
@@ -44,6 +45,7 @@ import (
4445
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
4546
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
4647
crwebhook "sigs.k8s.io/controller-runtime/pkg/webhook"
48+
"sigs.k8s.io/yaml"
4749

4850
"github.com/elastic/cloud-on-k8s/v3/pkg/about"
4951
agentv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/agent/v1alpha1"
@@ -69,6 +71,7 @@ import (
6971
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/container"
7072
commonesclient "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/esclient"
7173
commonlicense "github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/license"
74+
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/nsmatch"
7275
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/operator"
7376
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/password"
7477
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/common/reconciler"
@@ -86,6 +89,7 @@ import (
8689
licensetrial "github.com/elastic/cloud-on-k8s/v3/pkg/controller/license/trial"
8790
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/logstash"
8891
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/maps"
92+
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/namespace"
8993
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/packageregistry"
9094
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/remotecluster"
9195
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/stackconfigpolicy"
@@ -593,7 +597,29 @@ func startOperator(ctx context.Context) error {
593597
log.Error(err, "Failed to parse managed namespaces flag")
594598
return err
595599
}
600+
601+
// Parse the optional namespace label selector. This field is config-file
602+
// only (a metav1.LabelSelector object); it has no CLI flag. When set,
603+
// the operator runs in dynamic mode: the cache is cluster-wide and a
604+
// Matcher consulted by a predicate on every controller's watches
605+
// evaluates the selector against Namespace labels per event.
606+
parsedNsSelector, err := parseNSSelector(log)
607+
if err != nil {
608+
return err
609+
}
610+
dynamicNSSelector := parsedNsSelector != nil
611+
612+
// Validate that dynamic ns selector cannot co-exist with the fixed list of managed namespaces.
613+
if dynamicNSSelector && len(managedNamespaces) > 0 {
614+
log.Error(errors.New("namespaces and namespaceSelector are mutually exclusive"), "Invalid configuration")
615+
return errors.New("namespaces and namespaceSelector are mutually exclusive")
616+
}
617+
596618
switch {
619+
case dynamicNSSelector:
620+
log.Info("Operator configured to manage namespaces dynamically via selector",
621+
"selector", parsedNsSelector.String(),
622+
"operator_namespace", operatorNamespace)
597623
case len(managedNamespaces) == 0:
598624
log.Info("Operator configured to manage all namespaces")
599625
case len(managedNamespaces) == 1 && managedNamespaces[0] == operatorNamespace:
@@ -616,8 +642,10 @@ func startOperator(ctx context.Context) error {
616642
DefaultTransform: cache.TransformStripManagedFields(),
617643
ByObject: byObject,
618644
}
619-
for _, ns := range managedNamespaces {
620-
opts.Cache.DefaultNamespaces[ns] = cache.Config{}
645+
if !dynamicNSSelector {
646+
for _, ns := range managedNamespaces {
647+
opts.Cache.DefaultNamespaces[ns] = cache.Config{}
648+
}
621649
}
622650

623651
// only expose prometheus metrics if provided a non-zero port
@@ -730,6 +758,8 @@ func startOperator(ctx context.Context) error {
730758
return err
731759
}
732760

761+
nsMatchNotifier := nsmatch.NewMatchNotifier(mgr.GetCache(), parsedNsSelector, operatorNamespace)
762+
733763
params := operator.Parameters{
734764
Dialer: dialer,
735765
ElasticsearchObservationInterval: viper.GetDuration(operator.ElasticsearchObservationIntervalFlag),
@@ -752,6 +782,7 @@ func startOperator(ctx context.Context) error {
752782
SetDefaultSecurityContext: setDefaultSecurityContext,
753783
ValidateStorageClass: viper.GetBool(operator.ValidateStorageClassFlag),
754784
Tracer: tracer,
785+
NamespaceMatchNotifier: nsMatchNotifier,
755786
}
756787

757788
if viper.GetBool(operator.EnableWebhookFlag) {
@@ -940,6 +971,7 @@ func registerControllers(mgr manager.Manager, params operator.Parameters, access
940971
{name: "PackageRegistry", registerFunc: packageregistry.Add},
941972
{name: "StackConfigPolicy", registerFunc: stackconfigpolicy.Add},
942973
{name: "Logstash", registerFunc: logstash.Add},
974+
{name: "Namespace", registerFunc: namespace.Add},
943975
}
944976

945977
for _, c := range controllers {
@@ -1101,3 +1133,26 @@ func buildByObject(restrictWatchedResources bool) (map[client.Object]cache.ByObj
11011133

11021134
return byObject, nil
11031135
}
1136+
1137+
func parseNSSelector(log logr.Logger) (labels.Selector, error) {
1138+
if !viper.IsSet(operator.NamespaceSelectorFlag) {
1139+
return nil, nil
1140+
}
1141+
raw := viper.Get(operator.NamespaceSelectorFlag)
1142+
yamlBytes, err := yaml.Marshal(raw)
1143+
if err != nil {
1144+
log.Error(err, "Failed to serialize namespace-selector for parsing")
1145+
return nil, err
1146+
}
1147+
var ls metav1.LabelSelector
1148+
if err := yaml.Unmarshal(yamlBytes, &ls); err != nil {
1149+
log.Error(err, "Failed to parse namespace-selector")
1150+
return nil, err
1151+
}
1152+
sel, err := metav1.LabelSelectorAsSelector(&ls)
1153+
if err != nil {
1154+
log.Error(err, "Invalid namespace-selector")
1155+
return nil, err
1156+
}
1157+
return sel, nil
1158+
}

cmd/manager/validation.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,27 +86,28 @@ func setupWebhook(
8686
}
8787

8888
checker := commonlicense.NewLicenseChecker(mgr.GetClient(), params.OperatorNamespace)
89+
matcher := params.NamespaceMatchNotifier
8990
// setup webhooks for supported types
90-
commonwebhook.RegisterResourceWebhook(mgr, apmv1.WebhookPath, checker, managedNamespaces, apmv1.Validate, "APM Server")
91-
commonwebhook.RegisterResourceWebhook(mgr, apmv1beta1.WebhookPath, checker, managedNamespaces, apmv1beta1.Validate, "APM Server")
92-
commonwebhook.RegisterResourceWebhook(mgr, beatv1beta1.WebhookPath, checker, managedNamespaces, beatv1beta1.Validate, "Beat")
93-
commonwebhook.RegisterResourceWebhook(mgr, entv1.WebhookPath, checker, managedNamespaces, entv1.Validate, "Enterprise Search")
94-
commonwebhook.RegisterResourceWebhook(mgr, entv1beta1.WebhookPath, checker, managedNamespaces, entv1beta1.Validate, "Enterprise Search")
95-
commonwebhook.RegisterResourceWebhook(mgr, esv1beta1.WebhookPath, checker, managedNamespaces, esv1beta1.Validate, "Elasticsearch")
96-
commonwebhook.RegisterResourceWebhook(mgr, kbv1.WebhookPath, checker, managedNamespaces, kbv1.Validate, "Kibana")
97-
commonwebhook.RegisterResourceWebhook(mgr, kbv1beta1.WebhookPath, checker, managedNamespaces, kbv1beta1.Validate, "Kibana")
98-
commonwebhook.RegisterResourceWebhook(mgr, emsv1alpha1.WebhookPath, checker, managedNamespaces, emsv1alpha1.Validate, "Elastic Maps Server")
99-
commonwebhook.RegisterResourceWebhook(mgr, eprv1alpha1.WebhookPath, checker, managedNamespaces, eprv1alpha1.Validate, "Package Registry")
100-
commonwebhook.RegisterResourceWebhook(mgr, policyv1alpha1.WebhookPath, checker, managedNamespaces, policyv1alpha1.Validate, "Stack Config Policy")
91+
commonwebhook.RegisterResourceWebhook(mgr, apmv1.WebhookPath, checker, managedNamespaces, matcher, apmv1.Validate, "APM Server")
92+
commonwebhook.RegisterResourceWebhook(mgr, apmv1beta1.WebhookPath, checker, managedNamespaces, matcher, apmv1beta1.Validate, "APM Server")
93+
commonwebhook.RegisterResourceWebhook(mgr, beatv1beta1.WebhookPath, checker, managedNamespaces, matcher, beatv1beta1.Validate, "Beat")
94+
commonwebhook.RegisterResourceWebhook(mgr, entv1.WebhookPath, checker, managedNamespaces, matcher, entv1.Validate, "Enterprise Search")
95+
commonwebhook.RegisterResourceWebhook(mgr, entv1beta1.WebhookPath, checker, managedNamespaces, matcher, entv1beta1.Validate, "Enterprise Search")
96+
commonwebhook.RegisterResourceWebhook(mgr, esv1beta1.WebhookPath, checker, managedNamespaces, matcher, esv1beta1.Validate, "Elasticsearch")
97+
commonwebhook.RegisterResourceWebhook(mgr, kbv1.WebhookPath, checker, managedNamespaces, matcher, kbv1.Validate, "Kibana")
98+
commonwebhook.RegisterResourceWebhook(mgr, kbv1beta1.WebhookPath, checker, managedNamespaces, matcher, kbv1beta1.Validate, "Kibana")
99+
commonwebhook.RegisterResourceWebhook(mgr, emsv1alpha1.WebhookPath, checker, managedNamespaces, matcher, emsv1alpha1.Validate, "Elastic Maps Server")
100+
commonwebhook.RegisterResourceWebhook(mgr, eprv1alpha1.WebhookPath, checker, managedNamespaces, matcher, eprv1alpha1.Validate, "Package Registry")
101+
commonwebhook.RegisterResourceWebhook(mgr, policyv1alpha1.WebhookPath, checker, managedNamespaces, matcher, policyv1alpha1.Validate, "Stack Config Policy")
101102

102103
// Logstash, Elasticsearch v1, ElasticsearchAutoscaling, and AutoOps validating webhooks are wired up
103104
// separately so their validators can use the API client and/or embed license checks. Elasticsearch
104105
// v1beta1 remains in the RegisterResourceWebhook list above because it only needs a ValidateFunc.
105-
esvalidation.RegisterWebhook(mgr, params.ValidateStorageClass, exposedNodeLabels, checker, managedNamespaces)
106-
esavalidation.RegisterWebhook(mgr, params.ValidateStorageClass, checker, managedNamespaces)
107-
lsvalidation.RegisterWebhook(mgr, params.ValidateStorageClass, managedNamespaces)
108-
autoopsvalidation.RegisterWebhook(mgr, checker, managedNamespaces)
109-
agentcontroller.RegisterWebhook(mgr, checker, managedNamespaces)
106+
esvalidation.RegisterWebhook(mgr, params.ValidateStorageClass, exposedNodeLabels, checker, managedNamespaces, matcher)
107+
esavalidation.RegisterWebhook(mgr, params.ValidateStorageClass, checker, managedNamespaces, matcher)
108+
lsvalidation.RegisterWebhook(mgr, params.ValidateStorageClass, managedNamespaces, matcher)
109+
autoopsvalidation.RegisterWebhook(mgr, checker, managedNamespaces, matcher)
110+
agentcontroller.RegisterWebhook(mgr, checker, managedNamespaces, matcher)
110111

111112
// wait for the secret to be populated in the local filesystem before returning
112113
interval := time.Second * 1

deploy/eck-operator/templates/configmap.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ data:
7171
{{- with .Values.managedNamespaces }}
7272
namespaces: [{{ join "," . }}]
7373
{{- end }}
74+
{{- with .Values.namespaceSelector }}
75+
namespace-selector:
76+
{{- . | toYaml | nindent 6 }}
77+
{{- end }}
7478
operator-namespace: {{ .Release.Namespace }}
7579
enable-leader-election: {{ .Values.config.enableLeaderElection }}
7680
elasticsearch-observation-interval: {{ .Values.config.elasticsearchObservationInterval }}

deploy/eck-operator/templates/validate-chart.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,13 @@
2727
{{- fail "Leader election must be enabled with more than one replica" -}}
2828
{{- end -}}
2929
{{- end -}}
30+
31+
{{- if not (empty .Values.namespaceSelector) -}}
32+
{{- if not (empty .Values.managedNamespaces) -}}
33+
{{- fail "namespaceSelector and managedNamespaces are mutually exclusive" -}}
34+
{{- end -}}
35+
36+
{{- if not .Values.createClusterScopedResources -}}
37+
{{- fail "namespaceSelector requires createClusterScopedResources to be true" -}}
38+
{{- end -}}
39+
{{- end -}}

deploy/eck-operator/values.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,25 @@ nameOverride: "elastic-operator"
55
fullnameOverride: "elastic-operator"
66

77
# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces.
8+
# Mutually exclusive with namespaceSelector.
89
managedNamespaces: []
910

11+
# namespaceSelector is a Kubernetes label selector that dynamically controls which namespaces the operator manages.
12+
# The operator watches all namespaces cluster-wide and filters events by matching each namespace's labels against
13+
# this selector at runtime. When a namespace gains or loses the matching labels the operator automatically
14+
# starts or stops managing resources in that namespace without a restart.
15+
# Mutually exclusive with managedNamespaces. Requires createClusterScopedResources: true.
16+
# Example:
17+
# namespaceSelector:
18+
# matchLabels:
19+
# eck-managed: "true"
20+
# namespaceSelector:
21+
# matchExpressions:
22+
# - key: environment
23+
# operator: In
24+
# values: [production, staging]
25+
namespaceSelector: {}
26+
1027
# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart.
1128
# Note that CRDs are global resources and require cluster admin privileges to install.
1229
# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences.

docs/reference/third-party-dependencies/main.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ This page lists the third-party dependencies used to build {{eck}} from the main
6666
| [k8s.io/utils](https://github.com/kubernetes/utils) | v0.0.0-20260319190234-28399d86e0b5 | Apache-2.0 |
6767
| [sigs.k8s.io/controller-runtime](https://sigs.k8s.io/controller-runtime) | v0.24.1 | Apache-2.0 |
6868
| [sigs.k8s.io/controller-tools](https://sigs.k8s.io/controller-tools) | v0.21.0 | Apache-2.0 |
69+
| [sigs.k8s.io/yaml](https://sigs.k8s.io/yaml) | v1.6.0 | Apache-2.0 |
6970

7071

7172
## Indirect dependencies [k8s-dependencies-indirect]
@@ -273,5 +274,4 @@ This page lists the third-party dependencies used to build {{eck}} from the main
273274
| [sigs.k8s.io/json](https://sigs.k8s.io/json) | v0.0.0-20250730193827-2d320260d730 | Apache-2.0 |
274275
| [sigs.k8s.io/randfill](https://sigs.k8s.io/randfill) | v1.0.0 | Apache-2.0 |
275276
| [sigs.k8s.io/structured-merge-diff/v6](https://sigs.k8s.io/structured-merge-diff/v6) | v6.4.0 | Apache-2.0 |
276-
| [sigs.k8s.io/yaml](https://sigs.k8s.io/yaml) | v1.6.0 | Apache-2.0 |
277277

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ require (
5555
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5
5656
sigs.k8s.io/controller-runtime v0.24.1
5757
sigs.k8s.io/controller-tools v0.21.0
58+
sigs.k8s.io/yaml v1.6.0
5859
)
5960

6061
require (
@@ -170,6 +171,7 @@ require (
170171
github.com/spf13/cast v1.10.0 // indirect
171172
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
172173
github.com/stoewer/go-strcase v1.3.0 // indirect
174+
github.com/stretchr/objx v0.5.2 // indirect
173175
github.com/subosito/gotenv v1.6.0 // indirect
174176
github.com/tidwall/gjson v1.19.0 // indirect
175177
github.com/tidwall/match v1.1.1 // indirect
@@ -223,7 +225,6 @@ require (
223225
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
224226
sigs.k8s.io/randfill v1.0.0 // indirect
225227
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect
226-
sigs.k8s.io/yaml v1.6.0 // indirect
227228
)
228229

229230
// both of these dependencies are used by vegeta, but the version they use is older and did not include a licence. we require the licence and so pin both of these

pkg/controller/agent/controller.go

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import (
1414
apierrors "k8s.io/apimachinery/pkg/api/errors"
1515
"k8s.io/apimachinery/pkg/types"
1616
toolsevents "k8s.io/client-go/tools/events"
17+
"sigs.k8s.io/controller-runtime/pkg/client"
1718
"sigs.k8s.io/controller-runtime/pkg/controller"
1819
"sigs.k8s.io/controller-runtime/pkg/handler"
1920
"sigs.k8s.io/controller-runtime/pkg/manager"
2021
"sigs.k8s.io/controller-runtime/pkg/reconcile"
21-
"sigs.k8s.io/controller-runtime/pkg/source"
2222

2323
agentv1alpha1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/agent/v1alpha1"
2424
"github.com/elastic/cloud-on-k8s/v3/pkg/controller/association"
@@ -64,15 +64,16 @@ func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileAg
6464

6565
// addWatches adds watches for all resources this controller cares about
6666
func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAgent) error {
67+
m := r.NamespaceMatchNotifier
6768
// Watch for changes to Agent
6869
if err := c.Watch(
69-
source.Kind(mgr.GetCache(), &agentv1alpha1.Agent{}, &handler.TypedEnqueueRequestForObject[*agentv1alpha1.Agent]{})); err != nil {
70+
watches.NamespacedKind(m, mgr.GetCache(), &agentv1alpha1.Agent{}, &handler.TypedEnqueueRequestForObject[*agentv1alpha1.Agent]{})); err != nil {
7071
return err
7172
}
7273

7374
// Watch DaemonSets
7475
if err := c.Watch(
75-
source.Kind(mgr.GetCache(), &appsv1.DaemonSet{},
76+
watches.NamespacedKind(m, mgr.GetCache(), &appsv1.DaemonSet{},
7677
handler.TypedEnqueueRequestForOwner[*appsv1.DaemonSet](mgr.GetScheme(), mgr.GetRESTMapper(),
7778
&agentv1alpha1.Agent{}, handler.OnlyControllerOwner()),
7879
)); err != nil {
@@ -81,7 +82,7 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAgent)
8182

8283
// Watch Deployments
8384
if err := c.Watch(
84-
source.Kind(mgr.GetCache(), &appsv1.Deployment{},
85+
watches.NamespacedKind(m, mgr.GetCache(), &appsv1.Deployment{},
8586
handler.TypedEnqueueRequestForOwner[*appsv1.Deployment](mgr.GetScheme(), mgr.GetRESTMapper(),
8687
&agentv1alpha1.Agent{}, handler.OnlyControllerOwner()),
8788
)); err != nil {
@@ -90,7 +91,7 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAgent)
9091

9192
// Watch StatefulSets
9293
if err := c.Watch(
93-
source.Kind(mgr.GetCache(), &appsv1.StatefulSet{},
94+
watches.NamespacedKind(m, mgr.GetCache(), &appsv1.StatefulSet{},
9495
handler.TypedEnqueueRequestForOwner[*appsv1.StatefulSet](mgr.GetScheme(), mgr.GetRESTMapper(),
9596
&agentv1alpha1.Agent{}, handler.OnlyControllerOwner()),
9697
)); err != nil {
@@ -99,13 +100,13 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAgent)
99100

100101
// Watch Pods, to ensure `status.version` is correctly reconciled on any change.
101102
// Watching Deployments or DaemonSets only may lead to missing some events.
102-
if err := watches.WatchPods(mgr, c, NameLabelName); err != nil {
103+
if err := watches.WatchPods(mgr, c, m, NameLabelName); err != nil {
103104
return err
104105
}
105106

106107
// Watch Secrets
107108
if err := c.Watch(
108-
source.Kind(mgr.GetCache(), &corev1.Secret{},
109+
watches.NamespacedKind(m, mgr.GetCache(), &corev1.Secret{},
109110
handler.TypedEnqueueRequestForOwner[*corev1.Secret](mgr.GetScheme(), mgr.GetRESTMapper(),
110111
&agentv1alpha1.Agent{}, handler.OnlyControllerOwner()),
111112
)); err != nil {
@@ -115,23 +116,39 @@ func addWatches(mgr manager.Manager, c controller.Controller, r *ReconcileAgent)
115116
// Watch services - Agent in Fleet mode with Fleet Server enabled configures and exposes a Service
116117
// for Elastic Agents to connect to.
117118
if err := c.Watch(
118-
source.Kind(mgr.GetCache(), &corev1.Service{},
119+
watches.NamespacedKind(m, mgr.GetCache(), &corev1.Service{},
119120
handler.TypedEnqueueRequestForOwner[*corev1.Service](mgr.GetScheme(), mgr.GetRESTMapper(),
120121
&agentv1alpha1.Agent{}, handler.OnlyControllerOwner()),
121122
)); err != nil {
122123
return err
123124
}
124125

125126
// Watch soft-owned secrets (e.g. client certificate secrets for Fleet Server mTLS)
126-
if err := watches.WatchSoftOwnedSecrets(mgr, c, agentv1alpha1.Kind); err != nil {
127+
if err := watches.WatchSoftOwnedSecrets(mgr, c, r.NamespaceMatchNotifier, agentv1alpha1.Kind); err != nil {
127128
return err
128129
}
129130

130131
// Watch dynamically referenced Secrets
131-
return c.Watch(
132-
source.Kind(mgr.GetCache(), &corev1.Secret{},
133-
r.dynamicWatches.Secrets,
134-
))
132+
if err := c.Watch(watches.NamespacedKind(m, mgr.GetCache(), &corev1.Secret{}, r.dynamicWatches.Secrets)); err != nil {
133+
return err
134+
}
135+
return watches.WatchNamespaceFlips(c, mgr.GetClient(), r.NamespaceMatchNotifier, func() client.ObjectList {
136+
return &agentv1alpha1.AgentList{}
137+
})
138+
139+
// return watches.TypedWatchNamespaceFlips(c, mgr.GetClient(), r.NamespaceMatchNotifier, func(ctx context.Context, cl client.Client, ns *corev1.Namespace) (iter.Seq[client.Object], error) {
140+
// lst := &agentv1alpha1.AgentList{}
141+
// if err := cl.List(ctx, lst, client.InNamespace(ns.Name)); err != nil {
142+
// return nil, err
143+
// }
144+
// return func(yield func(client.Object) bool) {
145+
// for _, ob := range lst.Items {
146+
// if !yield(&ob) {
147+
// return
148+
// }
149+
// }
150+
// }, nil
151+
// })
135152
}
136153

137154
var _ reconcile.Reconciler = (*ReconcileAgent)(nil)
@@ -150,6 +167,9 @@ type ReconcileAgent struct {
150167
// Reconcile reads that state of the cluster for an Agent object and makes changes based on the state read
151168
// and what is in the Agent.Spec
152169
func (r *ReconcileAgent) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
170+
if !r.NamespaceMatchNotifier.Matches(ctx, request.Namespace) {
171+
return reconcile.Result{}, nil
172+
}
153173
ctx = common.NewReconciliationContext(ctx, &r.iteration, r.Tracer, controllerName, "agent_name", request)
154174
defer common.LogReconciliationRun(logconf.FromContext(ctx))()
155175
defer tracing.EndContextTransaction(ctx)

0 commit comments

Comments
 (0)