diff --git a/api/v2/config/controller.go b/api/v2/config/controller.go index f12a185..ab5ca92 100644 --- a/api/v2/config/controller.go +++ b/api/v2/config/controller.go @@ -132,9 +132,6 @@ func (c *NewControllerConfig) validate() error { if c.SeedConfig == nil { return fmt.Errorf("seed config must be specified") } - if c.SeedNamespace == "" { - return fmt.Errorf("seed namespace must be specified") - } if c.SeedAPIServerURL == "" { return fmt.Errorf("seed api server url must be specified") } diff --git a/api/v2/validation/firewalldeployment.go b/api/v2/validation/firewalldeployment.go index ab19882..a06e93c 100644 --- a/api/v2/validation/firewalldeployment.go +++ b/api/v2/validation/firewalldeployment.go @@ -49,9 +49,7 @@ func (*firewallDeploymentValidator) validateSpec(log logr.Logger, f *v2.Firewall }) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), f.Selector, "")) - } - - if !selector.Empty() { + } else if !selector.Empty() { labels := labels.Set(f.Template.Labels) if !selector.Matches(labels) { allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), f.Template.Labels, "`selector` does not match template `labels`")) diff --git a/controllers/deployment/controller.go b/controllers/deployment/controller.go index 6366b87..33f1c1d 100644 --- a/controllers/deployment/controller.go +++ b/controllers/deployment/controller.go @@ -31,7 +31,7 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M lastSetCreation: map[string]time.Time{}, }) - return ctrl.NewControllerManagedBy(mgr). + controller := ctrl.NewControllerManagedBy(mgr). For( &v2.FirewallDeployment{}, builder.WithPredicates( @@ -57,9 +57,13 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M ), ), ), - ). - WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))). - Complete(g) + ) + + if c.GetSeedNamespace() != "" { + controller = controller.WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))) + } + + return controller.Complete(g) } func SetupWebhookWithManager(log logr.Logger, mgr ctrl.Manager, c *config.ControllerConfig) error { diff --git a/controllers/deployment/infrastructure_status.go b/controllers/deployment/infrastructure_status.go index 1caa62b..93a9dcd 100644 --- a/controllers/deployment/infrastructure_status.go +++ b/controllers/deployment/infrastructure_status.go @@ -27,7 +27,7 @@ func (c *controller) updateInfrastructureStatus(r *controllers.Ctx[*v2.FirewallD }) err := c.c.GetSeedClient().Get(r.Ctx, client.ObjectKey{ - Namespace: c.c.GetSeedNamespace(), + Namespace: r.Target.Namespace, Name: infrastructureName, }, infraObj) if err != nil { @@ -129,7 +129,7 @@ func (c *controller) updateInfrastructureStatus(r *controllers.Ctx[*v2.FirewallD }) err = c.c.GetSeedClient().Get(r.Ctx, client.ObjectKey{ - Namespace: c.c.GetSeedNamespace(), + Namespace: r.Target.Namespace, Name: "acl", }, aclObj) if err != nil { @@ -150,6 +150,7 @@ func (c *controller) updateInfrastructureStatus(r *controllers.Ctx[*v2.FirewallD } func extractInfrastructureNameFromSeedNamespace(namespace string) (string, bool) { + // TODO: is this safe to not skip in the future? if !strings.HasPrefix(namespace, "shoot--") { return "", false } diff --git a/controllers/deployment/infrastructure_status_test.go b/controllers/deployment/infrastructure_status_test.go index 96fa1cb..b9c639e 100644 --- a/controllers/deployment/infrastructure_status_test.go +++ b/controllers/deployment/infrastructure_status_test.go @@ -12,6 +12,7 @@ import ( "github.com/metal-stack/metal-lib/pkg/pointer" "github.com/metal-stack/metal-lib/pkg/testcommon" "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -456,6 +457,11 @@ func Test_controller_updateInfrastructureStatus(t *testing.T) { err = ctrl.updateInfrastructureStatus(&controllers.Ctx[*v2.FirewallDeployment]{ Ctx: ctx, Log: log, + Target: &v2.FirewallDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + }, + }, }, "mycluster1", tt.ownedFirewalls) if diff := cmp.Diff(tt.wantErr, err, testcommon.ErrorStringComparer()); diff != "" { t.Errorf("error diff (+got -want):\n %s", diff) diff --git a/controllers/deployment/reconcile.go b/controllers/deployment/reconcile.go index 2b5625f..20f5056 100644 --- a/controllers/deployment/reconcile.go +++ b/controllers/deployment/reconcile.go @@ -83,7 +83,7 @@ func (c *controller) Reconcile(r *controllers.Ctx[*v2.FirewallDeployment]) error r.Log.Info("swapped latest set to shortest distance", "distance", v2.FirewallShortestDistance) } - infrastructureName, ok := extractInfrastructureNameFromSeedNamespace(c.c.GetSeedNamespace()) + infrastructureName, ok := extractInfrastructureNameFromSeedNamespace(r.Target.Namespace) if ok { var ownedFirewalls []*v2.Firewall for _, set := range ownedSets { diff --git a/controllers/firewall/controller.go b/controllers/firewall/controller.go index 6c18b9a..3ab23fd 100644 --- a/controllers/firewall/controller.go +++ b/controllers/firewall/controller.go @@ -88,7 +88,7 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M }), }) - return ctrl.NewControllerManagedBy(mgr). + controller := ctrl.NewControllerManagedBy(mgr). For( &v2.Firewall{}, builder.WithPredicates( @@ -99,9 +99,13 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M ), ). // don't think about owning the firewall monitor here, it's in the shoot cluster, we cannot watch two clusters with controller-runtime - Named("Firewall"). - WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))). - Complete(g) + Named("Firewall") + + if c.GetSeedNamespace() != "" { + controller = controller.WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))) + } + + return controller.Complete(g) } func SetupWebhookWithManager(log logr.Logger, mgr ctrl.Manager, c *config.ControllerConfig) error { diff --git a/controllers/generic_controller.go b/controllers/generic_controller.go index 39609b5..555e3fd 100644 --- a/controllers/generic_controller.go +++ b/controllers/generic_controller.go @@ -74,7 +74,7 @@ func (g *GenericController[O]) logger(req ctrl.Request) logr.Logger { } func (g GenericController[O]) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - if req.Namespace != g.namespace { // should already be filtered out through predicate, but we will check anyway + if g.namespace != "" && req.Namespace != g.namespace { // should already be filtered out through predicate, but we will check anyway return ctrl.Result{}, nil } diff --git a/controllers/monitor/controller.go b/controllers/monitor/controller.go index cc5d5ee..c84c2c4 100644 --- a/controllers/monitor/controller.go +++ b/controllers/monitor/controller.go @@ -22,7 +22,7 @@ func SetupWithManager(log logr.Logger, mgr ctrl.Manager, c *config.ControllerCon c: c, }).WithoutStatus() - return ctrl.NewControllerManagedBy(mgr). + controller := ctrl.NewControllerManagedBy(mgr). For(&v2.FirewallMonitor{}, builder.WithPredicates( predicate.Not( @@ -30,9 +30,13 @@ func SetupWithManager(log logr.Logger, mgr ctrl.Manager, c *config.ControllerCon ), ), ). - Named("FirewallMonitor"). - WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetShootNamespace()))). - Complete(g) + Named("FirewallMonitor") + + if c.GetSeedNamespace() != "" { + controller = controller.WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))) + } + + return controller.Complete(g) } func (c *controller) New() *v2.FirewallMonitor { diff --git a/controllers/monitor/reconcile.go b/controllers/monitor/reconcile.go index 4bcf1cb..55b2e50 100644 --- a/controllers/monitor/reconcile.go +++ b/controllers/monitor/reconcile.go @@ -37,7 +37,7 @@ func (c *controller) updateFirewallStatus(r *controllers.Ctx[*v2.FirewallMonitor fw := &v2.Firewall{ ObjectMeta: metav1.ObjectMeta{ Name: r.Target.Name, - Namespace: c.c.GetSeedNamespace(), + Namespace: r.Target.Namespace, }, } err := c.c.GetSeedClient().Get(r.Ctx, client.ObjectKeyFromObject(fw), fw) @@ -72,7 +72,7 @@ func (c *controller) rollSetAnnotation(r *controllers.Ctx[*v2.FirewallMonitor]) fw := &v2.Firewall{ ObjectMeta: metav1.ObjectMeta{ Name: r.Target.Name, - Namespace: c.c.GetSeedNamespace(), + Namespace: r.Target.Namespace, }, } diff --git a/controllers/set/controller.go b/controllers/set/controller.go index 06909c5..426a2ee 100644 --- a/controllers/set/controller.go +++ b/controllers/set/controller.go @@ -26,7 +26,7 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M c: c, }) - return ctrl.NewControllerManagedBy(mgr). + controller := ctrl.NewControllerManagedBy(mgr). For( &v2.FirewallSet{}, builder.WithPredicates( @@ -47,9 +47,13 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M ), ), ), - ). - WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))). - Complete(g) + ) + + if c.GetSeedNamespace() != "" { + controller = controller.WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))) + } + + return controller.Complete(g) } func SetupWebhookWithManager(log logr.Logger, mgr ctrl.Manager, c *config.ControllerConfig) error { diff --git a/controllers/update/controller.go b/controllers/update/controller.go index 991adde..3b4ba53 100644 --- a/controllers/update/controller.go +++ b/controllers/update/controller.go @@ -34,16 +34,20 @@ func SetupWithManager(log logr.Logger, recorder record.EventRecorder, mgr ctrl.M imageCache: newImageCache(c.GetMetal()), }).WithoutStatus() - return ctrl.NewControllerManagedBy(mgr). + controller := ctrl.NewControllerManagedBy(mgr). For( &v2.FirewallDeployment{}, builder.WithPredicates( v2.AnnotationAddedPredicate(v2.MaintenanceAnnotation), ), ). - Named("FirewallDeployment"). - WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))). - Complete(g) + Named("FirewallDeployment") + + if c.GetSeedNamespace() != "" { + controller = controller.WithEventFilter(predicate.NewPredicateFuncs(controllers.SkipOtherNamespace(c.GetSeedNamespace()))) + } + + return controller.Complete(g) } func (c *controller) New() *v2.FirewallDeployment { diff --git a/main.go b/main.go index f1b9f67..63e0dff 100644 --- a/main.go +++ b/main.go @@ -110,7 +110,7 @@ func main() { log.Fatalf("unable to create metal client %v", err) } - seedMgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + mgrConfig := ctrl.Options{ Scheme: scheme, Metrics: server.Options{ BindAddress: metricsAddr, @@ -121,15 +121,21 @@ func main() { }), Cache: cache.Options{ SyncPeriod: &reconcileInterval, - DefaultNamespaces: map[string]cache.Config{ - namespace: {}, - }, }, HealthProbeBindAddress: healthAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "firewall-controller-manager-leader-election", GracefulShutdownTimeout: &gracefulShutdownTimeout, - }) + } + + if namespace != "" { + l.Info("running in dedicated namespace only", "namespace", namespace) + mgrConfig.Cache.DefaultNamespaces = map[string]cache.Config{ + namespace: {}, + } + } + + seedMgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrConfig) if err != nil { log.Fatalf("unable to setup firewall-controller-manager %v", err) }