def test_execute_together(self, execute_async, client, policy, logger): stderr = [' ', '0', '1', ' '] stdout = [' ', '2', '3', ' '] exit_code = 0 chan = mock.Mock() recv_exit_status = mock.Mock(return_value=exit_code) chan.attach_mock(recv_exit_status, 'recv_exit_status') execute_async.return_value = chan, '', stderr, stdout host2 = '127.0.0.2' ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) ssh2 = SSHClient(host=host2, port=port, username=username, password=password, private_keys=private_keys) remotes = ssh, ssh2 SSHClient.execute_together(remotes=remotes, command=command) self.assertEqual(execute_async.call_count, len(remotes)) chan.assert_has_calls( (mock.call.recv_exit_status(), mock.call.close(), mock.call.recv_exit_status(), mock.call.close()))
def init_remote(self, ip, port=22, custom_creds=None): """ Initialise connection to remote :param ip: IP of host :type ip: str :param port: port for SSH :type port: int :param custom_creds: custom creds :type custom_creds: dict """ logger.debug('SSH_MANAGER: Create new connection for ' '{ip}:{port}'.format(ip=ip, port=port)) keys = self._get_keys() if ip != self.admin_ip else [] if ip == self.admin_ip: ssh_client = SSHClient( host=ip, port=port, auth=SSHAuth( username=self.admin_login, password=self.__admin_password, keys=keys) ) ssh_client.sudo_mode = SSH_FUEL_CREDENTIALS['sudo'] elif custom_creds: ssh_client = SSHClient( host=ip, port=port, auth=SSHAuth(**custom_creds)) else: try: ssh_client = SSHClient( host=ip, port=port, auth=SSHAuth( username=self.slave_login, password=self.__slave_password, keys=keys) ) except SSHException: ssh_client = SSHClient( host=ip, port=port, auth=SSHAuth( username=self.slave_fallback_login, password=self.__slave_password, keys=keys) ) ssh_client.sudo_mode = SSH_SLAVE_CREDENTIALS['sudo'] self.connections[(ip, port)] = ssh_client logger.debug('SSH_MANAGER: New connection for ' '{ip}:{port} is created'.format(ip=ip, port=port))
def update_connection(self, ip, login=None, password=None, keys=None, port=22): """Update existed connection :param ip: host ip string :param login: login string :param password: password string :param keys: list of keys :param port: ssh port int :return: None """ if (ip, port) in self.connections: logger.info('SSH_MANAGER: Close connection for {ip}:{port}'.format( ip=ip, port=port)) self.connections[(ip, port)].clear() logger.info('SSH_MANAGER: Create new connection for ' '{ip}:{port}'.format(ip=ip, port=port)) self.connections[(ip, port)] = SSHClient( host=ip, port=port, username=login, password=password, private_keys=keys if keys is not None else [])
def test_init_passwd(self, client, policy, logger): _ssh = mock.call() ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) client.assert_called_once() policy.assert_called_once() expected_calls = [ _ssh, _ssh.set_missing_host_key_policy('AutoAddPolicy'), _ssh.connect(host, password=password, port=port, username=username), _ssh.open_sftp() ] self.assertIn(expected_calls, client.mock_calls) self.check_defaults(ssh, host, port, username, password, private_keys) self.assertIsNone(ssh.private_key) self.assertIsNone(ssh.public_key) self.assertIn( mock.call.debug("Connect to '{0}:{1}' as '{2}:{3}'".format( host, port, username, password)), logger.mock_calls) sftp = ssh._sftp self.assertEqual(sftp, client().open_sftp())
def test_init_as_context(self, client, policy, logger): _ssh = mock.call() private_keys = gen_private_keys(1) with SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) as ssh: client.assert_called_once() policy.assert_called_once() expected_calls = [ _ssh, _ssh.set_missing_host_key_policy('AutoAddPolicy'), _ssh.connect(host, password=password, pkey=private_keys[0], port=port, username=username), _ssh.open_sftp() ] self.assertIn(expected_calls, client.mock_calls) self.check_defaults(ssh, host, port, username, password, private_keys) self.assertIn( mock.call.debug("Connect to '{0}:{1}' as '{2}:{3}'".format( host, port, username, password)), logger.mock_calls)
def remote(self, network_name, login, password=None, private_keys=None): """Create SSH-connection to the network :rtype : SSHClient """ return SSHClient(self.get_ip_address_by_network_name(network_name), username=login, password=password, private_keys=private_keys)
def get_ssh_to_remote_by_key(self, ip, keyfile): try: with open(keyfile) as f: keys = [RSAKey.from_private_key(f)] except IOError: logger.warning('Loading of SSH key from file failed. Trying to use' ' SSH agent ...') keys = Agent().get_keys() return SSHClient(ip, private_keys=keys)
def wait_ssh_cmd(host, port, check_cmd, username=SSH_CREDENTIALS['login'], password=SSH_CREDENTIALS['password'], timeout=0): ssh_client = SSHClient(host=host, port=port, username=username, password=password) wait(lambda: not ssh_client.execute(check_cmd)['exit_code'], timeout=timeout)
def get_remote(self, ip, port=22): """ Function returns remote SSH connection to node by ip address :param ip: IP of host :type ip: str :param port: port for SSH :type port: int :rtype: SSHClient """ if (ip, port) not in self.connections: logger.debug('SSH_MANAGER: Create new connection for ' '{ip}:{port}'.format(ip=ip, port=port)) keys = self._get_keys() if ip != self.admin_ip else [] if ip == self.admin_ip: ssh_client = SSHClient(host=ip, port=port, username=self.admin_login, password=self.__admin_password, private_keys=keys) ssh_client.sudo_mode = SSH_FUEL_CREDENTIALS['sudo'] else: try: ssh_client = SSHClient(host=ip, port=port, username=self.slave_login, password=self.__slave_password, private_keys=keys) except AuthenticationException: ssh_client = SSHClient(host=ip, port=port, username=self.slave_fallback_login, password=self.__slave_password, private_keys=keys) ssh_client.sudo_mode = SSH_SLAVE_CREDENTIALS['sudo'] self.connections[(ip, port)] = ssh_client logger.debug('SSH_MANAGER: Return existed connection for ' '{ip}:{port}'.format(ip=ip, port=port)) logger.debug('SSH_MANAGER: Connections {0}'.format(self.connections)) return self._connect(self.connections[(ip, port)])
def get_node_remote(env, node_name, login=SSH_SLAVE_CREDENTIALS['login'], password=SSH_SLAVE_CREDENTIALS['password']): ip = get_slave_ip(env, env.get_node(name=node_name).interfaces[0].mac_address) wait(lambda: tcp_ping(ip, 22), timeout=180, timeout_msg="Node {ip} is not accessible by SSH.".format(ip=ip)) return SSHClient(ip, username=login, password=password, private_keys=get_private_keys(env))
def init_ssh(self, client, policy, logger): ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) client.assert_called_once() policy.assert_called_once() self.assertIn( mock.call.debug("Connect to '{0}:{1}' as '{2}:{3}'".format( host, port, username, password)), logger.mock_calls) return ssh
def get_ssh_to_remote(self, ip, login=settings.SSH_SLAVE_CREDENTIALS['login'], password=settings.SSH_SLAVE_CREDENTIALS['password']): keys = [] for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']: if self.get_admin_remote().isfile(key_string): with self.get_admin_remote().open(key_string) as f: keys.append(RSAKey.from_private_key(f)) return SSHClient(ip, username=login, password=password, private_keys=keys)
def test_init_fail_sftp(self, client, policy, logger): _ssh = mock.Mock() client.return_value = _ssh open_sftp = mock.Mock(parent=_ssh, side_effect=paramiko.SSHException) _ssh.attach_mock(open_sftp, 'open_sftp') warning = mock.Mock(parent=logger) logger.attach_mock(warning, 'warning') ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) client.assert_called_once() policy.assert_called_once() self.check_defaults(ssh, host, port, username, password, private_keys) warning.assert_called_once_with( 'SFTP enable failed! SSH only is accessible.') with self.assertRaises(paramiko.SSHException): # pylint: disable=pointless-statement # noinspection PyStatementEffect ssh._sftp # pylint: enable=pointless-statement warning.assert_has_calls([ mock.call('SFTP enable failed! SSH only is accessible.'), mock.call('SFTP is not connected, try to reconnect'), mock.call('SFTP enable failed! SSH only is accessible.') ]) # Unblock sftp connection # (reset_mock is not possible to use in this case) _sftp = mock.Mock() open_sftp = mock.Mock(parent=_ssh, return_value=_sftp) _ssh.attach_mock(open_sftp, 'open_sftp') sftp = ssh._sftp self.assertEqual(sftp, _sftp)
def prepare_sftp_file_tests(self, client, policy, logger): _ssh = mock.Mock() client.return_value = _ssh _sftp = mock.Mock() open_sftp = mock.Mock(parent=_ssh, return_value=_sftp) _ssh.attach_mock(open_sftp, 'open_sftp') ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) client.assert_called_once() policy.assert_called_once() self.check_defaults(ssh, host, port, username, password, private_keys) self.assertIn( mock.call.debug("Connect to '{0}:{1}' as '{2}:{3}'".format( host, port, username, password)), logger.mock_calls) return ssh, _sftp
def ssh(*args, **kwargs): warn('devops.helpers.ssh is deprecated ' 'and will be removed soon', DeprecationWarning) return SSHClient(*args, **kwargs)
def test_execute_through_host_no_creds_key(self, transp, client, policy, logger): target = '10.0.0.2' private_keys = gen_private_keys(1) intermediate_channel = mock.Mock() open_channel = mock.Mock(return_value=intermediate_channel) intermediate_transport = mock.Mock() intermediate_transport.attach_mock(open_channel, 'open_channel') get_transport = mock.Mock(return_value=intermediate_transport) _ssh = mock.Mock() _ssh.attach_mock(get_transport, 'get_transport') client.return_value = _ssh transport = mock.Mock() transp.return_value = transport stderr = [' ', '0', '1', ' '] stdout = [' ', '2', '3', ' '] exit_code = 0 return_value = { 'stderr_str': ''.join(stderr).strip(), 'stdout_str': ''.join(stdout).strip(), 'exit_code': exit_code, 'stderr': stderr, 'stdout': stdout } recv_exit_status = mock.Mock(return_value=exit_code) makefile = mock.Mock() makefile.attach_mock(mock.Mock(return_value=stdout), 'read') makefile_stderr = mock.Mock() makefile_stderr.attach_mock(mock.Mock(return_value=stderr), 'read') channel = mock.Mock() channel.attach_mock(mock.Mock(return_value=makefile), 'makefile') channel.attach_mock(mock.Mock(return_value=makefile_stderr), 'makefile_stderr') channel.attach_mock(recv_exit_status, 'recv_exit_status') open_session = mock.Mock(return_value=channel) transport.attach_mock(open_session, 'open_session') ssh = SSHClient(host=host, port=port, username=username, password=password, private_keys=private_keys) client.assert_called_once() policy.assert_called_once() self.assertIn( mock.call.debug("Connect to '{0}:{1}' as '{2}:{3}'".format( host, port, username, password)), logger.mock_calls) result = ssh.execute_through_host(target, command) self.assertEqual(result, return_value) get_transport.assert_called_once() open_channel.assert_called_once() transp.assert_called_once_with(intermediate_channel) open_session.assert_called_once() transport.assert_has_calls( (mock.call.start_client(), mock.call.auth_publickey(username=username, key=private_keys[0]), mock.call.open_session())) channel.assert_has_calls( (mock.call.makefile('rb'), mock.call.makefile_stderr('rb'), mock.call.exec_command('ls ~ '), mock.call.recv_exit_status(), mock.call.close()))