def facts_domain(junos, facts): """ The following facts are required: facts['hostname'] The following facts are assigned: facts['domain'] facts['fqdn'] """ try: domain_filter_xml = E("configuration", E("system", E("domain-name"))) domain = junos.rpc.get_config(filter_xml=domain_filter_xml, options=INHERIT) domain_name = domain.xpath(".//domain-name") if len(domain_name) > 0: facts["domain"] = domain_name[0].text facts["fqdn"] = facts["hostname"] + "." + facts["domain"] return except RpcError: pass fs = FS(junos) file_content = fs.cat("/etc/resolv.conf") or fs.cat("/var/etc/resolv.conf") words = file_content.split() if file_content is not None else "" if "domain" not in words: facts["domain"] = None facts["fqdn"] = facts["hostname"] else: idx = words.index("domain") + 1 facts["domain"] = words[idx] facts["fqdn"] = facts["hostname"] + "." + facts["domain"]
def main (): parser = argparse.ArgumentParser(add_help=True) parser.add_argument("-i", action="store", help="IP Address") parser.add_argument("-u", action="store", help="user") parser.add_argument("-p", action="store", help="password") args = parser.parse_args() ip_address = None user = None password = None if args.i: ip_address = args.i if args.u: user = args.u if args.p: password= args.p dev = Device(host = ip_address, user = user, password=password) dev.open(gather_facts = False) fs = FS(dev) myfiles = fs.ls('/var/log').get('files') for key in myfiles: if key.startswith('mplsstats'): with SCP(dev, progress=True) as scp: scp.get("/var/log/%s" % key) dev.close()
def get_rsi(ip_addr): dev = call_dev(ip_addr) myprint(ip_addr + ' : accessing... <br>') try: dev.open(gather_facts=False) except Exception as err: return myprint(ip_addr + ' : creating RSI file...<br>') ts = datetime.datetime.today().strftime('%Y%m%d%H%M') RSI_File = 'RSI_' + ts + '.txt' RSI_File2 = config.Temp_Dir + RSI_File myprint(RSI_File + '<br>') myprint(RSI_File2 + '<br>') opcmd = 'op url ' + config.RSI_Slax + ' rsi-file "' + RSI_File2 + '"' myprint(opcmd + '<br>') dev.timeout = 120 sw = dev.cli(opcmd, warning=False) myprint(ip_addr + ' : uploading RSI file to this server...<br>') RSI_File3 = ip_addr + '_' + RSI_File cu = FS(dev) cu.cp(RSI_File2, config.FileSrv + RSI_File3) # print ip_addr, " : Finished<br>" str1 = ip_addr + ' : Complete creating RSI file. Click <a href="' + config.HTTP_RSI_Dir + RSI_File3 + '">here</a> to download.<br>' myprint(str1) dev.close()
def facts_domain(junos, facts): """ The following facts are required: facts['hostname'] The following facts are assigned: facts['domain'] facts['fqdn'] """ try: domain_filter_xml = E('configuration', E('system', E('domain-name'))) domain = junos.rpc.get_config(filter_xml=domain_filter_xml, options=INHERIT) domain_name = domain.xpath('.//domain-name') if len(domain_name) > 0: facts['domain'] = domain_name[0].text facts['fqdn'] = facts['hostname'] + '.' + facts['domain'] return except RpcError: pass fs = FS(junos) file_content = fs.cat('/etc/resolv.conf') or fs.cat('/var/etc/resolv.conf') words = file_content.split() if file_content is not None else '' if 'domain' not in words: facts['domain'] = None facts['fqdn'] = facts['hostname'] else: idx = words.index('domain') + 1 facts['domain'] = words[idx] facts['fqdn'] = facts['hostname'] + '.' + facts['domain']
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.fs = FS(self.dev)
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.fs = FS(self.dev)
def inventory(self): """ Returns dictionary of file listing information for current and rollback Junos install packages. This information comes from the /packages directory. """ from jnpr.junos.utils.fs import FS fs = FS(self.dev) pkgs = fs.ls('/packages') return dict(current=pkgs['files'].get( 'junos'), rollback=pkgs['files'].get('junos.old'))
def inventory(self): """ Returns dictionary of file listing information for current and rollback Junos install packages. This information comes from the /packages directory. """ from jnpr.junos.utils.fs import FS fs = FS(self.dev) pkgs = fs.ls('/packages') return dict(current=pkgs['files'].get('junos'), rollback=pkgs['files'].get('junos.old'))
def check_directory_usage(port): with Device(host=host, user=USER, passwd=PASSWD, mode="telnet", port=port) as dev: fs = FS(dev) print("Checking %s: " % port, ) print(fs.directory_usage(DIRECTORY)) facts = dev.facts["hostname"] + " " + dev.facts["version"] isis = dev.cli("show configuration protocols isis | display set") out.write(facts) out.write(isis)
def check_directory_usage(host): # (3) try: with Device(host=host, user=USER, password=PASSWD) as dev: fs = FS(dev) # (4) print("Checking %s: " % host, end="") print(fs.directory_usage(DIRECTORY)) # (5) except ConnectRefusedError: # (6) print("%s: Error - Device connection refused!" % host) except ConnectTimeoutError: print("%s: Error - Device connection timed out!" % host) except ConnectAuthError: print("%s: Error - Authentication failure!" % host)
def main(): dev = Device(host="192.168.65.61", user="******", passwd="lab123", normalize=True) dev.open() if dev.facts['junos_info']['re0']['text'] == TARGET_VERSION: print("Device OS version is already the target version") exit(1) fs = FS(dev) bytes_free = fs.storage_usage()['/dev/gpt/junos']['avail_block']*512 file_size = os.stat(IMAGE_FILE).st_size print("We have %d bytes free, image size is %d" % (bytes_free, file_size)) if bytes_free < file_size: print("Error: not enough space on device") exit(1) print("Copying image to the device...") with SCP(dev, progress=True) as scp: scp.put(IMAGE_FILE, remote_path=REMOTE_PATH) print("Installing package...") sw = SW(dev) install_result = sw.install(package=REMOTE_PATH+IMAGE_FILE, no_copy=True, validate=False, progress=True) if not install_result: print("Installation error, exiting") exit(1) print("Rebooting...") sw.reboot() for _ in range(20): print("Waiting for device reboot...") sleep(50) try: dev.open(auto_probe=10) ver = dev.facts['junos_info']['re0']['text'] except (ProbeError, ConnectError): continue dev.close() break else: print("The device did not complete reboot in time, please check.") exit(1) if ver == TARGET_VERSION: print("Reboot complete. Installation successful.") else: print("Reboot complete but something went wrong!") exit(1)
def check_directory_usage(host): try: with Device(host=host, user=USER, passwd=PASSWD) as dev: fs = FS(dev) print("Checking %s:" % host, end="") #print("Checking {}:".format{host}, end="") print(fs.directory_usage(DIRECTORY)) except ConnectRefusedError: print("{}: Error - Device connection refused!".format(host)) except ConnectTimeoutError: print("%s: Error - Device connection time out!" % host) except ConnectAuthError: print("%s: Error - Authentication failure!" % host)
def inventory(self): """ Returns dictionary of file listing information for current and rollback Junos install packages. This information comes from the /packages directory. .. warning:: Experimental method; may not work on all platforms. If you find this not working, please report issue. """ from jnpr.junos.utils.fs import FS fs = FS(self.dev) pkgs = fs.ls('/packages') return dict(current=pkgs['files'].get( 'junos'), rollback=pkgs['files'].get('junos.old'))
def inventory(self): """ Returns dictionary of file listing information for current and rollback Junos install packages. This information comes from the /packages directory. .. warning:: Experimental method; may not work on all platforms. If you find this not working, please report issue. """ from jnpr.junos.utils.fs import FS fs = FS(self.dev) pkgs = fs.ls('/packages') return dict(current=pkgs['files'].get('junos'), rollback=pkgs['files'].get('junos.old'))
def get_facts(device): """ Gathers domain facts from the configuration or /etc/resolv.conf. """ domain_config = """ <configuration> <system> <domain-name/> </system> </configuration> """ domain = None fqdn = None # Try to read the domain-name from the config. # This might fail due to lack of permissions. try: rsp = device.rpc.get_config(filter_xml=etree.XML(domain_config), options={ 'database': 'committed', 'inherit': 'inherit', 'commit-scripts': 'apply', }) domain = rsp.findtext('.//domain-name') # Ignore if user can't view the configuration. except PermissionError: pass # Try to read the domain from the resolv.conf file. This only requires # view permissions. if domain is None: fs = FS(device) file_content = (fs.cat('/etc/resolv.conf') or fs.cat('/var/etc/resolv.conf')) words = file_content.split() if file_content is not None else [] if 'domain' in words: idx = words.index('domain') + 1 domain = words[idx] # Set the fqdn fqdn = device.facts['hostname'] if fqdn is not None and domain is not None: fqdn = fqdn + '.' + domain return { 'domain': domain, 'fqdn': fqdn, }
def facts_domain(junos, facts): """ The following facts are required: facts['hostname'] The following facts are assigned: facts['domain'] facts['fqdn'] """ fs = FS(junos) words = fs.cat('/etc/resolv.conf').split() if 'domain' not in words: facts['domain'] = None facts['fqdn'] = facts['hostname'] else: idx = words.index('domain') + 1 facts['domain'] = words[idx] facts['fqdn'] = facts['hostname'] + '.' + facts['domain']
def get_facts(device): """ Gathers domain facts from the configuration or /etc/resolv.conf. """ domain_config = """ <configuration> <system> <domain-name/> </system> </configuration> """ domain = None fqdn = None # Try to read the domain-name from the config. # This might fail due to lack of permissions. try: rsp = device.rpc.get_config(filter_xml=etree.XML(domain_config), options={'database': 'committed', 'inherit': 'inherit', 'commit-scripts': 'apply', }) domain = rsp.findtext('.//domain-name') # Ignore if user can't view the configuration. except PermissionError: pass # Try to read the domain from the resolv.conf file. This only requires # view permissions. if domain is None: fs = FS(device) file_content = (fs.cat('/etc/resolv.conf') or fs.cat('/var/etc/resolv.conf')) words = file_content.split() if file_content is not None else [] if 'domain' in words: idx = words.index('domain') + 1 domain = words[idx] # Set the fqdn fqdn = device.facts['hostname'] if fqdn is not None and domain is not None: fqdn = fqdn + '.' + domain return {'domain': domain, 'fqdn': fqdn, }
def install_junos(ip_addr, image_file): # calucurate MD5 md5 = commands.getoutput('md5sum -b %s' % cofig.OS_Dir + '/' + image_file).split() local_md5 = md5[0] print 'local md5 = ', local_md5, '<br>' dev = call_dev(ip_addr) try: dev.open(gather_facts=False) dev.timeout = 1800 # copy the image print 'Copying os image. please wait...<br>' junos_image_file = config.Temp_Dir + image_file cu = FS(dev) result = cu.cp(config.OSImage_Dir + image_file, junos_image_file) # calcurate MD5 on device remote_md5 = cu.checksum(junos_image_file) print 'remote md5 = ', remote_md5, '<br>' if local_md5 == remote_md5: print 'Complete file copy successfully.<br>' # install the image print 'Start junos update. please wait...<br>' sw = SW(dev) result = sw.pkgadd(junos_image_file) if result is True: print 'OS installation process finished successfully.<br>' else: print 'OS installation process finished with failure.<br>' else: print 'Complete file copy with failure.<br>' except Exception as err: print err else: dev.close()
def get_rsi(equipment): try: print( "Gathering RSI...(This takes a bit - give it time. Timeout is 10 minutes.)" ) ss = StartShell(equipment) ss.open() ss.run('cli request support information \\| save /var/tmp/' + current_date + '_py_rsi.txt', this="%", timeout=600) print("RSI Done, copying it and deleting it...\n") ss.close() with SCP(equipment, progress=True) as scp: scp.get('/var/tmp/' + current_date + "_py_rsi.txt", full_file + "_" + current_date + "_rsi.txt") fileSystem = FS(equipment) fileSystem.rm('/var/tmp/*_py_rsi.txt') except Exception as err: missedEquipment[equipment] = "Error getting RSI - " + str(err)
def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor='juniper', device_type='juniper_junos_netconf', **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native)
def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor='juniper', device_type=JNPR_DEVICE_TYPE, **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native)
def __init__(self, host, username, password, *args, **kwargs): super().__init__(host, username, password, *args, device_type="juniper_junos_netconf", **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativeSW(self.native)
def get_logs(equipment): try: print("Compressing /var/log...") fileSystem = FS(equipment) fileSystem.tgz("/var/log/*", "/var/tmp/" + current_date + "_py_varlog.tgz") print( "Copying log files down and removing the .tgz that was created...") with SCP(equipment, progress=True) as scp: scp.get(f"/var/tmp/" + current_date + "_py_varlog.tgz", full_file + "_" + current_date + "_varlog.tgz") print("\nRemoving that var/log file\n") fileSystem.rm("/var/tmp/*_py_varlog.tgz") except Exception as err: missedEquipment[equipment] = "Error getting logs - " + str(err)
from jnpr.junos import Device from jnpr.junos.utils.config import Config from jnpr.junos.utils.fs import FS from pprint import pprint import sys dev = Device('host', user='******', password='******') dev.open() fs = FS(dev) pprint(fs.ls(path="/var/tmp/", brief=True)) print fs.pwd()
from jnpr.junos.utils.fs import FS from jnpr.junos import Device dev = Device(host='xxxx', user='******', password='******') dev.open() fs = FS(dev) pprint(fs.ls('/var/tmp')) dev.close()
with open(filename_snap) as f: for line in f: if re.search('Input/output error', line): print "-> (e) Device has Input/output error.Aborting snapshot!" log("-> (e) Device has Input/output error.Aborting snapshot!") close() sys.exit(1) text_file_snap.close() # request system storage cleanup # print "-> Performing system storage cleanup, please be patient" fs = FS(j_device) fs.storage_cleanup() # Disables traceoptions + syslog # print "-> Disabling syslog + traceoptions (when enabled)" my_commit(disable_cmds, j_device) # Take a snapshot # print "-> Snapshoting the device.." try: rsp = j_device.rpc.request_snapshot(slice='alternate', dev_timeout=600) except Exception as err: print "--> (e) Error when snapshoting the device!", err
class TestFS(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.fs = FS(self.dev) @patch('jnpr.junos.device.warnings') def test_cat_wrong_path_return_none(self, mock_warnings): path = 'test/report' self.assertEqual(self.fs.cat(path), None) def test_cat(self): self.fs._dev.rpc.file_show = MagicMock(side_effect=self._mock_manager) path = 'test/cat.txt' self.assertTrue('testing cat functionality' in self.fs.cat(path)) self.fs._dev.rpc.file_show.assert_called_with(filename='test/cat.txt') def test_cwd(self): self.fs._dev.rpc.set_cli_working_directory = MagicMock( side_effect=self._mock_manager) folder = 'change/directory' self.assertEqual('change/directory', self.fs.cwd(folder)) self.fs._dev.rpc.set_cli_working_directory.\ assert_called_with(directory='change/directory') @patch('jnpr.junos.Device.execute') def test_pwd(self, mock_execute): mock_execute.side_effect = MagicMock(side_effect=self._mock_manager) self.fs.pwd() self.assertEqual(self.fs.pwd(), '/cf/var/home/rick') @patch('jnpr.junos.device.warnings') def test_checksum_return_none(self, mock_warnings): path = 'test/report' self.assertEqual(self.fs.checksum(path), None) def test_checksum_unknown_calc(self): path = 'test/report' self.assertRaises(ValueError, self.fs.checksum, path=path, calc='abc') def test_checksum_return_rsp(self): self.fs.dev.rpc.get_sha256_checksum_information = \ MagicMock(side_effect=self._mock_manager) path = 'test/checksum' self.assertEqual(self.fs.checksum(path, 'sha256'), 'xxxx') self.fs.dev.rpc.get_sha256_checksum_information.\ assert_called_with(path='test/checksum') def test_stat_calling___decode_file(self): path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.stat(path), {'owner': 'pqr', 'path': '/var/abc.sh', 'permissions': 755, 'permissions_text': '-rwxr-xr-x', 'size': 2, 'ts_date': 'Mar 13 06:54', 'ts_epoc': '1394693680', 'type': 'file'}) def test_stat_calling___decode_dir(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.stat(path), {'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_stat_return_none(self): path = 'test/abc' self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = 'output' self.assertEqual(self.fs.stat(path), None) def test_ls_calling___decode_file(self): path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'owner': 'pqr', 'path': '/var/abc.sh', 'permissions': 755, 'permissions_text': '-rwxr-xr-x', 'size': 2, 'ts_date': 'Mar 13 06:54', 'ts_epoc': '1394693680', 'type': 'file'}) def test_ls_calling___decode_dir(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'files': {'abc': {'permissions_text': 'drwxr-xr-x', 'ts_date': 'Feb 17 15:30', 'ts_epoc': '1392651039', 'owner': 'root', 'path': 'abc', 'size': 2, 'type': 'dir', 'permissions': 555}}, 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_ls_return_none(self): path = 'test/abc' self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = 'output' self.assertEqual(self.fs.ls(path), None) @patch('jnpr.junos.utils.fs.FS._decode_file') def test_ls_link_path_false(self, mock_decode_file): mock_decode_file.get.return_value = False path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.fs.ls(path, followlink=False) mock_decode_file.assert_has_calls([call().get('link')]) def test_ls_brief_true(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path, brief=True), {'files': ['abc'], 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_ls_calling___decode_dir_type_symbolic_link(self): path = 'test/stat/decode_symbolic_link' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'files': {'abc': {'permissions_text': 'drwxr-xr-x', 'ts_date': 'Feb 17 15:30', 'link': 'symlink test', 'ts_epoc': '1392651039', 'owner': 'root', 'path': 'abc', 'size': 2, 'type': 'link', 'permissions': 555}}, 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_rm_return_true(self): self.fs.dev.rpc.file_delete = MagicMock(return_value=True) path = 'test/abc' self.assertTrue(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with( path='test/abc') def test_rm_return_false(self): path = 'test/abc' self.fs.dev.rpc.file_delete = MagicMock(return_value=False) self.assertFalse(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with( path='test/abc') def test_copy_return_true(self): self.fs.dev.rpc.file_copy = MagicMock() initial = 'test/abc' final = 'test/xyz' self.assertTrue(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source='test/abc', destination='test/xyz') def test_copy_return_false(self): initial = 'test/abc' final = 'test/xyz' self.fs.dev.rpc.file_copy = MagicMock(side_effect=Exception) self.assertFalse(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source='test/abc', destination='test/xyz') def test_move_return_true(self): self.fs.dev.rpc.file_rename = MagicMock(return_value=True) initial = 'test/abc' final = 'test/xyz' self.assertTrue(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source='test/abc', destination='test/xyz') def test_move_return_false(self): initial = 'test/abc' final = 'test/xyz' self.fs.dev.rpc.file_rename = MagicMock(return_value=False) self.assertFalse(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source='test/abc', destination='test/xyz') def test_tgz_return_true(self): src = 'test/tgz.txt' dst = 'test/xyz' self.fs.dev.rpc.file_archive = MagicMock(return_value=True) self.assertTrue(self.fs.tgz(src, dst)) self.fs.dev.rpc.file_archive.assert_called_once_with( source='test/tgz.txt', destination='test/xyz', compress=True) @patch('jnpr.junos.Device.execute') def test_tgz_return_error(self, mock_execute): mock_execute.side_effect = self._mock_manager src = 'test/tgz.txt' dst = 'test/xyz' self.assertTrue('testing tgz' in self.fs.tgz(src, dst)) @patch('jnpr.junos.utils.fs.StartShell') def test_rmdir(self, mock_StartShell): path = 'test/rmdir' print(self.fs.rmdir(path)) calls = [ call().__enter__(), call().__enter__().run('rmdir test/rmdir'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.utils.fs.StartShell') def test_mkdir(self, mock_StartShell): path = 'test/mkdir' print(self.fs.mkdir(path)) calls = [ call().__enter__(), call().__enter__().run('mkdir -p test/mkdir'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.utils.fs.StartShell') def test_symlink(self, mock_StartShell): src = 'test/tgz.txt' dst = 'test/xyz' print(self.fs.symlink(src, dst)) calls = [ call().__enter__(), call().__enter__().run('ln -sf test/tgz.txt test/xyz'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.Device.execute') def test_storage_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_usage(), {'/dev/abc': {'avail_block': 234234, 'used_blocks': 2346455, 'used_pct': '1', 'mount': '/', 'total_blocks': 567431, 'avail': '2F', 'used': '481M', 'total': '4F'}}) @patch('jnpr.junos.Device.execute') def test_directory_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.directory_usage(path="/var/tmp", depth=1), {'/var/tmp': {'blocks': 456076, 'bytes': 233510912, 'size': '223M'}, '/var/tmp/gres-tp': {'blocks': 68, 'bytes': 34816, 'size': '34K'}, '/var/tmp/install': {'blocks': 4, 'bytes': 2048, 'size': '2.0K'}, '/var/tmp/pics': {'blocks': 4, 'bytes': 2048, 'size': '2.0K'}, '/var/tmp/rtsdb': {'blocks': 4, 'bytes': 2048, 'size': '2.0K'}, '/var/tmp/sec-download': {'blocks': 8, 'bytes': 4096, 'size': '4.0K'}, '/var/tmp/vi.recover': {'blocks': 4, 'bytes': 2048, 'size': '2.0K'}} ) @patch('jnpr.junos.Device.execute') def test_directory_usage_error(self, mock_execute): mock_execute.return_value = etree.fromstring(""" <directory-usage-information> <directory> <used-space used-blocks="456076"> 223M </used-space> </directory> </directory-usage-information>""") self.assertRaises( RpcError, self.fs.directory_usage, path="/var/tmp", depth=1) @patch('jnpr.junos.Device.execute') def test_directory_usage_no_directory(self, mock_execute): mock_execute.side_effect = self._mock_manager_error1 self.assertRaises( RpcError, self.fs.directory_usage, path="/var/tmp", depth="1") @patch('jnpr.junos.Device.execute') def test_directory_usage_no_dir_name(self, mock_execute): mock_execute.side_effect = self._mock_manager_error2 self.assertRaises( RpcError, self.fs.directory_usage, path="/var/tmp", depth="1") @patch('jnpr.junos.Device.execute') def test_storage_cleanup(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup(), {'/var/abc.txt': {'ts_date': 'Apr 25 10:38', 'size': 11}}) @patch('jnpr.junos.Device.execute') def test_storage_cleanup_check(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup_check(), {'/var/abc.txt': {'ts_date': 'Apr 25 10:38', 'size': 11}}) 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' or fname == 'set-cli-working-directory.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: # if 'path' in kwargs and 'detail' in kwargs: # return self._read_file('dir_list_detail.xml') if 'path' in kwargs: if kwargs['path'] == 'test/stat/decode_dir': return self._read_file('file-list_dir.xml') elif kwargs['path'] == 'test/stat/decode_file': return self._read_file('file-list_file.xml') elif kwargs['path'] == 'test/checksum': return self._read_file('checksum.xml') elif kwargs['path'] == 'test/stat/decode_symbolic_link': return self._read_file('file-list_symlink.xml') if 'directory' in kwargs: if kwargs['directory'] == 'change/directory': return self._read_file('set-cli-working-directory.xml') if 'filename' in kwargs: if kwargs['filename'] == 'test/cat.txt': return self._read_file('file-show.xml') 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].tag == 'get-system-storage': return self._read_file('get-system-storage.xml') elif args[0].tag == 'get-directory-usage-information': return self._read_file('get-directory-usage-information.xml') elif args[0].tag == 'request-system-storage-cleanup': return self._read_file('request-system-storage-cleanup.xml') elif args[0].tag == 'file-archive': return self._read_file('file-archive.xml') def _mock_manager_error1(self, *args, **kwargs): if args: if args[0].tag == 'get-directory-usage-information': return self._read_file( 'get-directory-usage-information_error1.xml') def _mock_manager_error2(self, *args, **kwargs): if args: if args[0].tag == 'get-directory-usage-information': return self._read_file( 'get-directory-usage-information_error2.xml')
from jnpr.junos import Device from jnpr.junos.utils.config import Config from jnpr.junos.utils.fs import FS from pprint import pprint import sys dev = Device('host', user='******', password='******') dev.open() fs = FS(dev) pprint (fs.ls(path="/var/tmp/", brief=True)) print fs.pwd()
class TestFS(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.fs = FS(self.dev) def test_cat_wrong_path_return_none(self): path = "test/report" self.assertEqual(self.fs.cat(path), None) def test_cat(self): self.fs._dev.rpc.file_show = MagicMock(side_effect=self._mock_manager) path = "test/cat.txt" self.assertTrue("testing cat functionality" in self.fs.cat(path)) self.fs._dev.rpc.file_show.assert_called_with(filename="test/cat.txt") def test_cwd(self): self.fs._dev.rpc.set_cli_working_directory = MagicMock(side_effect=self._mock_manager) folder = "change/directory" self.assertEqual("change/directory", self.fs.cwd(folder)) self.fs._dev.rpc.set_cli_working_directory.assert_called_with(directory="change/directory") @patch("jnpr.junos.Device.execute") def test_pwd(self, mock_execute): mock_execute.side_effect = MagicMock(side_effect=self._mock_manager) self.fs.pwd() self.assertEqual(self.fs.pwd(), "/cf/var/home/rick") def test_checksum_return_none(self): path = "test/report" self.assertEqual(self.fs.checksum(path), None) def test_checksum_unknown_calc(self): path = "test/report" self.assertRaises(ValueError, self.fs.checksum, path=path, calc="abc") def test_checksum_return_rsp(self): self.fs.dev.rpc.get_sha256_checksum_information = MagicMock(side_effect=self._mock_manager) path = "test/checksum" self.assertEqual(self.fs.checksum(path, "sha256"), "xxxx") self.fs.dev.rpc.get_sha256_checksum_information.assert_called_with(path="test/checksum") def test_stat_calling___decode_file(self): path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.stat(path), { "owner": "pqr", "path": "/var/abc.sh", "permissions": 755, "permissions_text": "-rwxr-xr-x", "size": 2, "ts_date": "Mar 13 06:54", "ts_epoc": "1394693680", "type": "file", }, ) def test_stat_calling___decode_dir(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.stat(path), {"path": "/var", "type": "dir", "file_count": 1, "size": 2}) def test_stat_return_none(self): path = "test/abc" self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = "output" self.assertEqual(self.fs.stat(path), None) def test_ls_calling___decode_file(self): path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "owner": "pqr", "path": "/var/abc.sh", "permissions": 755, "permissions_text": "-rwxr-xr-x", "size": 2, "ts_date": "Mar 13 06:54", "ts_epoc": "1394693680", "type": "file", }, ) def test_ls_calling___decode_dir(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "files": { "abc": { "permissions_text": "drwxr-xr-x", "ts_date": "Feb 17 15:30", "ts_epoc": "1392651039", "owner": "root", "path": "abc", "size": 2, "type": "dir", "permissions": 555, } }, "path": "/var", "type": "dir", "file_count": 1, "size": 2, }, ) def test_ls_return_none(self): path = "test/abc" self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = "output" self.assertEqual(self.fs.ls(path), None) @patch("jnpr.junos.utils.fs.FS._decode_file") def test_ls_link_path_false(self, mock_decode_file): mock_decode_file.get.return_value = False path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.fs.ls(path, followlink=False) mock_decode_file.assert_has_calls(call().get("link")) def test_ls_brief_true(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path, brief=True), {"files": ["abc"], "path": "/var", "type": "dir", "file_count": 1, "size": 2} ) def test_ls_calling___decode_dir_type_symbolic_link(self): path = "test/stat/decode_symbolic_link" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "files": { "abc": { "permissions_text": "drwxr-xr-x", "ts_date": "Feb 17 15:30", "link": "symlink test", "ts_epoc": "1392651039", "owner": "root", "path": "abc", "size": 2, "type": "link", "permissions": 555, } }, "path": "/var", "type": "dir", "file_count": 1, "size": 2, }, ) def test_rm_return_true(self): self.fs.dev.rpc.file_delete = MagicMock(return_value=True) path = "test/abc" self.assertTrue(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with(path="test/abc") def test_rm_return_false(self): path = "test/abc" self.fs.dev.rpc.file_delete = MagicMock(return_value=False) self.assertFalse(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with(path="test/abc") def test_copy_return_true(self): self.fs.dev.rpc.file_copy = MagicMock() initial = "test/abc" final = "test/xyz" self.assertTrue(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with(source="test/abc", destination="test/xyz") def test_copy_return_false(self): initial = "test/abc" final = "test/xyz" self.fs.dev.rpc.file_copy = MagicMock(side_effect=Exception) self.assertFalse(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with(source="test/abc", destination="test/xyz") def test_move_return_true(self): self.fs.dev.rpc.file_rename = MagicMock(return_value=True) initial = "test/abc" final = "test/xyz" self.assertTrue(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with(source="test/abc", destination="test/xyz") def test_move_return_false(self): initial = "test/abc" final = "test/xyz" self.fs.dev.rpc.file_rename = MagicMock(return_value=False) self.assertFalse(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with(source="test/abc", destination="test/xyz") def test_tgz_return_true(self): src = "test/tgz.txt" dst = "test/xyz" self.fs.dev.rpc.file_archive = MagicMock(return_value=True) self.assertTrue(self.fs.tgz(src, dst)) self.fs.dev.rpc.file_archive.assert_called_once_with( source="test/tgz.txt", destination="test/xyz", compress=True ) @patch("jnpr.junos.Device.execute") def test_tgz_return_error(self, mock_execute): mock_execute.side_effect = self._mock_manager src = "test/tgz.txt" dst = "test/xyz" self.assertTrue("testing tgz" in self.fs.tgz(src, dst)) @patch("jnpr.junos.utils.fs.StartShell") def test_rmdir(self, mock_StartShell): path = "test/rmdir" print(self.fs.rmdir(path)) calls = [call().__enter__(), call().__enter__().run("rmdir test/rmdir"), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.utils.fs.StartShell") def test_mkdir(self, mock_StartShell): path = "test/mkdir" print(self.fs.mkdir(path)) calls = [call().__enter__(), call().__enter__().run("mkdir -p test/mkdir"), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.utils.fs.StartShell") def test_symlink(self, mock_StartShell): src = "test/tgz.txt" dst = "test/xyz" print(self.fs.symlink(src, dst)) calls = [ call().__enter__(), call().__enter__().run("ln -sf test/tgz.txt test/xyz"), call().__exit__(None, None, None), ] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.Device.execute") def test_storage_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.storage_usage(), { "/dev/abc": { "avail_block": 234234, "used_blocks": 2346455, "used_pct": "1", "mount": "/", "total_blocks": 567431, "avail": "2F", "used": "481M", "total": "4F", } }, ) @patch("jnpr.junos.Device.execute") def test_directory_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.directory_usage(path="/var/tmp", depth=1), { "/var/tmp": {"blocks": 456076, "bytes": 233510912, "size": "223M"}, "/var/tmp/gres-tp": {"blocks": 68, "bytes": 34816, "size": "34K"}, "/var/tmp/install": {"blocks": 4, "bytes": 2048, "size": "2.0K"}, "/var/tmp/pics": {"blocks": 4, "bytes": 2048, "size": "2.0K"}, "/var/tmp/rtsdb": {"blocks": 4, "bytes": 2048, "size": "2.0K"}, "/var/tmp/sec-download": {"blocks": 8, "bytes": 4096, "size": "4.0K"}, "/var/tmp/vi.recover": {"blocks": 4, "bytes": 2048, "size": "2.0K"}, }, ) @patch("jnpr.junos.Device.execute") def test_storage_cleanup(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup(), {"/var/abc.txt": {"ts_date": "Apr 25 10:38", "size": 11}}) @patch("jnpr.junos.Device.execute") def test_storage_cleanup_check(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup_check(), {"/var/abc.txt": {"ts_date": "Apr 25 10:38", "size": 11}}) 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" or fname == "set-cli-working-directory.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: # if 'path' in kwargs and 'detail' in kwargs: # return self._read_file('dir_list_detail.xml') if "path" in kwargs: if kwargs["path"] == "test/stat/decode_dir": return self._read_file("file-list_dir.xml") elif kwargs["path"] == "test/stat/decode_file": return self._read_file("file-list_file.xml") elif kwargs["path"] == "test/checksum": return self._read_file("checksum.xml") elif kwargs["path"] == "test/stat/decode_symbolic_link": return self._read_file("file-list_symlink.xml") if "directory" in kwargs: if kwargs["directory"] == "change/directory": return self._read_file("set-cli-working-directory.xml") if "filename" in kwargs: if kwargs["filename"] == "test/cat.txt": return self._read_file("file-show.xml") 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].tag == "get-system-storage": return self._read_file("get-system-storage.xml") elif args[0].tag == "get-directory-usage-information": return self._read_file("get-directory-usage-information.xml") elif args[0].tag == "request-system-storage-cleanup": return self._read_file("request-system-storage-cleanup.xml") elif args[0].tag == "file-archive": return self._read_file("file-archive.xml")
def save_data(dev, step, **options): from jnpr.junos.utils.fs import FS from jnpr.junos.utils.start_shell import StartShell if not dev.connected: reconnect = reconnect_dev(dev, 2) if not reconnect: logging.info("Connection Failed to {}\n".format(dev.hostname)) return if options.has_key('script_name'): script_name = options['script_name'] else: script_name = False if options.has_key('rsi'): rsi = True if options['rsi'] == 'brief': brief = True else: brief = False else: rsi = False if options.has_key('folder'): dst_dir = options['folder'] else: dst_dir = '/var/tmp' if options.has_key('save_config'): save_config = options['save_config'] else: save_config = False # Start Shell dev_shell = StartShell(dev) dev_shell.open() # Get RSI if rsi: logging.info( 'Running "request support information", this may take a while') if brief: rsi_cli = dev_shell.run( 'cli -c "request support information brief | save {}/{}_rsi.txt"' .format(dst_dir, step)) else: rsi_cli = dev_shell.run( 'cli -c "request support information | save {}/{}_rsi.txt"'. format(dst_dir, step)) # Run OP Script if script_name: logging.info("Running op script: '{}' ... ".format(script_name)) op_script = dev_shell.run('cli -c "op {} | save {}/{}_{}.txt"'.format( script_name, dst_dir, step, script_name)) # Save Configuration if save_config: logging.info("Saving Configuration backup") cfg = dev_shell.run( 'cli -c "show configuration | save {}/{}_backup_config.txt"'. format(dst_dir, step)) dev_shell.close() logging.info('Verifying stored files') dev_fs = FS(dev) tmp_list = dev_fs.ls(dst_dir) if rsi: if tmp_list['files'].has_key('{}_rsi.txt'.format(step)): logging.info("Compressing RSI") dev_fs.tgz( '{}/{}_rsi.txt'.format(dst_dir, step), '{}/{}_Upgrade-MOP-support-information.tgz'.format( dst_dir, step)) dev_fs.rm('{}/{}_rsi.txt'.format(dst_dir, step)) if tmp_list['files'].has_key( '{}_Upgrade-MOP-support-information.tgz'.format(step)): logging.info("RSI file saved in {}".format(dst_dir)) rsi_complete = True else: logging.info("RSI collection did not complete in time\n") if save_config: if tmp_list['files'].has_key('{}_backup_config.txt'.format(step)): config_saved = True logging.info( "Backup configuration saved to {}/{}_backup_config.txt".format( dst_dir, step)) else: logging.info("Failed to save backup config") if script_name: if tmp_list['files'].has_key('{}_{}.txt'.format(step, script_name)): op_complete = True logging.info("OP {} script output saved in {}".format( script_name, dst_dir)) else: logging.info("OP {} script did not complete Successfully".format( script_name))
class JunosDevice(BaseDevice): def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor='juniper', device_type=JNPR_DEVICE_TYPE, **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native) @property def connected(self): return self.native.connected def open(self): if not self.connected: self.native.open() def close(self): if self.connected: self.native.close() def show(self, command, raw_text=True): if not raw_text: raise ValueError('Juniper only supports raw text output. \ Append " | display xml" to your commands for a structured string.') if not command.startswith('show'): raise CommandError(command, 'Juniper "show" commands must begin with "show".') return self.native.cli(command, warning=False) def show_list(self, commands, raw_text=True): responses = [] for command in commands: responses.append(self.show(command, raw_text=raw_text)) return responses def backup_running_config(self, filename): with open(filename, 'w') as f: f.write(self.running_config) def config(self, command, format='set'): try: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(command, e.message) def config_list(self, commands, format='set'): try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) def _uptime_components(self, uptime_full_string): match_days = re.search(r'(\d+) days?', uptime_full_string) match_hours = re.search(r'(\d+) hours?', uptime_full_string) match_minutes = re.search(r'(\d+) minutes?', uptime_full_string) match_seconds = re.search(r'(\d+) seconds?', uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) return '%02d:%02d:%02d:%02d' % (days, hours, minutes, seconds) def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def checkpoint(self, filename): self.save(filename) def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format='text', overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def facts(self): if hasattr(self, '_facts'): return self._facts native_facts = self.native.facts facts = {} facts['hostname'] = native_facts['hostname'] facts['fqdn'] = native_facts['fqdn'] facts['model'] = native_facts['model'] native_uptime_string = native_facts['RE0']['up_time'] facts['uptime'] = self._uptime_to_seconds(native_uptime_string) facts['uptime_string'] = self._uptime_to_string(native_uptime_string) facts['serial_number'] = native_facts['serialnumber'] facts['interfaces'] = self._get_interfaces() for fact_key in native_facts: if fact_key.startswith('version') and fact_key != 'version_info': facts['os_version'] = native_facts[fact_key] break facts['vendor'] = self.vendor self._facts = facts return self._facts def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def file_copy_remote_exists(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None: if local_hash == remote_hash: return True return False def file_copy(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) def get_boot_options(self): return self.facts['os_version'] def set_boot_options(self, sys): raise NotImplementedError def reboot(self, timer=0, confirm=False): if confirm: self.sw.reboot(in_min=timer) else: print('Need to confirm reboot with confirm=True') @property def running_config(self): return self.show('show config') def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show('show config')) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True @property def startup_config(self): return self.show('show config')
class JunosDevice(BaseDevice): def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor='juniper', device_type=JNPR_DEVICE_TYPE, **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.connected = False self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native) def open(self): if not self.connected: self.native.open() self.connected = True def close(self): if self.connected: self.native.close() self.connected = False def show(self, command, raw_text=True): if not raw_text: raise ValueError('Juniper only supports raw text output. \ Append " | display xml" to your commands for a structured string.') if not command.startswith('show'): raise CommandError(command, 'Juniper "show" commands must begin with "show".') return self.native.cli(command, warning=False) def show_list(self, commands, raw_text=True): responses = [] for command in commands: responses.append(self.show(command, raw_text=raw_text)) return responses def backup_running_config(self, filename): with open(filename, 'w') as f: f.write(self.running_config) def config(self, command, format='set'): try: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(command, e.message) def config_list(self, commands, format='set'): try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) def _uptime_components(self, uptime_full_string): match_days = re.search(r'(\d+) days?', uptime_full_string) match_hours = re.search(r'(\d+) hours?', uptime_full_string) match_minutes = re.search(r'(\d+) minutes?', uptime_full_string) match_seconds = re.search(r'(\d+) seconds?', uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) return '%02d:%02d:%02d:%02d' % (days, hours, minutes, seconds) def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def checkpoint(self, filename): self.save(filename) def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format='text', overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def facts(self): if hasattr(self, '_facts'): return self._facts native_facts = self.native.facts facts = {} facts['hostname'] = native_facts['hostname'] facts['fqdn'] = native_facts['fqdn'] facts['model'] = native_facts['model'] native_uptime_string = native_facts['RE0']['up_time'] facts['uptime'] = self._uptime_to_seconds(native_uptime_string) facts['uptime_string'] = self._uptime_to_string(native_uptime_string) facts['serial_number'] = native_facts['serialnumber'] facts['interfaces'] = self._get_interfaces() for fact_key in native_facts: if fact_key.startswith('version') and fact_key != 'version_info': facts['os_version'] = native_facts[fact_key] break facts['vendor'] = self.vendor self._facts = facts return self._facts def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def file_copy_remote_exists(self, src, dest=None): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None: if local_hash == remote_hash: return True return False def file_copy(self, src, dest=None): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) def get_boot_options(self): return self.facts['os_version'] def set_boot_options(self, sys): raise NotImplementedError def reboot(self, timer=0, confirm=False): if confirm: self.sw.reboot(in_min=timer) else: print('Need to confirm reboot with confirm=True') @property def running_config(self): return self.show('show config') def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show('show config')) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True @property def startup_config(self): return self.show('show config')
class JunosDevice(BaseDevice): """Juniper JunOS Device Implementation.""" vendor = "juniper" def __init__(self, host, username, password, *args, **kwargs): super().__init__(host, username, password, *args, device_type="juniper_junos_netconf", **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativeSW(self.native) def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def _image_booted(self, image_name, **vendor_specifics): raise NotImplementedError def _uptime_components(self, uptime_full_string): match_days = re.search(r"(\d+) days?", uptime_full_string) match_hours = re.search(r"(\d+) hours?", uptime_full_string) match_minutes = re.search(r"(\d+) minutes?", uptime_full_string) match_seconds = re.search(r"(\d+) seconds?", uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) return "%02d:%02d:%02d:%02d" % (days, hours, minutes, seconds) def _wait_for_device_reboot(self, timeout=3600): start = time.time() while time.time() - start < timeout: try: self.open() return except: # noqa E722 pass raise RebootTimeoutError(hostname=self.facts["hostname"], wait_time=timeout) def backup_running_config(self, filename): with open(filename, "w") as f: f.write(self.running_config) @property def boot_options(self): return self.facts["os_version"] def checkpoint(self, filename): self.save(filename) def close(self): if self.connected: self.native.close() def config(self, command, format="set"): try: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(command, e.message) def config_list(self, commands, format="set"): try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) @property def connected(self): return self.native.connected @property def facts(self): if self._facts is None: native_facts = self.native.facts try: native_uptime_string = native_facts["RE0"]["up_time"] except (AttributeError, TypeError): native_uptime_string = None self._facts = { "hostname": native_facts.get("hostname"), "fqdn": native_facts.get("fqdn"), "model": native_facts.get("model"), "uptime": None, "uptime_string": None, "serial_number": native_facts.get("serialnumber"), "interfaces": self._get_interfaces(), "vendor": self.vendor, "version": native_facts.get("version"), } # TODO: Use a more reliable method for determining uptime (show system uptime) if native_uptime_string is not None: self._facts["uptime"] = self._uptime_to_seconds( native_uptime_string) self._facts["uptime_string"] = self._uptime_to_string( native_uptime_string) return self._facts def file_copy(self, src, dest=None, **kwargs): if not self.file_copy_remote_exists(src, dest, **kwargs): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) if not self.file_copy_remote_exists(src, dest, **kwargs): raise FileTransferError( message= "Attempted file copy, but could not validate file existed after transfer" ) # TODO: Make this an internal method since exposing file_copy should be sufficient def file_copy_remote_exists(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None and local_hash == remote_hash: return True return False def install_os(self, image_name, **vendor_specifics): raise NotImplementedError def open(self): if not self.connected: self.native.open() def reboot(self, timer=0, confirm=False): self.sw = JunosNativeSW(self.native) if confirm: self.sw.reboot(in_min=timer) else: print("Need to confirm reboot with confirm=True") def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format="text", overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def running_config(self): return self.show("show config") def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show("show config")) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True def set_boot_options(self, sys): raise NotImplementedError def show(self, command, raw_text=True): if not raw_text: raise ValueError('Juniper only supports raw text output. \ Append " | display xml" to your commands for a structured string.' ) if not command.startswith("show"): raise CommandError( command, 'Juniper "show" commands must begin with "show".') return self.native.cli(command, warning=False) def show_list(self, commands, raw_text=True): responses = [] for command in commands: responses.append(self.show(command, raw_text=raw_text)) return responses @property def startup_config(self): return self.show("show config")
user="******", password="******", gather_facts=False) dev.open() print("Connection successfully...") print("\n------ FILE CREATION") print("Starting shell for creating RSI...") ss = StartShell(dev) ss.open() ss.run('cli -c "request support information | save /var/tmp/pyez_rsi.txt"') print("RSI done...") ss.close() # Compress /var/log/ to /var/tmp/pyez_varlog.tgz fileSystem = FS(dev) fileSystem.tgz("/var/log/*", "/var/tmp/pyez_varlog.tgz") print("/var/log-compressed...") # Get file system information statRsi = fileSystem.stat("/var/tmp/pyez_rsi.txt") statLogs = fileSystem.stat("/var/tmp/pyez_varlog.tgz") # Transfering files via SCP print("\n------ Transfering files") # Get RSI if statRsi['size'] is not None: print("File: /var/tmp/pyez_rsi.txt - Size: " + (str(sizeof_fmt(statRsi['size'])))) askForTransferRsi = input("Do you want to transfer the RSI? (Yes, No)")
class JunosDevice(BaseDevice): """Juniper JunOS Device Implementation.""" vendor = "juniper" def __init__(self, host, username, password, *args, **kwargs): super().__init__(host, username, password, *args, device_type="juniper_junos_netconf", **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativeSW(self.native) def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() # nosec with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def _image_booted(self, image_name, **vendor_specifics): raise NotImplementedError def _uptime_components(self, uptime_full_string): match_days = re.search(r"(\d+) days?", uptime_full_string) match_hours = re.search(r"(\d+) hours?", uptime_full_string) match_minutes = re.search(r"(\d+) minutes?", uptime_full_string) match_seconds = re.search(r"(\d+) seconds?", uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) return "%02d:%02d:%02d:%02d" % (days, hours, minutes, seconds) def _wait_for_device_reboot(self, timeout=3600): start = time.time() while time.time() - start < timeout: try: self.open() return except: # noqa E722 # nosec pass raise RebootTimeoutError(hostname=self.hostname, wait_time=timeout) def backup_running_config(self, filename): with open(filename, "w") as f: f.write(self.running_config) @property def boot_options(self): return self.os_version def checkpoint(self, filename): self.save(filename) def close(self): if self.connected: self.native.close() def config(self, commands, format="set"): """Send configuration commands to a device. Args: commands (str, list): String with single command, or list with multiple commands. Raises: ConfigLoadError: Issue with loading the command. CommandError: Issue with the command provided, if its a single command, passed in as a string. CommandListError: Issue with a command in the list provided. """ if isinstance(commands, str): try: self.cu.load(commands, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(commands, e.message) else: try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) def config_list(self, commands, format="set"): """Send configuration commands in list format to a device. DEPRECATED - Use the `config` method. Args: commands (list): List with multiple commands. """ warnings.warn("config_list() is deprecated; use config().", DeprecationWarning) self.config(commands, format=format) @property def connected(self): return self.native.connected @property def uptime(self): try: native_uptime_string = self.native.facts["RE0"]["up_time"] except (AttributeError, TypeError): native_uptime_string = None if self._uptime is None: if native_uptime_string is not None: self._uptime = self._uptime_to_seconds(native_uptime_string) return self._uptime @property def uptime_string(self): try: native_uptime_string = self.native.facts["RE0"]["up_time"] except (AttributeError, TypeError): native_uptime_string = None if self._uptime_string is None: self._uptime_string = self._uptime_to_string(native_uptime_string) return self._uptime_string @property def hostname(self): if self._hostname is None: self._hostname = self.native.facts.get("hostname") return self._hostname @property def interfaces(self): if self._interfaces is None: self._interfaces = self._get_interfaces() return self._interfaces @property def fqdn(self): if self._fqdn is None: self._fqdn = self.native.facts.get("fqdn") return self._fqdn @property def model(self): if self._model is None: self._model = self.native.facts.get("model") return self._model @property def os_version(self): if self._os_version is None: self._os_version = self.native.facts.get("version") return self._os_version @property def serial_number(self): if self._serial_number is None: self._serial_number = self.native.facts.get("serialnumber") return self._serial_number def file_copy(self, src, dest=None, **kwargs): if not self.file_copy_remote_exists(src, dest, **kwargs): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) if not self.file_copy_remote_exists(src, dest, **kwargs): raise FileTransferError( message= "Attempted file copy, but could not validate file existed after transfer" ) # TODO: Make this an internal method since exposing file_copy should be sufficient def file_copy_remote_exists(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None and local_hash == remote_hash: return True return False def install_os(self, image_name, **vendor_specifics): raise NotImplementedError def open(self): if not self.connected: self.native.open() def reboot(self, timer=0, **kwargs): """ Reload the controller or controller pair. Args: timer (int, optional): The time to wait before reloading. Defaults to 0. Example: >>> device = JunosDevice(**connection_args) >>> device.reboot() >>> """ if kwargs.get("confirm"): warnings.warn("Passing 'confirm' to reboot method is deprecated.", DeprecationWarning) self.sw = JunosNativeSW(self.native) self.sw.reboot(in_min=timer) def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format="text", overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def running_config(self): return self.show("show config") def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show("show config")) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True def set_boot_options(self, sys): raise NotImplementedError def show(self, commands): """Send configuration commands to a device. Args: commands (str, list): String with single command, or list with multiple commands. Raises: CommandError: Issue with the command provided. CommandListError: Issue with a command in the list provided. """ original_commands_is_str = isinstance(commands, str) if original_commands_is_str: commands = [commands] responses = [] for command in commands: if not command.startswith("show"): if original_commands_is_str: raise CommandError( command, 'Juniper "show" commands must begin with "show".') raise CommandListError( commands, command, 'Juniper "show" commands must begin with "show".') response = self.native.cli(command, warning=False) responses.append(response) if original_commands_is_str: return responses[0] return responses def show_list(self, commands, raw_text=True): """Send show commands in list format to a device. DEPRECATED - Use the `show` method. Args: commands (list): List with multiple commands. """ warnings.warn("show_list() is deprecated; use show().", DeprecationWarning) return self.show(commands) @property def startup_config(self): return self.show("show config")
scp.get("/var/tmp/showintext.gz", local_path=ip + "showintext.gz") else: scp.get("/var/tmp/showintext", local_path=ip + "showintext") fp = open(ip + "showintext", "rb") data = fp.read() bindata = bytearray(data) with gzip.open(ip + "showintext.gz", "wb") as f: f.write(bindata) if os.path.exists(ip + "showintext"): os.remove(ip + "showintext") fp.close() else: logging.warning(f"{ip} not work SCP cat file /var/tmp/showintext and gzip") with gzip.open(ip + "showintext.gz", mode="wb") as file: dev.timeout = 600 fs = FS(dev) result = fs.cat("/var/tmp/showintext") if result: file.write(result.encode()) # удаляем с шасси if not telnet_flag and gz_flag: dev.rpc.file_delete(path="/var/tmp/showintext.gz") else: dev.rpc.file_delete(path="/var/tmp/showintext") dev.close() logging.info(f"host\t{hostname}\tversion\t{version} connect and get OK") while global_lock.locked(): continue global_lock.acquire()
class TestFS(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.fs = FS(self.dev) @patch("jnpr.junos.device.warnings") def test_cat_wrong_path_return_none(self, mock_warnings): path = "test/report" self.assertEqual(self.fs.cat(path), None) def test_cat(self): self.fs._dev.rpc.file_show = MagicMock(side_effect=self._mock_manager) path = "test/cat.txt" self.assertTrue("testing cat functionality" in self.fs.cat(path)) self.fs._dev.rpc.file_show.assert_called_with(filename="test/cat.txt") def test_cwd(self): self.fs._dev.rpc.set_cli_working_directory = MagicMock( side_effect=self._mock_manager) folder = "change/directory" self.assertEqual("change/directory", self.fs.cwd(folder)) self.fs._dev.rpc.set_cli_working_directory.assert_called_with( directory="change/directory") @patch("jnpr.junos.Device.execute") def test_pwd(self, mock_execute): mock_execute.side_effect = MagicMock(side_effect=self._mock_manager) self.fs.pwd() self.assertEqual(self.fs.pwd(), "/cf/var/home/rick") @patch("jnpr.junos.device.warnings") def test_checksum_return_none(self, mock_warnings): path = "test/report" self.assertEqual(self.fs.checksum(path), None) def test_checksum_unknown_calc(self): path = "test/report" self.assertRaises(ValueError, self.fs.checksum, path=path, calc="abc") def test_checksum_return_rsp(self): self.fs.dev.rpc.get_sha256_checksum_information = MagicMock( side_effect=self._mock_manager) path = "test/checksum" self.assertEqual(self.fs.checksum(path, "sha256"), "xxxx") self.fs.dev.rpc.get_sha256_checksum_information.assert_called_with( path="test/checksum") def test_stat_calling___decode_file(self): path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.stat(path), { "owner": "pqr", "path": "/var/abc.sh", "permissions": 755, "permissions_text": "-rwxr-xr-x", "size": 2, "ts_date": "Mar 13 06:54", "ts_epoc": "1394693680", "type": "file", }, ) def test_stat_calling___decode_dir(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.stat(path), { "path": "/var", "type": "dir", "file_count": 1, "size": 2 }, ) def test_stat_return_none(self): path = "test/abc" self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = "output" self.assertEqual(self.fs.stat(path), None) def test_ls_calling___decode_file(self): path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "owner": "pqr", "path": "/var/abc.sh", "permissions": 755, "permissions_text": "-rwxr-xr-x", "size": 2, "ts_date": "Mar 13 06:54", "ts_epoc": "1394693680", "type": "file", }, ) def test_ls_calling___decode_dir(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "files": { "abc": { "permissions_text": "drwxr-xr-x", "ts_date": "Feb 17 15:30", "ts_epoc": "1392651039", "owner": "root", "path": "abc", "size": 2, "type": "dir", "permissions": 555, } }, "path": "/var", "type": "dir", "file_count": 1, "size": 2, }, ) def test_ls_return_none(self): path = "test/abc" self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = "output" self.assertEqual(self.fs.ls(path), None) @patch("jnpr.junos.utils.fs.FS._decode_file") def test_ls_link_path_false(self, mock_decode_file): mock_decode_file.get.return_value = False path = "test/stat/decode_file" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.fs.ls(path, followlink=False) mock_decode_file.assert_has_calls([call().get("link")]) def test_ls_brief_true(self): path = "test/stat/decode_dir" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path, brief=True), { "files": ["abc"], "path": "/var", "type": "dir", "file_count": 1, "size": 2, }, ) def test_ls_calling___decode_dir_type_symbolic_link(self): path = "test/stat/decode_symbolic_link" self.fs.dev.rpc.file_list = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.fs.ls(path), { "files": { "abc": { "permissions_text": "drwxr-xr-x", "ts_date": "Feb 17 15:30", "link": "symlink test", "ts_epoc": "1392651039", "owner": "root", "path": "abc", "size": 2, "type": "link", "permissions": 555, } }, "path": "/var", "type": "dir", "file_count": 1, "size": 2, }, ) def test_rm_return_true(self): self.fs.dev.rpc.file_delete = MagicMock(return_value=True) path = "test/abc" self.assertTrue(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with(path="test/abc") def test_rm_return_false(self): path = "test/abc" self.fs.dev.rpc.file_delete = MagicMock(return_value=False) self.assertFalse(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with(path="test/abc") def test_copy_return_true(self): self.fs.dev.rpc.file_copy = MagicMock() initial = "test/abc" final = "test/xyz" self.assertTrue(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source="test/abc", destination="test/xyz") def test_copy_return_false(self): initial = "test/abc" final = "test/xyz" self.fs.dev.rpc.file_copy = MagicMock(side_effect=Exception) self.assertFalse(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source="test/abc", destination="test/xyz") def test_move_return_true(self): self.fs.dev.rpc.file_rename = MagicMock(return_value=True) initial = "test/abc" final = "test/xyz" self.assertTrue(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source="test/abc", destination="test/xyz") def test_move_return_false(self): initial = "test/abc" final = "test/xyz" self.fs.dev.rpc.file_rename = MagicMock(return_value=False) self.assertFalse(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source="test/abc", destination="test/xyz") def test_tgz_return_true(self): src = "test/tgz.txt" dst = "test/xyz" self.fs.dev.rpc.file_archive = MagicMock(return_value=True) self.assertTrue(self.fs.tgz(src, dst)) self.fs.dev.rpc.file_archive.assert_called_once_with( source="test/tgz.txt", destination="test/xyz", compress=True) @patch("jnpr.junos.Device.execute") def test_tgz_return_error(self, mock_execute): mock_execute.side_effect = self._mock_manager src = "test/tgz.txt" dst = "test/xyz" self.assertTrue("testing tgz" in self.fs.tgz(src, dst)) @patch("jnpr.junos.utils.fs.StartShell") def test_rmdir(self, mock_StartShell): path = "test/rmdir" print(self.fs.rmdir(path)) calls = [ call().__enter__(), call().__enter__().run("rmdir test/rmdir"), call().__exit__(None, None, None), ] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.utils.fs.StartShell") def test_mkdir(self, mock_StartShell): path = "test/mkdir" print(self.fs.mkdir(path)) calls = [ call().__enter__(), call().__enter__().run("mkdir -p test/mkdir"), call().__exit__(None, None, None), ] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.utils.fs.StartShell") def test_symlink(self, mock_StartShell): src = "test/tgz.txt" dst = "test/xyz" print(self.fs.symlink(src, dst)) calls = [ call().__enter__(), call().__enter__().run("ln -sf test/tgz.txt test/xyz"), call().__exit__(None, None, None), ] mock_StartShell.assert_has_calls(calls) @patch("jnpr.junos.Device.execute") def test_storage_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.storage_usage(), { "/dev/abc": { "avail_block": 234234, "used_blocks": 2346455, "used_pct": "1", "mount": "/", "total_blocks": 567431, "avail": "2F", "used": "481M", "total": "4F", } }, ) @patch("jnpr.junos.Device.execute") def test_storage_usage_linux(self, mock_execute): mock_execute.side_effect = self._mock_manager_linux self.assertEqual( self.fs.storage_usage(), { "re0": { "/dev/sda6": { "avail": "916M", "avail_block": 1874712, "mount": "/data/config", "total": "984M", "total_blocks": 2015024, "used": "1.4M", "used_blocks": 2688, "used_pct": "1", } } }, ) @patch("jnpr.junos.Device.execute") def test_directory_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.directory_usage(path="/var/tmp", depth=1), { "/var/tmp": { "blocks": 456076, "bytes": 233510912, "size": "223M" }, "/var/tmp/gres-tp": { "blocks": 68, "bytes": 34816, "size": "34K" }, "/var/tmp/install": { "blocks": 4, "bytes": 2048, "size": "2.0K" }, "/var/tmp/pics": { "blocks": 4, "bytes": 2048, "size": "2.0K" }, "/var/tmp/rtsdb": { "blocks": 4, "bytes": 2048, "size": "2.0K" }, "/var/tmp/sec-download": { "blocks": 8, "bytes": 4096, "size": "4.0K" }, "/var/tmp/vi.recover": { "blocks": 4, "bytes": 2048, "size": "2.0K" }, }, ) @patch("jnpr.junos.Device.execute") def test_directory_usage_error(self, mock_execute): mock_execute.return_value = etree.fromstring(""" <directory-usage-information> <directory> <used-space used-blocks="456076"> 223M </used-space> </directory> </directory-usage-information>""") self.assertRaises(RpcError, self.fs.directory_usage, path="/var/tmp", depth=1) @patch("jnpr.junos.Device.execute") def test_directory_usage_no_directory(self, mock_execute): mock_execute.side_effect = self._mock_manager_error1 self.assertRaises(RpcError, self.fs.directory_usage, path="/var/tmp", depth="1") @patch("jnpr.junos.Device.execute") def test_directory_usage_no_dir_name(self, mock_execute): mock_execute.side_effect = self._mock_manager_error2 self.assertRaises(RpcError, self.fs.directory_usage, path="/var/tmp", depth="1") @patch("jnpr.junos.Device.execute") def test_storage_cleanup(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.storage_cleanup(), {"/var/abc.txt": { "ts_date": "Apr 25 10:38", "size": 11 }}, ) @patch("jnpr.junos.Device.execute") def test_storage_cleanup_check(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.fs.storage_cleanup_check(), {"/var/abc.txt": { "ts_date": "Apr 25 10:38", "size": 11 }}, ) 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" or fname == "set-cli-working-directory.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: # if 'path' in kwargs and 'detail' in kwargs: # return self._read_file('dir_list_detail.xml') if "path" in kwargs: if kwargs["path"] == "test/stat/decode_dir": return self._read_file("file-list_dir.xml") elif kwargs["path"] == "test/stat/decode_file": return self._read_file("file-list_file.xml") elif kwargs["path"] == "test/checksum": return self._read_file("checksum.xml") elif kwargs["path"] == "test/stat/decode_symbolic_link": return self._read_file("file-list_symlink.xml") if "directory" in kwargs: if kwargs["directory"] == "change/directory": return self._read_file("set-cli-working-directory.xml") if "filename" in kwargs: if kwargs["filename"] == "test/cat.txt": return self._read_file("file-show.xml") 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].tag == "get-system-storage": return self._read_file("get-system-storage.xml") elif args[0].tag == "get-directory-usage-information": return self._read_file("get-directory-usage-information.xml") elif args[0].tag == "request-system-storage-cleanup": return self._read_file("request-system-storage-cleanup.xml") elif args[0].tag == "file-archive": return self._read_file("file-archive.xml") def _mock_manager_error1(self, *args, **kwargs): if args: if args[0].tag == "get-directory-usage-information": return self._read_file( "get-directory-usage-information_error1.xml") def _mock_manager_error2(self, *args, **kwargs): if args: if args[0].tag == "get-directory-usage-information": return self._read_file( "get-directory-usage-information_error2.xml") def _mock_manager_linux(self, *args, **kwargs): if args: if args[0].tag == "get-system-storage": return self._read_file("get-storage-usage-linux.xml")