kubernetes_utils: avoid 404 error code in delete_custom_resource_definition()
[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, skip_codes=None):
227     skip_codes = [] if not skip_codes else skip_codes
228     api = get_extensions_v1beta_api()
229     body_obj = client.V1DeleteOptions()
230     try:
231         api.delete_custom_resource_definition(name, body_obj)
232     except ApiException as e:
233         if e.status in skip_codes:
234             LOG.info(e.reason)
235         else:
236             raise exceptions.KubernetesApiException(
237                 action='delete', resource='CustomResourceDefinition')
238
239
240 def get_custom_resource_definition(kind):
241     api = get_extensions_v1beta_api()
242     try:
243         crd_list = api.list_custom_resource_definition()
244         for crd_obj in (crd_obj for crd_obj in crd_list.items
245                         if crd_obj.spec.names.kind == kind):
246             return crd_obj
247         return None
248     except ApiException:
249         raise exceptions.KubernetesApiException(
250             action='delete', resource='CustomResourceDefinition')
251
252
253 def create_network(scope, group, version, plural, body, namespace='default'):
254     api = get_custom_objects_api()
255     try:
256         if scope == consts.SCOPE_CLUSTER:
257             api.create_cluster_custom_object(group, version, plural, body)
258         else:
259             api.create_namespaced_custom_object(
260                 group, version, namespace, plural, body)
261     except ApiException:
262         raise exceptions.KubernetesApiException(
263             action='create', resource='Custom Object: Network')
264
265
266 def delete_network(scope, group, version, plural, name, namespace='default'):
267     api = get_custom_objects_api()
268     try:
269         if scope == consts.SCOPE_CLUSTER:
270             api.delete_cluster_custom_object(group, version, plural, name, {})
271         else:
272             api.delete_namespaced_custom_object(
273                 group, version, namespace, plural, name, {})
274     except ApiException:
275         raise exceptions.KubernetesApiException(
276             action='delete', resource='Custom Object: Network')
277
278
279 def get_pod_list(namespace='default'):      # pragma: no cover
280     core_v1_api = get_core_api()
281     try:
282         return core_v1_api.list_namespaced_pod(namespace=namespace)
283     except ApiException:
284         LOG.exception('Get pod list failed')
285         raise
286
287
288 def get_pod_by_name(name):  # pragma: no cover
289     pod_list = get_pod_list()
290     return next((n for n in pod_list.items if n.metadata.name.startswith(name)), None)
291
292
293 def get_volume_types():
294     """Return the "volume" types supported by the current API"""
295     return [vtype for vtype in client.V1Volume.attribute_map.values()
296             if vtype != 'name']