From 1818b5b3fc5ac70bd07736b9d6b0d2dc75fdf1d4 Mon Sep 17 00:00:00 2001 From: Piotr Szczesniak Date: Fri, 3 Jun 2016 13:31:50 +0200 Subject: [PATCH] Added hpa/v1 generator to kubectl autoscale --- hack/test-cmd.sh | 28 ++++++++++++++++++---------- pkg/kubectl/autoscale.go | 27 +++++++++++++++++++++++---- pkg/kubectl/cmd/autoscale.go | 6 +++--- pkg/kubectl/cmd/util/factory.go | 4 ++++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/hack/test-cmd.sh b/hack/test-cmd.sh index 2221df6892f..b51ffab0050 100755 --- a/hack/test-cmd.sh +++ b/hack/test-cmd.sh @@ -298,7 +298,7 @@ runTests() { image_field="(index .spec.containers 0).image" hpa_min_field=".spec.minReplicas" hpa_max_field=".spec.maxReplicas" - hpa_cpu_field=".spec.cpuUtilization.targetPercentage" + hpa_cpu_field=".spec.targetCPUUtilizationPercentage" job_parallelism_field=".spec.parallelism" deployment_replicas=".spec.replicas" secret_data=".data" @@ -884,7 +884,7 @@ __EOF__ [[ "$(kubectl get hpa.v1beta1.extensions frontend -o yaml "${kube_flags[@]}" | grep kubectl.kubernetes.io/last-applied-configuration)" ]] # Ensure we can interact with HPA objects in lists through both the extensions/v1beta1 and autoscaling/v1 APIs output_message=$(kubectl get hpa -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}") - kube::test::if_has_string "${output_message}" 'extensions/v1beta1' + kube::test::if_has_string "${output_message}" 'autoscaling/v1' output_message=$(kubectl get hpa.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" 'extensions/v1beta1' output_message=$(kubectl get hpa.autoscaling -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}") @@ -1050,8 +1050,8 @@ __EOF__ output_message=$(! kubectl autoscale --min=1 --max=2 -f hack/testdata/recursive/rc --recursive 2>&1 "${kube_flags[@]}") # Post-condition: busybox0 & busybox replication controllers are autoscaled # with min. of 1 replica & max of 2 replicas, and since busybox2 is malformed, it should error - kube::test::get_object_assert 'hpa busybox0' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 80' - kube::test::get_object_assert 'hpa busybox1' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 80' + kube::test::get_object_assert 'hpa busybox0' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 ' + kube::test::get_object_assert 'hpa busybox1' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 ' kube::test::if_has_string "${output_message}" "Object 'Kind' is missing" kubectl delete hpa busybox0 "${kube_flags[@]}" kubectl delete hpa busybox1 "${kube_flags[@]}" @@ -1652,9 +1652,17 @@ __EOF__ kubectl autoscale -f hack/testdata/frontend-controller.yaml "${kube_flags[@]}" --max=2 --cpu-percent=70 kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 70' kubectl delete hpa frontend "${kube_flags[@]}" - # autoscale 2~3 pods, default CPU utilization (80%), rc specified by name + # autoscale 1~2 pods, CPU utilization 70%, rc specified by file, using old generator + kubectl autoscale -f hack/testdata/frontend-controller.yaml "${kube_flags[@]}" --max=2 --cpu-percent=70 --generator=horizontalpodautoscaler/v1beta1 + kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 70' + kubectl delete hpa frontend "${kube_flags[@]}" + # autoscale 2~3 pods, no CPU utilization specified, rc specified by name kubectl autoscale rc frontend "${kube_flags[@]}" --min=2 --max=3 - kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 80' + kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 ' + kubectl delete hpa frontend "${kube_flags[@]}" + # autoscale 2~3 pods, no CPU utilization specified, rc specified by name, using old generator + kubectl autoscale rc frontend "${kube_flags[@]}" --min=2 --max=3 --generator=horizontalpodautoscaler/v1beta1 + kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 ' kubectl delete hpa frontend "${kube_flags[@]}" # autoscale without specifying --max should fail ! kubectl autoscale rc frontend "${kube_flags[@]}" @@ -1672,9 +1680,9 @@ __EOF__ # Command kubectl create -f docs/user-guide/deployment.yaml "${kube_flags[@]}" kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" 'nginx-deployment:' - # autoscale 2~3 pods, default CPU utilization (80%) + # autoscale 2~3 pods, no CPU utilization specified kubectl-with-retry autoscale deployment nginx-deployment "${kube_flags[@]}" --min=2 --max=3 - kube::test::get_object_assert 'hpa.extensions nginx-deployment' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 80' + kube::test::get_object_assert 'hpa nginx-deployment' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 ' # Clean up # Note that we should delete hpa first, otherwise it may fight with the deployment reaper. kubectl delete hpa nginx-deployment "${kube_flags[@]}" @@ -1849,9 +1857,9 @@ __EOF__ kubectl autoscale -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]}" --max=2 --cpu-percent=70 kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '1 2 70' kubectl delete hpa frontend "${kube_flags[@]}" - # autoscale 2~3 pods, default CPU utilization (80%), replica set specified by name + # autoscale 2~3 pods, no CPU utilization specified, replica set specified by name kubectl autoscale rs frontend "${kube_flags[@]}" --min=2 --max=3 - kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 80' + kube::test::get_object_assert 'hpa frontend' "{{$hpa_min_field}} {{$hpa_max_field}} {{$hpa_cpu_field}}" '2 3 ' kubectl delete hpa frontend "${kube_flags[@]}" # autoscale without specifying --max should fail ! kubectl autoscale rs frontend "${kube_flags[@]}" diff --git a/pkg/kubectl/autoscale.go b/pkg/kubectl/autoscale.go index e3a7fc088a9..979a93bf0f0 100644 --- a/pkg/kubectl/autoscale.go +++ b/pkg/kubectl/autoscale.go @@ -25,10 +25,6 @@ import ( "k8s.io/kubernetes/pkg/runtime" ) -const ( - scaleSubResource = "scale" -) - type HorizontalPodAutoscalerV1Beta1 struct{} func (HorizontalPodAutoscalerV1Beta1) ParamNames() []GeneratorParam { @@ -46,6 +42,29 @@ func (HorizontalPodAutoscalerV1Beta1) ParamNames() []GeneratorParam { } func (HorizontalPodAutoscalerV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object, error) { + return generateHPA(genericParams) +} + +type HorizontalPodAutoscalerV1 struct{} + +func (HorizontalPodAutoscalerV1) ParamNames() []GeneratorParam { + return []GeneratorParam{ + {"default-name", true}, + {"name", false}, + {"scaleRef-kind", false}, + {"scaleRef-name", false}, + {"scaleRef-apiVersion", false}, + {"min", false}, + {"max", true}, + {"cpu-percent", false}, + } +} + +func (HorizontalPodAutoscalerV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) { + return generateHPA(genericParams) +} + +func generateHPA(genericParams map[string]interface{}) (runtime.Object, error) { params := map[string]string{} for key, value := range genericParams { strVal, isString := value.(string) diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index e1e9b870e9a..8419ee8ec98 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -41,7 +41,7 @@ const ( Looks up a Deployment, ReplicaSet, or ReplicationController by name and creates an autoscaler that uses the given resource as a reference. An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.` - autoscaleExample = `# Auto scale a deployment "foo", with the number of pods between 2 to 10, target CPU utilization at a default value that server applies: + autoscaleExample = `# Auto scale a deployment "foo", with the number of pods between 2 to 10, no target CPU utilization specfied so a default autoscaling policy will be used: kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a replication controller "foo", with the number of pods between 1 to 5, target CPU utilization at 80%: @@ -62,11 +62,11 @@ func NewCmdAutoscale(f *cmdutil.Factory, out io.Writer) *cobra.Command { }, } cmdutil.AddPrinterFlags(cmd) - cmd.Flags().String("generator", "horizontalpodautoscaler/v1beta1", "The name of the API generator to use. Currently there is only 1 generator.") + cmd.Flags().String("generator", "horizontalpodautoscaler/v1", "The name of the API generator to use. Currently there is only 1 generator.") cmd.Flags().Int("min", -1, "The lower limit for the number of pods that can be set by the autoscaler. If it's not specified or negative, the server will apply a default value.") cmd.Flags().Int("max", -1, "The upper limit for the number of pods that can be set by the autoscaler. Required.") cmd.MarkFlagRequired("max") - cmd.Flags().Int("cpu-percent", -1, fmt.Sprintf("The target average CPU utilization (represented as a percent of requested CPU) over all the pods. If it's not specified or negative, the server will apply a default value.")) + cmd.Flags().Int("cpu-percent", -1, fmt.Sprintf("The target average CPU utilization (represented as a percent of requested CPU) over all the pods. If it's not specified or negative, a default autoscaling policy will be used.")) cmd.Flags().String("name", "", "The name for the newly created object. If not specified, the name of the input resource will be used.") cmdutil.AddDryRunFlag(cmd) usage := "Filename, directory, or URL to a file identifying the resource to autoscale." diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index d4c3cc54046..76df00b0d08 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -159,6 +159,7 @@ const ( ServiceV2GeneratorName = "service/v2" ServiceAccountV1GeneratorName = "serviceaccount/v1" HorizontalPodAutoscalerV1Beta1GeneratorName = "horizontalpodautoscaler/v1beta1" + HorizontalPodAutoscalerV1GeneratorName = "horizontalpodautoscaler/v1" DeploymentV1Beta1GeneratorName = "deployment/v1beta1" JobV1Beta1GeneratorName = "job/v1beta1" JobV1GeneratorName = "job/v1" @@ -185,6 +186,7 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator { } generators["autoscale"] = map[string]kubectl.Generator{ HorizontalPodAutoscalerV1Beta1GeneratorName: kubectl.HorizontalPodAutoscalerV1Beta1{}, + HorizontalPodAutoscalerV1GeneratorName: kubectl.HorizontalPodAutoscalerV1{}, } generators["namespace"] = map[string]kubectl.Generator{ NamespaceV1GeneratorName: kubectl.NamespaceGeneratorV1{}, @@ -317,11 +319,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { Delegate: outputRESTMapper, ResourcePriority: []unversioned.GroupVersionResource{ {Group: api.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource}, + {Group: autoscaling.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource}, {Group: extensions.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource}, {Group: federation.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource}, }, KindPriority: []unversioned.GroupVersionKind{ {Group: api.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind}, + {Group: autoscaling.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind}, {Group: extensions.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind}, {Group: federation.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind}, },