Merge "Module to manage pip packages"
[yardstick.git] / yardstick / orchestrator / kubernetes.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
10 from __future__ import absolute_import
11 from __future__ import print_function
12
13 from yardstick.common import utils
14 from yardstick.common import kubernetes_utils as k8s_utils
15
16
17 class KubernetesObject(object):
18
19     def __init__(self, name, **kwargs):
20         super(KubernetesObject, self).__init__()
21         self.name = name
22         self.image = kwargs.get('image', 'openretriever/yardstick')
23         self.command = [kwargs.get('command', '/bin/bash')]
24         self.args = kwargs.get('args', [])
25         self.ssh_key = kwargs.get('ssh_key', 'yardstick_key')
26         self.node_selector = kwargs.get('nodeSelector', {})
27
28         self.volumes = []
29
30         self.template = {
31             "apiVersion": "v1",
32             "kind": "ReplicationController",
33             "metadata": {
34                 "name": ""
35             },
36             "spec": {
37                 "replicas": 1,
38                 "template": {
39                     "metadata": {
40                         "labels": {
41                             "app": name
42                         }
43                     },
44                     "spec": {
45                         "containers": [],
46                         "volumes": [],
47                         "nodeSelector": {}
48                     }
49                 }
50             }
51         }
52
53         self._change_value_according_name(name)
54         self._add_containers()
55         self._add_node_selector()
56         self._add_ssh_key_volume()
57         self._add_volumes()
58
59     def get_template(self):
60         return self.template
61
62     def _change_value_according_name(self, name):
63         utils.set_dict_value(self.template, 'metadata.name', name)
64
65         utils.set_dict_value(self.template,
66                              'spec.template.metadata.labels.app',
67                              name)
68
69     def _add_containers(self):
70         containers = [self._add_container()]
71         utils.set_dict_value(self.template,
72                              'spec.template.spec.containers',
73                              containers)
74
75     def _add_container(self):
76         container_name = '{}-container'.format(self.name)
77         ssh_key_mount_path = "/root/.ssh/"
78
79         container = {
80             "args": self.args,
81             "command": self.command,
82             "image": self.image,
83             "name": container_name,
84             "volumeMounts": [
85                 {
86                     "mountPath": ssh_key_mount_path,
87                     "name": self.ssh_key
88                 }
89             ]
90         }
91
92         return container
93
94     def _add_node_selector(self):
95         utils.set_dict_value(self.template,
96                              'spec.template.spec.nodeSelector',
97                              self.node_selector)
98
99     def _add_volumes(self):
100         utils.set_dict_value(self.template,
101                              'spec.template.spec.volumes',
102                              self.volumes)
103
104     def _add_volume(self, volume):
105         self.volumes.append(volume)
106
107     def _add_ssh_key_volume(self):
108         key_volume = {
109             "configMap": {
110                 "name": self.ssh_key
111             },
112             "name": self.ssh_key
113         }
114         self._add_volume(key_volume)
115
116
117 class ServiceObject(object):
118
119     def __init__(self, name):
120         self.name = '{}-service'.format(name)
121         self.template = {
122             'metadata': {
123                 'name': '{}-service'.format(name)
124             },
125             'spec': {
126                 'type': 'NodePort',
127                 'ports': [
128                     {
129                         'port': 22,
130                         'protocol': 'TCP'
131                     }
132                 ],
133                 'selector': {
134                     'app': name
135                 }
136             }
137         }
138
139     def create(self):
140         k8s_utils.create_service(self.template)
141
142     def delete(self):
143         k8s_utils.delete_service(self.name)
144
145
146 class KubernetesTemplate(object):
147
148     def __init__(self, name, template_cfg):
149         self.name = name
150         self.ssh_key = '{}-key'.format(name)
151
152         self.rcs = [self._get_rc_name(rc) for rc in template_cfg]
153         self.k8s_objs = [KubernetesObject(self._get_rc_name(rc),
154                                           ssh_key=self.ssh_key,
155                                           **cfg)
156                          for rc, cfg in template_cfg.items()]
157         self.service_objs = [ServiceObject(s) for s in self.rcs]
158
159         self.pods = []
160
161     def _get_rc_name(self, rc_name):
162         return '{}-{}'.format(rc_name, self.name)
163
164     def get_rc_pods(self):
165         resp = k8s_utils.get_pod_list()
166         self.pods = [p.metadata.name for p in resp.items for s in self.rcs
167                      if p.metadata.name.startswith(s)]
168
169         return self.pods