1 ##############################################################################
2 # Copyright (c) 2017 Ericsson AB and others.
3 # Author: Jose Lausuch (jose.lausuch@ericsson.com)
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 ##############################################################################
10 from abc import abstractmethod
14 from opnfv.utils import opnfv_logger as logger
15 from opnfv.utils import ssh_utils
17 logger = logger.Logger(__name__).getLogger()
20 class Deployment(object):
32 self.deployment_info = {
33 'installer': installer,
34 'installer_ip': installer_ip,
38 'openstack_version': openstack_version,
39 'sdn_controller': sdn_controller,
43 def _get_openstack_release(self):
45 Translates an openstack version into the release name
56 version = self.deployment_info['openstack_version'].split('.')[0]
57 name = os_versions[version]
60 return 'Unknown release'
64 Returns a dictionary will all the attributes
66 return self.deployment_info
70 Override of the str method
73 INSTALLER: {installer}
75 INSTALLER IP: {installer_ip}
78 OPENSTACK: {openstack_version} ({openstack_release})
81 '''.format(installer=self.deployment_info['installer'],
82 scenario=self.deployment_info['scenario'],
83 installer_ip=self.deployment_info['installer_ip'],
84 pod=self.deployment_info['pod'],
85 status=self.deployment_info['status'],
86 openstack_version=self.deployment_info[
88 openstack_release=self._get_openstack_release(),
89 sdn_controller=self.deployment_info['sdn_controller'])
91 for node in self.deployment_info['nodes']:
92 s += '{node_object}\n'.format(node_object=node)
98 INSTALLER = 'installer'
99 CONTROLLER = 'controller'
107 STATUS_INACTIVE = 'inactive'
108 STATUS_OFFLINE = 'offline'
109 STATUS_ERROR = 'error'
110 STATUS_UNUSED = 'unused'
111 STATUS_UNKNOWN = 'unknown'
128 self.ssh_client = ssh_client
132 self.cpu_info = 'unknown'
133 self.memory = 'unknown'
136 if ssh_client and Role.INSTALLER not in self.roles:
137 sys_info = self.get_system_info()
138 self.cpu_info = sys_info['cpu_info']
139 self.memory = sys_info['memory']
140 self.ovs = self.get_ovs_info()
142 def get_file(self, src, dest):
146 if self.status is not NodeStatus.STATUS_OK:
147 logger.info("The node %s is not active" % self.ip)
149 logger.info("Fetching %s from %s" % (src, self.ip))
150 get_file_result = ssh_utils.get_file(self.ssh_client, src, dest)
151 if get_file_result is None:
152 logger.error("SFTP failed to retrieve the file.")
154 logger.info("Successfully copied %s:%s to %s" %
155 (self.ip, src, dest))
156 return get_file_result
158 def put_file(self, src, dest):
162 if self.status is not NodeStatus.STATUS_OK:
163 logger.info("The node %s is not active" % self.ip)
165 logger.info("Copying %s to %s" % (src, self.ip))
166 put_file_result = ssh_utils.put_file(self.ssh_client, src, dest)
167 if put_file_result is None:
168 logger.error("SFTP failed to retrieve the file.")
170 logger.info("Successfully copied %s to %s:%s" %
171 (src, dest, self.ip))
172 return put_file_result
174 def run_cmd(self, cmd):
176 Run command remotely on a node
178 if self.status is not NodeStatus.STATUS_OK:
180 "Error running command %s. The node %s is not active"
183 _, stdout, stderr = (self.ssh_client.exec_command(cmd))
184 error = stderr.readlines()
186 logger.error("error %s" % ''.join(error))
188 output = ''.join(stdout.readlines()).rstrip()
193 Returns a dictionary with all the attributes
199 'status': self.status,
201 'cpu_info': self.cpu_info,
202 'memory': self.memory,
209 Returns if the node is active
211 if self.status == NodeStatus.STATUS_OK:
215 def is_controller(self):
217 Returns if the node is a controller
219 return Role.CONTROLLER in self.roles
221 def is_compute(self):
223 Returns if the node is a compute
225 return Role.COMPUTE in self.roles
229 Returns if the node is an opendaylight
231 return Role.ODL in self.roles
235 Returns if the node is an ONOS
237 return Role.ONOS in self.roles
239 def get_ovs_info(self):
241 Returns the ovs version installed
244 cmd = "ovs-vsctl --version|head -1| sed 's/^.*) //'"
245 return self.run_cmd(cmd)
248 def get_system_info(self):
250 Returns the ovs version installed
252 cmd = 'grep MemTotal /proc/meminfo'
253 memory = self.run_cmd(cmd).partition('MemTotal:')[-1].strip().encode()
257 result = self.run_cmd(cmd)
258 for line in result.splitlines():
259 if line.startswith('CPU(s)'):
260 cpu_info['num_cpus'] = line.split(' ')[-1].encode()
261 elif line.startswith('Thread(s) per core'):
262 cpu_info['threads/core'] = line.split(' ')[-1].encode()
263 elif line.startswith('Core(s) per socket'):
264 cpu_info['cores/socket'] = line.split(' ')[-1].encode()
265 elif line.startswith('Model name'):
266 cpu_info['model'] = line.partition(
267 'Model name:')[-1].strip().encode()
268 elif line.startswith('Architecture'):
269 cpu_info['arch'] = line.split(' ')[-1].encode()
271 return {'memory': memory, 'cpu_info': cpu_info}
283 info: {info}'''.format(name=self.name,
288 cpu_info=self.cpu_info,
294 class DeploymentHandler(object):
297 EX_ERROR = os.EX_SOFTWARE
298 FUNCTION_NOT_IMPLEMENTED = "Function not implemented by adapter!"
307 self.installer = installer.lower()
308 self.installer_ip = installer_ip
309 self.installer_user = installer_user
310 self.installer_pwd = installer_pwd
311 self.pkey_file = pkey_file
313 if pkey_file is not None and not os.path.isfile(pkey_file):
315 'The private key file %s does not exist!' % pkey_file)
317 self.installer_connection = ssh_utils.get_ssh_client(
318 hostname=self.installer_ip,
319 username=self.installer_user,
320 password=self.installer_pwd,
321 pkey_file=self.pkey_file)
323 if self.installer_connection:
324 self.installer_node = Node(id='',
327 status=NodeStatus.STATUS_OK,
328 ssh_client=self.installer_connection,
329 roles=Role.INSTALLER)
332 'Cannot establish connection to the installer node!')
334 self.nodes = self.get_nodes()
337 def get_openstack_version(self):
339 Returns a string of the openstack version (nova-compute)
341 raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
344 def get_sdn_version(self):
346 Returns a string of the sdn controller and its version, if exists
348 raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
351 def get_deployment_status(self):
353 Returns a string of the status of the deployment
355 raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
358 def get_nodes(self, options=None):
360 Generates a list of all the nodes in the deployment
362 raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
364 def get_installer_node(self):
366 Returns the installer node object
368 return self.installer_node
372 Returns the architecture of the first compute node found
375 for node in self.nodes:
376 if node.is_compute():
377 arch = node.cpu_info.get('arch', None)
382 def get_deployment_info(self):
384 Returns an object of type Deployment
386 return Deployment(installer=self.installer,
387 installer_ip=self.installer_ip,
388 scenario=os.getenv('DEPLOY_SCENARIO', 'Unknown'),
389 status=self.get_deployment_status(),
390 pod=os.getenv('NODE_NAME', 'Unknown'),
391 openstack_version=self.get_openstack_version(),
392 sdn_controller=self.get_sdn_version(),