#Open file specified by user, format it so that it can be used by the next if statement device = [] for line in open(input_file,'r'): seperator = ',' line = line.split(seperator) for value in line: device.append(value) device = [x.strip('\n') for x in device] #Login to each device. If it is up, perform the lsp check, then move on to the next one. #If a device is not up, exit and continue until list is completed. for item in device: dev=Device(user=user,host=item,password=passwd) dev.probe() print 'Opening connection to %s for user %s ...' % (item,user) if dev.probe() is True: dev.open() print '\nAll times are in UTC!\n\n' print datetime.datetime.utcnow() print 'Connection successful, starting script...' dev.timeout = 10*60 #set variable that will be used to check detour_good = "<detours>800</detours>" detour_check = 0 count_checks = 0 count_good = 3
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'
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'
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'
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'
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"
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"
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'
def create_dev_conn(cls, sample_device=None, connect=True): """ Creates a device connection object according to driver settings. If an OSSH session is used hand over sock_fd. :param sample_device. Create a connection object for sample_device. :return Device. Return Device object with with the according connection """ if c.conf.DEVICEDRIVER.Driver == c.YAPT_DEVICE_DRIVER_PYEZ: # If we get an ossh connection hand over sock_fd if c.SERVICEPLUGIN_OSSH == sample_device.deviceServicePlugin: if c.conf.YAPT.DevicePwdIsRsa: dev_conn = Device(host=None, sock_fd=sample_device.deviceConnection, user=c.conf.YAPT.DeviceUsr, password=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE_RSA), gather_facts=False) if dev_conn is not None: if connect: try: dev_conn.open() sample_device.deviceConnection = dev_conn return True, sample_device except jnpr.junos.exception.ConnectError as err: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err))) return False, err else: sample_device.deviceConnection = dev_conn return True, sample_device else: dev_conn = Device(host=None, sock_fd=sample_device.deviceConnection, user=c.conf.YAPT.DeviceUsr, password=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE), gather_facts=False) if dev_conn is not None: if connect: try: dev_conn.open() sample_device.deviceConnection = dev_conn return True, sample_device except jnpr.junos.exception.ConnectError as err: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err))) return False, err else: sample_device.deviceConnection = dev_conn return True, sample_device else: if c.conf.YAPT.DevicePwdIsRsa: dev_conn = Device(host=sample_device.deviceIP, user=c.conf.YAPT.DeviceUsr, ssh_private_key_file=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE_RSA)) if connect: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_PROBING_DEV.format(sample_device.deviceIP, c.conf.YAPT.ConnectionProbeTimeout))) probe = dev_conn.probe(timeout=c.conf.YAPT.ConnectionProbeTimeout) if probe: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_PROBING_OK.format( sample_device.deviceIP, c.conf.YAPT.ConnectionProbeTimeout))) try: dev_conn.open() sample_device.deviceConnection = dev_conn return True, sample_device except jnpr.junos.exception.ConnectError as err: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err))) return False, err else: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_PROBING_FAILED.format( sample_device.deviceIP))) return False, Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_PROBING_FAILED.format( sample_device.deviceIP)) else: sample_device.deviceConnection = dev_conn return True, sample_device else: dev_conn = Device(host=sample_device.deviceIP, user=c.conf.YAPT.DeviceUsr, password=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE), gather_facts=False) if connect: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceSerial, logmsg.CONN_MGMT_PROBING_DEV.format(sample_device.deviceIP, c.conf.YAPT.ConnectionProbeTimeout))) probe = dev_conn.probe(timeout=c.conf.YAPT.ConnectionProbeTimeout) if probe: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceSerial, logmsg.CONN_MGMT_PROBING_OK.format( sample_device.deviceIP, c.conf.YAPT.ConnectionProbeTimeout))) try: dev_conn.open() sample_device.deviceConnection = dev_conn return True, sample_device except jnpr.junos.exception.ConnectError as err: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err))) return False, err else: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceSerial, logmsg.CONN_MGMT_PROBING_FAILED.format( sample_device.deviceIP))) return False, Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceSerial, logmsg.CONN_MGMT_PROBING_FAILED.format( sample_device.deviceIP)) else: sample_device.deviceConnection = dev_conn return True, sample_device elif c.conf.DEVICEDRIVER.Driver == c.YAPT_DEVICE_DRIVER_NAPALM: # Use the appropriate network driver to connect to the device driver = napalm.base.get_network_driver(c.conf.DEVICEDRIVER.Napalm.Module) # Connect dev_conn = driver(hostname=sample_device.deviceIP, username=c.conf.YAPT.DeviceUsr, password=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE), optional_args={'port': c.conf.DEVICEDRIVER.Napalm.Port}) try: sample_device.deviceConnection = dev_conn dev_conn.open() return True, sample_device except (napalm.base.exceptions.ConnectionException, napalm.base.exceptions.ConnectAuthError, jnpr.junos.exception.ConnectError) as err: c.logger.info(Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err))) return False, Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_OPEN_FAILED.format(err)) else: c.logger.info( Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_DEV_DRIVER_NOK)) return False, Tools.create_log_msg(logmsg.CONN_MGMT, sample_device.deviceIP, logmsg.CONN_MGMT_DEV_DRIVER_NOK)
class RunUpgrade(object): def __init__(self): self.arch = '' self.host = '' self.auth = ltoken() self.config = {} self.configfile = '/opt/ipeng/scripts/jtishey/junos_upgrade/config.yml' self.force = False self.yes_all = False self.no_install = False self.set_enhanced_ip = False self.pim_nonstop = False self.two_stage = False def get_arguments(self): """ Handle input from CLI """ p = argparse.ArgumentParser( description='Parse and compare before/after baseline files.', formatter_class=lambda prog: argparse.HelpFormatter( prog, max_help_position=32)) p.add_argument('-d', '--device', help='Specify an IP or hostname to upgrade', required=True, metavar='DEV') p.add_argument('-c', '--config', help='Specify an alternate config file', metavar='CFG') p.add_argument('-f', '--force', action='count', default=0, help='Use "force" option on all package adds (DANGER!)') p.add_argument( '-n', '--noinstall', action='count', default=0, help='Do a dry-run, check for files and copying them only') p.add_argument( '-y', '--yes_all', action='count', default=0, help='Answer "y" to all questions during the upgrade (DANGER!)') args = vars(p.parse_args()) self.host = args['device'] if args['config']: self.configfile = args['config'] if args['force']: self.force - True if args['noinstall']: self.no_install = True if args['yes_all']: self.yes_all = True def initial_setup(self): """ Setup logging, load config and check for the images on the server """ logfile = self.host + '_upgrade.log' logging.basicConfig(filename=logfile, level=logging.WARN, format='%(asctime)s:%(name)s: %(message)s') logging.getLogger().name = self.host logging.getLogger().addHandler(logging.StreamHandler()) logging.warn('Information logged in {0}'.format(logfile)) # Open config file try: with open(self.configfile) as f: self.config = yaml.load(f) except: logging.warn('ERROR: Issues opening config file "{0}"'.format( self.configfile)) exit(1) # verify needed packages exist on local server for pkg in [ 'CODE_IMAGE32', 'CODE_IMAGE64', 'CODE_2STAGE32', 'CODE_2STAGE64', 'CODE_JSU32', 'CODE_JSU64' ]: if self.config[pkg]: if not (os.path.isfile(self.config['CODE_FOLDER'] + self.config[pkg])): msg = 'Software package does not exist locally: {0}'.format( self.config['CODE_FOLDER'] + self.config[pkg]) logging.error(msg) if not self.yes_all: cont = self.input_parse('Continue? (n/n): ') if cont == 'n': exit() def open_connection(self): """ Open a NETCONF connection to the device """ if self.no_install: logging.warn('Running with no_install option - copy files only...') try: logging.warn('Connecting to ' + self.host + '...') self.dev = Device(host=self.host, user=self.auth['username'], password=self.auth['password'], gather_facts=True) self.dev.open() except ConnectError as e: logging.error('Cannot connect to device: {0}'.format(e)) exit(1) def collect_re_info(self): """ Print info on each RE: """ if self.dev.facts['RE0']: logging.warn('' + self.host + ' ' + self.dev.facts['model']) logging.warn('-' * 24) if self.dev.facts['version_RE0']: logging.warn(' RE0 \t RE1') logging.warn('Mastership: {0} \t {1}'.format( self.dev.facts['RE0']['mastership_state'], self.dev.facts['RE1']['mastership_state'])) logging.warn('Status: {0} \t\t {1}'.format( self.dev.facts['RE0']['status'], self.dev.facts['RE1']['status'])) logging.warn('Model: {0} \t {1}'.format( self.dev.facts['RE0']['model'], self.dev.facts['RE1']['model'])) logging.warn('Version: {0} \t {1}'.format( self.dev.facts['version_RE0'], self.dev.facts['version_RE1'])) else: logging.warn(' RE0 ') logging.warn('Mastership: {0}'.format( self.dev.facts['RE0']['mastership_state'] + '')) logging.warn( 'Status: {0}'.format(self.dev.facts['RE0']['status'] + '')) logging.warn( 'Model: {0}'.format(self.dev.facts['RE0']['model'] + '')) logging.warn( 'Version: {0}'.format(self.dev.facts['version'] + '')) logging.warn("") # Check for redundant REs logging.warn('Checking for redundant routing-engines...') if not self.dev.facts['2RE']: if not self.yes_all: re_stop = input( "Redundant RE's not found, Continue? (y/n): ") if re_stop.lower() != 'y': self.end_script() else: logging.warn("Redundant RE's not found...") def copy_image(self, source, dest): """ Copy files via SCP """ logging.warn("Image not found on active RE, copying now...") try: with SCP(self.dev, progress=True) as scp: logging.warn("Copying image to " + dest + "...") scp.put(source, remote_path=dest) except Exception as e: logging.warn(str(e)) self.end_script() def copy_to_other_re(self, source, dest): """Use netmiko to copy files from one RE to the other because PyEZ doesnt allow this""" logging.warn("Image not found on backup RE, copying now...") d = { 'device_type': 'juniper', 'ip': self.host, 'username': self.auth['username'], 'password': self.auth['password'], 'timeout': 3600 } try: net_connect = ConnectHandler(**d) net_connect.send_command("file copy " + source + " " + dest) net_connect.disconnect() except Exception as e: logging.warn(str(e)) logging.warn( "Error copying file to other RE, Please login and do this manually" ) logging.warn("CMD: file copy " + source + " " + dest) def recursive_search(self, obj, key): """ recursively search dict for a key value https://stackoverflow.com/questions/14962485/finding-a-key-recursively-in-a-dictionary """ if key in obj: return obj[key] for v in obj.values(): if isinstance(v, dict): item = self.recursive_search(v, key) if item is not None: return item def image_check(self): """ Check to make sure needed files are on the device and copy if needed, Currently only able to copy to the active RE """ # List of 64-bit capable RE's: RE_64 = [ 'RE-S-1800x2-8G', 'RE-S-1800x2-16G', 'RE-S-1800x4-8G', 'RE-S-1800x4-16G' ] if self.dev.facts['RE0']['model'] in RE_64: self.arch = '64-bit' else: # Determine 32-bit or 64-bit: logging.warn('Checking for 32 or 64-bit code...') ver = xmltodict.parse( etree.tostring( self.dev.rpc.get_software_information(detail=True))) version_info = json.dumps(ver) if '64-bit' in version_info: self.arch = '64-bit' logging.warn("Using 64-bit Image...") else: self.arch = '32-bit' logging.warn("Using 32-bit Image...") # Are we doing a two-stage upgrade? (Reqd for >3 major version change) if self.config['CODE_2STAGE32'] or self.config['CODE_2STAGE64']: if (int(self.config['CODE_NAME'][:2]) - int(self.dev.facts['version'][:2])) > 3: logging.warn('Two-Stage Upgrade will be performed...') self.two_stage = True # Define all the file names / paths if self.arch == '32-bit': source = self.config['CODE_FOLDER'] + self.config['CODE_IMAGE32'] source_2stg = self.config['CODE_FOLDER'] + self.config[ 'CODE_2STAGE32'] source_jsu = self.config['CODE_FOLDER'] + self.config['CODE_JSU32'] if self.two_stage: dest = self.config['CODE_PRESERVE'] + self.config[ 'CODE_2STAGE32'] dest_2stg = self.config['CODE_DEST'] + self.config[ 'CODE_IMAGE32'] dest_jsu = self.config['CODE_PRESERVE'] + self.config[ 'CODE_JSU32'] else: dest = self.config['CODE_DEST'] + self.config['CODE_IMAGE32'] dest_jsu = self.config['CODE_DEST'] + self.config['CODE_JSU32'] elif self.arch == '64-bit': source = self.config['CODE_FOLDER'] + self.config['CODE_IMAGE64'] source_2stg = self.config['CODE_FOLDER'] + self.config[ 'CODE_2STAGE64'] source_jsu = self.config['CODE_FOLDER'] + self.config['CODE_JSU64'] if self.two_stage: dest = self.config['CODE_PRESERVE'] + self.config[ 'CODE_2STAGE64'] dest_2stg = self.config['CODE_DEST'] + self.config[ 'CODE_IMAGE64'] dest_jsu = self.config['CODE_PRESERVE'] + self.config[ 'CODE_JSU64'] else: dest = self.config['CODE_DEST'] + self.config['CODE_IMAGE64'] dest_jsu = self.config['CODE_DEST'] + self.config['CODE_JSU64'] # Check for final software image on the device logging.warn('Checking for image on the active RE...') img = xmltodict.parse(etree.tostring( self.dev.rpc.file_list(path=dest))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_image(source, dest) # If dual RE - Check backup RE too if self.dev.facts['2RE']: if self.dev.facts['master'] == 'RE0': active_RE = 're0:' backup_RE = 're1:' else: active_RE = 're1:' backup_RE = 're0:' logging.warn('Checking for image on the backup RE...') img = xmltodict.parse( etree.tostring(self.dev.rpc.file_list(path=backup_RE + dest))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_to_other_re(active_RE + dest, backup_RE + dest) img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE + dest))) img_output = json.dumps(img) if 'No such file' in img_output: msg = 'file copy ' + dest + ' ' + backup_RE + dest logging.warn( 'ERROR: Copy the image to the backup RE, then re-run script' ) logging.warn('CMD : ' + msg) self.end_script() # If 2 stage upgrade, look for intermediate image if self.two_stage: logging.warn('Checking for 2-stage image on the active RE...') img = xmltodict.parse( etree.tostring(self.dev.rpc.file_list(path=dest_2stg))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_image(source_2stg, dest_2stg) # Check for intermediate image file on backup RE if self.dev.facts['2RE']: logging.warn('Checking for 2-stage image on the backup RE...') img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE + dest_2stg))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_to_other_re(active_RE + dest_2stg, backup_RE + dest_2stg) # Check again img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE + dest_2stg))) img_output = json.dumps(img) if 'No such file' in img_output: msg = 'file copy ' + active_RE + dest_2stg + ' ' + backup_RE + dest_2stg logging.warn( 'ERROR: Copy the image to the backup RE, then re-run script' ) logging.warn('CMD : ' + msg) self.end_script() # Check if JSU Install is requested (present in config.yml) if self.config['CODE_JSU32'] or self.config['CODE_JSU64']: # Check for the JSU on the active RE logging.warn('Checking for JSU on the active RE...') img = xmltodict.parse( etree.tostring(self.dev.rpc.file_list(path=dest_jsu))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_image(source_jsu, dest_jsu) # Check for the JSU on the backup RE if self.dev.facts['2RE']: logging.warn('Checking for JSU on the backup RE...') img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE + dest_jsu))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_to_other_re(active_RE + dest_jsu, backup_RE + dest_jsu) img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE + dest_jsu))) img_output = json.dumps(img) if 'No such file' in img_output: msg = 'file copy ' + active_RE + dest_jsu + ' ' + backup_RE + dest_jsu logging.warn( 'ERROR: Copy the image to the backup RE, then re-run script' ) logging.warn('CMD : ' + msg) self.end_script() def system_snapshot(self): """ Performs [request system snapshot] on the device """ logging.warn('Requesting system snapshot on RE0...') self.dev.timeout = 360 try: snap = xmltodict.parse( etree.tostring(self.dev.rpc.request_snapshot(re0=True))) err = self.recursive_search(snap, 'error') if err: logging.warn("Error taking snapshot... {0}".format( err['message'])) if self.dev.facts['2RE']: logging.warn('Requesting system snapshot on RE1...') snap = xmltodict.parse( etree.tostring(self.dev.rpc.request_snapshot(re1=True))) err = self.recursive_search(snap, 'error') if err: logging.warn("Error taking snapshot... {0}".format( err['message'])) except Exception as e: logging.warn('ERROR: Problem with snapshots') logging.warn(str(e)) if not self.yes_all: cont = self.input_parse("Contine with upgrade? (y/n): ") if cont == 'n': self.end_script() def remove_traffic(self): """ Execute the PRE_UPGRADE_CMDS from the self.config['py file to remove traffic """ config_cmds = self.config['PRE_UPGRADE_CMDS'] # Network Service check on MX Platform if self.dev.facts['model'][:2] == 'MX': logging.warn("Checking for network-services enhanced-ip...") dpc_flag = False net_mode = xmltodict.parse( etree.tostring(self.dev.rpc.network_services())) cur_mode = net_mode['network-services'][ 'network-services-information']['name'] if cur_mode != 'Enhanced-IP': # Check for DPCs logging.warn("Checking for any installed DPCs...") hw = xmltodict.parse( etree.tostring( self.dev.rpc.get_chassis_inventory(models=True))) for item in hw['chassis-inventory']['chassis'][ 'chassis-module']: if item['description'][:3] == 'DPC': dpc_flag = True if dpc_flag: logging.warn( "Chassis has DPCs installed, skipping network-services change" ) else: logging.warn('Network Services mode is ' + cur_mode + '') if not self.yes_all: cont = self.input_parse( 'Change Network Services Mode to Enhanced-IP? (y/n): ' ) if cont == 'y': # Set a flag to recheck at the end and reboot if needed: self.set_enhanced_ip = True else: self.set_enhanced_ip = True # PIM nonstop-routing (if configured) must be removed to deactivate GRES pim = self.dev.rpc.get_config( filter_xml='<protocols><pim><nonstop-routing/></pim></protocols>') if len(pim) > 0: config_cmds.append('deactivate protocols pim nonstop-routing') # set a flag so we konw to turn it back on at the end self.pim_nonstop = True # Make configuration changes if config_cmds: logging.warn('Entering Configuration Mode...') logging.warn('-' * 24) success = True try: with Config(self.dev, mode='exclusive') as cu: for cmd in config_cmds: cu.load(cmd, merge=True, ignore_warning=True) logging.warn("Configuration Changes:") logging.warn('-' * 24) cu.pdiff() if cu.diff(): if not self.yes_all: cont = self.input_parse('Commit Changes? (y/n): ') if cont == 'y': try: cu.commit() except Exception as e: logging.warn(str(e)) logging.warn( "Error occurred during commit") success = False else: logging.warn('Rolling back changes...') cu.rollback(rb_id=0) success = False else: logging.warn('Committing changes...') try: cu.commit() except Exception as e: logging.warn(str(e)) logging.warn("Error occurred during commit") success = False else: logging.warn('No changes found to commit...') except RuntimeError as e: if "Ex: format='set'" in str(e): logging.warn('ERROR: Unable to parse the PRE_UPGRADE_CMDS') logging.warn( ' Make sure they are formatted correctly.') else: logging.warn('ERROR: {0}'.format(e)) success = False if not success: self.end_script() else: logging.warn("No pre-upgrade commands in CONFIG file") def upgrade_backup_re(self): """ Cycle through installing packcages for Dual RE systems """ if self.dev.facts['master'] == 'RE0': backup_RE = 'RE1' else: backup_RE = 'RE0' # First Stage Upgrade if self.two_stage: # Only upgrade if the current version is not the 2stage, or final version: if self.dev.facts['version_' + backup_RE] != self.config['CODE_2STAGE_NAME'] and \ self.dev.facts['version_' + backup_RE] != self.config['CODE_NAME']: # Perform the upgrade self.backup_re_pkg_add(self.config['CODE_2STAGE32'], self.config['CODE_2STAGE64'], self.config['CODE_PRESERVE']) # Second Stage Upgrade # Only upgrade if the current version is not already the final version: if self.dev.facts['version_' + backup_RE] != self.config['CODE_NAME']: self.backup_re_pkg_add(self.config['CODE_IMAGE32'], self.config['CODE_IMAGE64'], self.config['CODE_DEST']) # JSU Upgrade # Only upgrade if the JSU is not already applied: if self.config['CODE_JSU32'] or self.config['CODE_JSU64']: if backup_RE == 'RE0': current_version = etree.tostring( self.dev.rpc.get_software_information(re0=True)) else: current_version = etree.tostring( self.dev.rpc.get_software_information(re1=True)) if self.config['CODE_JSU_NAME'] not in str(current_version): if self.two_stage: self.backup_re_pkg_add(self.config['CODE_JSU32'], self.config['CODE_JSU64'], self.config['CODE_PRESERVE']) else: self.backup_re_pkg_add(self.config['CODE_JSU32'], self.config['CODE_JSU64'], self.config['CODE_DEST']) else: logging.warn('JSU appears to already be applied on {0}'.format( backup_RE)) def backup_re_pkg_add(self, PKG32, PKG64, R_PATH): """ Perform software add and reboot the back RE """ self.dev.timeout = 3600 # Figure which RE is the current backup RE0, RE1 = False, False if self.dev.facts['master'] == 'RE0' and \ 'backup' in self.dev.facts['RE1'].values(): active_RE = 'RE0' backup_RE = 'RE1' RE1 = True elif self.dev.facts['master'] == 'RE1' and \ 'backup' in self.dev.facts['RE0'].values(): active_RE = 'RE1' backup_RE = 'RE0' RE0 = True else: logging.warn("Trouble finding the backup RE...") self.end_script() # Assign package path and name if self.arch == '32-bit': PACKAGE = R_PATH + PKG32 else: PACKAGE = R_PATH + PKG64 # Add package and reboot the backup RE # Had issues w/utils.sw install, so im using the rpc call instead startTime = datetime.now() logging.warn('Installing ' + PACKAGE + ' on ' + backup_RE + '...') # Change flags for JSU vs JINSTALL Package: if 'jselective' in PACKAGE: # JSU installs are failing with RPC call logging.warn( "Unable to instsall the JSU remotely, please do it manually..." ) logging.warn("CMD: request routing-engine login backup") logging.warn( "CMD: request system software add {0}".format(PACKAGE)) self.input_parse( "Once the JSU is installed, enter [Y] to continue...") else: rsp = self.dev.rpc.request_package_add(reboot=True, no_validate=True, package_name=PACKAGE, re0=RE0, re1=RE1, force=self.force) # Check to see if the package add succeeded: logging.warn('-----------------START PKG ADD OUTPUT-----------------') ok = True for o in rsp.getparent().findall('output'): logging.warn(o.text) for result in rsp.getparent().findall('package-result'): if result.text != '0': logging.warn('Pkgadd result ' + result.text) ok = False logging.warn('------------------END PKG ADD OUTPUT------------------') if not ok: self.dev.timeout = 60 logging.warn('Encountered issues with software add... Exiting') if not self.yes_all: cont = self.input_parse( 'Rollback configuration changes? (y/n): ') if cont == 'y': self.restore_traffic() else: self.restore_traffic() logging.warn( "Script complete, please check the package add errors manually" ) self.end_script() logging.warn('Rebooting, please wait...') # Wait 2 minutes for package to install / reboot, then start checking every 30s time.sleep(120) re_state = 'Present' while re_state == 'Present': time.sleep(30) re_state = xmltodict.parse(etree.tostring( self.dev.rpc.get_route_engine_information()))['route-engine-information']\ ['route-engine'][int(backup_RE[-1])]['mastership-state'] # Give it 20 seconds, then check status again time.sleep(20) re_status = xmltodict.parse(etree.tostring( self.dev.rpc.get_route_engine_information()))['route-engine-information']\ ['route-engine'][int(backup_RE[-1])]['status'] if re_status != 'OK': logging.warn('Backup RE state = ' + re_state) logging.warn('Backup RE status = ' + re_status) logging.warn( "Package " + PACKAGE + " took {0}".format(str(datetime.now() - startTime).split('.')[0])) # Grab core dump and SW version info self.dev.facts_refresh() core_dump = xmltodict.parse( etree.tostring(self.dev.rpc.get_system_core_dumps(re0=RE0, re1=RE1))) sw_version = xmltodict.parse( etree.tostring( self.dev.rpc.get_software_information(re0=RE0, re1=RE1))) # Check for core dumps: logging.warn("Checking for core dumps...") if 'directory' in core_dump['multi-routing-engine-results'][ 'multi-routing-engine-item']['directory-list'].keys(): logging.warn('Found Core Dumps! Please investigate.') cont = self.input_parse("Continue with upgrade? (y/n): ") if cont == 'n': cont = self.input_parse("Revert config changes? (y/n): ") if cont == 'y': self.restore_traffic() self.end_script() # Check SW Version: logging.warn(backup_RE + ' software version = ' + \ sw_version['multi-routing-engine-results']['multi-routing-engine-item']['software-information']['junos-version']) # Copy the final image back to the RE if needed after installing if self.arch == '64-bit': final_image = self.config['CODE_DEST'] + self.config['CODE_IMAGE64'] else: final_image = self.config['CODE_DEST'] + self.config['CODE_IMAGE32'] img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE.lower() + ':' + final_image))) img_output = json.dumps(img) if 'No such file' in img_output: self.copy_to_other_re(active_RE.lower() + ':' + final_image, backup_RE.lower() + ':' + final_image) img = xmltodict.parse( etree.tostring( self.dev.rpc.file_list(path=backup_RE.lower() + ':' + final_image))) img_output = json.dumps(img) if 'No such file' in img_output: msg = 'file copy ' + active_RE.lower( ) + ':' + final_image + ' ' + backup_RE + ':' + final_image logging.warn('ERROR: Copy the image to the backup RE manually') logging.warn('CMD : ' + msg) def upgrade_single_re(self): """ Cycle through installing packcages for single RE systems """ logging.warn( "------------------------WARNING-----------------------------") logging.warn( "Ready to upgrade, THIS WILL BE SERVICE IMPACTING!!! ") logging.warn( "-----------------------------------------------------------") if not self.yes_all: cont = self.input_parse( "Continue with software add / reboot? (y/n): ") if cont != 'y': self.restore_traffic() self.end_script() # First Stage Upgrade if self.two_stage: self.single_re_pkg_add(self.config['CODE_2STAGE32'], self.config['CODE_2STAGE64'], self.config['CODE_PRESERVE']) # Second Stage Upgrade self.single_re_pkg_add(self.config['CODE_IMAGE32'], self.config['CODE_IMAGE64'], self.config['CODE_DEST']) # JSU Upgrade if self.config['CODE_JSU32'] or self.config['CODE_JSU64']: if self.two_stage: self.single_re_pkg_add(self.config['CODE_JSU32'], self.config['CODE_JSU64'], self.config['CODE_PRESERVE']) else: self.single_re_pkg_add(self.config['CODE_JSU32'], self.config['CODE_JSU64'], self.config['CODE_DEST']) def single_re_pkg_add(self, PKG32, PKG64, R_PATH): """ Perform software add and reboot the RE / Device """ self.dev.timeout = 3600 if self.arch == '32-bit': PACKAGE = self.config['CODE_DEST'] + PKG32 else: PACKAGE = self.config['CODE_DEST'] + PKG64 # Had issues w/utils.sw install, so im using the rpc call instead startTime = datetime.now() logging.warn('Upgrading device... Please Wait...') # Change flags for JSU vs JINSTALL Package: if 'jselective' in PACKAGE: # JSU installs are failing with RPC call logging.warn( "Unable to instsall the JSU remotely, please do it manually..." ) logging.warn( "CMD: request system software add {0}".format(PACKAGE)) self.input_parse( "Once the JSU is installed, enter [Y] to continue...") else: rsp = self.dev.rpc.request_package_add(reboot=True, no_validate=True, package_name=PACKAGE, force=self.force) # Check to see if the package add succeeded: logging.warn('-----------------START PKG ADD OUTPUT-----------------') ok = True got = rsp.getparent() for o in got.findall('output'): logging.warn(o.text) package_result = got.findall('package-result') for result in package_result: if result.text != '0': logging.warn('Pkgadd result ' + result.text) ok = False self.dev.timeout = 120 logging.warn('------------------END PKG ADD OUTPUT------------------') if not ok: logging.warn('Encountered issues with software add... Exiting') if not self.yes_all: cont = self.input_parse( "Restore configuration before exiting? (y/n): ") if cont == 'y': self.restore_traffic() self.end_script() else: logging.warn('Restoring configuration before exiting...') self.restore_traffic() self.end_script() logging.warn('Rebooting, please wait...') # Wait 2 minutes for package to install and reboot, then start checking every 30s time.sleep(120) while self.dev.probe() is False: time.sleep(30) logging.warn( "Package " + PACKAGE + " took {0}".format(str(datetime.now() - startTime).split('.')[0])) # Once dev is reachable, re-open connection (refresh facts first to kill conn) self.dev.facts_refresh() self.dev.open() self.dev.facts_refresh() # Check for core dumps: logging.warn("Checking for core dumps...") core_dump = xmltodict.parse( etree.tostring(self.dev.rpc.get_system_core_dumps())) for item in core_dump['multi-routing-engine-results'][ 'multi-routing-engine-item']['directory-list']['output']: if 'No such file' not in item: logging.warn('Found Core Dumps! Please investigate.') logging.warn(item) if not self.yes_all: cont = self.input_parse("Continue with upgrade? (y/n): ") if cont.lower() != 'y': self.end_script() # Check SW Version: logging.warn('SW Version: ' + self.dev.facts['version'] + '') def switchover_RE(self): """ Issue RE switchover """ if self.dev.facts['2RE']: # Add a check for GRES / NSR x = self.dev.rpc.get_nonstop_routing_information() for item in x.getparent().iter(): if item.findtext('nonstop-routing-enabled'): nsr = item.findtext('nonstop-routing-enabled') if nsr != 'Enabled': logging.warn( "----------------------WARNING----------------------------" ) logging.warn( 'Nonstop-Routing is {0}, switchover will be impacting!'. format(nsr)) logging.warn( "---------------------------------------------------------" ) if not self.yes_all: cont = self.input_parse('Continue with switchover? (y/n): ') if cont != 'y': self.end_script() # Using dev.cli because I couldn't find an RPC call for switchover self.dev.timeout = 20 logging.warn("Performing routing-engine switchover...") try: r = self.dev.cli( 'request chassis routing-engine master switch no-confirm') except: time.sleep(10) if 'not ready' in str(r).lower(): logging.warn(str(r)) logging.warn("Waiting 2 minutes to stabilize...") time.sleep(120) try: r = self.dev.cli( 'request chassis routing-engine master switch no-confirm' ) except: time.sleep(5) if 'Not ready' in str(r): logging.warn(str(r)) cont = self.input_parse( 'Please switchover manually and enter "y" to continue: ' ) if cont == 'n': self.end_script try: self.dev.close() except: pass time.sleep(15) while self.dev.probe() is False: time.sleep(10) # Once dev is reachable, re-open connection (refresh facts first to kill conn) self.dev.open() def mx_network_services(self): """ Check if network-services mode enhanced-ip was requested, and set, reboot if not The reboot of both RE's was deemed nessicary by several issues where RE's were rebooted one at a time and did not sync network-services mode properly """ if self.dev.facts['model'][:2] == 'MX': if self.set_enhanced_ip: logging.warn("Setting chassis network-servies enhanced-ip...") try: with Config(self.dev, mode='exclusive') as cu: cu.load('set chassis network-services enhanced-ip', merge=True, ignore_warning=True) cu.commit(sync=True, full=True) except Exception as e: logging.warn(str(e)) logging.warn( 'Error commtitting "set chassis network-services enhanced-ip"' ) logging.warn( 'Device will not be rebooted, please check error configuring enhanced-ip' ) logging.warn( "-----------------------WARNING------------------------------" ) logging.warn("SERVICE IMPACTING REBOOT WARNING") logging.warn( "-----------------------------------------------------------" ) cont = 'y' if not self.yes_all: cont = self.input_parse( 'Reboot both REs now to set network-services mode enhanced-ip? (y/n): ' ) if cont != 'y': logging.warn( "Skipping reboot of both RE's for network-services mode..." ) else: logging.warn('Rebooting ' + self.host + '... Please wait...') self.dev.timeout = 600 try: self.dev.rpc.request_reboot( routing_engine='both-routing-engines') # Wait 2 minutes for reboot, then start checking every 30s time.sleep(120) while self.dev.probe() is False: time.sleep(30) self.dev.facts_refresh() self.dev.open() self.dev.facts_refresh() except: self.dev.open() def input_parse(self, msg): """ Prompt for input """ q = '' while q.lower() != 'y' and q.lower() != 'n': q = input(msg) return q.lower() def restore_traffic(self): """ Verify version, restore config, and wait for replication on dualRE """ # Check SW Version: self.dev.facts_refresh() if self.dev.facts['2RE']: if self.dev.facts['version_RE0'] == self.dev.facts['version_RE1']: logging.warn('Version matches on both routing engines.') else: logging.warn( 'ERROR: Versions do not match on both routing engines') logging.warn( 'Exiting script, please check device status manually.') self.end_script() logging.warn('Restoring configruation...') config_cmds = self.config['POST_UPGRADE_CMDS'] # If pim nonstop-routing was deactivated, re-activate it if self.pim_nonstop: config_cmds.append('activate protocols pim nonstop-routing') if config_cmds: success = True with Config(self.dev, mode='exclusive') as cu: for cmd in config_cmds: cu.load(cmd, merge=True, ignore_warning=True) logging.warn("Configuration Changes:") logging.warn('-' * 24) cu.pdiff() if cu.diff(): if not self.yes_all: cont = self.input_parse('Commit Changes? (y/n): ') if cont != 'y': logging.warn('Rolling back changes...') cu.rollback(rb_id=0) success = False else: try: if self.dev.facts['2RE']: cu.commit(sync=True, full=True) else: cu.commit(full=True) except Exception as e: logging.warn("Error occurred during commit") print(str(e)) success = False else: logging.warn('Committing Changes...') try: if self.dev.facts['2RE']: cu.commit(sync=True, full=True) else: cu.commit(full=True) except Exception as e: logging.warn(str(e)) logging.warn("Error committing changes") if not success: self.end_script() else: logging.warn("No post-upgrade commands in CONFIG file") def switch_to_master(self): """ Switch back to the default master - RE0 """ if self.dev.facts['2RE']: # Add a check for task replication logging.warn('Checking task replication...') task_sync = False waiting_on = '' while task_sync is False: rep = xmltodict.parse( etree.tostring( self.dev.rpc.get_routing_task_replication_state())) task_sync = True for i, item in enumerate(rep['task-replication-state'] ['task-protocol-replication-state']): if item != 'Complete': task_sync = False proto = rep['task-replication-state'][ 'task-protocol-replication-name'][i] if waiting_on != proto: waiting_on = proto logging.warn(proto + ': ' + item + '...') if task_sync is False: time.sleep(60) # Check which RE is active and switchover if needed if self.dev.facts['RE0']['mastership_state'] != 'master': self.switchover_RE() def end_script(self): """ Close the connection to the device and exit the script """ try: logging.warn("Disconnecting from {0}...".format(self.host)) self.dev.close() except: logging.warn("Did not disconnect cleanly.") exit()