Merge "Add new Kubernetes resource kind: "CustomResourceDefinition""
[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_node_list(**kwargs):        # pragma: no cover
40     core_v1_api = get_core_api()
41     try:
42         return core_v1_api.list_node(**kwargs)
43     except ApiException:
44         LOG.exception('Get node list failed')
45         raise
46
47
48 def create_service(template,
49                    namespace='default',
50                    wait=False,
51                    **kwargs):       # pragma: no cover
52     # pylint: disable=unused-argument
53     core_v1_api = get_core_api()
54     metadata = client.V1ObjectMeta(**template.get('metadata', {}))
55
56     ports = [client.V1ServicePort(**port) for port in
57              template.get('spec', {}).get('ports', [])]
58     template['spec']['ports'] = ports
59     spec = client.V1ServiceSpec(**template.get('spec', {}))
60
61     service = client.V1Service(metadata=metadata, spec=spec)
62
63     try:
64         core_v1_api.create_namespaced_service('default', service)
65     except ApiException:
66         LOG.exception('Create Service failed')
67         raise
68
69
70 def delete_service(name,
71                    namespace='default',
72                    **kwargs):       # pragma: no cover
73     core_v1_api = get_core_api()
74     try:
75         body = client.V1DeleteOptions()
76         core_v1_api.delete_namespaced_service(name, namespace, body, **kwargs)
77     except ApiException:
78         LOG.exception('Delete Service failed')
79
80
81 def get_service_list(namespace='default', **kwargs):
82     core_v1_api = get_core_api()
83     try:
84         return core_v1_api.list_namespaced_service(namespace, **kwargs)
85     except ApiException:
86         LOG.exception('Get Service list failed')
87         raise
88
89
90 def get_service_by_name(name):      # pragma: no cover
91     service_list = get_service_list()
92     return next((s.spec for s in service_list.items if s.metadata.name == name), None)
93
94
95 def create_replication_controller(template,
96                                   namespace='default',
97                                   wait=False,
98                                   **kwargs):    # pragma: no cover
99     # pylint: disable=unused-argument
100     core_v1_api = get_core_api()
101     try:
102         core_v1_api.create_namespaced_replication_controller(namespace,
103                                                              template,
104                                                              **kwargs)
105     except ApiException:
106         LOG.exception('Create replication controller failed')
107         raise
108
109
110 def delete_replication_controller(name,
111                                   namespace='default',
112                                   wait=False,
113                                   **kwargs):    # pragma: no cover
114     # pylint: disable=unused-argument
115     core_v1_api = get_core_api()
116     body = kwargs.get('body', client.V1DeleteOptions())
117     kwargs.pop('body', None)
118     try:
119         core_v1_api.delete_namespaced_replication_controller(name,
120                                                              namespace,
121                                                              body,
122                                                              **kwargs)
123     except ApiException:
124         LOG.exception('Delete replication controller failed')
125         raise
126
127
128 def delete_pod(name,
129                namespace='default',
130                wait=False,
131                **kwargs):    # pragma: no cover
132     # pylint: disable=unused-argument
133     core_v1_api = get_core_api()
134     body = kwargs.get('body', client.V1DeleteOptions())
135     kwargs.pop('body', None)
136     try:
137         core_v1_api.delete_namespaced_pod(name,
138                                           namespace,
139                                           body,
140                                           **kwargs)
141     except ApiException:
142         LOG.exception('Delete pod failed')
143         raise
144
145
146 def read_pod(name,
147              namespace='default',
148              **kwargs):  # pragma: no cover
149     core_v1_api = get_core_api()
150     try:
151         resp = core_v1_api.read_namespaced_pod(name, namespace, **kwargs)
152     except ApiException:
153         LOG.exception('Read pod failed')
154         raise
155     else:
156         return resp
157
158
159 def read_pod_status(name, namespace='default', **kwargs):   # pragma: no cover
160     # pylint: disable=unused-argument
161     return read_pod(name).status.phase
162
163
164 def create_config_map(name,
165                       data,
166                       namespace='default',
167                       wait=False,
168                       **kwargs):   # pragma: no cover
169     # pylint: disable=unused-argument
170     core_v1_api = get_core_api()
171     metadata = client.V1ObjectMeta(name=name)
172     body = client.V1ConfigMap(data=data, metadata=metadata)
173     try:
174         core_v1_api.create_namespaced_config_map(namespace, body, **kwargs)
175     except ApiException:
176         LOG.exception('Create config map failed')
177         raise
178
179
180 def delete_config_map(name,
181                       namespace='default',
182                       wait=False,
183                       **kwargs):     # pragma: no cover
184     # pylint: disable=unused-argument
185     core_v1_api = get_core_api()
186     body = kwargs.get('body', client.V1DeleteOptions())
187     kwargs.pop('body', None)
188     try:
189         core_v1_api.delete_namespaced_config_map(name,
190                                                  namespace,
191                                                  body,
192                                                  **kwargs)
193     except ApiException:
194         LOG.exception('Delete config map failed')
195         raise
196
197
198 def create_custom_resource_definition(body):
199     api = get_extensions_v1beta_api()
200     body_obj = client.V1beta1CustomResourceDefinition(
201         spec=body['spec'], metadata=body['metadata'])
202     try:
203         api.create_custom_resource_definition(body_obj)
204     except ValueError:
205         # NOTE(ralonsoh): bug in kubernetes-client/python 6.0.0
206         # https://github.com/kubernetes-client/python/issues/491
207         pass
208     except ApiException:
209         raise exceptions.KubernetesApiException(
210             action='create', resource='CustomResourceDefinition')
211
212
213 def delete_custom_resource_definition(name):
214     api = get_extensions_v1beta_api()
215     body_obj = client.V1DeleteOptions()
216     try:
217         api.delete_custom_resource_definition(name, body_obj)
218     except ApiException:
219         raise exceptions.KubernetesApiException(
220             action='delete', resource='CustomResourceDefinition')
221
222
223 def get_pod_list(namespace='default'):      # pragma: no cover
224     core_v1_api = get_core_api()
225     try:
226         return core_v1_api.list_namespaced_pod(namespace=namespace)
227     except ApiException:
228         LOG.exception('Get pod list failed')
229         raise
230
231
232 def get_pod_by_name(name):  # pragma: no cover
233     pod_list = get_pod_list()
234     return next((n for n in pod_list.items if n.metadata.name.startswith(name)), None)
235
236
237 def get_volume_types():
238     """Return the "volume" types supported by the current API"""
239     return [vtype for vtype in client.V1Volume.attribute_map.values()
240             if vtype != 'name']