Example #1
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    def test_new_console_return(self):
        dev = Device(host='1.1.1.1', user='******', password='******',
                     port=23, gather_facts=False)
        self.assertTrue(isinstance(dev, Console))

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + '.open', mock):
            if sys.version > '3':
                builtin_file = 'io.TextIOWrapper'
            else:
                builtin_file = builtin_string + '.file'
            with patch(builtin_file, MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_master_is_master(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_backup(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = False
        localdev.facts._cache['RE_hw_mi'] = False
        localdev.facts._cache['current_re'] = ['re0']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_multi_chassis_non_master1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_multi_chassis_non_master2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0',
                                               'lcc1-master', 'member1-master',
                                               'member1']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.master, None)

    def test_device_master_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['foo', 'bar']
        self.assertEqual(localdev.master, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_master_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.master, None)

    def test_device_master_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.master = 'foo'

    def test_device_re_name_is_re0(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'tapir',
                                                  're1': 'tapir1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_lcc_re1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 'lcc1-re1')

    def test_device_re_name_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['foo']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        localdev.facts._cache['hostname_info'] = None
        self.assertEqual(localdev.re_name, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_re_name_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.re_name = 'foo'

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            self.dev.facts._cache['current_re'] = ['re0']
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.factcache.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh(warnings_on_failure=True)
            self.assertTrue(mock_warnings.warn.called)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error_exception_on_error(self, mock_warnings,
                                                   mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_old_style_facts_error_exception_on_error(self,
                                                             mock_warnings,
                                                             mock_execute):
        self.dev._fact_style = 'old'
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    def test_device_facts_refresh_unknown_fact_style(self):
        self.dev._fact_style = 'bad'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh()

    def test_device_facts_refresh_old_fact_style_with_keys(self):
        self.dev._fact_style = 'old'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh(keys='domain')

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'test')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_string(self):
        self.dev.timeout = '10'
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_invalid_string_value(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = 'foo'

    def test_device_set_timeout_invalid_type(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = [1,2,3,4]

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    def test_device_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            ofacts = self.dev.ofacts

    def test_device_set_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            self.dev.ofacts = False

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory',
                                      warning=False).tag, 'cli')

    @patch('jnpr.junos.device.json.loads')
    def test_device_rpc_json_ex(self, mock_json_loads):
        self.dev.facts = facts
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        ex = ValueError('Extra data ')
        ex.message = 'Extra data '  # for py3 as we dont have message thr
        mock_json_loads.side_effect = [
            ex,
            self._mock_manager(etree.fromstring(
                '<get-route-information format="json"/>'))]
        self.dev.rpc.get_route_information({'format': 'json'})
        self.assertEqual(mock_json_loads.call_count, 2)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('show system uptime')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show system uptime | match foo | count')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_complex(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show interfaces ge-0/0/0.0 routing-instance all media')
        self.assertEqual("rpc.get_interface_information("
                         "routing_instance='all', media=True, "
                         "interface_name='ge-0/0/0.0')", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_invalid(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('foo')
        self.assertEqual(None, data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_format_json(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interface terse',
                            warning=False, format='json')
        self.assertEqual(type(data), dict)
        self.assertEqual(data['interface-information'][0]
                         ['physical-interface'][0]['oper-status'][0]['data'],
                         'up')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration',
                                                   warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms',
                                                warning=False))

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_cli_output_warning(self, mock_warnings, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance '
                            'all media', format='xml')
        ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/'
                           'address-family[address-family-name="inet"]/'
                           'interface-address/ifa-local')
        self.assertTrue('192.168.100.1' in ip)
        self.assertTrue(mock_warnings.warn.called)
        rpc_string = "rpc.get_interface_information(routing_instance='all', "\
                     "media=True, interface_name='ge-0/0/0.0')"
        self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0])

    def test_device_cli_blank_output(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual('', self.dev.cli('show configuration interfaces',
                                          warning=False))

    def test_device_cli_rpc_reply_with_message(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            '\nprotocol: operation-failed\nerror: device asdf not found\n',
            self.dev.cli('show interfaces terse asdf',
                         warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime| display xml rpc',
                                      warning=False)
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        val = self.dev.cli('foo')
        self.assertEqual(val, 'invalid command: foo: RpcError')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime',
                format='text'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    @patch('jnpr.junos.device.warnings')
    def test_device_execute_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == 'get-rpc-error.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == 'get-permission-denied.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == 'get-index-error.xml' or
                    fname == 'get-system-core-dumps.xml' or
                    fname == 'load-configuration-error.xml' or
                    fname == 'show-configuration-interfaces.xml' or
                  fname == 'show-interfaces-terse-asdf.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            elif (fname == 'show-configuration.xml' or
                  fname == 'show-system-alarms.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc
            elif fname == 'show-interface-terse.json':
                rpc_reply = json.loads(foo)
            elif fname == 'get-route-information.json':
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            else:
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs and 'normalize' not in kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)
        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                if args[0].text == 'show interface terse':
                    return self._read_file('show-interface-terse.json')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime| display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                elif args[0].text == 'show configuration interfaces':
                    return self._read_file('show-configuration-interfaces.xml')
                elif args[0].text == 'show interfaces terse asdf':
                    return self._read_file('show-interfaces-terse-asdf.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media':
                    return self._read_file(
                        'show-interfaces-routing-instance-media.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media| display ' \
                                     'xml rpc':
                    return self._read_file(
                        'show-interfaces-routing-instance-media-rpc.xml')
                else:
                    raise RpcError

            else:
                if args[0].attrib.get('format') == 'json':
                    return self._read_file(args[0].tag + '.json')
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Example #2
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    def test_new_console_return(self):
        dev = Device(host='1.1.1.1', user='******', password='******',
                     port=23, gather_facts=False)
        self.assertTrue(isinstance(dev, Console))

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + '.open', mock):
            if sys.version > '3':
                builtin_file = 'io.TextIOWrapper'
            else:
                builtin_file = builtin_string + '.file'
            with patch(builtin_file, MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_master_is_master(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_backup(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = False
        localdev.facts._cache['RE_hw_mi'] = False
        localdev.facts._cache['current_re'] = ['re0']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_multi_chassis_non_master1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_multi_chassis_non_master2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0',
                                               'lcc1-master', 'member1-master',
                                               'member1']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.master, None)

    def test_device_master_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['foo', 'bar']
        self.assertEqual(localdev.master, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_master_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.master, None)

    def test_device_master_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.master = 'foo'

    def test_device_re_name_is_re0(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'tapir',
                                                  're1': 'tapir1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_lcc_re1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 'lcc1-re1')

    def test_device_re_name_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['foo']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        localdev.facts._cache['hostname_info'] = None
        self.assertEqual(localdev.re_name, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_re_name_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.re_name = 'foo'

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            self.dev.facts._cache['current_re'] = ['re0']
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.factcache.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh(warnings_on_failure=True)
            self.assertTrue(mock_warnings.warn.called)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error_exception_on_error(self, mock_warnings,
                                                   mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_old_style_facts_error_exception_on_error(self,
                                                             mock_warnings,
                                                             mock_execute):
        self.dev._fact_style = 'old'
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    def test_device_facts_refresh_unknown_fact_style(self):
        self.dev._fact_style = 'bad'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh()

    def test_device_facts_refresh_old_fact_style_with_keys(self):
        self.dev._fact_style = 'old'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh(keys='domain')

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'test')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    def test_device_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            ofacts = self.dev.ofacts

    def test_device_set_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            self.dev.ofacts = False

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory',
                                      warning=False).tag, 'cli')

    @patch('jnpr.junos.device.json.loads')
    def test_device_rpc_json_ex(self, mock_json_loads):
        self.dev.facts = facts
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        ex = ValueError('Extra data ')
        ex.message = 'Extra data '  # for py3 as we dont have message thr
        mock_json_loads.side_effect = [
            ex,
            self._mock_manager(etree.fromstring(
                '<get-route-information format="json"/>'))]
        self.dev.rpc.get_route_information({'format': 'json'})
        self.assertEqual(mock_json_loads.call_count, 2)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('show system uptime')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show system uptime | match foo | count')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_complex(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show interfaces ge-0/0/0.0 routing-instance all media')
        self.assertEqual("rpc.get_interface_information("
                         "routing_instance='all', media=True, "
                         "interface_name='ge-0/0/0.0')", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_invalid(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('foo')
        self.assertEqual(None, data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_format_json(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interface terse',
                            warning=False, format='json')
        self.assertEqual(type(data), dict)
        self.assertEqual(data['interface-information'][0]
                         ['physical-interface'][0]['oper-status'][0]['data'],
                         'up')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration',
                                                   warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms',
                                                warning=False))

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_cli_output_warning(self, mock_warnings, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance '
                            'all media', format='xml')
        ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/'
                           'address-family[address-family-name="inet"]/'
                           'interface-address/ifa-local')
        self.assertTrue('192.168.100.1' in ip)
        self.assertTrue(mock_warnings.warn.called)
        rpc_string = "rpc.get_interface_information(routing_instance='all', "\
                     "media=True, interface_name='ge-0/0/0.0')"
        self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0])

    def test_device_cli_blank_output(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual('', self.dev.cli('show configuration interfaces',
                                          warning=False))

    def test_device_cli_rpc_reply_with_message(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            '\nprotocol: operation-failed\nerror: device asdf not found\n',
            self.dev.cli('show interfaces terse asdf',
                         warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime| display xml rpc',
                                      warning=False)
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        val = self.dev.cli('foo')
        self.assertEqual(val, 'invalid command: foo: RpcError')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime',
                format='text'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    @patch('jnpr.junos.device.warnings')
    def test_device_execute_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == 'get-rpc-error.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == 'get-permission-denied.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == 'get-index-error.xml' or
                    fname == 'get-system-core-dumps.xml' or
                    fname == 'load-configuration-error.xml' or
                    fname == 'show-configuration-interfaces.xml' or
                  fname == 'show-interfaces-terse-asdf.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            elif (fname == 'show-configuration.xml' or
                  fname == 'show-system-alarms.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc
            elif fname == 'show-interface-terse.json':
                rpc_reply = json.loads(foo)
            elif fname == 'get-route-information.json':
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            else:
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs and 'normalize' not in kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                if args[0].text == 'show interface terse':
                    return self._read_file('show-interface-terse.json')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime| display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                elif args[0].text == 'show configuration interfaces':
                    return self._read_file('show-configuration-interfaces.xml')
                elif args[0].text == 'show interfaces terse asdf':
                    return self._read_file('show-interfaces-terse-asdf.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media':
                    return self._read_file(
                        'show-interfaces-routing-instance-media.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media| display ' \
                                     'xml rpc':
                    return self._read_file(
                        'show-interfaces-routing-instance-media-rpc.xml')
                else:
                    raise RpcError

            else:
                if args[0].attrib.get('format') == 'json':
                    return self._read_file(args[0].tag + '.json')
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Example #3
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'cannot open'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch('__builtin__.open', mock):
            with patch('__builtin__.file', MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(host='2.2.2.2', user='******', password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            assert self.dev.facts['version'] == facts['version']

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'rick')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory').tag, 'cli')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime | display xml rpc')\
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

    def test_device_execute_exception(self):
        class MyException(Exception):
            rpc_err = """
<rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<error-severity>error</error-severity>
<error-info>
<bad-element>get-bgp-summary-information</bad-element>
</error-info>
<error-message>permission denied</error-message>
</rpc-error>                
            """
            xml = etree.XML(rpc_err)

        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(RpcError, self.dev.execute, 
            '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.func_doc,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            #for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            #for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template('tests/unit/templates/config-example')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                               'domain_name': '2'}),
                               'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        foo = open(fpath).read()

        if (fname == 'get-rpc-error.xml' or
                fname == 'get-index-error.xml' or
                fname == 'get-system-core-dumps.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())
        elif (fname == 'show-configuration.xml' or
              fname == 'show-system-alarms.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc
        else:
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime | display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                else:
                    raise RpcError

            else:
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
'''
print 'Auditing the BGP states using PyEZ Tables and Views:'
for device in my_list_of_devices:
    dev = Device(host=device["management_ip"],
                 user='******',
                 password='******')
    dev.open()
    bgp = BGPNeighborTable(dev)
    bgp.get()
    print "Status of BGP sessions for device " + device["host_name"] + ':'
    for item in bgp:
        print item.neighbor + " is " + item.state
    dev.close()
print 'Done for all the devices!\n'

print 'Auditing the BGP states pulling state data using NetConf get as per standard (Junos render the state data in Openconfig format):'
rpc = E('get', E('filter', {'type': 'xpath', 'source': '/bgp'}))
for item in my_list_of_devices:
    dev = Device(host=item["management_ip"],
                 user='******',
                 password='******')
    dev.open()
    print "Status of BGP sessions for device " + item["host_name"] + ':'
    op = dev.execute(rpc)
    for neighbor in op.findall("bgp/neighbors/neighbor"):
        print "Neighbor " + neighbor.findtext(
            "neighbor-address") + " is " + neighbor.findtext(
                "state/session-state")
    dev.close()
print 'Done for all the devices!\n'
Example #5
0
class NetconfAction(ActionBase):
    """
        Uses NetConf to execute the given template

        Can execute template as an op command
        or apply the template as a configuration template
    """

    dev = None
    request_type = "apply_template"
    result_msg = ""

    def set_endpoint(self, endpoint):
        try:
            # create the required iterator from the endpoint_list
            self.dev = Device(user=endpoint["username"], password=endpoint["password"], host=endpoint["ip"], port=22)
            self.dev.open(gather_facts=False)

        except Exception as err:
            print "Could not open device %s!" % endpoint["ip"]
            self.result_msg = str(err)
            self.dev = None

        return

    def execute_template(self, template):
        """
        switches based on request_type chosen from template configuration

        :param template:
        :return: String results from the endpoint netconf subsystem
        """
        if self.dev is None:
            return self.result_msg

        if self.request_type == "apply_template":
            return self.apply_template(template)
        elif self.request_type == "execute_cheat_command":
            return self.execute_cheat_command(template)
        elif self.request_type == "assert_set_configuration":
            return self.assert_set_configuration(template)
        elif self.request_type == "assert_xpath_configuration":
            return self.assert_xpath_configuration(template)
        else:
            return self.execute_op_command(template)

    def execute_op_command(self, template):
        # Django is so very helpful in escaping EVERYTHING, undo the madness before passing to pyez
        s = self.unescape(template)
        try:
            results = self.dev.execute(s)
        except RpcError as e:
            print e
            return "Error executing command: %s" % str(e)

        print etree.tostring(results, pretty_print=True)
        return etree.tostring(results, pretty_print=True)

    def execute_cheat_command(self, template):
        print "Executing cheat command"
        results = self.dev.cli(template)
        return self.format_results(results)

    def assert_set_configuration(self, pattern):

        print "Checking set command regex"
        config = self.dev.cli('show configuration | display set')
        print config
        config_pattern = re.compile(pattern)

        results = ""
        for line in config.split('\n'):
            if config_pattern.match(line):
                results += line + "\n"

        if results != "":
            return results

    def assert_xpath_configuration(self, xpath):

        print "Searching xpath"
        configuration_xml = self.dev.execute("<get-configuration></get-configuration>")
        print configuration_xml
        if configuration_xml.find(xpath):
            return "Configuration element: %s is present" % xpath

        return "not found"

    def apply_template(self, template):
        print self.dev
        conf_string = template.strip()

        print conf_string

        if re.search(r"^&lt;", conf_string):
            print "Found a encoded string"
            conf_string = self.unescape(conf_string)

        print conf_string
        # try to determine the format of our config_string
        config_format = "set"
        if re.search(r"^\s*<.*>$", conf_string, re.MULTILINE):
            print "found xml style config"
            config_format = "xml"
        elif re.search(r"^\s*(set|delete|replace|rename)\s", conf_string):
            print "found set style config"
            config_format = "set"
        elif re.search(r"^[a-z:]*\s*\w+\s+{", conf_string, re.I) and re.search(r".*}\s*$", conf_string):
            print "found a text style config"
            config_format = "text"

        print "using format: " + config_format
        cu = Config(self.dev)
        try:
            cu.lock()
        except LockError as le:
            print "Could not lock database!"
            print str(le)
            self.dev.close()
            return "Failed to lock configuration database! %s" % str(le)

        try:
            print "loading config"
            cu.load(conf_string, format=config_format)
        except Exception as e:
            print "Could not load configuration"
            print str(e)
            try:
                cu.unlock()
            except UnlockError as ue:
                print str(ue)

            self.dev.close()
            return "Failed, could not load the configuration template. %s" % str(e)

        diff = cu.diff()
        print diff
        if diff is not None:
            try:
                cu.commit_check()
                print "Committing config!"
                cu.commit(comment="Commit via a_frame")

            except CommitError as ce:
                print "Could not load config! %s" % str(ce)
                cu.rollback()
                try:
                    print "Unlocking database!"
                    cu.unlock()
                except UnlockError as ue:
                    print "Could not unlock database"
                    print str(ue)
                print repr(ce)
                self.dev.close()
                return "Failed, commit check failed. %s" % str(ce)

        else:
            # nothing to commit
            print "Nothing to commit - no diff found"
            cu.unlock()
            self.dev.close()
            return "Nothing to commit!"

        try:
            print "Unlocking database!"
            cu.unlock()
        except UnlockError as ue:
            print "Could not unlock database"
            print str(ue)
            self.dev.close()
            return "Committed, but could not unlock db"

        print "Closing device handle"
        self.dev.close()
        return "Completed with diff: %s" % diff

    @staticmethod
    def unescape(s):
        s = s.replace("&lt;", "<")
        s = s.replace("&gt;", ">")
        s = s.replace("&amp;", "&")
        return s

    @staticmethod
    def format_results(results):
        """
        detects string format (xml || json) and formats appropriately

        :param results: string from urlopen
        :return: formatted string output
        """
        print results
        try:
            if type(results) is str:
                results = etree.fromstring(results)

            print "found valid xml, formatting and returning"
            # use pretty_print if we have an xml document returned
            return etree.tostring(results, pretty_print=True)
        except XMLSyntaxError:
            pass
        except ValueError:
            pass
        except TypeError:
            pass

        # is the result valid json?
        try:
            json_string = json.loads(results)
            print "Found JSON results"
            return json.dumps(json_string, indent=4)
        except ValueError:
            pass
        except TypeError:
            pass

        print "no special formatting, returning"
        return results
Example #6
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch('__builtin__.open', mock):
            with patch('__builtin__.file', MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh()
            self.assertTrue(mock_warnings.warn.called)

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'rick')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory').tag, 'cli')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime | display xml rpc')
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime ').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime ',
                format='text'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    def test_device_execute_unknown_exception(self):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.func_doc,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        foo = open(fpath).read()

        if fname == 'get-rpc-error.xml':
            # Raise ncclient exception for error
            raise RPCError(etree.XML(foo))
        elif fname == 'get-permission-denied.xml':
            # Raise ncclient exception for error
            raise RPCError(etree.XML(foo))
        elif (fname == 'get-index-error.xml' or
                fname == 'get-system-core-dumps.xml' or
                fname == 'load-configuration-error.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())
        elif (fname == 'show-configuration.xml' or
              fname == 'show-system-alarms.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc
        else:
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime | display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                else:
                    raise RpcError

            else:
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Example #7
0
class NetconfAction(ActionBase):
    """
        Uses NetConf to execute the given template

        Can execute template as an op command
        or apply the template as a configuration template
    """

    dev = None
    request_type = "apply_template"
    result_msg = ""

    def set_endpoint(self, endpoint):
        try:
            # create the required iterator from the endpoint_list
            self.dev = Device(user=endpoint["username"], password=endpoint["password"], host=endpoint["ip"])
            self.dev.open(gather_facts=False)

        except Exception as err:
            print "Could not open device!"
            self.result_msg = str(err)
            self.dev = None

        return

    def execute_template(self, template):
        """
        switches based on request_type chosen from template configuration

        :param template:
        :return: String results from the endpoint netconf subsystem
        """
        if self.dev is None:
            return self.result_msg

        if self.request_type == "apply_template":
            return self.apply_template(template)
        elif self.request_type == "execute_cheat_command":
            return self.execute_cheat_command(template)
        elif self.request_type == "assert_set_configuration":
            return self.assert_set_configuration(template)
        elif self.request_type == "assert_xpath_configuration":
            return self.assert_xpath_configuration(template)
        else:
            return self.execute_op_command(template)

    def execute_op_command(self, template):
        try:
            results = self.dev.execute(template)
        except RpcError as e:
            print e
            return "Error executing command: %s" % str(e)

        print etree.tostring(results, pretty_print=True)
        return etree.tostring(results, pretty_print=True)

    def execute_cheat_command(self, template):
        print "Executing cheat command"
        results = self.dev.cli(template)
        return results

    def assert_set_configuration(self, pattern):

        print "Checking set command regex"
        config = self.dev.cli('show configuration | display set')
        print config
        config_pattern = re.compile(pattern)

        results = ""
        for line in config.split('\n'):
            if config_pattern.match(line):
                results += line + "\n"

        if results != "":
            return results

    def assert_xpath_configuration(self, xpath):

        print "Searching xpath"
        configuration_xml = self.dev.execute("<get-configuration></get-configuration>")
        print configuration_xml
        if configuration_xml.find(xpath):
            return "Configuration element: %s is present" % xpath

        return "not found"

    def apply_template(self, template):
        print self.dev
        conf_string = template.strip()
        # try to determine the format of our config_string
        config_format = "set"
        if re.search(r"^\s*<.*>$", conf_string, re.MULTILINE):
            config_format = "xml"
        elif re.search(r"^\s*(set|delete|replace|rename)\s", conf_string):
            config_format = "set"
        elif re.search(r"^[a-z:]*\s*\w+\s+{", conf_string, re.I) and re.search(r".*}\s*$", conf_string):
            config_format = "text"

        print "using format: " + config_format
        cu = Config(self.dev)
        try:
            cu.lock()
        except LockError as le:
            print "Could not lock database!"
            print str(le)
            self.dev.close()
            return "Failed to lock configuration database! %s" % str(le)

        try:
            print "loading config"
            cu.load(conf_string, format=config_format)
        except Exception as e:
            print "Could not load configuration"
            print str(e)
            try:
                cu.unlock()
            except UnlockError as ue:
                print str(ue)

            self.dev.close()
            return "Failed, could not load the configuration template. %s" % str(e)

        diff = cu.diff()
        print diff
        if diff is not None:
            try:
                cu.commit_check()
                print "Committing config!"
                cu.commit(comment="Commit via a_frame")

            except CommitError as ce:
                print "Could not load config! %s" % str(ce)
                cu.rollback()
                try:
                    print "Unlocking database!"
                    cu.unlock()
                except UnlockError as ue:
                    print "Could not unlock database"
                    print str(ue)
                print repr(ce)
                self.dev.close()
                return "Failed, commit check failed. %s" % str(ce)

        else:
            # nothing to commit
            print "Nothing to commit - no diff found"
            return "Nothing to commit!"

        try:
            print "Unlocking database!"
            cu.unlock()
        except UnlockError as ue:
            print "Could not unlock database"
            print str(ue)
            self.dev.close()
            return "Committed, but could not unlock db"

        print "Closing device handle"
        self.dev.close()
        return "Completed with diff: %s" % diff
Example #8
0
class TestDevice(unittest.TestCase):
    @patch("ncclient.manager.connect")
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False)
        self.dev.open()

    @patch("ncclient.operations.session.CloseSession.request")
    def tearDown(self, mock_session):
        self.dev.close()

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    @patch("jnpr.junos.device.datetime")
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError("Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime

        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    @patch("jnpr.junos.device.datetime")
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = "why are you trying :)"
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime

        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket

        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)

        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch("__builtin__.open", mock):
            with patch("__builtin__.file", MagicMock):
                handle = open("filename", "r")
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user="******", password="******", gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_repr(self):
        localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False)
        self.assertEqual(repr(localdev), "Device(1.1.1.1)")

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, "localhost")

    @patch("jnpr.junos.device.os")
    @patch("__builtin__.open")
    @patch("paramiko.config.SSHConfig.lookup")
    def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch("jnpr.junos.device.os")
    @patch("__builtin__.open")
    @patch("paramiko.config.SSHConfig.lookup")
    def test_device__sshconf_lkup_def(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = "/home/rsherman/.ssh/config"
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch("os.getenv")
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = "/home/test"
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch("os.getenv")
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with("HOME")

    @patch("ncclient.manager.connect")
    @patch("jnpr.junos.Device.execute")
    def test_device_open(self, mock_connect, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(host="2.2.2.2", user="******", password="******")
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch("jnpr.junos.Device.execute")
    def test_device_facts(self, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            assert self.dev.facts["version"] == facts["version"]

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.device.warnings")
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError("File cant be handled")
            self.dev.facts_refresh()
            self.assertTrue(mock_warnings.warn.called)

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, "1.1.1.1")

    def test_device_user(self):
        self.assertEqual(self.dev.user, "rick")

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = "******"
        self.assertEqual(self.dev._auth_password, "secret")

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [], "By default manages will be empty list")

    @patch("ncclient.manager.connect")
    @patch("jnpr.junos.Device.execute")
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host="2.2.2.2", user="******", password="******")
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = "test"
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    @patch("jnpr.junos.Device.execute")
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli("show cli directory").tag, "cli")

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue("ge-0/0/0" in self.dev.cli("show configuration"))

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue("Alarm" in self.dev.cli("show system alarms"))

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli("show system uptime | display xml rpc").tag, "get-system-uptime-information")

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli("show version")
        self.assertEqual(val, "invalid command: show version")

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.display_xml_rpc("show system uptime ").tag, "get-system-uptime-information")

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn("<get-system-uptime-information>", self.dev.display_xml_rpc("show system uptime ", format="text"))

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.display_xml_rpc("show foo"), "invalid command: show foo| display xml rpc")

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute("<get-system-core-dumps/>").tag, "directory-list")

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute("<get-system-core-dumps/>", to_py=self._do_nothing), "Nothing")

    # This test is for the commented out rpc-error code
    #     def test_device_execute_exception(self):
    #         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
    #         self.assertRaises(RpcError, self.dev.execute,
    #                           '<load-configuration-error/>')

    def test_device_execute_unknown_exception(self):
        class MyException(Exception):
            pass

        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute, "<get-software-information/>")

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(EzErrors.PermissionError, self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(EzErrors.RpcTimeoutError, self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.func_doc, "get-software-information")

    def test_device_probe_timeout_zero(self):
        with patch("jnpr.junos.device.socket"):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch("jnpr.junos.device.socket"):
            self.assertTrue(self.dev.probe(1), "probe fn is not working for" " timeout greater than zero")

    def test_device_probe_timeout_exception(self):
        with patch("jnpr.junos.device.socket") as mock_socket:
            with patch("jnpr.junos.device.time.sleep") as mock_time:
                mock_socket.socket.return_value.close.side_effect = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(0.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = "magic_mock"
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, "magic_mock")

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = "Test"
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, "Test")

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = "magic mock"
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)

        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = "magic mock"
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)

        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template("tests/unit/templates/config-example.xml")
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template("templates/config-example.xml")
            except:
                raise
        self.assertEqual(
            template.render({"host_name": "1", "domain_name": "2"}), "system {\n  host-name 1;\n  domain-name 2;\n}"
        )

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False

        self.dev.close = MagicMock(name="close")
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch("ncclient.manager.connect")
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host="3.3.3.3", user="******", password="******", gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name="_conn")
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False

                dev.close = MagicMock(name="close")
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__), "rpc-reply", fname)
        foo = open(fpath).read()

        if fname == "get-rpc-error.xml":
            # Raise ncclient exception for error
            raise RPCError(etree.XML(foo))
        elif fname == "get-permission-denied.xml":
            # Raise ncclient exception for error
            raise RPCError(etree.XML(foo))
        elif (
            fname == "get-index-error.xml"
            or fname == "get-system-core-dumps.xml"
            or fname == "load-configuration-error.xml"
        ):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler.transform_reply())
        elif fname == "show-configuration.xml" or fname == "show-system-alarms.xml":
            rpc_reply = NCElement(foo, self.dev._conn._device_handler.transform_reply())._NCElement__doc
        else:
            rpc_reply = NCElement(foo, self.dev._conn._device_handler.transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs:
            device_params = kwargs["device_params"]
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == "command":
                if args[0].text == "show cli directory":
                    return self._read_file("show-cli-directory.xml")
                elif args[0].text == "show configuration":
                    return self._read_file("show-configuration.xml")
                elif args[0].text == "show system alarms":
                    return self._read_file("show-system-alarms.xml")
                elif args[0].text == "show system uptime | display xml rpc":
                    return self._read_file("show-system-uptime-rpc.xml")
                else:
                    raise RpcError

            else:
                return self._read_file(args[0].tag + ".xml")

    def _do_nothing(self, *args, **kwargs):
        return "Nothing"
Example #9
0
class TestDevice(unittest.TestCase):
    @patch("ncclient.manager.connect")
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        self.dev.open()

    @patch("ncclient.operations.session.CloseSession.request")
    def tearDown(self, mock_session):
        self.dev.close()

    def test_new_console_return(self):
        dev = Device(
            host="1.1.1.1",
            user="******",
            password="******",
            port=23,
            gather_facts=False,
        )
        self.assertTrue(isinstance(dev, Console))

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    @patch("jnpr.junos.device.datetime")
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime

        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [
            currenttime,
            currenttime + timedelta(minutes=4),
        ]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    @patch("jnpr.junos.device.datetime")
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = "why are you trying :)"
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime

        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [
            currenttime,
            currenttime + timedelta(minutes=4),
        ]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket

        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch("jnpr.junos.device.netconf_ssh")
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)

        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + ".open", mock):
            if sys.version > "3":
                builtin_file = "io.TextIOWrapper"
            else:
                builtin_file = builtin_string + ".file"
            with patch(builtin_file, MagicMock):
                handle = open("filename", "r")
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError,
                          Device,
                          user="******",
                          password="******",
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    @patch("jnpr.junos.Device.execute")
    def test_device_uptime(self, mock_execute):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(localdev.uptime, 14234)

    def test_device_master_is_master(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = [
            "re1",
            "master",
            "node",
            "fwdd",
            "member",
            "pfem",
        ]
        self.assertEqual(localdev.master, True)

    def test_device_master_gnf_is_master(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["gnf1-re0", "gnf1-master"]
        localdev.facts._cache["hostname_info"] = {
            "bsys-re0": "foo",
            "bsys-re1": "foo1",
            "gnf1-re0": "bar",
            "gnf1-re1": "bar1",
        }
        self.assertEqual(localdev.master, True)

    def test_device_master_is_backup(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["re0", "backup"]
        self.assertEqual(localdev.master, False)

    def test_device_master_gnf_is_backup(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["gnf1-re1", "gnf1-backup"]
        localdev.facts._cache["hostname_info"] = {
            "bsys-re0": "foo",
            "bsys-re1": "foo1",
            "gnf1-re0": "bar",
            "gnf1-re1": "bar1",
        }
        self.assertEqual(localdev.master, False)

    def test_device_master_is_re0_only(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["2RE"] = False
        localdev.facts._cache["RE_hw_mi"] = False
        localdev.facts._cache["current_re"] = ["re0"]
        self.assertEqual(localdev.master, True)

    def test_device_master_is_multi_chassis_non_master1(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["2RE"] = True
        localdev.facts._cache["current_re"] = [
            "lcc1-re1",
            "member1-re1",
            "lcc1-backup",
            "member1-backup",
        ]
        self.assertEqual(localdev.master, False)

    def test_device_master_is_multi_chassis_non_master2(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["2RE"] = True
        localdev.facts._cache["current_re"] = [
            "lcc1-re0",
            "member1-re0",
            "lcc1-master",
            "member1-master",
            "member1",
        ]
        self.assertEqual(localdev.master, False)

    def test_device_master_is_none1(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = None
        self.assertEqual(localdev.master, None)

    def test_device_master_is_none2(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["2RE"] = True
        localdev.facts._cache["current_re"] = ["foo", "bar"]
        self.assertEqual(localdev.master, None)

    @patch("jnpr.junos.device.warnings")
    def test_device_master_is_old_facts(self, mock_warn):
        localdev = Device(
            host="1.1.1.1",
            user="******",
            password="******",
            fact_style="old",
            gather_facts=False,
        )
        mock_warn.assert_has_calls([
            call.warn(
                "fact-style old will be removed "
                "in a future release.",
                RuntimeWarning,
            )
        ])
        self.assertEqual(localdev.master, None)

    def test_device_master_setter(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.master = "foo"

    def test_device_re_name_is_re0(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["re0", "backup"]
        localdev.facts._cache["hostname_info"] = {
            "re0": "tapir",
            "re1": "tapir1"
        }
        self.assertEqual(localdev.re_name, "re0")

    def test_device_re_name_is_lcc_re1(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = [
            "lcc1-re1",
            "member1-re1",
            "lcc1-backup",
            "member1-backup",
        ]
        localdev.facts._cache["hostname_info"] = {"re0": "mj1"}
        self.assertEqual(localdev.re_name, "lcc1-re1")

    def test_device_re_name_is_re0_only(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["foo"]
        localdev.facts._cache["hostname_info"] = {"re0": "mj1"}
        self.assertEqual(localdev.re_name, "re0")

    def test_device_re_name_is_bsys_re0(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = ["re0"]
        localdev.facts._cache["hostname_info"] = {"bsys-re0": "foo"}
        self.assertEqual(localdev.re_name, "bsys-re0")

    def test_device_re_name_is_none1(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = None
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_is_none2(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        localdev.facts._cache["current_re"] = [
            "re1",
            "master",
            "node",
            "fwdd",
            "member",
            "pfem",
        ]
        localdev.facts._cache["hostname_info"] = None
        self.assertEqual(localdev.re_name, None)

    @patch("jnpr.junos.device.warnings")
    def test_device_re_name_is_old_facts(self, mock_warn):
        localdev = Device(
            host="1.1.1.1",
            user="******",
            password="******",
            fact_style="old",
            gather_facts=False,
        )
        mock_warn.assert_has_calls([
            call.warn(
                "fact-style old will be removed "
                "in a future release.",
                RuntimeWarning,
            )
        ])
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_setter(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.re_name = "foo"

    def test_device_repr(self):
        localdev = Device(host="1.1.1.1",
                          user="******",
                          password="******",
                          gather_facts=False)
        self.assertEqual(repr(localdev), "Device(1.1.1.1)")

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, "localhost")

    @patch("jnpr.junos.device.os")
    @patch(builtin_string + ".open")
    @patch("paramiko.config.SSHConfig.lookup")
    def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with("1.1.1.1")

    @patch("jnpr.junos.device.os")
    @patch(builtin_string + ".open")
    @patch("paramiko.config.SSHConfig.lookup")
    def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = "/home/rsherman/.ssh/config"
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with("1.1.1.1")

    @patch("paramiko.config.SSHConfig.lookup")
    def test_device__sshconf_lkup_sock_fd(self, mock_paramiko):
        self.dev2 = Device(sock_fd=6)
        self.dev2._sshconf_lkup()
        self.assertEqual(self.dev2._sshconf_lkup(), None)

    @patch("os.path.expanduser")
    def test_device__sshconf_lkup_path_not_exists(self, mock_path):
        mock_path.return_value = "/home/test"
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch("ncclient.manager.connect")
    @patch("jnpr.junos.Device.execute")
    def test_device_open(self, mock_connect, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(host="2.2.2.2",
                               user="******",
                               password="******")
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch("ncclient.manager.connect")
    @patch("jnpr.junos.Device.execute")
    def test_device_outbound(self, mock_connect, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(sock_fd=6, user="******", password="******")
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch("jnpr.junos.Device.execute")
    def test_device_facts(self, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            self.dev.facts._cache["current_re"] = ["re0"]
            assert self.dev.facts["version"] == facts["version"]

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.factcache.warnings")
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError("File cant be handled")
            self.dev.facts_refresh(warnings_on_failure=True)
            self.assertTrue(mock_warnings.warn.called)

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.device.warnings")
    def test_device_facts_error_exception_on_error(self, mock_warnings,
                                                   mock_execute):
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError("File cant be handled")
            self.assertRaises(IOError,
                              self.dev.facts_refresh,
                              exception_on_failure=True)

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.device.warnings")
    def test_device_old_style_facts_error_exception_on_error(
            self, mock_warnings, mock_execute):
        self.dev._fact_style = "old"
        with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError("File cant be handled")
            self.assertRaises(IOError,
                              self.dev.facts_refresh,
                              exception_on_failure=True)

    def test_device_facts_refresh_unknown_fact_style(self):
        self.dev._fact_style = "bad"
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh()

    def test_device_facts_refresh_old_fact_style_with_keys(self):
        self.dev._fact_style = "old"
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh(keys="domain")

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, "1.1.1.1")

    def test_device_user(self):
        self.assertEqual(self.dev.user, "test")

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = "******"
        self.assertEqual(self.dev._auth_password, "secret")

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_string(self):
        self.dev.timeout = "10"
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_invalid_string_value(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = "foo"

    def test_device_set_timeout_invalid_type(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = [1, 2, 3, 4]

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         "By default manages will be empty list")

    @patch("ncclient.manager.connect")
    @patch("jnpr.junos.Device.execute")
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host="2.2.2.2", user="******", password="******")
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_conn_None_transform(self):
        self.dev = Device(host="2.2.2.2", user="******", password="******")
        with self.assertRaises(EzErrors.ConnectError):
            self.dev.transform

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = "test"
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    def test_device_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            ofacts = self.dev.ofacts

    def test_device_set_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            self.dev.ofacts = False

    @patch("jnpr.junos.Device.execute")
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.cli("show cli directory", warning=False).tag, "cli")

    @patch("jnpr.junos.device.json.loads")
    def test_device_rpc_json_ex(self, mock_json_loads):
        self.dev.facts = facts
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        ex = ValueError("Extra data ")
        ex.message = "Extra data "  # for py3 as we dont have message thr
        mock_json_loads.side_effect = [
            ex,
            self._mock_manager(
                etree.fromstring('<get-route-information format="json"/>')),
        ]
        self.dev.rpc.get_route_information({"format": "json"})
        self.assertEqual(mock_json_loads.call_count, 2)

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_to_rpc_string(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string("show system uptime")
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            "show system uptime | match foo | count")
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_to_rpc_string_complex(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            "show interfaces ge-0/0/0.0 routing-instance all media")
        self.assertEqual(
            "rpc.get_interface_information("
            "routing_instance='all', media=True, "
            "interface_name='ge-0/0/0.0')",
            data,
        )

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_to_rpc_string_invalid(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string("foo")
        self.assertEqual(None, data)

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_format_json(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli("show interface terse",
                            warning=False,
                            format="json")
        self.assertEqual(type(data), dict)
        self.assertEqual(
            data["interface-information"][0]["physical-interface"][0]
            ["oper-status"][0]["data"],
            "up",
        )

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue(
            "ge-0/0/0" in self.dev.cli("show configuration", warning=False))

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue(
            "Alarm" in self.dev.cli("show system alarms", warning=False))

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.device.warnings")
    def test_device_cli_output_warning(self, mock_warnings, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli(
            "show interfaces ge-0/0/0.0 routing-instance "
            "all media",
            format="xml")
        ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/'
                           'address-family[address-family-name="inet"]/'
                           "interface-address/ifa-local")
        self.assertTrue("192.168.100.1" in ip)
        self.assertTrue(mock_warnings.warn.called)
        rpc_string = ("rpc.get_interface_information(routing_instance='all', "
                      "media=True, interface_name='ge-0/0/0.0')")
        self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0])

    def test_device_cli_blank_output(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            "", self.dev.cli("show configuration interfaces", warning=False))

    def test_device_cli_rpc_reply_with_message(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            "\nprotocol: operation-failed\nerror: device asdf not found\n",
            self.dev.cli("show interfaces terse asdf", warning=False),
        )

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.cli("show system uptime| display xml rpc",
                         warning=False).tag,
            "get-system-uptime-information",
        )

    def test_device_cli_connection_exception(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.cli, "foo")

    @patch("jnpr.junos.Device.execute")
    def test_device_cli_rpc_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertRaises(EzErrors.RpcError, self.dev.cli, "foo")

    def test_device_cli_timeout_exception(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(EzErrors.RpcTimeoutError, self.dev.cli, "foo")

    @patch("jnpr.junos.device.warnings")
    def test_device_cli_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass

        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.cli, "foo")

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc("show system uptime").tag,
            "get-system-uptime-information",
        )

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            "<get-system-uptime-information>",
            self.dev.display_xml_rpc("show system uptime", format="text"),
        )

    @patch("jnpr.junos.Device.execute")
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc("show foo"),
            "invalid command: show foo| display xml rpc",
        )

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            self.dev.execute("<get-system-core-dumps/>").tag, "directory-list")

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            self.dev.execute("<get-system-core-dumps/>",
                             to_py=self._do_nothing),
            "Nothing",
        )

    # This test is for the commented out rpc-error code
    #     def test_device_execute_exception(self):
    #         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
    #         self.assertRaises(RpcError, self.dev.execute,
    #                           '<load-configuration-error/>')

    @patch("jnpr.junos.device.warnings")
    def test_device_execute_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass

        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          "<get-software-information/>")

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    @unittest.skipIf(sys.platform == "win32",
                     "will work for windows in coming days")
    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(EzErrors.PermissionError,
                          self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(EzErrors.RpcTimeoutError,
                          self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(EzErrors.ConnectClosedError,
                          self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         "get-software-information")

    def test_device_probe_timeout_zero(self):
        with patch("jnpr.junos.device.socket"):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch("jnpr.junos.device.socket"):
            self.assertTrue(
                self.dev.probe(1),
                "probe fn is not working for"
                " timeout greater than zero",
            )

    def test_device_probe_timeout_exception(self):
        with patch("jnpr.junos.device.socket") as mock_socket:
            with patch("jnpr.junos.device.time.sleep") as mock_time:
                mock_socket.socket.return_value.close.side_effect = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(0.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = "magic_mock"
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, "magic_mock")

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = "Test"
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, "Test")

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = "magic mock"
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)

        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = "magic mock"
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)

        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                "tests/unit/templates/config-example.xml")
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template("templates/config-example.xml")
            except:
                raise
        self.assertEqual(
            template.render({
                "host_name": "1",
                "domain_name": "2"
            }),
            "system {\n  host-name 1;\n  domain-name 2;\n}",
        )

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False

        self.dev.close = MagicMock(name="close")
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch("ncclient.manager.connect")
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host="3.3.3.3",
                        user="******",
                        password="******",
                        gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name="_conn")
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False

                dev.close = MagicMock(name="close")
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__), "rpc-reply", fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == "get-rpc-error.xml":
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == "get-permission-denied.xml":
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == "get-index-error.xml"
                  or fname == "get-system-core-dumps.xml"
                  or fname == "load-configuration-error.xml"
                  or fname == "show-configuration-interfaces.xml"
                  or fname == "show-interfaces-terse-asdf.xml"):
                rpc_reply = NCElement(
                    foo, self.dev._conn._device_handler.transform_reply())
            elif fname == "show-configuration.xml" or fname == "show-system-alarms.xml":
                rpc_reply = NCElement(
                    foo, self.dev._conn._device_handler.transform_reply()
                )._NCElement__doc
            elif fname == "show-interface-terse.json":
                rpc_reply = json.loads(foo)
            elif fname == "get-route-information.json":
                rpc_reply = NCElement(
                    foo, self.dev._conn._device_handler.transform_reply())
            else:
                rpc_reply = NCElement(
                    foo, self.dev._conn._device_handler.transform_reply()
                )._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs and "normalize" not in kwargs:
            device_params = kwargs["device_params"]
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)
        elif args:
            if args[0].tag == "command":
                if args[0].text == "show cli directory":
                    return self._read_file("show-cli-directory.xml")
                if args[0].text == "show interface terse":
                    return self._read_file("show-interface-terse.json")
                elif args[0].text == "show configuration":
                    return self._read_file("show-configuration.xml")
                elif args[0].text == "show system alarms":
                    return self._read_file("show-system-alarms.xml")
                elif args[0].text == "show system uptime| display xml rpc":
                    return self._read_file("show-system-uptime-rpc.xml")
                elif args[0].text == "show configuration interfaces":
                    return self._read_file("show-configuration-interfaces.xml")
                elif args[0].text == "show interfaces terse asdf":
                    return self._read_file("show-interfaces-terse-asdf.xml")
                elif (args[0].text == "show interfaces ge-0/0/0.0 "
                      "routing-instance all media"):
                    return self._read_file(
                        "show-interfaces-routing-instance-media.xml")
                elif (args[0].text == "show interfaces ge-0/0/0.0 "
                      "routing-instance all media| display "
                      "xml rpc"):
                    return self._read_file(
                        "show-interfaces-routing-instance-media-rpc.xml")
                else:
                    raise RpcError

            else:
                if args[0].attrib.get("format") == "json":
                    return self._read_file(args[0].tag + ".json")
                return self._read_file(args[0].tag + ".xml")

    def _do_nothing(self, *args, **kwargs):
        return "Nothing"
Example #10
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + '.open', mock):
            if sys.version >'3':
                builtin_file = 'io.TextIOWrapper'
            else:
                builtin_file = builtin_string + '.file'
            with patch(builtin_file, MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh()
            self.assertTrue(mock_warnings.warn.called)

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'rick')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory').tag, 'cli')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime | display xml rpc')
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime ').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime ',
                format='text').decode('utf-8'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        print (self.dev.execute('<get-system-core-dumps/>').tag)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    def test_device_execute_unknown_exception(self):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == 'get-rpc-error.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == 'get-permission-denied.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == 'get-index-error.xml' or
                    fname == 'get-system-core-dumps.xml' or
                    fname == 'load-configuration-error.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())
            elif (fname == 'show-configuration.xml' or
                  fname == 'show-system-alarms.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc
            else:
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime | display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                else:
                    raise RpcError

            else:
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'