diff --git a/go.mod b/go.mod index 8419311d51..695cf299b6 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( k8s.io/api v0.25.9 k8s.io/apiextensions-apiserver v0.25.9 k8s.io/apimachinery v0.25.9 + k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0 k8s.io/cli-runtime v0.25.9 k8s.io/client-go v0.25.9 k8s.io/cluster-registry v0.0.6 diff --git a/go.sum b/go.sum index dd994bb0b8..9c716a707b 100644 --- a/go.sum +++ b/go.sum @@ -674,6 +674,8 @@ k8s.io/apimachinery v0.25.9 h1:MPjgTz4dbAKJ/KiHIvDeYkFfIn7ueihqvT520HkV7v4= k8s.io/apimachinery v0.25.9/go.mod h1:ZTl0drTQaFi5gMM3snYI5tWV1XJmRH1gfnDx2QCLsxk= k8s.io/apiserver v0.25.9 h1:1tuxeA28SnoK30bhOa48c6tOCQypcJJYlsGE8BJpUko= k8s.io/apiserver v0.25.9/go.mod h1:FHU743u4KKL79IpiQU/d8MiwA+JdHX26vfhG7gBJSYo= +k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0 h1:pH6AsxeBZcyX6KBqcnl7SPIJqbN1d59RrEBuIE6Rq6c= +k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0/go.mod h1:LraL5kR2xX7jb4VMCG6/tUH4I75uRHlnzC0VWQHcyWk= k8s.io/cli-runtime v0.25.9 h1:XNJ82pj8ior9TqO22OGQ0Di6e1p/wXm7IJyqM8iq8I4= k8s.io/cli-runtime v0.25.9/go.mod h1:Xl7L+X3Uxb8J9rfzICvIi9EP4CYYXXtMdaWSsdcFRHo= k8s.io/client-go v0.25.9 h1:U0S3nc71NRfHXiA0utyCkPt3Mv1SWpQw0g5VfBCv5xg= diff --git a/pkg/core/scheme.go b/pkg/core/scheme.go index b0dd98388e..1f8f6fca65 100644 --- a/pkg/core/scheme.go +++ b/pkg/core/scheme.go @@ -26,6 +26,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + autoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1" "k8s.io/client-go/kubernetes/scheme" clusterregistry "k8s.io/cluster-registry/pkg/apis/clusterregistry/v1alpha1" k8sadmissionv1 "k8s.io/kubernetes/pkg/apis/admission/v1" @@ -107,6 +108,9 @@ func mustRegisterKubernetesResources() { utilruntime.Must(k8srbacv1beta1.RegisterConversions(scheme.Scheme)) utilruntime.Must(scheme.Scheme.SetVersionPriority(rbacv1.SchemeGroupVersion, rbacv1beta1.SchemeGroupVersion)) + + utilruntime.Must(autoscalingv1.AddToScheme(scheme.Scheme)) + // autoscaling API has no generated defaults or conversions } func mustRegisterAPIExtensionsResources() { diff --git a/pkg/kinds/kinds.go b/pkg/kinds/kinds.go index ebaf3026c5..7b6937cd58 100644 --- a/pkg/kinds/kinds.go +++ b/pkg/kinds/kinds.go @@ -26,6 +26,7 @@ import ( rbacv1beta1 "k8s.io/api/rbac/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" + autoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1" "kpt.dev/configsync/pkg/api/configmanagement" v1 "kpt.dev/configsync/pkg/api/configmanagement/v1" "kpt.dev/configsync/pkg/api/configsync" @@ -263,3 +264,8 @@ func APIService() schema.GroupVersionKind { func ValidatingWebhookConfiguration() schema.GroupVersionKind { return admissionv1.SchemeGroupVersion.WithKind("ValidatingWebhookConfiguration") } + +// VerticalPodAutoscaler returns the VerticalPodAutoscaler kind. +func VerticalPodAutoscaler() schema.GroupVersionKind { + return autoscalingv1.SchemeGroupVersion.WithKind("VerticalPodAutoscaler") +} diff --git a/pkg/reconcilermanager/controllers/garbage_collector.go b/pkg/reconcilermanager/controllers/garbage_collector.go index cf1a0b7e60..20e09fd8f0 100644 --- a/pkg/reconcilermanager/controllers/garbage_collector.go +++ b/pkg/reconcilermanager/controllers/garbage_collector.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" + autoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1" "kpt.dev/configsync/pkg/core" "kpt.dev/configsync/pkg/kinds" "kpt.dev/configsync/pkg/reconcilermanager" @@ -204,3 +205,10 @@ func (r *RootSyncReconciler) deleteClusterRoleBinding(ctx context.Context, recon } return nil } + +func (r *reconcilerBase) deleteVerticalPodAutoscaler(ctx context.Context, reconcilerRef types.NamespacedName) error { + vpa := &autoscalingv1.VerticalPodAutoscaler{} + vpa.Name = reconcilerRef.Name + vpa.Namespace = reconcilerRef.Namespace + return r.cleanup(ctx, vpa) +} diff --git a/pkg/reconcilermanager/controllers/reconciler_base.go b/pkg/reconcilermanager/controllers/reconciler_base.go index 31a8c6c435..1336dbcfdf 100644 --- a/pkg/reconcilermanager/controllers/reconciler_base.go +++ b/pkg/reconcilermanager/controllers/reconciler_base.go @@ -23,15 +23,19 @@ import ( "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" + autoscaling "k8s.io/api/autoscaling/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + autoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1" "k8s.io/client-go/dynamic" + "k8s.io/utils/pointer" "kpt.dev/configsync/pkg/api/configsync" "kpt.dev/configsync/pkg/api/configsync/v1beta1" hubv1 "kpt.dev/configsync/pkg/api/hub/v1" @@ -74,9 +78,9 @@ const ( logFieldResourceVersion = "resourceVersion" ) -// The fields in reconcilerManagerAllowList are the fields that reconciler manager allow -// users or other controllers to modify. -var reconcilerManagerAllowList = []string{ +// The fields in reconcilerDriftAllowList are the fields that reconciler manager +// allows users or other controllers to modify on the reconciler Deployment. +var reconcilerDriftAllowList = []string{ "$.spec.template.spec.containers[*].terminationMessagePath", "$.spec.template.spec.containers[*].terminationMessagePolicy", "$.spec.template.spec.containers[*].*.timeoutSeconds", @@ -93,6 +97,10 @@ var reconcilerManagerAllowList = []string{ "$.spec.progressDeadlineSeconds", } +// reconcilerContainerResourceField is the JSONPath to the resources field, +// which is optionally allowed to drift on the reconciler Deployment. +const reconcilerContainerResourceField = "$.spec.template.spec.containers[*].resources" + // reconcilerBase provides common data and methods for the RepoSync and RootSync reconcilers type reconcilerBase struct { loggingController @@ -102,7 +110,7 @@ type reconcilerBase struct { watcher client.WithWatch // non-caching dynamicClient dynamic.Interface scheme *runtime.Scheme - isAutopilotCluster *bool + autopilot *bool reconcilerPollingPeriod time.Duration hydrationPollingPeriod time.Duration membership *hubv1.Membership @@ -158,7 +166,7 @@ func (r *reconcilerBase) upsertServiceAccount( type mutateFn func(client.Object) error -func (r *reconcilerBase) upsertDeployment(ctx context.Context, reconcilerRef types.NamespacedName, labelMap map[string]string, mutateObject mutateFn) (*unstructured.Unstructured, controllerutil.OperationResult, error) { +func (r *reconcilerBase) upsertDeployment(ctx context.Context, reconcilerRef types.NamespacedName, labelMap map[string]string, mutateObject mutateFn, ignoredFields []string) (*unstructured.Unstructured, controllerutil.OperationResult, error) { reconcilerDeployment := &appsv1.Deployment{} if err := parseDeployment(reconcilerDeployment); err != nil { return nil, controllerutil.OperationResultNone, errors.Wrap(err, "failed to parse reconciler Deployment manifest from ConfigMap") @@ -190,7 +198,7 @@ func (r *reconcilerBase) upsertDeployment(ctx context.Context, reconcilerRef typ if err := mutateObject(reconcilerDeployment); err != nil { return nil, controllerutil.OperationResultNone, err } - appliedObj, op, err := r.createOrPatchDeployment(ctx, reconcilerDeployment) + appliedObj, op, err := r.createOrPatchDeployment(ctx, reconcilerDeployment, ignoredFields) if op != controllerutil.OperationResultNone { r.logger(ctx).Info("Managed object upsert successful", @@ -204,7 +212,7 @@ func (r *reconcilerBase) upsertDeployment(ctx context.Context, reconcilerRef typ // createOrPatchDeployment() first call Get() on the object. If the // object does not exist, Create() will be called. If it does exist, Patch() // will be called. -func (r *reconcilerBase) createOrPatchDeployment(ctx context.Context, declared *appsv1.Deployment) (*unstructured.Unstructured, controllerutil.OperationResult, error) { +func (r *reconcilerBase) createOrPatchDeployment(ctx context.Context, declared *appsv1.Deployment, ignoredFields []string) (*unstructured.Unstructured, controllerutil.OperationResult, error) { id := core.ID{ ObjectKey: client.ObjectKeyFromObject(declared), GroupKind: kinds.Deployment().GroupKind(), @@ -232,14 +240,7 @@ func (r *reconcilerBase) createOrPatchDeployment(ctx context.Context, declared * currentGeneration := currentDeploymentUnstructured.GetGeneration() currentUID := currentDeploymentUnstructured.GetUID() - if r.isAutopilotCluster == nil { - isAutopilot, err := util.IsGKEAutopilotCluster(r.client) - if err != nil { - return nil, controllerutil.OperationResultNone, fmt.Errorf("unable to determine if it is an Autopilot cluster: %w", err) - } - r.isAutopilotCluster = &isAutopilot - } - dep, err := compareDeploymentsToCreatePatchData(*r.isAutopilotCluster, declared, currentDeploymentUnstructured, reconcilerManagerAllowList, r.scheme) + dep, err := r.compareDeploymentsToCreatePatchData(declared, currentDeploymentUnstructured, ignoredFields) if err != nil { return nil, controllerutil.OperationResultNone, err } @@ -285,6 +286,29 @@ func (r *reconcilerBase) createOrPatchDeployment(ctx context.Context, declared * return appliedObj, controllerutil.OperationResultUpdated, nil } +func (r *reconcilerBase) reconcilerFieldsAllowedToDrift(override *v1beta1.OverrideSpec) ([]string, error) { + vpaEnabled, err := r.isVPAEnabled(override) + if err != nil { + return nil, err + } + if !vpaEnabled { + return reconcilerDriftAllowList, nil + } + return append([]string{reconcilerContainerResourceField}, reconcilerDriftAllowList...), nil +} + +func (r *reconcilerBase) isAutopilot() (bool, error) { + if r.autopilot != nil { + return *r.autopilot, nil + } + autopilot, err := util.IsGKEAutopilotCluster(r.client) + if err != nil { + return false, fmt.Errorf("unable to determine if it is an Autopilot cluster: %w", err) + } + r.autopilot = &autopilot + return autopilot, nil +} + // deleteDeploymentFields delete all the fields in allowlist from unstructured object and convert the unstructured object to Deployment object func deleteDeploymentFields(allowList []string, unstructuredDeployment *unstructured.Unstructured) (*appsv1.Deployment, error) { for _, path := range allowList { @@ -306,30 +330,33 @@ type deploymentProcessResult struct { } // compareDeploymentsToCreatePatchData checks if current deployment is same with declared deployment when ignore the fields in allowlist. If not, it creates a byte array used for PATCH later -func compareDeploymentsToCreatePatchData(isAutopilot bool, declared *appsv1.Deployment, currentDeploymentUnstructured *unstructured.Unstructured, allowList []string, scheme *runtime.Scheme) (*deploymentProcessResult, error) { - processedCurrent, err := deleteDeploymentFields(allowList, currentDeploymentUnstructured) +func (r *reconcilerBase) compareDeploymentsToCreatePatchData(declared *appsv1.Deployment, currentDeploymentUnstructured *unstructured.Unstructured, ignoredFields []string) (*deploymentProcessResult, error) { + isAutopilot, err := r.isAutopilot() if err != nil { - return &deploymentProcessResult{}, err + return nil, err + } + processedCurrent, err := deleteDeploymentFields(ignoredFields, currentDeploymentUnstructured) + if err != nil { + return nil, err } adjusted, err := adjustContainerResources(isAutopilot, declared, processedCurrent) if err != nil { - return &deploymentProcessResult{}, err + return nil, err } - - unObjDeclared, err := kinds.ToUnstructured(declared, scheme) + unObjDeclared, err := kinds.ToUnstructured(declared, r.scheme) if err != nil { - return &deploymentProcessResult{}, err + return nil, err } - processedDeclared, err := deleteDeploymentFields(allowList, unObjDeclared) + processedDeclared, err := deleteDeploymentFields(ignoredFields, unObjDeclared) if err != nil { - return &deploymentProcessResult{}, err + return nil, err } if equality.Semantic.DeepEqual(processedCurrent.Labels, processedDeclared.Labels) && equality.Semantic.DeepEqual(processedCurrent.Spec, processedDeclared.Spec) { return &deploymentProcessResult{true, adjusted, nil}, nil } data, err := json.Marshal(unObjDeclared) if err != nil { - return &deploymentProcessResult{}, err + return nil, err } return &deploymentProcessResult{false, adjusted, data}, nil } @@ -613,3 +640,52 @@ func (r *reconcilerBase) setupOrTeardown(ctx context.Context, syncObj client.Obj return nil } + +func (r *reconcilerBase) upsertVerticalPodAutoscaler(ctx context.Context, deployID core.ID, labelMap map[string]string) (client.ObjectKey, error) { + vpaRef := deployID.ObjectKey + vpa := &autoscalingv1.VerticalPodAutoscaler{} + vpa.Name = vpaRef.Name + vpa.Namespace = vpaRef.Namespace + op, err := CreateOrUpdate(ctx, r.client, vpa, func() error { + r.addLabels(vpa, labelMap) + vpa.Spec.TargetRef = &autoscaling.CrossVersionObjectReference{ + // TODO: APIVersion is optional but is it useful? + Kind: deployID.Kind, + Name: deployID.Name, + } + updateMode := autoscalingv1.UpdateModeAuto + vpa.Spec.UpdatePolicy = &autoscalingv1.PodUpdatePolicy{ + UpdateMode: &updateMode, + // VPA is allowed to evict the last reconciler pod, + // because there's only one replica. + MinReplicas: pointer.Int32(0), + } + return nil + }) + if err != nil { + return vpaRef, err + } + if op != controllerutil.OperationResultNone { + r.logger(ctx).Info("Managed object upsert successful", + logFieldObjectRef, vpaRef.String(), + logFieldObjectKind, "VerticalPodAutoscaler", + logFieldOperation, op) + } + return vpaRef, nil +} + +func (r *reconcilerBase) isVPAEnabled(override *v1beta1.OverrideSpec) (bool, error) { + if override != nil && len(override.Resources) > 0 { + // Don't use VPA if resource overrides are specified by the user + return false, nil + } + vpaGVK := kinds.VerticalPodAutoscaler() + _, err := r.client.RESTMapper().RESTMapping(vpaGVK.GroupKind(), vpaGVK.Version) + if err != nil { + if errors.Is(err, &meta.NoKindMatchError{}) { + return false, nil + } + return false, err + } + return true, nil +} diff --git a/pkg/reconcilermanager/controllers/reconciler_base_test.go b/pkg/reconcilermanager/controllers/reconciler_base_test.go index 0753f32ed3..f046e68af6 100644 --- a/pkg/reconcilermanager/controllers/reconciler_base_test.go +++ b/pkg/reconcilermanager/controllers/reconciler_base_test.go @@ -15,6 +15,7 @@ package controllers import ( + "context" "encoding/json" "fmt" "testing" @@ -30,6 +31,7 @@ import ( "kpt.dev/configsync/pkg/kinds" "kpt.dev/configsync/pkg/metadata" "kpt.dev/configsync/pkg/reconcilermanager" + syncerFake "kpt.dev/configsync/pkg/syncer/syncertest/fake" "kpt.dev/configsync/pkg/testing/fake" "kpt.dev/configsync/pkg/util" "sigs.k8s.io/controller-runtime/pkg/client" @@ -608,7 +610,16 @@ func TestCompareDeploymentsToCreatePatchData(t *testing.T) { } else { testCurrent = tc.current.DeepCopy() } - dep, err := compareDeploymentsToCreatePatchData(tc.isAutopilot, testDeclared, testCurrent, reconcilerManagerAllowList, core.Scheme) + fakeClient := syncerFake.NewClient(t, core.Scheme) + if tc.isAutopilot { + err := fakeClient.Create(context.Background(), util.FakeAutopilotWebhookObject()) + require.NoError(t, err) + } + r := &reconcilerBase{ + scheme: fakeClient.Scheme(), + client: fakeClient, + } + dep, err := r.compareDeploymentsToCreatePatchData(testDeclared, testCurrent, reconcilerDriftAllowList) require.NoError(t, err) require.Equal(t, tc.expectedSame, dep.same) }) diff --git a/pkg/reconcilermanager/controllers/reposync_controller.go b/pkg/reconcilermanager/controllers/reposync_controller.go index a5485f5cf2..02bab49b44 100644 --- a/pkg/reconcilermanager/controllers/reposync_controller.go +++ b/pkg/reconcilermanager/controllers/reposync_controller.go @@ -238,8 +238,18 @@ func (r *RepoSyncReconciler) upsertManagedObjects(ctx context.Context, reconcile containerEnvs := r.populateContainerEnvs(ctx, rs, reconcilerRef.Name) mut := r.mutationsFor(ctx, rs, containerEnvs) + vpaEnabled, err := r.isVPAEnabled(rs.Spec.Override) + if err != nil { + return err + } + + ignoredFields := reconcilerDriftAllowList + if vpaEnabled { + ignoredFields = append([]string{reconcilerContainerResourceField}, ignoredFields...) + } + // Upsert Namespace reconciler deployment. - deployObj, op, err := r.upsertDeployment(ctx, reconcilerRef, labelMap, mut) + deployObj, op, err := r.upsertDeployment(ctx, reconcilerRef, labelMap, mut, ignoredFields) if err != nil { return err } @@ -254,13 +264,23 @@ func (r *RepoSyncReconciler) upsertManagedObjects(ctx context.Context, reconcile } } - gvk, err := kinds.Lookup(deployObj, r.scheme) + deployGVK, err := kinds.Lookup(deployObj, r.scheme) if err != nil { return err } deployID := core.ID{ ObjectKey: reconcilerRef, - GroupKind: gvk.GroupKind(), + GroupKind: deployGVK.GroupKind(), + } + + if vpaEnabled { + if _, err := r.upsertVerticalPodAutoscaler(ctx, deployID, labelMap); err != nil { + return err + } + } else { + if err := r.deleteVerticalPodAutoscaler(ctx, reconcilerRef); err != nil { + return err + } } result, err := kstatus.Compute(deployObj) @@ -393,6 +413,10 @@ func (r *RepoSyncReconciler) handleReconcileError(ctx context.Context, err error func (r *RepoSyncReconciler) deleteManagedObjects(ctx context.Context, reconcilerRef, rsRef types.NamespacedName) error { r.logger(ctx).Info("Deleting managed objects") + if err := r.deleteVerticalPodAutoscaler(ctx, reconcilerRef); err != nil { + return err + } + if err := r.deleteDeployment(ctx, reconcilerRef); err != nil { return err } diff --git a/pkg/reconcilermanager/controllers/rootsync_controller.go b/pkg/reconcilermanager/controllers/rootsync_controller.go index 103c4830eb..1838a63ee4 100644 --- a/pkg/reconcilermanager/controllers/rootsync_controller.go +++ b/pkg/reconcilermanager/controllers/rootsync_controller.go @@ -238,8 +238,18 @@ func (r *RootSyncReconciler) upsertManagedObjects(ctx context.Context, reconcile containerEnvs := r.populateContainerEnvs(ctx, rs, reconcilerRef.Name) mut := r.mutationsFor(ctx, rs, containerEnvs) + vpaEnabled, err := r.isVPAEnabled(rs.Spec.Override) + if err != nil { + return err + } + + ignoredFields := reconcilerDriftAllowList + if vpaEnabled { + ignoredFields = append([]string{reconcilerContainerResourceField}, ignoredFields...) + } + // Upsert Root reconciler deployment. - deployObj, op, err := r.upsertDeployment(ctx, reconcilerRef, labelMap, mut) + deployObj, op, err := r.upsertDeployment(ctx, reconcilerRef, labelMap, mut, ignoredFields) if err != nil { return err } @@ -254,13 +264,23 @@ func (r *RootSyncReconciler) upsertManagedObjects(ctx context.Context, reconcile } } - gvk, err := kinds.Lookup(deployObj, r.scheme) + deployGVK, err := kinds.Lookup(deployObj, r.scheme) if err != nil { return err } deployID := core.ID{ ObjectKey: reconcilerRef, - GroupKind: gvk.GroupKind(), + GroupKind: deployGVK.GroupKind(), + } + + if vpaEnabled { + if _, err := r.upsertVerticalPodAutoscaler(ctx, deployID, labelMap); err != nil { + return err + } + } else { + if err := r.deleteVerticalPodAutoscaler(ctx, reconcilerRef); err != nil { + return err + } } result, err := kstatus.Compute(deployObj) @@ -393,6 +413,10 @@ func (r *RootSyncReconciler) handleReconcileError(ctx context.Context, err error func (r *RootSyncReconciler) deleteManagedObjects(ctx context.Context, reconcilerRef types.NamespacedName) error { r.logger(ctx).Info("Deleting managed objects") + if err := r.deleteVerticalPodAutoscaler(ctx, reconcilerRef); err != nil { + return err + } + if err := r.deleteDeployment(ctx, reconcilerRef); err != nil { return err } diff --git a/pkg/util/autopilot.go b/pkg/util/autopilot.go index 5c8f608aa0..d31d1bff75 100644 --- a/pkg/util/autopilot.go +++ b/pkg/util/autopilot.go @@ -132,3 +132,11 @@ func AutopilotResourceMutation(annotation string) (map[string]corev1.ResourceReq } return input, output, nil } + +// FakeAutopilotWebhookObject returns a fake empty MutatingWebhookConfiguration +// that satisfies IsGKEAutopilotCluster, for testing. +func FakeAutopilotWebhookObject() client.Object { + webhook := &admissionregistrationv1.MutatingWebhookConfiguration{} + webhook.Name = autopilotWebhooks[0] + return webhook +} diff --git a/pkg/util/watch/delete.go b/pkg/util/watch/delete.go index f8354c2d46..247ca4660c 100644 --- a/pkg/util/watch/delete.go +++ b/pkg/util/watch/delete.go @@ -20,6 +20,7 @@ import ( "github.com/pkg/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" @@ -166,6 +167,13 @@ func DeleteAndWait(ctx context.Context, c client.WithWatch, obj client.Object, r // Stop waiting - object already deleted return true, nil } + if meta.IsNoMatchError(err) { + klog.V(3).Infof("Resource not registered %q=%q, %q=%q", + logFieldObjectRef, id.ObjectKey.String(), + logFieldObjectKind, id.Kind) + // Stop waiting - resource not registered + return true, nil + } // Stop waiting return false, err } diff --git a/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/LICENSE b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/doc.go b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/doc.go new file mode 100644 index 0000000000..8b81690810 --- /dev/null +++ b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2019 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. +*/ + +// +k8s:deepcopy-gen=package,register + +// Package v1 contains definitions of Vertical Pod Autoscaler related objects. +// +groupName=autoscaling.k8s.io +// +kubebuilder:object:generate=true +package v1 diff --git a/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/register.go b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/register.go new file mode 100644 index 0000000000..70214933be --- /dev/null +++ b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/register.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 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 v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: "autoscaling.k8s.io", Version: "v1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder points to a list of functions added to Scheme. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + // AddToScheme applies all the stored functions to the scheme. + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &VerticalPodAutoscaler{}, + &VerticalPodAutoscalerList{}, + &VerticalPodAutoscalerCheckpoint{}, + &VerticalPodAutoscalerCheckpointList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/types.go b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/types.go new file mode 100644 index 0000000000..3842bcd719 --- /dev/null +++ b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/types.go @@ -0,0 +1,393 @@ +/* +Copyright 2019 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 v1 contains definitions of Vertical Pod Autoscaler related objects. +package v1 + +import ( + autoscaling "k8s.io/api/autoscaling/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// VerticalPodAutoscalerList is a list of VerticalPodAutoscaler objects. +type VerticalPodAutoscalerList struct { + metav1.TypeMeta `json:",inline"` + // metadata is the standard list metadata. + // +optional + metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` + + // items is the list of vertical pod autoscaler objects. + Items []VerticalPodAutoscaler `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion +// +kubebuilder:resource:shortName=vpa +// +kubebuilder:printcolumn:name="Mode",type="string",JSONPath=".spec.updatePolicy.updateMode" +// +kubebuilder:printcolumn:name="CPU",type="string",JSONPath=".status.recommendation.containerRecommendations[0].target.cpu" +// +kubebuilder:printcolumn:name="Mem",type="string",JSONPath=".status.recommendation.containerRecommendations[0].target.memory" +// +kubebuilder:printcolumn:name="Provided",type="string",JSONPath=".status.conditions[?(@.type=='RecommendationProvided')].status" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// VerticalPodAutoscaler is the configuration for a vertical pod +// autoscaler, which automatically manages pod resources based on historical and +// real time resource utilization. +type VerticalPodAutoscaler struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Specification of the behavior of the autoscaler. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + Spec VerticalPodAutoscalerSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // Current information about the autoscaler. + // +optional + Status VerticalPodAutoscalerStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// VerticalPodAutoscalerRecommenderSelector points to a specific Vertical Pod Autoscaler recommender. +// In the future it might pass parameters to the recommender. +type VerticalPodAutoscalerRecommenderSelector struct { + // Name of the recommender responsible for generating recommendation for this object. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` +} + +// VerticalPodAutoscalerSpec is the specification of the behavior of the autoscaler. +type VerticalPodAutoscalerSpec struct { + + // TargetRef points to the controller managing the set of pods for the + // autoscaler to control - e.g. Deployment, StatefulSet. VerticalPodAutoscaler + // can be targeted at controller implementing scale subresource (the pod set is + // retrieved from the controller's ScaleStatus) or some well known controllers + // (e.g. for DaemonSet the pod set is read from the controller's spec). + // If VerticalPodAutoscaler cannot use specified target it will report + // ConfigUnsupported condition. + // Note that VerticalPodAutoscaler does not require full implementation + // of scale subresource - it will not use it to modify the replica count. + // The only thing retrieved is a label selector matching pods grouped by + // the target resource. + TargetRef *autoscaling.CrossVersionObjectReference `json:"targetRef" protobuf:"bytes,1,name=targetRef"` + + // Describes the rules on how changes are applied to the pods. + // If not specified, all fields in the `PodUpdatePolicy` are set to their + // default values. + // +optional + UpdatePolicy *PodUpdatePolicy `json:"updatePolicy,omitempty" protobuf:"bytes,2,opt,name=updatePolicy"` + + // Controls how the autoscaler computes recommended resources. + // The resource policy may be used to set constraints on the recommendations + // for individual containers. If not specified, the autoscaler computes recommended + // resources for all containers in the pod, without additional constraints. + // +optional + ResourcePolicy *PodResourcePolicy `json:"resourcePolicy,omitempty" protobuf:"bytes,3,opt,name=resourcePolicy"` + + // Recommender responsible for generating recommendation for this object. + // List should be empty (then the default recommender will generate the + // recommendation) or contain exactly one recommender. + // +optional + Recommenders []*VerticalPodAutoscalerRecommenderSelector `json:"recommenders,omitempty" protobuf:"bytes,4,opt,name=recommenders"` +} + +// PodUpdatePolicy describes the rules on how changes are applied to the pods. +type PodUpdatePolicy struct { + // Controls when autoscaler applies changes to the pod resources. + // The default is 'Auto'. + // +optional + UpdateMode *UpdateMode `json:"updateMode,omitempty" protobuf:"bytes,1,opt,name=updateMode"` + + // Minimal number of replicas which need to be alive for Updater to attempt + // pod eviction (pending other checks like PDB). Only positive values are + // allowed. Overrides global '--min-replicas' flag. + // +optional + MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` +} + +// UpdateMode controls when autoscaler applies changes to the pod resoures. +// +kubebuilder:validation:Enum=Off;Initial;Recreate;Auto +type UpdateMode string + +const ( + // UpdateModeOff means that autoscaler never changes Pod resources. + // The recommender still sets the recommended resources in the + // VerticalPodAutoscaler object. This can be used for a "dry run". + UpdateModeOff UpdateMode = "Off" + // UpdateModeInitial means that autoscaler only assigns resources on pod + // creation and does not change them during the lifetime of the pod. + UpdateModeInitial UpdateMode = "Initial" + // UpdateModeRecreate means that autoscaler assigns resources on pod + // creation and additionally can update them during the lifetime of the + // pod by deleting and recreating the pod. + UpdateModeRecreate UpdateMode = "Recreate" + // UpdateModeAuto means that autoscaler assigns resources on pod creation + // and additionally can update them during the lifetime of the pod, + // using any available update method. Currently this is equivalent to + // Recreate, which is the only available update method. + UpdateModeAuto UpdateMode = "Auto" +) + +// PodResourcePolicy controls how autoscaler computes the recommended resources +// for containers belonging to the pod. There can be at most one entry for every +// named container and optionally a single wildcard entry with `containerName` = '*', +// which handles all containers that don't have individual policies. +type PodResourcePolicy struct { + // Per-container resource policies. + // +optional + // +patchMergeKey=containerName + // +patchStrategy=merge + ContainerPolicies []ContainerResourcePolicy `json:"containerPolicies,omitempty" patchStrategy:"merge" patchMergeKey:"containerName" protobuf:"bytes,1,rep,name=containerPolicies"` +} + +// ContainerResourcePolicy controls how autoscaler computes the recommended +// resources for a specific container. +type ContainerResourcePolicy struct { + // Name of the container or DefaultContainerResourcePolicy, in which + // case the policy is used by the containers that don't have their own + // policy specified. + ContainerName string `json:"containerName,omitempty" protobuf:"bytes,1,opt,name=containerName"` + // Whether autoscaler is enabled for the container. The default is "Auto". + // +optional + Mode *ContainerScalingMode `json:"mode,omitempty" protobuf:"bytes,2,opt,name=mode"` + // Specifies the minimal amount of resources that will be recommended + // for the container. The default is no minimum. + // +optional + MinAllowed v1.ResourceList `json:"minAllowed,omitempty" protobuf:"bytes,3,rep,name=minAllowed,casttype=ResourceList,castkey=ResourceName"` + // Specifies the maximum amount of resources that will be recommended + // for the container. The default is no maximum. + // +optional + MaxAllowed v1.ResourceList `json:"maxAllowed,omitempty" protobuf:"bytes,4,rep,name=maxAllowed,casttype=ResourceList,castkey=ResourceName"` + + // Specifies the type of recommendations that will be computed + // (and possibly applied) by VPA. + // If not specified, the default of [ResourceCPU, ResourceMemory] will be used. + ControlledResources *[]v1.ResourceName `json:"controlledResources,omitempty" patchStrategy:"merge" protobuf:"bytes,5,rep,name=controlledResources"` + + // Specifies which resource values should be controlled. + // The default is "RequestsAndLimits". + // +optional + ControlledValues *ContainerControlledValues `json:"controlledValues,omitempty" protobuf:"bytes,6,rep,name=controlledValues"` +} + +const ( + // DefaultContainerResourcePolicy can be passed as + // ContainerResourcePolicy.ContainerName to specify the default policy. + DefaultContainerResourcePolicy = "*" +) + +// ContainerScalingMode controls whether autoscaler is enabled for a specific +// container. +// +kubebuilder:validation:Enum=Auto;Off +type ContainerScalingMode string + +const ( + // ContainerScalingModeAuto means autoscaling is enabled for a container. + ContainerScalingModeAuto ContainerScalingMode = "Auto" + // ContainerScalingModeOff means autoscaling is disabled for a container. + ContainerScalingModeOff ContainerScalingMode = "Off" +) + +// ContainerControlledValues controls which resource value should be autoscaled. +// +kubebuilder:validation:Enum=RequestsAndLimits;RequestsOnly +type ContainerControlledValues string + +const ( + // ContainerControlledValuesRequestsAndLimits means resource request and limits + // are scaled automatically. The limit is scaled proportionally to the request. + ContainerControlledValuesRequestsAndLimits ContainerControlledValues = "RequestsAndLimits" + // ContainerControlledValuesRequestsOnly means only requested resource is autoscaled. + ContainerControlledValuesRequestsOnly ContainerControlledValues = "RequestsOnly" +) + +// VerticalPodAutoscalerStatus describes the runtime state of the autoscaler. +type VerticalPodAutoscalerStatus struct { + // The most recently computed amount of resources recommended by the + // autoscaler for the controlled pods. + // +optional + Recommendation *RecommendedPodResources `json:"recommendation,omitempty" protobuf:"bytes,1,opt,name=recommendation"` + + // Conditions is the set of conditions required for this autoscaler to scale its target, + // and indicates whether or not those conditions are met. + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + Conditions []VerticalPodAutoscalerCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,2,rep,name=conditions"` +} + +// RecommendedPodResources is the recommendation of resources computed by +// autoscaler. It contains a recommendation for each container in the pod +// (except for those with `ContainerScalingMode` set to 'Off'). +type RecommendedPodResources struct { + // Resources recommended by the autoscaler for each container. + // +optional + ContainerRecommendations []RecommendedContainerResources `json:"containerRecommendations,omitempty" protobuf:"bytes,1,rep,name=containerRecommendations"` +} + +// RecommendedContainerResources is the recommendation of resources computed by +// autoscaler for a specific container. Respects the container resource policy +// if present in the spec. In particular the recommendation is not produced for +// containers with `ContainerScalingMode` set to 'Off'. +type RecommendedContainerResources struct { + // Name of the container. + ContainerName string `json:"containerName,omitempty" protobuf:"bytes,1,opt,name=containerName"` + // Recommended amount of resources. Observes ContainerResourcePolicy. + Target v1.ResourceList `json:"target" protobuf:"bytes,2,rep,name=target,casttype=ResourceList,castkey=ResourceName"` + // Minimum recommended amount of resources. Observes ContainerResourcePolicy. + // This amount is not guaranteed to be sufficient for the application to operate in a stable way, however + // running with less resources is likely to have significant impact on performance/availability. + // +optional + LowerBound v1.ResourceList `json:"lowerBound,omitempty" protobuf:"bytes,3,rep,name=lowerBound,casttype=ResourceList,castkey=ResourceName"` + // Maximum recommended amount of resources. Observes ContainerResourcePolicy. + // Any resources allocated beyond this value are likely wasted. This value may be larger than the maximum + // amount of application is actually capable of consuming. + // +optional + UpperBound v1.ResourceList `json:"upperBound,omitempty" protobuf:"bytes,4,rep,name=upperBound,casttype=ResourceList,castkey=ResourceName"` + // The most recent recommended resources target computed by the autoscaler + // for the controlled pods, based only on actual resource usage, not taking + // into account the ContainerResourcePolicy. + // May differ from the Recommendation if the actual resource usage causes + // the target to violate the ContainerResourcePolicy (lower than MinAllowed + // or higher that MaxAllowed). + // Used only as status indication, will not affect actual resource assignment. + // +optional + UncappedTarget v1.ResourceList `json:"uncappedTarget,omitempty" protobuf:"bytes,5,opt,name=uncappedTarget"` +} + +// VerticalPodAutoscalerConditionType are the valid conditions of +// a VerticalPodAutoscaler. +type VerticalPodAutoscalerConditionType string + +var ( + // RecommendationProvided indicates whether the VPA recommender was able to calculate a recommendation. + RecommendationProvided VerticalPodAutoscalerConditionType = "RecommendationProvided" + // LowConfidence indicates whether the VPA recommender has low confidence in the recommendation for + // some of containers. + LowConfidence VerticalPodAutoscalerConditionType = "LowConfidence" + // NoPodsMatched indicates that label selector used with VPA object didn't match any pods. + NoPodsMatched VerticalPodAutoscalerConditionType = "NoPodsMatched" + // FetchingHistory indicates that VPA recommender is in the process of loading additional history samples. + FetchingHistory VerticalPodAutoscalerConditionType = "FetchingHistory" + // ConfigDeprecated indicates that this VPA configuration is deprecated + // and will stop being supported soon. + ConfigDeprecated VerticalPodAutoscalerConditionType = "ConfigDeprecated" + // ConfigUnsupported indicates that this VPA configuration is unsupported + // and recommendations will not be provided for it. + ConfigUnsupported VerticalPodAutoscalerConditionType = "ConfigUnsupported" +) + +// VerticalPodAutoscalerCondition describes the state of +// a VerticalPodAutoscaler at a certain point. +type VerticalPodAutoscalerCondition struct { + // type describes the current condition + Type VerticalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) + Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from + // one status to another + // +optional + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. + // +optional + Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about + // the transition + // +optional + Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion +// +kubebuilder:resource:shortName=vpacheckpoint + +// VerticalPodAutoscalerCheckpoint is the checkpoint of the internal state of VPA that +// is used for recovery after recommender's restart. +type VerticalPodAutoscalerCheckpoint struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Specification of the checkpoint. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // +optional + Spec VerticalPodAutoscalerCheckpointSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + + // Data of the checkpoint. + // +optional + Status VerticalPodAutoscalerCheckpointStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// VerticalPodAutoscalerCheckpointList is a list of VerticalPodAutoscalerCheckpoint objects. +type VerticalPodAutoscalerCheckpointList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []VerticalPodAutoscalerCheckpoint `json:"items"` +} + +// VerticalPodAutoscalerCheckpointSpec is the specification of the checkpoint object. +type VerticalPodAutoscalerCheckpointSpec struct { + // Name of the VPA object that stored VerticalPodAutoscalerCheckpoint object. + VPAObjectName string `json:"vpaObjectName,omitempty" protobuf:"bytes,1,opt,name=vpaObjectName"` + + // Name of the checkpointed container. + ContainerName string `json:"containerName,omitempty" protobuf:"bytes,2,opt,name=containerName"` +} + +// VerticalPodAutoscalerCheckpointStatus contains data of the checkpoint. +type VerticalPodAutoscalerCheckpointStatus struct { + // The time when the status was last refreshed. + // +nullable + LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,1,opt,name=lastUpdateTime"` + + // Version of the format of the stored data. + Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` + + // Checkpoint of histogram for consumption of CPU. + CPUHistogram HistogramCheckpoint `json:"cpuHistogram,omitempty" protobuf:"bytes,3,rep,name=cpuHistograms"` + + // Checkpoint of histogram for consumption of memory. + MemoryHistogram HistogramCheckpoint `json:"memoryHistogram,omitempty" protobuf:"bytes,4,rep,name=memoryHistogram"` + + // Timestamp of the fist sample from the histograms. + // +nullable + FirstSampleStart metav1.Time `json:"firstSampleStart,omitempty" protobuf:"bytes,5,opt,name=firstSampleStart"` + + // Timestamp of the last sample from the histograms. + // +nullable + LastSampleStart metav1.Time `json:"lastSampleStart,omitempty" protobuf:"bytes,6,opt,name=lastSampleStart"` + + // Total number of samples in the histograms. + TotalSamplesCount int `json:"totalSamplesCount,omitempty" protobuf:"bytes,7,opt,name=totalSamplesCount"` +} + +// HistogramCheckpoint contains data needed to reconstruct the histogram. +type HistogramCheckpoint struct { + // Reference timestamp for samples collected within this histogram. + // +nullable + ReferenceTimestamp metav1.Time `json:"referenceTimestamp,omitempty" protobuf:"bytes,1,opt,name=referenceTimestamp"` + + // Map from bucket index to bucket weight. + // +kubebuilder:validation:Type=object + // +kubebuilder:validation:XPreserveUnknownFields + BucketWeights map[int]uint32 `json:"bucketWeights,omitempty" protobuf:"bytes,2,opt,name=bucketWeights"` + + // Sum of samples to be used as denominator for weights from BucketWeights. + TotalWeight float64 `json:"totalWeight,omitempty" protobuf:"bytes,3,opt,name=totalWeight"` +} diff --git a/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/zz_generated.deepcopy.go b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..9cea0376dd --- /dev/null +++ b/vendor/k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1/zz_generated.deepcopy.go @@ -0,0 +1,479 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + autoscalingv1 "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResourcePolicy) DeepCopyInto(out *ContainerResourcePolicy) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(ContainerScalingMode) + **out = **in + } + if in.MinAllowed != nil { + in, out := &in.MinAllowed, &out.MinAllowed + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.MaxAllowed != nil { + in, out := &in.MaxAllowed, &out.MaxAllowed + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.ControlledResources != nil { + in, out := &in.ControlledResources, &out.ControlledResources + *out = new([]corev1.ResourceName) + if **in != nil { + in, out := *in, *out + *out = make([]corev1.ResourceName, len(*in)) + copy(*out, *in) + } + } + if in.ControlledValues != nil { + in, out := &in.ControlledValues, &out.ControlledValues + *out = new(ContainerControlledValues) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourcePolicy. +func (in *ContainerResourcePolicy) DeepCopy() *ContainerResourcePolicy { + if in == nil { + return nil + } + out := new(ContainerResourcePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HistogramCheckpoint) DeepCopyInto(out *HistogramCheckpoint) { + *out = *in + in.ReferenceTimestamp.DeepCopyInto(&out.ReferenceTimestamp) + if in.BucketWeights != nil { + in, out := &in.BucketWeights, &out.BucketWeights + *out = make(map[int]uint32, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HistogramCheckpoint. +func (in *HistogramCheckpoint) DeepCopy() *HistogramCheckpoint { + if in == nil { + return nil + } + out := new(HistogramCheckpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodResourcePolicy) DeepCopyInto(out *PodResourcePolicy) { + *out = *in + if in.ContainerPolicies != nil { + in, out := &in.ContainerPolicies, &out.ContainerPolicies + *out = make([]ContainerResourcePolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodResourcePolicy. +func (in *PodResourcePolicy) DeepCopy() *PodResourcePolicy { + if in == nil { + return nil + } + out := new(PodResourcePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodUpdatePolicy) DeepCopyInto(out *PodUpdatePolicy) { + *out = *in + if in.UpdateMode != nil { + in, out := &in.UpdateMode, &out.UpdateMode + *out = new(UpdateMode) + **out = **in + } + if in.MinReplicas != nil { + in, out := &in.MinReplicas, &out.MinReplicas + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodUpdatePolicy. +func (in *PodUpdatePolicy) DeepCopy() *PodUpdatePolicy { + if in == nil { + return nil + } + out := new(PodUpdatePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RecommendedContainerResources) DeepCopyInto(out *RecommendedContainerResources) { + *out = *in + if in.Target != nil { + in, out := &in.Target, &out.Target + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.LowerBound != nil { + in, out := &in.LowerBound, &out.LowerBound + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.UpperBound != nil { + in, out := &in.UpperBound, &out.UpperBound + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.UncappedTarget != nil { + in, out := &in.UncappedTarget, &out.UncappedTarget + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecommendedContainerResources. +func (in *RecommendedContainerResources) DeepCopy() *RecommendedContainerResources { + if in == nil { + return nil + } + out := new(RecommendedContainerResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RecommendedPodResources) DeepCopyInto(out *RecommendedPodResources) { + *out = *in + if in.ContainerRecommendations != nil { + in, out := &in.ContainerRecommendations, &out.ContainerRecommendations + *out = make([]RecommendedContainerResources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecommendedPodResources. +func (in *RecommendedPodResources) DeepCopy() *RecommendedPodResources { + if in == nil { + return nil + } + out := new(RecommendedPodResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscaler) DeepCopyInto(out *VerticalPodAutoscaler) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscaler. +func (in *VerticalPodAutoscaler) DeepCopy() *VerticalPodAutoscaler { + if in == nil { + return nil + } + out := new(VerticalPodAutoscaler) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticalPodAutoscaler) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerCheckpoint) DeepCopyInto(out *VerticalPodAutoscalerCheckpoint) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerCheckpoint. +func (in *VerticalPodAutoscalerCheckpoint) DeepCopy() *VerticalPodAutoscalerCheckpoint { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerCheckpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticalPodAutoscalerCheckpoint) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerCheckpointList) DeepCopyInto(out *VerticalPodAutoscalerCheckpointList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VerticalPodAutoscalerCheckpoint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerCheckpointList. +func (in *VerticalPodAutoscalerCheckpointList) DeepCopy() *VerticalPodAutoscalerCheckpointList { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerCheckpointList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticalPodAutoscalerCheckpointList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerCheckpointSpec) DeepCopyInto(out *VerticalPodAutoscalerCheckpointSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerCheckpointSpec. +func (in *VerticalPodAutoscalerCheckpointSpec) DeepCopy() *VerticalPodAutoscalerCheckpointSpec { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerCheckpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerCheckpointStatus) DeepCopyInto(out *VerticalPodAutoscalerCheckpointStatus) { + *out = *in + in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) + in.CPUHistogram.DeepCopyInto(&out.CPUHistogram) + in.MemoryHistogram.DeepCopyInto(&out.MemoryHistogram) + in.FirstSampleStart.DeepCopyInto(&out.FirstSampleStart) + in.LastSampleStart.DeepCopyInto(&out.LastSampleStart) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerCheckpointStatus. +func (in *VerticalPodAutoscalerCheckpointStatus) DeepCopy() *VerticalPodAutoscalerCheckpointStatus { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerCheckpointStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerCondition) DeepCopyInto(out *VerticalPodAutoscalerCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerCondition. +func (in *VerticalPodAutoscalerCondition) DeepCopy() *VerticalPodAutoscalerCondition { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerList) DeepCopyInto(out *VerticalPodAutoscalerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VerticalPodAutoscaler, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerList. +func (in *VerticalPodAutoscalerList) DeepCopy() *VerticalPodAutoscalerList { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticalPodAutoscalerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerRecommenderSelector) DeepCopyInto(out *VerticalPodAutoscalerRecommenderSelector) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerRecommenderSelector. +func (in *VerticalPodAutoscalerRecommenderSelector) DeepCopy() *VerticalPodAutoscalerRecommenderSelector { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerRecommenderSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerSpec) DeepCopyInto(out *VerticalPodAutoscalerSpec) { + *out = *in + if in.TargetRef != nil { + in, out := &in.TargetRef, &out.TargetRef + *out = new(autoscalingv1.CrossVersionObjectReference) + **out = **in + } + if in.UpdatePolicy != nil { + in, out := &in.UpdatePolicy, &out.UpdatePolicy + *out = new(PodUpdatePolicy) + (*in).DeepCopyInto(*out) + } + if in.ResourcePolicy != nil { + in, out := &in.ResourcePolicy, &out.ResourcePolicy + *out = new(PodResourcePolicy) + (*in).DeepCopyInto(*out) + } + if in.Recommenders != nil { + in, out := &in.Recommenders, &out.Recommenders + *out = make([]*VerticalPodAutoscalerRecommenderSelector, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(VerticalPodAutoscalerRecommenderSelector) + **out = **in + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerSpec. +func (in *VerticalPodAutoscalerSpec) DeepCopy() *VerticalPodAutoscalerSpec { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticalPodAutoscalerStatus) DeepCopyInto(out *VerticalPodAutoscalerStatus) { + *out = *in + if in.Recommendation != nil { + in, out := &in.Recommendation, &out.Recommendation + *out = new(RecommendedPodResources) + (*in).DeepCopyInto(*out) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]VerticalPodAutoscalerCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticalPodAutoscalerStatus. +func (in *VerticalPodAutoscalerStatus) DeepCopy() *VerticalPodAutoscalerStatus { + if in == nil { + return nil + } + out := new(VerticalPodAutoscalerStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/modules.txt b/vendor/modules.txt index c6f176f5b7..e4fb892a00 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -746,6 +746,9 @@ k8s.io/apimachinery/third_party/forked/golang/reflect ## explicit; go 1.19 k8s.io/apiserver/pkg/features k8s.io/apiserver/pkg/util/feature +# k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0 +## explicit; go 1.19 +k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1 # k8s.io/cli-runtime v0.25.9 ## explicit; go 1.19 k8s.io/cli-runtime/pkg/genericclioptions