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 ##############################################################################
17 from yardstick.benchmark import contexts
18 from yardstick.benchmark.contexts import base as ctx_base
19 from yardstick.benchmark.contexts import model
20 from yardstick.common import constants
21 from yardstick.common import exceptions
22 from yardstick.common import kubernetes_utils as k8s_utils
23 from yardstick.common import utils
24 from yardstick.orchestrator import kubernetes
27 LOG = logging.getLogger(__name__)
31 class KubernetesContext(ctx_base.Context):
32 """Class that handle nodes info"""
34 __context_type__ = contexts.CONTEXT_KUBERNETES
39 self.public_key_path = ''
41 super(KubernetesContext, self).__init__(host_name_separator='-')
43 def init(self, attrs):
44 super(KubernetesContext, self).init(attrs)
46 networks = attrs.get('networks', {})
47 self.template = kubernetes.KubernetesTemplate(self.name, attrs)
48 self.ssh_key = '{}-key'.format(self.name)
49 self.key_path = self._get_key_path()
50 self.public_key_path = '{}.pub'.format(self.key_path)
51 self._networks = collections.OrderedDict(
52 (net_name, model.Network(net_name, self, network))
53 for net_name, network in networks.items())
56 LOG.info('Creating ssh key')
60 self._create_networks()
61 LOG.info('Launch containers')
63 self._create_services()
65 self.template.get_rc_pods()
67 self._wait_until_running()
70 self._delete_ssh_key()
73 self._delete_services()
74 self._delete_networks()
77 super(KubernetesContext, self).undeploy()
79 def _wait_until_running(self):
80 while not all(self._check_pod_status(p) for p in self.template.pods):
83 def _check_pod_status(self, pod):
84 status = k8s_utils.read_pod_status(pod)
85 LOG.debug('%s:%s', pod, status)
86 if status == 'Failed':
87 LOG.error('Pod %s status is failed', pod)
89 if status != 'Running':
93 def _create_services(self):
94 for obj in self.template.service_objs:
97 def _delete_services(self):
98 for obj in self.template.service_objs:
101 def _create_rcs(self):
102 for obj in self.template.rc_objs:
103 self._create_rc(obj.get_template())
105 def _create_rc(self, template):
106 k8s_utils.create_replication_controller(template)
108 def _delete_rcs(self):
109 for rc in self.template.rcs:
112 def _delete_rc(self, rc):
113 k8s_utils.delete_replication_controller(rc, skip_codes=[404])
115 def _delete_pods(self):
116 for pod in self.template.pods:
117 self._delete_pod(pod)
119 def _delete_pod(self, pod):
120 k8s_utils.delete_pod(pod, skip_codes=[404])
122 def _create_crd(self):
123 LOG.info('Create Custom Resource Definition elements')
124 for crd in self.template.crd:
127 def _delete_crd(self):
128 LOG.info('Delete Custom Resource Definition elements')
129 for crd in self.template.crd:
132 def _create_networks(self): # pragma: no cover
133 LOG.info('Create Network elements')
134 for net in self.template.network_objs:
137 def _delete_networks(self): # pragma: no cover
138 LOG.info('Create Network elements')
139 for net in self.template.network_objs:
142 def _get_key_path(self):
143 task_id = self.name.split('-')[-1]
144 k = 'files/yardstick_key-{}'.format(task_id)
145 return pkg_resources.resource_filename('yardstick.resources', k)
147 def _set_ssh_key(self):
148 rsa_key = paramiko.RSAKey.generate(bits=BITS_LENGTH)
150 LOG.info('Writing private key')
151 rsa_key.write_private_key_file(self.key_path)
153 LOG.info('Writing public key')
154 key = '{} {}\n'.format(rsa_key.get_name(), rsa_key.get_base64())
155 with open(self.public_key_path, 'w') as f:
158 LOG.info('Create configmap for ssh key')
159 k8s_utils.create_config_map(self.ssh_key, {'authorized_keys': key})
161 def _delete_ssh_key(self):
162 k8s_utils.delete_config_map(self.ssh_key, skip_codes=[404])
163 utils.remove_file(self.key_path)
164 utils.remove_file(self.public_key_path)
166 def _get_server(self, name):
167 node_ports = self._get_service_ports(name)
168 for sn_port in (sn_port for sn_port in node_ports
169 if sn_port['port'] == constants.SSH_PORT):
170 node_port = sn_port['node_port']
173 raise exceptions.KubernetesSSHPortNotDefined()
177 'ip': self._get_node_ip(),
178 'private_ip': k8s_utils.get_pod_by_name(name).status.pod_ip,
179 'ssh_port': node_port,
181 'key_filename': self.key_path,
182 'interfaces': self._get_interfaces(name),
183 'service_ports': node_ports
186 def _get_network(self, net_name):
187 """Retrieves the network object, searching by name
189 :param net_name: (str) replication controller name
190 :return: (dict) network information (name)
192 network = self._networks.get(net_name)
195 return {'name': net_name}
197 def _get_interfaces(self, rc_name):
198 """Retrieves the network list of a replication controller
200 :param rc_name: (str) replication controller name
201 :return: (dict) names and information of the networks used in this
202 replication controller; those networks must be defined in the
205 rc = self.template.get_rc_by_name(rc_name)
208 return {name: {'network_name': name,
211 for name in rc.networks}
213 def _get_node_ip(self):
214 return k8s_utils.get_node_list().items[0].status.addresses[0].address
216 def _get_physical_nodes(self):
219 def _get_physical_node_for_server(self, server_name):
222 def _get_service_ports(self, name):
223 service_name = '{}-service'.format(name)
224 service = k8s_utils.get_service_by_name(service_name)
226 raise exceptions.KubernetesServiceObjectNotDefined()
228 for port in service.ports:
229 ports.append({'name': port.name,
230 'node_port': port.node_port,
232 'protocol': port.protocol,
233 'target_port': port.target_port})