-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhpa.go
96 lines (94 loc) · 3.46 KB
/
hpa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package controller
import (
"context"
gomaprojv1beta1 "github.com/jkaninda/goma-operator/api/v1beta1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"reflect"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
)
// createHpa creates HPA
func createHpa(r GatewayReconciler, ctx context.Context, req ctrl.Request, gateway *gomaprojv1beta1.Gateway) error {
logger := log.FromContext(ctx)
var metrics []autoscalingv2.MetricSpec
targetCPUUtilizationPercentage := gateway.Spec.AutoScaling.TargetCPUUtilizationPercentage
targetMemoryUtilizationPercentage := gateway.Spec.AutoScaling.TargetMemoryUtilizationPercentage
// Add CPU metric if targetCPUUtilizationPercentage is set
if targetCPUUtilizationPercentage != 0 {
metrics = append(metrics, autoscalingv2.MetricSpec{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
Name: "cpu",
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: int32Ptr(targetCPUUtilizationPercentage),
},
},
})
}
// Add Memory metric if targetMemoryUtilizationPercentage is set
if targetMemoryUtilizationPercentage != 0 {
metrics = append(metrics, autoscalingv2.MetricSpec{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
Name: "memory",
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: int32Ptr(targetMemoryUtilizationPercentage),
},
},
})
}
// Create HPA
hpa := &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: req.Name,
Namespace: req.Namespace,
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
MinReplicas: int32Ptr(gateway.Spec.AutoScaling.MinReplicas),
MaxReplicas: gateway.Spec.AutoScaling.MaxReplicas,
Metrics: metrics,
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: req.Name,
},
},
}
// Check if the hpa already exists
var existHpa autoscalingv2.HorizontalPodAutoscaler
err := r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, &existHpa)
if err != nil && client.IgnoreNotFound(err) != nil {
logger.Error(err, "Failed to get HorizontalPodAutoscaler")
return err
}
if err != nil && client.IgnoreNotFound(err) == nil {
// Create the HPA if it doesn't exist
if err = controllerutil.SetControllerReference(gateway, hpa, r.Scheme); err != nil {
logger.Error(err, "Failed to set controller reference")
return err
}
if err = r.Create(ctx, hpa); err != nil {
logger.Error(err, "Failed to create HorizontalPodAutoscaler")
return err
}
logger.Info("Created HorizontalPodAutoscaler", "HorizontalPodAutoscaler.Name", hpa.Name)
} else {
logger.Info("HorizontalPodAutoscaler already exists", "HorizontalPodAutoscaler.Name", hpa.Name)
// Update the Deployment if the spec has changed
if !reflect.DeepEqual(existHpa.Spec, hpa.Spec) {
existHpa.Spec = hpa.Spec
if err = r.Update(ctx, &existHpa); err != nil {
logger.Error(err, "Failed to update Deployment")
return err
}
logger.Info("Updated HorizontalPodAutoscaler", "HorizontalPodAutoscaler.Name", hpa.Name)
}
}
return nil
}