def get_ssh_client(hostname, username, password=None, proxy=None, pkey_file=None): client = None try: if proxy is None: client = paramiko.SSHClient() else: client = ProxyHopClient() client.configure_jump_host(proxy['ip'], proxy['username'], proxy['password']) if client is None: raise Exception('Could not connect to client') client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) if pkey_file is not None: key = paramiko.RSAKey.from_private_key_file(pkey_file) client.load_system_host_keys() client.connect(hostname, username=username, pkey=key, timeout=SSH_TIMEOUT) else: client.connect(hostname, username=username, password=password, timeout=SSH_TIMEOUT) return client except Exception as e: logger.error(e) return None
def put_file(ssh_conn, src, dest): try: sftp = ssh_conn.open_sftp() sftp.put(src, dest) return True except Exception as e: logger.error("Error [put_file(ssh_conn, '%s', '%s']: %s" % (src, dest, e)) return None
def get_deployment_status(self): if self.deployment_status is not None: logger.debug('Skip - Node status has been retrieved once') return self.deployment_status for k, v in self.nodes_dict.iteritems(): if manager.Role.CONTROLLER in v['roles']: cmd = 'source /opt/admin-openrc.sh; nova hypervisor-list;' ''' +----+---------------------+-------+---------+ | ID | Hypervisor hostname | State | Status | +----+---------------------+-------+---------+ | 3 | host4 | up | enabled | | 6 | host5 | up | enabled | +----+---------------------+-------+---------+ ''' _, stdout, stderr = (v['ssh_client'].exec_command(cmd)) error = stderr.readlines() if len(error) > 0: logger.error("error %s" % ''.join(error)) status = manager.NodeStatus.STATUS_ERROR v['status'] = status continue lines = stdout.readlines() for i in range(3, len(lines) - 1): fields = lines[i].strip().encode().rsplit(' | ') hostname = fields[1].strip().encode().lower() state = fields[2].strip().encode().lower() if 'up' == state: status = manager.NodeStatus.STATUS_OK else: status = manager.NodeStatus.STATUS_ERROR self.nodes_dict[hostname]['status'] = status v['status'] = manager.NodeStatus.STATUS_OK failed_nodes = [ k for k, v in self.nodes_dict.iteritems() if v['status'] != manager.NodeStatus.STATUS_OK ] if failed_nodes and len(failed_nodes) > 0: return 'Hosts {0} failed'.format(','.join(failed_nodes)) return 'active'
def put_file(self, src, dest): ''' SCP file to a node ''' if self.status is not NodeStatus.STATUS_OK: logger.info("The node %s is not active" % self.ip) return 1 logger.info("Copying %s to %s" % (src, self.ip)) put_file_result = ssh_utils.put_file(self.ssh_client, src, dest) if put_file_result is None: logger.error("SFTP failed to retrieve the file.") else: logger.info("Successfully copied %s to %s:%s" % (src, dest, self.ip)) return put_file_result
def run_cmd(self, cmd): ''' Run command remotely on a node ''' if self.status is not NodeStatus.STATUS_OK: logger.error( "Error running command %s. The node %s is not active" % (cmd, self.ip)) return None _, stdout, stderr = (self.ssh_client.exec_command(cmd)) error = stderr.readlines() if len(error) > 0: logger.error("error %s" % ''.join(error)) return None output = ''.join(stdout.readlines()).rstrip() return output
def connect(self, hostname, port=22, username='******', password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None): try: if self.proxy_ssh is None: raise Exception('You must configure the jump ' 'host before calling connect') get_file_res = get_file(self.proxy_ssh, self.proxy_ssh_key, self.local_ssh_key) if get_file_res is None: raise Exception('Could\'t fetch SSH key from jump host') if self.proxy_ssh_key.split('/')[-1] == 'id_dsa': proxy_key = (paramiko.DSSKey.from_private_key_file( self.local_ssh_key)) else: proxy_key = (paramiko.RSAKey.from_private_key_file( self.local_ssh_key)) self.proxy_channel = self.proxy_transport.open_channel( "direct-tcpip", (hostname, 22), (self.proxy_ip, 22)) self.set_missing_host_key_policy(paramiko.AutoAddPolicy()) super(ProxyHopClient, self).connect(hostname, username=username, pkey=proxy_key, sock=self.proxy_channel, timeout=timeout) os.remove(self.local_ssh_key) except Exception as e: logger.error(e)
def get_nodes(self, options=None): try: # if we have retrieved previously all the nodes, don't do it again # This fails the first time when the constructor calls this method # therefore the try/except if len(self.nodes) > 0: return self.nodes except: pass with open(self.DST_PATH_UC, 'r') as stream: try: file = yaml.load(stream) raw_nodes = self._find_nodes(file) except yaml.YAMLError as exc: logger.error(exc) self.nodes = self._process_nodes(raw_nodes) return self.nodes
def _get_deployment_nodes(self): sql_query = ('select host.host_id, host.roles, ' 'network.ip_int, machine.mac from clusterhost as host, ' 'host_network as network, machine as machine ' 'where host.host_id=network.host_id ' 'and host.id=machine.id;') cmd = 'mysql -uroot -Dcompass -e "{0}"'.format(sql_query) logger.debug('mysql command: %s', cmd) output = self.installer_node.run_cmd(cmd) ''' host_id roles ip_int mac 1 ["controller", "ha", "odl", "ceph-adm", "ceph-mon"] 167837746 00:00:e3:ee:a8:63 2 ["controller", "ha", "odl", "ceph-mon"] 167837747 00:00:31:1d:16:7a 3 ["controller", "ha", "odl", "ceph-mon"] 167837748 00:00:0c:bf:eb:01 4 ["compute", "ceph-osd"] 167837749 00:00:d8:22:6f:59 5 ["compute", "ceph-osd"] 167837750 00:00:75:d5:6b:9e ''' lines = output.encode().rsplit('\n') nodes_dict = {} if (not lines or len(lines) < 2): logger.error('No nodes are found in the deployment.') return nodes_dict proxy = { 'ip': self.installer_ip, 'username': self.installer_user, 'password': self.installer_pwd } for i in range(1, len(lines)): fields = lines[i].strip().encode().rsplit('\t') host_id = fields[0].strip().encode() name = 'host{0}'.format(host_id) node_roles_str = fields[1].strip().encode().lower() node_roles_list = json.loads(node_roles_str) node_roles = [ manager.Role.ODL if x == 'odl' else x for x in node_roles_list ] roles = [ x for x in [ manager.Role.CONTROLLER, manager.Role.COMPUTE, manager.Role.ODL, manager.Role.ONOS ] if x in node_roles ] ip = fields[2].strip().encode() ip = str(netaddr.IPAddress(ip)) mac = fields[3].strip().encode() nodes_dict[name] = {} nodes_dict[name]['id'] = host_id nodes_dict[name]['roles'] = roles nodes_dict[name]['ip'] = ip nodes_dict[name]['mac'] = mac ssh_client = ssh_utils.get_ssh_client(hostname=ip, username='******', proxy=proxy) nodes_dict[name]['ssh_client'] = ssh_client nodes_dict[name]['status'] = manager.NodeStatus.STATUS_UNKNOWN return nodes_dict