From 9809dc3347626737d5778e700b75d97f0d092006 Mon Sep 17 00:00:00 2001 From: mmirecki Date: Mon, 16 Aug 2021 13:42:06 +0200 Subject: [PATCH] Set webhook failurePolicy to Ignore on controller pod shutdown --- api/v1/helper.go | 13 ++- controllers/helper.go | 26 +----- controllers/sriovibnetwork_controller.go | 9 +- controllers/sriovnetwork_controller.go | 9 +- .../sriovnetworknodepolicy_controller.go | 29 +++--- .../sriovnetworkpoolconfig_controller.go | 14 ++- .../sriovnetworkpoolconfig_controller_test.go | 3 +- controllers/sriovoperatorconfig_controller.go | 15 +-- controllers/suite_test.go | 5 +- main.go | 2 +- pkg/utils/constants.go | 24 +++++ pkg/utils/shutdown.go | 91 +++++++++++++++++-- 12 files changed, 167 insertions(+), 73 deletions(-) create mode 100644 pkg/utils/constants.go diff --git a/api/v1/helper.go b/api/v1/helper.go index 4559f0451..650d17643 100644 --- a/api/v1/helper.go +++ b/api/v1/helper.go @@ -219,12 +219,15 @@ func StringInArray(val string, array []string) bool { return false } -func RemoveString(s string, slice []string) (result []string) { - for _, item := range slice { - if item == s { - continue +func RemoveString(s string, slice []string) (result []string, found bool) { + if len(slice) != 0 { + for _, item := range slice { + if item == s { + found = true + continue + } + result = append(result, item) } - result = append(result, item) } return } diff --git a/controllers/helper.go b/controllers/helper.go index 947125c1e..98c5cd8c9 100644 --- a/controllers/helper.go +++ b/controllers/helper.go @@ -18,33 +18,13 @@ package controllers import ( "os" - "time" -) -const ( - ResyncPeriod = 5 * time.Minute - DEFAULT_CONFIG_NAME = "default" - CONFIG_DAEMON_PATH = "./bindata/manifests/daemon" - INJECTOR_WEBHOOK_PATH = "./bindata/manifests/webhook" - OPERATOR_WEBHOOK_PATH = "./bindata/manifests/operator-webhook" - SERVICE_CA_CONFIGMAP_ANNOTATION = "service.beta.openshift.io/inject-cabundle" - INJECTOR_WEBHOOK_NAME = "network-resources-injector-config" - OPERATOR_WEBHOOK_NAME = "sriov-operator-webhook-config" - DEPRECATED_OPERATOR_WEBHOOK_NAME = "operator-webhook-config" - PLUGIN_PATH = "./bindata/manifests/plugins" - DAEMON_PATH = "./bindata/manifests/daemon" - DEFAULT_POLICY_NAME = "default" - CONFIGMAP_NAME = "device-plugin-config" - DP_CONFIG_FILENAME = "config.json" - OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX = "ovs-hw-offload" - - linkTypeEthernet = "ether" - linkTypeInfiniband = "infiniband" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" ) var webhooks = map[string](string){ - INJECTOR_WEBHOOK_NAME: INJECTOR_WEBHOOK_PATH, - OPERATOR_WEBHOOK_NAME: OPERATOR_WEBHOOK_PATH, + constants.INJECTOR_WEBHOOK_NAME: constants.INJECTOR_WEBHOOK_PATH, + constants.OPERATOR_WEBHOOK_NAME: constants.OPERATOR_WEBHOOK_PATH, } var namespace = os.Getenv("NAMESPACE") diff --git a/controllers/sriovibnetwork_controller.go b/controllers/sriovibnetwork_controller.go index 5313efb93..8fee236e1 100644 --- a/controllers/sriovibnetwork_controller.go +++ b/controllers/sriovibnetwork_controller.go @@ -98,9 +98,12 @@ func (r *SriovIBNetworkReconciler) Reconcile(ctx context.Context, req ctrl.Reque return reconcile.Result{}, err } // remove our finalizer from the list and update it. - instance.ObjectMeta.Finalizers = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) - if err := r.Update(context.Background(), instance); err != nil { - return reconcile.Result{}, err + var found bool + instance.ObjectMeta.Finalizers, found = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) + if found { + if err := r.Update(context.Background(), instance); err != nil { + return reconcile.Result{}, err + } } } return reconcile.Result{}, err diff --git a/controllers/sriovnetwork_controller.go b/controllers/sriovnetwork_controller.go index 6795ae35f..9d3d25d6f 100644 --- a/controllers/sriovnetwork_controller.go +++ b/controllers/sriovnetwork_controller.go @@ -99,9 +99,12 @@ func (r *SriovNetworkReconciler) Reconcile(ctx context.Context, req ctrl.Request return reconcile.Result{}, err } // remove our finalizer from the list and update it. - instance.ObjectMeta.Finalizers = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) - if err := r.Update(context.Background(), instance); err != nil { - return reconcile.Result{}, err + var found bool + instance.ObjectMeta.Finalizers, found = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) + if found { + if err := r.Update(context.Background(), instance); err != nil { + return reconcile.Result{}, err + } } } return reconcile.Result{}, err diff --git a/controllers/sriovnetworknodepolicy_controller.go b/controllers/sriovnetworknodepolicy_controller.go index b3d798f52..0bc4cead7 100644 --- a/controllers/sriovnetworknodepolicy_controller.go +++ b/controllers/sriovnetworknodepolicy_controller.go @@ -45,6 +45,7 @@ import ( sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/apply" render "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" ) // SriovNetworkNodePolicyReconciler reconciles a SriovNetworkNodePolicy object @@ -72,12 +73,12 @@ func (r *SriovNetworkNodePolicyReconciler) Reconcile(ctx context.Context, req ct reqLogger.Info("Reconciling") defaultPolicy := &sriovnetworkv1.SriovNetworkNodePolicy{} - err := r.Get(context.TODO(), types.NamespacedName{Name: DEFAULT_POLICY_NAME, Namespace: namespace}, defaultPolicy) + err := r.Get(context.TODO(), types.NamespacedName{Name: constants.DEFAULT_POLICY_NAME, Namespace: namespace}, defaultPolicy) if err != nil { if errors.IsNotFound(err) { // Default policy object not found, create it. defaultPolicy.SetNamespace(namespace) - defaultPolicy.SetName(DEFAULT_POLICY_NAME) + defaultPolicy.SetName(constants.DEFAULT_POLICY_NAME) defaultPolicy.Spec = sriovnetworkv1.SriovNetworkNodePolicySpec{ NumVfs: 0, NodeSelector: make(map[string]string), @@ -85,7 +86,7 @@ func (r *SriovNetworkNodePolicyReconciler) Reconcile(ctx context.Context, req ct } err = r.Create(context.TODO(), defaultPolicy) if err != nil { - reqLogger.Error(err, "Failed to create default Policy", "Namespace", namespace, "Name", DEFAULT_POLICY_NAME) + reqLogger.Error(err, "Failed to create default Policy", "Namespace", namespace, "Name", constants.DEFAULT_POLICY_NAME) return reconcile.Result{}, err } return reconcile.Result{}, nil @@ -111,7 +112,7 @@ func (r *SriovNetworkNodePolicyReconciler) Reconcile(ctx context.Context, req ct nodeList := &corev1.NodeList{} lo := &client.MatchingLabels{} defaultOpConf := &sriovnetworkv1.SriovOperatorConfig{} - if err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: DEFAULT_CONFIG_NAME}, defaultOpConf); err != nil { + if err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: constants.DEFAULT_CONFIG_NAME}, defaultOpConf); err != nil { return reconcile.Result{}, err } if len(defaultOpConf.Spec.ConfigDaemonNodeSelector) > 0 { @@ -148,7 +149,7 @@ func (r *SriovNetworkNodePolicyReconciler) Reconcile(ctx context.Context, req ct // All was successful. Request that this be re-triggered after ResyncPeriod, // so we can reconcile state again. - return reconcile.Result{RequeueAfter: ResyncPeriod}, nil + return reconcile.Result{RequeueAfter: constants.ResyncPeriod}, nil } // SetupWithManager sets up the controller with the Manager. @@ -181,7 +182,7 @@ func (r *SriovNetworkNodePolicyReconciler) syncDevicePluginConfigMap(pl *sriovne Kind: "ConfigMap", }, ObjectMeta: metav1.ObjectMeta{ - Name: CONFIGMAP_NAME, + Name: constants.CONFIGMAP_NAME, Namespace: namespace, }, Data: configData, @@ -212,8 +213,8 @@ func (r *SriovNetworkNodePolicyReconciler) syncAllSriovNetworkNodeStates(np *sri logger := log.Log.WithName("syncAllSriovNetworkNodeStates") logger.Info("Start to sync all SriovNetworkNodeState custom resource") found := &corev1.ConfigMap{} - if err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: CONFIGMAP_NAME}, found); err != nil { - logger.Info("Fail to get", "ConfigMap", CONFIGMAP_NAME) + if err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: constants.CONFIGMAP_NAME}, found); err != nil { + logger.Info("Fail to get", "ConfigMap", constants.CONFIGMAP_NAME) } for _, node := range nl.Items { logger.Info("Sync SriovNetworkNodeState CR", "name", node.Name) @@ -327,7 +328,7 @@ func (r *SriovNetworkNodePolicyReconciler) syncPluginDaemonObjs(dp *sriovnetwork data.Data["ReleaseVersion"] = os.Getenv("RELEASEVERSION") data.Data["ResourcePrefix"] = os.Getenv("RESOURCE_PREFIX") - objs, err := renderDsForCR(PLUGIN_PATH, &data) + objs, err := renderDsForCR(constants.PLUGIN_PATH, &data) if err != nil { logger.Error(err, "Fail to render SR-IoV manifests") return err @@ -335,7 +336,7 @@ func (r *SriovNetworkNodePolicyReconciler) syncPluginDaemonObjs(dp *sriovnetwork defaultConfig := &sriovnetworkv1.SriovOperatorConfig{} err = r.Get(context.TODO(), types.NamespacedName{ - Name: DEFAULT_CONFIG_NAME, Namespace: namespace}, defaultConfig) + Name: constants.DEFAULT_CONFIG_NAME, Namespace: namespace}, defaultConfig) if err != nil { return err } @@ -610,9 +611,9 @@ func (r *SriovNetworkNodePolicyReconciler) renderDevicePluginConfigData(pl *srio // vfio-pci device link type is not detectable if p.Spec.DeviceType != "vfio-pci" { if p.Spec.LinkType != "" { - linkType := linkTypeEthernet + linkType := constants.LinkTypeEthernet if strings.ToLower(p.Spec.LinkType) == "ib" { - linkType = linkTypeInfiniband + linkType = constants.LinkTypeInfiniband } if !sriovnetworkv1.StringInArray(linkType, netDeviceSelectors.LinkTypes) { netDeviceSelectors.LinkTypes = sriovnetworkv1.UniqueAppend(netDeviceSelectors.LinkTypes, linkType) @@ -676,9 +677,9 @@ func (r *SriovNetworkNodePolicyReconciler) renderDevicePluginConfigData(pl *srio // vfio-pci device link type is not detectable if p.Spec.DeviceType != "vfio-pci" { if p.Spec.LinkType != "" { - linkType := linkTypeEthernet + linkType := constants.LinkTypeEthernet if strings.ToLower(p.Spec.LinkType) == "ib" { - linkType = linkTypeInfiniband + linkType = constants.LinkTypeInfiniband } netDeviceSelectors.LinkTypes = sriovnetworkv1.UniqueAppend(netDeviceSelectors.LinkTypes, linkType) } diff --git a/controllers/sriovnetworkpoolconfig_controller.go b/controllers/sriovnetworkpoolconfig_controller.go index b3ff6c4ad..9142b7df8 100644 --- a/controllers/sriovnetworkpoolconfig_controller.go +++ b/controllers/sriovnetworkpoolconfig_controller.go @@ -16,6 +16,7 @@ import ( sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" render "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" ) @@ -86,15 +87,18 @@ func (r *SriovNetworkPoolConfigReconciler) Reconcile(ctx context.Context, req ct } } // remove our finalizer from the list and update it. - instance.ObjectMeta.Finalizers = sriovnetworkv1.RemoveString(sriovnetworkv1.POOLCONFIGFINALIZERNAME, instance.ObjectMeta.Finalizers) - if err := r.Update(context.Background(), instance); err != nil { - return reconcile.Result{}, err + var found bool + instance.ObjectMeta.Finalizers, found = sriovnetworkv1.RemoveString(sriovnetworkv1.POOLCONFIGFINALIZERNAME, instance.ObjectMeta.Finalizers) + if found { + if err := r.Update(context.Background(), instance); err != nil { + return reconcile.Result{}, err + } } } return reconcile.Result{}, err } - return reconcile.Result{RequeueAfter: ResyncPeriod}, nil + return reconcile.Result{RequeueAfter: constants.ResyncPeriod}, nil } // SetupWithManager sets up the controller with the Manager. @@ -108,7 +112,7 @@ func (r *SriovNetworkPoolConfigReconciler) syncOvsHardwareOffloadMachineConfigs( logger := log.Log.WithName("syncOvsHardwareOffloadMachineConfigs") mcpName := nc.Spec.OvsHardwareOffloadConfig.Name - mcName := "00-" + mcpName + "-" + OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX + mcName := "00-" + mcpName + "-" + constants.OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX foundMC := &mcfgv1.MachineConfig{} mcp := &mcfgv1.MachineConfigPool{} diff --git a/controllers/sriovnetworkpoolconfig_controller_test.go b/controllers/sriovnetworkpoolconfig_controller_test.go index e7d38e84a..9aff4cf29 100644 --- a/controllers/sriovnetworkpoolconfig_controller_test.go +++ b/controllers/sriovnetworkpoolconfig_controller_test.go @@ -11,6 +11,7 @@ import ( . "github.com/onsi/gomega" sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" ) @@ -22,7 +23,7 @@ var _ = Describe("Operator", func() { config.SetName("ovs-hw-offload-config") mcpName := "worker" mc := &mcfgv1.MachineConfig{} - mcName := "00-" + mcpName + "-" + OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX + mcName := "00-" + mcpName + "-" + constants.OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX err := k8sClient.Get(goctx.TODO(), types.NamespacedName{Name: mcName, Namespace: testNamespace}, mc) Expect(errors.IsNotFound(err)).Should(BeTrue()) diff --git a/controllers/sriovoperatorconfig_controller.go b/controllers/sriovoperatorconfig_controller.go index fa8018637..c47f29ef4 100644 --- a/controllers/sriovoperatorconfig_controller.go +++ b/controllers/sriovoperatorconfig_controller.go @@ -39,6 +39,7 @@ import ( apply "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/apply" render "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" ) // SriovOperatorConfigReconciler reconciles a SriovOperatorConfig object @@ -74,12 +75,12 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl. } defaultConfig := &sriovnetworkv1.SriovOperatorConfig{} err := r.Get(context.TODO(), types.NamespacedName{ - Name: DEFAULT_CONFIG_NAME, Namespace: namespace}, defaultConfig) + Name: constants.DEFAULT_CONFIG_NAME, Namespace: namespace}, defaultConfig) if err != nil { if errors.IsNotFound(err) { // Default Config object not found, create it. defaultConfig.SetNamespace(namespace) - defaultConfig.SetName(DEFAULT_CONFIG_NAME) + defaultConfig.SetName(constants.DEFAULT_CONFIG_NAME) defaultConfig.Spec = sriovnetworkv1.SriovOperatorConfigSpec{ EnableInjector: func() *bool { b := enableAdmissionController; return &b }(), EnableOperatorWebhook: func() *bool { b := enableAdmissionController; return &b }(), @@ -89,7 +90,7 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl. err = r.Create(context.TODO(), defaultConfig) if err != nil { logger.Error(err, "Failed to create default Operator Config", "Namespace", - namespace, "Name", DEFAULT_CONFIG_NAME) + namespace, "Name", constants.DEFAULT_CONFIG_NAME) return reconcile.Result{}, err } return reconcile.Result{}, nil @@ -116,7 +117,7 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl. return reconcile.Result{}, err } - return reconcile.Result{RequeueAfter: ResyncPeriod}, nil + return reconcile.Result{RequeueAfter: constants.ResyncPeriod}, nil } // SetupWithManager sets up the controller with the Manager. @@ -178,7 +179,7 @@ func (r *SriovOperatorConfigReconciler) syncConfigDaemonSet(dc *sriovnetworkv1.S logger.Info("New cni bin found", "CNIBinPath", envCniBinPath) data.Data["CNIBinPath"] = envCniBinPath } - objs, err := render.RenderDir(CONFIG_DAEMON_PATH, &data) + objs, err := render.RenderDir(constants.CONFIG_DAEMON_PATH, &data) if err != nil { logger.Error(err, "Fail to render config daemon manifests") return err @@ -230,7 +231,7 @@ func (r *SriovOperatorConfigReconciler) syncWebhookObjs(dc *sriovnetworkv1.Sriov } // Delete injector webhook - if *dc.Spec.EnableInjector != true && path == INJECTOR_WEBHOOK_PATH { + if *dc.Spec.EnableInjector != true && path == constants.INJECTOR_WEBHOOK_PATH { for _, obj := range objs { err = r.deleteWebhookObject(obj) if err != nil { @@ -243,7 +244,7 @@ func (r *SriovOperatorConfigReconciler) syncWebhookObjs(dc *sriovnetworkv1.Sriov continue } // Delete operator webhook - if *dc.Spec.EnableOperatorWebhook != true && path == OPERATOR_WEBHOOK_PATH { + if *dc.Spec.EnableOperatorWebhook != true && path == constants.OPERATOR_WEBHOOK_PATH { for _, obj := range objs { err = r.deleteWebhookObject(obj) if err != nil { diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 1ccbaf36c..034e5811c 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -41,6 +41,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" + constants "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" //+kubebuilder:scaffold:imports ) @@ -151,7 +152,7 @@ var _ = BeforeSuite(func(done Done) { config := &sriovnetworkv1.SriovOperatorConfig{} config.SetNamespace(testNamespace) - config.SetName(DEFAULT_CONFIG_NAME) + config.SetName(constants.DEFAULT_CONFIG_NAME) config.Spec = sriovnetworkv1.SriovOperatorConfigSpec{ EnableInjector: func() *bool { b := true; return &b }(), EnableOperatorWebhook: func() *bool { b := true; return &b }(), @@ -162,7 +163,7 @@ var _ = BeforeSuite(func(done Done) { poolConfig := &sriovnetworkv1.SriovNetworkPoolConfig{} poolConfig.SetNamespace(testNamespace) - poolConfig.SetName(DEFAULT_CONFIG_NAME) + poolConfig.SetName(constants.DEFAULT_CONFIG_NAME) poolConfig.Spec = sriovnetworkv1.SriovNetworkPoolConfigSpec{} Expect(k8sClient.Create(context.TODO(), poolConfig)).Should(Succeed()) close(done) diff --git a/main.go b/main.go index e858aaa2b..63a84bac1 100644 --- a/main.go +++ b/main.go @@ -175,7 +175,7 @@ func main() { }() // Remove all finalizers after controller is shut down - defer utils.Shutdown(mgr.GetClient()) + defer utils.Shutdown() setupLog.Info("starting manager") if err := mgr.Start(stopCh); err != nil { diff --git a/pkg/utils/constants.go b/pkg/utils/constants.go new file mode 100644 index 000000000..45a45e444 --- /dev/null +++ b/pkg/utils/constants.go @@ -0,0 +1,24 @@ +package utils + +import "time" + +const ( + ResyncPeriod = 5 * time.Minute + DEFAULT_CONFIG_NAME = "default" + CONFIG_DAEMON_PATH = "./bindata/manifests/daemon" + INJECTOR_WEBHOOK_PATH = "./bindata/manifests/webhook" + OPERATOR_WEBHOOK_PATH = "./bindata/manifests/operator-webhook" + SERVICE_CA_CONFIGMAP_ANNOTATION = "service.beta.openshift.io/inject-cabundle" + INJECTOR_WEBHOOK_NAME = "network-resources-injector-config" + OPERATOR_WEBHOOK_NAME = "sriov-operator-webhook-config" + DEPRECATED_OPERATOR_WEBHOOK_NAME = "operator-webhook-config" + PLUGIN_PATH = "./bindata/manifests/plugins" + DAEMON_PATH = "./bindata/manifests/daemon" + DEFAULT_POLICY_NAME = "default" + CONFIGMAP_NAME = "device-plugin-config" + DP_CONFIG_FILENAME = "config.json" + OVS_HWOL_MACHINE_CONFIG_NAME_SUFFIX = "ovs-hw-offload" + + LinkTypeEthernet = "ether" + LinkTypeInfiniband = "infiniband" +) diff --git a/pkg/utils/shutdown.go b/pkg/utils/shutdown.go index 7065b5db0..f000037ce 100644 --- a/pkg/utils/shutdown.go +++ b/pkg/utils/shutdown.go @@ -3,28 +3,101 @@ package utils import ( "context" + snclientset "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/client/clientset/versioned" + admv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + + "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + conf "sigs.k8s.io/controller-runtime/pkg/client/config" sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" ) -func Shutdown(c client.Client) { - shutdownLog := ctrl.Log.WithName("shutdown") +var shutdownLog = ctrl.Log.WithName("shutdown") + +var sriovnetworksGVR = schema.GroupVersionResource{ + Group: "sriovnetwork.openshift.io", + Version: "v1", + Resource: "sriovnetworks", +} + +var failurePolicyIgnore = admv1.Ignore + +func Shutdown() { + updateFinalizers() + updateWebhooks() +} + +func updateFinalizers() { shutdownLog.Info("Clearing finalizers on exit") - networkList := &sriovnetworkv1.SriovNetworkList{} - err := c.List(context.TODO(), networkList) + c, err := snclientset.NewForConfig(conf.GetConfigOrDie()) + if err != nil { + shutdownLog.Error(err, "Error creating client") + } + sriovNetworkClient := c.SriovnetworkV1() + networkList, err := sriovNetworkClient.SriovNetworks("").List(context.TODO(), metav1.ListOptions{}) if err != nil { shutdownLog.Error(err, "Failed to list SriovNetworks") } else { for _, instance := range networkList.Items { - shutdownLog.Info("Clearing finalizers on SriovNetwork ", "namespace", instance.GetNamespace(), "name", instance.GetName()) - instance.ObjectMeta.Finalizers = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) - err := c.Update(context.TODO(), &instance) + if instance.ObjectMeta.Finalizers == nil || len(instance.ObjectMeta.Finalizers) == 0 { + continue + } if err != nil { - shutdownLog.Error(err, "Failed to remove finalizer") + shutdownLog.Error(err, "Failed get finalizers map") + } + shutdownLog.Info("Clearing finalizers on SriovNetwork ", "namespace", instance.GetNamespace(), "name", instance.GetName()) + var found bool + instance.ObjectMeta.Finalizers, found = sriovnetworkv1.RemoveString(sriovnetworkv1.NETATTDEFFINALIZERNAME, instance.ObjectMeta.Finalizers) + if found { + _, err = sriovNetworkClient.SriovNetworks(instance.GetNamespace()).Update(context.TODO(), &instance, metav1.UpdateOptions{}) + if err != nil { + shutdownLog.Error(err, "Failed to remove finalizer") + } } } } shutdownLog.Info("Done clearing finalizers on exit") } + +func updateWebhooks() { + shutdownLog.Info("Seting webhook failure policies to Ignore on exit") + clientset, err := kubernetes.NewForConfig(conf.GetConfigOrDie()) + if err != nil { + shutdownLog.Error(err, "Error getting client") + } + updateValidatingWebhook(clientset) + updateMutatingWebhooks(clientset) + shutdownLog.Info("Done seting webhook failure policies to Ignore") +} + +func updateValidatingWebhook(c *kubernetes.Clientset) { + validatingWebhookClient := c.AdmissionregistrationV1().ValidatingWebhookConfigurations() + webhook, err := validatingWebhookClient.Get(context.TODO(), OPERATOR_WEBHOOK_NAME, metav1.GetOptions{}) + if err != nil { + shutdownLog.Error(err, "Error getting webhook") + } + webhook.Webhooks[0].FailurePolicy = &failurePolicyIgnore + _, err = validatingWebhookClient.Update(context.TODO(), webhook, metav1.UpdateOptions{}) + if err != nil { + shutdownLog.Error(err, "Error updating webhook") + } +} + +func updateMutatingWebhooks(c *kubernetes.Clientset) { + mutatingWebhookClient := c.AdmissionregistrationV1().MutatingWebhookConfigurations() + for _, name := range []string{OPERATOR_WEBHOOK_NAME, INJECTOR_WEBHOOK_NAME} { + mutatingWebhook, err := mutatingWebhookClient.Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + shutdownLog.Error(err, "Error getting webhook") + continue + } + mutatingWebhook.Webhooks[0].FailurePolicy = &failurePolicyIgnore + _, err = mutatingWebhookClient.Update(context.TODO(), mutatingWebhook, metav1.UpdateOptions{}) + if err != nil { + shutdownLog.Error(err, "Error updating webhook") + } + } +}