コード例 #1
0
    def test_add_to_known_hosts_dry(self, mock_popen):
        hosts = [
            msshcopyid.Host(hostname='server1'),
            msshcopyid.Host(hostname='server2'),
            msshcopyid.Host(hostname='server3')
        ]
        known_hosts = MagicMock()

        server1_ssh_key = 'server1 ssh-rsa KRDZhqpguSRxeiqLseaD'
        server2_ssh_key = 'server2 ssh-rsa AAAAB3NzaC1yc2EAAAAB'
        server3_ssh_key = 'server3 ssh-rsa O2gDXC6h6QDXCaHo6pOH'
        server4_ssh_key = 'server4 ssh-rsa hdHWpZ8fDvQArTUFCfgU'

        keyscans = [server2_ssh_key, server3_ssh_key, server1_ssh_key]
        mock_popen.return_value.communicate.return_value = (
            '\n'.join(keyscans), MagicMock())

        known_hosts_content = [server1_ssh_key, server4_ssh_key]
        mock_bopen = mock_open(read_data='\n'.join(known_hosts_content))

        with patch('msshcopyid.open', mock_bopen):
            self.sshcopyid.add_to_known_hosts(hosts,
                                              known_hosts=known_hosts,
                                              dry=True)

        mock_bopen.return_value.writelines.assert_not_called()
コード例 #2
0
    def test_remove_from_known_hosts_error(self, mock_logger, mock_check_call,
                                           mock_format_error,
                                           mock_format_exception):
        hosts = [
            msshcopyid.Host(hostname='server1'),
            msshcopyid.Host(hostname='server2'),
            msshcopyid.Host(hostname='server3')
        ]
        known_hosts = '/path/to/known_hosts'
        cmds = []
        check_call_side_effect = []
        for host in hosts:
            cmd = ['ssh-keygen', '-f', known_hosts, '-R', host.hostname]
            cmds.append(cmd)
            check_call_side_effect.append(subprocess.CalledProcessError(
                1, cmd))
        mock_check_call.side_effect = check_call_side_effect

        self.sshcopyid.remove_from_known_hosts(hosts,
                                               known_hosts=known_hosts,
                                               dry=False)

        for cmd, ex in zip(cmds, check_call_side_effect):
            mock_check_call.assert_any_call(cmd)
            mock_logger.error.assert_any_call(
                mock_format_error(mock_format_exception(ex)))
コード例 #3
0
    def test_remove_from_known_hosts_dry(self, mock_check_call):
        hosts = [
            msshcopyid.Host(hostname='server1'),
            msshcopyid.Host(hostname='server2'),
            msshcopyid.Host(hostname='server3')
        ]
        known_hosts = '/path/to/known_hosts'

        self.sshcopyid.remove_from_known_hosts(hosts,
                                               known_hosts=known_hosts,
                                               dry=True)

        mock_check_call.assert_not_called()
コード例 #4
0
    def test_remove_from_known_hosts(self, mock_check_call):
        hosts = [
            msshcopyid.Host(hostname='server1'),
            msshcopyid.Host(hostname='server2'),
            msshcopyid.Host(hostname='server3')
        ]
        known_hosts = '/path/to/known_hosts'

        self.sshcopyid.remove_from_known_hosts(hosts,
                                               known_hosts=known_hosts,
                                               dry=False)

        for host in hosts:
            cmd = ['ssh-keygen', '-f', known_hosts, '-R', host.hostname]
            mock_check_call.assert_any_call(cmd)
コード例 #5
0
    def test_copy_ssh_keys_to_host_wrong_password(self, mock_ssh_client,
                                                  mock_auto_add_policy,
                                                  mock_isfile):
        host = msshcopyid.Host(hostname='server1',
                               port=12345,
                               user='******',
                               password='******')
        known_hosts = MagicMock()
        client = mock_ssh_client.return_value
        auth_exception = paramiko.ssh_exception.AuthenticationException(
            'authentication exception')
        client.connect.side_effect = auth_exception

        self.sshcopyid.priv_key = MagicMock()
        self.sshcopyid.pub_key_content = 'ssh-rsa AAAAB3NzaC1yc2EAAAAD'
        password = None

        with self.assertRaises(paramiko.ssh_exception.SSHException) as exctx:
            self.sshcopyid.copy_ssh_keys_to_host(host,
                                                 password=password,
                                                 no_add_host=True,
                                                 known_hosts=known_hosts)
            self.assertEqual(exctx.exception, auth_exception)

        client.set_missing_host_key_policy.assert_not_called()
        client.connect.assert_called_once_with(
            host.hostname,
            port=host.port,
            username=host.user,
            password=password,
            key_filename=self.sshcopyid.priv_key)
        client.exec_command.assert_not_called()
コード例 #6
0
    def test_copy_ssh_keys_to_host(self, mock_ssh_client, mock_auto_add_policy,
                                   mock_isfile):
        host = msshcopyid.Host(hostname='server1',
                               port=12345,
                               user='******',
                               password='******')
        known_hosts = MagicMock()

        self.sshcopyid.priv_key = MagicMock()
        self.sshcopyid.pub_key_content = 'ssh-rsa AAAAB3NzaC1yc2EAAAAD'
        password = None

        self.sshcopyid.copy_ssh_keys_to_host(host,
                                             password=password,
                                             no_add_host=False,
                                             known_hosts=known_hosts)

        client = mock_ssh_client.return_value
        client.set_missing_host_key_policy.assert_called_once_with(
            mock_auto_add_policy.return_value)
        client.connect.assert_called_once_with(
            host.hostname,
            port=host.port,
            username=host.user,
            password=password,
            key_filename=self.sshcopyid.priv_key)
        cmd = (r'''mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
k='{0}' && if ! grep -qFx "$k" ~/.ssh/authorized_keys; then echo "$k" >> ~/.ssh/authorized_keys; fi'''
               .format(self.sshcopyid.pub_key_content))
        client.exec_command.assert_called_once_with(cmd)
コード例 #7
0
ファイル: utils.py プロジェクト: samuel-phan/mssh-copy-id
def parse_hosts(hosts, ssh_port=None, ssh_config=None):
    """
    Parse a list of hosts (string) and return a list of `msshcopyid.Host` objects.

    The information about the host are taken in this order of priority:

    - host:
        - from the host (string) itself.
    - user:
        - from the host (string) itself.
        - from the `paramiko.config.SSHConfig` object.
        - current logged user.
    - port:
        - from the function argument `port`.
        - from the `paramiko.config.SSHConfig` object.
        - default SSH port: 22

    :param hosts: list of hosts (string). Eg: ['server1', 'user1@server2']
    :param ssh_config: a `paramiko.config.SSHConfig` object.
    :return: a list of `msshcopyid.Host` objects.
    """
    host_list = []  # list of Host objects
    current_user = getpass.getuser()
    for host in hosts:
        # host_info = {'hostname': 'server1', 'hashknownhosts': 'no', 'user': '******'}
        if ssh_config is not None:
            host_info = ssh_config.lookup(host)
        else:
            host_info = {}

        # hostname & user
        if '@' in host:
            user, hostname = host.split('@', 1)
        else:
            hostname = host
            user = host_info.get('user', current_user)

        # port
        port = ssh_port or host_info.get('port', DEFAULT_SSH_PORT)

        host_list.append(
            msshcopyid.Host(hostname=hostname, port=port, user=user))

    return host_list