コード例 #1
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_key_with_passphrase_success(self):
        path = os.path.join(get_resources_base_path(), "ssh",
                            "dummy_rsa_passphrase")

        with open(path, "r") as fp:
            private_key = fp.read()

        # Key material provided
        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "key_material": private_key,
            "passphrase": "testphrase",
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        pkey = paramiko.RSAKey.from_private_key(StringIO(private_key),
                                                "testphrase")
        expected_conn = {
            "username": "******",
            "allow_agent": False,
            "hostname": "dummy.host.org",
            "look_for_keys": False,
            "pkey": pkey,
            "timeout": 30,
            "port": 22,
        }
        mock.client.connect.assert_called_once_with(**expected_conn)

        # Path to private key file provided
        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "key_files": path,
            "passphrase": "testphrase",
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_conn = {
            "username": "******",
            "allow_agent": False,
            "hostname": "dummy.host.org",
            "look_for_keys": False,
            "key_filename": path,
            "password": "******",
            "timeout": 30,
            "port": 22,
        }
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #2
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_key_with_passphrase_success(self):
        path = os.path.join(get_resources_base_path(), 'ssh',
                            'dummy_rsa_passphrase')

        with open(path, 'r') as fp:
            private_key = fp.read()

        # Key material provided
        conn_params = {
            'hostname': 'dummy.host.org',
            'username': '******',
            'key_material': private_key,
            'passphrase': 'testphrase'
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        pkey = paramiko.RSAKey.from_private_key(StringIO(private_key),
                                                'testphrase')
        expected_conn = {
            'username': '******',
            'allow_agent': False,
            'hostname': 'dummy.host.org',
            'look_for_keys': False,
            'pkey': pkey,
            'timeout': 30,
            'port': 22
        }
        mock.client.connect.assert_called_once_with(**expected_conn)

        # Path to private key file provided
        conn_params = {
            'hostname': 'dummy.host.org',
            'username': '******',
            'key_files': path,
            'passphrase': 'testphrase'
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_conn = {
            'username': '******',
            'allow_agent': False,
            'hostname': 'dummy.host.org',
            'look_for_keys': False,
            'key_filename': path,
            'password': '******',
            'timeout': 30,
            'port': 22
        }
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #3
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_key_material_argument(self):
        path = os.path.join(get_resources_base_path(), "ssh", "dummy_rsa")

        with open(path, "r") as fp:
            private_key = fp.read()

        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "key_material": private_key,
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        pkey = paramiko.RSAKey.from_private_key(StringIO(private_key))
        expected_conn = {
            "username": "******",
            "allow_agent": False,
            "hostname": "dummy.host.org",
            "look_for_keys": False,
            "pkey": pkey,
            "timeout": 30,
            "port": 22,
        }
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #4
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_key_material_argument(self):
        path = os.path.join(get_resources_base_path(), 'ssh', 'dummy_rsa')

        with open(path, 'r') as fp:
            private_key = fp.read()

        conn_params = {
            'hostname': 'dummy.host.org',
            'username': '******',
            'key_material': private_key
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        pkey = paramiko.RSAKey.from_private_key(StringIO(private_key))
        expected_conn = {
            'username': '******',
            'allow_agent': False,
            'hostname': 'dummy.host.org',
            'look_for_keys': False,
            'pkey': pkey,
            'timeout': 30,
            'port': 22
        }
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #5
0
ファイル: parallel_ssh.py プロジェクト: vishnu81/st2
    def _connect(self, host, results, raise_on_any_error=False):
        (hostname, port) = self._get_host_port_info(host)

        extra = {'host': host, 'port': port, 'user': self._ssh_user}
        if self._ssh_password:
            extra['password'] = '******'
        elif self._ssh_key_file:
            extra['key_file_path'] = self._ssh_key_file
        else:
            extra['private_key'] = '<redacted>'

        LOG.debug('Connecting to host.', extra=extra)

        client = ParamikoSSHClient(hostname, username=self._ssh_user,
                                   password=self._ssh_password,
                                   bastion_host=self._bastion_host,
                                   key_files=self._ssh_key_file,
                                   key_material=self._ssh_key_material,
                                   passphrase=self._passphrase,
                                   port=port)
        try:
            client.connect()
        except Exception as ex:
            error = 'Failed connecting to host %s.' % hostname
            LOG.exception(error)
            if raise_on_any_error:
                raise
            error_dict = self._generate_error_result(exc=ex, message=error)
            self._bad_hosts[hostname] = error_dict
            results[hostname] = error_dict
        else:
            self._successful_connects += 1
            self._hosts_client[hostname] = client
            results[hostname] = {'message': 'Connected to host.'}
コード例 #6
0
    def test_create_with_key_via_bastion(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'bastion_host': 'bastion.host.org',
                       'username': '******',
                       'key_files': 'id_rsa'}
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_bastion_conn = {'username': '******',
                                 'allow_agent': False,
                                 'hostname': 'bastion.host.org',
                                 'look_for_keys': False,
                                 'key_filename': 'id_rsa',
                                 'timeout': 60,
                                 'port': 22}
        mock.bastion_client.connect.assert_called_once_with(**expected_bastion_conn)

        expected_conn = {'username': '******',
                         'allow_agent': False,
                         'hostname': 'dummy.host.org',
                         'look_for_keys': False,
                         'key_filename': 'id_rsa',
                         'timeout': 60,
                         'port': 22,
                         'sock': mock.bastion_socket}
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #7
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_create_with_key_via_bastion(self):
        conn_params = {
            "hostname": "dummy.host.org",
            "bastion_host": "bastion.host.org",
            "username": "******",
            "key_files": "id_rsa",
        }
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_bastion_conn = {
            "username": "******",
            "allow_agent": False,
            "hostname": "bastion.host.org",
            "look_for_keys": False,
            "key_filename": "id_rsa",
            "timeout": 30,
            "port": 22,
        }
        mock.bastion_client.connect.assert_called_once_with(
            **expected_bastion_conn)

        expected_conn = {
            "username": "******",
            "allow_agent": False,
            "hostname": "dummy.host.org",
            "look_for_keys": False,
            "key_filename": "id_rsa",
            "timeout": 30,
            "port": 22,
            "sock": mock.bastion_socket,
        }
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #8
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_socket_closed(self):
        conn_params = {
            'hostname': 'dummy.host.org',
            'username': '******',
            'password': '******',
            'timeout': '600'
        }
        ssh_client = ParamikoSSHClient(**conn_params)

        # Make sure .close() doesn't actually call anything real
        ssh_client.client = Mock()
        ssh_client.sftp_client = Mock()
        ssh_client.bastion_client = Mock()

        ssh_client.socket = Mock()
        ssh_client.bastion_socket = Mock()

        # Make sure we havent called any close methods at this point
        # TODO: Replace these with .assert_not_called() once it's Python 3.6+ only
        self.assertEqual(ssh_client.socket.close.call_count, 0)
        self.assertEqual(ssh_client.client.close.call_count, 0)
        self.assertEqual(ssh_client.sftp_client.close.call_count, 0)
        self.assertEqual(ssh_client.bastion_socket.close.call_count, 0)
        self.assertEqual(ssh_client.bastion_client.close.call_count, 0)

        # Call the function that has changed
        ssh_client.close()

        # TODO: Replace these with .assert_called_once() once it's Python 3.6+ only
        self.assertEqual(ssh_client.socket.close.call_count, 1)
        self.assertEqual(ssh_client.client.close.call_count, 1)
        self.assertEqual(ssh_client.sftp_client.close.call_count, 1)
        self.assertEqual(ssh_client.bastion_socket.close.call_count, 1)
        self.assertEqual(ssh_client.bastion_client.close.call_count, 1)
コード例 #9
0
 def test_passphrase_not_provided_for_encrypted_key_file(self):
     path = os.path.join(get_resources_base_path(),
                         'ssh', 'dummy_rsa_passphrase')
     conn_params = {'hostname': 'dummy.host.org',
                    'username': '******',
                    'key_files': path}
     mock = ParamikoSSHClient(**conn_params)
     self.assertRaises(paramiko.ssh_exception.PasswordRequiredException, mock.connect)
コード例 #10
0
    def test_passphrase_no_key_provided(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'passphrase': 'testphrase'}

        expected_msg = 'passphrase should accompany private key material'
        client = ParamikoSSHClient(**conn_params)
        self.assertRaisesRegexp(ValueError, expected_msg, client.connect)
コード例 #11
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_sftp_connection_is_only_established_if_required(self):
        # Verify that SFTP connection is lazily established only if and when needed.
        conn_params = {
            'hostname': 'dummy.host.org',
            'username': '******',
            'password': '******'
        }

        # Verify sftp connection and client hasn't been established yet
        client = ParamikoSSHClient(**conn_params)
        client.connect()

        self.assertIsNone(client.sftp_client)

        # run method doesn't require sftp access so it shouldn't establish connection
        client = ParamikoSSHClient(**conn_params)
        client.connect()
        client.run(cmd='whoami')

        self.assertIsNone(client.sftp_client)

        # Methods below require SFTP access so they should cause SFTP connection to be established
        # put
        client = ParamikoSSHClient(**conn_params)
        client.connect()
        path = '/root/random_script.sh'
        client.put(path, path, mirror_local_mode=False)

        self.assertIsNotNone(client.sftp_client)

        # exists
        client = ParamikoSSHClient(**conn_params)
        client.connect()
        client.exists('/root/somepath.txt')

        self.assertIsNotNone(client.sftp_client)

        # mkdir
        client = ParamikoSSHClient(**conn_params)
        client.connect()
        client.mkdir('/root/somedirfoo')

        self.assertIsNotNone(client.sftp_client)

        # Verify close doesn't throw if SFTP connection is not established
        client = ParamikoSSHClient(**conn_params)
        client.connect()

        self.assertIsNone(client.sftp_client)
        client.close()

        # Verify SFTP connection is closed if it's opened
        client = ParamikoSSHClient(**conn_params)
        client.connect()
        client.mkdir('/root/somedirfoo')

        self.assertIsNotNone(client.sftp_client)
        client.close()

        self.assertEqual(client.sftp_client.close.call_count, 1)
コード例 #12
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_passphrase_no_key_provided(self):
        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "passphrase": "testphrase",
        }

        expected_msg = "passphrase should accompany private key material"
        client = ParamikoSSHClient(**conn_params)
        self.assertRaisesRegexp(ValueError, expected_msg, client.connect)
コード例 #13
0
    def test_key_material_argument_invalid_key(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'key_material': 'id_rsa'}

        mock = ParamikoSSHClient(**conn_params)

        expected_msg = 'Invalid or unsupported key type'
        self.assertRaisesRegexp(paramiko.ssh_exception.SSHException,
                                expected_msg, mock.connect)
コード例 #14
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
 def test_passphrase_not_provided_for_encrypted_key_file(self):
     path = os.path.join(get_resources_base_path(), "ssh",
                         "dummy_rsa_passphrase")
     conn_params = {
         "hostname": "dummy.host.org",
         "username": "******",
         "key_files": path,
     }
     mock = ParamikoSSHClient(**conn_params)
     self.assertRaises(paramiko.ssh_exception.PasswordRequiredException,
                       mock.connect)
コード例 #15
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_key_material_argument_invalid_key(self):
        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "key_material": "id_rsa",
        }

        mock = ParamikoSSHClient(**conn_params)

        expected_msg = "Invalid or unsupported key type"
        self.assertRaisesRegexp(paramiko.ssh_exception.SSHException,
                                expected_msg, mock.connect)
コード例 #16
0
    def test_key_files_and_key_material_arguments_are_mutual_exclusive(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'key_files': 'id_rsa',
                       'key_material': 'key'}

        expected_msg = ('key_files and key_material arguments are mutually exclusive. '
                        'Supply only one.')

        client = ParamikoSSHClient(**conn_params)

        self.assertRaisesRegexp(ValueError, expected_msg,
                                client.connect)
コード例 #17
0
    def setUp(self):
        """
        Creates the object patching the actual connection.
        """
        cfg.CONF.set_override(name='ssh_key_file', override=None, group='system_user')
        cfg.CONF.set_override(name='use_ssh_config', override=False, group='ssh_runner')

        conn_params = {'hostname': 'dummy.host.org',
                       'port': 8822,
                       'username': '******',
                       'key_files': '~/.ssh/ubuntu_ssh',
                       'timeout': '600'}
        self.ssh_cli = ParamikoSSHClient(**conn_params)
コード例 #18
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_key_material_contains_path_not_contents(self):
        conn_params = {'hostname': 'dummy.host.org', 'username': '******'}
        key_materials = ['~/.ssh/id_rsa', '/tmp/id_rsa', 'C:\\id_rsa']

        expected_msg = (
            '"private_key" parameter needs to contain private key data / content and '
            'not a path')

        for key_material in key_materials:
            conn_params = conn_params.copy()
            conn_params['key_material'] = key_material
            mock = ParamikoSSHClient(**conn_params)

            self.assertRaisesRegexp(paramiko.ssh_exception.SSHException,
                                    expected_msg, mock.connect)
コード例 #19
0
    def test_deprecated_key_argument(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'key_files': 'id_rsa'}
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_conn = {'username': '******',
                         'allow_agent': False,
                         'hostname': 'dummy.host.org',
                         'look_for_keys': False,
                         'key_filename': 'id_rsa',
                         'timeout': 60,
                         'port': 22}
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #20
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_key_material_contains_path_not_contents(self):
        conn_params = {"hostname": "dummy.host.org", "username": "******"}
        key_materials = ["~/.ssh/id_rsa", "/tmp/id_rsa", "C:\\id_rsa"]

        expected_msg = (
            '"private_key" parameter needs to contain private key data / content and '
            "not a path")

        for key_material in key_materials:
            conn_params = conn_params.copy()
            conn_params["key_material"] = key_material
            mock = ParamikoSSHClient(**conn_params)

            self.assertRaisesRegexp(paramiko.ssh_exception.SSHException,
                                    expected_msg, mock.connect)
コード例 #21
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_create_without_credentials(self):
        """
        Initialize object with no credentials.

        Just to have better coverage, initialize the object
        without 'password' neither 'key'. Now that we only reconcile
        the final parameters at the last moment when we explicitly
        try to connect, all the credentials should be set to None.
        """
        conn_params = {'hostname': 'dummy.host.org', 'username': '******'}
        mock = ParamikoSSHClient(**conn_params)

        self.assertEqual(mock.password, None)
        self.assertEqual(mock.key_material, None)
        self.assertEqual(mock.key_files, None)
コード例 #22
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_key_files_and_key_material_arguments_are_mutual_exclusive(self):
        conn_params = {
            "hostname": "dummy.host.org",
            "username": "******",
            "key_files": "id_rsa",
            "key_material": "key",
        }

        expected_msg = (
            "key_files and key_material arguments are mutually exclusive. "
            "Supply only one.")

        client = ParamikoSSHClient(**conn_params)

        self.assertRaisesRegexp(ValueError, expected_msg, client.connect)
コード例 #23
0
    def test_create_with_password(self):
        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'password': '******'}
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_conn = {'username': '******',
                         'password': '******',
                         'allow_agent': False,
                         'hostname': 'dummy.host.org',
                         'look_for_keys': False,
                         'timeout': 60,
                         'port': 22}
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #24
0
    def _connect(self, host, results, raise_on_any_error=False):
        (hostname, port) = self._get_host_port_info(host)

        extra = {"host": host, "port": port, "user": self._ssh_user}
        if self._ssh_password:
            extra["password"] = "******"
        elif self._ssh_key_file:
            extra["key_file_path"] = self._ssh_key_file
        else:
            extra["private_key"] = "<redacted>"

        LOG.debug("Connecting to host.", extra=extra)

        client = ParamikoSSHClient(
            hostname=hostname,
            port=port,
            username=self._ssh_user,
            password=self._ssh_password,
            bastion_host=self._bastion_host,
            key_files=self._ssh_key_file,
            key_material=self._ssh_key_material,
            passphrase=self._passphrase,
            handle_stdout_line_func=self._handle_stdout_line_func,
            handle_stderr_line_func=self._handle_stderr_line_func,
        )
        try:
            client.connect()
        except SSHException as ex:
            LOG.exception(ex)
            if raise_on_any_error:
                raise
            error_dict = self._generate_error_result(
                exc=ex, message="Connection error."
            )
            self._bad_hosts[hostname] = error_dict
            results[hostname] = error_dict
        except Exception as ex:
            error = "Failed connecting to host %s." % hostname
            LOG.exception(error)
            if raise_on_any_error:
                raise
            error_dict = self._generate_error_result(exc=ex, message=error)
            self._bad_hosts[hostname] = error_dict
            results[hostname] = error_dict
        else:
            self._successful_connects += 1
            self._hosts_client[hostname] = client
            results[hostname] = {"message": "Connected to host."}
コード例 #25
0
    def test_fail_set_proxycommand(self, mock_ProxyCommand):
        """
        Loads proxy commands from ssh config file
        """
        ssh_config_file_path = os.path.join(get_resources_base_path(),
                                            'ssh', 'dummy_ssh_config_fail')
        cfg.CONF.set_override(name='ssh_config_file_path',
                              override=ssh_config_file_path,
                              group='ssh_runner')
        cfg.CONF.set_override(name='use_ssh_config',
                              override=True, group='ssh_runner')

        conn_params = {'hostname': 'dummy.host.org'}
        mock = ParamikoSSHClient(**conn_params)
        self.assertRaises(Exception, mock.connect)
        mock_ProxyCommand.assert_not_called()
コード例 #26
0
    def test_set_proxycommand(self, mock_ProxyCommand):
        """
        Loads proxy commands from ssh config file
        """
        ssh_config_file_path = os.path.join(get_resources_base_path(),
                                            'ssh', 'dummy_ssh_config')
        cfg.CONF.set_override(name='ssh_config_file_path',
                              override=ssh_config_file_path,
                              group='ssh_runner')
        cfg.CONF.set_override(name='use_ssh_config', override=True,
                              group='ssh_runner')

        conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'password': '******'}
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()
        mock_ProxyCommand.assert_called_once_with('ssh -q -W dummy.host.org:22 dummy_bastion')
コード例 #27
0
    def test_incorrect_passphrase(self):
        path = os.path.join(get_resources_base_path(),
                            'ssh', 'dummy_rsa_passphrase')

        with open(path, 'r') as fp:
            private_key = fp.read()

        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******',
                       'key_material': private_key,
                       'passphrase': 'incorrect'}
        mock = ParamikoSSHClient(**conn_params)

        expected_msg = 'Invalid passphrase or invalid/unsupported key type'
        self.assertRaisesRegexp(paramiko.ssh_exception.SSHException,
                                expected_msg, mock.connect)
コード例 #28
0
    def test_create_without_credentials_use_default_key(self):
        # No credentials are provided by default stanley ssh key exists so it should use that
        cfg.CONF.set_override(name='ssh_key_file', override='stanley_rsa', group='system_user')

        conn_params = {'hostname': 'dummy.host.org',
                       'username': '******'}
        mock = ParamikoSSHClient(**conn_params)
        mock.connect()

        expected_conn = {'username': '******',
                         'hostname': 'dummy.host.org',
                         'key_filename': 'stanley_rsa',
                         'allow_agent': False,
                         'look_for_keys': False,
                         'timeout': 60,
                         'port': 22}
        mock.client.connect.assert_called_once_with(**expected_conn)
コード例 #29
0
ファイル: test_paramiko_ssh.py プロジェクト: yetudada/st2
    def test_consume_stderr(self):
        # Test utf-8 decoding of ``stderr`` still works fine when reading CHUNK_SIZE splits a
        # multi-byte utf-8 character in the middle. We should wait to collect all bytes
        # and finally decode.
        conn_params = {'hostname': 'dummy.host.org', 'username': '******'}
        mock = ParamikoSSHClient(**conn_params)
        mock.CHUNK_SIZE = 1
        chan = Mock()
        chan.recv_stderr_ready.side_effect = [True, True, True, True, False]

        chan.recv_stderr.side_effect = [b'\xF0', b'\x90', b'\x8D', b'\x88']
        try:
            b'\xF0'.decode('utf-8')
            self.fail('Test fixture is not right.')
        except UnicodeDecodeError:
            pass
        stderr = mock._consume_stderr(chan)
        self.assertEqual(u'\U00010348', stderr.getvalue())
コード例 #30
0
ファイル: test_paramiko_ssh.py プロジェクト: st2sandbox/st2
    def test_consume_stderr(self):
        # Test utf-8 decoding of ``stderr`` still works fine when reading CHUNK_SIZE splits a
        # multi-byte utf-8 character in the middle. We should wait to collect all bytes
        # and finally decode.
        conn_params = {"hostname": "dummy.host.org", "username": "******"}
        mock = ParamikoSSHClient(**conn_params)
        mock.CHUNK_SIZE = 1
        chan = Mock()
        chan.recv_stderr_ready.side_effect = [True, True, True, True, False]

        chan.recv_stderr.side_effect = [b"\xF0", b"\x90", b"\x8D", b"\x88"]
        try:
            b"\xF0".decode("utf-8")
            self.fail("Test fixture is not right.")
        except UnicodeDecodeError:
            pass
        stderr = mock._consume_stderr(chan)
        self.assertEqual("\U00010348", stderr.getvalue())