diff --git a/data/kubevirt-ipam-controller/004-primary-udn-networkattachdef.yaml b/data/kubevirt-ipam-controller/004-primary-udn-networkattachdef.yaml new file mode 100644 index 000000000..0dcda5711 --- /dev/null +++ b/data/kubevirt-ipam-controller/004-primary-udn-networkattachdef.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: "k8s.cni.cncf.io/v1" +kind: NetworkAttachmentDefinition +metadata: + name: primary-user-defined-network + namespace: default +spec: + config: '{ + "cniVersion": "1.0.0", + "name": "primary-user-defined-network", + "plugins": [ + { + "type": "cni-passt-binding-plugin" + } + ] +}' diff --git a/go.mod b/go.mod index 16aeec76d..9ba94b1bb 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/go-git/go-git/v5 v5.11.0 github.com/gobwas/glob v0.2.3 github.com/google/go-github/v32 v32.1.0 + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0 github.com/kubevirt/monitoring/pkg/metrics/parser v0.0.0-20231024120544-6a3ba1a680b4 github.com/machadovilaca/operator-observability v0.0.19-0.20240326121036-9f2e5a31675f github.com/onsi/ginkgo/v2 v2.11.0 @@ -144,7 +145,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.3.0 // indirect github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.16.0 // indirect diff --git a/hack/components/bump-kubevirt-ipam-controller.sh b/hack/components/bump-kubevirt-ipam-controller.sh index ebfac4b77..00d7bb1f8 100755 --- a/hack/components/bump-kubevirt-ipam-controller.sh +++ b/hack/components/bump-kubevirt-ipam-controller.sh @@ -148,7 +148,7 @@ echo 'Adjust kubevirt-ipam-controller to CNAO' echo 'Copy manifests' shopt -s extglob -rm -rf data/kubevirt-ipam-controller/!(002-rbac.yaml) +rm -rf data/kubevirt-ipam-controller/!(002-rbac.yaml|004-primary-udn-networkattachdef.yaml) # CRD crd_manifest="https://raw.githubusercontent.com/k8snetworkplumbingwg/ipamclaims/${IPAMCLAIMS_CRD_VERSION}/artifacts/k8s.cni.cncf.io_ipamclaims.yaml" diff --git a/pkg/network/kubevirt_ipam_controller_test.go b/pkg/network/kubevirt_ipam_controller_test.go new file mode 100644 index 000000000..3811b80a7 --- /dev/null +++ b/pkg/network/kubevirt_ipam_controller_test.go @@ -0,0 +1,45 @@ +package network + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + osv1 "github.com/openshift/api/operator/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + + cnao "github.com/kubevirt/cluster-network-addons-operator/pkg/apis/networkaddonsoperator/shared" +) + +var _ = Describe("Testing kubevirt ipam controller", func() { + Context("Render KubevirtIpamController", func() { + conf := &cnao.NetworkAddonsConfigSpec{ImagePullPolicy: v1.PullAlways, Multus: &cnao.Multus{}, KubevirtIpamController: &cnao.KubevirtIpamController{}, PlacementConfiguration: &cnao.PlacementConfiguration{Workloads: &cnao.Placement{}}} + manifestDir := "../../data" + openshiftNetworkConf := &osv1.Network{} + clusterInfo := &ClusterInfo{} + expectedGroupVersionKind := schema.GroupVersionKind{ + Group: "k8s.cni.cncf.io", + Version: "v1", + Kind: "NetworkAttachmentDefinition", + } + const expectedName = "primary-user-defined-network" + + It("should add the primary-udn network-attach-def obj", func() { + objs, err := Render(conf, manifestDir, openshiftNetworkConf, clusterInfo) + Expect(err).NotTo(HaveOccurred()) + Expect(objs).NotTo(BeEmpty()) + + Expect(objs).To(ContainElement( + SatisfyAll( + WithTransform(func(obj *unstructured.Unstructured) string { + return obj.GetName() + }, Equal(expectedName)), + WithTransform(func(obj *unstructured.Unstructured) schema.GroupVersionKind { + return obj.GetObjectKind().GroupVersionKind() + }, Equal(expectedGroupVersionKind)), + ), + )) + }) + }) +}) diff --git a/test/check/check.go b/test/check/check.go index e47f3ab60..6612db55a 100644 --- a/test/check/check.go +++ b/test/check/check.go @@ -13,6 +13,7 @@ import ( . "github.com/onsi/gomega" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + k8snetworkplumbingwgv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" testenv "github.com/kubevirt/cluster-network-addons-operator/test/env" conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" securityapi "github.com/openshift/origin/pkg/security/apis/security" @@ -346,6 +347,10 @@ func checkForComponent(component *Component) error { errsAppend(checkForPrometheusRule(component.PrometheusRule)) } + if component.NetworkAttachmentDefinition != "" { + errsAppend(checkForNetworkAttachmentDefinition(component.NetworkAttachmentDefinition)) + } + return errsToErr(errs) } @@ -389,6 +394,10 @@ func checkForComponentRemoval(component *Component) error { errsAppend(checkForPrometheusRuleRemoval(component.PrometheusRule)) } + if component.NetworkAttachmentDefinition != "" { + errsAppend(checkForNetworkAttachmentDefinitionRemoval(component.NetworkAttachmentDefinition)) + } + return errsToErr(errs) } @@ -649,6 +658,21 @@ func checkForPrometheusRule(name string) error { return nil } +func checkForNetworkAttachmentDefinition(name string) error { + networkAttachmentDefinition := k8snetworkplumbingwgv1.NetworkAttachmentDefinition{} + err := testenv.Client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: corev1.NamespaceDefault}, &networkAttachmentDefinition) + if err != nil { + return err + } + + err = checkRelationshipLabels(networkAttachmentDefinition.GetLabels(), "NetworkAttachmentDefinition", name) + if err != nil { + return err + } + + return nil +} + func checkRelationshipLabels(labels map[string]string, kind, name string) error { expectedValues := map[string]string{ names.COMPONENT_LABEL_KEY: names.COMPONENT_LABEL_DEFAULT_VALUE, @@ -708,6 +732,14 @@ func checkForPrometheusRuleRemoval(name string) error { return isNotFound("PrometheusRule", name, err) } +func checkForNetworkAttachmentDefinitionRemoval(name string) error { + err := testenv.Client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: corev1.NamespaceDefault}, &k8snetworkplumbingwgv1.NetworkAttachmentDefinition{}) + if isNotSupportedKind(err) { + return nil + } + return isNotFound("NetworkAttachmentDefinition", name, err) +} + func getMonitoringEndpoint() (*corev1.Endpoints, error) { By("Finding CNAO prometheus endpoint") endpoint := &corev1.Endpoints{} diff --git a/test/check/components.go b/test/check/components.go index ebd5ee0fd..a87986cb2 100644 --- a/test/check/components.go +++ b/test/check/components.go @@ -20,6 +20,7 @@ type Component struct { Service string ServiceMonitor string PrometheusRule string + NetworkAttachmentDefinition string } var ( @@ -87,11 +88,12 @@ var ( Deployments: []string{"secondary-dns"}, } KubevirtIpamController = Component{ - ComponentName: "KubevirtIpamController", - ClusterRole: "kubevirt-ipam-controller-manager-role", - ClusterRoleBinding: "kubevirt-ipam-controller-manager-rolebinding", - Deployments: []string{"kubevirt-ipam-controller-manager"}, - DaemonSets: []string{"passt-binding-cni"}, + ComponentName: "KubevirtIpamController", + ClusterRole: "kubevirt-ipam-controller-manager-role", + ClusterRoleBinding: "kubevirt-ipam-controller-manager-rolebinding", + Deployments: []string{"kubevirt-ipam-controller-manager"}, + DaemonSets: []string{"passt-binding-cni"}, + NetworkAttachmentDefinition: "primary-user-defined-network", } AllComponents = []Component{ KubeMacPoolComponent, diff --git a/test/e2e/workflow/deployment_test.go b/test/e2e/workflow/deployment_test.go index afeb14e8d..9dda94803 100644 --- a/test/e2e/workflow/deployment_test.go +++ b/test/e2e/workflow/deployment_test.go @@ -91,9 +91,10 @@ var _ = Describe("NetworkAddonsConfig", func() { Entry( KubevirtIpamController.ComponentName, cnao.NetworkAddonsConfigSpec{ + Multus: &cnao.Multus{}, KubevirtIpamController: &cnao.KubevirtIpamController{}, }, - []Component{KubevirtIpamController}, + []Component{MultusComponent, KubevirtIpamController}, ), ) It("should deploy prometheus if NetworkAddonsConfigSpec is not empty", func() { diff --git a/test/env/env.go b/test/env/env.go index b72bb3362..babae5d03 100644 --- a/test/env/env.go +++ b/test/env/env.go @@ -1,6 +1,7 @@ package env import ( + k8snetworkplumbingwgv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" . "github.com/onsi/gomega" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" @@ -39,6 +40,8 @@ func Start() { ExpectWithOffset(1, err).NotTo(HaveOccurred()) err = monitoringv1.AddToScheme(scheme.Scheme) ExpectWithOffset(1, err).NotTo(HaveOccurred()) + err = k8snetworkplumbingwgv1.AddToScheme(scheme.Scheme) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme