From 43b6f3967440885a16c888c9e785abe7e906c900 Mon Sep 17 00:00:00 2001 From: Francesco Torta <62566275+fra98@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:12:46 +0100 Subject: [PATCH] fixup! feature: ipam support reserved networks --- cmd/liqo-controller-manager/main.go | 2 +- .../modules/authentication.go | 3 +- .../modules/networking.go | 83 ++++++++++++++++++- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/cmd/liqo-controller-manager/main.go b/cmd/liqo-controller-manager/main.go index 000290e989..3146880de6 100644 --- a/cmd/liqo-controller-manager/main.go +++ b/cmd/liqo-controller-manager/main.go @@ -260,7 +260,7 @@ func main() { ipamClient = ipam.NewIPAMClient(conn) } - if err := modules.SetupNetworkingModule(mgr, &modules.NetworkingOption{ + if err := modules.SetupNetworkingModule(ctx, mgr, uncachedClient, &modules.NetworkingOption{ DynClient: dynClient, Factory: factory, diff --git a/cmd/liqo-controller-manager/modules/authentication.go b/cmd/liqo-controller-manager/modules/authentication.go index 5cae0f6046..47a1d80de6 100644 --- a/cmd/liqo-controller-manager/modules/authentication.go +++ b/cmd/liqo-controller-manager/modules/authentication.go @@ -61,6 +61,7 @@ func SetupAuthenticationModule(ctx context.Context, mgr manager.Manager, uncache } if err := enforceAuthenticationKeys(ctx, uncachedClient, opts.LiqoNamespace); err != nil { + klog.Errorf("Unable to enforce authentication keys: %v", err) return err } @@ -135,7 +136,7 @@ func SetupAuthenticationModule(ctx context.Context, mgr manager.Manager, uncache func enforceAuthenticationKeys(ctx context.Context, cl client.Client, liqoNamespace string) error { if err := authentication.InitClusterKeys(ctx, cl, liqoNamespace); err != nil { - klog.Errorf("Unable to initialize cluster authentication keys: %v", err) + return err } klog.Info("Enforced cluster authentication keys") diff --git a/cmd/liqo-controller-manager/modules/networking.go b/cmd/liqo-controller-manager/modules/networking.go index 6135df9ae1..6c1ce86214 100644 --- a/cmd/liqo-controller-manager/modules/networking.go +++ b/cmd/liqo-controller-manager/modules/networking.go @@ -15,10 +15,15 @@ package modules import ( + "context" + "fmt" + "k8s.io/client-go/dynamic" "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" + ipamv1alpha1 "github.com/liqotech/liqo/apis/ipam/v1alpha1" "github.com/liqotech/liqo/pkg/ipam" clientoperator "github.com/liqotech/liqo/pkg/liqo-controller-manager/networking/external-network/client-operator" configuration "github.com/liqotech/liqo/pkg/liqo-controller-manager/networking/external-network/configuration" @@ -36,6 +41,7 @@ import ( ipctrl "github.com/liqotech/liqo/pkg/liqo-controller-manager/networking/ip-controller" networkctrl "github.com/liqotech/liqo/pkg/liqo-controller-manager/networking/network-controller" dynamicutils "github.com/liqotech/liqo/pkg/utils/dynamic" + ipamutils "github.com/liqotech/liqo/pkg/utils/ipam" ) // NetworkingOption defines the options to setup the Networking module. @@ -59,7 +65,13 @@ type NetworkingOption struct { } // SetupNetworkingModule setup the networking module and initializes its controllers . -func SetupNetworkingModule(mgr manager.Manager, opts *NetworkingOption) error { +func SetupNetworkingModule(ctx context.Context, mgr manager.Manager, uncachedClient client.Client, opts *NetworkingOption) error { + // Initialize reserved networks + if err := initializeReservedNetworks(ctx, uncachedClient, opts.IpamClient); err != nil { + klog.Errorf("Unable to initialize reserved networks: %v", err) + return err + } + networkReconciler := networkctrl.NewNetworkReconciler(mgr.GetClient(), mgr.GetScheme(), opts.IpamClient) if err := networkReconciler.SetupWithManager(mgr, opts.NetworkWorkers); err != nil { klog.Errorf("Unable to start the networkReconciler: %v", err) @@ -209,3 +221,72 @@ func SetupNetworkingModule(mgr manager.Manager, opts *NetworkingOption) error { return nil } + +func initializeReservedNetworks(ctx context.Context, cl client.Client, ipamClient ipam.IPAMClient) error { + var networksToReserve []ipamv1alpha1.Network + + // PodCIDR is a special case of reserved network + podCidr, err := ipamutils.GetPodCIDRNetwork(ctx, cl) + if err != nil { + return err + } + networksToReserve = append(networksToReserve, *podCidr) + + // ServiceCIDR is a special case of reserved network + serviceCidr, err := ipamutils.GetServiceCIDRNetwork(ctx, cl) + if err != nil { + return err + } + networksToReserve = append(networksToReserve, *serviceCidr) + + // Get the reserved networks + reservedNetworks, err := ipamutils.GetReservedSubnetNetworks(ctx, cl) + if err != nil { + return err + } + networksToReserve = append(networksToReserve, reservedNetworks...) + + // Reserve the networks and fill their status CIDR. + for i := range networksToReserve { + nw := &networksToReserve[i] + + // If the status CIDR is already set, we do not need to reserve the network + // as it will be reserved when the ipam server is initialized. + if nw.Status.CIDR != "" { + continue + } + + if ipamClient == nil { + nw.Status.CIDR = nw.Spec.CIDR + } else { + // First check if the network is already reserved + res, err := ipamClient.NetworkIsAvailable(ctx, &ipam.NetworkAvailableRequest{ + Cidr: nw.Spec.CIDR.String(), + }) + if err != nil { + return err + } + + if res.Available { + // Network is not reserved, reserve it + _, err := ipamClient.NetworkAcquire(ctx, &ipam.NetworkAcquireRequest{ + Cidr: nw.Spec.CIDR.String(), + Immutable: true, + }) + if err != nil { + return err + } + } + + // Since reserved network must not be remapped (immutable), we can set the status CIDR to the spec CIDR + nw.Status.CIDR = nw.Spec.CIDR + } + + if err := cl.Status().Update(ctx, nw); err != nil { + return fmt.Errorf("unable to update the reserved network %s: %w", nw.Name, err) + } + } + + klog.Info("Reserved networks initialized") + return nil +}