From f99de41c265b689f106e714d11a69896df99f0e6 Mon Sep 17 00:00:00 2001 From: laminar Date: Mon, 19 Dec 2022 18:13:39 +0800 Subject: [PATCH] add exclusivity to the BuiltinHPARule Signed-off-by: laminar --- api/compute/v1alpha1/function_webhook.go | 5 +++++ api/compute/v1alpha1/validate.go | 22 +++++++++++++++++++ controllers/function_controller_test.go | 2 +- controllers/spec/hpa.go | 28 ++++++++++++++++-------- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/api/compute/v1alpha1/function_webhook.go b/api/compute/v1alpha1/function_webhook.go index b2107fb6a..691f6ae95 100644 --- a/api/compute/v1alpha1/function_webhook.go +++ b/api/compute/v1alpha1/function_webhook.go @@ -276,6 +276,11 @@ func (r *Function) ValidateCreate() error { allErrs = append(allErrs, fieldErr) } + fieldErr = validateBuiltinHPARules(r.Spec.Pod.BuiltinAutoscaler) + if fieldErr != nil { + allErrs = append(allErrs, fieldErr) + } + if len(allErrs) == 0 { return nil } diff --git a/api/compute/v1alpha1/validate.go b/api/compute/v1alpha1/validate.go index dab9073fb..13d0e1bbc 100644 --- a/api/compute/v1alpha1/validate.go +++ b/api/compute/v1alpha1/validate.go @@ -396,3 +396,25 @@ func validateMessaging(messaging *Messaging) *field.Error { } return nil } + +func validateBuiltinHPARules(rules []BuiltinHPARule) *field.Error { + isCPURuleExists := false + isMemoryRuleExists := false + for _, rule := range rules { + switch rule { + case AverageUtilizationCPUPercent20, AverageUtilizationCPUPercent50, AverageUtilizationCPUPercent80: + if isCPURuleExists { + return field.Invalid(field.NewPath("spec").Child("pod", "builtinAutoscaler"), rules, + "Duplicate CPU autoscaler metrics are set") + } + isCPURuleExists = true + case AverageUtilizationMemoryPercent20, AverageUtilizationMemoryPercent50, AverageUtilizationMemoryPercent80: + if isMemoryRuleExists { + return field.Invalid(field.NewPath("spec").Child("pod", "builtinAutoscaler"), rules, + "Duplicate Memory autoscaler metrics are set") + } + isMemoryRuleExists = true + } + } + return nil +} diff --git a/controllers/function_controller_test.go b/controllers/function_controller_test.go index 37fbc56a1..92730ed2a 100644 --- a/controllers/function_controller_test.go +++ b/controllers/function_controller_test.go @@ -286,7 +286,7 @@ func createFunction(function *v1alpha1.Function) { if len(function.Spec.Pod.BuiltinAutoscaler) > 0 { Expect(len(hpa.Spec.Metrics)).Should(Equal(len(function.Spec.Pod.BuiltinAutoscaler))) for _, rule := range function.Spec.Pod.BuiltinAutoscaler { - autoscaler := spec.GetBuiltinAutoScaler(rule) + autoscaler, _ := spec.GetBuiltinAutoScaler(rule) Expect(autoscaler).Should(Not(BeNil())) Expect(hpa.Spec.Metrics).Should(ContainElement(autoscaler.Metrics()[0])) } diff --git a/controllers/spec/hpa.go b/controllers/spec/hpa.go index 6191145cd..dd4f3e92c 100644 --- a/controllers/spec/hpa.go +++ b/controllers/spec/hpa.go @@ -86,22 +86,22 @@ func NewHPARuleAverageUtilizationMemoryPercent(memoryPercentage int32) BuiltinAu } } -func GetBuiltinAutoScaler(builtinRule v1alpha1.BuiltinHPARule) BuiltinAutoScaler { +func GetBuiltinAutoScaler(builtinRule v1alpha1.BuiltinHPARule) (BuiltinAutoScaler, int) { switch builtinRule { case v1alpha1.AverageUtilizationCPUPercent80: - return NewHPARuleAverageUtilizationCPUPercent(80) + return NewHPARuleAverageUtilizationCPUPercent(80), cpuRuleIdx case v1alpha1.AverageUtilizationCPUPercent50: - return NewHPARuleAverageUtilizationCPUPercent(50) + return NewHPARuleAverageUtilizationCPUPercent(50), cpuRuleIdx case v1alpha1.AverageUtilizationCPUPercent20: - return NewHPARuleAverageUtilizationCPUPercent(20) + return NewHPARuleAverageUtilizationCPUPercent(20), cpuRuleIdx case v1alpha1.AverageUtilizationMemoryPercent80: - return NewHPARuleAverageUtilizationMemoryPercent(80) + return NewHPARuleAverageUtilizationMemoryPercent(80), memoryRuleIdx case v1alpha1.AverageUtilizationMemoryPercent50: - return NewHPARuleAverageUtilizationMemoryPercent(50) + return NewHPARuleAverageUtilizationMemoryPercent(50), memoryRuleIdx case v1alpha1.AverageUtilizationMemoryPercent20: - return NewHPARuleAverageUtilizationMemoryPercent(20) + return NewHPARuleAverageUtilizationMemoryPercent(20), memoryRuleIdx default: - return nil + return nil, 2 } } @@ -126,11 +126,21 @@ func makeDefaultHPA(objectMeta *metav1.ObjectMeta, minReplicas, maxReplicas int3 } } +const ( + cpuRuleIdx = iota + memoryRuleIdx +) + func MakeMetricsFromBuiltinHPARules(builtinRules []v1alpha1.BuiltinHPARule) []autov2beta2.MetricSpec { + isRuleExists := map[int]bool{} metrics := []autov2beta2.MetricSpec{} for _, r := range builtinRules { - s := GetBuiltinAutoScaler(r) + s, idx := GetBuiltinAutoScaler(r) if s != nil { + if isRuleExists[idx] { + continue + } + isRuleExists[idx] = true metrics = append(metrics, s.Metrics()...) } }