示例#1
0
def test_get_device_sendline(mock_pxssh, mock_nxos_device, mock_paramiko):
    mock_pxssh.return_value.expect.side_effect = [2, 0]
    get_device(target=dev_info['target'],
               user=dev_info['user'],
               passwd=dev_info['passwd'])
    calls = [call('show version'), call('cat /proc/version')]
    mock_pxssh.return_value.sendline.assert_has_calls(calls)
示例#2
0
def test_get_device_paramiko_authentication_exception(mock_paramiko):
    mock_paramiko.return_value.connect.side_effect = AuthenticationException
    with pytest.raises(TargetError) as e:
        get_device(target=dev_info['target'],
                   user=dev_info['user'],
                   passwd=dev_info['passwd'])
    assert e.value.message == ('Authentication error: %s' % dev_info['target'])
示例#3
0
def test_get_device_paramiko_ssh_exception(mock_paramiko):
    mock_paramiko.return_value.connect.side_effect = SSHException
    with pytest.raises(TargetError) as e:
        get_device(target=dev_info['target'],
                   user=dev_info['user'],
                   passwd=dev_info['passwd'])
    assert e.value.message == ('Error logging in: %s' % dev_info['target'])
示例#4
0
def test_get_device_socket_error(mock_paramiko):
    mock_paramiko.return_value.connect.side_effect = socket.error
    with pytest.raises(TargetError) as e:
        get_device(target=dev_info['target'],
                   user=dev_info['user'],
                   passwd=dev_info['passwd'])
    assert e.value.message == ('Device unreachable: %s' % dev_info['target'])
示例#5
0
def test_get_device_login(mock_pxssh, mock_nxos_device, mock_paramiko):
    mock_pxssh.return_value.expect.return_value = 0
    get_device(target=dev_info['target'],
               user=dev_info['user'],
               passwd=dev_info['passwd'])
    mock_paramiko.return_value.connect.assert_called_with(
        dev_info['target'],
        username=dev_info['user'],
        timeout=5,
        password=dev_info['passwd'])
    mock_pxssh.return_value.login.assert_called_with(
        dev_info['target'],
        dev_info['user'],
        auto_prompt_reset=False,
        login_timeout=10,
        password=dev_info['passwd'])
示例#6
0
def test_get_device_cumulus(mock_pxssh, mock_cumulus_device, mock_paramiko):
    device_name = 'cumulus_device'
    mock_pxssh.return_value.expect.side_effect = [2, 0]
    mock_cumulus_device.return_value = device_name
    dev = get_device(target=dev_info['target'],
                     user=dev_info['user'],
                     passwd=dev_info['passwd'])
    assert dev == device_name
示例#7
0
def test_get_device_eos(mock_pxssh, mock_eos_device, mock_paramiko):
    device_name = 'eos_device'
    mock_pxssh.return_value.expect.return_value = 1
    mock_eos_device.return_value = device_name
    dev = get_device(target=dev_info['target'],
                     user=dev_info['user'],
                     passwd=dev_info['passwd'])
    assert dev == device_name
示例#8
0
def test_get_device_target_error(mock_pxssh, mock_ssh):
    mock_pxssh.return_value.expect.side_effect = [2, 4]
    with pytest.raises(TargetError) as e:
        dev = get_device(target=dev_info['target'],
                         user=dev_info['user'],
                         passwd=dev_info['passwd'])
    assert e.value.message == 'Unable to determine device type for %s' % dev_info[
        'target']
示例#9
0
def test_get_device_nos_only(mock_pxssh, mock_nxos_device, mock_paramiko):
    device_name = 'nxos'
    mock_pxssh.return_value.expect.return_value = 0
    mock_nxos_device.return_value = device_name
    dev = get_device(target=dev_info['target'],
                     user=dev_info['user'],
                     passwd=dev_info['passwd'],
                     nos_only=True)
    assert dev == device_name
示例#10
0
def test_get_device_exception(mock_pxssh, mock_ssh):
    exception_msg = 'Test Exception Message'
    mock_pxssh.return_value.login.side_effect = ExceptionPxssh(exception_msg)
    with pytest.raises(TargetError) as e:
        dev = get_device(target=dev_info['target'],
                         user=dev_info['user'],
                         passwd=dev_info['passwd'])
    assert e.value.message == 'Error logging in to {target} : {error}'.format(
        target=dev_info['target'], error=exception_msg)
示例#11
0
def retry_ztp(target, nos=None, user='******', password='******'):
    log = setup_logging(logname='aeon-retry', target=target)
    cumulus_lease_file = '/var/lib/dhcp/dhclient.eth0.leases'
    server = "{}:{}".format(get_server_ipaddr(target), _AEON_PORT)
    dev_table = {
        'eos': {
            'dev_obj': EosDevice,
            'cmds': ['write erase now', 'reload now']
        },
        'cumulus': {
            'dev_obj':
            CumulusDevice,
            'cmds': [
                "sudo sed -i '/vrf mgmt/d' /etc/network/interfaces",
                'sudo ztp -R', 'sudo reboot'
            ],
            'virt_cmds': [
                "sudo ztp -v -r $(cat %s | grep 'cumulus-provision-url'| tail -1 | cut -f2 -d \\\")"
                % cumulus_lease_file
            ]
        },
        'nxos': {
            'dev_obj': NxosDevice,
            'cmds': 'terminal dont-ask ; write erase ; reload'
        },
        'ubuntu': {
            'dev_obj':
            UbuntuDevice,
            'cmds': [
                'curl "http://{}/api/register/ubuntu"'.format(
                    get_server_ipaddr(target))
            ]
        },
        'centos': {
            'dev_obj':
            CentosDevice,
            'cmds': [
                'curl "http://{}/api/register/centos"'.format(
                    get_server_ipaddr(target))
            ]
        }
    }

    def post_success():
        message = 'Retry successfully initiated'
        log.info(message)
        post_device_status(server=server,
                           target=target,
                           state='RETRY',
                           message=message)

    try:
        if not nos:
            log.info('Determining device OS type')
            dev = get_device(target=target, user=user, passwd=password)
            dev.gather_facts()
            nos = dev.facts['os_name'].lower()
        else:
            nos = nos.lower()
            log.info('Device OS type: %s' % nos)
            if not any(nos in x for x in dev_table):
                error_msg = 'Retry not supported for device type %s' % nos
                log.error(error_msg)
                post_device_status(server=server,
                                   target=target,
                                   state='ERROR',
                                   message=error_msg)
                return False, error_msg
            dev = dev_table[nos]['dev_obj'](target, user=user, passwd=password)
    except (ProbeError, TargetError) as e:
        error_msg = 'Error accessing device: %s' % str(e)
        log.error(error_msg)
        post_device_status(server=server,
                           target=target,
                           state='ERROR',
                           message=error_msg)
        log.handlers.pop()
        return False, error_msg

    try:
        # CumulusVX doesn't always boot into ZTP mode without network errors
        # Use different retry commands for CVX
        if dev.facts['os_name'] == 'cumulus' and dev.facts['virtual']:
            log.info('Running retry commands: %s' %
                     dev_table[nos]['virt_cmds'])
            ok, output = dev.api.execute(dev_table[nos]['virt_cmds'])
            post_success()
            return ok, output
        # aeon-venos NxosDevice doesn't use execute for some reason
        elif dev.facts['os_name'] == 'nxos':
            # Ignore timeout after reload
            try:
                log.info('Running retry commands. %s' % dev_table[nos]['cmds'])
                output = (dev.api.exec_config(dev_table[nos]['cmds'],
                                              timeout=10))
            except TimeoutError:
                post_success()
                output = True
                ok = True
        else:
            log.info('Running retry commands: %s' % dev_table[nos]['cmds'])
            ok, output = dev.api.execute(dev_table[nos]['cmds'])
            post_success()
            return ok, output
    except (CommandError, NxosCommandError) as e:
        # IncompleteRead error raised when reloading EOS. This is normal.
        if 'IncompleteRead' in str(e.exc):
            post_success()
            return True, None
        error_msg = 'Unable to initiate ZTP retry: %s' % str(e)
        log.error(error_msg)
        post_device_status(server=server,
                           target=target,
                           state='ERROR',
                           message=error_msg)
        return False, e
    except TimeoutError:
        error_msg = 'Device %s unreachable' % target
        log.error('Unable to initiate ZTP retry: Device %s unreachable' %
                  target)
        post_device_status(server=server,
                           target=target,
                           state='ERROR',
                           message=error_msg)
        return False, error_msg
    except LoginNotReadyError as e:
        error_msg = 'Unable to login to device: %s' % str(e)
        log.error(error_msg)
        post_device_status(server=server,
                           target=target,
                           state='ERROR',
                           message=error_msg)

    finally:
        log.handlers.pop()

    return ok, output