diff --git a/api/v1alpha1/flowcollector_types.go b/api/v1alpha1/flowcollector_types.go index aa3d984da..701d885d7 100644 --- a/api/v1alpha1/flowcollector_types.go +++ b/api/v1alpha1/flowcollector_types.go @@ -346,7 +346,7 @@ type FlowCollectorFLP struct { // kafkaConsumerAutoscaler spec of a horizontal pod autoscaler to set up for flowlogs-pipeline-transformer, which consumes Kafka messages. // This setting is ignored when Kafka is disabled. // +optional - KafkaConsumerAutoscaler *FlowCollectorHPA `json:"kafkaConsumerAutoscaler,omitempty"` + KafkaConsumerAutoscaler FlowCollectorHPA `json:"kafkaConsumerAutoscaler,omitempty"` //+kubebuilder:default:=1000 // +optional @@ -366,7 +366,19 @@ type FlowCollectorFLP struct { Env map[string]string `json:"env,omitempty"` } +const ( + HPAStatusDisabled = "DISABLED" + HPAStatusEnabled = "ENABLED" +) + type FlowCollectorHPA struct { + // +kubebuilder:validation:Enum:=DISABLED;ENABLED + // +kubebuilder:default:=DISABLED + // Status describe the desired status regarding deploying an horizontal pod autoscaler + // DISABLED will not deploy an horizontal pod autoscaler + // ENABLED will deploy an horizontal pod autoscaler + Status string `json:"status,omitempty"` + // minReplicas is the lower limit for the number of replicas to which the autoscaler // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the // alpha feature gate HPAScaleToZero is enabled and at least one Object or External @@ -375,12 +387,22 @@ type FlowCollectorHPA struct { // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + // +kubebuilder:default:=3 + // +optional MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` // metrics used by the pod autoscaler // +optional Metrics []ascv2.MetricSpec `json:"metrics"` } +func (spec *FlowCollectorHPA) Disabled() bool { + return spec.Status == HPAStatusDisabled +} + +func (spec *FlowCollectorHPA) Enabled() bool { + return spec.Status == HPAStatusEnabled +} + const ( LokiAuthDisabled = "DISABLED" LokiAuthUseHostToken = "HOST" @@ -510,7 +532,7 @@ type FlowCollectorConsolePlugin struct { // autoscaler spec of a horizontal pod autoscaler to set up for the plugin Deployment. // +optional - Autoscaler *FlowCollectorHPA `json:"autoscaler,omitempty"` + Autoscaler FlowCollectorHPA `json:"autoscaler,omitempty"` //+kubebuilder:default:={enable:true} // portNaming defines the configuration of the port-to-service name translation diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 064bed80a..5bd9dc81e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -165,11 +165,7 @@ func (in *FlowCollectorAgent) DeepCopy() *FlowCollectorAgent { func (in *FlowCollectorConsolePlugin) DeepCopyInto(out *FlowCollectorConsolePlugin) { *out = *in in.Resources.DeepCopyInto(&out.Resources) - if in.Autoscaler != nil { - in, out := &in.Autoscaler, &out.Autoscaler - *out = new(FlowCollectorHPA) - (*in).DeepCopyInto(*out) - } + in.Autoscaler.DeepCopyInto(&out.Autoscaler) in.PortNaming.DeepCopyInto(&out.PortNaming) } @@ -226,11 +222,7 @@ func (in *FlowCollectorFLP) DeepCopyInto(out *FlowCollectorFLP) { *out = *in in.Metrics.DeepCopyInto(&out.Metrics) in.Resources.DeepCopyInto(&out.Resources) - if in.KafkaConsumerAutoscaler != nil { - in, out := &in.KafkaConsumerAutoscaler, &out.KafkaConsumerAutoscaler - *out = new(FlowCollectorHPA) - (*in).DeepCopyInto(*out) - } + in.KafkaConsumerAutoscaler.DeepCopyInto(&out.KafkaConsumerAutoscaler) if in.Env != nil { in, out := &in.Env, &out.Env *out = make(map[string]string, len(*in)) diff --git a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml index 705669032..f81fbdab1 100644 --- a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml +++ b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml @@ -278,6 +278,7 @@ spec: set up for the plugin Deployment. properties: maxReplicas: + default: 3 description: maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. @@ -790,8 +791,16 @@ spec: active as long as at least one metric value is available. format: int32 type: integer - required: - - maxReplicas + status: + default: DISABLED + description: Status describe the desired status regarding + deploying an horizontal pod autoscaler DISABLED will not + deploy an horizontal pod autoscaler ENABLED will deploy + an horizontal pod autoscaler + enum: + - DISABLED + - ENABLED + type: string type: object image: default: quay.io/netobserv/network-observability-console-plugin:main @@ -1189,6 +1198,7 @@ spec: is disabled. properties: maxReplicas: + default: 3 description: maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. @@ -1701,8 +1711,16 @@ spec: active as long as at least one metric value is available. format: int32 type: integer - required: - - maxReplicas + status: + default: DISABLED + description: Status describe the desired status regarding + deploying an horizontal pod autoscaler DISABLED will not + deploy an horizontal pod autoscaler ENABLED will deploy + an horizontal pod autoscaler + enum: + - DISABLED + - ENABLED + type: string type: object kafkaConsumerBatchSize: default: 10485760 diff --git a/config/samples/flows_v1alpha1_flowcollector.yaml b/config/samples/flows_v1alpha1_flowcollector.yaml index ce537eb32..2e78f866e 100644 --- a/config/samples/flows_v1alpha1_flowcollector.yaml +++ b/config/samples/flows_v1alpha1_flowcollector.yaml @@ -94,7 +94,17 @@ spec: imagePullPolicy: IfNotPresent port: 9001 logLevel: info - autoscaler: null + autoscaler: + status: DISABLED + minReplicas: 1 + maxReplicas: 3 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 portNaming: enable: true portNames: diff --git a/controllers/consoleplugin/consoleplugin_reconciler.go b/controllers/consoleplugin/consoleplugin_reconciler.go index a404d311a..817ae3a13 100644 --- a/controllers/consoleplugin/consoleplugin_reconciler.go +++ b/controllers/consoleplugin/consoleplugin_reconciler.go @@ -201,7 +201,7 @@ func (r *CPReconciler) reconcileService(ctx context.Context, builder builder, de func (r *CPReconciler) reconcileHPA(ctx context.Context, builder builder, desired *flowsv1alpha1.FlowCollectorSpec, ns string) error { // Delete or Create / Update Autoscaler according to HPA option - if desired.ConsolePlugin.Autoscaler == nil { + if desired.ConsolePlugin.Autoscaler.Disabled() { r.nobjMngr.TryDelete(ctx, r.owned.hpa) } else { newASC := builder.autoScaler() @@ -229,7 +229,7 @@ func deploymentNeedsUpdate(depl *appsv1.Deployment, desired *flowsv1alpha1.FlowC } return containerNeedsUpdate(&depl.Spec.Template.Spec, &desired.ConsolePlugin, &desired.Loki) || configChanged(&depl.Spec.Template, cmDigest) || - (desired.ConsolePlugin.Autoscaler == nil && *depl.Spec.Replicas != desired.ConsolePlugin.Replicas) + (desired.ConsolePlugin.Autoscaler.Disabled() && *depl.Spec.Replicas != desired.ConsolePlugin.Replicas) } func configChanged(tmpl *corev1.PodTemplateSpec, cmDigest string) bool { diff --git a/controllers/consoleplugin/consoleplugin_test.go b/controllers/consoleplugin/consoleplugin_test.go index 48a79cdb0..526797859 100644 --- a/controllers/consoleplugin/consoleplugin_test.go +++ b/controllers/consoleplugin/consoleplugin_test.go @@ -43,7 +43,8 @@ func getPluginConfig() flowsv1alpha1.FlowCollectorConsolePlugin { Image: testImage, ImagePullPolicy: string(testPullPolicy), Resources: testResources, - Autoscaler: &flowsv1alpha1.FlowCollectorHPA{ + Autoscaler: flowsv1alpha1.FlowCollectorHPA{ + Status: flowsv1alpha1.HPAStatusEnabled, MinReplicas: &minReplicas, MaxReplicas: maxReplicas, Metrics: []ascv2.MetricSpec{{ diff --git a/controllers/flowcollector_controller_console_test.go b/controllers/flowcollector_controller_console_test.go index d9cafc1bb..b203fa729 100644 --- a/controllers/flowcollector_controller_console_test.go +++ b/controllers/flowcollector_controller_console_test.go @@ -78,7 +78,8 @@ func flowCollectorConsolePluginSpecs() { ImagePullPolicy: "Never", Image: "testimg:latest", Register: true, - Autoscaler: &flowsv1alpha1.FlowCollectorHPA{ + Autoscaler: flowsv1alpha1.FlowCollectorHPA{ + Status: flowsv1alpha1.HPAStatusEnabled, MinReplicas: pointer.Int32(1), MaxReplicas: 1, Metrics: []ascv2.MetricSpec{{ @@ -152,7 +153,7 @@ func flowCollectorConsolePluginSpecs() { } fc.Spec.ConsolePlugin.Port = 9099 fc.Spec.ConsolePlugin.Replicas = 2 - fc.Spec.ConsolePlugin.Autoscaler = nil + fc.Spec.ConsolePlugin.Autoscaler.Status = flowsv1alpha1.HPAStatusDisabled return k8sClient.Update(ctx, &fc) }).Should(Succeed()) diff --git a/controllers/flowcollector_controller_test.go b/controllers/flowcollector_controller_test.go index 3e168524b..459a1c70c 100644 --- a/controllers/flowcollector_controller_test.go +++ b/controllers/flowcollector_controller_test.go @@ -381,7 +381,8 @@ func flowCollectorControllerSpecs() { hpa := ascv2.HorizontalPodAutoscaler{} It("Should update with HPA", func() { UpdateCR(crKey, func(fc *flowsv1alpha1.FlowCollector) { - fc.Spec.Processor.KafkaConsumerAutoscaler = &flowsv1alpha1.FlowCollectorHPA{ + fc.Spec.Processor.KafkaConsumerAutoscaler = flowsv1alpha1.FlowCollectorHPA{ + Status: flowsv1alpha1.HPAStatusEnabled, MinReplicas: pointer.Int32(1), MaxReplicas: 1, Metrics: []ascv2.MetricSpec{{ diff --git a/controllers/flowlogspipeline/flp_test.go b/controllers/flowlogspipeline/flp_test.go index 7fa663038..b6b34754a 100644 --- a/controllers/flowlogspipeline/flp_test.go +++ b/controllers/flowlogspipeline/flp_test.go @@ -66,7 +66,8 @@ func getConfig() v1alpha1.FlowCollectorSpec { }, }, KafkaConsumerReplicas: 1, - KafkaConsumerAutoscaler: &v1alpha1.FlowCollectorHPA{ + KafkaConsumerAutoscaler: v1alpha1.FlowCollectorHPA{ + Status: v1alpha1.HPAStatusEnabled, MinReplicas: &minReplicas, MaxReplicas: maxReplicas, Metrics: []ascv2.MetricSpec{{ @@ -105,7 +106,7 @@ func getConfig() v1alpha1.FlowCollectorSpec { func getConfigNoHPA() v1alpha1.FlowCollectorSpec { cfg := getConfig() - cfg.Processor.KafkaConsumerAutoscaler = nil + cfg.Processor.KafkaConsumerAutoscaler.Status = v1alpha1.HPAStatusDisabled return cfg } @@ -134,7 +135,7 @@ func getAutoScalerSpecs() (ascv2.HorizontalPodAutoscaler, v1alpha1.FlowCollector }, } - return autoScaler, *getConfig().Processor.KafkaConsumerAutoscaler + return autoScaler, getConfig().Processor.KafkaConsumerAutoscaler } func TestDaemonSetNoChange(t *testing.T) { @@ -399,27 +400,27 @@ func TestAutoScalerUpdateCheck(t *testing.T) { //equals specs autoScalerSpec, hpa := getAutoScalerSpecs() - assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, &hpa, testNamespace), false) + assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, hpa, testNamespace), false) //wrong max replicas autoScalerSpec, hpa = getAutoScalerSpecs() autoScalerSpec.Spec.MaxReplicas = 10 - assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, &hpa, testNamespace), true) + assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, hpa, testNamespace), true) //missing min replicas autoScalerSpec, hpa = getAutoScalerSpecs() autoScalerSpec.Spec.MinReplicas = nil - assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, &hpa, testNamespace), true) + assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, hpa, testNamespace), true) //missing metrics autoScalerSpec, hpa = getAutoScalerSpecs() autoScalerSpec.Spec.Metrics = []ascv2.MetricSpec{} - assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, &hpa, testNamespace), true) + assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, hpa, testNamespace), true) //wrong namespace autoScalerSpec, hpa = getAutoScalerSpecs() autoScalerSpec.Namespace = "NewNamespace" - assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, &hpa, testNamespace), true) + assert.Equal(autoScalerNeedsUpdate(&autoScalerSpec, hpa, testNamespace), true) } func TestLabels(t *testing.T) { diff --git a/controllers/flowlogspipeline/flp_transfo_reconciler.go b/controllers/flowlogspipeline/flp_transfo_reconciler.go index 0977c9232..d3af2ce58 100644 --- a/controllers/flowlogspipeline/flp_transfo_reconciler.go +++ b/controllers/flowlogspipeline/flp_transfo_reconciler.go @@ -137,7 +137,7 @@ func (r *flpTransformerReconciler) reconcileDeployment(ctx context.Context, desi } // Delete or Create / Update Autoscaler according to HPA option - if desiredFLP.KafkaConsumerAutoscaler == nil { + if desiredFLP.KafkaConsumerAutoscaler.Disabled() { r.nobjMngr.TryDelete(ctx, r.owned.hpa) } else { newASC := builder.autoScaler() @@ -182,10 +182,10 @@ func (r *flpTransformerReconciler) reconcilePermissions(ctx context.Context, bui func deploymentNeedsUpdate(depl *appsv1.Deployment, desired *flpSpec, configDigest string) bool { return containerNeedsUpdate(&depl.Spec.Template.Spec, desired, false) || configChanged(&depl.Spec.Template, configDigest) || - (desired.KafkaConsumerAutoscaler == nil && *depl.Spec.Replicas != desired.KafkaConsumerReplicas) + (desired.KafkaConsumerAutoscaler.Disabled() && *depl.Spec.Replicas != desired.KafkaConsumerReplicas) } -func autoScalerNeedsUpdate(asc *ascv2.HorizontalPodAutoscaler, desired *flowsv1alpha1.FlowCollectorHPA, ns string) bool { +func autoScalerNeedsUpdate(asc *ascv2.HorizontalPodAutoscaler, desired flowsv1alpha1.FlowCollectorHPA, ns string) bool { if asc.Namespace != ns { return true } diff --git a/docs/FlowCollector.md b/docs/FlowCollector.md index 747f1d88c..cf6d57c74 100644 --- a/docs/FlowCollector.md +++ b/docs/FlowCollector.md @@ -626,8 +626,9 @@ autoscaler spec of a horizontal pod autoscaler to set up for the plugin Deployme maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.

Format: int32
+ Default: 3
- true + false metrics []object @@ -644,6 +645,16 @@ autoscaler spec of a horizontal pod autoscaler to set up for the plugin Deployme Format: int32
false + + status + enum + + Status describe the desired status regarding deploying an horizontal pod autoscaler DISABLED will not deploy an horizontal pod autoscaler ENABLED will deploy an horizontal pod autoscaler
+
+ Enum: DISABLED, ENABLED
+ Default: DISABLED
+ + false @@ -2251,8 +2262,9 @@ kafkaConsumerAutoscaler spec of a horizontal pod autoscaler to set up for flowlo maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.

Format: int32
+ Default: 3
- true + false metrics []object @@ -2269,6 +2281,16 @@ kafkaConsumerAutoscaler spec of a horizontal pod autoscaler to set up for flowlo Format: int32
false + + status + enum + + Status describe the desired status regarding deploying an horizontal pod autoscaler DISABLED will not deploy an horizontal pod autoscaler ENABLED will deploy an horizontal pod autoscaler
+
+ Enum: DISABLED, ENABLED
+ Default: DISABLED
+ + false