-
Notifications
You must be signed in to change notification settings - Fork 2
/
limitrange.go
121 lines (101 loc) · 3.83 KB
/
limitrange.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package kube
import (
"context"
"encoding/json"
"fmt"
"github.com/rs/zerolog/log"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
)
// ApplyLimitRange Applies limit range to namespace
func (kubeutil *Kube) ApplyLimitRange(namespace string, limitRange *corev1.LimitRange) error {
log.Debug().Msgf("Apply limit range %s", limitRange.Name)
oldLimitRange, err := kubeutil.getLimitRange(namespace, limitRange.GetName())
if err != nil && errors.IsNotFound(err) {
createdLimitRange, err := kubeutil.kubeClient.CoreV1().LimitRanges(namespace).Create(context.TODO(), limitRange, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("failed to create LimitRange object: %v", err)
}
log.Debug().Msgf("Created LimitRange: %s in namespace %s", createdLimitRange.Name, namespace)
return nil
} else if err != nil {
return fmt.Errorf("failed to get limit range object: %v", err)
}
log.Debug().Msgf("LimitRange object %s already exists in namespace %s, updating the object now", limitRange.GetName(), namespace)
newLimitRange := oldLimitRange.DeepCopy()
newLimitRange.ObjectMeta.OwnerReferences = limitRange.ObjectMeta.OwnerReferences
newLimitRange.Spec = limitRange.Spec
oldLimitRangeJSON, err := json.Marshal(oldLimitRange)
if err != nil {
return fmt.Errorf("failed to marshal old limitRange object: %v", err)
}
newLimitRangeJSON, err := json.Marshal(newLimitRange)
if err != nil {
return fmt.Errorf("failed to marshal new limitRange object: %v", err)
}
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldLimitRangeJSON, newLimitRangeJSON, corev1.LimitRange{})
if err != nil {
return fmt.Errorf("failed to create two way merge patch limitRange objects: %v", err)
}
if !IsEmptyPatch(patchBytes) {
patchedLimitRange, err := kubeutil.kubeClient.CoreV1().LimitRanges(namespace).Patch(context.TODO(), limitRange.GetName(), types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("failed to patch limitRange object: %v", err)
}
log.Debug().Msgf("Patched limitRange: %s in namespace %s", patchedLimitRange.Name, namespace)
} else {
log.Debug().Msgf("No need to patch limitRange: %s ", limitRange.GetName())
}
return nil
}
// BuildLimitRange Builds a limit range spec
func (kubeutil *Kube) BuildLimitRange(namespace, name, appName string, defaultResourceMemory, defaultRequestCPU, defaultRequestMemory *resource.Quantity) *corev1.LimitRange {
defaultResources := make(corev1.ResourceList)
defaultResources[corev1.ResourceMemory] = *defaultResourceMemory
defaultRequest := make(corev1.ResourceList)
defaultRequest[corev1.ResourceCPU] = *defaultRequestCPU
defaultRequest[corev1.ResourceMemory] = *defaultRequestMemory
limitRange := &corev1.LimitRange{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "LimitRange",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: map[string]string{
RadixAppLabel: appName,
},
},
Spec: corev1.LimitRangeSpec{
Limits: []corev1.LimitRangeItem{
{
Type: corev1.LimitTypeContainer,
Default: defaultResources,
DefaultRequest: defaultRequest,
},
},
},
}
return limitRange
}
func (kubeutil *Kube) getLimitRange(namespace, name string) (*corev1.LimitRange, error) {
var limitRange *corev1.LimitRange
var err error
if kubeutil.LimitRangeLister != nil {
limitRange, err = kubeutil.LimitRangeLister.LimitRanges(namespace).Get(name)
if err != nil {
return nil, err
}
} else {
limitRange, err = kubeutil.kubeClient.CoreV1().LimitRanges(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, err
}
}
return limitRange, nil
}