fix EOF, DefaultMaxReplicas set to 3, extended user guide about hpa, more tests

add warning in situations like:
- maxreplicas < minreplicas
- value from label < 0
- validate percentage in cpu, memory metrics
This commit is contained in:
jose luis 2024-04-04 20:18:51 +02:00
parent 516930ccee
commit 8ff0f334eb
No known key found for this signature in database
GPG Key ID: 6D23FAD11F88081A
7 changed files with 368 additions and 90 deletions

View File

@ -472,7 +472,7 @@ services:
kompose.volume.sub-path: pg-data kompose.volume.sub-path: pg-data
``` ```
- `kompose.hpa.replicas.min` defines minimum replicas from Horizontal Pod Autoscaler. Default value 1 [HPA Min Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). - `kompose.hpa.replicas.min` defines the floor for the number of replicas that the HPA can scale down to during a scaling event. Default value is set to 1. This means that, regardless of the load on the system, the HPA will always maintain at least one replica. More info: [HPA Min Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example: For example:
@ -484,7 +484,7 @@ services:
kompose.hpa.replicas.min: 1 kompose.hpa.replicas.min: 1
``` ```
- `kompose.hpa.replicas.max` defines maximum replicas from Horizontal Pod Autoscaler. Default value 10 [HPA Max Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). - `kompose.hpa.replicas.max` defines the upper limit for the number of replicas that the HPA can create during a scaling event. Default value is set to 3. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA Max Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example: For example:
@ -496,7 +496,7 @@ services:
kompose.hpa.replicas.max: 10 kompose.hpa.replicas.max: 10
``` ```
- `kompose.hpa.cpu` defines % cpu utilization trigger scale from Horizontal Pod Autoscaler. It is represented as a percentage of a resource. Default value: 50 [HPA CPU Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). - `kompose.hpa.cpu` defines % cpu utilization that triggers to scale the number of pods. It is represented as a percentage of a resource. Default value is set to 50. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA CPU Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example: For example:
@ -508,7 +508,7 @@ services:
kompose.hpa.cpu: 50 kompose.hpa.cpu: 50
``` ```
- `kompose.hpa.memory` defines memory utilization trigger scale from Horizontal Pod Autoscaler. It is represented as a percentage of a resource. Default value: 70 [HPA Memory Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). - `kompose.hpa.memory` defines memory utilization that triggers to scale the number of pods. It is represented as a percentage of a resource. Default value is set to 70. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA Memory Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example: For example:

View File

@ -52,8 +52,8 @@ import (
// Default values for Horizontal Pod Autoscaler (HPA) // Default values for Horizontal Pod Autoscaler (HPA)
const ( const (
DefaultMinReplicas = 1 DefaultMinReplicas = 1
DefaultMaxReplicas = 10 DefaultMaxReplicas = 3
DefaultCpuUtilization = 50 DefaultCPUUtilization = 50
DefaultMemoryUtilization = 70 DefaultMemoryUtilization = 70
) )
@ -1013,13 +1013,12 @@ func reformatSecretConfigUnderscoreWithDash(secretConfig types.ServiceSecretConf
// searchHPAValues is useful to check if labels // searchHPAValues is useful to check if labels
// contains any labels related to Horizontal Pod Autoscaler // contains any labels related to Horizontal Pod Autoscaler
func searchHPAValues(labels map[string]string) bool { func searchHPAValues(labels map[string]string) bool {
found := true
for _, value := range LabelKeys { for _, value := range LabelKeys {
if _, ok := labels[value]; ok { if _, ok := labels[value]; ok {
return found return true
} }
} }
return !found return false
} }
// createHPAResources creates a HorizontalPodAutoscaler (HPA) resource // createHPAResources creates a HorizontalPodAutoscaler (HPA) resource
@ -1059,23 +1058,39 @@ func getResourceHpaValues(service *kobject.ServiceConfig) HpaValues {
maxReplicas := getHpaValue(service, compose.LabelHpaMaxReplicas, DefaultMaxReplicas) maxReplicas := getHpaValue(service, compose.LabelHpaMaxReplicas, DefaultMaxReplicas)
if maxReplicas < minReplicas { if maxReplicas < minReplicas {
log.Warnf("maxReplicas %d is less than minReplicas %d. Using minReplicas value %d", maxReplicas, minReplicas, minReplicas)
maxReplicas = minReplicas maxReplicas = minReplicas
} }
cpuUtilization := validatePercentageMetric(service, compose.LabelHpaCPU, DefaultCPUUtilization)
memoryUtilization := validatePercentageMetric(service, compose.LabelHpaMemory, DefaultMemoryUtilization)
return HpaValues{ return HpaValues{
MinReplicas: minReplicas, MinReplicas: minReplicas,
MaxReplicas: maxReplicas, MaxReplicas: maxReplicas,
CPUtilization: getHpaValue(service, compose.LabelHpaCPU, DefaultCpuUtilization), CPUtilization: cpuUtilization,
MemoryUtilization: getHpaValue(service, compose.LabelHpaMemory, DefaultMemoryUtilization), MemoryUtilization: memoryUtilization,
} }
} }
// validatePercentageMetric validates the CPU or memory metrics value
// ensuring that it falls within the acceptable range [1, 100].
func validatePercentageMetric(service *kobject.ServiceConfig, metricLabel string, defaultValue int32) int32 {
metricValue := getHpaValue(service, metricLabel, defaultValue)
if metricValue > 100 || metricValue < 1 {
log.Warnf("Metric value %d is not within the acceptable range [1, 100]. Using default value %d", metricValue, defaultValue)
return defaultValue
}
return metricValue
}
// getHpaValue convert the label value to integer // getHpaValue convert the label value to integer
// If the label is not present or the conversion fails // If the label is not present or the conversion fails
// it returns the provided default value // it returns the provided default value
func getHpaValue(service *kobject.ServiceConfig, label string, defaultValue int32) int32 { func getHpaValue(service *kobject.ServiceConfig, label string, defaultValue int32) int32 {
valueFromLabel, err := strconv.Atoi(service.Labels[label]) valueFromLabel, err := strconv.Atoi(service.Labels[label])
if err != nil || valueFromLabel <= 0 { if err != nil || valueFromLabel < 0 {
log.Warnf("Error converting label %s. Using default value %d", label, defaultValue)
return defaultValue return defaultValue
} }
return int32(valueFromLabel) return int32(valueFromLabel)

View File

@ -783,7 +783,7 @@ func Test_getHpaValue(t *testing.T) {
label: compose.LabelHpaMinReplicas, label: compose.LabelHpaMinReplicas,
defaultValue: 1, defaultValue: 1,
}, },
want: 1, want: 0,
}, },
{ {
name: "LabelHpaMinReplicas with error value", name: "LabelHpaMinReplicas with error value",
@ -830,9 +830,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaMaxReplicas, label: compose.LabelHpaMaxReplicas,
defaultValue: 10, defaultValue: DefaultMaxReplicas,
}, },
want: 10, want: 0,
}, },
{ {
name: "LabelHpaMaxReplicas with error value", name: "LabelHpaMaxReplicas with error value",
@ -846,9 +846,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaMaxReplicas, label: compose.LabelHpaMaxReplicas,
defaultValue: 10, defaultValue: DefaultMaxReplicas,
}, },
want: 10, want: DefaultMaxReplicas,
}, },
// LabelHpaCPU // LabelHpaCPU
{ {
@ -879,9 +879,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaCPU, label: compose.LabelHpaCPU,
defaultValue: 50, defaultValue: DefaultCPUUtilization,
}, },
want: 50, want: 0,
}, },
{ {
name: "LabelHpaCPU with error value", name: "LabelHpaCPU with error value",
@ -895,9 +895,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaCPU, label: compose.LabelHpaCPU,
defaultValue: 50, defaultValue: DefaultCPUUtilization,
}, },
want: 50, want: DefaultCPUUtilization,
}, },
// LabelHpaMemory // LabelHpaMemory
{ {
@ -928,9 +928,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaMemory, label: compose.LabelHpaMemory,
defaultValue: 70, defaultValue: DefaultMemoryUtilization,
}, },
want: 70, want: 0,
}, },
{ {
name: "LabelHpaMemory with error value", name: "LabelHpaMemory with error value",
@ -944,9 +944,9 @@ func Test_getHpaValue(t *testing.T) {
}, },
}, },
label: compose.LabelHpaMemory, label: compose.LabelHpaMemory,
defaultValue: 70, defaultValue: DefaultMemoryUtilization,
}, },
want: 70, want: DefaultMemoryUtilization,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
@ -973,7 +973,7 @@ func Test_getResourceHpaValues(t *testing.T) {
service: &kobject.ServiceConfig{ service: &kobject.ServiceConfig{
Labels: map[string]string{ Labels: map[string]string{
compose.LabelHpaMinReplicas: "1", compose.LabelHpaMinReplicas: "1",
compose.LabelHpaMaxReplicas: "10", compose.LabelHpaMaxReplicas: "3",
compose.LabelHpaCPU: "50", compose.LabelHpaCPU: "50",
compose.LabelHpaMemory: "70", compose.LabelHpaMemory: "70",
}, },
@ -981,7 +981,7 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, MinReplicas: 1,
MaxReplicas: 10, MaxReplicas: 3,
CPUtilization: 50, CPUtilization: 50,
MemoryUtilization: 70, MemoryUtilization: 70,
}, },
@ -1018,7 +1018,7 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 3, MaxReplicas: 3,
CPUtilization: 50, CPUtilization: 50,
MemoryUtilization: 70, MemoryUtilization: 70,
@ -1058,12 +1058,12 @@ func Test_getResourceHpaValues(t *testing.T) {
want: HpaValues{ want: HpaValues{
MinReplicas: 6, MinReplicas: 6,
MaxReplicas: 6, // same as min replicas number MaxReplicas: 6, // same as min replicas number
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, MemoryUtilization: 70,
}, },
}, },
{ {
name: "error label and LabelHpaMaxReplicas is minor to LabelHpaMinReplicas", name: "error label and LabelHpaMaxReplicas is minor to LabelHpaMinReplicas and cannot transform hpa mmemor utilization",
args: args{ args: args{
service: &kobject.ServiceConfig{ service: &kobject.ServiceConfig{
Labels: map[string]string{ Labels: map[string]string{
@ -1078,7 +1078,7 @@ func Test_getResourceHpaValues(t *testing.T) {
MinReplicas: 6, MinReplicas: 6,
MaxReplicas: 6, MaxReplicas: 6,
CPUtilization: 50, CPUtilization: 50,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1094,10 +1094,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1111,10 +1111,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1125,10 +1125,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1142,9 +1142,9 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 3, MinReplicas: 3,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1157,10 +1157,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 5, MaxReplicas: 5,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1176,10 +1176,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1192,10 +1192,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 80, CPUtilization: 80,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1208,9 +1208,9 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 90, MemoryUtilization: 90,
}, },
}, },
@ -1225,8 +1225,8 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 80, CPUtilization: 80,
MemoryUtilization: 90, MemoryUtilization: 90,
}, },
@ -1244,10 +1244,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1263,10 +1263,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
{ {
@ -1282,10 +1282,10 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: 0,
MaxReplicas: 10, // Default value MaxReplicas: 0,
CPUtilization: 50, // Default value CPUtilization: 50,
MemoryUtilization: 70, // Default value MemoryUtilization: 70,
}, },
}, },
{ {
@ -1301,10 +1301,29 @@ func Test_getResourceHpaValues(t *testing.T) {
}, },
}, },
want: HpaValues{ want: HpaValues{
MinReplicas: 1, // Default value MinReplicas: DefaultMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
CPUtilization: 50, // Default value CPUtilization: DefaultCPUUtilization,
MemoryUtilization: 70, // Default value MemoryUtilization: DefaultMemoryUtilization,
},
},
{
name: "check default values when labels cpu and memory are over",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMinReplicas: "-2",
compose.LabelHpaMaxReplicas: "-2",
compose.LabelHpaCPU: "120",
compose.LabelHpaMemory: "120",
},
},
},
want: HpaValues{
MinReplicas: DefaultMinReplicas,
MaxReplicas: DefaultMaxReplicas,
CPUtilization: DefaultCPUUtilization,
MemoryUtilization: DefaultMemoryUtilization,
}, },
}, },
} }
@ -1317,9 +1336,189 @@ func Test_getResourceHpaValues(t *testing.T) {
} }
} }
func Test_validatePercentageMetric(t *testing.T) {
type args struct {
service *kobject.ServiceConfig
metricLabel string
defaultValue int32
}
tests := []struct {
name string
args args
want int32
}{
{
name: "0 cpu utilization",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "0",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: 50,
},
{
name: "default cpu valid range",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "120",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: DefaultCPUUtilization,
},
{
name: "cpu invalid range",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "-120",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: DefaultCPUUtilization,
},
{
name: "cpu utilization set to 100",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "100",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: 100,
},
{
name: "cpu utlization set to 101",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "101",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: DefaultCPUUtilization,
},
{
name: "cannot convert value in cpu label",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaCPU: "not converted",
},
},
metricLabel: compose.LabelHpaCPU,
defaultValue: DefaultCPUUtilization,
},
want: DefaultCPUUtilization,
},
{
name: "0 memory utilization",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "0",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: 70,
},
{
name: "memory over 100 utilization",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "120",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: DefaultMemoryUtilization,
},
{
name: "-120 utilization memory wrong range",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "-120",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: DefaultMemoryUtilization,
},
{
name: "memory 100 usage",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "100",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: 100,
},
{
name: "101 memory utilization",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "101",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: DefaultMemoryUtilization,
},
{
name: "cannot convert memory from label",
args: args{
service: &kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelHpaMemory: "not converted",
},
},
metricLabel: compose.LabelHpaMemory,
defaultValue: DefaultMemoryUtilization,
},
want: DefaultMemoryUtilization,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := validatePercentageMetric(tt.args.service, tt.args.metricLabel, tt.args.defaultValue); got != tt.want {
t.Errorf("validatePercentageMetric() = %v, want %v", got, tt.want)
}
})
}
}
func Test_getHpaMetricSpec(t *testing.T) { func Test_getHpaMetricSpec(t *testing.T) {
valueCPUFixed := int32(50) valueCPUFixed := int32(50)
valueMemoryFixed := int32(70) valueMemoryFixed := int32(70)
valueOver100 := int32(120)
valueUnderZero := int32(-120)
// valueZero := int32(0)
type args struct { type args struct {
hpaValues HpaValues hpaValues HpaValues
} }
@ -1331,7 +1530,7 @@ func Test_getHpaMetricSpec(t *testing.T) {
{ {
name: "no values", name: "no values",
args: args{ args: args{
hpaValues: HpaValues{}, hpaValues: HpaValues{}, // set all values to 0
}, },
want: nil, want: nil,
}, },
@ -1339,7 +1538,7 @@ func Test_getHpaMetricSpec(t *testing.T) {
name: "only cpu", name: "only cpu",
args: args{ args: args{
hpaValues: HpaValues{ hpaValues: HpaValues{
CPUtilization: 50, CPUtilization: valueCPUFixed,
}, },
}, },
want: []hpa.MetricSpec{ want: []hpa.MetricSpec{
@ -1379,8 +1578,8 @@ func Test_getHpaMetricSpec(t *testing.T) {
name: "cpu and memory", name: "cpu and memory",
args: args{ args: args{
hpaValues: HpaValues{ hpaValues: HpaValues{
CPUtilization: 50, CPUtilization: valueCPUFixed,
MemoryUtilization: 70, MemoryUtilization: valueMemoryFixed,
}, },
}, },
want: []hpa.MetricSpec{ want: []hpa.MetricSpec{
@ -1406,7 +1605,69 @@ func Test_getHpaMetricSpec(t *testing.T) {
}, },
}, },
}, },
{
name: "memory over 100",
args: args{
hpaValues: HpaValues{
MemoryUtilization: valueOver100,
},
},
want: []hpa.MetricSpec{
{
Type: hpa.ResourceMetricSourceType,
Resource: &hpa.ResourceMetricSource{
Name: "memory",
Target: hpa.MetricTarget{
Type: hpa.UtilizationMetricType,
AverageUtilization: &valueOver100,
},
},
},
},
},
{
name: "cpu and memory over 100",
args: args{
hpaValues: HpaValues{
CPUtilization: valueOver100,
MemoryUtilization: valueOver100,
},
},
want: []hpa.MetricSpec{
{
Type: hpa.ResourceMetricSourceType,
Resource: &hpa.ResourceMetricSource{
Name: "cpu",
Target: hpa.MetricTarget{
Type: hpa.UtilizationMetricType,
AverageUtilization: &valueOver100,
},
},
},
{
Type: hpa.ResourceMetricSourceType,
Resource: &hpa.ResourceMetricSource{
Name: "memory",
Target: hpa.MetricTarget{
Type: hpa.UtilizationMetricType,
AverageUtilization: &valueOver100,
},
},
},
},
},
{
name: "cpu and memory under 0",
args: args{
hpaValues: HpaValues{
CPUtilization: valueUnderZero,
MemoryUtilization: valueUnderZero,
},
},
want: nil,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := getHpaMetricSpec(tt.args.hpaValues); !reflect.DeepEqual(got, tt.want) { if got := getHpaMetricSpec(tt.args.hpaValues); !reflect.DeepEqual(got, tt.want) {
@ -1509,7 +1770,7 @@ func Test_createHPAResources(t *testing.T) {
APIVersion: "apps/v1", APIVersion: "apps/v1",
}, },
MinReplicas: &fixedMinReplicas, MinReplicas: &fixedMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
Metrics: []hpa.MetricSpec{ Metrics: []hpa.MetricSpec{
{ {
Type: hpa.ResourceMetricSourceType, Type: hpa.ResourceMetricSourceType,
@ -1667,7 +1928,7 @@ func Test_createHPAResources(t *testing.T) {
APIVersion: "apps/v1", APIVersion: "apps/v1",
}, },
MinReplicas: &fixedMinReplicas, MinReplicas: &fixedMinReplicas,
MaxReplicas: 10, // Default value MaxReplicas: DefaultMaxReplicas,
Metrics: []hpa.MetricSpec{ Metrics: []hpa.MetricSpec{
{ {
Type: hpa.ResourceMetricSourceType, Type: hpa.ResourceMetricSourceType,

View File

@ -1656,7 +1656,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
} }
err = k.configHorizontalPodScaler(name, service, opt, &objects) err = k.configHorizontalPodScaler(name, service, opt, &objects)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "Error transforming Kubernetes objects") return nil, errors.Wrap(err, "Error creating Kubernetes HPA")
} }
allobjects = append(allobjects, objects...) allobjects = append(allobjects, objects...)
} }

View File

@ -4,6 +4,7 @@ services:
image: nginx image: nginx
labels: labels:
kompose.hpa.cpu: 50 kompose.hpa.cpu: 50
kompose.hap.memory: 70 kompose.hpa.memory: 70
kompose.hap.replicas.min: 1 kompose.hpa.replicas.min: 1
kompose.hap.replicas.max: 10 kompose.hpa.replicas.max: 10

View File

@ -46,3 +46,4 @@ spec:
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
name: web name: web