diff --git a/pkg/webhook/nad/validator.go b/pkg/webhook/nad/validator.go index 636bb0bb..a1a3762e 100644 --- a/pkg/webhook/nad/validator.go +++ b/pkg/webhook/nad/validator.go @@ -61,6 +61,13 @@ func (v *Validator) Create(_ *admission.Request, newObj runtime.Object) error { return fmt.Errorf(createErr, nad.Namespace, nad.Name, err) } + //allow overlay nad creation only if subnet crd/kubeovn is enabled + if conf.IsKubeOVNCNI() { + if !v.subnetEnabled { + return fmt.Errorf(createErr, nad.Namespace, nad.Name, fmt.Errorf("kubeovn is not yet enabled")) + } + } + if err := v.checkNadConfig(conf, nad); err != nil { return fmt.Errorf(createErr, nad.Namespace, nad.Name, err) } @@ -135,8 +142,9 @@ func (v *Validator) Delete(_ *admission.Request, oldObj runtime.Object) error { // do not delete nad when a subnet is using it // This will also make sure nad is not deleted when VMIs,VMs are using it if nadConf.IsKubeOVNCNI() { + //allow deletion of overlay nad even if kubeovn is not enabled. if !v.subnetEnabled { - return fmt.Errorf("operation is not permitted as kubeovn is not yet enabled") + return nil } return v.checkSubnetsUsingNAD(nad) } diff --git a/pkg/webhook/nad/validator_test.go b/pkg/webhook/nad/validator_test.go index 2762bc36..c3177578 100644 --- a/pkg/webhook/nad/validator_test.go +++ b/pkg/webhook/nad/validator_test.go @@ -946,3 +946,108 @@ func TestDeleteNAD(t *testing.T) { }) } } + +func TestCreateOverlayNADWithNoSubnetCRD(t *testing.T) { + tests := []struct { + name string + returnErr bool + errKey string + currentNAD *cniv1.NetworkAttachmentDefinition + }{ + { + name: "NAD can't be created as it has no subnet CRD", + returnErr: true, + errKey: "kubeovn is not yet enabled", + currentNAD: &cniv1.NetworkAttachmentDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: testKubeOVNNadName, + Namespace: testKubeOVNNamespace, + }, + Spec: cniv1.NetworkAttachmentDefinitionSpec{ + Config: testKubeOVNNadConfig, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.NotNil(t, tc.currentNAD) + if tc.currentNAD == nil { + return + } + + nchclientset := fake.NewSimpleClientset() + vmCache := fakeclients.VirtualMachineCache(nchclientset.KubevirtV1().VirtualMachines) + vmiCache := fakeclients.VirtualMachineInstanceCache(nchclientset.KubevirtV1().VirtualMachineInstances) + cnCache := fakeclients.ClusterNetworkCache(nchclientset.NetworkV1beta1().ClusterNetworks) + vcCache := fakeclients.VlanConfigCache(nchclientset.NetworkV1beta1().VlanConfigs) + subnetCache := fakeclients.SubnetCache(nchclientset.KubeovnV1().Subnets) + nadCache := fakeclients.NetworkAttachmentDefinitionCache(nchclientset.K8sCniCncfIoV1().NetworkAttachmentDefinitions) + hncCache := fakeclients.HostNetworkConfigCache(nchclientset.NetworkV1beta1().HostNetworkConfigs) + validator := NewNadValidator(vmCache, vmiCache, cnCache, vcCache, subnetCache, false, hncCache, nadCache) + + err := validator.Create(nil, tc.currentNAD) + logrus.Infof("Create NAD test case '%s' result error: %v", tc.name, err) + assert.True(t, tc.returnErr == (err != nil)) + if tc.returnErr { + assert.NotNil(t, err) + if err != nil { + assert.True(t, strings.Contains(err.Error(), tc.errKey)) + } + } + }) + } +} + +func TestDeleteOverlayNADWithNoSubnetCRD(t *testing.T) { + tests := []struct { + name string + returnErr bool + errKey string + currentNAD *cniv1.NetworkAttachmentDefinition + }{ + { + name: "NAD can be deleted when kubeovn is not enabled", + returnErr: false, + currentNAD: &cniv1.NetworkAttachmentDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: testKubeOVNNadName, + Namespace: testKubeOVNNamespace, + }, + Spec: cniv1.NetworkAttachmentDefinitionSpec{ + Config: testKubeOVNNadConfig, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.NotNil(t, tc.currentNAD) + if tc.currentNAD == nil { + return + } + + nchclientset := fake.NewSimpleClientset() + vmCache := fakeclients.VirtualMachineCache(nchclientset.KubevirtV1().VirtualMachines) + vmiCache := fakeclients.VirtualMachineInstanceCache(nchclientset.KubevirtV1().VirtualMachineInstances) + cnCache := fakeclients.ClusterNetworkCache(nchclientset.NetworkV1beta1().ClusterNetworks) + vcCache := fakeclients.VlanConfigCache(nchclientset.NetworkV1beta1().VlanConfigs) + subnetCache := fakeclients.SubnetCache(nchclientset.KubeovnV1().Subnets) + nadCache := fakeclients.NetworkAttachmentDefinitionCache(nchclientset.K8sCniCncfIoV1().NetworkAttachmentDefinitions) + hncCache := fakeclients.HostNetworkConfigCache(nchclientset.NetworkV1beta1().HostNetworkConfigs) + validator := NewNadValidator(vmCache, vmiCache, cnCache, vcCache, subnetCache, false, hncCache, nadCache) + + err := validator.Delete(nil, tc.currentNAD) + logrus.Infof("Delete NAD test case '%s' result error: %v", tc.name, err) + assert.True(t, tc.returnErr == (err != nil)) + if tc.returnErr { + assert.NotNil(t, err) + if err != nil { + assert.True(t, strings.Contains(err.Error(), tc.errKey)) + } + } + }) + } +}