From a829c057ad742378bdbaf58237bac601d8bbc0d0 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Thu, 30 Sep 2021 15:23:12 -0500 Subject: [PATCH] Add logic to set the operator's status in the NFD CR Add logic that sets the operator's status in the NFD CR based on whether one or more of NFD's resources is: degraded, progressing, upgradeable, or available. Also add a "applyComponents" function to simplify readability. Signed-off-by: Carlos Eduardo Arango Gutierrez Co-Authored-by: Courtney Pacheco --- api/v1/nodefeaturediscovery_types.go | 3 +- api/v1/zz_generated.deepcopy.go | 5 +- .../nodefeaturediscovery_controller.go | 104 +++- controllers/nodefeaturediscovery_resources.go | 51 ++ controllers/nodefeaturediscovery_status.go | 529 ++++++++++++++++++ go.mod | 1 - go.sum | 41 -- 7 files changed, 685 insertions(+), 49 deletions(-) create mode 100644 controllers/nodefeaturediscovery_status.go diff --git a/api/v1/nodefeaturediscovery_types.go b/api/v1/nodefeaturediscovery_types.go index 8d675dd0..70716853 100644 --- a/api/v1/nodefeaturediscovery_types.go +++ b/api/v1/nodefeaturediscovery_types.go @@ -17,7 +17,6 @@ limitations under the License. package v1 import ( - conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -92,7 +91,7 @@ type ConfigMap struct { type NodeFeatureDiscoveryStatus struct { // Conditions represents the latest available observations of current state. // +optional - Conditions []conditionsv1.Condition `json:"conditions,omitempty"` + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index e40680f7..a579367f 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* @@ -21,7 +22,7 @@ limitations under the License. package v1 import ( - conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -131,7 +132,7 @@ func (in *NodeFeatureDiscoveryStatus) DeepCopyInto(out *NodeFeatureDiscoveryStat *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]conditionsv1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/controllers/nodefeaturediscovery_controller.go b/controllers/nodefeaturediscovery_controller.go index c561f4c3..9adf7d0b 100644 --- a/controllers/nodefeaturediscovery_controller.go +++ b/controllers/nodefeaturediscovery_controller.go @@ -162,17 +162,115 @@ func (r *NodeFeatureDiscoveryReconciler) Reconcile(ctx context.Context, req ctrl r.Log.Info("Ready to apply components") nfd.init(r, instance) + result, err := applyComponents() + if err != nil { + return ctrl.Result{Requeue: true}, err + } + + // Check the status of the NFD Operator Worker ServiceAccount + if rstatus, err := r.getWorkerServiceAccountConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDWorkerServiceAccount, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDWorkerServiceAccountDegraded, "nfd-worker service account has been degraded") + } + + // Check the status of the NFD Operator Master ServiceAccount + if rstatus, err := r.getMasterServiceAccountConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDMasterServiceAccount, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDMasterServiceAccountDegraded, "nfd-master service account has been degraded") + } + + // Check the status of the NFD Operator role + if rstatus, err := r.getRoleConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionNFDRoleDegraded, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDRoleDegraded, "nfd-worker role has been degraded") + } + + // Check the status of the NFD Operator cluster role + if rstatus, err := r.getClusterRoleConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionNFDClusterRoleDegraded, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDClusterRoleDegraded, "nfd ClusterRole has been degraded") + } + + // Check the status of the NFD Operator cluster role binding + if rstatus, err := r.getClusterRoleBindingConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDClusterRoleBinding, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDClusterRoleBindingDegraded, "nfd ClusterRole has been degraded") + } + + // Check the status of the NFD Operator role binding + if rstatus, err := r.getRoleBindingConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDRoleBinding, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDRoleBindingDegraded, "nfd ClusterRoleBinding has been degraded") + } + + // Check the status of the NFD Operator Service + if rstatus, err := r.getServiceConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDService, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDServiceDegraded, "nfd Service has been degraded") + } + + // Check the status of the NFD Operator worker ConfigMap + if rstatus, err := r.getWorkerConfigConditions(nfd); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDWorkerConfig, err.Error()) + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, conditionNFDWorkerConfigDegraded, "nfd-worker ConfigMap has been degraded") + } + + // Check the status of the NFD Operator Worker DaemonSet + if rstatus, err := r.getWorkerDaemonSetConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDWorkerDaemonSet, err.Error()) + } else if rstatus.isProgressing { + return r.updateProgressingCondition(instance, err.Error(), "nfd-worker Daemonset is progressing") + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, err.Error(), "nfd-worker Daemonset has been degraded") + } + + // Check the status of the NFD Operator Master DaemonSet + if rstatus, err := r.getMasterDaemonSetConditions(ctx); err != nil { + return r.updateDegradedCondition(instance, conditionFailedGettingNFDMasterDaemonSet, err.Error()) + } else if rstatus.isProgressing { + return r.updateProgressingCondition(instance, err.Error(), "nfd-master Daemonset is progressing") + } else if rstatus.isDegraded { + return r.updateDegradedCondition(instance, err.Error(), "nfd-master Daemonset has been degraded") + } + + // Get available conditions + conditions := r.getAvailableConditions() + + // Update the status of the resource on the CRD + if err := r.updateStatus(instance, conditions); err != nil { + if result != nil { + return *result, err + } + return reconcile.Result{}, err + } + + if result != nil { + return *result, nil + } + + // All objects are healthy during reconcile loop + return ctrl.Result{}, nil +} + +func applyComponents() (*reconcile.Result, error) { // Run through all control functions, return an error on any NotReady resource. for { err := nfd.step() if err != nil { - return reconcile.Result{}, err + return &reconcile.Result{}, err } if nfd.last() { break } } - - return ctrl.Result{}, nil + return &ctrl.Result{}, nil } diff --git a/controllers/nodefeaturediscovery_resources.go b/controllers/nodefeaturediscovery_resources.go index d84461d7..188cbcde 100644 --- a/controllers/nodefeaturediscovery_resources.go +++ b/controllers/nodefeaturediscovery_resources.go @@ -17,6 +17,7 @@ limitations under the License. package controllers import ( + "context" "io/ioutil" "os" "path/filepath" @@ -28,6 +29,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/kubectl/pkg/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" ) // assetsFromFile is the content of an asset file as raw data @@ -162,3 +164,52 @@ func panicIfError(err error) { panic(err) } } + +// getServiceAccount gets one of the NFD Operator's ServiceAccounts +func (r *NodeFeatureDiscoveryReconciler) getServiceAccount(ctx context.Context, namespace string, name string) (*corev1.ServiceAccount, error) { + sa := &corev1.ServiceAccount{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, sa) + return sa, err +} + +// getDaemonSet gets one of the NFD Operator's DaemonSets +func (r *NodeFeatureDiscoveryReconciler) getDaemonSet(ctx context.Context, namespace string, name string) (*appsv1.DaemonSet, error) { + ds := &appsv1.DaemonSet{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, ds) + return ds, err +} + +// getService gets one of the NFD Operator's Services +func (r *NodeFeatureDiscoveryReconciler) getService(ctx context.Context, namespace string, name string) (*corev1.Service, error) { + svc := &corev1.Service{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, svc) + return svc, err +} + +// getRole gets one of the NFD Operator's Roles +func (r *NodeFeatureDiscoveryReconciler) getRole(ctx context.Context, namespace string, name string) (*rbacv1.Role, error) { + role := &rbacv1.Role{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, role) + return role, err +} + +// getRoleBinding gets one of the NFD Operator's RoleBindings +func (r *NodeFeatureDiscoveryReconciler) getRoleBinding(ctx context.Context, namespace string, name string) (*rbacv1.RoleBinding, error) { + rb := &rbacv1.RoleBinding{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, rb) + return rb, err +} + +// getClusterRole gets one of the NFD Operator's ClusterRoles +func (r *NodeFeatureDiscoveryReconciler) getClusterRole(ctx context.Context, namespace string, name string) (*rbacv1.ClusterRole, error) { + cr := &rbacv1.ClusterRole{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, cr) + return cr, err +} + +// getClusterRoleBinding gets one of the NFD Operator's ClusterRoleBindings +func (r *NodeFeatureDiscoveryReconciler) getClusterRoleBinding(ctx context.Context, namespace string, name string) (*rbacv1.ClusterRoleBinding, error) { + crb := &rbacv1.ClusterRoleBinding{} + err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, crb) + return crb, err +} diff --git a/controllers/nodefeaturediscovery_status.go b/controllers/nodefeaturediscovery_status.go new file mode 100644 index 00000000..31f7e310 --- /dev/null +++ b/controllers/nodefeaturediscovery_status.go @@ -0,0 +1,529 @@ +/* +Copyright 2020-2021 The Kubernetes 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 controllers + +import ( + "context" + "errors" + "time" + + meta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + nfdv1 "github.com/kubernetes-sigs/node-feature-discovery-operator/api/v1" +) + +const ( + nfdNamespace = "node-feature-discovery-operator" + workerInstance string = "nfd-worker" + masterInstance string = "nfd-master" +) + +const ( + // Resource is missing + conditionFailedGettingNFDWorkerConfig = "FailedGettingNFDWorkerConfig" + conditionFailedGettingNFDWorkerServiceAccount = "FailedGettingNFDWorkerServiceAccount" + conditionFailedGettingNFDMasterServiceAccount = "FailedGettingNFDMasterServiceAccount" + conditionFailedGettingNFDService = "FailedGettingNFDService" + conditionFailedGettingNFDWorkerDaemonSet = "FailedGettingNFDWorkerDaemonSet" + conditionFailedGettingNFDMasterDaemonSet = "FailedGettingNFDMasterDaemonSet" + conditionFailedGettingNFDRoleBinding = "FailedGettingNFDRoleBinding" + conditionFailedGettingNFDClusterRoleBinding = "FailedGettingNFDClusterRole" + + // Resource degraded + conditionNFDWorkerConfigDegraded = "NFDWorkerConfigResourceDegraded" + conditionNFDWorkerServiceAccountDegraded = "NFDWorkerServiceAccountDegraded" + conditionNFDMasterServiceAccountDegraded = "NFDMasterServiceAccountDegraded" + conditionNFDServiceDegraded = "NFDServiceDegraded" + conditionNFDWorkerDaemonSetDegraded = "NFDWorkerDaemonSetDegraded" + conditionNFDMasterDaemonSetDegraded = "NFDMasterDaemonSetDegraded" + conditionNFDRoleDegraded = "NFDRoleDegraded" + conditionNFDRoleBindingDegraded = "NFDRoleBindingDegraded" + conditionNFDClusterRoleDegraded = "NFDClusterRoleDegraded" + conditionNFDClusterRoleBindingDegraded = "NFDClusterRoleBindingDegraded" + + // Unknown errors. (Catch all) + errorNFDWorkerDaemonSetUnknown = "NFDWorkerDaemonSetCorrupted" + errorNFDMasterDaemonSetUnknown = "NFDMasterDaemonSetCorrupted" + + // Invalid node type. (Denotes that the node should be either + // 'worker' or 'master') + errorInvalidNodeType = "InvalidNodeTypeSelected" + + // More nodes are listed as "ready" than selected + errorTooManyNFDWorkerDaemonSetReadyNodes = "NFDWorkerDaemonSetHasMoreNodesThanScheduled" + errorTooManyNFDMasterDaemonSetReadyNodes = "NFDMasterDaemonSetHasMoreNodesThanScheduled" + + // DaemonSet warnings (for "Progressing" conditions) + warningNumberOfReadyNodesIsLessThanScheduled = "warningNumberOfReadyNodesIsLessThanScheduled" + warningNFDWorkerDaemonSetProgressing = "warningNFDWorkerDaemonSetProgressing" + warningNFDMasterDaemonSetProgressing = "warningNFDMasterDaemonSetProgressing" + + // ConditionAvailable indicates that the resources maintained by the operator, + // is functional and available in the cluster. + ConditionAvailable string = "Available" + + // ConditionProgressing indicates that the operator is actively making changes to the resources maintained by the + // operator + ConditionProgressing string = "Progressing" + + // ConditionDegraded indicates that the resources maintained by the operator are not functioning completely. + // An example of a degraded state would be if not all pods in a deployment were running. + // It may still be available, but it is degraded + ConditionDegraded string = "Degraded" + + // ConditionUpgradeable indicates whether the resources maintained by the operator are in a state that is safe to upgrade. + // When `False`, the resources maintained by the operator should not be upgraded and the + // message field should contain a human readable description of what the administrator should do to + // allow the operator to successfully update the resources maintained by the operator. + ConditionUpgradeable string = "Upgradeable" +) + +// updateStatus is used to update the status of a resource (e.g., degraded, +// available, etc.) +func (r *NodeFeatureDiscoveryReconciler) updateStatus(nfd *nfdv1.NodeFeatureDiscovery, condition []metav1.Condition) error { + + // The actual 'nfd' object should *not* be modified when trying to + // check the object's status. This variable is a dummy variable used + // to set temporary conditions. + nfdCopy := nfd.DeepCopy() + + // If a set of conditions exists, then it should be added to the + // 'nfd' Copy. + if condition != nil { + nfdCopy.Status.Conditions = condition + } + + // Next step is to check if we need to update the status + modified := false + + // Because there are only four possible conditions (degraded, available, + // updatable, and progressing), it isn't necessary to check if old + // conditions should be removed. + for _, newCondition := range nfdCopy.Status.Conditions { + oldCondition := meta.FindStatusCondition(nfd.Status.Conditions, newCondition.Type) + if oldCondition == nil { + modified = true + break + } + // Ignore timestamps to avoid infinite reconcile loops + if oldCondition.Status != newCondition.Status || + oldCondition.Reason != newCondition.Reason || + oldCondition.Message != newCondition.Message { + modified = true + break + } + } + + // If nothing has been modified, then return nothing. Even if the list + // of 'conditions' is not empty, it should not be counted as an update + // if it was already counted as an update before. + if !modified { + return nil + } + return r.Status().Update(context.TODO(), nfdCopy) +} + +// updateDegradedCondition is used to mark a given resource as "degraded" so that +// the reconciler can take steps to rectify the situation. +func (r *NodeFeatureDiscoveryReconciler) updateDegradedCondition(nfd *nfdv1.NodeFeatureDiscovery, reason, message string) (ctrl.Result, error) { + degradedCondition := r.getDegradedConditions(reason, message) + if err := r.updateStatus(nfd, degradedCondition); err != nil { + return reconcile.Result{}, err + } + + return reconcile.Result{Requeue: true}, nil +} + +// updateProgressingCondition is used to mark a given resource as "progressing" so +// that the reconciler can take steps to rectify the situation. +func (r *NodeFeatureDiscoveryReconciler) updateProgressingCondition(nfd *nfdv1.NodeFeatureDiscovery, reason, message string) (ctrl.Result, error) { + progressingCondition := r.getProgressingConditions(reason, message) + if err := r.updateStatus(nfd, progressingCondition); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{Requeue: true}, nil +} + +// getAvailableConditions returns a list of conditionsv1.Condition objects and marks +// every condition as FALSE except for conditionsv1.ConditionAvailable so that the +// reconciler can determine that the resource is available. +func (r *NodeFeatureDiscoveryReconciler) getAvailableConditions() []metav1.Condition { + now := time.Now() + return []metav1.Condition{ + { + Type: ConditionAvailable, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionUpgradeable, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionProgressing, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionDegraded, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + } +} + +// getDegradedConditions returns a list of conditions.Condition objects and marks +// every condition as FALSE except for conditions.ConditionDegraded so that the +// reconciler can determine that the resource is degraded. +func (r *NodeFeatureDiscoveryReconciler) getDegradedConditions(reason string, message string) []metav1.Condition { + now := time.Now() + return []metav1.Condition{ + { + Type: ConditionAvailable, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionUpgradeable, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionProgressing, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionDegraded, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + Reason: reason, + Message: message, + }, + } +} + +// getProgressingConditions returns a list of conditions.Condition objects and marks +// every condition as FALSE except for conditions.ConditionProgressing so that the +// reconciler can determine that the resource is progressing. +func (r *NodeFeatureDiscoveryReconciler) getProgressingConditions(reason string, message string) []metav1.Condition { + now := time.Now() + return []metav1.Condition{ + { + Type: ConditionAvailable, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionUpgradeable, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: ConditionProgressing, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + Reason: reason, + Message: message, + }, + { + Type: ConditionDegraded, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + } +} + +// The status of the resource (available, upgradeable, progressing, or +// degraded). +type Status struct { + + // Is the resource available, upgradable, etc.? + isAvailable bool + isUpgradeable bool + isProgressing bool + isDegraded bool +} + +// initializeDegradedStatus initializes the status struct to degraded +func initializeDegradedStatus() Status { + return Status{ + isAvailable: false, + isUpgradeable: false, + isProgressing: false, + isDegraded: true, + } +} + +// getWorkerDaemonSetConditions is a wrapper around "getDaemonSetConditions" for +// worker DaemonSets +func (r *NodeFeatureDiscoveryReconciler) getWorkerDaemonSetConditions(ctx context.Context) (Status, error) { + return r.getDaemonSetConditions(ctx, workerInstance) +} + +// getMasterDaemonSetConditions is a wrapper around "getDaemonSetConditions" for +// master DaemonSets +func (r *NodeFeatureDiscoveryReconciler) getMasterDaemonSetConditions(ctx context.Context) (Status, error) { + return r.getDaemonSetConditions(ctx, masterInstance) +} + +// getDaemonSetConditions gets the current status of a DaemonSet. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getDaemonSetConditions(ctx context.Context, nodeType string) (Status, error) { + + // Initialize the resource's status to 'Degraded' + status := initializeDegradedStatus() + + ds, err := r.getDaemonSet(ctx, nfdNamespace, nodeType) + if err != nil { + return status, err + } + + // Index the DaemonSet status. (Note: there is no "Conditions" array here.) + dsStatus := ds.Status + + // Index the relevant values from here + numberReady := dsStatus.NumberReady + currentNumberScheduled := dsStatus.CurrentNumberScheduled + numberDesired := dsStatus.DesiredNumberScheduled + numberUnavailable := dsStatus.NumberUnavailable + + // If the number desired is zero or the number of unavailable nodes is zero, + // then we have a problem because we should at least see 1 pod per node + if numberDesired == 0 { + if nodeType == workerInstance { + return status, errors.New(errorNFDWorkerDaemonSetUnknown) + } + return status, errors.New(errorNFDMasterDaemonSetUnknown) + } + if numberUnavailable > 0 { + status.isProgressing = true + status.isDegraded = false + if nodeType == workerInstance { + return status, errors.New(warningNFDWorkerDaemonSetProgressing) + } + return status, errors.New(warningNFDMasterDaemonSetProgressing) + } + + // If there are none scheduled, then we have a problem because we should + // at least see 1 pod per node, even after the scheduling happens. + if currentNumberScheduled == 0 { + if nodeType == workerInstance { + return status, errors.New(conditionNFDWorkerDaemonSetDegraded) + } + return status, errors.New(conditionNFDMasterDaemonSetDegraded) + } + + // Just check in case the number of "ready" nodes is greater than the + // number of scheduled ones (for whatever reason) + if numberReady > currentNumberScheduled { + status.isDegraded = false + if nodeType == workerInstance { + return status, errors.New(errorTooManyNFDWorkerDaemonSetReadyNodes) + } + return status, errors.New(errorTooManyNFDMasterDaemonSetReadyNodes) + } + + // If we have less than the number of scheduled pods, then the DaemonSet + // is in progress + if numberReady < currentNumberScheduled { + status.isProgressing = true + status.isDegraded = false + return status, errors.New(warningNumberOfReadyNodesIsLessThanScheduled) + } + + // If all nodes are ready, then update the status to be "isAvailable" + status.isAvailable = true + status.isDegraded = false + + return status, nil +} + +// getServiceConditions gets the current status of a Service. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getServiceConditions(ctx context.Context) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing Service from the reconciler + _, err := r.getService(ctx, nfdNamespace, masterInstance) + + // If the Service could not be obtained, then it is degraded + if err != nil { + return status, errors.New(conditionNFDServiceDegraded) + } + + // If we could get the Service, then it is not empty and it exists + status.isAvailable = true + status.isDegraded = false + + return status, nil + +} + +// getWorkerConfigConditions gets the current status of a worker config. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getWorkerConfigConditions(n NFD) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing ConfigMap from the reconciler + wc := n.ins.Spec.WorkerConfig.ConfigData + + // If 'wc' is nil, then the resource hasn't been (re)created yet + if wc == "" { + return status, errors.New(conditionNFDWorkerConfigDegraded) + } + + // If we could get the WorkerConfig, then it is not empty and it exists + status.isDegraded = false + status.isAvailable = true + + return status, nil +} + +// getRoleConditions gets the current status of a Role. If an error occurs, this +// function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getRoleConditions(ctx context.Context) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing Role from the reconciler + _, err := r.getRole(ctx, nfdNamespace, workerInstance) + + // If the error is not nil, then the Role hasn't been (re)created yet + if err != nil { + return status, errors.New(conditionNFDRoleDegraded) + } + + // Set the resource to available + status.isAvailable = true + status.isDegraded = false + + return status, nil +} + +// getDaemonRoleBindingConditions gets the current status of a RoleBinding. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getRoleBindingConditions(ctx context.Context) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing RoleBinding from the reconciler + _, err := r.getRoleBinding(ctx, nfdNamespace, workerInstance) + + // If the error is not nil, then the RoleBinding hasn't been (re)created yet + if err != nil { + return status, errors.New(conditionNFDRoleBindingDegraded) + } + + // Set the resource to available + status.isAvailable = true + status.isDegraded = false + + return status, nil +} + +// geClusterRoleConditions gets the current status of a ClusterRole. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getClusterRoleConditions(ctx context.Context) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing ClusterRole from the reconciler + _, err := r.getClusterRole(ctx, "", masterInstance) + + // If 'clusterRole' is nil, then it hasn't been (re)created yet + if err != nil { + return status, errors.New(conditionNFDClusterRoleDegraded) + } + + // Set the resource to available + status.isAvailable = true + status.isDegraded = false + + return status, nil +} + +// getClusterRoleBindingConditions gets the current status of a ClusterRoleBinding. +// If an error occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getClusterRoleBindingConditions(ctx context.Context) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the existing ClusterRoleBinding from the reconciler + _, err := r.getClusterRoleBinding(ctx, "", masterInstance) + + // If the error is not nil, then the ClusterRoleBinding hasn't been (re)created + // yet + if err != nil { + return status, errors.New(conditionNFDClusterRoleBindingDegraded) + } + + // Set the resource to available + status.isAvailable = true + status.isDegraded = false + + return status, nil +} + +// getWorkerServiceAccountConditions is a wrapper around "getServiceAccountConditions" for +// worker service accounts +func (r *NodeFeatureDiscoveryReconciler) getWorkerServiceAccountConditions(ctx context.Context) (Status, error) { + return r.getServiceAccountConditions(ctx, workerInstance) +} + +// getMasterServiceAccountConditions is a wrapper around "getServiceAccountConditions" for +// master service accounts +func (r *NodeFeatureDiscoveryReconciler) getMasterServiceAccountConditions(ctx context.Context) (Status, error) { + return r.getServiceAccountConditions(ctx, masterInstance) +} + +// getServiceAccountConditions gets the current status of a ServiceAccount. If an error +// occurs, this function returns the corresponding error message +func (r *NodeFeatureDiscoveryReconciler) getServiceAccountConditions(ctx context.Context, nodeType string) (Status, error) { + + // Initialize status to 'Degraded' + status := initializeDegradedStatus() + + // Get the service account from the reconciler + _, err := r.getServiceAccount(ctx, nfdNamespace, nodeType) + + // If the error is not nil, then the ServiceAccount hasn't been (re)created yet + if err != nil { + if nodeType == workerInstance { + return status, errors.New(conditionNFDWorkerServiceAccountDegraded) + } + return status, errors.New(conditionNFDMasterServiceAccountDegraded) + } + + // Set the resource to available + status.isAvailable = true + status.isDegraded = false + + return status, nil +} diff --git a/go.mod b/go.mod index deca7bfa..e4be6a7c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/go-logr/logr v0.3.0 github.com/onsi/ginkgo v1.14.1 github.com/onsi/gomega v1.10.2 - github.com/openshift/custom-resource-status v0.0.0-20210221154447-420d9ecf2a00 k8s.io/api v0.20.4 k8s.io/apimachinery v0.20.4 k8s.io/client-go v0.20.4 diff --git a/go.sum b/go.sum index ce85d37a..5e98f8bc 100644 --- a/go.sum +++ b/go.sum @@ -106,7 +106,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -120,13 +119,11 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -200,7 +197,6 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= @@ -217,7 +213,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -244,7 +239,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -261,8 +255,6 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= @@ -305,7 +297,6 @@ github.com/imdario/mergo v0.3.10 h1:6q5mVkdH/vYmqngx7kZQTjJ5HRsx+ImorDIEQ+beJgc= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= @@ -358,7 +349,6 @@ github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/f github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -372,21 +362,17 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/openshift/custom-resource-status v0.0.0-20210221154447-420d9ecf2a00 h1:w/APGa+Tkf3TUaws5TiPa7ZCkXT0GHY6GK0f/7+MDPc= -github.com/openshift/custom-resource-status v0.0.0-20210221154447-420d9ecf2a00/go.mod h1:GDjWl0tX6FNIj82vIxeudWeSx2Ff6nDZ8uJn0ohUFvo= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -395,7 +381,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -422,7 +407,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -456,7 +440,6 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -513,9 +496,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= @@ -546,7 +527,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -592,7 +572,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -632,7 +611,6 @@ golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -652,7 +630,6 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -699,9 +676,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k= gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -765,7 +739,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -794,13 +767,11 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.0.0-20190725062911-6607c48751ae/go.mod h1:1O0xzX/RAtnm7l+5VEUxZ1ysO2ghatfq/OZED4zM9kA= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= k8s.io/api v0.20.4 h1:xZjKidCirayzX6tHONRQyTNDVIR55TYVqgATqo6ZULY= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/apiextensions-apiserver v0.19.2 h1:oG84UwiDsVDu7dlsGQs5GySmQHCzMhknfhFExJMz9tA= k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg= -k8s.io/apimachinery v0.0.0-20190719140911-bfcf53abc9f8/go.mod h1:sBJWIJZfxLhp7mRsRyuAE/NfKTr3kXGR1iaqg8O0gJo= k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.20.4 h1:vhxQ0PPUUU2Ns1b9r4/UFp13UPs8cw2iOoTjnY9faa0= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= @@ -809,26 +780,21 @@ k8s.io/cli-runtime v0.20.4/go.mod h1:dz38e1CM4uuIhy8PMFUZv7qsvIdoE3ByZYlmbHNCkt4 k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= k8s.io/client-go v0.20.4 h1:85crgh1IotNkLpKYKZHVNI1JT86nr/iDCvq2iWKsql4= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= -k8s.io/code-generator v0.0.0-20190717022600-77f3a1fe56bb/go.mod h1:cDx5jQmWH25Ff74daM7NVYty9JWw9dvIS9zT9eIubCY= k8s.io/code-generator v0.19.2/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/code-generator v0.20.4/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo= k8s.io/component-base v0.20.4 h1:gdvPs4G11e99meQnW4zN+oYOjH8qkLz1sURrAzvKWqc= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-helpers v0.20.4/go.mod h1:S7jGg8zQp3kwvSzfuGtNaQAMVmvzomXDioTm5vABn9g= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= @@ -839,11 +805,6 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= @@ -851,8 +812,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQb sigs.k8s.io/controller-runtime v0.7.0 h1:bU20IBBEPccWz5+zXpLnpVsgBYxqclaHu1pVDl/gEt8= sigs.k8s.io/controller-runtime v0.7.0/go.mod h1:pJ3YBrJiAqMAZKi6UVGuE98ZrroV1p+pIhoHsMm9wdU= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=