From ff8a05272322ff7d5d86f6108584508f7f0f1891 Mon Sep 17 00:00:00 2001 From: Shafeeque E S Date: Thu, 2 Mar 2023 12:58:14 +0530 Subject: [PATCH] Run `make revendor` --- .../pkg/controller/healthcheck/actuator.go | 143 -------- .../pkg/controller/healthcheck/controller.go | 199 ------------ .../healthcheck/general/daemonset.go | 129 -------- .../healthcheck/general/deployment.go | 129 -------- .../healthcheck/general/managed_resource.go | 110 ------- .../healthcheck/general/statefulsets.go | 127 -------- .../healthcheck/healthcheck_actuator.go | 285 ---------------- .../pkg/controller/healthcheck/inject.go | 49 --- .../controller/healthcheck/message_util.go | 99 ------ .../pkg/controller/healthcheck/reconciler.go | 306 ------------------ vendor/modules.txt | 2 - 11 files changed, 1578 deletions(-) delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/actuator.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/controller.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/daemonset.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/deployment.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/managed_resource.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/statefulsets.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/healthcheck_actuator.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/inject.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/message_util.go delete mode 100644 vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/reconciler.go diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/actuator.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/actuator.go deleted file mode 100644 index 241d50ac..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/actuator.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "context" - "time" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" -) - -/* - Each extension can register multiple HealthCheckActuators with various health checks to check the API Objects it deploys. - Each new actuator is responsible for a single extension resource (e.g Worker) - predicates can be defined for fine-grained control over which objects to watch. - - The HealthCheck reconciler triggers the registered actuator to execute the health checks. - After, the reconciler writes conditions to the extension resource. Multiple checks that contribute to the HealthConditionType XYZ result in only one condition with .type XYZ). - To contribute to the Shoot's health, the Gardener/Gardenlet checks each extension for conditions containing one of the following HealthConditionTypes: - - SystemComponentsHealthy, - - EveryNodeReady, - - ControlPlaneHealthy. - However, extensions are free to choose any healthCheckType. - - Generic HealthCheck functions for various API Objects are provided and can be reused. - Many providers deploy helm charts via managed resources that are picked up by the resource-manager making sure that - the helm chart is applied and all its components (Deployments, StatefulSets, DaemonSets, ...) are healthy. - To integrate, the health check controller can also check the health of managed resources. - - More sophisticated checks should be implemented in the extension itself by using the HealthCheck interface. -*/ - -// GetExtensionObjectFunc returns the extension object that should be registered with the health check controller. -// For example: func() extensionsv1alpha1.Object {return &extensionsv1alpha1.Worker{}} -type GetExtensionObjectFunc = func() extensionsv1alpha1.Object - -// GetExtensionObjectListFunc returns the extension object list that should be registered with the health check controller. -// For example: func() client.ObjectList { return &extensionsv1alpha1.WorkerList{} } -type GetExtensionObjectListFunc = func() client.ObjectList - -// PreCheckFunc checks whether the health check shall be performed based on the given object and cluster. -type PreCheckFunc = func(context.Context, client.Client, client.Object, *extensionscontroller.Cluster) bool - -// ErrorCodeCheckFunc checks if the given error is user specific and return respective Gardener ErrorCodes. -type ErrorCodeCheckFunc = func(error) []gardencorev1beta1.ErrorCode - -// ConditionTypeToHealthCheck registers a HealthCheck for the given ConditionType. If the PreCheckFunc is not nil it will -// be executed with the given object before the health check if performed. Otherwise, the health check will always be -// performed. -type ConditionTypeToHealthCheck struct { - ConditionType string - PreCheckFunc PreCheckFunc - HealthCheck HealthCheck - ErrorCodeCheckFunc ErrorCodeCheckFunc -} - -// HealthCheckActuator acts upon registered resources. -type HealthCheckActuator interface { - // ExecuteHealthCheckFunctions is regularly called by the health check controller - // Executes all registered health checks and aggregates the results. - // Returns - // - Result for each healthConditionTypes registered with the individual health checks. - // - an error if it could not execute the health checks. - // This results in a condition with with type "Unknown" with reason "ConditionCheckError". - ExecuteHealthCheckFunctions(context.Context, logr.Logger, types.NamespacedName) (*[]Result, error) -} - -// Result represents an aggregated health status for the health checks performed on the dependent API Objects of an extension resource. -// A Result refers to a single healthConditionType (e.g SystemComponentsHealthy) of an extension Resource. -type Result struct { - // HealthConditionType is used as the .type field of the Condition that the HealthCheck controller writes to the extension Resource. - // To contribute to the Shoot's health, the Gardener checks each extension for a Health Condition Type of SystemComponentsHealthy, EveryNodeReady, ControlPlaneHealthy. - HealthConditionType string - // Status contains the status for the health checks that have been performed for an extension resource - Status gardencorev1beta1.ConditionStatus - // Detail contains details to why the health checks are unsuccessful - Detail *string - // SuccessfulChecks is the amount of successful health checks - SuccessfulChecks int - // ProgressingChecks is the amount of progressing health checks - ProgressingChecks int - // UnsuccessfulChecks is the amount of unsuccessful health checks - UnsuccessfulChecks int - // FailedChecks is the amount of health checks that could not be performed (e.g client could not reach Api Server) - // Results in a condition with with type "Unknown" with reason "ConditionCheckError" for this healthConditionType - FailedChecks int - // Codes is an optional list of error codes that were produced by the health checks. - Codes []gardencorev1beta1.ErrorCode - // ProgressingThreshold is the threshold duration after which a health check that reported the `Progressing` status - // shall be transitioned to `False` - ProgressingThreshold *time.Duration -} - -// GetDetails returns the details of the health check result -func (h *Result) GetDetails() string { - if h.Detail == nil { - return "" - } - return *h.Detail -} - -// HealthCheck represents a single health check -// Each health check gets the shoot and seed clients injected -// returns isHealthy, conditionReason, conditionDetail and error -// returning an error means the health check could not be conducted and will result in a condition with with type "Unknown" and reason "ConditionCheckError" -type HealthCheck interface { - // Check is the function that executes the actual health check - Check(context.Context, types.NamespacedName) (*SingleCheckResult, error) - // SetLoggerSuffix injects the logger - SetLoggerSuffix(string, string) - // DeepCopy clones the healthCheck - DeepCopy() HealthCheck -} - -// SingleCheckResult is the result for a health check -type SingleCheckResult struct { - // Status contains the status for the health check that has been performed for an extension resource - Status gardencorev1beta1.ConditionStatus - // Detail contains details for the health check being unsuccessful - Detail string - // Codes optionally contains a list of error codes related to the health check - Codes []gardencorev1beta1.ErrorCode - // ProgressingThreshold is the threshold duration after which a health check that reported the `Progressing` status - // shall be transitioned to `False` - ProgressingThreshold *time.Duration -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/controller.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/controller.go deleted file mode 100644 index 832e0be8..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/controller.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "fmt" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/source" - - extensionsconfig "github.com/gardener/gardener/extensions/pkg/apis/config" - extensionspredicate "github.com/gardener/gardener/extensions/pkg/predicate" - "github.com/gardener/gardener/pkg/api/extensions" - extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" - "github.com/gardener/gardener/pkg/controllerutils/mapper" - "github.com/gardener/gardener/pkg/utils" -) - -const ( - // ControllerName is the name of the controller. - ControllerName = "healthcheck" -) - -// AddArgs are arguments for adding an health check controller to a controller-runtime manager. -type AddArgs struct { - // ControllerOptions are the controller options used for creating a controller. - // The options.Reconciler is always overridden with a reconciler created from the - // given actuator. - ControllerOptions controller.Options - // Predicates are the predicates to use. - // If unset, GenerationChanged will be used. - Predicates []predicate.Predicate - // Type is the type of the resource considered for reconciliation. - Type string - // SyncPeriod is the duration how often the registered extension is being reconciled - SyncPeriod metav1.Duration - // registeredExtension is the registered extensions that the HealthCheck Controller watches and writes HealthConditions for. - // The Gardenlet reads the conditions on the extension Resource. - // Through this mechanism, the extension can contribute to the Shoot's HealthStatus. - registeredExtension *RegisteredExtension - // GetExtensionObjListFunc returns a client.ObjectList representation of the extension to register - GetExtensionObjListFunc GetExtensionObjectListFunc -} - -// DefaultAddArgs are the default Args for the health check controller. -type DefaultAddArgs struct { - // Controller are the controller.Options. - Controller controller.Options - // HealthCheckConfig contains additional config for the health check controller - HealthCheckConfig extensionsconfig.HealthCheckConfig -} - -// RegisteredExtension is a registered extensions that the HealthCheck Controller watches. -// The field extension contains any extension object -// The field healthConditionTypes contains all distinct healthCondition types (extracted from the healthCheck). -// They are used as the .type field of the Condition that the HealthCheck controller writes to the extension resource. -// The field groupVersionKind stores the GroupVersionKind of the extension resource -type RegisteredExtension struct { - extension extensionsv1alpha1.Object - getExtensionObjFunc GetExtensionObjectFunc - healthConditionTypes []string - groupVersionKind schema.GroupVersionKind -} - -// DefaultRegistration configures the default health check NewActuator to execute the provided health checks and adds it to the provided controller-runtime manager. -// the NewActuator reconciles a single extension with a specific type and writes conditions for each distinct healthConditionTypes. -// extensionType (e.g aws) defines the spec.type of the extension to watch -// kind defines the GroupVersionKind of the extension -// GetExtensionObjListFunc returns a client.ObjectList representation of the extension to register -// getExtensionObjFunc returns a extensionsv1alpha1.Object representation of the extension to register -// mgr is the controller runtime manager -// opts contain config for the healthcheck controller -// custom predicates allow for fine-grained control which resources to watch -// healthChecks defines the checks to execute mapped to the healthConditionTypes its contributing to (e.g checkDeployment in Seed -> ControlPlaneHealthy). -// register returns a runtime representation of the extension resource to register it with the controller-runtime -func DefaultRegistration(extensionType string, kind schema.GroupVersionKind, getExtensionObjListFunc GetExtensionObjectListFunc, getExtensionObjFunc GetExtensionObjectFunc, mgr manager.Manager, opts DefaultAddArgs, customPredicates []predicate.Predicate, healthChecks []ConditionTypeToHealthCheck) error { - predicates := append(DefaultPredicates(), customPredicates...) - opts.Controller.RecoverPanic = pointer.Bool(true) - - args := AddArgs{ - ControllerOptions: opts.Controller, - Predicates: predicates, - Type: extensionType, - SyncPeriod: opts.HealthCheckConfig.SyncPeriod, - GetExtensionObjListFunc: getExtensionObjListFunc, - } - - if err := args.RegisterExtension(getExtensionObjFunc, getHealthCheckTypes(healthChecks), kind); err != nil { - return err - } - - var shootRestOptions extensionsconfig.RESTOptions - if opts.HealthCheckConfig.ShootRESTOptions != nil { - shootRestOptions = *opts.HealthCheckConfig.ShootRESTOptions - } - - healthCheckActuator := NewActuator(args.Type, args.GetExtensionGroupVersionKind().Kind, getExtensionObjFunc, healthChecks, shootRestOptions) - return Register(mgr, args, healthCheckActuator) -} - -// RegisterExtension registered a resource and its corresponding healthCheckTypes. -// throws and error if the extensionResources is not a extensionsv1alpha1.Object -// The controller writes the healthCheckTypes as a condition.type into the extension resource. -// To contribute to the Shoot's health, the Gardener checks each extension for a Health Condition Type of SystemComponentsHealthy, EveryNodeReady, ControlPlaneHealthy. -// However extensions are free to choose any healthCheckType -func (a *AddArgs) RegisterExtension(getExtensionObjFunc GetExtensionObjectFunc, conditionTypes []string, kind schema.GroupVersionKind) error { - acc, err := extensions.Accessor(getExtensionObjFunc()) - if err != nil { - return err - } - - a.registeredExtension = &RegisteredExtension{ - extension: acc, - healthConditionTypes: conditionTypes, - groupVersionKind: kind, - getExtensionObjFunc: getExtensionObjFunc, - } - return nil -} - -// GetExtensionGroupVersionKind returns the schema.GroupVersionKind of the registered extension of this AddArgs. -func (a *AddArgs) GetExtensionGroupVersionKind() schema.GroupVersionKind { - return a.registeredExtension.groupVersionKind -} - -// DefaultPredicates returns the default predicates. -func DefaultPredicates() []predicate.Predicate { - return []predicate.Predicate{ - // watch: only requeue on spec change to prevent infinite loop - // health checks are being executed every 'sync period' anyways - predicate.GenerationChangedPredicate{}, - } -} - -// Register the extension resource. Must be of type extensionsv1alpha1.Object -// Add creates a new Reconciler and adds it to the Manager. -// and Start it when the Manager is Started. -func Register(mgr manager.Manager, args AddArgs, actuator HealthCheckActuator) error { - args.ControllerOptions.Reconciler = NewReconciler(actuator, *args.registeredExtension, args.SyncPeriod) - return add(mgr, args) -} - -func add(mgr manager.Manager, args AddArgs) error { - // generate random string to create unique manager name, in case multiple managers register the same extension resource - str, err := utils.GenerateRandomString(10) - if err != nil { - return err - } - - controllerName := fmt.Sprintf("%s-%s-%s-%s-%s", ControllerName, args.registeredExtension.groupVersionKind.Kind, args.registeredExtension.groupVersionKind.Group, args.registeredExtension.groupVersionKind.Version, str) - ctrl, err := controller.New(controllerName, mgr, args.ControllerOptions) - if err != nil { - return err - } - - log.Log.Info("Registered health check controller", "kind", args.registeredExtension.groupVersionKind.Kind, "type", args.Type, "conditionTypes", args.registeredExtension.healthConditionTypes, "syncPeriod", args.SyncPeriod.Duration.String()) - - // add type predicate to only watch registered resource (e.g ControlPlane) with a certain type (e.g aws) - predicates := extensionspredicate.AddTypePredicate(args.Predicates, args.Type) - - if err := ctrl.Watch(&source.Kind{Type: args.registeredExtension.getExtensionObjFunc()}, &handler.EnqueueRequestForObject{}, predicates...); err != nil { - return err - } - - // watch Cluster of Shoot provider type (e.g aws) - // this is to be notified when the Shoot is being hibernated (stop health checks) and wakes up (start health checks again) - return ctrl.Watch( - &source.Kind{Type: &extensionsv1alpha1.Cluster{}}, - mapper.EnqueueRequestsFrom(mapper.ClusterToObjectMapper(args.GetExtensionObjListFunc, predicates), mapper.UpdateWithNew, ctrl.GetLogger()), - ) -} - -func getHealthCheckTypes(healthChecks []ConditionTypeToHealthCheck) []string { - types := sets.New[string]() - for _, healthCheck := range healthChecks { - types.Insert(healthCheck.ConditionType) - } - return types.UnsortedList() -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/daemonset.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/daemonset.go deleted file mode 100644 index 0efadca2..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/daemonset.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 general - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/gardener/gardener/extensions/pkg/controller/healthcheck" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - "github.com/gardener/gardener/pkg/utils/kubernetes/health" -) - -// DaemonSetHealthChecker contains all the information for the DaemonSet HealthCheck -type DaemonSetHealthChecker struct { - logger logr.Logger - seedClient client.Client - shootClient client.Client - name string - checkType DaemonSetCheckType -} - -// DaemonSetCheckType in which cluster the check will be executed -type DaemonSetCheckType string - -const ( - daemonSetCheckTypeSeed DaemonSetCheckType = "Seed" - daemonSetCheckTypeShoot DaemonSetCheckType = "Shoot" -) - -// NewSeedDaemonSetHealthChecker is a healthCheck function to check DaemonSets -func NewSeedDaemonSetHealthChecker(name string) healthcheck.HealthCheck { - return &DaemonSetHealthChecker{ - name: name, - checkType: daemonSetCheckTypeSeed, - } -} - -// NewShootDaemonSetHealthChecker is a healthCheck function to check DaemonSets -func NewShootDaemonSetHealthChecker(name string) healthcheck.HealthCheck { - return &DaemonSetHealthChecker{ - name: name, - checkType: daemonSetCheckTypeShoot, - } -} - -// InjectSeedClient injects the seed client -func (healthChecker *DaemonSetHealthChecker) InjectSeedClient(seedClient client.Client) { - healthChecker.seedClient = seedClient -} - -// InjectShootClient injects the shoot client -func (healthChecker *DaemonSetHealthChecker) InjectShootClient(shootClient client.Client) { - healthChecker.shootClient = shootClient -} - -// SetLoggerSuffix injects the logger -func (healthChecker *DaemonSetHealthChecker) SetLoggerSuffix(provider, extension string) { - healthChecker.logger = log.Log.WithName(fmt.Sprintf("%s-%s-healthcheck-deployment", provider, extension)) -} - -// DeepCopy clones the healthCheck struct by making a copy and returning the pointer to that new copy -func (healthChecker *DaemonSetHealthChecker) DeepCopy() healthcheck.HealthCheck { - copy := *healthChecker - return © -} - -// Check executes the health check -func (healthChecker *DaemonSetHealthChecker) Check(ctx context.Context, request types.NamespacedName) (*healthcheck.SingleCheckResult, error) { - daemonSet := &appsv1.DaemonSet{} - var err error - if healthChecker.checkType == daemonSetCheckTypeSeed { - err = healthChecker.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, daemonSet) - } else { - err = healthChecker.shootClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, daemonSet) - } - if err != nil { - if apierrors.IsNotFound(err) { - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("DaemonSet %q in namespace %q not found", healthChecker.name, request.Namespace), - }, nil - } - - err := fmt.Errorf("failed to retrieve DaemonSet %q in namespace %q: %w", healthChecker.name, request.Namespace, err) - healthChecker.logger.Error(err, "Health check failed") - return nil, err - } - if isHealthy, err := DaemonSetIsHealthy(daemonSet); !isHealthy { - healthChecker.logger.Error(err, "Health check failed") - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: err.Error(), - }, nil - } - - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionTrue, - }, nil -} - -// DaemonSetIsHealthy takes a daemon set resource and returns -// if it is healthy or not or an error -func DaemonSetIsHealthy(daemonSet *appsv1.DaemonSet) (bool, error) { - if err := health.CheckDaemonSet(daemonSet); err != nil { - err := fmt.Errorf("daemonSet %q in namespace %q is unhealthy: %w", daemonSet.Name, daemonSet.Namespace, err) - return false, err - } - return true, nil -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/deployment.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/deployment.go deleted file mode 100644 index c0d77ee4..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/deployment.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 general - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/gardener/gardener/extensions/pkg/controller/healthcheck" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - "github.com/gardener/gardener/pkg/utils/kubernetes/health" -) - -// DeploymentHealthChecker contains all the information for the Deployment HealthCheck -type DeploymentHealthChecker struct { - logger logr.Logger - seedClient client.Client - shootClient client.Client - name string - checkType DeploymentCheckType -} - -// DeploymentCheckType in which cluster the check will be executed -type DeploymentCheckType string - -const ( - deploymentCheckTypeSeed DeploymentCheckType = "Seed" - deploymentCheckTypeShoot DeploymentCheckType = "Shoot" -) - -// NewSeedDeploymentHealthChecker is a healthCheck function to check Deployments in the Seed cluster -func NewSeedDeploymentHealthChecker(deploymentName string) healthcheck.HealthCheck { - return &DeploymentHealthChecker{ - name: deploymentName, - checkType: deploymentCheckTypeSeed, - } -} - -// NewShootDeploymentHealthChecker is a healthCheck function to check Deployments in the Shoot cluster -func NewShootDeploymentHealthChecker(deploymentName string) healthcheck.HealthCheck { - return &DeploymentHealthChecker{ - name: deploymentName, - checkType: deploymentCheckTypeShoot, - } -} - -// InjectSeedClient injects the seed client -func (healthChecker *DeploymentHealthChecker) InjectSeedClient(seedClient client.Client) { - healthChecker.seedClient = seedClient -} - -// InjectShootClient injects the shoot client -func (healthChecker *DeploymentHealthChecker) InjectShootClient(shootClient client.Client) { - healthChecker.shootClient = shootClient -} - -// SetLoggerSuffix injects the logger -func (healthChecker *DeploymentHealthChecker) SetLoggerSuffix(provider, extension string) { - healthChecker.logger = log.Log.WithName(fmt.Sprintf("%s-%s-healthcheck-deployment", provider, extension)) -} - -// DeepCopy clones the healthCheck struct by making a copy and returning the pointer to that new copy -func (healthChecker *DeploymentHealthChecker) DeepCopy() healthcheck.HealthCheck { - copy := *healthChecker - return © -} - -// Check executes the health check -func (healthChecker *DeploymentHealthChecker) Check(ctx context.Context, request types.NamespacedName) (*healthcheck.SingleCheckResult, error) { - deployment := &appsv1.Deployment{} - - var err error - if healthChecker.checkType == deploymentCheckTypeSeed { - err = healthChecker.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, deployment) - } else { - err = healthChecker.shootClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, deployment) - } - if err != nil { - if apierrors.IsNotFound(err) { - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("deployment %q in namespace %q not found", healthChecker.name, request.Namespace), - }, nil - } - - err := fmt.Errorf("failed to retrieve deployment %q in namespace %q: %w", healthChecker.name, request.Namespace, err) - healthChecker.logger.Error(err, "Health check failed") - return nil, err - } - - if isHealthy, err := deploymentIsHealthy(deployment); !isHealthy { - healthChecker.logger.Error(err, "Health check failed") - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: err.Error(), - }, nil - } - - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionTrue, - }, nil -} - -func deploymentIsHealthy(deployment *appsv1.Deployment) (bool, error) { - if err := health.CheckDeployment(deployment); err != nil { - err := fmt.Errorf("deployment %q in namespace %q is unhealthy: %w", deployment.Name, deployment.Namespace, err) - return false, err - } - return true, nil -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/managed_resource.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/managed_resource.go deleted file mode 100644 index 79dfba80..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/managed_resource.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 general - -import ( - "context" - "fmt" - "regexp" - - "github.com/go-logr/logr" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/gardener/gardener/extensions/pkg/controller/healthcheck" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - resourcesv1alpha1 "github.com/gardener/gardener/pkg/apis/resources/v1alpha1" - "github.com/gardener/gardener/pkg/utils/kubernetes/health" -) - -// ManagedResourceHealthChecker contains all the information for the ManagedResource HealthCheck -type ManagedResourceHealthChecker struct { - logger logr.Logger - seedClient client.Client - managedResourceName string -} - -// CheckManagedResource is a healthCheck function to check ManagedResources -func CheckManagedResource(managedResourceName string) healthcheck.HealthCheck { - return &ManagedResourceHealthChecker{ - managedResourceName: managedResourceName, - } -} - -// InjectSeedClient injects the seed client -func (healthChecker *ManagedResourceHealthChecker) InjectSeedClient(seedClient client.Client) { - healthChecker.seedClient = seedClient -} - -// SetLoggerSuffix injects the logger -func (healthChecker *ManagedResourceHealthChecker) SetLoggerSuffix(provider, extension string) { - healthChecker.logger = log.Log.WithName(fmt.Sprintf("%s-%s-healthcheck-managed-resource", provider, extension)) -} - -// DeepCopy clones the healthCheck struct by making a copy and returning the pointer to that new copy -func (healthChecker *ManagedResourceHealthChecker) DeepCopy() healthcheck.HealthCheck { - copy := *healthChecker - return © -} - -// Check executes the health check -func (healthChecker *ManagedResourceHealthChecker) Check(ctx context.Context, request types.NamespacedName) (*healthcheck.SingleCheckResult, error) { - mcmDeployment := &resourcesv1alpha1.ManagedResource{} - - if err := healthChecker.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.managedResourceName}, mcmDeployment); err != nil { - if apierrors.IsNotFound(err) { - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("Managed Resource %q in namespace %q not found", healthChecker.managedResourceName, request.Namespace), - }, nil - } - - err := fmt.Errorf("check Managed Resource failed. Unable to retrieve managed resource %q in namespace %q: %w", healthChecker.managedResourceName, request.Namespace, err) - healthChecker.logger.Error(err, "Health check failed") - return nil, err - } - if isHealthy, err := managedResourceIsHealthy(mcmDeployment); !isHealthy { - healthChecker.logger.Error(err, "Health check failed") - - var ( - errorCodes []gardencorev1beta1.ErrorCode - configurationProblemRegexp = regexp.MustCompile(`(?i)(error during apply of object .* is invalid:)`) - ) - - if configurationProblemRegexp.MatchString(err.Error()) { - errorCodes = append(errorCodes, gardencorev1beta1.ErrorConfigurationProblem) - } - - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: err.Error(), - Codes: errorCodes, - }, nil - } - - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionTrue, - }, nil -} - -func managedResourceIsHealthy(managedResource *resourcesv1alpha1.ManagedResource) (bool, error) { - if err := health.CheckManagedResource(managedResource); err != nil { - err := fmt.Errorf("managed resource %q in namespace %q is unhealthy: %w", managedResource.Name, managedResource.Namespace, err) - return false, err - } - return true, nil -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/statefulsets.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/statefulsets.go deleted file mode 100644 index f0d92fc7..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general/statefulsets.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 general - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/gardener/gardener/extensions/pkg/controller/healthcheck" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - "github.com/gardener/gardener/pkg/utils/kubernetes/health" -) - -// StatefulSetHealthChecker contains all the information for the StatefulSet HealthCheck -type StatefulSetHealthChecker struct { - logger logr.Logger - seedClient client.Client - shootClient client.Client - name string - checkType StatefulSetCheckType -} - -// StatefulSetCheckType in which cluster the check will be executed -type StatefulSetCheckType string - -const ( - statefulSetCheckTypeSeed StatefulSetCheckType = "Seed" - statefulSetCheckTypeShoot StatefulSetCheckType = "Shoot" -) - -// NewSeedStatefulSetChecker is a healthCheck function to check StatefulSets -func NewSeedStatefulSetChecker(name string) healthcheck.HealthCheck { - return &StatefulSetHealthChecker{ - name: name, - checkType: statefulSetCheckTypeSeed, - } -} - -// NewShootStatefulSetChecker is a healthCheck function to check StatefulSets -func NewShootStatefulSetChecker(name string) healthcheck.HealthCheck { - return &StatefulSetHealthChecker{ - name: name, - checkType: statefulSetCheckTypeShoot, - } -} - -// InjectSeedClient injects the seed client -func (healthChecker *StatefulSetHealthChecker) InjectSeedClient(seedClient client.Client) { - healthChecker.seedClient = seedClient -} - -// InjectShootClient injects the shoot client -func (healthChecker *StatefulSetHealthChecker) InjectShootClient(shootClient client.Client) { - healthChecker.shootClient = shootClient -} - -// SetLoggerSuffix injects the logger -func (healthChecker *StatefulSetHealthChecker) SetLoggerSuffix(provider, extension string) { - healthChecker.logger = log.Log.WithName(fmt.Sprintf("%s-%s-healthcheck-deployment", provider, extension)) -} - -// DeepCopy clones the healthCheck struct by making a copy and returning the pointer to that new copy -func (healthChecker *StatefulSetHealthChecker) DeepCopy() healthcheck.HealthCheck { - copy := *healthChecker - return © -} - -// Check executes the health check -func (healthChecker *StatefulSetHealthChecker) Check(ctx context.Context, request types.NamespacedName) (*healthcheck.SingleCheckResult, error) { - statefulSet := &appsv1.StatefulSet{} - - var err error - if healthChecker.checkType == statefulSetCheckTypeSeed { - err = healthChecker.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, statefulSet) - } else { - err = healthChecker.shootClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: healthChecker.name}, statefulSet) - } - if err != nil { - if apierrors.IsNotFound(err) { - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("StatefulSet %q in namespace %q not found", healthChecker.name, request.Namespace), - }, nil - } - err := fmt.Errorf("failed to retrieve StatefulSet %q in namespace %q: %w", healthChecker.name, request.Namespace, err) - healthChecker.logger.Error(err, "Health check failed") - return nil, err - } - if isHealthy, err := statefulSetIsHealthy(statefulSet); !isHealthy { - healthChecker.logger.Error(err, "Health check failed") - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: err.Error(), - }, nil - } - - return &healthcheck.SingleCheckResult{ - Status: gardencorev1beta1.ConditionTrue, - }, nil -} - -func statefulSetIsHealthy(statefulSet *appsv1.StatefulSet) (bool, error) { - if err := health.CheckStatefulSet(statefulSet); err != nil { - err := fmt.Errorf("statefulSet %q in namespace %q is unhealthy: %w", statefulSet.Name, statefulSet.Namespace, err) - return false, err - } - return true, nil -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/healthcheck_actuator.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/healthcheck_actuator.go deleted file mode 100644 index b7229a30..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/healthcheck_actuator.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "context" - "fmt" - "strings" - "sync" - "time" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" - "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/client" - - extensionsconfig "github.com/gardener/gardener/extensions/pkg/apis/config" - extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" - "github.com/gardener/gardener/extensions/pkg/util" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" -) - -// Actuator contains all the health checks and the means to execute them -type Actuator struct { - restConfig *rest.Config - seedClient client.Client - scheme *runtime.Scheme - decoder runtime.Decoder - - provider string - extensionKind string - getExtensionObjFunc GetExtensionObjectFunc - healthChecks []ConditionTypeToHealthCheck - shootRESTOptions extensionsconfig.RESTOptions -} - -// NewActuator creates a new Actuator. -func NewActuator(provider, extensionKind string, getExtensionObjFunc GetExtensionObjectFunc, healthChecks []ConditionTypeToHealthCheck, shootRESTOptions extensionsconfig.RESTOptions) HealthCheckActuator { - return &Actuator{ - healthChecks: healthChecks, - getExtensionObjFunc: getExtensionObjFunc, - provider: provider, - extensionKind: extensionKind, - shootRESTOptions: shootRESTOptions, - } -} - -// InjectScheme injects the given runtime.Scheme into this Actuator. -func (a *Actuator) InjectScheme(scheme *runtime.Scheme) error { - a.scheme = scheme - a.decoder = serializer.NewCodecFactory(a.scheme).UniversalDecoder() - return nil -} - -// InjectClient injects the given client.Client into this Actuator. -func (a *Actuator) InjectClient(client client.Client) error { - a.seedClient = client - return nil -} - -// InjectConfig injects the given rest.Config into this Actuator. -func (a *Actuator) InjectConfig(config *rest.Config) error { - a.restConfig = config - return nil -} - -type healthCheckUnsuccessful struct { - detail string -} - -type healthCheckProgressing struct { - detail string - threshold *time.Duration -} - -type channelResult struct { - healthConditionType string - healthCheckResult *SingleCheckResult - error error -} - -type checkResultForConditionType struct { - failedChecks []error - unsuccessfulChecks []healthCheckUnsuccessful - progressingChecks []healthCheckProgressing - successfulChecks int - codes []gardencorev1beta1.ErrorCode -} - -// ExecuteHealthCheckFunctions executes all the health check functions, injects clients and logger & aggregates the results. -// returns an Result for each HealthConditionType (e.g ControlPlaneHealthy) -func (a *Actuator) ExecuteHealthCheckFunctions(ctx context.Context, log logr.Logger, request types.NamespacedName) (*[]Result, error) { - var ( - shootClient client.Client - channel = make(chan channelResult, len(a.healthChecks)) - wg sync.WaitGroup - ) - - for _, hc := range a.healthChecks { - // clone to avoid problems during parallel execution - check := hc.HealthCheck.DeepCopy() - SeedClientInto(a.seedClient, check) - if _, ok := check.(ShootClient); ok { - if shootClient == nil { - var err error - _, shootClient, err = util.NewClientForShoot(ctx, a.seedClient, request.Namespace, client.Options{}, a.shootRESTOptions) - if err != nil { - // don't return here, as we might have started some goroutines already to prevent leakage - channel <- channelResult{ - healthCheckResult: &SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("failed to create shoot client: %v", err), - }, - error: err, - healthConditionType: hc.ConditionType, - } - continue - } - } - ShootClientInto(shootClient, check) - } - - check.SetLoggerSuffix(a.provider, a.extensionKind) - - wg.Add(1) - go func(ctx context.Context, request types.NamespacedName, check HealthCheck, preCheckFunc PreCheckFunc, errorCodeCheckFunc ErrorCodeCheckFunc, healthConditionType string) { - defer wg.Done() - - if preCheckFunc != nil { - obj := a.getExtensionObjFunc() - if err := a.seedClient.Get(ctx, client.ObjectKey{Namespace: request.Namespace, Name: request.Name}, obj); err != nil { - channel <- channelResult{ - healthCheckResult: &SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("failed to read the extension resource: %v", err), - }, - error: err, - healthConditionType: healthConditionType, - } - return - } - - cluster, err := extensionscontroller.GetCluster(ctx, a.seedClient, request.Namespace) - if err != nil { - channel <- channelResult{ - healthCheckResult: &SingleCheckResult{ - Status: gardencorev1beta1.ConditionFalse, - Detail: fmt.Sprintf("failed to read the cluster resource: %v", err), - }, - error: err, - healthConditionType: healthConditionType, - } - return - } - - if !preCheckFunc(ctx, a.seedClient, obj, cluster) { - log.V(1).Info("Skipping health check as pre check function returned false", "conditionType", healthConditionType) - channel <- channelResult{ - healthCheckResult: &SingleCheckResult{ - Status: gardencorev1beta1.ConditionTrue, - }, - error: nil, - healthConditionType: healthConditionType, - } - return - } - } - - healthCheckResult, err := check.Check(ctx, request) - - if errorCodeCheckFunc != nil { - healthCheckResult.Codes = append(healthCheckResult.Codes, errorCodeCheckFunc(fmt.Errorf("%s", healthCheckResult.Detail))...) - } - - channel <- channelResult{ - healthCheckResult: healthCheckResult, - error: err, - healthConditionType: healthConditionType, - } - }(ctx, request, check, hc.PreCheckFunc, hc.ErrorCodeCheckFunc, hc.ConditionType) - } - - // close channel when wait group has 0 counter - go func() { - wg.Wait() - close(channel) - }() - - groupedHealthCheckResults := make(map[string]*checkResultForConditionType) - // loop runs until channel is closed - for channelResult := range channel { - if groupedHealthCheckResults[channelResult.healthConditionType] == nil { - groupedHealthCheckResults[channelResult.healthConditionType] = &checkResultForConditionType{} - } - if channelResult.error != nil { - groupedHealthCheckResults[channelResult.healthConditionType].failedChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].failedChecks, channelResult.error) - continue - } - if channelResult.healthCheckResult.Status == gardencorev1beta1.ConditionFalse { - groupedHealthCheckResults[channelResult.healthConditionType].unsuccessfulChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].unsuccessfulChecks, healthCheckUnsuccessful{detail: channelResult.healthCheckResult.Detail}) - groupedHealthCheckResults[channelResult.healthConditionType].codes = append(groupedHealthCheckResults[channelResult.healthConditionType].codes, channelResult.healthCheckResult.Codes...) - continue - } - if channelResult.healthCheckResult.Status == gardencorev1beta1.ConditionProgressing { - groupedHealthCheckResults[channelResult.healthConditionType].progressingChecks = append(groupedHealthCheckResults[channelResult.healthConditionType].progressingChecks, healthCheckProgressing{detail: channelResult.healthCheckResult.Detail, threshold: channelResult.healthCheckResult.ProgressingThreshold}) - groupedHealthCheckResults[channelResult.healthConditionType].codes = append(groupedHealthCheckResults[channelResult.healthConditionType].codes, channelResult.healthCheckResult.Codes...) - continue - } - groupedHealthCheckResults[channelResult.healthConditionType].successfulChecks++ - } - - var checkResults []Result - for conditionType, result := range groupedHealthCheckResults { - if len(result.unsuccessfulChecks) > 0 || len(result.failedChecks) > 0 { - var details strings.Builder - result.appendFailedChecksDetails(&details) - result.appendUnsuccessfulChecksDetails(&details) - result.appendProgressingChecksDetails(&details) - - checkResults = append(checkResults, Result{ - HealthConditionType: conditionType, - Status: gardencorev1beta1.ConditionFalse, - Detail: pointer.String(trimTrailingWhitespace(details.String())), - SuccessfulChecks: result.successfulChecks, - UnsuccessfulChecks: len(result.unsuccessfulChecks), - FailedChecks: len(result.failedChecks), - Codes: result.codes, - }) - continue - } - - if len(result.progressingChecks) > 0 { - var ( - details strings.Builder - threshold *time.Duration - ) - - for index, check := range result.progressingChecks { - if len(result.progressingChecks) == 1 { - details.WriteString(ensureTrailingDot(check.detail)) - } else { - details.WriteString(fmt.Sprintf("%d) %s ", index+1, ensureTrailingDot(check.detail))) - } - - if check.threshold != nil && (threshold == nil || *threshold > *check.threshold) { - threshold = check.threshold - } - } - - checkResults = append(checkResults, Result{ - HealthConditionType: conditionType, - Status: gardencorev1beta1.ConditionProgressing, - ProgressingThreshold: threshold, - Detail: pointer.String(trimTrailingWhitespace(details.String())), - SuccessfulChecks: result.successfulChecks, - ProgressingChecks: len(result.progressingChecks), - Codes: result.codes, - }) - continue - } - - checkResults = append(checkResults, Result{ - HealthConditionType: conditionType, - Status: gardencorev1beta1.ConditionTrue, - SuccessfulChecks: result.successfulChecks, - }) - } - - return &checkResults, nil -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/inject.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/inject.go deleted file mode 100644 index a81fc6ff..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/inject.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// ShootClient is an interface to be used to receive a shoot client. -type ShootClient interface { - // InjectShootClient injects the shoot client - InjectShootClient(client.Client) -} - -// SeedClient is an interface to be used to receive a seed client. -type SeedClient interface { - // InjectSeedClient injects the seed client - InjectSeedClient(client.Client) -} - -// ShootClientInto will set the shoot client on i if i implements ShootClient. -func ShootClientInto(client client.Client, i interface{}) bool { - if s, ok := i.(ShootClient); ok { - s.InjectShootClient(client) - return true - } - return false -} - -// SeedClientInto will set the seed client on i if i implements SeedClient. -func SeedClientInto(client client.Client, i interface{}) bool { - if s, ok := i.(SeedClient); ok { - s.InjectSeedClient(client) - return true - } - return false -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/message_util.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/message_util.go deleted file mode 100644 index f1b6dfa4..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/message_util.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "fmt" - "strings" -) - -// getUnsuccessfulDetailMessage returns a message depending on the number of -// unsuccessful and pending checks -func getUnsuccessfulDetailMessage(unsuccessfulChecks, progressingChecks int, details string) string { - if progressingChecks > 0 && unsuccessfulChecks > 0 { - return fmt.Sprintf("%d failing and %d progressing %s: %s", unsuccessfulChecks, progressingChecks, getSingularOrPlural("check", progressingChecks), details) - } - - return details -} - -// getSingularOrPlural returns the given verb in either singular or plural -func getSingularOrPlural(verb string, count int) string { - if count > 1 { - return fmt.Sprintf("%ss", verb) - } - return verb -} - -// appendUnsuccessfulChecksDetails appends a formatted detail message to the given string builder -func (h *checkResultForConditionType) appendUnsuccessfulChecksDetails(details *strings.Builder) { - if len(h.unsuccessfulChecks) > 0 && (len(h.progressingChecks) != 0 || len(h.failedChecks) != 0) { - details.WriteString(fmt.Sprintf("Failed %s: ", getSingularOrPlural("check", len(h.unsuccessfulChecks)))) - } - - if len(h.unsuccessfulChecks) == 1 { - details.WriteString(fmt.Sprintf("%s ", ensureTrailingDot(h.unsuccessfulChecks[0].detail))) - return - } - - for index, check := range h.unsuccessfulChecks { - details.WriteString(fmt.Sprintf("%d) %s ", index+1, ensureTrailingDot(check.detail))) - } -} - -// appendProgressingChecksDetails appends a formatted detail message to the given string builder -func (h *checkResultForConditionType) appendProgressingChecksDetails(details *strings.Builder) { - if len(h.progressingChecks) > 0 && (len(h.unsuccessfulChecks) != 0 || len(h.failedChecks) != 0) { - details.WriteString(fmt.Sprintf("Progressing %s: ", getSingularOrPlural("check", len(h.progressingChecks)))) - } - - if len(h.progressingChecks) == 1 { - details.WriteString(fmt.Sprintf("%s ", ensureTrailingDot(h.progressingChecks[0].detail))) - return - } - - for index, check := range h.progressingChecks { - details.WriteString(fmt.Sprintf("%d) %s ", index+1, ensureTrailingDot(check.detail))) - } -} - -// appendFailedChecksDetails appends a formatted detail message to the given string builder -func (h *checkResultForConditionType) appendFailedChecksDetails(details *strings.Builder) { - if len(h.failedChecks) > 0 && (len(h.unsuccessfulChecks) != 0 || len(h.progressingChecks) != 0) { - details.WriteString(fmt.Sprintf("Unable to execute %s: ", getSingularOrPlural("check", len(h.failedChecks)))) - } - - if len(h.failedChecks) == 1 { - details.WriteString(fmt.Sprintf("%s ", ensureTrailingDot(h.failedChecks[0].Error()))) - return - } - - for index, check := range h.failedChecks { - details.WriteString(fmt.Sprintf("%d) %s ", index+1, ensureTrailingDot(check.Error()))) - } -} - -// ensureTrailingDot adds a trailing dot if it does not exist -func ensureTrailingDot(details string) string { - if !strings.HasSuffix(details, ".") { - return fmt.Sprintf("%s.", details) - } - return details -} - -// trimTrailingWhitespace removes a trailing whitespace character -func trimTrailingWhitespace(details string) string { - return strings.TrimSuffix(details, " ") -} diff --git a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/reconciler.go b/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/reconciler.go deleted file mode 100644 index 3efa580e..00000000 --- a/vendor/github.com/gardener/gardener/extensions/pkg/controller/healthcheck/reconciler.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 healthcheck - -import ( - "context" - "fmt" - "time" - - "github.com/go-logr/logr" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/clock" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" - - extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" - "github.com/gardener/gardener/pkg/api/extensions" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants" - v1beta1helper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper" - extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" -) - -type reconciler struct { - client client.Client - - actuator HealthCheckActuator - registeredExtension RegisteredExtension - syncPeriod metav1.Duration -} - -const ( - // ReasonUnsuccessful is the reason phrase for the health check condition if one or more of its tests failed. - ReasonUnsuccessful = "HealthCheckUnsuccessful" - // ReasonProgressing is the reason phrase for the health check condition if one or more of its tests are progressing. - ReasonProgressing = "HealthCheckProgressing" - // ReasonSuccessful is the reason phrase for the health check condition if all tests are successful. - ReasonSuccessful = "HealthCheckSuccessful" -) - -// NewReconciler creates a new performHealthCheck.Reconciler that reconciles -// the registered extension resources (Gardener's `extensions.gardener.cloud` API group). -func NewReconciler(actuator HealthCheckActuator, registeredExtension RegisteredExtension, syncPeriod metav1.Duration) reconcile.Reconciler { - return &reconciler{ - actuator: actuator, - registeredExtension: registeredExtension, - syncPeriod: syncPeriod, - } -} - -func (r *reconciler) InjectFunc(f inject.Func) error { - return f(r.actuator) -} - -func (r *reconciler) InjectClient(client client.Client) error { - r.client = client - return nil -} - -func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - log := logf.FromContext(ctx) - - // overall timeout for all calls in this reconciler (including status updates); - // this gives status updates a bit of headroom if the actual health checks run into timeouts, - // so that we will still update the condition to the failed status - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, 2*r.syncPeriod.Duration) - defer cancel() - - extension := r.registeredExtension.getExtensionObjFunc() - if err := r.client.Get(ctx, request.NamespacedName, extension); err != nil { - if apierrors.IsNotFound(err) { - log.V(1).Info("Object was not found, requeueing") - return r.resultWithRequeue(), nil - } - return reconcile.Result{}, fmt.Errorf("error retrieving object from store: %w", err) - } - - acc, err := extensions.Accessor(extension.DeepCopyObject()) - if err != nil { - return reconcile.Result{}, err - } - - if acc.GetDeletionTimestamp() != nil { - log.V(1).Info("Do not perform HealthCheck for extension resource, extension is being deleted") - return reconcile.Result{}, nil - } - - if isInMigration(acc) { - log.Info("Do not perform HealthCheck for extension resource, extension is being migrated") - return reconcile.Result{}, nil - } - - cluster, err := extensionscontroller.GetCluster(ctx, r.client, acc.GetNamespace()) - if err != nil { - return reconcile.Result{}, err - } - - if extensionscontroller.IsHibernationEnabled(cluster) { - var conditions []condition - for _, healthConditionType := range r.registeredExtension.healthConditionTypes { - conditionBuilder, err := v1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthConditionType)) - if err != nil { - return reconcile.Result{}, err - } - - conditions = append(conditions, extensionConditionHibernated(conditionBuilder, healthConditionType)) - } - if err := r.updateExtensionConditions(ctx, extension, conditions...); err != nil { - return reconcile.Result{}, err - } - - log.V(1).Info("Do not perform HealthCheck for extension resource, Shoot is hibernated", "groupVersionKind", r.registeredExtension.groupVersionKind) - return reconcile.Result{}, nil - } - - log.V(1).Info("Performing healthcheck", "groupVersionKind", r.registeredExtension.groupVersionKind) - return r.performHealthCheck(ctx, log, request, extension) -} - -func (r *reconciler) performHealthCheck(ctx context.Context, log logr.Logger, request reconcile.Request, extension extensionsv1alpha1.Object) (reconcile.Result, error) { - // use a dedicated context for the actual health checks so that we can still update the conditions in case of timeouts - healthCheckCtx, cancel := context.WithTimeout(ctx, r.syncPeriod.Duration) - defer cancel() - - healthCheckResults, err := r.actuator.ExecuteHealthCheckFunctions(healthCheckCtx, log, types.NamespacedName{Namespace: request.Namespace, Name: request.Name}) - if err != nil { - var conditions []condition - log.Error(err, "Failed to execute healthChecks, updating each HealthCheckCondition for the extension resource to ConditionCheckError", "kind", r.registeredExtension.groupVersionKind.Kind, "conditionTypes", r.registeredExtension.healthConditionTypes) - for _, healthConditionType := range r.registeredExtension.healthConditionTypes { - conditionBuilder, buildErr := v1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthConditionType)) - if buildErr != nil { - return reconcile.Result{}, buildErr - } - - conditions = append(conditions, extensionConditionFailedToExecute(conditionBuilder, healthConditionType, err)) - } - if updateErr := r.updateExtensionConditions(ctx, extension, conditions...); updateErr != nil { - return reconcile.Result{}, updateErr - } - return r.resultWithRequeue(), nil - } - - conditions := make([]condition, 0, len(*healthCheckResults)) - for _, healthCheckResult := range *healthCheckResults { - conditionBuilder, err := v1beta1helper.NewConditionBuilder(gardencorev1beta1.ConditionType(healthCheckResult.HealthConditionType)) - if err != nil { - return reconcile.Result{}, err - } - - var logger logr.Logger - if healthCheckResult.Status == gardencorev1beta1.ConditionTrue || healthCheckResult.Status == gardencorev1beta1.ConditionProgressing { - logger = log.V(1) - } else { - logger = log - } - - if healthCheckResult.Status == gardencorev1beta1.ConditionTrue { - logger.Info("Health check for extension resource successful", "kind", r.registeredExtension.groupVersionKind.Kind, "conditionType", healthCheckResult.HealthConditionType) - conditions = append(conditions, extensionConditionSuccessful(conditionBuilder, healthCheckResult.HealthConditionType, healthCheckResult)) - continue - } - - if healthCheckResult.FailedChecks > 0 { - logger.Info("Updating HealthCheckCondition for extension resource to ConditionCheckError", "kind", r.registeredExtension.groupVersionKind.Kind, "conditionType", healthCheckResult.HealthConditionType) - conditions = append(conditions, extensionConditionCheckError(conditionBuilder, healthCheckResult.HealthConditionType, healthCheckResult)) - continue - } - - logger.Info("Health check for extension resource progressing or unsuccessful", "kind", fmt.Sprintf("%s.%s.%s", r.registeredExtension.groupVersionKind.Kind, r.registeredExtension.groupVersionKind.Group, r.registeredExtension.groupVersionKind.Version), "failed", healthCheckResult.FailedChecks, "progressing", healthCheckResult.ProgressingChecks, "successful", healthCheckResult.SuccessfulChecks, "details", healthCheckResult.GetDetails()) - conditions = append(conditions, extensionConditionUnsuccessful(conditionBuilder, healthCheckResult.HealthConditionType, extension, healthCheckResult)) - } - - if err := r.updateExtensionConditions(ctx, extension, conditions...); err != nil { - return reconcile.Result{}, err - } - - return r.resultWithRequeue(), nil -} - -func extensionConditionFailedToExecute(conditionBuilder v1beta1helper.ConditionBuilder, healthConditionType string, executionError error) condition { - conditionBuilder. - WithStatus(gardencorev1beta1.ConditionUnknown). - WithReason(gardencorev1beta1.ConditionCheckError). - WithMessage(fmt.Sprintf("unable to execute any health check: %v", executionError.Error())) - return condition{ - builder: conditionBuilder, - healthConditionType: healthConditionType, - } -} - -func extensionConditionCheckError(conditionBuilder v1beta1helper.ConditionBuilder, healthConditionType string, healthCheckResult Result) condition { - conditionBuilder. - WithStatus(gardencorev1beta1.ConditionUnknown). - WithReason(gardencorev1beta1.ConditionCheckError). - WithMessage(fmt.Sprintf("failed to execute %d health %s: %v", healthCheckResult.FailedChecks, getSingularOrPlural("check", healthCheckResult.FailedChecks), healthCheckResult.GetDetails())) - return condition{ - builder: conditionBuilder, - healthConditionType: healthConditionType, - } -} - -func extensionConditionUnsuccessful(conditionBuilder v1beta1helper.ConditionBuilder, healthConditionType string, extension extensionsv1alpha1.Object, healthCheckResult Result) condition { - var ( - detail = getUnsuccessfulDetailMessage(healthCheckResult.UnsuccessfulChecks, healthCheckResult.ProgressingChecks, healthCheckResult.GetDetails()) - status = gardencorev1beta1.ConditionFalse - reason = ReasonUnsuccessful - ) - - if healthCheckResult.ProgressingChecks > 0 && healthCheckResult.ProgressingThreshold != nil { - if oldCondition := v1beta1helper.GetCondition(extension.GetExtensionStatus().GetConditions(), gardencorev1beta1.ConditionType(healthConditionType)); oldCondition == nil { - status = gardencorev1beta1.ConditionProgressing - reason = ReasonProgressing - } else if oldCondition.Status != gardencorev1beta1.ConditionFalse { - delta := time.Now().UTC().Sub(oldCondition.LastTransitionTime.Time.UTC()) - if oldCondition.Status == gardencorev1beta1.ConditionTrue || delta <= *healthCheckResult.ProgressingThreshold { - status = gardencorev1beta1.ConditionProgressing - reason = ReasonProgressing - } - } - } - - conditionBuilder. - WithStatus(status). - WithReason(reason). - WithCodes(healthCheckResult.Codes...). - WithMessage(detail) - return condition{ - builder: conditionBuilder, - healthConditionType: healthConditionType, - } -} - -func extensionConditionSuccessful(conditionBuilder v1beta1helper.ConditionBuilder, healthConditionType string, healthCheckResult Result) condition { - conditionBuilder. - WithStatus(gardencorev1beta1.ConditionTrue). - WithReason(ReasonSuccessful). - WithMessage("All health checks successful") - return condition{ - builder: conditionBuilder, - healthConditionType: healthConditionType, - } -} - -func extensionConditionHibernated(conditionBuilder v1beta1helper.ConditionBuilder, healthConditionType string) condition { - conditionBuilder. - WithStatus(gardencorev1beta1.ConditionTrue). - WithReason(ReasonSuccessful). - WithMessage("Shoot is hibernated") - return condition{ - builder: conditionBuilder, - healthConditionType: healthConditionType, - } -} - -type condition struct { - builder v1beta1helper.ConditionBuilder - healthConditionType string -} - -func (r *reconciler) updateExtensionConditions(ctx context.Context, extension extensionsv1alpha1.Object, conditions ...condition) error { - for _, cond := range conditions { - if c := v1beta1helper.GetCondition(extension.GetExtensionStatus().GetConditions(), gardencorev1beta1.ConditionType(cond.healthConditionType)); c != nil { - cond.builder.WithOldCondition(*c) - } - updatedCondition, _ := cond.builder.WithClock(clock.RealClock{}).Build() - extension.GetExtensionStatus().SetConditions(v1beta1helper.MergeConditions(extension.GetExtensionStatus().GetConditions(), updatedCondition)) - } - return r.client.Status().Update(ctx, extension) -} - -func (r *reconciler) resultWithRequeue() reconcile.Result { - return reconcile.Result{RequeueAfter: r.syncPeriod.Duration} -} - -func isInMigration(accessor extensionsv1alpha1.Object) bool { - annotations := accessor.GetAnnotations() - if annotations != nil && - annotations[v1beta1constants.GardenerOperation] == v1beta1constants.GardenerOperationMigrate { - return true - } - - status := accessor.GetExtensionStatus() - if status == nil { - return false - } - - lastOperation := status.GetLastOperation() - return lastOperation != nil && lastOperation.Type == gardencorev1beta1.LastOperationTypeMigrate -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 21724f17..cdd989b1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -59,8 +59,6 @@ github.com/gardener/gardener/extensions/pkg/apis/config/v1alpha1 github.com/gardener/gardener/extensions/pkg/controller github.com/gardener/gardener/extensions/pkg/controller/cmd github.com/gardener/gardener/extensions/pkg/controller/extension -github.com/gardener/gardener/extensions/pkg/controller/healthcheck -github.com/gardener/gardener/extensions/pkg/controller/healthcheck/general github.com/gardener/gardener/extensions/pkg/controller/heartbeat github.com/gardener/gardener/extensions/pkg/controller/heartbeat/cmd github.com/gardener/gardener/extensions/pkg/predicate