-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathhpa.py
More file actions
136 lines (109 loc) · 4.78 KB
/
Copy pathhpa.py
File metadata and controls
136 lines (109 loc) · 4.78 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import json
import logging
from scheduler.resources import Resource
from scheduler.exceptions import KubeException, KubeHTTPException
class HorizontalPodAutoscaler(Resource):
api_prefix = 'apis'
api_version = 'autoscaling/v1'
short_name = 'hpa'
def get(self, namespace, name=None, **kwargs):
"""
Fetch a single HorizontalPodAutoscaler or a list
"""
url = '/namespaces/{}/horizontalpodautoscalers'
args = [namespace]
if name is not None:
args.append(name)
url += '/{}'
message = 'get HorizontalPodAutoscaler "{}" in Namespace "{}"'
else:
message = 'get HorizontalPodAutoscalers in Namespace "{}"'
url = self.api(url, *args)
response = self.http_get(url, params=self.query_params(**kwargs))
if self.unhealthy(response.status_code):
args.reverse() # error msg is in reverse order
raise KubeHTTPException(response, message, *args)
return response
def manifest(self, namespace, name, **kwargs):
app_type = kwargs.get('app_type')
target = kwargs.get('target')
min_replicas = kwargs.get('min')
max_replicas = kwargs.get('max')
cpu_percent = kwargs.get('cpu_percent')
if min_replicas < 1:
raise KubeException('min replicas needs to be 1 or higher')
if max_replicas < min_replicas:
raise KubeException('max replicas can not be smaller than min replicas')
labels = {
'app': namespace,
'type': app_type,
'heritage': 'drycc',
}
manifest = {
'kind': 'HorizontalPodAutoscaler',
'apiVersion': self.api_version,
'metadata': {
'name': name,
'namespace': namespace,
'labels': labels,
},
'spec': {
'minReplicas': min_replicas,
'maxReplicas': max_replicas,
'targetCPUUtilizationPercentage': cpu_percent,
'scaleTargetRef': {
'apiVersion': target['apiVersion'],
'kind': target['kind'],
'name': target['metadata']['name'],
}
}
}
return manifest
def create(self, namespace, name, **kwargs):
manifest = self.manifest(namespace, name, **kwargs)
url = self.api("/namespaces/{}/horizontalpodautoscalers", namespace)
response = self.http_post(url, json=manifest)
if self.unhealthy(response.status_code):
self.log(namespace, 'template used: {}'.format(
json.dumps(manifest, indent=4)), logging.DEBUG)
raise KubeHTTPException(
response,
'create HorizontalPodAutoscaler "{}" in Namespace "{}"', name, namespace
)
if kwargs.get('wait', False):
self.wait(namespace, name)
return response
def update(self, namespace, name, **kwargs):
manifest = self.manifest(namespace, name, **kwargs)
url = self.api("/namespaces/{}/horizontalpodautoscalers/{}", namespace, name)
response = self.http_put(url, json=manifest)
if self.unhealthy(response.status_code):
self.log(namespace, 'template used: {}'.format(
json.dumps(manifest, indent=4)), logging.DEBUG)
raise KubeHTTPException(response, 'update HorizontalPodAutoscaler "{}"', name)
if kwargs.get('wait', False):
self.wait(namespace, name)
return response
def delete(self, namespace, name, **kwargs):
url = self.api("/namespaces/{}/horizontalpodautoscalers/{}", namespace, name)
response = self.http_delete(url)
if not kwargs.get('ignore_exception', False) and self.unhealthy(response.status_code):
raise KubeHTTPException(
response,
'delete HorizontalPodAutoscaler "{}" in Namespace "{}"', name, namespace
)
return response
def wait(self, namespace, name):
"""Wait for HPA to stabilize."""
hpa = self.hpa.get(namespace, name).json()
for _ in range(30):
resource_kind = hpa['spec']['scaleTargetRef']['kind'].lower()
resource_name = hpa['spec']['scaleTargetRef']['name']
resource = getattr(self, resource_kind)
resource = getattr(resource, 'get')(namespace, resource_name).json()
if resource_kind in ['replicationcontroller', 'replicaset']:
replicas = resource['status']['replicas']
elif resource_kind == 'deployment':
replicas = resource['status']['availableReplicas']
if replicas <= hpa['spec']['maxReplicas'] or replicas >= hpa['spec']['minReplicas']:
break