def _test_compromising_ssh(self, rc, check): fixture = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) fake_stdin = six.BytesIO() fake_stdout = mock.Mock() fake_stdout.channel.recv_exit_status.return_value = rc fake_stdout.read.return_value = b'password="******"' fake_stderr = mock.Mock() fake_stderr.read.return_value = b'password="******"' command = 'ls --password="******"' connection = mock.Mock() connection.exec_command.return_value = (fake_stdin, fake_stdout, fake_stderr) if check and rc != -1 and rc != 0: err = self.assertRaises(processutils.ProcessExecutionError, processutils.ssh_execute, connection, command, check_exit_code=check) self.assertEqual(rc, err.exit_code) self.assertEqual('password="******"', err.stdout) self.assertEqual('password="******"', err.stderr) self.assertEqual('ls --password="******"', err.cmd) self.assertNotIn('secret', str(err)) self.assertNotIn('foobar', str(err)) # test ssh_execute with sanitize_stdout=False err = self.assertRaises(processutils.ProcessExecutionError, processutils.ssh_execute, connection, command, check_exit_code=check, sanitize_stdout=False) self.assertEqual(rc, err.exit_code) self.assertEqual('password="******"', err.stdout) self.assertEqual('password="******"', err.stderr) self.assertEqual('ls --password="******"', err.cmd) self.assertNotIn('secret', str(err)) self.assertNotIn('foobar', str(err)) else: o, e = processutils.ssh_execute(connection, command, check_exit_code=check) self.assertEqual('password="******"', o) self.assertEqual('password="******"', e) self.assertIn('password="******"', fixture.output) self.assertNotIn('bar', fixture.output) # test ssh_execute with sanitize_stdout=False o, e = processutils.ssh_execute(connection, command, check_exit_code=check, sanitize_stdout=False) self.assertEqual('password="******"', o) self.assertEqual('password="******"', e) self.assertIn('password="******"', fixture.output) self.assertNotIn('bar', fixture.output)
def _run_ssh(self, host, cmd_list, check_exit_code=True): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) if not self.sshpool: gpfs_ssh_login = self.configuration.gpfs_ssh_login password = self.configuration.gpfs_ssh_password privatekey = self.configuration.gpfs_ssh_private_key gpfs_ssh_port = self.configuration.gpfs_ssh_port ssh_conn_timeout = self.configuration.ssh_conn_timeout min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn self.sshpool = utils.SSHPool(host, gpfs_ssh_port, ssh_conn_timeout, gpfs_ssh_login, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) try: with self.sshpool.item() as ssh: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: with excutils.save_and_reraise_exception(): msg = (_('Error running SSH command: %(cmd)s. ' 'Error: %(excmsg)s.'), { 'cmd': command, 'excmsg': six.text_type(e) }) LOG.error(msg) raise exception.GPFSException(msg)
def _ssh_execute(self, sshpool, command, check_exit_code=True, attempts=1): try: with sshpool.item() as ssh: last_exception = None while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.exception('Error has occurred') last_exception = e greenthread.sleep(1) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error("Error running SSH command: %s", command)
def test_binary(self): o, e = processutils.ssh_execute(FakeSshConnection(0), 'ls', binary=True) self.assertEqual(b'stdout', o) self.assertEqual(b'stderr', e) self.assertIsInstance(o, bytes) self.assertIsInstance(e, bytes)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): # TODO(skolathur): Need to implement ssh_injection check # currently, the check will fail for zonecreate command # as zone members are separated by ';'which is a danger char command = " ".join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool( self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5 ) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute(ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(e) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd, ) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command ) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error running SSH command: %s") % command)
def test_exec_ssh_command_good(self): class Channel(object): def recv_exit_status(self): return 0 class Stream(object): def __init__(self, buffer=''): self.buffer = buffer self.channel = Channel() def read(self): return self.buffer def close(self): pass with mock.patch.object(self.sshclient, 'exec_command', autospec=True) as exec_command_mock: exec_command_mock.return_value = (Stream(), Stream('hello'), Stream()) stdout, stderr = processutils.ssh_execute(self.sshclient, "command") self.assertEqual('hello', stdout) exec_command_mock.assert_called_once_with("command")
def test_binary(self): o, e = processutils.ssh_execute(FakeSshConnection(0), 'ls', binary=True) self.assertEqual(b'stdout', o) self.assertEqual(b'stderr', e) self.assertIsInstance(o, bytes) self.assertIsInstance(e, bytes)
def _run_ssh(self, host, cmd_list, check_exit_code=True): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) if not self.sshpool: gpfs_ssh_login = self.configuration.gpfs_ssh_login password = self.configuration.gpfs_ssh_password privatekey = self.configuration.gpfs_ssh_private_key gpfs_ssh_port = self.configuration.gpfs_ssh_port ssh_conn_timeout = self.configuration.ssh_conn_timeout min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn self.sshpool = utils.SSHPool(host, gpfs_ssh_port, ssh_conn_timeout, gpfs_ssh_login, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) try: with self.sshpool.item() as ssh: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: with excutils.save_and_reraise_exception(): msg = (_('Error running SSH command: %(cmd)s. ' 'Error: %(excmsg)s.'), {'cmd': command, 'excmsg': six.text_type(e)}) LOG.error(msg) raise exception.GPFSException(msg)
def test_exec_ssh_command_good(self): class Channel(object): def recv_exit_status(self): return 0 class Stream(object): def __init__(self, buffer=''): self.buffer = buffer self.channel = Channel() def read(self): return self.buffer def close(self): pass with mock.patch.object(self.sshclient, 'exec_command', autospec=True) as exec_command_mock: exec_command_mock.return_value = (Stream(), Stream('hello'), Stream()) stdout, stderr = processutils.ssh_execute(self.sshclient, "command") self.assertEqual('hello', stdout) exec_command_mock.assert_called_once_with("command")
def _ssh_exec(self, server, command, check_exit_code=True): connection = self.ssh_connections.get(server['instance_id']) ssh_conn_timeout = self.configuration.ssh_conn_timeout if not connection: ssh_pool = utils.SSHPool(server['ip'], 22, ssh_conn_timeout, server['username'], server.get('password'), server.get('pk_path'), max_size=1) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) # (aovchinnikov): ssh_execute does not behave well when passed # parameters with spaces. wrap = lambda token: "\"" + token + "\"" command = [wrap(tkn) if tkn.count(' ') else tkn for tkn in command] return processutils.ssh_execute(ssh, ' '.join(command), check_exit_code=check_exit_code)
def _run_ssh(self, host, cmd_list, check_exit_code=False): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) connection = self.ssh_connections.get(host) if connection is None: ssh_name = self.configuration.maprfs_ssh_name password = self.configuration.maprfs_ssh_pw private_key = self.configuration.maprfs_ssh_private_key remote_ssh_port = self.configuration.maprfs_ssh_port ssh_conn_timeout = self.configuration.ssh_conn_timeout min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn ssh_pool = utils.SSHPool(host, remote_ssh_port, ssh_conn_timeout, ssh_name, password=password, privatekey=private_key, min_size=min_size, max_size=max_size) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code)
def _ssh_execute(ssh_obj, cmd_to_exec): """Executes a command via ssh. Executes a command via ssh and returns a list of the lines of the output from the command. :param ssh_obj: paramiko.SSHClient, an active ssh connection. :param cmd_to_exec: command to execute. :returns: list of the lines of output from the command. :raises: SSHCommandFailed on an error from ssh. """ LOG.debug(_translators.log_error("Executing SSH cmd: %r"), cmd_to_exec) try: output_list = processutils.ssh_execute(ssh_obj, cmd_to_exec)[0].split('\n') except Exception as e: LOG.error( _translators.log_error( "Cannot execute SSH cmd %(cmd)s. Reason: %(err)s."), { 'cmd': cmd_to_exec, 'err': e }) raise exception.SSHCommandFailed(cmd=cmd_to_exec) return output_list
def _test_compromising_ssh(self, rc, check): fixture = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) fake_stdin = six.BytesIO() fake_stdout = mock.Mock() fake_stdout.channel.recv_exit_status.return_value = rc fake_stdout.read.return_value = b'password="******"' fake_stderr = six.BytesIO(b'password="******"') command = 'ls --password="******"' connection = mock.Mock() connection.exec_command.return_value = (fake_stdin, fake_stdout, fake_stderr) if check and rc != -1 and rc != 0: err = self.assertRaises(processutils.ProcessExecutionError, processutils.ssh_execute, connection, command, check_exit_code=check) self.assertEqual(rc, err.exit_code) self.assertEqual('password="******"', err.stdout) self.assertEqual('password="******"', err.stderr) self.assertEqual('ls --password="******"', err.cmd) self.assertNotIn('secret', str(err)) self.assertNotIn('foobar', str(err)) else: o, e = processutils.ssh_execute(connection, command, check_exit_code=check) self.assertEqual('password="******"', o) self.assertEqual('password="******"', e) self.assertIn('password="******"', fixture.output) self.assertNotIn('bar', fixture.output)
def _ssh_exec(self, server, command, check_exit_code=True): LOG.debug("_ssh_exec - server: %s, command: %s, check_exit_code: %s", server, command, check_exit_code) connection = self.ssh_connections.get(server['instance_id']) ssh_conn_timeout = self.configuration.ssh_conn_timeout if not connection: ssh_pool = utils.SSHPool(server['ip'], 22, ssh_conn_timeout, server['username'], server.get('password'), server.get('pk_path'), max_size=1) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) # (aovchinnikov): ssh_execute does not behave well when passed # parameters with spaces. wrap = lambda token: "\"" + token + "\"" command = [wrap(tkn) if tkn.count(' ') else tkn for tkn in command] return processutils.ssh_execute(ssh, ' '.join(command), check_exit_code=check_exit_code)
def __call__(self, *args, **kwargs): cmd = ' '.join(pipes.quote(a) for a in args) ssh = self.pool.get() try: ret = processutils.ssh_execute(ssh, cmd, **kwargs) finally: self.pool.put(ssh) return ret
def __call__(self, *args, **kwargs): cmd = ' '.join(pipes.quote(a) for a in args) ssh = self.pool.get() try: ret = processutils.ssh_execute(ssh, cmd, **kwargs) finally: self.pool.put(ssh) return ret
def run_cmd(self, cmd, ip0, user, pw, *args, **kwargs): """Run a command on SMU or using SSH :param cmd: the command that will be run on SMU :param ip0: string IP address of controller :param user: string user authentication for array :param pw: string password authentication for array :returns: formated string with version information """ LOG.debug('Enable ssh: %s', six.text_type(self.drv_configs['ssh_enabled'])) if self.drv_configs['ssh_enabled'] != 'True': # Direct connection via ssc args = (cmd, '-u', user, '-p', pw, ip0) + args out, err = utils.execute(*args, **kwargs) LOG.debug("command %(cmd)s result: out = %(out)s - err = " "%(err)s", {'cmd': cmd, 'out': out, 'err': err}) return out, err else: if self.drv_configs['cluster_admin_ip0'] is None: # Connect to SMU through SSH and run ssc locally args = (cmd, 'localhost') + args else: args = (cmd, '--smuauth', self.drv_configs['cluster_admin_ip0']) + args utils.check_ssh_injection(args) command = ' '.join(args) command = command.replace('"', '\\"') if not self.sshpool: server = self.drv_configs['mgmt_ip0'] port = int(self.drv_configs['ssh_port']) username = self.drv_configs['username'] # We only accept private/public key auth password = "" privatekey = self.drv_configs['ssh_private_key'] self.sshpool = ssh_utils.SSHPool(server, port, None, username, password=password, privatekey=privatekey) with self.sshpool.item() as ssh: try: out, err = processutils.ssh_execute(ssh, command, check_exit_code=True) LOG.debug("command %(cmd)s result: out = %(out)s - err = " "%(err)s", {'cmd': cmd, 'out': out, 'err': err}) return out, err except processutils.ProcessExecutionError: LOG.error(_LE("Error running SSH command.")) raise
def run_cmd(self, cmd, ip0, user, pw, *args, **kwargs): """Run a command on SMU or using SSH :param cmd: the command that will be run on SMU :param ip0: string IP address of controller :param user: string user authentication for array :param pw: string password authentication for array :returns: formated string with version information """ LOG.debug('Enable ssh: %s', six.text_type(self.drv_configs['ssh_enabled'])) if self.drv_configs['ssh_enabled'] != 'True': # Direct connection via ssc args = (cmd, '-u', user, '-p', pw, ip0) + args out, err = utils.execute(*args, **kwargs) LOG.debug("command %(cmd)s result: out = %(out)s - err = " "%(err)s", {'cmd': cmd, 'out': out, 'err': err}) return out, err else: if self.drv_configs['cluster_admin_ip0'] is None: # Connect to SMU through SSH and run ssc locally args = (cmd, 'localhost') + args else: args = (cmd, '--smuauth', self.drv_configs['cluster_admin_ip0']) + args utils.check_ssh_injection(args) command = ' '.join(args) command = command.replace('"', '\\"') if not self.sshpool: server = self.drv_configs['mgmt_ip0'] port = int(self.drv_configs['ssh_port']) username = self.drv_configs['username'] # We only accept private/public key auth password = "" privatekey = self.drv_configs['ssh_private_key'] self.sshpool = ssh_utils.SSHPool(server, port, None, username, password=password, privatekey=privatekey) with self.sshpool.item() as ssh: try: out, err = processutils.ssh_execute(ssh, command, check_exit_code=True) LOG.debug("command %(cmd)s result: out = %(out)s - err = " "%(err)s", {'cmd': cmd, 'out': out, 'err': err}) return out, err except processutils.ProcessExecutionError: LOG.error(_LE("Error running SSH command.")) raise
def check_undecodable_bytes(self, binary): out_bytes = b'out: ' + UNDECODABLE_BYTES err_bytes = b'err: ' + UNDECODABLE_BYTES conn = FakeSshConnection(0, out=out_bytes, err=err_bytes) out, err = processutils.ssh_execute(conn, 'ls', binary=binary) if six.PY3 and not binary: self.assertEqual(os.fsdecode(out_bytes), out) self.assertEqual(os.fsdecode(err_bytes), err) else: self.assertEqual(out_bytes, out) self.assertEqual(err_bytes, err)
def check_undecodable_bytes(self, binary): out_bytes = b'out: ' + UNDECODABLE_BYTES err_bytes = b'err: ' + UNDECODABLE_BYTES conn = FakeSshConnection(0, out=out_bytes, err=err_bytes) out, err = processutils.ssh_execute(conn, 'ls', binary=binary) if six.PY3 and not binary: self.assertEqual(os.fsdecode(out_bytes), out) self.assertEqual(os.fsdecode(err_bytes), err) else: self.assertEqual(out_bytes, out) self.assertEqual(err_bytes, err)
def execute(self, ssh, sftp): """Execute action. Fetch resources, upload them, and run command. """ cmd = ("%s %s" % (self.cmd, self.args)) if self.sudo: cmd = "sudo %s" % cmd self.fetch_resources() self.upload_resources(sftp) return processutils.ssh_execute(ssh, cmd)
def run_ssh(self, cmd_list, check_exit_code=False): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) with self.sshpool.item() as ssh: try: out, err = processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) self.log_request(command, out, err) return out, err except processutils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Error running SSH command: %(cmd)s.'), {'cmd': command})
def _get_switch_data(self, ssh_pool, cmd): utils.check_ssh_injection([cmd]) with ssh_pool.item() as ssh: try: switch_data, err = processutils.ssh_execute(ssh, cmd) except processutils.ProcessExecutionError as e: msg = (_("SSH Command failed with error: '%(err)s', Command: " "'%(command)s'") % {'err': six.text_type(e), 'command': cmd}) LOG.error(msg) raise exception.FCSanLookupServiceException(message=msg) return switch_data
def _management_call(self, command): """Send a command over ssh to the ring management host. :param command: command to execute :param command: string :returns: tuple of (stdout, stderr) with command output """ cmd = 'sudo scality-manila-utils %s %s %s' % ( self.PROTOCOL.lower(), self.optional_args, command) LOG.debug("Management execute: %s", cmd) with self.ssh_pool.item() as connection: result = processutils.ssh_execute(connection, cmd) return result
def __call__(self, *args, **kwargs): # argument with identifier 'run_as_root=' is not accepted by # processutils's ssh_execute() method unlike processutils's execute() # method. So implement workaround to enable or disable 'run as root' # behavior. run_as_root = kwargs.pop('run_as_root', False) cmd = ' '.join(pipes.quote(a) for a in args) if run_as_root: cmd = ' '.join(['sudo', cmd]) ssh = self.pool.get() try: ret = processutils.ssh_execute(ssh, cmd, **kwargs) finally: self.pool.put(ssh) return ret
def __call__(self, *args, **kwargs): # argument with identifier 'run_as_root=' is not accepted by # processutils's ssh_execute() method unlike processutils's execute() # method. So implement workaround to enable or disable 'run as root' # behavior. run_as_root = kwargs.pop('run_as_root', False) cmd = ' '.join(pipes.quote(a) for a in args) if run_as_root: cmd = ' '.join(['sudo', cmd]) ssh = self.pool.get() try: ret = processutils.ssh_execute(ssh, cmd, **kwargs) finally: self.pool.put(ssh) return ret
def run_ssh(self, cmd_list, check_exit_code=False): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) with self.sshpool.item() as ssh: try: out, err = processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) self.log_request(command, out, err) return out, err except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error('Error running SSH command: %(cmd)s. ' 'Error: %(excmsg)s.', {'cmd': command, 'excmsg': e})
def _ssh_execute(self, commands): try: out, err = processutils.ssh_execute( self.ssh, commands, timeout=self.ssh_timeout, check_exit_code=True) except processutils.ProcessExecutionError as pe: rc = pe.exit_code out = pe.stdout out = out.replace('\n', '\\n') msg = _('Error on execute ssh command. ' 'Exit code: %(rc)d, msg: %(out)s') % { 'rc': rc, 'out': out} raise exception.InfortrendNASException(err=msg) return out
def _execute(self, commands): command = ['ssc', '127.0.0.1'] if self.admin_ip0 is not None: command = ['ssc', '--smuauth', self.admin_ip0] command += ['console-context', '--evs', self.evs_id] commands = command + commands mutils.check_ssh_injection(commands) commands = ' '.join(commands) if not self.sshpool: self.sshpool = mutils.SSHPool(ip=self.ip, port=self.port, conn_timeout=None, login=self.user, password=self.password, privatekey=self.priv_key) with self.sshpool.item() as ssh: ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: out, err = processutils.ssh_execute(ssh, commands, check_exit_code=True) LOG.debug( "Command %(cmd)s result: out = %(out)s - err = " "%(err)s.", { 'cmd': commands, 'out': out, 'err': err, }) return out, err except processutils.ProcessExecutionError as e: if 'Failed to establish SSC connection' in e.stderr: msg = _("Failed to establish SSC connection.") LOG.debug(msg) raise exception.HNASConnException(msg=msg) else: LOG.debug( "Error running SSH command. " "Command %(cmd)s result: out = %(out)s - err = " "%(err)s - exit = %(exit)s.", { 'cmd': e.cmd, 'out': e.stdout, 'err': e.stderr, 'exit': e.exit_code, }) raise
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): utils.check_ssh_injection(cmd_list) command = ' '. join(cmd_list) if not self.sshpool: password = self.configuration.san_password privatekey = self.configuration.san_private_key min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn self.sshpool = ssh_utils.SSHPool( self.configuration.san_ip, self.configuration.san_ssh_port, self.configuration.ssh_conn_timeout, self.configuration.san_login, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(e) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error("Error running SSH command: %s", command)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): utils.check_ssh_injection(cmd_list) command = ' '. join(cmd_list) if not self.sshpool: password = self.configuration.san_password privatekey = self.configuration.san_private_key min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn self.sshpool = ssh_utils.SSHPool( self.configuration.san_ip, self.configuration.san_ssh_port, self.configuration.ssh_conn_timeout, self.configuration.san_login, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(e) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error("Error running SSH command: %s", command)
def _get_switch_data(self, ssh_pool, cmd): utils.check_ssh_injection([cmd]) with ssh_pool.item() as ssh: try: switch_data, err = processutils.ssh_execute(ssh, cmd) except processutils.ProcessExecutionError as e: msg = (_("SSH Command failed with error: '%(err)s', Command: " "'%(command)s'") % { 'err': six.text_type(e), 'command': cmd }) LOG.error(msg) raise exception.FCSanLookupServiceException(message=msg) return switch_data
def _bareon_log(self, task, ssh): node_uuid = task.node.uuid try: # TODO(oberezovskyi): Chenge log pulling mechanism (e.g. use # remote logging feature of syslog) stdout, stderr = processutils.ssh_execute( ssh, 'cat /var/log/bareon.log') except processutils.ProcessExecutionError as exec_err: LOG.warning(_LI('[%(node)s] Error getting Bareon log. ' 'Error: %(error)s') % {'node': node_uuid, 'error': exec_err}) else: LOG.info("[{1}] {0} Start Bareon log {0}\n{2}\n" "[{1}] {0} End Bareon log {0}".format("#" * 20, node_uuid, stdout))
def _run_cmd(self, *args, **kwargs): """Runs a command on SMU using SSH. :returns: stdout and stderr of the command """ if self.cluster_admin_ip0 is None: # Connect to SMU through SSH and run ssc locally args = (self.hnas_cmd, 'localhost') + args else: args = (self.hnas_cmd, '--smuauth', self.cluster_admin_ip0) + args utils.check_ssh_injection(args) command = ' '.join(args) command = command.replace('"', '\\"') if not self.sshpool: self.sshpool = ssh_utils.SSHPool(ip=self.mgmt_ip0, port=int(self.ssh_port), conn_timeout=None, login=self.ssh_username, password=self.ssh_pwd, privatekey=self.ssh_private_key) with self.sshpool.item() as ssh: try: out, err = putils.ssh_execute(ssh, command, check_exit_code=True) LOG.debug( "command %(cmd)s result: out = " "%(out)s - err = %(err)s", { 'cmd': self.hnas_cmd, 'out': out, 'err': err }) return out, err except putils.ProcessExecutionError as e: if 'Failed to establish SSC connection' in e.stderr: msg = _("Failed to establish SSC connection!") LOG.exception(msg) raise exception.HNASConnError(msg) elif 'Connection reset' in e.stderr: msg = _("HNAS connection reset!") LOG.exception(msg) raise exception.HNASConnError(msg) else: raise
def _ssh_execute(self, sshpool, command, check_exit_code=True): # noinspection PyBroadException try: with sshpool.item() as ssh: try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error('Error has occurred: %s', e) raise processutils.ProcessExecutionError( exit_code=e.exit_code, stdout=e.stdout, stderr=e.stderr, cmd=e.cmd) except Exception: with excutils.save_and_reraise_exception(): LOG.error('Error running SSH command: %s', command)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): utils.check_ssh_injection(cmd_list) # TODO(vhou): We'll have a common method in ssh_utils to take # care of this _run_ssh method. command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool( self.target.get('san_ip'), self.target.get('san_ssh_port', 22), self.target.get('ssh_conn_timeout', 30), self.target.get('san_login'), password=self.target.get('san_password'), privatekey=self.target.get('san_private_key', ''), min_size=self.target.get('ssh_min_pool_conn', 1), max_size=self.target.get('ssh_max_pool_conn', 5), ) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(six.text_type(e)) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error running SSH command: %s"), command)
def _execute(self, commands): command = ['ssc', '127.0.0.1'] if self.admin_ip0 is not None: command = ['ssc', '--smuauth', self.admin_ip0] command += ['console-context', '--evs', self.evs_id] commands = command + commands mutils.check_ssh_injection(commands) commands = ' '.join(commands) if not self.sshpool: self.sshpool = mutils.SSHPool(ip=self.ip, port=self.port, conn_timeout=None, login=self.user, password=self.password, privatekey=self.priv_key) with self.sshpool.item() as ssh: ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: out, err = processutils.ssh_execute(ssh, commands, check_exit_code=True) LOG.debug("Command %(cmd)s result: out = %(out)s - err = " "%(err)s.", { 'cmd': commands, 'out': out, 'err': err, }) return out, err except processutils.ProcessExecutionError as e: if 'Failed to establish SSC connection' in e.stderr: msg = _("Failed to establish SSC connection.") LOG.debug(msg) raise exception.HNASConnException(msg=msg) else: LOG.debug("Error running SSH command. " "Command %(cmd)s result: out = %(out)s - err = " "%(err)s - exit = %(exit)s.", { 'cmd': e.cmd, 'out': e.stdout, 'err': e.stderr, 'exit': e.exit_code, }) raise
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): utils.check_ssh_injection(cmd_list) # TODO(vhou): We'll have a common method in ssh_utils to take # care of this _run_ssh method. command = ' '. join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool( self.target.get('san_ip'), self.target.get('san_ssh_port', 22), self.target.get('ssh_conn_timeout', 30), self.target.get('san_login'), password=self.target.get('san_password'), privatekey=self.target.get('san_private_key', ''), min_size=self.target.get('ssh_min_pool_conn', 1), max_size=self.target.get('ssh_max_pool_conn', 5),) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(six.text_type(e)) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error running SSH command: %s"), command)
def _ssh_execute(ssh_obj, cmd_to_exec): """Executes a command via ssh. Executes a command via ssh and returns a list of the lines of the output from the command. :param ssh_obj: paramiko.SSHClient, an active ssh connection. :param cmd_to_exec: command to execute. :returns: list of the lines of output from the command. :raises: SSHCommandFailed on an error from ssh. """ try: output_list = processutils.ssh_execute(ssh_obj, cmd_to_exec)[0].split("\n") except Exception as e: LOG.error(_LE("Cannot execute SSH cmd %(cmd)s. Reason: %(err)s."), {"cmd": cmd_to_exec, "err": e}) raise exception.SSHCommandFailed(cmd=cmd_to_exec) return output_list
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): command = ' '.join(cmd_list) if self.sshpool.get(self.switch_ip) is None: self.sshpool[self.switch_ip] = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) last_exception = None try: with self.sshpool.get(self.switch_ip).item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: msg = _("Exception: %s") % six.text_type(e) LOG.error(msg) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error("Error running SSH command: %s", command)
def _run_cmd(self, *args, **kwargs): """Runs a command on SMU using SSH. :returns: stdout and stderr of the command """ if self.cluster_admin_ip0 is None: # Connect to SMU through SSH and run ssc locally args = (self.hnas_cmd, 'localhost') + args else: args = (self.hnas_cmd, '--smuauth', self.cluster_admin_ip0) + args utils.check_ssh_injection(args) command = ' '.join(args) command = command.replace('"', '\\"') if not self.sshpool: self.sshpool = ssh_utils.SSHPool(ip=self.mgmt_ip0, port=int(self.ssh_port), conn_timeout=None, login=self.ssh_username, password=self.ssh_pwd, privatekey=self.ssh_private_key) with self.sshpool.item() as ssh: try: out, err = putils.ssh_execute(ssh, command, check_exit_code=True) LOG.debug("command %(cmd)s result: out = " "%(out)s - err = %(err)s", {'cmd': self.hnas_cmd, 'out': out, 'err': err}) return out, err except putils.ProcessExecutionError as e: if 'Failed to establish SSC connection' in e.stderr: LOG.debug("SSC connection error!") msg = _("Failed to establish SSC connection.") raise exception.HNASConnError(msg) elif 'Connection reset' in e.stderr: LOG.debug("HNAS connection reset!") msg = _("HNAS has disconnected SSC") raise exception.HNASConnError(msg) else: raise
def _run_ssh(self, host, cmd_list, check_exit_code=False): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) connection = self.ssh_connections.get(host) if not connection: hdfs_ssh_name = self.configuration.hdfs_ssh_name password = self.configuration.hdfs_ssh_pw privatekey = self.configuration.hdfs_ssh_private_key hdfs_ssh_port = self.configuration.hdfs_ssh_port ssh_conn_timeout = self.configuration.ssh_conn_timeout min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn ssh_pool = utils.SSHPool(host, hdfs_ssh_port, ssh_conn_timeout, hdfs_ssh_name, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) try: return processutils.ssh_execute(ssh, command, check_exit_code=check_exit_code) except Exception as e: msg = (_('Error running SSH command: %(cmd)s. ' 'Error: %(excmsg)s.') % { 'cmd': command, 'excmsg': six.text_type(e) }) LOG.error(msg) raise exception.HDFSException(msg)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): # TODO(skolathur): Need to implement ssh_injection check # currently, the check will fail for zonecreate command # as zone members are separated by ';'which is a danger char command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, self.switch_key, min_size=1, max_size=5) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.exception('Error executing SSH command.') last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error("Error running SSH command: %s", command)
def _run_ssh(self, cmd_list, check_exit_code=True): command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) try: with self.sshpool.item() as ssh: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception: with excutils.save_and_reraise_exception(): LOG.warning("Error running SSH command: %s", command)
def _ssh_exec(self, server, command): connection = self.ssh_connections.get(server['instance_id']) if not connection: ssh_pool = utils.SSHPool(server['ip'], 22, None, server['username'], server.get('password'), server.get('pk_path'), max_size=1) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) return processutils.ssh_execute(ssh, ' '.join(command))
def _ssh_exec(self, server, command): connection = self.ssh_connections.get(server['instance_id']) if not connection: ssh_pool = utils.SSHPool(server['ip'], 22, None, server['username'], server.get('password'), server.get('pk_path'), max_size=1) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[server['instance_id']] = (ssh_pool, ssh) return processutils.ssh_execute(ssh, ' '.join(command))
def _run_ssh(self, host, cmd_list, check_exit_code=False): command = ' '.join(pipes.quote(cmd_arg) for cmd_arg in cmd_list) connection = self.ssh_connections.get(host) if not connection: hdfs_ssh_name = self.configuration.hdfs_ssh_name password = self.configuration.hdfs_ssh_pw privatekey = self.configuration.hdfs_ssh_private_key hdfs_ssh_port = self.configuration.hdfs_ssh_port ssh_conn_timeout = self.configuration.ssh_conn_timeout min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn ssh_pool = utils.SSHPool(host, hdfs_ssh_port, ssh_conn_timeout, hdfs_ssh_name, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) else: ssh_pool, ssh = connection if not ssh.get_transport().is_active(): ssh_pool.remove(ssh) ssh = ssh_pool.create() self.ssh_connections[host] = (ssh_pool, ssh) try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: msg = (_('Error running SSH command: %(cmd)s. ' 'Error: %(excmsg)s.') % {'cmd': command, 'excmsg': six.text_type(e)}) LOG.error(msg) raise exception.HDFSException(msg)
def _get_boot_info(self, task, ssh): node = task.node node_uuid = node.uuid if not node.instance_info.get('multiboot', False): return try: stdout, stderr = processutils.ssh_execute( ssh, 'cat /tmp/boot_entries.json') except processutils.ProcessExecutionError as exec_err: LOG.warning(_LI('[%(node)s] Error getting boot info. ' 'Error: %(error)s') % {'node': node_uuid, 'error': exec_err}) raise else: multiboot_info = json.loads(stdout) bareon_utils.change_node_dict(node, 'instance_info', { 'multiboot_info': multiboot_info }) LOG.info("[{1}] {0} Multiboot info {0}\n{2}" "\n".format("#" * 20, node_uuid, multiboot_info))
def _run_ssh(self, cmd_list, check_exit_code=True): command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) try: with self.sshpool.item() as ssh: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception: with excutils.save_and_reraise_exception(): LOG.warning(_LW("Error running SSH command: %s"), command)
def _run_on_fail_script(self, task, sftp, ssh): node = task.node node_uuid = node.uuid try: on_fail_script_path = get_on_fail_script_path(node) if not os.path.exists(on_fail_script_path): LOG.info(_LI("[%(node)s] No on_fail_script passed. Skipping") % {'node': node_uuid}) return LOG.debug(_LI('[%(node)s] Uploading on_fail script to the node.'), {'node': node_uuid}) sftp.put(on_fail_script_path, '/tmp/bareon_on_fail.sh') LOG.debug("[%(node)s] Executing on_fail_script." % {'node': node_uuid}) out, err = processutils.ssh_execute( ssh, "bash %s" % '/tmp/bareon_on_fail.sh') except processutils.ProcessExecutionError as ex: LOG.warning(_LI('[%(node)s] Error executing OnFail script. ' 'Error: %(er)s') % {'node': node_uuid, 'er': ex}) except exception.SSHConnectFailed as ex: LOG.warning(_LI('[%(node)s] SSH connection error. ' 'Error: %(er)s') % {'node': node_uuid, 'er': ex}) except Exception as ex: LOG.warning(_LI('[%(node)s] Unknown error. ' 'Error: %(error)s') % {'node': node_uuid, 'error': ex}) else: LOG.info( "{0} [{1}] on_fail sctipt result below {0}".format("#" * 40, node_uuid)) LOG.info(out) LOG.info(err) LOG.info("{0} [{1}] End on_fail script " "result {0}".format("#" * 40, node_uuid))
def _ssh_execute(self, commands): if not self.sshpool: self.sshpool = utils.SSHPool(ip=self.nas_ip, port=self.port, conn_timeout=None, login=self.username, password=self.password, privatekey=self.ssh_key) with self.sshpool.item() as ssh: try: out, err = processutils.ssh_execute( ssh, commands, check_exit_code=True) rc, result = self._parser(out) except processutils.ProcessExecutionError as pe: rc = pe.exit_code result = pe.stdout result = result.replace('\n', '\\n') LOG.error(_LE( 'Error on execute ssh command. ' 'Error code: %(exit_code)d Error msg: %(result)s'), { 'exit_code': pe.exit_code, 'result': result}) return rc, result
def _check_bareon_version(self, ssh, node_uuid): try: stdout, stderr = processutils.ssh_execute( ssh, 'cat /etc/bareon-release') LOG.info(_LI("[{0}] Tracing Bareon version.\n{1}").format( node_uuid, stdout)) version = "" lines = stdout.splitlines() if lines: version_line = lines[0] name, _, version = version_line.partition("==") if version.startswith(REQUIRED_BAREON_VERSION): return msg = ("Bareon version '%(req)s' is required, but version " "'%(found)s' found on the ramdisk." % dict(req=REQUIRED_BAREON_VERSION, found=version)) raise bareon_exception.IncompatibleRamdiskVersion(details=msg) except processutils.ProcessExecutionError: msg = "Bareon version cannot be read on the ramdisk." raise bareon_exception.IncompatibleRamdiskVersion(details=msg)
def switch_boot(self, task, **kwargs): # NOTE(oberezovskyi): exception messages should not be changed because # of hardcode in nova-ironic driver image = kwargs.get('image') LOG.info('[{0}] Attempt to switch boot to {1} ' 'image'.format(task.node.uuid, image)) msg = "" try: if not task.node.instance_info.get('multiboot', False): msg = "[{}] Non-multiboot deployment".format(task.node.uuid) raise exception.IronicException(message=msg, code=400) boot_info = task.node.instance_info.get('multiboot_info', {'elements': []}) grub_id = next((element['grub_id'] for element in boot_info['elements'] if (element['image_uuid'] == image or element['image_name'] == image)), None) if grub_id is None: msg = ('[{}] Can\'t find desired multiboot ' 'image'.format(task.node.uuid)) raise exception.IronicException(message=msg, code=400) elif grub_id == boot_info.get('current_element', None): msg = ('[{}] Already in desired boot ' 'device.'.format(task.node.uuid)) raise exception.IronicException(message=msg, code=400) node_ip = bareon_utils.get_node_ip(task) ssh_key = resources.url_download_raw_secured(task.context, task.node, kwargs['ssh_key']) ssh = bareon_utils.get_ssh_connection(task, **{ 'host': node_ip, 'username': kwargs['ssh_user'], 'key_contents': ssh_key }) tmp_path = processutils.ssh_execute(ssh, 'mktemp -d')[0].split()[0] cfg_path = os.path.join(tmp_path, 'boot', 'grub2', 'grub.cfg') commands = [ 'mount /dev/disk/by-uuid/{} {}'.format( boot_info['multiboot_partition'], tmp_path), "sed -i 's/\(set default=\)[0-9]*/\\1{}/' {}".format(grub_id, cfg_path), 'umount {}'.format(tmp_path), 'rmdir {}'.format(tmp_path) ] map(lambda cmd: processutils.ssh_execute(ssh, 'sudo ' + cmd), commands) except exception.SSHConnectFailed as e: msg = ( _('[%(node)s] SSH connect to node %(host)s failed. ' 'Error: %(error)s') % {'host': node_ip, 'error': e, 'node': task.node.uuid}) raise exception.IronicException(message=msg, code=400) except exception.IronicException as e: msg = str(e) raise except Exception as e: msg = (_('[%(node)s] Multiboot switch failed for node %(node)s. ' 'Error: %(error)s') % {'node': task.node.uuid, 'error': e}) raise exception.IronicException(message=msg, code=400) else: boot_info['current_element'] = grub_id bareon_utils.change_node_dict( task.node, 'instance_info', {'multiboot_info': boot_info}) task.node.save() finally: if msg: LOG.error(msg) task.node.last_error = msg task.node.save()
def test_works(self): out, err = processutils.ssh_execute(FakeSshConnection(0), 'ls') self.assertEqual('stdout', out) self.assertEqual('stderr', err) self.assertIsInstance(out, six.text_type) self.assertIsInstance(err, six.text_type)
def test_works(self): o, e = processutils.ssh_execute(FakeSshConnection(0), 'ls') self.assertEqual('stdout', o) self.assertEqual('stderr', e)
port = int(self.drv_configs['ssh_port']) username = self.drv_configs['username'] # We only accept private/public key auth password = "" privatekey = self.drv_configs['ssh_private_key'] self.sshpool = ssh_utils.SSHPool(server, port, None, username, password=password, privatekey=privatekey) with self.sshpool.item() as ssh: try: out, err = putils.ssh_execute(ssh, command, check_exit_code=True) LOG.debug("command %(cmd)s result: out = " "%(out)s - err = %(err)s", {'cmd': cmd, 'out': out, 'err': err}) return out, err except putils.ProcessExecutionError as e: if 'Failed to establish SSC connection' in e.stderr: LOG.debug("SSC connection error!") msg = _("Failed to establish SSC connection.") raise exception.HNASConnError(msg) else: raise putils.ProcessExecutionError def get_version(self, cmd, ver, ip0, user, pw): """Gets version information from the storage unit