예제 #1
0
    def test_mkdir(self, execute, exists, client, policy, logger):
        exists.side_effect = [False, True]

        path = '~/tst'

        ssh = SSHClient(
            host=host,
            port=port,
            auth=SSHAuth(
                username=username,
                password=password
            ))

        # Path not exists
        ssh.mkdir(path)
        exists.assert_called_once_with(path)
        execute.assert_called_once_with("mkdir -p {}\n".format(path))

        # Path exists
        exists.reset_mock()
        execute.reset_mock()

        ssh.mkdir(path)
        exists.assert_called_once_with(path)
        execute.assert_not_called()
예제 #2
0
    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()
        ))
예제 #3
0
    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()))
예제 #4
0
    def test_init_reconnect(
            self, client, policy, logger, sleep):
        """Test reconnect

        :type client: mock.Mock
        :type policy: mock.Mock
        :type logger: mock.Mock
        """
        ssh = SSHClient(host=host, auth=SSHAuth())
        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_not_called()

        self.assertEqual(ssh.auth, SSHAuth())

        sftp = ssh._sftp
        self.assertEqual(sftp, client().open_sftp())

        self.assertEqual(ssh._ssh, client())

        client.reset_mock()
        policy.reset_mock()

        self.assertEqual(ssh.hostname, host)
        self.assertEqual(ssh.port, port)

        ssh.reconnect()

        _ssh = mock.call()

        expected_calls = [
            _ssh.close(),
            _ssh,
            _ssh.set_missing_host_key_policy('AutoAddPolicy'),
            _ssh.connect(
                hostname='127.0.0.1',
                password=None,
                pkey=None,
                port=22,
                username=None),
        ]
        self.assertIn(
            expected_calls,
            client.mock_calls
        )

        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_not_called()

        self.assertEqual(ssh.auth, SSHAuth())

        sftp = ssh._sftp
        self.assertEqual(sftp, client().open_sftp())

        self.assertEqual(ssh._ssh, client())
예제 #5
0
파일: node.py 프로젝트: lukaszo/fuel-devops
 def _close_remotes(self):
     """Call close cached ssh connections for current node"""
     for network_name in {'admin', 'public', 'internal'}:
         try:
             SSHClient.close_connections(
                 hostname=self.get_ip_address_by_network_name(network_name))
         except BaseException:
             logger.debug(
                 '{0}._close_remotes for {1} failed'.format(
                     self.name, network_name))
예제 #6
0
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)
예제 #7
0
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)
예제 #8
0
    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))
예제 #9
0
    def test_init_clear_failed(
            self, client, policy, logger, sleep):
        """Test reconnect

        :type client: mock.Mock
        :type policy: mock.Mock
        :type logger: mock.Mock
        """
        _ssh = mock.Mock()
        _ssh.attach_mock(
            mock.Mock(
                side_effect=[
                    Exception('Mocked SSH close()'),
                    mock.Mock()
                ]),
            'close')
        _sftp = mock.Mock()
        _sftp.attach_mock(
            mock.Mock(
                side_effect=[
                    Exception('Mocked SFTP close()'),
                    mock.Mock()
                ]),
            'close')
        client.return_value = _ssh
        _ssh.attach_mock(mock.Mock(return_value=_sftp), 'open_sftp')

        ssh = SSHClient(host=host, auth=SSHAuth())
        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_not_called()

        self.assertEqual(ssh.auth, SSHAuth())

        sftp = ssh._sftp
        self.assertEqual(sftp, _sftp)

        self.assertEqual(ssh._ssh, _ssh)

        self.assertEqual(ssh.hostname, host)
        self.assertEqual(ssh.port, port)

        logger.reset_mock()

        ssh.close()

        logger.assert_has_calls((
            mock.call.exception('Could not close ssh connection'),
            mock.call.exception('Could not close sftp connection'),
        ))
예제 #10
0
    def test_rm_rf(self, execute, client, policy, logger):
        path = '~/tst'

        ssh = SSHClient(
            host=host,
            port=port,
            auth=SSHAuth(
                username=username,
                password=password
            ))

        # Path not exists
        ssh.rm_rf(path)
        execute.assert_called_once_with("rm -rf {}".format(path))
예제 #11
0
    def test_init_clear(self, warn, client, policy, logger, sleep):
        ssh01 = SSHClient(host=host, auth=SSHAuth())

        ssh01.clear()
        warn.assert_called_once_with(
            "clear is removed: use close() only if it mandatory: "
            "it's automatically called on revert|shutdown|suspend|destroy",
            DeprecationWarning
        )

        self.assertNotIn(
            mock.call.close(),
            client.mock_calls
        )
예제 #12
0
def one():
    environment = Environment.create('cdrom')
    internal_pool = Network.create_network_pool(
        networks=[IPNetwork('10.108.0.0/16')], prefix=24)
    private_pool = Network.create_network_pool(
        networks=[IPNetwork('10.108.0.0/16')], prefix=24)
    external_pool = Network.create_network_pool(
        networks=[IPNetwork('172.18.95.0/24')], prefix=27)
    internal = Network.network_create(environment=environment,
                                      name='internal',
                                      pool=internal_pool)
    external = Network.network_create(environment=environment,
                                      name='external',
                                      pool=external_pool,
                                      forward='nat')
    private = Network.network_create(environment=environment,
                                     name='private',
                                     pool=private_pool)
    for i in range(1, 2):
        node = Node.node_create(name='test_node' + str(i),
                                environment=environment)
        Interface.interface_create(node=node, network=internal)
        Interface.interface_create(node=node, network=external)
        Interface.interface_create(node=node, network=private)
        volume = Volume.volume_get_predefined(
            '/var/lib/libvirt/images/centos63-cobbler-base.qcow2')
        v3 = Volume.volume_create_child('test_vp895' + str(i),
                                        backing_store=volume,
                                        environment=environment)
        v4 = Volume.volume_create_child('test_vp896' + str(i),
                                        backing_store=volume,
                                        environment=environment)
        DiskDevice.node_attach_volume(node=node, volume=v3)
        DiskDevice.node_attach_volume(node, v4)
        DiskDevice.node_attach_volume(
            node,
            Volume.volume_get_predefined(
                '/var/lib/libvirt/images/fuel-centos-6.3-x86_64.iso'),
            device='cdrom',
            bus='sata')
    environment.define()
    environment.start()
    remotes = []
    for node in environment.get_nodes():
        node. await ('internal')
        node.remote('internal', 'root', 'r00tme').check_stderr('ls -la',
                                                               verbose=True)
        remotes.append(node.remote('internal', 'root', 'r00tme'))
    SSHClient.execute_together(remotes, 'ls -la')
예제 #13
0
    def test_init_change_login_passwd(self, client, policy, logger):
        _ssh = mock.call()

        def check_expected_on_connect(pwd):
            client.assert_called_once()
            policy.assert_called_once()

            expected_calls = [
                _ssh,
                _ssh.set_missing_host_key_policy('AutoAddPolicy'),
                _ssh.connect(
                    host, password=pwd,
                    port=port, username=username),
                _ssh.open_sftp()
            ]

            self.assertIn(expected_calls, client.mock_calls)

            self.check_defaults(ssh, host, port, username, pwd,
                                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, pwd
                )),
                logger.mock_calls
            )
            sftp = ssh._sftp
            self.assertEqual(sftp, client().open_sftp())

        ssh = SSHClient(
            host=host,
            port=port,
            username=username,
            password=password,
            private_keys=private_keys)

        check_expected_on_connect(pwd=password)

        new_password = '******'

        client.reset_mock()
        policy.reset_mock()
        logger.reset_mock()
        ssh.password = new_password

        check_expected_on_connect(pwd=new_password)
예제 #14
0
def one():
    environment = Environment.create('cdrom')
    internal_pool = Network.create_network_pool(
        networks=[IPNetwork('10.108.0.0/16')], prefix=24
    )
    private_pool = Network.create_network_pool(
        networks=[IPNetwork('10.108.0.0/16')], prefix=24
    )
    external_pool = Network.create_network_pool(
        networks=[IPNetwork('172.18.95.0/24')], prefix=27
    )
    internal = Network.network_create(
        environment=environment, name='internal', pool=internal_pool)
    external = Network.network_create(
        environment=environment, name='external', pool=external_pool,
        forward='nat')
    private = Network.network_create(
        environment=environment, name='private', pool=private_pool)
    for i in range(1, 2):
        node = Node.node_create(
            name='test_node' + str(i), environment=environment)
        Interface.interface_create(node=node, network=internal)
        Interface.interface_create(node=node, network=external)
        Interface.interface_create(node=node, network=private)
        volume = Volume.volume_get_predefined(
            '/var/lib/libvirt/images/centos63-cobbler-base.qcow2')
        v3 = Volume.volume_create_child(
            'test_vp895' + str(i), backing_store=volume,
            environment=environment)
        v4 = Volume.volume_create_child(
            'test_vp896' + str(i), backing_store=volume,
            environment=environment)
        DiskDevice.node_attach_volume(node=node, volume=v3)
        DiskDevice.node_attach_volume(node, v4)
        DiskDevice.node_attach_volume(
            node,
            Volume.volume_get_predefined(
                '/var/lib/libvirt/images/fuel-centos-6.3-x86_64.iso'),
            device='cdrom', bus='sata')
    environment.define()
    environment.start()
    remotes = []
    for node in environment.get_nodes():
        node.await('internal')
        node.remote('internal', 'root', 'r00tme').check_stderr(
            'ls -la', verbose=True)
        remotes.append(node.remote('internal', 'root', 'r00tme'))
    SSHClient.execute_together(remotes, 'ls -la')
예제 #15
0
    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())
예제 #16
0
    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)
예제 #17
0
    def test_execute_async_with_sudo(self, client, policy, logger):
        chan = mock.Mock()
        open_session = mock.Mock(return_value=chan)
        transport = mock.Mock()
        transport.attach_mock(open_session, 'open_session')
        get_transport = mock.Mock(return_value=transport)
        _ssh = mock.Mock()
        _ssh.attach_mock(get_transport, 'get_transport')
        client.return_value = _ssh

        ssh = self.init_ssh(client, policy, logger)
        self.assertFalse(ssh.sudo_mode)
        with SSHClient.get_sudo(ssh):
            self.assertTrue(ssh.sudo_mode)
            result = ssh.execute_async(command=command)
        self.assertFalse(ssh.sudo_mode)

        get_transport.assert_called_once()
        open_session.assert_called_once()

        self.assertIn(chan, result)
        chan.assert_has_calls(
            (mock.call.makefile('wb'), mock.call.makefile('rb'),
             mock.call.makefile_stderr('rb'),
             mock.call.exec_command('sudo -S bash -c "{}\n"'.format(command))))
        self.assertIn(
            mock.call.debug("Executing command: '{}'".format(
                command.rstrip())), logger.mock_calls)
예제 #18
0
    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 [])
예제 #19
0
    def test_execute_async_with_sudo(self, client, policy, logger):
        chan = mock.Mock()
        open_session = mock.Mock(return_value=chan)
        transport = mock.Mock()
        transport.attach_mock(open_session, 'open_session')
        get_transport = mock.Mock(return_value=transport)
        _ssh = mock.Mock()
        _ssh.attach_mock(get_transport, 'get_transport')
        client.return_value = _ssh

        ssh = self.get_ssh()
        self.assertFalse(ssh.sudo_mode)
        with SSHClient.get_sudo(ssh):
            self.assertTrue(ssh.sudo_mode)
            result = ssh.execute_async(command=command)
        self.assertFalse(ssh.sudo_mode)

        get_transport.assert_called_once()
        open_session.assert_called_once()

        self.assertIn(chan, result)
        chan.assert_has_calls((
            mock.call.makefile('wb'),
            mock.call.makefile('rb'),
            mock.call.makefile_stderr('rb'),
            mock.call.exec_command(
                "sudo -S bash -c '"
                "eval $(base64 -d <(echo \"{0}\"))'".format(encoded_cmd))
        ))
        self.assertIn(
            mock.call.debug(
                "Executing command: '{}'".format(command.rstrip())),
            logger.mock_calls
        )
예제 #20
0
    def test_init_memorize(self, client, policy, logger, sleep):
        port1 = 2222
        host1 = '127.0.0.2'

        # 1. Normal init
        ssh01 = SSHClient(host=host)
        ssh02 = SSHClient(host=host)
        ssh11 = SSHClient(host=host, port=port1)
        ssh12 = SSHClient(host=host, port=port1)
        ssh21 = SSHClient(host=host1)
        ssh22 = SSHClient(host=host1)

        self.assertTrue(ssh01 is ssh02)
        self.assertTrue(ssh11 is ssh12)
        self.assertTrue(ssh21 is ssh22)
        self.assertFalse(ssh01 is ssh11)
        self.assertFalse(ssh01 is ssh21)
        self.assertFalse(ssh11 is ssh21)

        # 2. Close connections check
        client.reset_mock()
        ssh01.close_connections(ssh01.hostname)
        client.assert_has_calls((
            mock.call().get_transport(),
            mock.call().get_transport(),
            mock.call().close(),
            mock.call().close(),
        ))
        client.reset_mock()
        ssh01.close_connections()
        # Mock returns false-connected state, so we just count close calls

        client.assert_has_calls((
            mock.call().get_transport(),
            mock.call().get_transport(),
            mock.call().get_transport(),
            mock.call().close(),
            mock.call().close(),
            mock.call().close(),
        ))

        # change creds
        SSHClient(host=host, auth=SSHAuth(username=username))

        # Change back: new connection differs from old with the same creds
        ssh004 = SSHAuth(host)
        self.assertFalse(ssh01 is ssh004)
예제 #21
0
    def test_execute_through_host_auth(
            self, transp, client, policy, logger):
        _login = '******'
        _password = '******'

        target = '127.0.0.2'
        exit_code = 0
        return_value = {
            'stderr_str': '0\n1',
            'stdout_str': '2\n3',
            'exit_code': exit_code,
            'stderr': [b' \n', b'0\n', b'1\n', b' \n'],
            'stdout': [b' \n', b'2\n', b'3\n', b' \n']}

        (
            open_session, transport, channel, get_transport,
            open_channel, intermediate_channel
        ) = self.prepare_execute_through_host(
            transp, client, exit_code=exit_code)

        ssh = SSHClient(
            host=host,
            port=port,
            auth=SSHAuth(
                username=username,
                password=password
            ))

        result = ssh.execute_through_host(
            target, command,
            auth=SSHAuth(username=_login, password=_password))
        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.connect(username=_login, password=_password, pkey=None),
            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()
        ))
예제 #22
0
    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)])
예제 #23
0
 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)
예제 #24
0
    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)
예제 #25
0
    def test_execute_together(self, execute_async, client, policy, logger):
        chan, _stdin, stderr, stdout = self.get_patched_execute_async_retval()
        execute_async.return_value = chan, _stdin, stderr, stdout

        host2 = '127.0.0.2'

        ssh = self.get_ssh()
        ssh2 = SSHClient(
            host=host2,
            port=port,
            auth=SSHAuth(
                username=username,
                password=password
            ))

        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()
        ))

        SSHClient.execute_together(
            remotes=remotes, command=command, expected=[1], raise_on_err=False)

        with self.assertRaises(DevopsCalledProcessError):
            SSHClient.execute_together(
                remotes=remotes, command=command, expected=[1])
예제 #26
0
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))
예제 #27
0
    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
예제 #28
0
    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)
예제 #29
0
    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)])
예제 #30
0
    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)
예제 #31
0
    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
예제 #32
0
            super(self.__class__, self).__init__(ssh=ssh, enforce=enforce)

    # New API frontend
    def sudo(self, enforce=None):
        return self._get_sudo(ssh=self, enforce=enforce)

    # Apply patch
    # noinspection PyUnresolvedReferences
    SSHClient._get_sudo = _get_sudo
    # noinspection PyUnresolvedReferences
    SSHClient.get_sudo = get_sudo
    # noinspection PyUnresolvedReferences
    SSHClient.sudo = sudo

    # Enforce closing all connections for objects recreate and API arrival
    SSHClient.close_connections()

else:
    with open(
            os.path.abspath(
                os.path.join(
                    os.path.dirname(os.path.abspath(__file__)),
                    '../requirements-devops-source.txt'
                ))
    ) as req:
        d_req = req.read()

    req_ver = d_req.split('@')[-1]

    if StrictVersion(req_ver) >= StrictVersion('3.0.2'):
        logger.warning(
예제 #33
0
def ssh(*args, **kwargs):
    warn('devops.helpers.ssh is deprecated '
         'and will be removed soon', DeprecationWarning)
    return SSHClient(*args, **kwargs)
예제 #34
0
            super(self.__class__, self).__init__(ssh=ssh, enforce=enforce)

    # New API frontend
    def sudo(self, enforce=None):
        return self._get_sudo(ssh=self, enforce=enforce)

    # Apply patch
    # noinspection PyUnresolvedReferences
    SSHClient._get_sudo = _get_sudo
    # noinspection PyUnresolvedReferences
    SSHClient.get_sudo = get_sudo
    # noinspection PyUnresolvedReferences
    SSHClient.sudo = sudo

    # Enforce closing all connections for objects recreate and API arrival
    SSHClient.close_connections()

else:
    with open(
            os.path.abspath(
                os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             '../requirements-devops-source.txt'))) as req:
        d_req = req.read()

    req_ver = d_req.split('@')[-1]

    if StrictVersion(req_ver) >= StrictVersion('3.0.2'):
        logger.warning(
            'Please revert changes with change-id:\n'
            '\tId90f06b4c83f9e0a21adf5c90aa04111d2a4153e (gerrit 359684)\n'
            'This solution is not required for now due to using actual version'
예제 #35
0
    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()
        ))
예제 #36
0
    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()))
예제 #37
0
 def tearDown(self):
     SSHClient._clear_cache()