Merge "add support of dpdk for bottlenecks_ping"
[yardstick.git] / yardstick / common / kubernetes_utils.py
1 ##############################################################################
2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import logging
10
11 from kubernetes import client
12 from kubernetes import config
13 from kubernetes.client.rest import ApiException
14
15 from yardstick.common import constants as consts
16 from yardstick.common import exceptions
17
18
19 LOG = logging.getLogger(__name__)
20 LOG.setLevel(logging.DEBUG)
21
22
23 def get_core_api():     # pragma: no cover
24     try:
25         config.load_kube_config(config_file=consts.K8S_CONF_FILE)
26     except IOError:
27         raise exceptions.KubernetesConfigFileNotFound()
28     return client.CoreV1Api()
29
30
31 def get_extensions_v1beta_api():
32     try:
33         config.load_kube_config(config_file=consts.K8S_CONF_FILE)
34     except IOError:
35         raise exceptions.KubernetesConfigFileNotFound()
36     return client.ApiextensionsV1beta1Api()
37
38
39 def get_custom_objects_api():
40     try:
41         config.load_kube_config(config_file=consts.K8S_CONF_FILE)
42     except IOError:
43         raise exceptions.KubernetesConfigFileNotFound()
44     return client.CustomObjectsApi()
45
46
47 def get_node_list(**kwargs):        # pragma: no cover
48     core_v1_api = get_core_api()
49     try:
50         return core_v1_api.list_node(**kwargs)
51     except ApiException:
52         LOG.exception('Get node list failed')
53         raise
54
55
56 def create_service(template,
57                    namespace='default',
58                    wait=False,
59                    **kwargs):       # pragma: no cover
60     # pylint: disable=unused-argument
61     core_v1_api = get_core_api()
62     metadata = client.V1ObjectMeta(**template.get('metadata', {}))
63
64     ports = [client.V1ServicePort(**port) for port in
65              template.get('spec', {}).get('ports', [])]
66     template['spec']['ports'] = ports
67     spec = client.V1ServiceSpec(**template.get('spec', {}))
68
69     service = client.V1Service(metadata=metadata, spec=spec)
70
71     try:
72         core_v1_api.create_namespaced_service('default', service)
73     except ApiException:
74         LOG.exception('Create Service failed')
75         raise
76
77
78 def delete_service(name,
79                    namespace='default',
80                    **kwargs):       # pragma: no cover
81     core_v1_api = get_core_api()
82     try:
83         body = client.V1DeleteOptions()
84         core_v1_api.delete_namespaced_service(name, namespace, body, **kwargs)
85     except ApiException:
86         LOG.exception('Delete Service failed')
87
88
89 def get_service_list(namespace='default', **kwargs):
90     core_v1_api = get_core_api()
91     try:
92         return core_v1_api.list_namespaced_service(namespace, **kwargs)
93     except ApiException:
94         LOG.exception('Get Service list failed')
95         raise
96
97
98 def get_service_by_name(name):      # pragma: no cover
99     service_list = get_service_list()
100     return next((s.spec for s in service_list.items if s.metadata.name == name), None)
101
102
103 def create_replication_controller(template,
104                                   namespace='default',
105                                   wait=False,
106                                   **kwargs):    # pragma: no cover
107     # pylint: disable=unused-argument
108     core_v1_api = get_core_api()
109     try:
110         core_v1_api.create_namespaced_replication_controller(namespace,
111                                                              template,
112                                                              **kwargs)
113     except ApiException:
114         LOG.exception('Create replication controller failed')
115         raise
116
117
118 def delete_replication_controller(name,
119                                   namespace='default',
120                                   wait=False,
121                                   **kwargs):    # pragma: no cover
122     # pylint: disable=unused-argument
123     core_v1_api = get_core_api()
124     body = kwargs.get('body', client.V1DeleteOptions())
125     kwargs.pop('body', None)
126     try:
127         core_v1_api.delete_namespaced_replication_controller(name,
128                                                              namespace,
129                                                              body,
130                                                              **kwargs)
131     except ApiException:
132         LOG.exception('Delete replication controller failed')
133         raise
134
135
136 def delete_pod(name,
137                namespace='default',
138                wait=False,
139                skip_codes=None,
140                **kwargs):    # pragma: no cover
141     # pylint: disable=unused-argument
142     skip_codes = [] if not skip_codes else skip_codes
143     core_v1_api = get_core_api()
144     body = kwargs.get('body', client.V1DeleteOptions())
145     kwargs.pop('body', None)
146     try:
147         core_v1_api.delete_namespaced_pod(name,
148                                           namespace,
149                                           body,
150                                           **kwargs)
151     except ApiException as e:
152         if e.status in skip_codes:
153             LOG.info(e.reason)
154         else:
155             raise exceptions.KubernetesApiException(
156                 action='delete', resource='Pod')
157
158
159 def read_pod(name,
160              namespace='default',
161              **kwargs):  # pragma: no cover
162     core_v1_api = get_core_api()
163     try:
164         resp = core_v1_api.read_namespaced_pod(name, namespace, **kwargs)
165     except ApiException:
166         LOG.exception('Read pod failed')
167         raise
168     else:
169         return resp
170
171
172 def read_pod_status(name, namespace='default', **kwargs):   # pragma: no cover
173     # pylint: disable=unused-argument
174     return read_pod(name).status.phase
175
176
177 def create_config_map(name,
178                       data,
179                       namespace='default',
180                       wait=False,
181                       **kwargs):   # pragma: no cover
182     # pylint: disable=unused-argument
183     core_v1_api = get_core_api()
184     metadata = client.V1ObjectMeta(name=name)
185     body = client.V1ConfigMap(data=data, metadata=metadata)
186     try:
187         core_v1_api.create_namespaced_config_map(namespace, body, **kwargs)
188     except ApiException:
189         LOG.exception('Create config map failed')
190         raise
191
192
193 def delete_config_map(name,
194                       namespace='default',
195                       wait=False,
196                       **kwargs):     # pragma: no cover
197     # pylint: disable=unused-argument
198     core_v1_api = get_core_api()
199     body = kwargs.get('body', client.V1DeleteOptions())
200     kwargs.pop('body', None)
201     try:
202         core_v1_api.delete_namespaced_config_map(name,
203                                                  namespace,
204                                                  body,
205                                                  **kwargs)
206     except ApiException:
207         LOG.exception('Delete config map failed')
208         raise
209
210
211 def create_custom_resource_definition(body):
212     api = get_extensions_v1beta_api()
213     body_obj = client.V1beta1CustomResourceDefinition(
214         spec=body['spec'], metadata=body['metadata'])
215     try:
216         api.create_custom_resource_definition(body_obj)
217     except ValueError:
218         # NOTE(ralonsoh): bug in kubernetes-client/python 6.0.0
219         # https://github.com/kubernetes-client/python/issues/491
220         pass
221     except ApiException:
222         raise exceptions.KubernetesApiException(
223             action='create', resource='CustomResourceDefinition')
224
225
226 def delete_custom_resource_definition(name):
227     api = get_extensions_v1beta_api()
228     body_obj = client.V1DeleteOptions()
229     try:
230         api.delete_custom_resource_definition(name, body_obj)
231     except ApiException:
232         raise exceptions.KubernetesApiException(
233             action='delete', resource='CustomResourceDefinition')
234
235
236 def get_custom_resource_definition(kind):
237     api = get_extensions_v1beta_api()
238     try:
239         crd_list = api.list_custom_resource_definition()
240         for crd_obj in (crd_obj for crd_obj in crd_list.items
241                         if crd_obj.spec.names.kind == kind):
242             return crd_obj
243         return None
244     except ApiException:
245         raise exceptions.KubernetesApiException(
246             action='delete', resource='CustomResourceDefinition')
247
248
249 def create_network(scope, group, version, plural, body, namespace='default'):
250     api = get_custom_objects_api()
251     try:
252         if scope == consts.SCOPE_CLUSTER:
253             api.create_cluster_custom_object(group, version, plural, body)
254         else:
255             api.create_namespaced_custom_object(
256                 group, version, namespace, plural, body)
257     except ApiException:
258         raise exceptions.KubernetesApiException(
259             action='create', resource='Custom Object: Network')
260
261
262 def delete_network(scope, group, version, plural, name, namespace='default'):
263     api = get_custom_objects_api()
264     try:
265         if scope == consts.SCOPE_CLUSTER:
266             api.delete_cluster_custom_object(group, version, plural, name, {})
267         else:
268             api.delete_namespaced_custom_object(
269                 group, version, namespace, plural, name, {})
270     except ApiException:
271         raise exceptions.KubernetesApiException(
272             action='delete', resource='Custom Object: Network')
273
274
275 def get_pod_list(namespace='default'):      # pragma: no cover
276     core_v1_api = get_core_api()
277     try:
278         return core_v1_api.list_namespaced_pod(namespace=namespace)
279     except ApiException:
280         LOG.exception('Get pod list failed')
281         raise
282
283
284 def get_pod_by_name(name):  # pragma: no cover
285     pod_list = get_pod_list()
286     return next((n for n in pod_list.items if n.metadata.name.startswith(name)), None)
287
288
289 def get_volume_types():
290     """Return the "volume" types supported by the current API"""
291     return [vtype for vtype in client.V1Volume.attribute_map.values()
292             if vtype != 'name']