From 3e457ea338b4b3e4c04863bb9b47e2d6d9ba9ac2 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Fri, 26 Jun 2020 17:47:12 +0530 Subject: [PATCH 01/12] GA; work to make v1 --- README.md | 12 +- artifacts/crd.yaml | 74 +++++++++ artifacts/deployment-template.yaml | 2 +- artifacts/examples/example-wpa.yaml | 2 +- cmd/workerpodautoscaler/run.go | 6 - hack/install.sh | 7 +- pkg/apis/workerpodautoscaler/v1/doc.go | 5 + .../workerpodautoscaler/v1/get_default.go | 8 + pkg/apis/workerpodautoscaler/v1/register.go | 43 ++++++ pkg/apis/workerpodautoscaler/v1/types.go | 45 ++++++ .../v1/zz_generated.deepcopy.go | 143 ++++++++++++++++++ pkg/apis/workerpodautoscaler/v1alpha1/crd.go | 48 ------ 12 files changed, 332 insertions(+), 63 deletions(-) create mode 100644 artifacts/crd.yaml create mode 100644 pkg/apis/workerpodautoscaler/v1/doc.go create mode 100644 pkg/apis/workerpodautoscaler/v1/get_default.go create mode 100644 pkg/apis/workerpodautoscaler/v1/register.go create mode 100644 pkg/apis/workerpodautoscaler/v1/types.go create mode 100644 pkg/apis/workerpodautoscaler/v1/zz_generated.deepcopy.go delete mode 100644 pkg/apis/workerpodautoscaler/v1alpha1/crd.go diff --git a/README.md b/README.md index 1cc83aa3..0202579c 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,10 @@ spec: Beanstalk's queueURI would be like: `beanstalk://beanstalkDNSName:11300/test-tube` ### WPA Spec documentation: -- **minReplicas**: minimum number of workers you want to run. (mandatory) -- **maxReplicas**: maximum number of workers you want to run. (mandatory) -- **deploymentName**: name of the kubernetes deployment in the same namespace as WPA object. (mandatory) -- **queueURI**: full URL of the queue. (mandatory) +- **minReplicas**: Minimum number of workers you want to run. (mandatory) +- **maxReplicas**: Maximum number of workers you want to run. (mandatory) +- **deploymentName**: Name of the kubernetes deployment in the same namespace as WPA object. (mandatory) +- **queueURI**: Full URL of the queue. (mandatory) - **targetMessagesPerWorker**: Number of jobs in the queue which have not been picked up by the workers. This also used to calculate the desired number of workers. (mandatory) - **secondsToProcessOneJob:**: This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds. (optional, highly recommended, default=0.0 i.e. disabled) - **maxDisruption:** amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity. Using this you can control how fast a scale down can happen. This can be expressed both as an absolute value and a percentage. Explained with the help of some examples: (optional, default is the WPA flag `wpa-default-max-disruption`) @@ -183,11 +183,11 @@ git pull origin master - Build and push the image to `hub.docker.com/practodev`. Note: practodev push access is required. ``` git fetch --tags -git tag v1.0.0-beta +git tag v1.0.0 make push ``` -- Create a Release in Github. Refer this https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0-beta and create a release. Release should contain the Changelog information of all the issues and pull request after the last release. +- Create a Release in Github. Refer this https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0 and create a release. Release should contain the Changelog information of all the issues and pull request after the last release. - Publish the release in Github 🎉 diff --git a/artifacts/crd.yaml b/artifacts/crd.yaml new file mode 100644 index 00000000..0610a7c6 --- /dev/null +++ b/artifacts/crd.yaml @@ -0,0 +1,74 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workerpodautoscalers.k8s.practo.dev +spec: + conversion: + strategy: None + group: k8s.practo.dev + names: + kind: WorkerPodAutoScaler + listKind: WorkerPodAutoScalerList + plural: workerpodautoscalers + shortNames: + - wpa + - wpas + singular: workerpodautoscaler + preserveUnknownFields: true + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + openAPIV3Schema: + schema: + openAPIV3Schema: + description: WokerPodAutoscaler + properties: + apiVersion: + type: string + kind: + type: string + metadata: + name: string + spec: + properties: + deploymentName: + type: string + description: 'Name of the kubernetes deployment in the same namespace as WPA object' + maxDisruption: + type: + description: 'Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity' + maxReplicas: + type: integer + format: int32 + description: 'Maximum number of workers you want to run' + minReplicas: + type: integer + format: int32 + description: 'Minimum number of workers you want to run' + queueURI: + type: string + description: 'Full URL of the queue' + targetMessagesPerWorker: + type: integer + format: int32 + description: 'Number of jobs in the queue which have not been picked up by the workers. This also used to calculate the desired number of workers' + secondsToProcessOneJob: + type: float + format: float64 + description: 'This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds' + required: + - deploymentName + - maxReplicas + - minReplicas + - queueURI + - targetMessagesPerWorker + required: + - spec + - name: v1alpha1 + served: true + storage: true + storedVersions: + - v1 + - v1alpha1 diff --git a/artifacts/deployment-template.yaml b/artifacts/deployment-template.yaml index de9e5c75..02883bbd 100644 --- a/artifacts/deployment-template.yaml +++ b/artifacts/deployment-template.yaml @@ -28,7 +28,7 @@ spec: value: {{ WPA_AWS_ACCESS_KEY_ID }} - name: AWS_SECRET_ACCESS_KEY value: {{ WPA_AWS_SECRET_ACCESS_KEY }} - image: practodev/workerpodautoscaler:v1.0.0-beta + image: practodev/workerpodautoscaler:v1.0.0 imagePullPolicy: Always command: - /workerpodautoscaler diff --git a/artifacts/examples/example-wpa.yaml b/artifacts/examples/example-wpa.yaml index cb92fd22..992ad0c5 100644 --- a/artifacts/examples/example-wpa.yaml +++ b/artifacts/examples/example-wpa.yaml @@ -1,4 +1,4 @@ -apiVersion: k8s.practo.dev/v1alpha1 +apiVersion: k8s.practo.dev/v1 kind: WorkerPodAutoScaler metadata: name: example-wpa diff --git a/cmd/workerpodautoscaler/run.go b/cmd/workerpodautoscaler/run.go index 585ee3f8..00afc9b4 100644 --- a/cmd/workerpodautoscaler/run.go +++ b/cmd/workerpodautoscaler/run.go @@ -14,7 +14,6 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1alpha1" "github.com/practo/k8s-worker-pod-autoscaler/pkg/cmdutil" "github.com/practo/k8s-worker-pod-autoscaler/pkg/signals" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -142,11 +141,6 @@ func (v *runCmd) run(cmd *cobra.Command, args []string) { klog.Fatalf("Error creating api extension client: %s", err.Error()) } - err = v1alpha1.CreateCRD(apiExtensionClient) - if err != nil { - klog.Fatalf("Error creating crd: %s", err.Error()) - } - queues := queue.NewQueues() go queues.Sync(stopCh) diff --git a/hack/install.sh b/hack/install.sh index 2047fcbc..e8e0f1f7 100755 --- a/hack/install.sh +++ b/hack/install.sh @@ -2,6 +2,7 @@ set -e +crd='./artifacts/crd.yaml' serviceaccount='./artifacts/serviceaccount.yaml' clusterrole='./artifacts/clusterrole.yaml' clusterrolebinding='./artifacts/clusterrolebinding.yaml' @@ -21,13 +22,17 @@ if [ -z "${AWS_SECRET_ACCESS_KEY}" ]; then exit 1 fi +echo "Creating CRD..." +kubectl apply -f ${crd} + +echo "Generating Deployment Manifest..." export WPA_AWS_REGIONS="${AWS_REGIONS}" export WPA_AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" export WPA_AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" - cp -f $template_deployment $new_deployment ./hack/generate.sh ${new_deployment} +echo "Applying manifests.." kubectl apply -f ${serviceaccount} kubectl apply -f ${clusterrole} kubectl apply -f ${clusterrolebinding} diff --git a/pkg/apis/workerpodautoscaler/v1/doc.go b/pkg/apis/workerpodautoscaler/v1/doc.go new file mode 100644 index 00000000..55e899fc --- /dev/null +++ b/pkg/apis/workerpodautoscaler/v1/doc.go @@ -0,0 +1,5 @@ +// +k8s:deepcopy-gen=package +// +groupName=k8s.practo.dev + +// Package v1 is the v1 version of the API. +package v1 // import "github.com/practo/k8s-worker-pod-autoscalers/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/apis/workerpodautoscaler/v1/get_default.go b/pkg/apis/workerpodautoscaler/v1/get_default.go new file mode 100644 index 00000000..ffba5e6e --- /dev/null +++ b/pkg/apis/workerpodautoscaler/v1/get_default.go @@ -0,0 +1,8 @@ +package v1 + +func (w *WorkerPodAutoScaler) GetMaxDisruption(defaultDisruption string) *string { + if w.Spec.MaxDisruption == nil { + return &defaultDisruption + } + return w.Spec.MaxDisruption +} diff --git a/pkg/apis/workerpodautoscaler/v1/register.go b/pkg/apis/workerpodautoscaler/v1/register.go new file mode 100644 index 00000000..4529836d --- /dev/null +++ b/pkg/apis/workerpodautoscaler/v1/register.go @@ -0,0 +1,43 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler" +) + +const ( + GroupName = "k8s.practo.dev" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: workerpodautoscaler.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder initializes a scheme builder + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &WorkerPodAutoScaler{}, + &WorkerPodAutoScalerList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/workerpodautoscaler/v1/types.go b/pkg/apis/workerpodautoscaler/v1/types.go new file mode 100644 index 00000000..50ef6046 --- /dev/null +++ b/pkg/apis/workerpodautoscaler/v1/types.go @@ -0,0 +1,45 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkerPodAutoScaler is a specification for a WorkerPodAutoScaler resource +type WorkerPodAutoScaler struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec WorkerPodAutoScalerSpec `json:"spec"` + Status WorkerPodAutoScalerStatus `json:"status"` +} + +// WorkerPodAutoScalerSpec is the spec for a WorkerPodAutoScaler resource +type WorkerPodAutoScalerSpec struct { + MinReplicas *int32 `json:"minReplicas"` + MaxReplicas *int32 `json:"maxReplicas"` + MaxDisruption *string `json:"maxDisruption"` + QueueURI string `json:"queueURI"` + DeploymentName string `json:"deploymentName"` + TargetMessagesPerWorker *int32 `json:"targetMessagesPerWorker"` + SecondsToProcessOneJob *float64 `json:"secondsToProcessOneJob"` +} + +// WorkerPodAutoScalerStatus is the status for a WorkerPodAutoScaler resource +type WorkerPodAutoScalerStatus struct { + CurrentMessages int32 `json:"CurrentMessages"` + CurrentReplicas int32 `json:"CurrentReplicas"` + DesiredReplicas int32 `json:"DesiredReplicas"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkerPodAutoScalerList is a list of WorkerPodAutoScaler resources +type WorkerPodAutoScalerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []WorkerPodAutoScaler `json:"items"` +} diff --git a/pkg/apis/workerpodautoscaler/v1/zz_generated.deepcopy.go b/pkg/apis/workerpodautoscaler/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000..2fe0c204 --- /dev/null +++ b/pkg/apis/workerpodautoscaler/v1/zz_generated.deepcopy.go @@ -0,0 +1,143 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Practo 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 ( + 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 *WorkerPodAutoScaler) DeepCopyInto(out *WorkerPodAutoScaler) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkerPodAutoScaler. +func (in *WorkerPodAutoScaler) DeepCopy() *WorkerPodAutoScaler { + if in == nil { + return nil + } + out := new(WorkerPodAutoScaler) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkerPodAutoScaler) 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 *WorkerPodAutoScalerList) DeepCopyInto(out *WorkerPodAutoScalerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]WorkerPodAutoScaler, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkerPodAutoScalerList. +func (in *WorkerPodAutoScalerList) DeepCopy() *WorkerPodAutoScalerList { + if in == nil { + return nil + } + out := new(WorkerPodAutoScalerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkerPodAutoScalerList) 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 *WorkerPodAutoScalerSpec) DeepCopyInto(out *WorkerPodAutoScalerSpec) { + *out = *in + if in.MinReplicas != nil { + in, out := &in.MinReplicas, &out.MinReplicas + *out = new(int32) + **out = **in + } + if in.MaxReplicas != nil { + in, out := &in.MaxReplicas, &out.MaxReplicas + *out = new(int32) + **out = **in + } + if in.TargetMessagesPerWorker != nil { + in, out := &in.TargetMessagesPerWorker, &out.TargetMessagesPerWorker + *out = new(int32) + **out = **in + } + if in.MaxDisruption != nil { + in, out := &in.MaxDisruption, &out.MaxDisruption + *out = new(string) + **out = **in + } + if in.SecondsToProcessOneJob != nil { + in, out := &in.SecondsToProcessOneJob, &out.SecondsToProcessOneJob + *out = new(float64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkerPodAutoScalerSpec. +func (in *WorkerPodAutoScalerSpec) DeepCopy() *WorkerPodAutoScalerSpec { + if in == nil { + return nil + } + out := new(WorkerPodAutoScalerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkerPodAutoScalerStatus) DeepCopyInto(out *WorkerPodAutoScalerStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkerPodAutoScalerStatus. +func (in *WorkerPodAutoScalerStatus) DeepCopy() *WorkerPodAutoScalerStatus { + if in == nil { + return nil + } + out := new(WorkerPodAutoScalerStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/workerpodautoscaler/v1alpha1/crd.go b/pkg/apis/workerpodautoscaler/v1alpha1/crd.go deleted file mode 100644 index 8a8e0b9d..00000000 --- a/pkg/apis/workerpodautoscaler/v1alpha1/crd.go +++ /dev/null @@ -1,48 +0,0 @@ -package v1alpha1 - -import ( - "reflect" - - "github.com/practo/klog/v2" - - "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler" - - apiextensionv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - apiextension "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - apierrors "k8s.io/apimachinery/pkg/api/errors" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - CRDShortName string = "wpa" - CRDSingular string = "workerpodautoscaler" - CRDPlural string = "workerpodautoscalers" - - Version string = "v1alpha1" - FullCRDName string = CRDPlural + "." + workerpodautoscaler.GroupName -) - -func CreateCRD(clientset apiextension.Interface) error { - crd := &apiextensionv1beta1.CustomResourceDefinition{ - ObjectMeta: meta_v1.ObjectMeta{Name: FullCRDName}, - Spec: apiextensionv1beta1.CustomResourceDefinitionSpec{ - Group: workerpodautoscaler.GroupName, - Version: Version, - Scope: apiextensionv1beta1.NamespaceScoped, - Names: apiextensionv1beta1.CustomResourceDefinitionNames{ - Singular: CRDSingular, - Plural: CRDPlural, - ShortNames: []string{CRDShortName}, - Kind: reflect.TypeOf(WorkerPodAutoScaler{}).Name(), - }, - }, - } - - _, err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd) - if err != nil && apierrors.IsAlreadyExists(err) { - klog.Infof("CRD %s already exists", CRDPlural) - return nil - } - klog.Infof("Created CRD %s", CRDPlural) - return err -} From b7f4829bd737f7937effb7b908a9377830fcb909 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Fri, 26 Jun 2020 17:59:16 +0530 Subject: [PATCH 02/12] Generate v1 --- .../typed/workerpodautoscaler/v1/doc.go | 20 ++ .../typed/workerpodautoscaler/v1/fake/doc.go | 20 ++ .../v1/fake/fake_workerpodautoscaler.go | 140 +++++++++++++ .../fake/fake_workerpodautoscaler_client.go | 40 ++++ .../v1/generated_expansion.go | 21 ++ .../v1/workerpodautoscaler.go | 191 ++++++++++++++++++ .../v1/workerpodautoscaler_client.go | 89 ++++++++ .../workerpodautoscaler/v1/interface.go | 45 +++++ .../v1/workerpodautoscaler.go | 89 ++++++++ .../v1/expansion_generated.go | 27 +++ .../v1/workerpodautoscaler.go | 94 +++++++++ 11 files changed, 776 insertions(+) create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler_client.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/generated_expansion.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler.go create mode 100644 pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go create mode 100644 pkg/generated/informers/externalversions/workerpodautoscaler/v1/interface.go create mode 100644 pkg/generated/informers/externalversions/workerpodautoscaler/v1/workerpodautoscaler.go create mode 100644 pkg/generated/listers/workerpodautoscaler/v1/expansion_generated.go create mode 100644 pkg/generated/listers/workerpodautoscaler/v1/workerpodautoscaler.go diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/doc.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/doc.go new file mode 100644 index 00000000..1f90027c --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/doc.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/doc.go new file mode 100644 index 00000000..9dab8e84 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler.go new file mode 100644 index 00000000..f1bbdb6a --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +package fake + +import ( + wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeWorkerPodAutoScalers implements WorkerPodAutoScalerInterface +type FakeWorkerPodAutoScalers struct { + Fake *FakeK8sV1 + ns string +} + +var workerpodautoscalersResource = schema.GroupVersionResource{Group: "k8s.practo.dev", Version: "v1", Resource: "workerpodautoscalers"} + +var workerpodautoscalersKind = schema.GroupVersionKind{Group: "k8s.practo.dev", Version: "v1", Kind: "WorkerPodAutoScaler"} + +// Get takes name of the workerPodAutoScaler, and returns the corresponding workerPodAutoScaler object, and an error if there is any. +func (c *FakeWorkerPodAutoScalers) Get(name string, options v1.GetOptions) (result *wpav1.WorkerPodAutoScaler, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(workerpodautoscalersResource, c.ns, name), &wpav1.WorkerPodAutoScaler{}) + + if obj == nil { + return nil, err + } + return obj.(*wpav1.WorkerPodAutoScaler), err +} + +// List takes label and field selectors, and returns the list of WorkerPodAutoScalers that match those selectors. +func (c *FakeWorkerPodAutoScalers) List(opts v1.ListOptions) (result *wpav1.WorkerPodAutoScalerList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(workerpodautoscalersResource, workerpodautoscalersKind, c.ns, opts), &wpav1.WorkerPodAutoScalerList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &wpav1.WorkerPodAutoScalerList{ListMeta: obj.(*wpav1.WorkerPodAutoScalerList).ListMeta} + for _, item := range obj.(*wpav1.WorkerPodAutoScalerList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested workerPodAutoScalers. +func (c *FakeWorkerPodAutoScalers) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(workerpodautoscalersResource, c.ns, opts)) + +} + +// Create takes the representation of a workerPodAutoScaler and creates it. Returns the server's representation of the workerPodAutoScaler, and an error, if there is any. +func (c *FakeWorkerPodAutoScalers) Create(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (result *wpav1.WorkerPodAutoScaler, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(workerpodautoscalersResource, c.ns, workerPodAutoScaler), &wpav1.WorkerPodAutoScaler{}) + + if obj == nil { + return nil, err + } + return obj.(*wpav1.WorkerPodAutoScaler), err +} + +// Update takes the representation of a workerPodAutoScaler and updates it. Returns the server's representation of the workerPodAutoScaler, and an error, if there is any. +func (c *FakeWorkerPodAutoScalers) Update(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (result *wpav1.WorkerPodAutoScaler, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(workerpodautoscalersResource, c.ns, workerPodAutoScaler), &wpav1.WorkerPodAutoScaler{}) + + if obj == nil { + return nil, err + } + return obj.(*wpav1.WorkerPodAutoScaler), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeWorkerPodAutoScalers) UpdateStatus(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (*wpav1.WorkerPodAutoScaler, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(workerpodautoscalersResource, "status", c.ns, workerPodAutoScaler), &wpav1.WorkerPodAutoScaler{}) + + if obj == nil { + return nil, err + } + return obj.(*wpav1.WorkerPodAutoScaler), err +} + +// Delete takes name of the workerPodAutoScaler and deletes it. Returns an error if one occurs. +func (c *FakeWorkerPodAutoScalers) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(workerpodautoscalersResource, c.ns, name), &wpav1.WorkerPodAutoScaler{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeWorkerPodAutoScalers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(workerpodautoscalersResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &wpav1.WorkerPodAutoScalerList{}) + return err +} + +// Patch applies the patch and returns the patched workerPodAutoScaler. +func (c *FakeWorkerPodAutoScalers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *wpav1.WorkerPodAutoScaler, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(workerpodautoscalersResource, c.ns, name, pt, data, subresources...), &wpav1.WorkerPodAutoScaler{}) + + if obj == nil { + return nil, err + } + return obj.(*wpav1.WorkerPodAutoScaler), err +} diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler_client.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler_client.go new file mode 100644 index 00000000..bb395093 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake/fake_workerpodautoscaler_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeK8sV1 struct { + *testing.Fake +} + +func (c *FakeK8sV1) WorkerPodAutoScalers(namespace string) v1.WorkerPodAutoScalerInterface { + return &FakeWorkerPodAutoScalers{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeK8sV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/generated_expansion.go new file mode 100644 index 00000000..e99e3811 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +package v1 + +type WorkerPodAutoScalerExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler.go new file mode 100644 index 00000000..db560520 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + "time" + + wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + scheme "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// WorkerPodAutoScalersGetter has a method to return a WorkerPodAutoScalerInterface. +// A group's client should implement this interface. +type WorkerPodAutoScalersGetter interface { + WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerInterface +} + +// WorkerPodAutoScalerInterface has methods to work with WorkerPodAutoScaler resources. +type WorkerPodAutoScalerInterface interface { + Create(*wpav1.WorkerPodAutoScaler) (*wpav1.WorkerPodAutoScaler, error) + Update(*wpav1.WorkerPodAutoScaler) (*wpav1.WorkerPodAutoScaler, error) + UpdateStatus(*wpav1.WorkerPodAutoScaler) (*wpav1.WorkerPodAutoScaler, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*wpav1.WorkerPodAutoScaler, error) + List(opts v1.ListOptions) (*wpav1.WorkerPodAutoScalerList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *wpav1.WorkerPodAutoScaler, err error) + WorkerPodAutoScalerExpansion +} + +// workerPodAutoScalers implements WorkerPodAutoScalerInterface +type workerPodAutoScalers struct { + client rest.Interface + ns string +} + +// newWorkerPodAutoScalers returns a WorkerPodAutoScalers +func newWorkerPodAutoScalers(c *K8sV1Client, namespace string) *workerPodAutoScalers { + return &workerPodAutoScalers{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the workerPodAutoScaler, and returns the corresponding workerPodAutoScaler object, and an error if there is any. +func (c *workerPodAutoScalers) Get(name string, options v1.GetOptions) (result *wpav1.WorkerPodAutoScaler, err error) { + result = &wpav1.WorkerPodAutoScaler{} + err = c.client.Get(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of WorkerPodAutoScalers that match those selectors. +func (c *workerPodAutoScalers) List(opts v1.ListOptions) (result *wpav1.WorkerPodAutoScalerList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &wpav1.WorkerPodAutoScalerList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested workerPodAutoScalers. +func (c *workerPodAutoScalers) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a workerPodAutoScaler and creates it. Returns the server's representation of the workerPodAutoScaler, and an error, if there is any. +func (c *workerPodAutoScalers) Create(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (result *wpav1.WorkerPodAutoScaler, err error) { + result = &wpav1.WorkerPodAutoScaler{} + err = c.client.Post(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + Body(workerPodAutoScaler). + Do(). + Into(result) + return +} + +// Update takes the representation of a workerPodAutoScaler and updates it. Returns the server's representation of the workerPodAutoScaler, and an error, if there is any. +func (c *workerPodAutoScalers) Update(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (result *wpav1.WorkerPodAutoScaler, err error) { + result = &wpav1.WorkerPodAutoScaler{} + err = c.client.Put(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + Name(workerPodAutoScaler.Name). + Body(workerPodAutoScaler). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *workerPodAutoScalers) UpdateStatus(workerPodAutoScaler *wpav1.WorkerPodAutoScaler) (result *wpav1.WorkerPodAutoScaler, err error) { + result = &wpav1.WorkerPodAutoScaler{} + err = c.client.Put(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + Name(workerPodAutoScaler.Name). + SubResource("status"). + Body(workerPodAutoScaler). + Do(). + Into(result) + return +} + +// Delete takes name of the workerPodAutoScaler and deletes it. Returns an error if one occurs. +func (c *workerPodAutoScalers) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *workerPodAutoScalers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("workerpodautoscalers"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched workerPodAutoScaler. +func (c *workerPodAutoScalers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *wpav1.WorkerPodAutoScaler, err error) { + result = &wpav1.WorkerPodAutoScaler{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("workerpodautoscalers"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go new file mode 100644 index 00000000..241af035 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 Practo 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type K8sV1Interface interface { + RESTClient() rest.Interface + WorkerPodAutoScalersGetter +} + +// K8sV1Client is used to interact with features provided by the k8s.practo.dev group. +type K8sV1Client struct { + restClient rest.Interface +} + +func (c *K8sv1Client) WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerInterface { + return newWorkerPodAutoScalers(c, namespace) +} + +// NewForConfig creates a new K8sV1Client for the given config. +func NewForConfig(c *rest.Config) (*K8sV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &K8sV1Client{client}, nil +} + +// NewForConfigOrDie creates a new K8sV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *K8sV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new K8sV1Client for the given RESTClient. +func New(c rest.Interface) *K8sV1Client { + return &K8sV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := wpav1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *K8sV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/generated/informers/externalversions/workerpodautoscaler/v1/interface.go b/pkg/generated/informers/externalversions/workerpodautoscaler/v1/interface.go new file mode 100644 index 00000000..adace66b --- /dev/null +++ b/pkg/generated/informers/externalversions/workerpodautoscaler/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright 2019 Practo 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // WorkerPodAutoScalers returns a WorkerPodAutoScalerInformer. + WorkerPodAutoScalers() WorkerPodAutoScalerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// WorkerPodAutoScalers returns a WorkerPodAutoScalerInformer. +func (v *version) WorkerPodAutoScalers() WorkerPodAutoScalerInformer { + return &workerPodAutoScalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/informers/externalversions/workerpodautoscaler/v1/workerpodautoscaler.go b/pkg/generated/informers/externalversions/workerpodautoscaler/v1/workerpodautoscaler.go new file mode 100644 index 00000000..b36f0897 --- /dev/null +++ b/pkg/generated/informers/externalversions/workerpodautoscaler/v1/workerpodautoscaler.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 Practo 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + time "time" + + workerpodautoscalerv1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + versioned "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned" + internalinterfaces "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/informers/externalversions/internalinterfaces" + wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/listers/workerpodautoscaler/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// WorkerPodAutoScalerInformer provides access to a shared informer and lister for +// WorkerPodAutoScalers. +type WorkerPodAutoScalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() wpav1.WorkerPodAutoScalerLister +} + +type workerPodAutoScalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewWorkerPodAutoScalerInformer constructs a new informer for WorkerPodAutoScaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewWorkerPodAutoScalerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredWorkerPodAutoScalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredWorkerPodAutoScalerInformer constructs a new informer for WorkerPodAutoScaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredWorkerPodAutoScalerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.K8sV1().WorkerPodAutoScalers(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.K8sV1().WorkerPodAutoScalers(namespace).Watch(options) + }, + }, + &workerpodautoscalerv1.WorkerPodAutoScaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *workerPodAutoScalerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredWorkerPodAutoScalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *workerPodAutoScalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&workerpodautoscalerv1.WorkerPodAutoScaler{}, f.defaultInformer) +} + +func (f *workerPodAutoScalerInformer) Lister() wpav1.WorkerPodAutoScalerLister { + return wpav1.NewWorkerPodAutoScalerLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/listers/workerpodautoscaler/v1/expansion_generated.go b/pkg/generated/listers/workerpodautoscaler/v1/expansion_generated.go new file mode 100644 index 00000000..9febc4e4 --- /dev/null +++ b/pkg/generated/listers/workerpodautoscaler/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright 2019 Practo 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 lister-gen. DO NOT EDIT. + +package v1 + +// WorkerPodAutoScalerListerExpansion allows custom methods to be added to +// WorkerPodAutoScalerLister. +type WorkerPodAutoScalerListerExpansion interface{} + +// WorkerPodAutoScalerNamespaceListerExpansion allows custom methods to be added to +// WorkerPodAutoScalerNamespaceLister. +type WorkerPodAutoScalerNamespaceListerExpansion interface{} diff --git a/pkg/generated/listers/workerpodautoscaler/v1/workerpodautoscaler.go b/pkg/generated/listers/workerpodautoscaler/v1/workerpodautoscaler.go new file mode 100644 index 00000000..1f6dd340 --- /dev/null +++ b/pkg/generated/listers/workerpodautoscaler/v1/workerpodautoscaler.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 Practo 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 lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// WorkerPodAutoScalerLister helps list WorkerPodAutoScalers. +type WorkerPodAutoScalerLister interface { + // List lists all WorkerPodAutoScalers in the indexer. + List(selector labels.Selector) (ret []*v1.WorkerPodAutoScaler, err error) + // WorkerPodAutoScalers returns an object that can list and get WorkerPodAutoScalers. + WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerNamespaceLister + WorkerPodAutoScalerListerExpansion +} + +// workerPodAutoScalerLister implements the WorkerPodAutoScalerLister interface. +type workerPodAutoScalerLister struct { + indexer cache.Indexer +} + +// NewWorkerPodAutoScalerLister returns a new WorkerPodAutoScalerLister. +func NewWorkerPodAutoScalerLister(indexer cache.Indexer) WorkerPodAutoScalerLister { + return &workerPodAutoScalerLister{indexer: indexer} +} + +// List lists all WorkerPodAutoScalers in the indexer. +func (s *workerPodAutoScalerLister) List(selector labels.Selector) (ret []*v1.WorkerPodAutoScaler, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.WorkerPodAutoScaler)) + }) + return ret, err +} + +// WorkerPodAutoScalers returns an object that can list and get WorkerPodAutoScalers. +func (s *workerPodAutoScalerLister) WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerNamespaceLister { + return workerPodAutoScalerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// WorkerPodAutoScalerNamespaceLister helps list and get WorkerPodAutoScalers. +type WorkerPodAutoScalerNamespaceLister interface { + // List lists all WorkerPodAutoScalers in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1.WorkerPodAutoScaler, err error) + // Get retrieves the WorkerPodAutoScaler from the indexer for a given namespace and name. + Get(name string) (*v1.WorkerPodAutoScaler, error) + WorkerPodAutoScalerNamespaceListerExpansion +} + +// workerPodAutoScalerNamespaceLister implements the WorkerPodAutoScalerNamespaceLister +// interface. +type workerPodAutoScalerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all WorkerPodAutoScalers in the indexer for a given namespace. +func (s workerPodAutoScalerNamespaceLister) List(selector labels.Selector) (ret []*v1.WorkerPodAutoScaler, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.WorkerPodAutoScaler)) + }) + return ret, err +} + +// Get retrieves the WorkerPodAutoScaler from the indexer for a given namespace and name. +func (s workerPodAutoScalerNamespaceLister) Get(name string) (*v1.WorkerPodAutoScaler, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("workerpodautoscaler"), name) + } + return obj.(*v1.WorkerPodAutoScaler), nil +} From e5d9df698506fb913602c1e4a5d23edf8b355cb6 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Fri, 26 Jun 2020 20:17:48 +0530 Subject: [PATCH 03/12] Add generate code This time it was not generated but made from v1alpha1 to v1 by making changes manually. --- cmd/workerpodautoscaler/run.go | 6 ------ pkg/generated/clientset/versioned/clientset.go | 8 ++++++++ .../clientset/versioned/fake/clientset_generated.go | 7 +++++++ .../workerpodautoscaler/v1/workerpodautoscaler_client.go | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cmd/workerpodautoscaler/run.go b/cmd/workerpodautoscaler/run.go index 00afc9b4..80f4d288 100644 --- a/cmd/workerpodautoscaler/run.go +++ b/cmd/workerpodautoscaler/run.go @@ -23,7 +23,6 @@ import ( clientset "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned" informers "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/informers/externalversions" queue "github.com/practo/k8s-worker-pod-autoscaler/pkg/queue" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" ) type runCmd struct { @@ -136,11 +135,6 @@ func (v *runCmd) run(cmd *cobra.Command, args []string) { klog.Fatalf("Error building custom clientset: %s", err.Error()) } - apiExtensionClient, err := apiextensionsclient.NewForConfig(cfg) - if err != nil { - klog.Fatalf("Error creating api extension client: %s", err.Error()) - } - queues := queue.NewQueues() go queues.Sync(stopCh) diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index fd946c6c..76b67a23 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -21,6 +21,7 @@ package versioned import ( "fmt" + k8sv1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1" k8sv1alpha1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" @@ -30,6 +31,7 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface K8sV1alpha1() k8sv1alpha1.K8sV1alpha1Interface + K8sV1() k8sv1.K8sV1Interface } // Clientset contains the clients for groups. Each group has exactly one @@ -37,6 +39,7 @@ type Interface interface { type Clientset struct { *discovery.DiscoveryClient k8sV1alpha1 *k8sv1alpha1.K8sV1alpha1Client + k8sV1 *k8sv1.K8sV1Client } // K8sV1alpha1 retrieves the K8sV1alpha1Client @@ -44,6 +47,11 @@ func (c *Clientset) K8sV1alpha1() k8sv1alpha1.K8sV1alpha1Interface { return c.k8sV1alpha1 } +// K8sV1 retrieves the K8sV1Client +func (c *Clientset) K8sV1() k8sv1.K8sV1Interface { + return c.k8sV1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go index 50764c1a..6c9cc9ee 100644 --- a/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -20,6 +20,8 @@ package fake import ( clientset "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned" + k8sv1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1" + fakek8sv1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/fake" k8sv1alpha1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1alpha1" fakek8sv1alpha1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" @@ -80,3 +82,8 @@ var _ clientset.Interface = &Clientset{} func (c *Clientset) K8sV1alpha1() k8sv1alpha1.K8sV1alpha1Interface { return &fakek8sv1alpha1.FakeK8sV1alpha1{Fake: &c.Fake} } + +// K8sV1 retrieves the K8sV1Client +func (c *Clientset) K8sV1() k8sv1.K8sV1Interface { + return &fakek8sv1.FakeK8sV1{Fake: &c.Fake} +} diff --git a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go index 241af035..9f220d7e 100644 --- a/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go +++ b/pkg/generated/clientset/versioned/typed/workerpodautoscaler/v1/workerpodautoscaler_client.go @@ -34,7 +34,7 @@ type K8sV1Client struct { restClient rest.Interface } -func (c *K8sv1Client) WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerInterface { +func (c *K8sV1Client) WorkerPodAutoScalers(namespace string) WorkerPodAutoScalerInterface { return newWorkerPodAutoScalers(c, namespace) } From e7b3559d73868a9ae3d2d2d193cd7c27f9dedc65 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Sat, 27 Jun 2020 16:43:19 +0530 Subject: [PATCH 04/12] Fixes in the OpenAPIV3 schema validations --- artifacts/crd.yaml | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/artifacts/crd.yaml b/artifacts/crd.yaml index 0610a7c6..963c9433 100644 --- a/artifacts/crd.yaml +++ b/artifacts/crd.yaml @@ -20,24 +20,32 @@ spec: - name: v1 served: true storage: true - openAPIV3Schema: - schema: + schema: openAPIV3Schema: - description: WokerPodAutoscaler + type: object + required: + - spec properties: apiVersion: type: string kind: type: string metadata: - name: string + type: object spec: + type: object + required: + - deploymentName + - minReplicas + - maxReplicas + - queueURI + - targetMessagesPerWorker properties: deploymentName: type: string description: 'Name of the kubernetes deployment in the same namespace as WPA object' maxDisruption: - type: + type: string description: 'Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity' maxReplicas: type: integer @@ -55,20 +63,9 @@ spec: format: int32 description: 'Number of jobs in the queue which have not been picked up by the workers. This also used to calculate the desired number of workers' secondsToProcessOneJob: - type: float - format: float64 + type: number + format: float description: 'This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds' - required: - - deploymentName - - maxReplicas - - minReplicas - - queueURI - - targetMessagesPerWorker - required: - - spec - name: v1alpha1 served: true - storage: true - storedVersions: - - v1 - - v1alpha1 + storage: false From 244966d2ef2fb25ffc71c0e82a2ee270f42587f5 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Sun, 28 Jun 2020 12:14:00 +0530 Subject: [PATCH 05/12] Add nullable for the not mandatory flags --- artifacts/crd.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/artifacts/crd.yaml b/artifacts/crd.yaml index 963c9433..8287f435 100644 --- a/artifacts/crd.yaml +++ b/artifacts/crd.yaml @@ -46,6 +46,7 @@ spec: description: 'Name of the kubernetes deployment in the same namespace as WPA object' maxDisruption: type: string + nullable: true description: 'Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity' maxReplicas: type: integer @@ -65,6 +66,7 @@ spec: secondsToProcessOneJob: type: number format: float + nullable: true description: 'This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds' - name: v1alpha1 served: true From fe525e6b5f208b16b9a58ee3ec02c4711df172f5 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Sun, 28 Jun 2020 18:55:14 +0530 Subject: [PATCH 06/12] Updated the README --- README.md | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0202579c..2d522e73 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ Currently the supported Message Queueing Services are: - [AWS SQS](https://aws.amazon.com/sqs/) - [Beanstalkd](https://beanstalkd.github.io/) -There is a plan to integrate other commonly used message queing services. +There is a plan to integrate other commonly used message queuing services. ---- # Install the WorkerPodAutoscaler ### Install -Running the below script will create the WPA [CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and start the controller. The controller watches over all the specified queues in AWS SQS and scales the Kubernetes deployments based on the specification. +Running the below script will create the WPA [CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and install the worker pod autoscaler deployment. ```bash export AWS_REGIONS='ap-south-1,ap-southeast-1' @@ -28,7 +28,7 @@ export AWS_SECRET_ACCESS_KEY='sample-aws-secret-acesss-key' ./hack/install.sh ``` -Note: IAM policy required is [this](artifacts/iam-policy.json). +Note: IAM policy required is [this](artifacts/iam-policy.json), and the AWS credential can be passed as `""` if not using SQS. ### Verify Installation Check the wpa resource is accessible using kubectl @@ -38,7 +38,7 @@ kubectl get wpa ``` # Example -Do install the controller before going with the example. +Do install the wpa crd and wpa deployment before going with the example. (Please check above.) - Create Deployment that needs to scale based on queue length. ```bash @@ -56,7 +56,7 @@ This will start scaling `example-deployment` based on SQS queue length. ## WPA Resource ```yaml -apiVersion: k8s.practo.dev/v1alpha1 +apiVersion: k8s.practo.dev/v1 kind: WorkerPodAutoScaler metadata: name: example-wpa @@ -71,14 +71,19 @@ spec: ``` Beanstalk's queueURI would be like: `beanstalk://beanstalkDNSName:11300/test-tube` -### WPA Spec documentation: -- **minReplicas**: Minimum number of workers you want to run. (mandatory) -- **maxReplicas**: Maximum number of workers you want to run. (mandatory) -- **deploymentName**: Name of the kubernetes deployment in the same namespace as WPA object. (mandatory) -- **queueURI**: Full URL of the queue. (mandatory) -- **targetMessagesPerWorker**: Number of jobs in the queue which have not been picked up by the workers. This also used to calculate the desired number of workers. (mandatory) -- **secondsToProcessOneJob:**: This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds. (optional, highly recommended, default=0.0 i.e. disabled) -- **maxDisruption:** amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity. Using this you can control how fast a scale down can happen. This can be expressed both as an absolute value and a percentage. Explained with the help of some examples: (optional, default is the WPA flag `wpa-default-max-disruption`) +### WPA Spec Documentation: + +| Spec | Description | Mandatory | +| :------------ | :----------- |:------------| +| minReplicas | Minimum number of workers you want to run. | Yes | +| maxReplicas | Maximum number of workers you want to run | Yes | +| deploymentName | Name of the kubernetes deployment in the same namespace as WPA object. | Yes | +| queueURI | Full URL of the queue. | Yes | +| targetMessagesPerWorker | Number of jobs in the queue which have not been picked up by the workers. This is also used to calculate the desired number of workers. | Yes | +| secondsToProcessOneJob | This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds. (highly recommended, default=0.0 i.e. disabled). | No | +| maxDisruption | Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity. Using this you can control how fast a scale down can happen. This can be expressed both as an absolute value and a percentage. (default is the WPA flag `wpa-default-max-disruption`). | No | + +`maxDisruption` explained with the help of some examples: ``` min=2, max=1000, current=500, maxDisruption=50%: then the scale down cannot bring down more than 250 pods in a single scale down activity. ``` @@ -127,7 +132,7 @@ If you need to enable multiple queue support, you can add queues comma separated Running WPA at scale require changes in `--k8s-api-burst` and `--k8s-api-qps` flags. -WPA makes update to Kubernetes API to update the WPA status. WPA uses [client-go](https://github.com/kubernetes/client-go) as the kubernetes client to make Kubernetes API calls. This client allows 5QPS and 10Burst requests to Kubernetes API by default. The defaults can be changed by using `k8s-api-burst` and `k8s-api-qps` flags. +WPA makes call to the Kubernetes API to update the WPA resource status. [client-go](https://github.com/kubernetes/client-go) is used as the kubernetes client to make the Kubernetes API calls. This client allows 5QPS and 10Burst requests to Kubernetes API by default. The defaults can be changed by using `k8s-api-burst` and `k8s-api-qps` flags. You may need to increase the `--k8s-api-qps` and `k8s-api-burst` if [wpa_controller_loop_duration_seconds](https://github.com/practo/k8s-worker-pod-autoscaler/tree/master#wpa-metrics) is greater than 200ms (wpa_controller_loop_duration_seconds>0.200) @@ -199,7 +204,7 @@ kubectl edit deployment -n kube-system workerpodautoscaler ``` ## Contributing -It would be really helpful to add all the major message queuing service providers. This [interface](https://github.com/practo/k8s-worker-pod-autoscaler/blob/master/pkg/queue/queueing_service.go#L5-L14) implementation needs to be written down to make that possible. +It would be really helpful to add all the major message queuing service providers. This [interface](https://github.com/practo/k8s-worker-pod-autoscaler/blob/master/pkg/queue/queue_service.go) implementation needs to be written down to make that possible. - After making code changes, run the below commands to build and run locally. ``` @@ -217,7 +222,7 @@ $ bin/darwin_amd64/workerpodautoscaler run --kube-config /home/user/.kube/config ## Thanks -Thanks to kubernetes team for making [crds](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and [sample controller](https://github.com/kubernetes/sample-controller) +Thanks to kubernetes team for making [crds](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and [sample controller](https://github.com/kubernetes/sample-controller). Thanks for [go-build-template](https://github.com/thockin/go-build-template). [latest-release]: https://github.com/practo/k8s-worker-pod-autoscaler/releases [GoDoc]: https://godoc.org/github.com/practo/k8s-worker-pod-autoscaler From 2fe31e5d1b4b8ab09ead5a72610b5ad16d149165 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Mon, 29 Jun 2020 12:55:27 +0530 Subject: [PATCH 07/12] Changes for backward compatiblity with v1aplha1 and 1.15 k8s cluster --- artifacts/crd.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/artifacts/crd.yaml b/artifacts/crd.yaml index 8287f435..515a3db8 100644 --- a/artifacts/crd.yaml +++ b/artifacts/crd.yaml @@ -1,4 +1,4 @@ -apiVersion: apiextensions.k8s.io/v1 +apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: workerpodautoscalers.k8s.practo.dev @@ -16,6 +16,7 @@ spec: singular: workerpodautoscaler preserveUnknownFields: true scope: Namespaced + versions: v1 versions: - name: v1 served: true From 4de299b3cdb61ec48f2736dd5eea1e0585827bff Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Mon, 29 Jun 2020 16:37:42 +0530 Subject: [PATCH 08/12] PUBLISH tags for major minor version --- Makefile | 23 ++++++++++++++++++----- README.md | 5 +++-- artifacts/deployment-template.yaml | 2 +- hack/install.sh | 4 ++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 0c4df1fb..31f3afed 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,12 @@ UNIQUE:=$(shell date +%s) # Where to push the docker image. REGISTRY := practodev +BASE_BRANCH := master +CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) # This version-strategy uses git tags to set the version string VERSION := $(shell git describe --tags --always --dirty) +MAJOR_MINOR_VERSION = $(shell git describe --tags --dirty | \ + awk -F'.' '{print $$1"."$$2}') # # This version-strategy uses a manual value to set the version string #VERSION := 1.2.3 @@ -30,13 +34,22 @@ ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH)) BASEIMAGE ?= gcr.io/distroless/static IMAGE := $(REGISTRY)/$(BIN) + TAG := $(VERSION) -BETA := v1.0-beta +MAJOR_MINOR_TAG := $(MAJOR_MINOR_VERSION) -ifneq (,$(findstring v1.0,$(TAG))$(findstring -beta,$(TAG))) - PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(BETA) -else - PUBLISH_TAGS := $(IMAGE):$(TAG) +PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION) +ifneq (,$(findstring -beta,$(TAG))) + PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-beta +endif +ifneq (,$(findstring -alpha,$(TAG))) + PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-alpha +endif +ifneq ($(CURRENT_BRANCH), $(BASE_BRANCH)) + PUBLISH_TAGS := $(IMAGE):$(TAG) +endif +ifneq (,$(findstring -dirty,$(TAG))) + PUBLISH_TAGS := $(IMAGE):$(TAG) endif define \n diff --git a/README.md b/README.md index 2d522e73..e32596d6 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Beanstalk's queueURI would be like: `beanstalk://beanstalkDNSName:11300/test-tub | queueURI | Full URL of the queue. | Yes | | targetMessagesPerWorker | Number of jobs in the queue which have not been picked up by the workers. This is also used to calculate the desired number of workers. | Yes | | secondsToProcessOneJob | This metric is useful to calculate the desired number of workers more accurately. It is particularly very useful for workers which have `targetMessagesPerWorker` as always zero. `secondsToProcessOneJob` in the combination with `messagesSentPerMinute`(queue RPM) helps in calculating the minimum workers that is expected to be running to handle `messagesSentPerMinute`(RPM) with every job being processed in `secondsToProcessOneJob` seconds. (highly recommended, default=0.0 i.e. disabled). | No | -| maxDisruption | Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity. Using this you can control how fast a scale down can happen. This can be expressed both as an absolute value and a percentage. (default is the WPA flag `wpa-default-max-disruption`). | No | +| maxDisruption | Amount of disruption that can be tolerated in a single scale down activity. Number of pods or percentage of pods that can scale down in a single down scale down activity. Using this you can control how fast a scale down can happen. This can be expressed both as an absolute value and a percentage. (default is the WPA flag `--wpa-default-max-disruption`). | No | `maxDisruption` explained with the help of some examples: ``` @@ -191,8 +191,9 @@ git fetch --tags git tag v1.0.0 make push ``` +Note: If you are on master branch and there is no dirty commit present(local changes). Then, the `make push` will overwrite the major minor tag everytime. For example, if you are pushing `v1.0.0-beta-70-g47f789d` then `v1.0-beta` will also get overwritten and say if you are pushing `v1.0.0-70-4g7f78d9` then `v1.0` will also get overwritten. It is recommended to use major minor version tag. -- Create a Release in Github. Refer this https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0 and create a release. Release should contain the Changelog information of all the issues and pull request after the last release. +- Create a Release in Github. Refer [this](https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0) and create a release. Release should contain the Changelog information of all the issues and pull request after the last release. - Publish the release in Github 🎉 diff --git a/artifacts/deployment-template.yaml b/artifacts/deployment-template.yaml index 02883bbd..f3105a7a 100644 --- a/artifacts/deployment-template.yaml +++ b/artifacts/deployment-template.yaml @@ -28,7 +28,7 @@ spec: value: {{ WPA_AWS_ACCESS_KEY_ID }} - name: AWS_SECRET_ACCESS_KEY value: {{ WPA_AWS_SECRET_ACCESS_KEY }} - image: practodev/workerpodautoscaler:v1.0.0 + image: practodev/workerpodautoscaler:{{ WPA_TAG }} imagePullPolicy: Always command: - /workerpodautoscaler diff --git a/hack/install.sh b/hack/install.sh index e8e0f1f7..590fe468 100755 --- a/hack/install.sh +++ b/hack/install.sh @@ -29,6 +29,10 @@ echo "Generating Deployment Manifest..." export WPA_AWS_REGIONS="${AWS_REGIONS}" export WPA_AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" export WPA_AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" + +export WPA_TAG=`git describe --tags --dirty | awk -F'.' '{print $1"."$2}'` +echo "Image to be used: practodev/${WPA_TAG}" + cp -f $template_deployment $new_deployment ./hack/generate.sh ${new_deployment} From fcf74c6c84dde3fd506b723550beb8189d3960c5 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Mon, 29 Jun 2020 18:44:14 +0530 Subject: [PATCH 09/12] Publish major version tags --- Makefile | 9 ++++++--- README.md | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 31f3afed..8748db67 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ BASE_BRANCH := master CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) # This version-strategy uses git tags to set the version string VERSION := $(shell git describe --tags --always --dirty) +MAJOR_VERSION = $(shell git describe --tags --dirty | \ + awk -F'.' '{print $$1}') MAJOR_MINOR_VERSION = $(shell git describe --tags --dirty | \ awk -F'.' '{print $$1"."$$2}') # @@ -36,14 +38,15 @@ BASEIMAGE ?= gcr.io/distroless/static IMAGE := $(REGISTRY)/$(BIN) TAG := $(VERSION) +MAJOR_TAG := $(MAJOR_VERSION) MAJOR_MINOR_TAG := $(MAJOR_MINOR_VERSION) -PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION) +PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION) $(IMAGE):$(MAJOR_VERSION) ifneq (,$(findstring -beta,$(TAG))) - PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-beta + PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-beta $(IMAGE):$(MAJOR_VERSION)-beta endif ifneq (,$(findstring -alpha,$(TAG))) - PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-alpha + PUBLISH_TAGS := $(IMAGE):$(TAG) $(IMAGE):$(MAJOR_MINOR_VERSION)-alpha $(IMAGE):$(MAJOR_VERSION)-alpha endif ifneq ($(CURRENT_BRANCH), $(BASE_BRANCH)) PUBLISH_TAGS := $(IMAGE):$(TAG) diff --git a/README.md b/README.md index e32596d6..1a884526 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ git fetch --tags git tag v1.0.0 make push ``` -Note: If you are on master branch and there is no dirty commit present(local changes). Then, the `make push` will overwrite the major minor tag everytime. For example, if you are pushing `v1.0.0-beta-70-g47f789d` then `v1.0-beta` will also get overwritten and say if you are pushing `v1.0.0-70-4g7f78d9` then `v1.0` will also get overwritten. It is recommended to use major minor version tag. +Note: For every tag major and major minor versions tags also available. For example: `v1` and `v1.0` - Create a Release in Github. Refer [this](https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0) and create a release. Release should contain the Changelog information of all the issues and pull request after the last release. From 5af4ec3db1645d288c12030e3d96766d1006e490 Mon Sep 17 00:00:00 2001 From: J Kishore Kumar Date: Mon, 29 Jun 2020 13:19:42 +0000 Subject: [PATCH 10/12] Automatically fetch the latest stable release from Github to install It is better to use a specific release instead of using major-minor version that can result in pods getting updated unintentionally --- hack/install.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hack/install.sh b/hack/install.sh index 590fe468..7ba727df 100755 --- a/hack/install.sh +++ b/hack/install.sh @@ -2,6 +2,12 @@ set -e +if [ $# -eq 0 ]; then + WPA_TAG=`curl -s https://api.github.com/repos/practo/k8s-worker-pod-autoscaler/releases/latest|python -c "import json;import sys;sys.stdout.write(json.load(sys.stdin)['tag_name']+'\n')"` +else + WPA_TAG=$1 +fi + crd='./artifacts/crd.yaml' serviceaccount='./artifacts/serviceaccount.yaml' clusterrole='./artifacts/clusterrole.yaml' @@ -30,7 +36,6 @@ export WPA_AWS_REGIONS="${AWS_REGIONS}" export WPA_AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" export WPA_AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" -export WPA_TAG=`git describe --tags --dirty | awk -F'.' '{print $1"."$2}'` echo "Image to be used: practodev/${WPA_TAG}" cp -f $template_deployment $new_deployment From aa7d099a1030d6b1b1d97e180882b5a5de983e88 Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Wed, 1 Jul 2020 19:12:12 +0530 Subject: [PATCH 11/12] Don't break the script if it is not aws creds are not passed --- README.md | 2 +- hack/install.sh | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/README.md b/README.md index 1a884526..90db3b97 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ export AWS_SECRET_ACCESS_KEY='sample-aws-secret-acesss-key' ./hack/install.sh ``` -Note: IAM policy required is [this](artifacts/iam-policy.json), and the AWS credential can be passed as `""` if not using SQS. +Note: IAM policy required is [this](artifacts/iam-policy.json) ### Verify Installation Check the wpa resource is accessible using kubectl diff --git a/hack/install.sh b/hack/install.sh index 7ba727df..3d6bab9f 100755 --- a/hack/install.sh +++ b/hack/install.sh @@ -15,19 +15,6 @@ clusterrolebinding='./artifacts/clusterrolebinding.yaml' new_deployment='./artifacts/deployment.yaml' template_deployment='./artifacts/deployment-template.yaml' -if [ -z "${AWS_REGIONS}" ]; then - echo "AWS_REGIONS not set in environment, exiting" - exit 1 -fi -if [ -z "${AWS_ACCESS_KEY_ID}" ]; then - echo "AWS_ACCESS_KEY_ID not set in environment, exiting" - exit 1 -fi -if [ -z "${AWS_SECRET_ACCESS_KEY}" ]; then - echo "AWS_SECRET_ACCESS_KEY not set in environment, exiting" - exit 1 -fi - echo "Creating CRD..." kubectl apply -f ${crd} From 6f48bbd6fe61132b6d6472c62a04470570b5d77c Mon Sep 17 00:00:00 2001 From: Alok Kumar Singh Date: Wed, 1 Jul 2020 19:45:38 +0530 Subject: [PATCH 12/12] Upgrade instruction --- README.md | 4 ++++ UPGRADE.md | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 UPGRADE.md diff --git a/README.md b/README.md index 90db3b97..1a5cbc0f 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ Check the wpa resource is accessible using kubectl kubectl get wpa ``` +### Upgrade + +Please follow [this document](UPGRADE.md) for upgrading Worker Pod Autoscaler. + # Example Do install the wpa crd and wpa deployment before going with the example. (Please check above.) diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 00000000..5f47938b --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,18 @@ +# Upgrade Worker Pod Autoscaler + +## Upgrade from v0.2 to v1 + +### Breaking Changes +There is no backward breaking change from `v0.2` to `v1`. + +### Recommended Actions +Update the WorkerPodAutoScaler CRD from `v1alpha1` to `v1` using below: +``` +kubectl apply -f ./artifacts/crd.yaml +``` + +Note: Support for `v1alpha1` CRD version is still there, but it would be discontinued in the future releases. + +### Changes +- [v1.0.0](https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0) +- [v1.0.0-beta](https://github.com/practo/k8s-worker-pod-autoscaler/releases/tag/v1.0.0-beta)