1 ##############################################################################
2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd.
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 ##############################################################################
12 from yardstick.common import exceptions
13 from yardstick.common import utils
14 from yardstick.common import kubernetes_utils as k8s_utils
17 class ContainerObject(object):
19 SSH_MOUNT_PATH = '/tmp/.ssh/'
20 IMAGE_DEFAULT = 'openretriever/yardstick'
21 COMMAND_DEFAULT = '/bin/bash'
23 def __init__(self, name, ssh_key, **kwargs):
25 self._ssh_key = ssh_key
26 self._image = kwargs.get('image', self.IMAGE_DEFAULT)
27 self._command = [kwargs.get('command', self.COMMAND_DEFAULT)]
28 self._args = kwargs.get('args', [])
29 self._volume_mounts = kwargs.get('volumeMounts', [])
30 self._security_context = kwargs.get('securityContext')
32 def _create_volume_mounts(self):
33 """Return all "volumeMounts" items per container"""
34 volume_mounts_items = [self._create_volume_mounts_item(vol)
35 for vol in self._volume_mounts]
36 ssh_vol = {'name': self._ssh_key,
37 'mountPath': self.SSH_MOUNT_PATH}
38 volume_mounts_items.append(self._create_volume_mounts_item(ssh_vol))
39 return volume_mounts_items
42 def _create_volume_mounts_item(volume_mount):
43 """Create a "volumeMounts" item"""
44 return {'name': volume_mount['name'],
45 'mountPath': volume_mount['mountPath'],
46 'readOnly': volume_mount.get('readOnly', False)}
48 def get_container_item(self):
49 """Create a "container" item"""
50 container_name = '{}-container'.format(self._name)
51 container = {'args': self._args,
52 'command': self._command,
54 'name': container_name,
55 'volumeMounts': self._create_volume_mounts()}
56 if self._security_context:
57 container['securityContext'] = self._security_context
61 class KubernetesObject(object):
63 SSHKEY_DEFAULT = 'yardstick_key'
65 def __init__(self, name, **kwargs):
66 super(KubernetesObject, self).__init__()
67 parameters = copy.deepcopy(kwargs)
69 self.node_selector = parameters.pop('nodeSelector', {})
70 self.ssh_key = parameters.pop('ssh_key', self.SSHKEY_DEFAULT)
71 self._volumes = parameters.pop('volumes', [])
72 self._security_context = parameters.pop('securityContext', None)
74 containers = parameters.pop('containers', None)
77 ContainerObject(self.name, self.ssh_key, **container)
78 for container in containers]
81 ContainerObject(self.name, self.ssh_key, **parameters)]
85 "kind": "ReplicationController",
106 self._change_value_according_name(name)
107 self._add_containers()
108 self._add_node_selector()
110 self._add_security_context()
112 def get_template(self):
115 def _change_value_according_name(self, name):
116 utils.set_dict_value(self.template, 'metadata.name', name)
118 utils.set_dict_value(self.template,
119 'spec.template.metadata.labels.app',
122 def _add_containers(self):
123 containers = [container.get_container_item()
124 for container in self._containers]
125 utils.set_dict_value(self.template,
126 'spec.template.spec.containers',
129 def _add_node_selector(self):
130 utils.set_dict_value(self.template,
131 'spec.template.spec.nodeSelector',
134 def _add_volumes(self):
135 """Add "volume" items to container specs, including the SSH one"""
136 volume_items = [self._create_volume_item(vol) for vol in self._volumes]
137 volume_items.append(self._create_ssh_key_volume())
138 utils.set_dict_value(self.template,
139 'spec.template.spec.volumes',
142 def _create_ssh_key_volume(self):
143 """Create a "volume" item of type "configMap" for the SSH key"""
144 return {'name': self.ssh_key,
145 'configMap': {'name': self.ssh_key}}
148 def _create_volume_item(volume):
149 """Create a "volume" item"""
150 volume = copy.deepcopy(volume)
151 name = volume.pop('name')
152 for key in (k for k in volume if k in k8s_utils.get_volume_types()):
154 type_data = volume[key]
157 raise exceptions.KubernetesTemplateInvalidVolumeType(volume=volume)
159 return {'name': name,
160 type_name: type_data}
162 def _add_security_context(self):
163 if self._security_context:
164 utils.set_dict_value(self.template,
165 'spec.template.spec.securityContext',
166 self._security_context)
169 class ServiceObject(object):
171 def __init__(self, name):
172 self.name = '{}-service'.format(name)
175 'name': '{}-service'.format(name)
192 k8s_utils.create_service(self.template)
195 k8s_utils.delete_service(self.name)
198 class KubernetesTemplate(object):
200 def __init__(self, name, context_cfg):
201 """KubernetesTemplate object initialization
203 :param name: (str) name of the Kubernetes context
204 :param context_cfg: (dict) context definition
206 context_cfg = copy.deepcopy(context_cfg)
207 servers_cfg = context_cfg.pop('servers', {})
209 self.ssh_key = '{}-key'.format(name)
211 self.rcs = [self._get_rc_name(rc) for rc in servers_cfg]
212 self.k8s_objs = [KubernetesObject(self._get_rc_name(rc),
213 ssh_key=self.ssh_key,
215 for rc, cfg in servers_cfg.items()]
216 self.service_objs = [ServiceObject(s) for s in self.rcs]
220 def _get_rc_name(self, rc_name):
221 return '{}-{}'.format(rc_name, self.name)
223 def get_rc_pods(self):
224 resp = k8s_utils.get_pod_list()
225 self.pods = [p.metadata.name for p in resp.items for s in self.rcs
226 if p.metadata.name.startswith(s)]