-
Notifications
You must be signed in to change notification settings - Fork 115
/
hpa.go
100 lines (83 loc) · 2.91 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
97
98
99
100
package k8s
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
autoscalingv1 "k8s.io/api/autoscaling/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"
k8sapiv1 "github.com/lyft/clutch/backend/api/k8s/v1"
)
func (s *svc) DescribeHPA(ctx context.Context, clientset, cluster, namespace, name string) (*k8sapiv1.HPA, error) {
cs, err := s.manager.GetK8sClientset(ctx, clientset, cluster, namespace)
if err != nil {
return nil, err
}
hpas, err := cs.AutoscalingV1().HorizontalPodAutoscalers(cs.Namespace()).List(ctx, metav1.ListOptions{
FieldSelector: "metadata.name=" + name,
})
if err != nil {
return nil, err
}
if len(hpas.Items) == 1 {
return ProtoForHPA(cs.Cluster(), &hpas.Items[0]), nil
} else if len(hpas.Items) > 1 {
return nil, status.Error(codes.FailedPrecondition, "located multiple HPAs")
}
return nil, status.Error(codes.NotFound, "unable to locate specified HPA")
}
func ProtoForHPA(cluster string, autoscaler *autoscalingv1.HorizontalPodAutoscaler) *k8sapiv1.HPA {
clusterName := GetKubeClusterName(autoscaler)
if clusterName == "" {
clusterName = cluster
}
return &k8sapiv1.HPA{
Cluster: clusterName,
Namespace: autoscaler.Namespace,
Name: autoscaler.Name,
Sizing: &k8sapiv1.HPA_Sizing{
MinReplicas: uint32(*autoscaler.Spec.MinReplicas),
MaxReplicas: uint32(autoscaler.Spec.MaxReplicas),
CurrentReplicas: uint32(autoscaler.Status.CurrentReplicas),
DesiredReplicas: uint32(autoscaler.Status.DesiredReplicas),
},
Labels: autoscaler.Labels,
Annotations: autoscaler.Annotations,
}
}
func (s *svc) ResizeHPA(ctx context.Context, clientset, cluster, namespace, name string, sizing *k8sapiv1.ResizeHPARequest_Sizing) error {
cs, err := s.manager.GetK8sClientset(ctx, clientset, cluster, namespace)
if err != nil {
return err
}
opts := metav1.GetOptions{}
hpa, err := cs.AutoscalingV1().HorizontalPodAutoscalers(cs.Namespace()).Get(ctx, name, opts)
if err != nil {
return err
}
normalizeHPAChanges(hpa, sizing)
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
_, err := cs.AutoscalingV1().HorizontalPodAutoscalers(cs.Namespace()).Update(ctx, hpa, metav1.UpdateOptions{})
return err
})
return retryErr
}
func normalizeHPAChanges(hpa *autoscalingv1.HorizontalPodAutoscaler, sizing *k8sapiv1.ResizeHPARequest_Sizing) {
if sizing == nil {
return
}
min := int32(sizing.Min)
hpa.Spec.MinReplicas = &min
hpa.Spec.MaxReplicas = int32(sizing.Max)
if *hpa.Spec.MinReplicas > hpa.Spec.MaxReplicas {
hpa.Spec.MaxReplicas = *hpa.Spec.MinReplicas
}
}
func (s *svc) DeleteHPA(ctx context.Context, clientset, cluster, namespace, name string) error {
cs, err := s.manager.GetK8sClientset(ctx, clientset, cluster, namespace)
if err != nil {
return err
}
opts := metav1.DeleteOptions{}
return cs.AutoscalingV1().HorizontalPodAutoscalers(cs.Namespace()).Delete(ctx, name, opts)
}