From 071d0833301be66a08a611beb279d398402575c1 Mon Sep 17 00:00:00 2001 From: Luca Kuendig Date: Tue, 31 Jan 2023 10:43:01 +0100 Subject: [PATCH] add replicas.idle to set idleReplicaCount on SO Signed-off-by: Luca Kuendig --- config/crd/bases/http.keda.sh_httpscaledobjects.yaml | 8 ++++++++ e2e/k8s.go | 1 + examples/xkcd/templates/httpscaledobject.yaml | 1 + examples/xkcd/values.yaml | 1 + operator/api/v1alpha1/httpscaledobject_types.go | 3 +++ operator/controllers/scaled_object.go | 3 ++- operator/controllers/scaled_object_test.go | 11 ++++++++++- operator/controllers/suite_test.go | 5 +++-- pkg/k8s/scaledobject.go | 2 ++ pkg/k8s/templates/scaledobject.yaml | 1 + 10 files changed, 32 insertions(+), 4 deletions(-) diff --git a/config/crd/bases/http.keda.sh_httpscaledobjects.yaml b/config/crd/bases/http.keda.sh_httpscaledobjects.yaml index ac8064598..094cc1453 100644 --- a/config/crd/bases/http.keda.sh_httpscaledobjects.yaml +++ b/config/crd/bases/http.keda.sh_httpscaledobjects.yaml @@ -33,6 +33,9 @@ spec: - jsonPath: .spec.replicas.max name: MaxReplicas type: integer + - jsonPath: .spec.replicas.idle + name: IdleReplicas + type: integer - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -66,6 +69,11 @@ spec: replicas: description: (optional) Replica information properties: + idle: + description: Amount of replicas to have in the deployment while + being idle + format: int32 + type: integer max: description: Maximum amount of replicas to have in the deployment (Default 100) diff --git a/e2e/k8s.go b/e2e/k8s.go index 7657193c4..56e2c61d2 100644 --- a/e2e/k8s.go +++ b/e2e/k8s.go @@ -46,6 +46,7 @@ func getScaledObject( "", 1, 2, + 0, 30, ) if err != nil { diff --git a/examples/xkcd/templates/httpscaledobject.yaml b/examples/xkcd/templates/httpscaledobject.yaml index 613280ee3..c5a8547e7 100644 --- a/examples/xkcd/templates/httpscaledobject.yaml +++ b/examples/xkcd/templates/httpscaledobject.yaml @@ -12,3 +12,4 @@ spec: replicas: min: {{ .Values.autoscaling.http.minReplicas }} max: {{ .Values.autoscaling.http.maxReplicas }} + idle: {{ .Values.autoscaling.http.idleReplicas }} diff --git a/examples/xkcd/values.yaml b/examples/xkcd/values.yaml index 716eb9db3..8aefe659e 100644 --- a/examples/xkcd/values.yaml +++ b/examples/xkcd/values.yaml @@ -46,3 +46,4 @@ autoscaling: http: minReplicas: 0 maxReplicas: 10 + idleReplicas: 0 diff --git a/operator/api/v1alpha1/httpscaledobject_types.go b/operator/api/v1alpha1/httpscaledobject_types.go index 7c3aa45f4..cb7f3c174 100644 --- a/operator/api/v1alpha1/httpscaledobject_types.go +++ b/operator/api/v1alpha1/httpscaledobject_types.go @@ -84,6 +84,8 @@ type ReplicaStruct struct { Min int32 `json:"min,omitempty" description:"Minimum amount of replicas to have in the deployment (Default 0)"` // Maximum amount of replicas to have in the deployment (Default 100) Max int32 `json:"max,omitempty" description:"Maximum amount of replicas to have in the deployment (Default 100)"` + // Amount of replicas to have in the deployment while being idle + Idle int32 `json:"idle,omitempty" description:"Amount of replicas to have in the deployment while being idle"` } // HTTPScaledObjectSpec defines the desired state of HTTPScaledObject @@ -133,6 +135,7 @@ type HTTPScaledObjectStatus struct { // +kubebuilder:printcolumn:name="ScaleTargetPort",type="integer",JSONPath=".spec.scaleTargetRef" // +kubebuilder:printcolumn:name="MinReplicas",type="integer",JSONPath=".spec.replicas.min" // +kubebuilder:printcolumn:name="MaxReplicas",type="integer",JSONPath=".spec.replicas.max" +// +kubebuilder:printcolumn:name="IdleReplicas",type="integer",JSONPath=".spec.replicas.idle" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" // +kubebuilder:printcolumn:name="Active",type="string",JSONPath=".status.conditions[?(@.type==\"HTTPScaledObjectIsReady\")].status" diff --git a/operator/controllers/scaled_object.go b/operator/controllers/scaled_object.go index b3eb82597..2f1c635fa 100644 --- a/operator/controllers/scaled_object.go +++ b/operator/controllers/scaled_object.go @@ -25,7 +25,7 @@ func createOrUpdateScaledObject( httpso *v1alpha1.HTTPScaledObject, ) error { logger.Info("Creating scaled objects", "external scaler host name", externalScalerHostName) - + logger.Info("This is the current httpso object", "output", httpso.Spec) appScaledObject, appErr := k8s.NewScaledObject( httpso.GetNamespace(), fmt.Sprintf("%s-app", httpso.GetName()), // HTTPScaledObject name is the same as the ScaledObject name @@ -34,6 +34,7 @@ func createOrUpdateScaledObject( httpso.Spec.Host, httpso.Spec.Replicas.Min, httpso.Spec.Replicas.Max, + httpso.Spec.Replicas.Idle, httpso.Spec.CooldownPeriod, ) if appErr != nil { diff --git a/operator/controllers/scaled_object_test.go b/operator/controllers/scaled_object_test.go index a3b6fcba8..2204f35b4 100644 --- a/operator/controllers/scaled_object_test.go +++ b/operator/controllers/scaled_object_test.go @@ -60,7 +60,7 @@ func TestCreateOrUpdateScaledObject(t *testing.T) { metadata["name"], ) - // HTTPScaledObject min/max replicas are int32s, + // HTTPScaledObject min/max/idle replicas are int32s, // but the ScaledObject's spec is decoded into // an *unsructured.Unstructured (basically a map[string]interface{}) // which is an int64. we need to convert the @@ -73,11 +73,16 @@ func TestCreateOrUpdateScaledObject(t *testing.T) { int64(testInfra.httpso.Spec.Replicas.Max), spec["maxReplicaCount"], ) + r.Equal( + int64(testInfra.httpso.Spec.Replicas.Idle), + spec["idleReplicaCount"], + ) // now update the min and max replicas on the httpso // and call createOrUpdateScaledObject again testInfra.httpso.Spec.Replicas.Min++ testInfra.httpso.Spec.Replicas.Max++ + testInfra.httpso.Spec.Replicas.Idle++ r.NoError(createOrUpdateScaledObject( testInfra.ctx, testInfra.cl, @@ -104,6 +109,10 @@ func TestCreateOrUpdateScaledObject(t *testing.T) { int64(testInfra.httpso.Spec.Replicas.Max), spec["maxReplicaCount"], ) + r.Equal( + int64(testInfra.httpso.Spec.Replicas.Idle), + spec["idleReplicaCount"], + ) } func getSO( diff --git a/operator/controllers/suite_test.go b/operator/controllers/suite_test.go index deded4b74..dd6eafa57 100644 --- a/operator/controllers/suite_test.go +++ b/operator/controllers/suite_test.go @@ -72,8 +72,9 @@ func newCommonTestInfra(namespace, appName string) *commonTestInfra { Port: 8081, }, Replicas: v1alpha1.ReplicaStruct{ - Min: 0, - Max: 20, + Min: 0, + Max: 20, + Idle: 0, }, }, } diff --git a/pkg/k8s/scaledobject.go b/pkg/k8s/scaledobject.go index e10154a05..bc917ae95 100644 --- a/pkg/k8s/scaledobject.go +++ b/pkg/k8s/scaledobject.go @@ -53,6 +53,7 @@ func NewScaledObject( host string, minReplicas, maxReplicas int32, + idleReplicas int32, cooldownPeriod int32, ) (*unstructured.Unstructured, error) { // https://keda.sh/docs/1.5/faq/ @@ -79,6 +80,7 @@ func NewScaledObject( "Labels": labels, "MinReplicas": minReplicas, "MaxReplicas": maxReplicas, + "IdleReplicas": idleReplicas, "DeploymentName": deploymentName, "ScalerAddress": scalerAddress, "Host": host, diff --git a/pkg/k8s/templates/scaledobject.yaml b/pkg/k8s/templates/scaledobject.yaml index c379449b0..080d69d90 100644 --- a/pkg/k8s/templates/scaledobject.yaml +++ b/pkg/k8s/templates/scaledobject.yaml @@ -10,6 +10,7 @@ metadata: spec: minReplicaCount: {{ .MinReplicas }} maxReplicaCount: {{ .MaxReplicas }} + idleReplicaCount: {{ .IdleReplicas }} cooldownPeriod: {{ .CooldownPeriod }} pollingInterval: 1 scaleTargetRef: