diff --git a/cmd/controller-manager/main.go b/cmd/controller-manager/main.go index 73081a19..7980849d 100644 --- a/cmd/controller-manager/main.go +++ b/cmd/controller-manager/main.go @@ -9,6 +9,7 @@ import ( "github.com/ironcore-dev/controller-utils/configutils" ironcorenetv1alpha1 "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1" + apinetclient "github.com/ironcore-dev/ironcore-net/internal/client" "github.com/ironcore-dev/ironcore-net/internal/controllers" ironcorenet "github.com/ironcore-dev/ironcore-net/internal/controllers/certificate/ironcore-net" "github.com/ironcore-dev/ironcore-net/internal/controllers/scheduler" @@ -62,6 +63,7 @@ func main() { flag.Parse() ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + ctx := ctrl.SetupSignalHandler() cfg, err := configutils.GetConfig() if err != nil { @@ -165,6 +167,11 @@ func main() { os.Exit(1) } + if err := apinetclient.SetupNetworkInterfaceNetworkNameFieldIndexer(ctx, mgr.GetFieldIndexer()); err != nil { + setupLog.Error(err, "unable to setup field indexer", "field", apinetclient.NetworkInterfaceSpecNetworkRefNameField) + os.Exit(1) + } + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { setupLog.Error(err, "unable to set up health check") os.Exit(1) diff --git a/internal/client/client.go b/internal/client/client.go index 84dfb5e5..f4fa1dd9 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -17,6 +17,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +const NetworkInterfaceSpecNetworkRefNameField = "spec.networkRef.name" + func ClaimNetworkInterfaceNAT( ctx context.Context, c client.Client, @@ -126,3 +128,10 @@ func ReleaseNetworkInterfaceNAT(ctx context.Context, c client.Client, nic *v1alp return nil }) } + +func SetupNetworkInterfaceNetworkNameFieldIndexer(ctx context.Context, indexer client.FieldIndexer) error { + return indexer.IndexField(ctx, &v1alpha1.NetworkInterface{}, NetworkInterfaceSpecNetworkRefNameField, func(obj client.Object) []string { + nic := obj.(*v1alpha1.NetworkInterface) + return []string{nic.Spec.NetworkRef.Name} + }) +} diff --git a/internal/controllers/controllers_suite_test.go b/internal/controllers/controllers_suite_test.go index 853e5d14..0eecf933 100644 --- a/internal/controllers/controllers_suite_test.go +++ b/internal/controllers/controllers_suite_test.go @@ -12,6 +12,7 @@ import ( "github.com/ironcore-dev/controller-utils/buildutils" "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1" + apinetclient "github.com/ironcore-dev/ironcore-net/internal/client" ironcorenet "github.com/ironcore-dev/ironcore-net/internal/controllers/certificate/ironcore-net" "github.com/ironcore-dev/ironcore-net/internal/controllers/scheduler" "github.com/ironcore-dev/ironcore-net/utils/expectations" @@ -171,6 +172,9 @@ var _ = BeforeSuite(func() { mgrCtx, cancel := context.WithCancel(context.Background()) DeferCleanup(cancel) + + Expect(apinetclient.SetupNetworkInterfaceNetworkNameFieldIndexer(mgrCtx, k8sManager.GetFieldIndexer())).To(Succeed()) + go func() { defer GinkgoRecover() Expect(k8sManager.Start(mgrCtx)).To(Succeed(), "failed to start manager") diff --git a/internal/controllers/natgateway_controller.go b/internal/controllers/natgateway_controller.go index 7c4dd8f7..15f5d9fd 100644 --- a/internal/controllers/natgateway_controller.go +++ b/internal/controllers/natgateway_controller.go @@ -162,6 +162,7 @@ func (r *NATGatewayReconciler) manageNATTable( nicList := &v1alpha1.NetworkInterfaceList{} if err := r.List(ctx, nicList, client.InNamespace(natGateway.Namespace), + client.MatchingFields{apinetclient.NetworkInterfaceSpecNetworkRefNameField: natGateway.Spec.NetworkRef.Name}, ); err != nil { return 0, 0, fmt.Errorf("error listing network interfaces: %w", err) } diff --git a/internal/controllers/natgateway_controller_test.go b/internal/controllers/natgateway_controller_test.go index 7944075e..4bd78a46 100644 --- a/internal/controllers/natgateway_controller_test.go +++ b/internal/controllers/natgateway_controller_test.go @@ -17,6 +17,7 @@ import ( var _ = Describe("NATGatewayController", func() { ns := SetupNamespace(&k8sClient) network := SetupNetwork(ns) + networkWithoutNAT := SetupNetwork(ns) It("should correctly reconcile the NAT gateway", func(ctx SpecContext) { By("creating a NAT gateway") @@ -51,6 +52,20 @@ var _ = Describe("NATGatewayController", func() { } Expect(k8sClient.Create(ctx, nic)).To(Succeed()) + By("creating a network interface using network not claiming NAT Gateway") + nic1 := &v1alpha1.NetworkInterface{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns.Name, + GenerateName: "nic-", + }, + Spec: v1alpha1.NetworkInterfaceSpec{ + NodeRef: corev1.LocalObjectReference{Name: "my-node"}, + NetworkRef: corev1.LocalObjectReference{Name: networkWithoutNAT.Name}, + IPs: []net.IP{net.MustParseIP("10.0.0.2")}, + }, + } + Expect(k8sClient.Create(ctx, nic1)).To(Succeed()) + By("waiting for the NAT table to be updated") natTable := &v1alpha1.NATTable{ ObjectMeta: metav1.ObjectMeta{