def test_extract_dev_data_invalid_config_data(self, mock_connect): with self.assertRaises(SystemExit): dev = Device(user='******', host='abc', passwd='xyz') dev.open() js = SnapAdmin() config_data = 1 # config_data no meaning js.snapcheck(config_data, 'mock_pre', dev)
def _connect(self): # Default connect_mode to ssh connect_mode = self._kwargs.get('connect_mode', 'ssh').lower() # Check for valid connect modes if connect_mode not in ('telnet', 'ssh', 'console', 'netconf'): raise TobyException( 'Invalid connect mode({0}) specified. Connect mode can be ' 'telnet/ssh/console/netconf'.format(connect_mode)) handle = None try: user, password = self._get_credentials() device_args = { 'host': self._kwargs['host'], 'user': user, 'passwd': password, 'gather_facts': False } if connect_mode == 'ssh': device_args['port'] = 22 if connect_mode == 'telnet' or connect_mode == 'console': device_args['mode'] = 'telnet' if self._kwargs['pyez_port'] is not None: device_args['port'] = int(self._kwargs['pyez_port']) handle = Pyez_Device(**device_args) handle.open() except Exception as exp: logging.error('Could not connect to device ' + self._kwargs['host'] + ':' + str(exp)) return handle
def test_extract_dev_data_device_closed(self, mock_dev, mock_path): mock_path.return_value = os.path.join(os.path.dirname(__file__), 'configs') with self.assertRaises(Exception): dev = Device(user='******', host='abc', passwd='xyz') dev.open() dev.close() js = SnapAdmin() js.args.file = 'main_local.yml' js.snapcheck(js.args.file, 'mock_pre', dev)
def retrieve_config(hostname): print "Starting: " + hostname session = Device(host=hostname, user=username, passwd=password) session.open() with open('./configs/%s' % hostname, 'w') as fp: fp.write(session.cli('show configuration | display set').strip()) print "Finished: " + hostname
def test_generate_reply_error_2(self, mock_dev, mock_err): par = Parser() test_file = os.path.join(os.path.dirname(__file__), 'configs', 'bogus_testfile_2.yml') test_file = open(test_file, 'r') test_file = yaml.load(test_file) dev = Device(user='******', host='abc', passwd='xyz') dev.open() par.generate_reply(test_file, dev, '1.1.1.1_snap_mock', self.hostname, self.db) mock_err.assert_called()
def test_generate_reply_error_2(self, mock_dev, mock_err): par = Parser() test_file = os.path.join(os.path.dirname(__file__), 'configs', 'bogus_testfile_2.yml') test_file = open(test_file, 'r') test_file = yaml.load(test_file, Loader=yaml.FullLoader) dev = Device(user='******', host='abc', passwd='xyz') dev.open() par.generate_reply(test_file, dev, '1.1.1.1_snap_mock', self.hostname, self.db) mock_err.assert_called()
def test_action_api_based_data_passed_in_string_with_device(self, mock_data, mock_dev_data, mock_connect): js = SnapAdmin() js.args.file = os.path.join(os.path.dirname(__file__), 'configs', 'main.yml') config_file = open(js.args.file, 'r') data = yaml.load(config_file, Loader=yaml.FullLoader) dev = Device(user='******', host='abc', passwd='xyz') dev.open() js.snapcheck(data, 'mock_file', dev) self.assertFalse(mock_data.called) self.assertTrue(mock_dev_data.called)
def test_extract_dev_data_dictionary_based_data(self, mock_gen_rpc, mock_dev, mock_path, mock_test): mock_path.return_value = os.path.join(os.path.dirname(__file__), 'configs') dev = Device(user='******', host='abc', passwd='xyz') dev.open() js = SnapAdmin() conf_file = os.path.join(os.path.dirname(__file__), 'configs', 'main_1.yml') config_file = open(conf_file, 'r') config_data = yaml.load(config_file) js.snapcheck(config_data, 'mock_pre', dev) mock_gen_rpc.assert_called_with(dev, 'mock_pre', 'abc', config_data) mock_test.assert_called()
def test_extract_dev_data_from_file_and_local(self, mock_gen_rpc, mock_dev, mock_path, mock_test): mock_path.return_value = os.path.join(os.path.dirname(__file__), 'configs') dev = Device(user='******', host='abc', passwd='xyz') dev.open() js = SnapAdmin() conf_file = os.path.join(os.path.dirname(__file__), 'configs', 'main_local.yml') config_file = open(conf_file, 'r') config_data = yaml.load(config_file, Loader=yaml.FullLoader) js.snapcheck(config_data, 'mock_pre', dev) self.assertFalse(mock_gen_rpc.called) mock_test.assert_called()
def facts(): # This is a temporary work around until __proxy__ can be called from the # grains. dev = Device(user=__opts__['proxy']['username'], host=__opts__['proxy']['host'], password=__opts__['proxy']['passwd']) dev.open() facts = dev.facts facts['version_info'] = 'override' dev.close() return facts
def test_generate_reply_rpc_error_4(self, mock_dev, mock_tostring, mock_err, mock_rpc, mock_write_warn): from jnpr.junos.exception import RpcError mock_rpc.side_effect = RpcError par = Parser() test_file = os.path.join(os.path.dirname(__file__), 'configs', 'bogus_testfile_4.yml') test_file = open(test_file, 'r') test_file = yaml.load(test_file, Loader=yaml.FullLoader) dev = Device(host='10.221.136.250', user='******', passwd='xyz') dev.open() par.generate_reply(test_file, dev, 'mock.xml', self.hostname, self.db) mock_err.assert_called() mock_write_warn.assert_called()
def test_generate_reply_rpc_error_4(self, mock_dev, mock_tostring, mock_err, mock_rpc, mock_write_warn): from jnpr.junos.exception import RpcError mock_rpc.side_effect = RpcError par = Parser() test_file = os.path.join(os.path.dirname(__file__), 'configs', 'bogus_testfile_4.yml') test_file = open(test_file, 'r') test_file = yaml.load(test_file) dev = Device(host='10.221.136.250', user='******', passwd='xyz') dev.open() par.generate_reply(test_file, dev, 'mock.xml', self.hostname, self.db) mock_err.assert_called() mock_write_warn.assert_called()
def __connect(self): try: dev = Device(host=self.host, user=self.user, port=self.port, password=self.password) dev.open() return dev except Exception as err: logger.error( 'Unable to connect to {} with error: {}.' 'Ensure SSH-key pairs, connectivity, passwords'.format( self.host, err))
def add_config(router, interface, mtu, **kwargs): r = requests.get('http://api_server:9000/api/v1/device/%s/' % router, verify=False) device_info = r.json() hostname = device_info['host'] userid = device_info['authentication']['password']['username'] password = device_info['authentication']['password']['password'] dev = Device(host=hostname, user=userid, password=password, normalize=True) dev.open() cu = Config(dev) data = "set interfaces %s mtu %s" % (interface, mtu) cu.load(data, format='set') cu.commit() dev.close()
def attemptToConnectToRebootedDevice(hostname, username, password): timeout_counter = 0 while True: try: timeout_counter += 10 dev = Device(host=hostname, user=username, passwd=password, timeout=10) dev.open() return dev except: if timeout_counter > 900: return False
def config_junos(self, data, device, format): print("connecting to " + device) try: dev = Device(host=device, user=userid, password=password, normalize=True) dev.open() cu = Config(dev) data = data print(data) cu.load(data, format=format) cu.commit() dev.close() result = "succesful" except Exception as e: print(e) result = "failed" print(result) return result
class Test_Decorators(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() def test_timeout(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 function = lambda x: x decorator = timeoutDecorator(function) decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] mock_timeout.assert_has_calls(calls) def test_timeout_except(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(*args, **kwargs): raise Exception() decorator = timeoutDecorator(function) # test to ensure the exception is raised with self.assertRaises(Exception): decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] # verify timeout was set/reset mock_timeout.assert_has_calls(calls) 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)
class Test_Decorators(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() def test_timeout(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(x): return x decorator = timeoutDecorator(function) decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] mock_timeout.assert_has_calls(calls) def test_timeout_except(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(*args, **kwargs): raise Exception() decorator = timeoutDecorator(function) # test to ensure the exception is raised with self.assertRaises(Exception): decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] # verify timeout was set/reset mock_timeout.assert_has_calls(calls) # Test default of true and passing true keyword def test_normalize_true_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of true and passing true keyword and a func exception def test_normalize_true_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of True and passing false keyword def test_normalize_true_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of True and passing false keyword and a func exception def test_normalize_true_false_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword def test_normalize_false_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] #print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword and a func exception def test_normalize_false_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] #print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing false keyword def test_normalize_false_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) self.assertFalse(mock_transform.called) 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)
class Test_RpcMetaExec(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() self.rpc = _RpcMetaExec(self.dev) def test_rpcmeta_constructor(self): self.assertTrue(isinstance(self.rpc._junos, Device)) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_with_configuration_tag(self, mock_execute_fn): root = etree.XML( '<configuration><root><a>test</a></root></configuration>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_option_action(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, action='set') self.assertEqual(mock_execute_fn.call_args[0][0].get('action'), 'set') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, format='text') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format_json(self, mock_execute_fn): json_commands = """ { "configuration" : { "system" : { "services" : { "telnet" : [null] } } } } """ self.rpc.load_config(json_commands, format='json') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'json') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_vargs(self, mock_execute_fn): self.rpc.system_users_information(dict(format='text')) self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs(self, mock_execute_fn): self.rpc.system_users_information(set_data=('test', )) self.assertEqual(mock_execute_fn.call_args[0][0][0].text, 'test') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_normalize(self, mock_execute_fn): self.rpc.any_ole_rpc(normalize=True) self.assertEqual(mock_execute_fn.call_args[1], {'normalize': True}) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_get_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.get_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'get-configuration') def test_rpcmeta_exec_rpc_format_json_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('14.2X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual( op['system-users-information'][0]['uptime-information'][0] ['date-time'][0]['data'], u'4:43AM') def test_rpcmeta_exec_rpc_format_json_gt_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('15.1X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual( op['system-users-information'][0]['uptime-information'][0] ['date-time'][0]['data'], u'4:43AM') @patch('jnpr.junos.device.warnings') def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('13.1X46-D15.3') self.rpc.get_system_users_information(dict(format='json')) mock_warn.assert_has_calls([ call.warn('Native JSON support is only from 14.2 onwards', RuntimeWarning) ]) def test_get_rpc(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(filter_select='bgp') self.assertEqual(resp.tag, 'data') def test_get_config_filter_xml_string_xml(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config( filter_xml='<system><services/></system>') self.assertEqual(resp.tag, 'configuration') def test_get_config_filter_xml_string(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config(filter_xml='system/services') self.assertEqual(resp.tag, 'configuration') def test_get_config_filter_xml_model(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config('bgp/neighbors', model='openconfig') self.assertEqual(resp.tag, 'bgp') def test_get_rpc_ignore_warning_bool(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=True) self.assertEqual(resp.tag, 'data') def test_get_rpc_ignore_warning_str(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning='vrrp subsystem not running') self.assertEqual(resp.tag, 'data') def test_get_rpc_ignore_warning_list(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=[ 'vrrp subsystem not running', 'statement not found' ]) self.assertEqual(resp.tag, 'data') # below test need to be fixed for Python 3.x """ def test_get_config_remove_ns(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config('bgp/neighbors', model='openconfig', remove_ns=False) self.assertEqual(resp.tag, '{http://openconfig.net/yang/bgp}bgp') """ # def test_model_true(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) data = self.dev.rpc.get_config(model=True) self.assertEqual(data.tag, 'data') def _mock_manager(self, *args, **kwargs): if kwargs: if 'normalize' in kwargs and args: return self._read_file(args[0].tag + '.xml') device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: if len(args[0]) > 0 and args[0][0].tag == 'bgp': return self._read_file(args[0].tag + '_bgp_openconfig.xml') return self._read_file(args[0].tag + '.xml') 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() return NCElement(foo, self.dev._conn._device_handler.transform_reply()) return rpc_reply
from jnpr.junos.device import Device from jnpr.junos.utils.config import Config from pprint import pprint junos_hosts = ['172.25.11.1', '1.1.1.1'] for ip in junos_hosts: dev = Device(host=ip, user='******', password='******') dev.open() config = Config(dev) config.lock() config.load(path='add_snmp.conf', merge=True) config.pdiff() config.commit() config.unlock() dev.close()
def script2(hostname): ######### Prologue stuff # Remove old log file if one exists for the given hostname if os.path.exists('./logs/' + hostname): os.remove('./logs/' + hostname) # Start a new log file log(hostname, "------------------------") # Variables we'll use in different places. Same quick method for assigning username and password in one line (username, password) = open('./config/credentials.txt').read().splitlines()[:2] root_password = open('./config/root_password.txt').readline() rc_file_location = '/etc/rc.mount.platform' rc_md5 = 'e4e17e0aa795f4dd790ed3f15f18859b' # Can't use context managers here since we're rebooting # Attempt to connect to the given hostname try: dev = Device(host=hostname, user=username, passwd=password) dev.open() except Exception as e: log(hostname, 'Failed to connect for Device()') return {'success': 0, 'message': 'Failed to connect to Device()'} # Attempt to create a shell connection to the given hostname try: shell = StartShell(dev) shell.open() except: log(hostname, 'Failed to connect for StartShell()') return {'success': 0, 'message': 'Failed to connect to StartShell()'} # RC file check - We do this using Junos's RPC for "file list" op command, this is exactly # like sending "file list /etc/rc.mount.platform" from the command-line file_show = dev.rpc.file_list(path=rc_file_location) file_show = file_show.xpath('//total-files') # If the length of file_show variable is 0, that means the file wasn't found if len(file_show) < 1: return { 'success': 0, 'message': 'RC file not found in /etc/rc.mount.platform, didn\'t show in ls listing' } file_show = str(file_show[0].text).strip() log(hostname, 'file_show: ' + file_show) # Excessive check most likely, but I wanted to be certain. Pretty much the same check as the previous check if file_show != "1": return { 'success': 0, 'message': 'RC file not found in /etc/rc.mount.platform' } ############################################ # MD5 file check - We do this using Junos's RPC for "file checksum md5" md5_rc_check = dev.rpc.get_checksum_information(path=rc_file_location) md5_rc_check = md5_rc_check.xpath('//checksum') # If the length of md5_rc_check is less than 0, that means no checksum XML node was found, which means something # went wrong, or that the file didn't exist. Realistically we probably don't need this here because execution would # not make it this far due to our previous checks, but I wanted to be explicit about the checks we're doing and # follow the MOP as exact as I could if len(md5_rc_check) < 1: return { 'success': 0, 'message': 'MD5 check on RC file unable to be executed' } md5_rc_check = str(md5_rc_check[0].text).strip() # Log / print information about the step we're on so the user is aware of where the script is currently at in its # execution log(hostname, 'md5 of rc file: ' + md5_rc_check + ' compared to: ' + rc_md5) # If the checksum doesn't match our hard-coded/expected checksum of the file, we report a failure back to master.py # in the form of a dict if md5_rc_check != rc_md5: return { 'success': 0, 'message': 'MD5 check FAILED. RC on device is corrupted, did not match ' + rc_md5 } ############################################ # Switch StartShell with su root - We need this to run some of the commands later on. StartShell() is an # "extension" for PyEZ that allows us simple access to shell shell.run('su root', this='Password:'******'whoami') if 'whoami\r\r\nroot\r\n' not in whoami[1]: log(hostname, 'INVALID ROOT PASSWORD GIVEN, COULD NOT SU TO ROOT. EXITING.') return { 'success': 0, 'message': 'Invalid root password given. Exiting.' } # c. Run fsck utility on the Unmounted partition to make sure its clean # Check which is backup partition (/dev/da0s1a or /dev/da0s2a) using "show system snapshot media internal" RPC show_system_snapshot = dev.rpc.get_snapshot_information(media='internal') snapshot_information = show_system_snapshot.xpath('//snapshot-information') if len(snapshot_information) < 1: return { 'success': 0, 'message': 'Unable to retrieve "show system snapshot media internal" output' } snapshot_information = snapshot_information[0] snapshot_medium = snapshot_information.xpath('//snapshot-medium') partitions = {} for medium in snapshot_medium: temp = str(medium.text).split('internal (')[1] if 'primary' in temp: temp = temp.split(') (primary)')[0] partitions['primary'] = temp else: temp = temp.split(') (backup)')[0] partitions['backup'] = temp log(hostname, 'partitions: ' + json.dumps(partitions)) fsck_output = shell.run('fsck -f -y ' + partitions['backup']) log(hostname, "fsck -f -y " + partitions['backup'] + "\n" + fsck_output[1]) # d. Perform snapshot slice alternate and save rescue configuration ########## Save rescue configuration - request system configuration rescue save log(hostname, "request configuration rescue save - Starting") request_rescue_configuration_save = dev.rpc.request_save_rescue_configuration( dev_timeout=500) log(hostname, "request configuration rescue save - Completed") #@TODO: Not sure if there's error-handling we need to do here. There is a //success xpath we can check for log(hostname, "request system snapshot slice alternate - Starting") request_system_snapshot_slice_alternate = dev.rpc.request_snapshot( slice="alternate", dev_timeout=500) log(hostname, "request system snapshot slice alternate - Completed") ########### REBOOT THE DEVICE request_system_reboot = dev.rpc.request_reboot() log( hostname, "REBOOTING - Initializing sleep to give device time to actually reboot" ) # Need to kill the dev and shell connections or it'll error out. # Need to sleep to give device time to reboot. Junos waits 60 seconds before initiating shutdown process, so # I pad 30 seconds on to give it time to actually shutdown. shell.close() dev.close() time.sleep(90) # While loop to reconnect to rebooted device, attemptToConnectToRebootedDevice() returns a Device() instantiation log(hostname, "Beginning post-reboot reconnect attempts") reconnDev = attemptToConnectToRebootedDevice(hostname, username, password) # this means we timed out... device needs manual intervention if reconnDev == False: log( hostname, "Post-reboot FAILED. Device failed to come back up - Manual intervention required" ) return { 'success': 0, 'message': "Post-reboot FAILED. Device failed to come back up - Manual intervention required" } log(hostname, "Post-reboot reconnection successful!") log( hostname, "Checking if we booted from backup partition - show system storage partitions" ) # Check if backup partition was booted partition_check = reconnDev.rpc.get_system_storage_partitions() partition_check = partition_check.xpath('//partitions/booted-from') if len(partition_check) > 1: return { 'success': 0, 'message': "Couldn't determine active/backup partition from 'show system storage partitions'" } partition_check = str(partition_check[0].text).strip() log(hostname, 'show system storage partitions: booted from ' + partition_check) ################################################################################ ################################################################################ ################################################################################ ################################################################################ # If we booted from backup, COMMENCE THE "OTHER" SCRIPT (MOP-Clean-Primary-partition.pdf). # I should probably extract this out into a separate function, but I don't want to deal with figuring out what # variables I need to pass-thru if partition_check == "backup": ########### Check which is backup partition (/dev/da0s1a or /dev/da0s2a) show_system_snapshot = reconnDev.rpc.get_snapshot_information( media='internal') snapshot_information = show_system_snapshot.xpath( '//snapshot-information') if len(snapshot_information) < 1: return { 'success': 0, 'message': 'Unable to retrieve "show system snapshot media internal" output' } snapshot_information = snapshot_information[0] snapshot_medium = snapshot_information.xpath('//snapshot-medium') partitions = {} for medium in snapshot_medium: temp = str(medium.text).split('internal (')[1] if 'primary' in temp: temp = temp.split(') (primary)')[0] partitions['primary'] = temp else: temp = temp.split(') (backup)')[0] partitions['backup'] = temp log(hostname, 'partitions: ' + json.dumps(partitions)) fsck_output = shell.run('fsck -f -y ' + partitions['backup']) log(hostname, "fsck -f -y " + partitions['backup'] + "\n" + fsck_output[1]) # 3. Take a snapshot to the alternate partition (this is a hidden command), then compare "show system snapshot media internal" to ensure # both partitions have the same versions log( hostname, 'request system snapshot media internal slice alternate - Starting' ) request_system_snapshot_media_internal_slice_alternate = reconnDev.rpc.request_snapshot( slice='alternate', media='internal', dev_timeout=500) log( hostname, 'request system snapshot media internal slice alternate - Completed' ) # 3a. Packages should be the same on both slices log(hostname, 'show system snapshot media internal - Started') show_system_snapshot_media_internal = reconnDev.rpc.get_snapshot_information( media='internal') show_system_snapshot_media_internal = show_system_snapshot_media_internal.xpath( '//software-version') log( hostname, 'show system snapshot media internal - Comparing packages between slices' ) software_versions = {} for software_index, software_version in enumerate( show_system_snapshot_media_internal): packages = software_version.xpath('./package') software_versions.setdefault(software_index, {}) for package_index, package in enumerate(packages): package_name = str( package.xpath('./package-name')[0].text).strip() package_version = str( package.xpath('./package-version')[0].text).strip() software_versions[software_index][ package_name] = package_version packages_match = True for package_name in software_versions[0].keys(): if software_versions[0][package_name] != software_versions[1][ package_name]: packages_match = False break if packages_match != True: log( hostname, "Packages from 'show system snapshot media internal' do not match" ) return { 'success': 0, 'message': "Packages from 'show system snapshot media internal' do not match" } log(hostname, 'show system snapshot media internal - Comparison completed') ####################### # 4. show system storage partitions - The MOP doesn't really explain what we're looking for with this command. Skipping for now. # 5. show system alarms - Check for alarm-description containing "Boot from backup root", if we find one, run "request system reboot slice alternate media internal" show_system_alarms = reconnDev.rpc.get_system_alarm_information() show_system_alarms = show_system_alarms.xpath('//alarm-description') for alarm_description in show_system_alarms: alarm_description = str(alarm_description.text).strip() # If we see the backup root alarm, we need to reboot AGAIN if "Boot from backup root" in alarm_description: log( hostname, 'REBOOTING - Backup root alarm FOUND - request system reboot slice alternate media internal' ) reconnDev.rpc.request_reboot(media='internal', slice='alternate') reconnDev.close() time.sleep(90) # While loop to reconnect to rebooted device, attemptToConnectToRebootedDevice() returns a Device instantation log(hostname, "Beginning second post-reboot reconnect attempts") secondReconnDev = attemptToConnectToRebootedDevice( hostname, username, password) # this means we timed out... device needs manual intervention if secondReconnDev == False: log( hostname, "SECOND Post-reboot FAILED. Device failed to come back up - Manual intervention required" ) return { 'success': 0, 'message': "SECOND Post-reboot FAILED. Device failed to come back up - Manual intervention required" } log(hostname, "Second post-reboot reconnection successful!") log( hostname, "Checking if we booted from backup partition - show system storage partitions" ) # Check if backup partition was booted partition_check = secondReconnDev.rpc.get_system_storage_partitions( ) partition_check = partition_check.xpath( '//partitions/booted-from') if len(partition_check) > 1: return { 'success': 0, 'message': "Couldn't determine active/backup partition from 'show system storage partitions'" } partition_check = str(partition_check[0].text).strip() if partition_check == "backup": log( hostname, "PROCEDURE FAILED, DEVICE STILL BOOTING FROM BACKUP PARTITION, DEVICE NEEDS TO BE RMA'D" ) return { 'success': 0, 'message': "PROCEDURE FAILED, DEVICE STILL BOOTING FROM BACKUP PARTITION, DEVICE NEEDS TO BE RMA'D" } # 3. Run the NAND media check after boot up with StartShell(reconnDev) as reconnShell: reconnShell.run('su root', this='Password:'******'nand-mediack -C') log(hostname, 'Running nand-mediack -C') if "nand-mediack -C\r\r\nMedia check on da0 on ex platforms\r\nroot@" not in nand_mediack[ 1]: log(hostname, 'nand-mediack check FAILED: ' + nand_mediack[1]) return {'success': 0, 'message': 'nand-mediack check FAILED'} else: log(hostname, 'nand-mediack check PASSED: ' + nand_mediack[1]) reconnDev.close() log(hostname, "Completed execution") log(hostname, "------------------------") return {'success': 1, 'message': 'SCRIPT COMPLETED EXECUTION'}
class Test_Decorators(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager_setup self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() def test_timeout(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(x): return x decorator = timeoutDecorator(function) decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] mock_timeout.assert_has_calls(calls) def test_timeout_except(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(*args, **kwargs): raise Exception() decorator = timeoutDecorator(function) # test to ensure the exception is raised with self.assertRaises(Exception): decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] # verify timeout was set/reset mock_timeout.assert_has_calls(calls) # Test default of true and passing true keyword def test_normalize_true_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of true and passing true keyword and a func exception def test_normalize_true_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of True and passing false keyword def test_normalize_true_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of True and passing false keyword and a func exception def test_normalize_true_false_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword def test_normalize_false_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] # print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword and a func exception def test_normalize_false_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] # print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing false keyword def test_normalize_false_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) self.assertFalse(mock_transform.called) # Test default with ignore_warning not present. def test_ignore_warning_missing(self): def method(self, x): return x decorator = ignoreWarnDecorator(method) response = decorator(self.dev, 'foo') self.assertEqual('foo', response) # Test default with ignore_warning=False. def test_ignore_warning_false(self): def method(self, x): return x decorator = ignoreWarnDecorator(method) response = decorator(self.dev, 'foo', ignore_warning=False) self.assertEqual('foo', response) # Test with ignore_warning=True and only warnings. def test_ignore_warning_true_3snf_warnings(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning=True)) # Test with ignore_warning='statement not found' and 3 snf warnings. def test_ignore_warning_string_3snf_warnings(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning='statement not found')) # Test with ignore_warning='statement not found', 1 snf warning, # and 1 error. def test_ignore_warning_string_1snf_warning_1err(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_1snf_warning_1err) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning='statement not found') # Test with ignore_warning=True, RpcError with no errs attribute. # I haven't seen this from an actual device, so this is a very contrived # test. def test_ignore_warning_string_1snf_warning_1err(self): def method(self, x): rpc_error = RPCError(XML('<foo/>'), errs=None) raise rpc_error decorator = ignoreWarnDecorator(method) with self.assertRaises(RPCError): decorator(self.dev, 'foo', ignore_warning=True) # Test with ignore_warning=['foo', 'statement not found'] and # three statement not found warnings. def test_ignore_warning_list_3snf_warnings(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning=['foo', 'statement not found'])) # Test with ignore_warning='foo', and three statement not found warnings. def test_ignore_warning_string_3snf_no_match(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning='foo') # Test with ignore_warning=['foo', 'bar], and # three statement not found warnings. def test_ignore_warning_list_3snf_no_match(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning=['foo', 'bar']) # Test with ignore_warning=['foo', 'bar], and # three warnings which are 'foo boom', 'boom bar', and 'foo bar' def test_ignore_warning_list_3warn_match(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3foobar_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning=['foo', 'bar'])) # Test with ignore_warning=['foo', 'foo bar], and # three warnings which are 'foo boom', 'boom bar', and 'foo bar' def test_ignore_warning_list_3warn_no_match(self): self.dev._conn.rpc = MagicMock(side_effect= self._mock_manager_3foobar_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning=['foo', 'foo bar']) def _mock_manager_setup(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) def _mock_manager_3snf_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//'+qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors) def _mock_manager_3foobar_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> foo boom </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> boom bar </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> foo bar </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//'+qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors) def _mock_manager_1snf_warning_1err(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>protcols</bad-element> </error-info> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//'+qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors)
class Test_RpcMetaExec(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() self.rpc = _RpcMetaExec(self.dev) def test_rpcmeta_constructor(self): self.assertTrue(isinstance(self.rpc._junos, Device)) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_with_configuration_tag(self, mock_execute_fn): root = etree.XML( '<configuration><root><a>test</a></root></configuration>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_option_action(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, action='set') self.assertEqual(mock_execute_fn.call_args[0][0].get('action'), 'set') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, format='text') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format_json(self, mock_execute_fn): json_commands = """ { "configuration" : { "system" : { "services" : { "telnet" : [null] } } } } """ self.rpc.load_config(json_commands, format='json') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'json') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_vargs(self, mock_execute_fn): self.rpc.system_users_information(dict(format='text')) self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs_bool_true(self, mock_execute_fn): self.rpc.system_users_information(test=True) self.assertEqual(mock_execute_fn.call_args[0][0][0].tag, 'test') self.assertEqual(mock_execute_fn.call_args[0][0][0].text, None) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs_bool_False(self, mock_execute_fn): self.rpc.system_users_information(test=False) self.assertEqual(mock_execute_fn.call_args[0][0].find('test'), None) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs_tuple(self, mock_execute_fn): self.rpc.system_users_information(set_data=('test', 'foo')) self.assertEqual(mock_execute_fn.call_args[0][0][0].text, 'test') self.assertEqual(mock_execute_fn.call_args[0][0][1].text, 'foo') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs_dict(self, mock_execute_fn): self.assertRaises(TypeError, self.rpc.system_users_information, dict_data={'test': 'foo'}) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs_list_with_dict(self, mock_execute_fn): self.assertRaises(TypeError, self.rpc.system_users_information, list_with_dict_data=[True, {'test': 'foo'}]) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_normalize(self, mock_execute_fn): self.rpc.any_ole_rpc(normalize=True) self.assertEqual(mock_execute_fn.call_args[1], {'normalize': True}) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_get_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.get_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'get-configuration') def test_rpcmeta_exec_rpc_format_json_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('14.2X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual(op['system-users-information'][0] ['uptime-information'][0]['date-time'][0]['data'], u'4:43AM') def test_rpcmeta_exec_rpc_format_json_gt_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('15.1X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual(op['system-users-information'][0] ['uptime-information'][0]['date-time'][0]['data'], u'4:43AM') @patch('jnpr.junos.device.warnings') def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('13.1X46-D15.3') self.rpc.get_system_users_information(dict(format='json')) mock_warn.assert_has_calls([call.warn( 'Native JSON support is only from 14.2 onwards', RuntimeWarning)]) def test_get_rpc(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(filter_select='bgp') self.assertEqual(resp.tag, 'data') def test_get_config_filter_xml_string_xml(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config( filter_xml='<system><services/></system>') self.assertEqual(resp.tag, 'configuration') def test_get_config_filter_xml_string(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config(filter_xml='system/services') self.assertEqual(resp.tag, 'configuration') def test_get_config_filter_xml_model(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config('bgp/neighbors', model='openconfig') self.assertEqual(resp.tag, 'bgp') def test_get_rpc_ignore_warning_bool(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=True) self.assertEqual(resp.tag, 'data') def test_get_rpc_ignore_warning_str(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning='vrrp subsystem not running') self.assertEqual(resp.tag, 'data') def test_get_rpc_ignore_warning_list(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=['vrrp subsystem not running', 'statement not found']) self.assertEqual(resp.tag, 'data') # below test need to be fixed for Python 3.x """ def test_get_config_remove_ns(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config('bgp/neighbors', model='openconfig', remove_ns=False) self.assertEqual(resp.tag, '{http://openconfig.net/yang/bgp}bgp') """ # def test_model_true(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) data = self.dev.rpc.get_config(model=True) self.assertEqual(data.tag, 'data') def test_get_config_format_json_JSONLoadError_with_line(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('15.1X46-D15.3') try: self.dev.rpc.get_config(options={'format': 'json'}) except JSONLoadError as ex: self.assertTrue(re.search( "Expecting \'?,\'? delimiter: line 17 column 39 \(char 516\)", ex.ex_msg) is not None) def _mock_manager(self, *args, **kwargs): if kwargs: if 'normalize' in kwargs and args: return self._read_file(args[0].tag + '.xml') device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: if len(args[0]) > 0 and args[0][0].tag == 'bgp': return self._read_file(args[0].tag + '_bgp_openconfig.xml') elif (args[0].attrib.get('format') == 'json' and args[0].tag == 'get-configuration'): return self._read_file(args[0].tag + '.json') return self._read_file(args[0].tag + '.xml') 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() return NCElement(foo, self.dev._conn._device_handler.transform_reply())
class Test_RpcMetaExec(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() self.rpc = _RpcMetaExec(self.dev) def test_rpcmeta_constructor(self): self.assertTrue(isinstance(self.rpc._junos, Device)) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_load_config(self, mock_execute_fn): root = etree.XML("<root><a>test</a></root>") self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, "load-configuration") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_load_config_with_configuration_tag(self, mock_execute_fn): root = etree.XML( "<configuration><root><a>test</a></root></configuration>") self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, "load-configuration") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_load_config_option_action(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, action="set") self.assertEqual(mock_execute_fn.call_args[0][0].get("action"), "set") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_option_format(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, format="text") self.assertEqual(mock_execute_fn.call_args[0][0].get("format"), "text") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_option_format_json(self, mock_execute_fn): json_commands = """ { "configuration" : { "system" : { "services" : { "telnet" : [null] } } } } """ self.rpc.load_config(json_commands, format="json") self.assertEqual(mock_execute_fn.call_args[0][0].get("format"), "json") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_vargs(self, mock_execute_fn): self.rpc.system_users_information(dict(format="text")) self.assertEqual(mock_execute_fn.call_args[0][0].get("format"), "text") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_kvargs_bool_true(self, mock_execute_fn): self.rpc.system_users_information(test=True) self.assertEqual(mock_execute_fn.call_args[0][0][0].tag, "test") self.assertEqual(mock_execute_fn.call_args[0][0][0].text, None) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_kvargs_bool_False(self, mock_execute_fn): self.rpc.system_users_information(test=False) self.assertEqual(mock_execute_fn.call_args[0][0].find("test"), None) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_kvargs_tuple(self, mock_execute_fn): self.rpc.system_users_information(set_data=("test", "foo")) self.assertEqual(mock_execute_fn.call_args[0][0][0].text, "test") self.assertEqual(mock_execute_fn.call_args[0][0][1].text, "foo") @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_kvargs_dict(self, mock_execute_fn): self.assertRaises(TypeError, self.rpc.system_users_information, dict_data={"test": "foo"}) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_kvargs_list_with_dict(self, mock_execute_fn): self.assertRaises( TypeError, self.rpc.system_users_information, list_with_dict_data=[True, { "test": "foo" }], ) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_exec_rpc_normalize(self, mock_execute_fn): self.rpc.any_ole_rpc(normalize=True) self.assertEqual(mock_execute_fn.call_args[1], {"normalize": True}) @patch("jnpr.junos.device.Device.execute") def test_rpcmeta_get_config(self, mock_execute_fn): root = etree.XML("<root><a>test</a></root>") self.rpc.get_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, "get-configuration") def test_rpcmeta_exec_rpc_format_json_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache["version_info"] = version_info("14.2X46-D15.3") op = self.rpc.get_system_users_information(dict(format="json")) self.assertEqual( op["system-users-information"][0]["uptime-information"][0] ["date-time"][0]["data"], u"4:43AM", ) def test_rpcmeta_exec_rpc_format_json_gt_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache["version_info"] = version_info("15.1X46-D15.3") op = self.rpc.get_system_users_information(dict(format="json")) self.assertEqual( op["system-users-information"][0]["uptime-information"][0] ["date-time"][0]["data"], u"4:43AM", ) @patch("jnpr.junos.device.warnings") def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache["version_info"] = version_info("13.1X46-D15.3") self.rpc.get_system_users_information(dict(format="json")) mock_warn.assert_has_calls([ call.warn("Native JSON support is only from 14.2 onwards", RuntimeWarning) ]) def test_get_rpc(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(filter_select="bgp") self.assertEqual(resp.tag, "data") def test_get_config_filter_xml_string_xml(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config( filter_xml="<system><services/></system>") self.assertEqual(resp.tag, "configuration") def test_get_config_filter_xml_string(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config(filter_xml="system/services") self.assertEqual(resp.tag, "configuration") def test_get_config_filter_xml_model(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config("bgp/neighbors", model="openconfig") self.assertEqual(resp.tag, "bgp") def test_get_rpc_ignore_warning_bool(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=True) self.assertEqual(resp.tag, "data") def test_get_rpc_ignore_warning_str(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning="vrrp subsystem not running") self.assertEqual(resp.tag, "data") def test_get_rpc_ignore_warning_list(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get(ignore_warning=[ "vrrp subsystem not running", "statement not found" ]) self.assertEqual(resp.tag, "data") # below test need to be fixed for Python 3.x """ def test_get_config_remove_ns(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) resp = self.dev.rpc.get_config('bgp/neighbors', model='openconfig', remove_ns=False) self.assertEqual(resp.tag, '{http://openconfig.net/yang/bgp}bgp') """ # def test_model_true(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) data = self.dev.rpc.get_config(model=True) self.assertEqual(data.tag, "data") def test_get_config_format_json_JSONLoadError_with_line(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache["version_info"] = version_info("15.1X46-D15.3") try: self.dev.rpc.get_config(options={"format": "json"}) except JSONLoadError as ex: self.assertTrue( re.search( "Expecting '?,'? delimiter: line 17 column 39 \(char 516\)", ex.ex_msg, ) is not None) def _mock_manager(self, *args, **kwargs): if kwargs: if "normalize" in kwargs and args: return self._read_file(args[0].tag + ".xml") device_params = kwargs["device_params"] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: if len(args[0]) > 0 and args[0][0].tag == "bgp": return self._read_file(args[0].tag + "_bgp_openconfig.xml") elif (args[0].attrib.get("format") == "json" and args[0].tag == "get-configuration"): return self._read_file(args[0].tag + ".json") return self._read_file(args[0].tag + ".xml") 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() return NCElement(foo, self.dev._conn._device_handler.transform_reply())
def get_vlan_vni(message, **kwargs): # Get previous values temp = re.search(r'set vlans v(\d+) vxlan vni (\d+)', message) vni_num = int(temp.group(2)) vlan_num = int(temp.group(1)) print(kwargs, file=sys.stderr) r = requests.get('http://config-server:9000/api/v2/device-group/%s/' % kwargs['device_group'], verify=False) #print(r.status_code, file=sys.stderr) if r.status_code != 200: return False device_group_info = r.json() devices_list = device_group_info['devices'] d = requests.get('http://config-server:9000/api/v2/device/%s/' % kwargs['device_id'], verify=False) if d.status_code != 200: return False device_info = d.json() device_name = device_info['device-id'] for dev in devices_list: if dev != device_name: rd = requests.get('http://config-server:9000/api/v2/device/%s/' % dev, verify=False) if r.status_code != 200: return False devices_info = rd.json() hostname = devices_info['host'] userid = devices_info['authentication']['password']['username'] password = devices_info['authentication']['password']['password'] dev = Device(host=hostname, user=userid, password=password, normalize=True) dev.open() sw = dev.cli("show vlans v%s" % vlan_num, warning=False) try: tmp = re.search(r'default-switch\s+v(\d*)\s+', sw) vlan = int(tmp.group(1)) except: vlan = None print(vlan) if (vlan is vlan_num): print("VNI configuration exists") else: cu = Config(dev) config = """ set vlans v{0} vlan-id {0} set vlans v{0} vxlan vni {1} set vlans v{0} l3-interface irb.{0} set vlans v{0} description "Tenant_1 - brdige domain id {0}" set protocols evpn extended-vni-list {1} set policy-options policy-statement OVERLAY-IMPORT term vni-Tenant_1-v{0} from community com-vni-Tenant_1-v{0} set policy-options policy-statement OVERLAY-IMPORT term vni-Tenant_1-v{0} then accept set policy-options community com-vni-Tenant_1-v{0} members target:1:{0} set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} then community add com-vni-Tenant_1-v{0} set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} then accept set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} from interface irb.{0} set policy-options policy-statement TENANT_1-IMPORT term vni-Tenant_1-v{0} from community com-vni-Tenant_1-v{0} set policy-options policy-statement TENANT_1-IMPORT term vni-Tenant_1-v{0} then accept """.format(vlan_num, vni_num) cu.load(config, format='set') if cu.commit_check(): res = cu.commit() print("Added config") else: print("commit check failed") return False else: print("Local device") return True
class Test_RpcMetaExec(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() self.rpc = _RpcMetaExec(self.dev) def test_rpcmeta_constructor(self): self.assertTrue(isinstance(self.rpc._junos, Device)) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_with_configuration_tag(self, mock_execute_fn): root = etree.XML( '<configuration><root><a>test</a></root></configuration>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_option_action(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, action='set') self.assertEqual(mock_execute_fn.call_args[0][0].get('action'), 'set') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, format='text') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format_json(self, mock_execute_fn): json_commands = """ { "configuration" : { "system" : { "services" : { "telnet" : [null] } } } } """ self.rpc.load_config(json_commands, format='json') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'json') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_vargs(self, mock_execute_fn): self.rpc.system_users_information(dict(format='text')) self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs(self, mock_execute_fn): self.rpc.system_users_information(set_data=('test',)) self.assertEqual(mock_execute_fn.call_args[0][0][0].text, 'test') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_normalize(self, mock_execute_fn): self.rpc.any_ole_rpc(normalize=True) self.assertEqual(mock_execute_fn.call_args[1], {'normalize': True}) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_get_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.get_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'get-configuration') def test_rpcmeta_exec_rpc_format_json_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('14.2X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual(op['system-users-information'][0] ['uptime-information'][0]['date-time'][0]['data'], u'4:43AM') def test_rpcmeta_exec_rpc_format_json_gt_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('15.1X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual(op['system-users-information'][0] ['uptime-information'][0]['date-time'][0]['data'], u'4:43AM') @patch('jnpr.junos.device.warnings') def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev.facts._cache['version_info'] = version_info('13.1X46-D15.3') self.rpc.get_system_users_information(dict(format='json')) mock_warn.assert_has_calls(call.warn( 'Native JSON support is only from 14.2 onwards', RuntimeWarning)) def _mock_manager(self, *args, **kwargs): if kwargs: if 'normalize' in kwargs and args: return self._read_file(args[0].tag + '.xml') device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: return self._read_file(args[0].tag + '.xml') 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-system-users-information.xml': return NCElement(foo, self.dev._conn._device_handler.transform_reply()) rpc_reply = NCElement(foo, self.dev._conn. _device_handler.transform_reply())\ ._NCElement__doc[0] return rpc_reply
#! /usr/bin/env python from jnpr.junos.device import Device from jnpr.junos.utils.config import Config dev = Device(host='20.0.2.31',user='******',password='******') dev.open() cu = Config(dev) print cu.load(path="/home/hans/git/juniper/juniper/manual_file.set", format='set') print cu.pdiff() dev.close()
class Test_RpcMetaExec(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() self.rpc = _RpcMetaExec(self.dev) def test_rpcmeta_constructor(self): self.assertTrue(isinstance(self.rpc._junos, Device)) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_with_configuration_tag(self, mock_execute_fn): root = etree.XML( '<configuration><root><a>test</a></root></configuration>') self.rpc.load_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'load-configuration') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_load_config_option_action(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, action='set') self.assertEqual(mock_execute_fn.call_args[0][0].get('action'), 'set') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_option_format(self, mock_execute_fn): set_commands = """ set system host-name test_rpc set system domain-name test.juniper.net """ self.rpc.load_config(set_commands, format='text') self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_vargs(self, mock_execute_fn): self.rpc.system_users_information(dict(format='text')) self.assertEqual(mock_execute_fn.call_args[0][0].get('format'), 'text') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_kvargs(self, mock_execute_fn): self.rpc.system_users_information(set_data=('test', )) self.assertEqual(mock_execute_fn.call_args[0][0][0].text, 'test') @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_exec_rpc_normalize(self, mock_execute_fn): self.rpc.any_ole_rpc(normalize=True) self.assertEqual(mock_execute_fn.call_args[1], {'normalize': True}) @patch('jnpr.junos.device.Device.execute') def test_rpcmeta_get_config(self, mock_execute_fn): root = etree.XML('<root><a>test</a></root>') self.rpc.get_config(root) self.assertEqual(mock_execute_fn.call_args[0][0].tag, 'get-configuration') def test_rpcmeta_exec_rpc_format_json_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev._facts['version_info'] = version_info('14.2X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual( op['system-users-information'][0]['uptime-information'][0] ['date-time'][0]['data'], u'4:43AM') def test_rpcmeta_exec_rpc_format_json_gt_14_2(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev._facts['version_info'] = version_info('15.1X46-D15.3') op = self.rpc.get_system_users_information(dict(format='json')) self.assertEqual( op['system-users-information'][0]['uptime-information'][0] ['date-time'][0]['data'], u'4:43AM') @patch('jnpr.junos.device.warnings') def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.dev._facts['version_info'] = version_info('13.1X46-D15.3') self.rpc.get_system_users_information(dict(format='json')) mock_warn.assert_has_calls( call.warn('Native JSON support is only from 14.2 onwards', RuntimeWarning)) def _mock_manager(self, *args, **kwargs): if kwargs: if 'normalize' in kwargs and args: return self._read_file(args[0].tag + '.xml') device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: return self._read_file(args[0].tag + '.xml') 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-system-users-information.xml': return NCElement(foo, self.dev._conn._device_handler.transform_reply()) rpc_reply = NCElement(foo, self.dev._conn. _device_handler.transform_reply())\ ._NCElement__doc[0] return rpc_reply
class Test_Decorators(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager_setup self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() def test_timeout(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(x): return x decorator = timeoutDecorator(function) decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] mock_timeout.assert_has_calls(calls) def test_timeout_except(self): with patch('jnpr.junos.Device.timeout', new_callable=PropertyMock) as mock_timeout: mock_timeout.return_value = 30 def function(*args, **kwargs): raise Exception() decorator = timeoutDecorator(function) # test to ensure the exception is raised with self.assertRaises(Exception): decorator(self.dev, dev_timeout=10) calls = [call(), call(10), call(30)] # verify timeout was set/reset mock_timeout.assert_has_calls(calls) # Test default of true and passing true keyword def test_normalize_true_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of true and passing true keyword and a func exception def test_normalize_true_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) self.assertFalse(mock_transform.called) # Test default of True and passing false keyword def test_normalize_true_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of True and passing false keyword and a func exception def test_normalize_true_false_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = True def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=False) calls = [call(), call(self.dev._nc_transform), call('o.g.')] mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword def test_normalize_false_true(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] # print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing true keyword and a func exception def test_normalize_false_true_except(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: mock_transform.return_value = 'o.g.' self.dev._normalize = False def function(*args, **kwargs): raise Exception() decorator = normalizeDecorator(function) with self.assertRaises(Exception): decorator(self.dev, normalize=True) calls = [call(), call(self.dev._norm_transform), call('o.g.')] # print mock_transform.call_args_list mock_transform.assert_has_calls(calls) # Test default of false and passing false keyword def test_normalize_false_false(self): with patch('jnpr.junos.Device.transform', new_callable=PropertyMock) as mock_transform: self.dev._normalize = False def function(x): return x decorator = normalizeDecorator(function) decorator(self.dev, normalize=False) self.assertFalse(mock_transform.called) # Test default with ignore_warning not present. def test_ignore_warning_missing(self): def method(self, x): return x decorator = ignoreWarnDecorator(method) response = decorator(self.dev, 'foo') self.assertEqual('foo', response) # Test default with ignore_warning=False. def test_ignore_warning_false(self): def method(self, x): return x decorator = ignoreWarnDecorator(method) response = decorator(self.dev, 'foo', ignore_warning=False) self.assertEqual('foo', response) # Test with ignore_warning=True and only warnings. def test_ignore_warning_true_3snf_warnings(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning=True)) # Test with ignore_warning='statement not found' and 3 snf warnings. def test_ignore_warning_string_3snf_warnings(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning='statement not found')) # Test with ignore_warning='statement not found', 1 snf warning, # and 1 error. def test_ignore_warning_string_1snf_warning_1err(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_1snf_warning_1err) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning='statement not found') # Test with ignore_warning=True, RpcError with no errs attribute. # I haven't seen this from an actual device, so this is a very contrived # test. def test_ignore_warning_string_1snf_warning_1err(self): def method(self, x): rpc_error = RPCError(XML('<foo/>'), errs=None) raise rpc_error decorator = ignoreWarnDecorator(method) with self.assertRaises(RPCError): decorator(self.dev, 'foo', ignore_warning=True) # Test with ignore_warning=['foo', 'statement not found'] and # three statement not found warnings. def test_ignore_warning_list_3snf_warnings(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo """ self.assertTrue( cu.load(config, ignore_warning=['foo', 'statement not found'])) # Test with ignore_warning='foo', and three statement not found warnings. def test_ignore_warning_string_3snf_no_match(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning='foo') # Test with ignore_warning=['foo', 'bar], and # three statement not found warnings. def test_ignore_warning_list_3snf_no_match(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3snf_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning=['foo', 'bar']) # Test with ignore_warning=['foo', 'bar], and # three warnings which are 'foo boom', 'boom bar', and 'foo bar' def test_ignore_warning_list_3warn_match(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3foobar_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ self.assertTrue(cu.load(config, ignore_warning=['foo', 'bar'])) # Test with ignore_warning=['foo', 'foo bar], and # three warnings which are 'foo boom', 'boom bar', and 'foo bar' def test_ignore_warning_list_3warn_no_match(self): self.dev._conn.rpc = MagicMock( side_effect=self._mock_manager_3foobar_warnings) cu = Config(self.dev) config = """ delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo """ with self.assertRaises(ConfigLoadError): cu.load(config, ignore_warning=['foo', 'foo bar']) def _mock_manager_setup(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) def _mock_manager_3snf_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//' + qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors) def _mock_manager_3foobar_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> foo boom </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> boom bar </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> foo bar </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//' + qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors) def _mock_manager_1snf_warning_1err(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>protcols</bad-element> </error-info> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//' + qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors)
def connect_to_device(hostname=None, user=None, password=None): dev = Device(hostname, user=user, password=password, normalize=True) dev.open(timeout=300) return dev
# first python script to make changes to juniper device # we're using simple set commands in set_config.set to configure device from jnpr.junos.device import Device from jnpr.junos.utils.config import Config # first create netconf device object and then open connection device = Device(host='vsrx04.t-i.demo',user='******',passwd="xxxxx") device.open() # Now create config object and load candidate configuration cfg = Config(device) cfg.load(path="set_config.set",format="set") # Lock candidate configuration cfg.lock() # now try to commit changes if(cfg.commit(comment="eznc generated config")): print "changes made to %s" % device.hostname else: print "failed" # no unlock candidate configuration again cfg.unlock() # we're done, close netconf connection device.close()