diff --git a/pkg/ipam/initialize_test.go b/pkg/ipam/initialize_test.go new file mode 100644 index 0000000000..75d19a63d6 --- /dev/null +++ b/pkg/ipam/initialize_test.go @@ -0,0 +1,114 @@ +// Copyright 2019-2024 The Liqo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ipam + +import ( + "context" + "net/netip" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + ipamcore "github.com/liqotech/liqo/pkg/ipam/core" + "github.com/liqotech/liqo/pkg/utils/testutil" +) + +var _ = Describe("Initialize routine tests", func() { + const ( + testNamespace = "test" + ) + + var ( + ctx context.Context + fakeClientBuilder *fake.ClientBuilder + + fakeIpamServer *LiqoIPAM + ) + + BeforeEach(func() { + ctx = context.Background() + fakeClientBuilder = fake.NewClientBuilder().WithScheme(scheme.Scheme) + }) + + Describe("Testing ipam initialization", func() { + Context("Initialize", func() { + BeforeEach(func() { + // Add in-cluster networks + client := fakeClientBuilder.WithObjects( + // First pool + testutil.FakeNetwork("net1", testNamespace, "10.0.0.0/16", nil), + testutil.FakeNetwork("net2", testNamespace, "10.2.0.0/16", nil), + testutil.FakeNetwork("net3", testNamespace, "10.4.0.0/24", nil), + testutil.FakeNetwork("net4", testNamespace, "10.3.0.0/16", nil), // network with some IPs + testutil.FakeIP("ip1", testNamespace, "10.3.0.0", "10.3.0.0/16", nil, nil, false), + testutil.FakeIP("ip2", testNamespace, "10.3.0.2", "10.3.0.0/16", nil, nil, false), + + // Second pool + testutil.FakeNetwork("net5", testNamespace, "192.168.1.0/24", nil), + + // Network with full pool + testutil.FakeNetwork("net6", testNamespace, "172.16.1.0/24", nil), + ).Build() + + ipamCore, err := ipamcore.NewIpam([]string{"10.0.0.0/8", "192.168.0.0/16", "172.16.1.0/24"}) + Expect(err).To(BeNil()) + + // Init ipam server + fakeIpamServer = &LiqoIPAM{ + Client: client, + IpamCore: ipamCore, + opts: &ServerOptions{ + GraphvizEnabled: false, + }, + } + }) + + It("should populate the cache", func() { + // Run initialize + Expect(fakeIpamServer.initialize(ctx)).To(Succeed()) + + // Check the cache: + + // First pool + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.0.0.0/16"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.1.0.0/16"))).To(Equal(true)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.2.0.0/16"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.4.0.0/24"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.4.0.0/16"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.4.0.0/30"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.3.0.0/16"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("172.16.1.0/24"))).To(Equal(false)) + available, err := fakeIpamServer.isIPAvailable(netip.MustParseAddr("10.3.0.0"), netip.MustParsePrefix("10.3.0.0/16")) + Expect(err).To(BeNil()) + Expect(available).To(Equal(false)) + available, err = fakeIpamServer.isIPAvailable(netip.MustParseAddr("10.3.0.1"), netip.MustParsePrefix("10.3.0.0/16")) + Expect(err).To(BeNil()) + Expect(available).To(Equal(true)) + available, err = fakeIpamServer.isIPAvailable(netip.MustParseAddr("10.3.0.2"), netip.MustParsePrefix("10.3.0.0/16")) + Expect(err).To(BeNil()) + Expect(available).To(Equal(false)) + + // Second pool + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("192.168.1.0/24"))).To(Equal(false)) + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("192.168.2.0/24"))).To(Equal(true)) + + // Out of pools + Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("1.1.1.1/24"))).To(Equal(false)) + }) + }) + }) +}) diff --git a/pkg/ipam/sync_test.go b/pkg/ipam/sync_test.go index ab324cba7a..4c601c9238 100644 --- a/pkg/ipam/sync_test.go +++ b/pkg/ipam/sync_test.go @@ -66,10 +66,10 @@ var _ = Describe("Sync routine tests", func() { BeforeEach(func() { // Add in-cluster networks client := fakeClientBuilder.WithObjects( - testutil.FakeNetwork("net1", "10.0.0.0/16", map[string]string{}), - testutil.FakeNetwork("net2", "10.1.0.0/16", map[string]string{}), - testutil.FakeNetwork("net3", "10.2.0.0/16", map[string]string{}), - testutil.FakeNetwork("net4", "10.4.0.0/16", map[string]string{}), + testutil.FakeNetwork("net1", testNamespace, "10.0.0.0/16", nil), + testutil.FakeNetwork("net2", testNamespace, "10.1.0.0/16", nil), + testutil.FakeNetwork("net3", testNamespace, "10.2.0.0/16", nil), + testutil.FakeNetwork("net4", testNamespace, "10.4.0.0/16", nil), ).Build() ipamCore, err := ipamcore.NewIpam([]string{"10.0.0.0/8"}) @@ -149,11 +149,11 @@ var _ = Describe("Sync routine tests", func() { BeforeEach(func() { // Add in-cluster IPs client := fakeClientBuilder.WithObjects( - testutil.FakeNetwork("net1", "10.0.0.0/24", map[string]string{}), + testutil.FakeNetwork("net1", testNamespace, "10.0.0.0/24", nil), - testutil.FakeIP("ip1", "10.0.0.0", "10.0.0.0/24", nil, nil, false), - testutil.FakeIP("ip2", "10.0.0.1", "10.0.0.0/24", nil, nil, false), - testutil.FakeIP("ip3", "10.0.0.2", "10.0.0.0/24", nil, nil, false), + testutil.FakeIP("ip1", testNamespace, "10.0.0.0", "10.0.0.0/24", nil, nil, false), + testutil.FakeIP("ip2", testNamespace, "10.0.0.1", "10.0.0.0/24", nil, nil, false), + testutil.FakeIP("ip3", testNamespace, "10.0.0.2", "10.0.0.0/24", nil, nil, false), ).Build() ipamCore, err := ipamcore.NewIpam([]string{"10.0.0.0/8"}) diff --git a/pkg/utils/testutil/liqo.go b/pkg/utils/testutil/liqo.go index 9d9f9c373f..528ec793dc 100644 --- a/pkg/utils/testutil/liqo.go +++ b/pkg/utils/testutil/liqo.go @@ -177,11 +177,11 @@ func FakeForgingOpts() *forge.ForgingOpts { } // FakeNetwork returns a fake Network. -func FakeNetwork(name, cidr string, labels map[string]string) *ipamv1alpha1.Network { +func FakeNetwork(name, namespace, cidr string, labels map[string]string) *ipamv1alpha1.Network { return &ipamv1alpha1.Network{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: liqoconsts.DefaultLiqoNamespace, + Namespace: namespace, Labels: labels, }, Spec: ipamv1alpha1.NetworkSpec{ @@ -195,7 +195,7 @@ func FakeNetwork(name, cidr string, labels map[string]string) *ipamv1alpha1.Netw // FakeNetworkPodCIDR returns a fake Network of type PodCIDR. func FakeNetworkPodCIDR() *ipamv1alpha1.Network { - return FakeNetwork("pod-cidr", PodCIDR, map[string]string{ + return FakeNetwork("pod-cidr", liqoconsts.DefaultLiqoNamespace, PodCIDR, map[string]string{ liqoconsts.NetworkNotRemappedLabelKey: liqoconsts.NetworkNotRemappedLabelValue, liqoconsts.NetworkTypeLabelKey: string(liqoconsts.NetworkTypePodCIDR), }) @@ -203,7 +203,7 @@ func FakeNetworkPodCIDR() *ipamv1alpha1.Network { // FakeNetworkServiceCIDR returns a fake Network of type ServiceCIDR. func FakeNetworkServiceCIDR() *ipamv1alpha1.Network { - return FakeNetwork("service-cidr", ServiceCIDR, map[string]string{ + return FakeNetwork("service-cidr", liqoconsts.DefaultLiqoNamespace, ServiceCIDR, map[string]string{ liqoconsts.NetworkNotRemappedLabelKey: liqoconsts.NetworkNotRemappedLabelValue, liqoconsts.NetworkTypeLabelKey: string(liqoconsts.NetworkTypeServiceCIDR), }) @@ -211,32 +211,32 @@ func FakeNetworkServiceCIDR() *ipamv1alpha1.Network { // FakeNetworkExternalCIDR returns a fake Network of type ExternalCIDR. func FakeNetworkExternalCIDR() *ipamv1alpha1.Network { - return FakeNetwork("external-cidr", ExternalCIDR, map[string]string{ + return FakeNetwork("external-cidr", liqoconsts.DefaultLiqoNamespace, ExternalCIDR, map[string]string{ liqoconsts.NetworkTypeLabelKey: string(liqoconsts.NetworkTypeExternalCIDR), }) } // FakeNetworkInternalCIDR returns a fake Network of type InternalCIDR. func FakeNetworkInternalCIDR() *ipamv1alpha1.Network { - return FakeNetwork("internal-cidr", InternalCIDR, map[string]string{ + return FakeNetwork("internal-cidr", liqoconsts.DefaultLiqoNamespace, InternalCIDR, map[string]string{ liqoconsts.NetworkTypeLabelKey: string(liqoconsts.NetworkTypeInternalCIDR), }) } // FakeNetworkReservedSubnet returns a fake Network of type Reserved Subnet. func FakeNetworkReservedSubnet(i int) *ipamv1alpha1.Network { - return FakeNetwork(ReservedSubnets[i], ReservedSubnets[i], map[string]string{ + return FakeNetwork(ReservedSubnets[i], liqoconsts.DefaultLiqoNamespace, ReservedSubnets[i], map[string]string{ liqoconsts.NetworkTypeLabelKey: string(liqoconsts.NetworkTypeReserved), liqoconsts.NetworkNotRemappedLabelKey: liqoconsts.NetworkNotRemappedLabelValue, }) } // FakeIP returns a fake IP. -func FakeIP(name, ip, cidr string, labels map[string]string, networkRef *corev1.ObjectReference, masquerade bool) *ipamv1alpha1.IP { +func FakeIP(name, namespace, ip, cidr string, labels map[string]string, networkRef *corev1.ObjectReference, masquerade bool) *ipamv1alpha1.IP { return &ipamv1alpha1.IP{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: liqoconsts.DefaultLiqoNamespace, + Namespace: namespace, Labels: labels, }, Spec: ipamv1alpha1.IPSpec{