// SPDX-License-Identifier: BSD-3-Clause package v1 import ( "context" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" nbv1 "github.com/netbirdio/kubernetes-operator/api/v1" nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1" ) var _ = Describe("Pod Webhook", func() { var ( obj *corev1.Pod defaulter PodNetbirdInjector ) BeforeEach(func() { obj = &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", Annotations: make(map[string]string), }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: "test", }, }, }, } defaulter = PodNetbirdInjector{ client: k8sClient, managementURL: "https://api.netbird.io", clientImage: "netbirdio/netbird:latest", } Expect(defaulter).NotTo(BeNil(), "Expected defaulter to be initialized") Expect(obj).NotTo(BeNil(), "Expected obj to be initialized") }) AfterEach(func() { }) Context("When creating Pod without annotation", func() { It("Should not modify anything", func() { err := defaulter.Default(context.Background(), obj) Expect(err).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(1)) }) }) Context("When creating Pod with annotation", func() { BeforeEach(func() { obj.Annotations[setupKeyAnnotation] = "test" }) When("NBSetupKey doesn't exist", func() { It("Should fail", func() { Expect(defaulter.Default(context.Background(), obj)).To(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(1)) }) }) When("NBSetupKey exists", Ordered, func() { BeforeAll(func() { sk := nbv1.NBSetupKey{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, Spec: nbv1.NBSetupKeySpec{ SecretKeyRef: corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "test", }, Key: "test", }, }, } err := k8sClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "test", }, }) Expect(err).NotTo(HaveOccurred()) err = k8sClient.Create(context.Background(), &sk) Expect(err).NotTo(HaveOccurred()) sk.Status = nbv1.NBSetupKeyStatus{ Conditions: []nbv1.NBCondition{ { Type: nbv1.NBSetupKeyReady, Status: corev1.ConditionTrue, }, }, } err = k8sClient.Status().Update(context.Background(), &sk) Expect(err).NotTo(HaveOccurred()) }) It("Should inject NB container", func() { Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(2)) Expect(obj.Spec.Containers[1].Name).To(Equal("netbird")) }) It("Should inject NB container as native sidecar when init-sidecar annotation is true", func() { obj.Annotations[sidecarAnnotation] = "true" Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(1), "original containers should be unchanged") Expect(obj.Spec.InitContainers).To(HaveLen(1)) Expect(obj.Spec.InitContainers[0].Name).To(Equal("netbird")) Expect(obj.Spec.InitContainers[0].RestartPolicy).NotTo(BeNil()) Expect(*obj.Spec.InitContainers[0].RestartPolicy).To(Equal(corev1.ContainerRestartPolicyAlways)) }) It("Should inject NB as regular container when init-sidecar annotation is false", func() { obj.Annotations[sidecarAnnotation] = "false" Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(2)) Expect(obj.Spec.Containers[1].Name).To(Equal("netbird")) Expect(obj.Spec.InitContainers).To(BeEmpty()) }) It("Should inject NB as regular container when init-sidecar annotation is absent", func() { delete(obj.Annotations, sidecarAnnotation) Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(2)) Expect(obj.Spec.Containers[1].Name).To(Equal("netbird")) Expect(obj.Spec.InitContainers).To(BeEmpty()) }) }) }) Context("When creating Pod with SidecarProfile", func() { BeforeEach(func() { sidecarProfile := &nbv1alpha1.SidecarProfile{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, Spec: nbv1alpha1.SidecarProfileSpec{ SetupKeyRef: corev1.LocalObjectReference{ Name: "test", }, InjectionMode: nbv1alpha1.InjectionModeContainer, }, } Expect(k8sClient.Create(context.Background(), sidecarProfile)).To(Succeed()) }) AfterEach(func() { sidecarProfile := &nbv1alpha1.SidecarProfile{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, } Expect(k8sClient.Delete(ctx, sidecarProfile)).To(Succeed()) }) When("SetupKey doesn't exist", func() { It("Should fail", func() { Expect(defaulter.Default(context.Background(), obj)).To(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(1)) }) }) When("SetupKey exists", func() { It("Should succeed", func() { setupKey := &nbv1alpha1.SetupKey{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, Spec: nbv1alpha1.SetupKeySpec{ Name: "test", Ephemeral: true, }, } Expect(k8sClient.Create(context.Background(), setupKey)).To(Succeed()) Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred()) Expect(obj.Spec.Containers).To(HaveLen(2)) Expect(obj.Spec.Containers[1].Name).To(Equal("netbird")) }) }) }) })