def Upload_conf(input, hostname, username, password, mode="telnet", port=23, commant="Commited by NetConf"): # Connect to the Host try: dev = Device(host=hostname, user=username, passwd=password, mode=mode, port=port) dev.open() except Exception as err: sys.exit(1) dev.bind(cu=Config) # Load configuration changes print(bcolors.OKBLUE + "Loading configuration changes" + bcolors.ENDC) try: dev.cu.load(input, merge=True) except (ConfigLoadError, Exception) as err: print(bcolors.WARNING + "Unable to load configuration changes: {0}".format(err) + bcolors.ENDC) return # Commit the configuration print(bcolors.OKGREEN + "Committing the configuration" + bcolors.ENDC) try: dev.cu.commit(comment=commant) except CommitError as err: print(bcolors.WARNING + "Unable to commit configuration: {0}".format(err) + bcolors.ENDC) dev.close() return False except ConnectionResetError as err: return False except RuntimeError as err: print(bcolors.WARNING + "Unable to connect: {0}".format(err) + bcolors.ENDC) return False print(bcolors.OKGREEN + "Configuration commited" + bcolors.ENDC) return True """
def main(): dev = Device(host=host, user=user, password=password) try: dev.open() except Exception as err: print("Cannot connect to device: {}".format(err)) return dev.bind(cu=Config) # Lock the configuration, load changes, commit print("Locking the configuration on: {}".format(host)) try: dev.cu.lock() except LockError: print("Error: Unable to lock configuration on: {}".format(host)) dev.close() return print("Loading configuration changes on: {}".format(host)) try: dev.cu.load(template=j2_template, template_vars=vars, format='text', merge=True) except ValueError as err: print(err.message) except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') print("Unable to load config changes: {}".format(rpc_msg)) print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close() return print("Committing the configuration on: {}".format(host)) try: dev.cu.commit() # print dev.cu.diff() except CommitError: print("Error: Unable to commit configuration") print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close() return print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close()
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf') @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') @patch('paramiko.SSHClient') @patch('paramiko.proxy.ProxyCommand') def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy): os_mock.path.exists.return_value = True self.dev._sshconf_path = '/home/rsherman/.ssh/config' with SCP(self.dev) as scp: scp.get('addrbook.conf') mock_proxy.assert_called_any()
def load_merge_config(Deivces, config_file): for device in Deivces: try: dev = Device(host=device['host_IP'], user=device['usr'], passwd=device['pwd']) dev.open() except ConnectError as err: print(device['host_IP'] + ":Cannot connect to device: {0}".format(err)) return dev.bind(cu=Config) print(device['host_IP'] + ":Locking the configuration") try: dev.cu.lock() except LockError as err: print(device['host_IP'] + ":Unable to lock configuration: {0}".format(err)) dev.close() return print(device['host_IP'] + "::Loading configuration changes") try: dev.cu.load(path=config_file, merge=True) except (ConfigLoadError, Exception) as err: print(device['host_IP'] + ":Unable to load configuration changes: {0}".format(err)) print(device['host_IP'] + ":Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print(device['host_IP'] + ":Unable to unlock configuration: {0}".format(err)) dev.close() return print(device['host_IP'] + ":Committing the configuration") try: dev.cu.commit() except CommitError as err: print(device['host_IP'] + ":Unable to commit configuration: {0}".format(err)) print(device['host_IP'] + ":Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print(device['host_IP'] + ":Unable to unlock configuration: {0}".format(err)) dev.close() return print(device['host_IP'] + ":Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print(device['host_IP'] + ":Unable to unlock configuration: {0}".format(err)) dev.close() return
def main(argv): sys.stdout.write("commitment\n\n") if len(sys.argv) != 2: sys.stdout.write("Error: Missing parameter\n") sys.stdout.write("Usage: commitment.py <device-list.txt>\n") sys.exit() username = raw_input('Username: '******'Password (leave blank to use SSH Key): ') hostsfile = open(str(sys.argv[1]),'r') for address in hostsfile: if password != '': dev = Device(host=address.rstrip('\n'),user=username,passwd=password) else: dev = Device(host=address.rstrip('\n'),user=username) print "Opening :" + str(dev.hostname) dev.open() print "Opened :" + str(dev.hostname) print "Opening config" dev.bind(cf=Config) print "Locking config" dev.cf.lock() print "Committing config" dev.cf.commit() print "Unlocking config" dev.cf.unlock print "Closing: " + str(dev.hostname) dev.close() print "Closed :" + str(dev.hostname) hostsfile.close()
def main(argv): sys.stdout.write("commitment\n\n") if len(sys.argv) != 2: sys.stdout.write("Error: Missing parameter\n") sys.stdout.write("Usage: commitment.py <device-list.txt>\n") sys.exit() username = raw_input('Username: '******'Password (leave blank to use SSH Key): ') hostsfile = open(str(sys.argv[1]), 'r') for address in hostsfile: if password != '': dev = Device(host=address.rstrip('\n'), user=username, passwd=password) else: dev = Device(host=address.rstrip('\n'), user=username) print "Opening :" + str(dev.hostname) dev.open() print "Opened :" + str(dev.hostname) print "Opening config" dev.bind(cf=Config) print "Locking config" dev.cf.lock() print "Committing config" dev.cf.commit() print "Unlocking config" dev.cf.unlock print "Closing: " + str(dev.hostname) dev.close() print "Closed :" + str(dev.hostname) hostsfile.close()
def main(): # open a connection with the device and start a NETCONF session try: dev = Device(host=host,user=user,ssh_private_key_file=privateKey) print ("Connecting...") dev.open() print ("Connected.") dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print ("Locking the configuration") dev.cu.lock() print ("Loading configuration changes") #dev.cu.load(path=conf_file, merge=True) dev.cu.load(cmd, merge=True) print ("Diff") dev.cu.pdiff() print ("Committing the configuration") dev.cu.commit(comment='Loaded by example.') print ("Unlocking the configuration") dev.cu.unlock() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) except LockError as err: print ("Unable to lock configuration: {0}".format(err)) except (ConfigLoadError, Exception) as err: print ("Unable to load configuration changes: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print ("Unable to unlock configuration: {0}".format(err)) except CommitError as err: print ("Unable to commit configuration: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) # End the NETCONF session and close the connection dev.close()
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config()
def fnWriteToDevice(sConfiguration): logging.debug("fnWriteToDevice:") hDev = Device() hDev.open() hDev.bind(sCu=Config) # # Lock the configuration, load configuration changes, and commit # logging.info("fnWriteToDevice: Locking the configuration") # try: # sCu.lock() # logging.debug("fnWriteToDevice: Configuration Locked") # except LockError: # logging.debug("fnWriteToDevice: Error: Unable to lock configuration") # hDev.close() # return # # logging.info("fnWriteToDevice: Loading configuration changes") # try: # sCu.load(sConfiguration, format = "set", ignore_warning="statement not found") # logging.debug("fnWriteToDevice: Configuration Loaded") # except ConfigLoadError as err: # logging.debug("fnWriteToDevice: " + err) # logging.debug("fnWriteToDevice: UNABLE TO LOAD CONFIGURATION CHANGES:") # logging.debug("fnWriteToDevice: UNLOCKING THE CONFIGURATION") # try: # sCu.unlock() # logging.debug("fnWriteToDevice: Unlocking from Load Failure") # except UnlockError: # logging.debug("fnWriteToDevice: Error: Unable to unlock configuration from Load Failure") # sDev.close() # return # # logging.info("fnWriteToDevice: Committing the configuration") # try: # hDev.sCu.commit() # logging.debug("fnWriteToDevice: Commiting Configuration") # logging.debug("fnWriteToDevice: " + sConfiguration) # except CommitError: # logging.debug("fnWriteToDevice: Error: Unable to commit configuration") # try: # sCu.unlock() # logging.debug("fnWriteToDevice: Unlocking from Commit Failure") # except UnlockError: # logging.debug("fnWriteToDevice: Error: Unable to unlock configuration from Commit Failure") # hDev.close() # logging.debug("fnWriteToDevice: Close Device Connection") # return # # logging.debug("fnWriteToDevice: Unlocking the configuration") # try: # hDev.sCu.unlock() # logging.debug("fnWriteToDevice: Unlocking configuration") # except UnlockError: # logging.debug("fnWriteToDevice: Error: Unable to unlock configuration") # hdev.close() return
def rollback(hostname): dev = Device(hostname, user='******', password='******') dev.open(gather_facts=False) dev.timeout = 60 dev.bind(cu=Config) with Config(dev, mode='private') as cu: cu.rollback(1) cu.commit() print('{} - Done'.format(hostname)) dev.close()
def customize(hostip, switchvars, templatefile="access_switch.j2"): dev = Device(user="******", host=hostip, password="******") dev.open() dev.bind(cu=Config) dev.cu print "Loading template onto: {0} (SN: {1}) @ {2}".format(switchvars['hostname'], switchvars['serial_number'], switchvars['mgmt_ip']) dev.cu.load(template_path=templatefile, template_vars=switchvars, format="set") dev.cu.commit() dev.close()
def groups_apply_by_cli(hostname, username, password, cli): # open a connection with the device and start a NETCONF session try: dev = Device(host=hostname, username=username, password=password) dev.open() dev.timeout = 300 except ConnectError as err: print("Cannot connect to device: {0}".format(err)) return dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print("Locking the configuration") try: dev.cu.lock() except LockError as err: print("Unable to lock configuration: {0}".format(err)) dev.close() return try: dev.cu.load(cli, format='set', ignore_warning=True) dev.cu.pdiff() except (ConfigLoadError, Exception) as err: print("Unable to load configuration changes: {0}".format(err)) print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Unable to unlock configuration: {0}".format(err)) dev.close() return print("Committing the configuration") try: dev.cu.commit_check() dev.cu.commit(confirm=1, comment='Apply service group configurations') dev.cu.commit( comment='Confirm commit by PyEZ SQT Auto-provisioning Tool.', timeout=60) except CommitError as err: print("Unable to commit configuration: {0}".format(err)) print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print("Unable to unlock configuration: {0}".format(err)) dev.close() return print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print("Unable to unlock configuration: {0}".format(err)) # End the NETCONF session and close the connection dev.close()
def main(): # open a connection with the device and start a NETCONF session try: dev = Device(host=host,user=user,password=password) dev.open() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) return dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print ("Locking the configuration") try: dev.cu.lock() except LockError as err: print ("Unable to lock configuration: {0}".format(err)) dev.close() return print ("Loading configuration changes") try: dev.cu.load(path=conf_file, merge=True) except (ConfigLoadError, Exception) as err: print ("Unable to load configuration changes: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print ("Unable to unlock configuration: {0}".format(err)) dev.close() return print ("Committing the configuration") try: dev.cu.commit(comment='Loaded by example.') except CommitError as err: print ("Unable to commit configuration: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) dev.close() return print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) # End the NETCONF session and close the connection dev.close()
def commit_config(device, config_text): dev = Device(host=device, user=username, password=password) dev.open() dev.bind(cfg=Config) try: dev.cfg.load(config_text, format="set", merge=True) except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') return "Error:", rpc_msg dev.cfg.commit() dev.close() return
def main(): print 'Start configuration building' # YAML file. with open(options.data) as fh: data = yaml.load(fh.read()) # Jinja2 template file. with open(options.template) as t_fh: t_format = t_fh.read() for device in data: hostname = device[options.key] print ' * Start updating ' + hostname logger.info('Start updating %s', hostname) template = Template(t_format) jdev = Device(host=hostname, user=options.username, password=options.password, gather_facts=False) jdev.open() print " * Connected to " + hostname logger.info('connected to %s', hostname) jdev.bind(cu=Config) # Execute Rollback to prevent commit change from old config session jdev.cu.rollback() rsp = jdev.cu.load(template_path=options.template, template_vars=device) # Display some informations - Configuration Diff # Only if verbose Mode is enable if (options.verbose): print delimiter_tab + " * Configuration Diff is :" for diff in cleanup_answer(jdev.cu.diff()): print delimiter_tab + diff # Apply changes if options.safe is not enable. Protect user aginst script error. In case of test, user can emulate script and change w/out impact production if options.safe is True: print delimiter_tab + ' ** Running in dry-run mode, commit aborted' logger.info( 'Running in DRY-RUN mode, commit aborted and rollback to previsous stage' ) # Execute Rollback to prevent change are loaded and not discraded before next config change jdev.cu.rollback() else: rsp = jdev.cu.commit() print delimiter_tab + " * Commit Complete" logger.warning('Dry-run disable, commit complete') print("") print 'End of Script'
def customize(hostip, switchvars, templatefile="access_switch.j2"): dev = Device(user="******", host=hostip, password="******") dev.open() dev.bind(cu=Config) dev.cu print "Loading template onto: {0} (SN: {1}) @ {2}".format( switchvars['hostname'], switchvars['serial_number'], switchvars['mgmt_ip']) dev.cu.load(template_path=templatefile, template_vars=switchvars, format="set") dev.cu.commit() dev.close()
def push(hostname, config): if args.pp: print(config) else: dev = Device(hostname, user='******', password='******') dev.open(gather_facts=False) dev.timeout = 60 dev.bind(cu=Config) with Config(dev, mode='private') as cu: rsp = cu.load(config, format='text', merge=True) diff = show_diff(cu) if diff: print(diff) # commit(cu) cu.rollback()
class Manager(): def __init__(self,host,user,password): self.dev = Device(host=host,user=user,password=password) self.dev.bind(cu=Config) def open(self): try: self.dev.open() print "Connection Open" except Exception as err: print err def close(self): try: self.dev.close() print "Connection Closed" except Exception as err: print err def get_facts(self): pprint(self.dev.facts) def open_config(self,type): try: #attempt to open a configuration output = self.dev.rpc("<open-configuration><{0}/></open-configuration>".format(type)) print "Open {0} configuration".format(type) except Exception as err: #output an error if the configuration is not availble print err def load_config_template(self,template,template_vars): new_template = Template(template) final_template = new_template.render(template_vars) try: output = self.dev.cu.load(final_template,format="text",merge=True) print "Load Complete" except Exception as err: print err def commit_config(self): try: self.dev.rpc.commit_configuration() self.dev.rpc.close_configuration() print "Commit Complete" except Exception as err: print err
def provision_junos(port, username, password): device = Device('127.0.0.1', user=username, port=port) device.open() device.bind(cu=Config) with open('../junos/initial.conf', 'r') as f: configuration = f.read() device.cu.load(configuration, format='text', overwrite=True) try: device.cu.commit() device.close() except jnpr.junos.exception.RpcTimeoutError: # This actually means everything went fine print_info_message()
def main(): dev = Device(host='172.27.0.159',user='******',password='******') # open a connection with the device and start a NETCONF session try: dev.open() except Exception as err: print "Cannot connect to device:", err return dev.bind( cu=Config ) # Lock the configuration, load configuration changes, and commit print "Locking the configuration" try: dev.cu.lock() except LockError: print "Error: Unable to lock configuration" dev.close() return print "configuring" set_cmd = 'set system login message "Hello, Just testing Python!"' print "loading config" dev.cu.load(set_cmd, format='set') print "Committing the configuration" # commit the configuration try: dev.cu.commit() except CommitError: print "Error: Unable to commit configuration" print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" dev.close() return print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" dev.close()
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf') @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') @patch('paramiko.SSHClient') @patch('paramiko.proxy.ProxyCommand') def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy): os_mock.path.exists.return_value = True self.dev._sshconf_path = '/home/rsherman/.ssh/config' with SCP(self.dev) as scp: scp.get('addrbook.conf') mock_proxy.assert_called_any() def test_scp_progress(self): scp = SCP(self.dev) print scp._scp_progress('test', 100, 50) @contextmanager def capture(self, command, *args, **kwargs): out, sys.stdout = sys.stdout, StringIO() command(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() sys.stdout = out
def main(): print 'Start configuration building' # YAML file. with open( options.data ) as fh: data = yaml.load( fh.read() ) # Jinja2 template file. with open( options.template ) as t_fh: t_format = t_fh.read() for device in data: hostname = device[ options.key ] print ' * Start updating '+hostname logger.info('Start updating %s',hostname) template = Template( t_format ) jdev = Device( host=hostname , user=options.username , password=options.password , gather_facts=False) jdev.open() print " * Connected to "+ hostname logger.info('connected to %s',hostname) jdev.bind( cu=Config ) # Execute Rollback to prevent commit change from old config session jdev.cu.rollback() rsp = jdev.cu.load( template_path = options.template, template_vars = device) # Display some informations - Configuration Diff # Only if verbose Mode is enable if( options.verbose ): print delimiter_tab+" * Configuration Diff is :" for diff in cleanup_answer( jdev.cu.diff() ): print delimiter_tab+diff # Apply changes if options.safe is not enable. Protect user aginst script error. In case of test, user can emulate script and change w/out impact production if options.safe is True: print delimiter_tab+' ** Running in dry-run mode, commit aborted' logger.info('Running in DRY-RUN mode, commit aborted and rollback to previsous stage') # Execute Rollback to prevent change are loaded and not discraded before next config change jdev.cu.rollback() else: rsp = jdev.cu.commit() print delimiter_tab+" * Commit Complete" logger.warning('Dry-run disable, commit complete') print ("") print 'End of Script'
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf')
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertIsNone(self.dev.scp.close()) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf')
def upload_config(obj, config_path, vsrx_ip, vsrx_user, vsrx_pass): """Upload and commit configuration for VSRX. :param obj: test case object :type obj: object :param config_path: path to vsrx conf file :type config_path: string :param vsrx_ip: vsrx ip address :type vsrx_ip: string :param vsrx_user: username for vsrx :type vsrx_user: string :param vsrx_pass: password for vsrx :type vsrx_pass: string """ jun_gw = Device(host=vsrx_ip, user=vsrx_user, password=vsrx_pass) for i in range(10): try: jun_gw.open() except ConnectTimeoutError: time.sleep(15) continue else: break else: logger.info("Configuration of vsrx failed. Check router") return False jun_gw.bind(cu=Config) logger.info("Loading config file") jun_gw.cu.load(path=config_path) logger.info("Checking configuration...") if jun_gw.cu.commit_check(): logger.info("New config was verified") jun_gw.cu.commit() logger.info("New config was commited") else: logger.info("Wrong configuration") jun_gw.cu.rollback() jun_gw.close()
def upgrade_os(): upgrade_host = request.form.getlist('upgrade_srx') reboot_list = request.form.getlist('optradio') file = request.files['file'] filename = secure_filename(file.filename) print "Upgrade hosts are: ", upgrade_host print "Reboot options are: ", reboot_list print "Upgrade image: ", filename print "update_list", update_list for i in upgrade_host: for j in update_list: if i in j: hostname = j[0] usr = j[1] psswd = j[2] dev = Device(hostname, user=usr, password=psswd) dev.open() dev.bind(sw=SW) upgrade_file = "images/"+filename flash(dev.sw.install(package = upgrade_file, progress = my_progress)) return render_template('/add_device.html')
def addconfig(Config_File): dev = Device(host=hostName, user=uName, password=uPass) dev.open() dev.bind(cu=Config) print("#=" * 40) print("binding the device to configuration mode") print("#=" * 40) try: # Lock the configuration, load configuration changes, and commit dev.cu.lock() print("Strep:1 ==> Locking the configuration") except LockError as err: dev.close() print("Step:1 ==> Unable to lock configuration: {0}".format(err)) try: dev.cu.load(template_path=Config_File, format="set", merge=True) print( "Step2: ==> Loading configuration changes : Adding command for Routing Engine Redundancy" ) except (ConfigLoadError, Exception) as err: print( "Step2: ==> Unable to load configuration changes: {0}".format(err)) try: dev.cu.commit(comment='Juniper JUNOS Device Upgrade') print( "Step3: ==> Committing the configuration : Routing Engine Redundancy Commands Added" ) except CommitError as err: print("Step3: ==> Unable to commit configuration: {0}".format(err)) try: dev.cu.unlock() print("Step4: ==> Unlocking the configuration") except UnlockError as err: print("Step4: ==> Unable to unlock configuration: {0}".format(err)) dev.close()
def push(hostname, config): if args.pp: print(config) else: dev = Device(hostname, user='******', password='******') dev.open(gather_facts=False) dev.timeout = 60 dev.bind(cu=Config) with Config(dev, mode='private') as cu: cu.load( 'delete policy-options policy-statement EVPN-host-routes term default' ) cu.load(config, format='text', merge=True) cu.load( 'set policy-options policy-statement EVPN-host-routes term default then reject' ) diff = show_diff(cu) if diff: print(diff) commit(cu) #cu.rollback() dev.close()
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.config_replace = False self.locked = False if optional_args is None: optional_args = {} self.port = optional_args.get('port', 22) self.config_lock = optional_args.get('config_lock', True) self.device = Device(hostname, user=username, password=password, port=self.port) def open(self): try: self.device.open() except ConnectTimeoutError as cte: raise ConnectionException(cte.message) self.device.timeout = self.timeout self.device.bind(cu=Config) if self.config_lock: self.lock() def close(self): if self.config_lock: self.unlock() self.device.close() def lock(self): if not self.locked: self.device.cu.lock() self.locked = True def unlock(self): if self.locked: self.device.cu.unlock() self.locked = False def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() if not self.config_lock: # if not locked during connection time # will try to lock it if not already aquired self.lock() # and the device will be locked till first commit/rollback try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff.strip() def commit_config(self): self.device.cu.commit() if not self.config_lock: self.unlock() def discard_config(self): self.device.cu.rollback(rb_id=0) if not self.config_lock: self.unlock() def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config() # perhaps both should be moved in napalm_base.helpers at some point @staticmethod def _find_txt(xml_tree, path, default = ''): try: return xml_tree.find(path).text.strip() except Exception: return default @staticmethod def _convert(to, who, default = u''): if who is None: return default try: return to(who) except: return default def get_facts(self): output = self.device.facts uptime = 0 if 'RE0' in output: uptime = output['RE0']['up_time'] interfaces = junos_views.junos_iface_table(self.device) interfaces.get() interface_list = interfaces.keys() return { 'vendor': u'Juniper', 'model': unicode(output['model']), 'serial_number': unicode(output['serialnumber']), 'os_version': unicode(output['version']), 'hostname': unicode(output['hostname']), 'fqdn': unicode(output['fqdn']), 'uptime': string_parsers.convert_uptime_string_seconds(uptime), 'interface_list': interface_list } def get_interfaces(self): # init result dict result = {} interfaces = junos_views.junos_iface_table(self.device) interfaces.get() # convert all the tuples to our pre-defined dict structure for iface in interfaces.keys(): result[iface] = { 'is_up': interfaces[iface]['is_up'], 'is_enabled': interfaces[iface]['is_enabled'], 'description': (interfaces[iface]['description'] or u''), 'last_flapped': float((interfaces[iface]['last_flapped'] or -1)), 'mac_address': unicode((interfaces[iface]['mac_address'] or '')), 'speed': -1 } # result[iface]['last_flapped'] = float(result[iface]['last_flapped']) match = re.search(r'(\d+)(\w*)', interfaces[iface]['speed'] or u'') if match is None: continue speed_value = self._convert(int, match.group(1), -1) if speed_value == -1: continue speed_unit = match.group(2) if speed_unit.lower() == 'gbps': speed_value *= 1000 result[iface]['speed'] = speed_value return result def get_interfaces_counters(self): query = junos_views.junos_iface_counter_table(self.device) query.get() interface_counters = dict() for interface, counters in query.items(): interface_counters[interface] = {k: v if v is not None else -1 for k, v in counters} return interface_counters def get_environment(self): environment = junos_views.junos_enviroment_table(self.device) routing_engine = junos_views.junos_routing_engine_table(self.device) temperature_thresholds = junos_views.junos_temperature_thresholds(self.device) environment.get() routing_engine.get() temperature_thresholds.get() environment_data = dict() for sensor_object, object_data in environment.items(): structured_object_data = {k: v for k, v in object_data} if structured_object_data['class'] == 'Power': # Create a dict for the 'power' key try: environment_data['power'][sensor_object] = dict() except KeyError: environment_data['power'] = dict() environment_data['power'][sensor_object] = dict() # Set these values to -1, because Junos does not provide them environment_data['power'][sensor_object]['capacity'] = -1.0 environment_data['power'][sensor_object]['output'] = -1.0 if structured_object_data['class'] == 'Fans': # Create a dict for the 'fans' key try: environment_data['fans'][sensor_object] = dict() except KeyError: environment_data['fans'] = dict() environment_data['fans'][sensor_object] = dict() if structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Power': # If status is Failed, Absent or Testing, set status to False. environment_data['power'][sensor_object]['status'] = True elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Power': environment_data['power'][sensor_object]['status'] = False elif structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Fans': # If status is Failed, Absent or Testing, set status to False. environment_data['fans'][sensor_object]['status'] = True elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Fans': environment_data['fans'][sensor_object]['status'] = False for temperature_object, temperature_data in temperature_thresholds.items(): structured_temperature_data = {k: v for k, v in temperature_data} if structured_object_data['class'] == 'Temp': # Create a dict for the 'temperature' key try: environment_data['temperature'][sensor_object] = dict() except KeyError: environment_data['temperature'] = dict() environment_data['temperature'][sensor_object] = dict() environment_data['temperature'][sensor_object]['temperature'] = float(structured_object_data['temperature']) # Set a default value (False) to the key is_critical and is_alert environment_data['temperature'][sensor_object]['is_alert'] = False environment_data['temperature'][sensor_object]['is_critical'] = False # Check if the working temperature is equal to or higher than alerting threshold if structured_temperature_data['red-alarm'] <= structured_object_data['temperature']: environment_data['temperature'][sensor_object]['is_critical'] = True environment_data['temperature'][sensor_object]['is_alert'] = True elif structured_temperature_data['yellow-alarm'] <= structured_object_data['temperature']: environment_data['temperature'][sensor_object]['is_alert'] = True for routing_engine_object, routing_engine_data in routing_engine.items(): structured_routing_engine_data = {k: v for k, v in routing_engine_data} # Create dicts for 'cpu' and 'memory'. try: environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() except KeyError: environment_data['cpu'] = dict() environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() # Calculate the CPU usage by using the CPU idle value. environment_data['cpu'][routing_engine_object]['%usage'] = 100.0 - structured_routing_engine_data['cpu-idle'] try: environment_data['memory']['available_ram'] = int(structured_routing_engine_data['memory-dram-size']) except ValueError: environment_data['memory']['available_ram'] = int(''.join(i for i in structured_routing_engine_data['memory-dram-size'] if i.isdigit())) # Junos gives us RAM in %, so calculation has to be made. # Sadly, bacause of this, results are not 100% accurate to the truth. environment_data['memory']['used_ram'] = (environment_data['memory']['available_ram'] / 100 * structured_routing_engine_data['memory-buffer-utilization']) return environment_data @staticmethod def _get_address_family(table): """ Function to derive address family from a junos table name :params table: The name of the routing table :returns: address family """ address_family_mapping = { 'inet': 'ipv4', 'inet6': 'ipv6' } family = table.split('.')[-2] return address_family_mapping[family] def _parse_route_stats(self, neighbor): data = {} if not neighbor['is_up']: pass elif isinstance(neighbor['tables'], list): for idx, table in enumerate(neighbor['tables']): family = self._get_address_family(table) data[family] = {} data[family]['received_prefixes'] = neighbor['received_prefixes'][idx] data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'][idx] data[family]['sent_prefixes'] = neighbor['sent_prefixes'][idx] else: family = self._get_address_family(neighbor['tables']) data[family] = {} data[family]['received_prefixes'] = neighbor['received_prefixes'] data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'] data[family]['sent_prefixes'] = neighbor['sent_prefixes'] return data @staticmethod def _parse_value(value): if isinstance(value, basestring): return unicode(value) elif value is None: return u'' else: return value def get_bgp_neighbors(self): instances = junos_views.junos_route_instance_table(self.device) uptime_table = junos_views.junos_bgp_uptime_table(self.device) bgp_neighbors = junos_views.junos_bgp_table(self.device) keys =['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id'] bgp_neighbor_data = {} for instance, instance_data in instances.get().items(): if instance.startswith('__'): # junos internal instances continue instance_name = "global" if instance == 'master' else instance bgp_neighbor_data[instance_name] = {'peers': {}} for neighbor, data in bgp_neighbors.get(instance=instance).items(): neighbor_data = {k: v for k, v in data} peer_ip = neighbor.split('+')[0] if 'router_id' not in bgp_neighbor_data[instance_name]: # we only need to set this once bgp_neighbor_data[instance_name]['router_id'] = unicode(neighbor_data['local_id']) peer = {key:self._parse_value(value) for key, value in neighbor_data.iteritems() if key in keys} peer['address_family'] = self._parse_route_stats(neighbor_data) bgp_neighbor_data[instance_name]['peers'][peer_ip] = peer for neighbor, uptime in uptime_table.get(instance=instance).items(): bgp_neighbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1] for key in bgp_neighbor_data.keys(): if not bgp_neighbor_data[key]['peers']: del bgp_neighbor_data[key] return bgp_neighbor_data def get_lldp_neighbors(self): lldp = junos_views.junos_lldp_table(self.device) lldp.get() result = lldp.items() neighbors = dict() for neigh in result: if neigh[0] not in neighbors.keys(): neighbors[neigh[0]] = list() neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]}) return neighbors def get_lldp_neighbors_detail(self, interface=''): lldp_neighbors = dict() lldp_table = junos_views.junos_lldp_neighbors_detail_table(self.device) lldp_table.get() interfaces = lldp_table.get().keys() old_junos = self._convert(int, self.device.facts.get('version', '0.0').split('.')[0], '0') < 13 lldp_table.GET_RPC = 'get-lldp-interface-neighbors' if old_junos: lldp_table.GET_RPC = 'get-lldp-interface-neighbors-information' for interface in interfaces: if old_junos: lldp_table.get(interface_name=interface) else: lldp_table.get(interface_device=interface) for item in lldp_table: if interface not in lldp_neighbors.keys(): lldp_neighbors[interface] = list() lldp_neighbors[interface].append({ 'parent_interface' : item.parent_interface, 'remote_port' : item.remote_port, 'remote_chassis_id' : item.remote_chassis_id, 'remote_port' : item.remote_port, 'remote_port_description' : item.remote_port_description, 'remote_system_name' : item.remote_system_name, 'remote_system_description' : item.remote_system_description, 'remote_system_capab' : item.remote_system_capab, 'remote_system_enable_capab': item.remote_system_enable_capab }) return lldp_neighbors def cli(self, commands = None): cli_output = dict() if type(commands) is not list: raise TypeError('Please enter a valid list of commands!') for command in commands: try: cli_output[unicode(command)] = unicode(self.device.cli(command)) except Exception as e: cli_output[unicode(command)] = 'Unable to execute command "{cmd}": {err}'.format( cmd = command, err = e ) raise CommandErrorException(str(cli_output)) return cli_output def get_bgp_config(self, group='', neighbor=''): def update_dict(d, u): # for deep dictionary update for k, v in u.iteritems(): if isinstance(d, collections.Mapping): if isinstance(v, collections.Mapping): r = update_dict(d.get(k, {}), v) d[k] = r else: d[k] = u[k] else: d = {k: u[k]} return d def build_prefix_limit(**args): """ This helper will transform the lements of a dictionary into nested dictionaries: Example: { 'inet_unicast_limit': 500, 'inet_unicast_teardown_threshold': 95, 'inet_unicast_teardown_timeout': 5 } becomes: { 'inet': { 'unicast': { 'limit': 500, 'teardown': { 'threshold': 95, 'timeout': 5 } } } } """ prefix_limit = dict() for key, value in args.iteritems(): key_levels = key.split('_') length = len(key_levels)-1 temp_dict = { key_levels[length]: value } for index in reversed(range(length)): level = key_levels[index] temp_dict = {level: temp_dict} update_dict(prefix_limit, temp_dict) return prefix_limit _COMMON_FIELDS_DATATYPE_ = { 'description': unicode, 'local_address': unicode, 'local_as': int, 'remote_as': int, 'import_policy': unicode, 'export_policy': unicode, 'inet_unicast_limit_prefix_limit': int, 'inet_unicast_teardown_threshold_prefix_limit': int, 'inet_unicast_teardown_timeout_prefix_limit': int, 'inet_unicast_novalidate_prefix_limit': int, 'inet_flow_limit_prefix_limit': int, 'inet_flow_teardown_threshold_prefix_limit': int, 'inet_flow_teardown_timeout_prefix_limit': int, 'inet_flow_novalidate_prefix_limit': unicode, 'inet6_unicast_limit_prefix_limit': int, 'inet6_unicast_teardown_threshold_prefix_limit': int, 'inet6_unicast_teardown_timeout_prefix_limit': int, 'inet6_unicast_novalidate_prefix_limit': int, 'inet6_flow_limit_prefix_limit': int, 'inet6_flow_teardown_threshold_prefix_limit': int, 'inet6_flow_teardown_timeout_prefix_limit': int, 'inet6_flow_novalidate_prefix_limit': unicode, } _PEER_FIELDS_DATATYPE_MAP_ = { 'group': unicode, 'authentication_key': unicode, 'route_reflector_client': bool, 'nhs': bool } _PEER_FIELDS_DATATYPE_MAP_.update( _COMMON_FIELDS_DATATYPE_ ) _GROUP_FIELDS_DATATYPE_MAP_ = { 'type': unicode, 'apply_groups': list, 'remove_private_as': bool, 'multipath': bool, 'multihop_ttl': int } _GROUP_FIELDS_DATATYPE_MAP_.update( _COMMON_FIELDS_DATATYPE_ ) _DATATYPE_DEFAULT_ = { unicode: u'', int: 0, bool: False, list: [] } bgp_config = dict() if group: bgp = junos_views.junos_bgp_config_group_table(self.device) bgp.get(group = group) else: bgp = junos_views.junos_bgp_config_table(self.device) bgp.get() neighbor = '' # if no group is set, no neighbor should be set either bgp_items = bgp.items() peers = junos_views.junos_bgp_config_peers_table(self.device) peers.get() # unfortunately cannot add filters for group name of neighbor address peers_items = peers.items() bgp_neighbors = dict() for bgp_group_neighbor in peers_items: bgp_peer_address = bgp_group_neighbor[0] if neighbor and bgp_peer_address != neighbor: continue # if filters applied, jump over all other neighbors bgp_group_details = bgp_group_neighbor[1] bgp_peer_details = { field: _DATATYPE_DEFAULT_.get(datatype) \ for field, datatype in _PEER_FIELDS_DATATYPE_MAP_.iteritems() \ if '_prefix_limit' not in field } for elem in bgp_group_details: if not('_prefix_limit' not in elem[0] and elem[1] is not None): continue datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) key = elem[0] value = elem[1] if key in ['export_policy', 'import_policy']: if isinstance(value, list): value = ' '.join(value) bgp_peer_details.update({ key: self._convert(datatype, value, default) }) prefix_limit_fields = dict() for elem in bgp_group_details: if '_prefix_limit' in elem[0] and elem[1] is not None: datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) prefix_limit_fields.update({ elem[0].replace('_prefix_limit', ''): self._convert(datatype, elem[1], default) }) bgp_peer_details['prefix_limit'] = build_prefix_limit(**prefix_limit_fields) # and all these things only because PyEZ cannto convert to a specifc datatype when retrieving config... group = bgp_peer_details.pop('group') if group not in bgp_neighbors.keys(): bgp_neighbors[group] = dict() bgp_neighbors[group][bgp_peer_address] = bgp_peer_details if neighbor and bgp_peer_address == neighbor: break # found the desired neighbor for bgp_group in bgp_items: bgp_group_name = bgp_group[0] bgp_group_details = bgp_group[1] bgp_config[bgp_group_name] = { field: _DATATYPE_DEFAULT_.get(datatype) \ for field, datatype in _GROUP_FIELDS_DATATYPE_MAP_.iteritems() \ if '_prefix_limit' not in field } for elem in bgp_group_details: if not('_prefix_limit' not in elem[0] and elem[1] is not None): continue datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) key = elem[0] value = elem[1] if key in ['export_policy', 'import_policy']: if isinstance(value, list): value = ' '.join(value) bgp_config[bgp_group_name].update({ key: self._convert(datatype, value, default) }) prefix_limit_fields = dict() for elem in bgp_group_details: if '_prefix_limit' in elem[0] and elem[1] is not None: datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) prefix_limit_fields.update({ elem[0].replace('_prefix_limit', ''): self._convert(datatype, elem[1], default) }) bgp_config[bgp_group_name]['prefix_limit'] = build_prefix_limit(**prefix_limit_fields) bgp_config[bgp_group_name]['neighbors'] = bgp_neighbors.get(bgp_group_name, {}) return bgp_config def get_bgp_neighbors_detail(self, neighbor_address = ''): bgp_neighbors = dict() bgp_neighbors_table = junos_views.junos_bgp_neighbors_table(self.device) bgp_neighbors_table.get( neighbor_address = neighbor_address ) bgp_neighbors_items = bgp_neighbors_table.items() default_neighbor_details = { 'up' : False, 'local_as' : 0, 'remote_as' : 0, 'local_address' : u'', 'routing_table' : u'', 'local_address_configured' : False, 'local_port' : 0, 'remote_address' : u'', 'remote_port' : 0, 'multihop' : False, 'multipath' : False, 'remove_private_as' : False, 'import_policy' : u'', 'export_policy' : u'', 'input_messages' : 0, 'output_messages' : 0, 'input_updates' : 0, 'output_updates' : 0, 'messages_queued_out' : 0, 'connection_state' : u'', 'previous_connection_state' : u'', 'last_event' : u'', 'suppress_4byte_as' : False, 'local_as_prepend' : False, 'holdtime' : 0, 'configured_holdtime' : 0, 'keepalive' : 0, 'configured_keepalive' : 0, 'active_prefix_count' : 0, 'received_prefix_count' : 0, 'accepted_prefix_count' : 0, 'suppressed_prefix_count' : 0, 'advertise_prefix_count' : 0, 'flap_count' : 0 } _OPTION_KEY_MAP_ = { 'RemovePrivateAS': 'remove_private_as', 'Multipath' : 'multipath', 'Multihop' : 'multihop', 'AddressFamily' : 'local_address_configured' # 'AuthKey' : 'authentication_key_set' # but other vendors do not specify if auth key is set # other options: # Preference, HoldTime, Ttl, LogUpDown, Refresh } for bgp_neighbor in bgp_neighbors_items: remote_as = int(bgp_neighbor[0]) if remote_as not in bgp_neighbors.keys(): bgp_neighbors[remote_as] = list() neighbor_details = default_neighbor_details.copy() neighbor_details.update( {elem[0]: elem[1] for elem in bgp_neighbor[1] if elem[1] is not None} ) options = neighbor_details.pop('options', '') if isinstance(options, str): options_list = options.split() for option in options_list: key = _OPTION_KEY_MAP_.get(option) if key is None: continue neighbor_details[key] = True four_byte_as = neighbor_details.pop('4byte_as', 0) local_address = neighbor_details.pop('local_address', '') local_details = local_address.split('+') neighbor_details['local_address'] = unicode(local_details[0]) if len(local_details) == 2: neighbor_details['local_port']= int(local_details[1]) else: neighbor_details['local_port']=179 neighbor_details['suppress_4byte_as'] = (remote_as != four_byte_as) peer_address = neighbor_details.pop('peer_address', '') remote_details = peer_address.split('+') neighbor_details['remote_address'] = unicode(remote_details[0]) if len(remote_details) == 2: neighbor_details['remote_port'] = int(remote_details[1]) else: neighbor_details['remote_port'] = 179 bgp_neighbors[remote_as].append(neighbor_details) return bgp_neighbors def get_arp_table(self): # could use ArpTable # from jnpr.junos.op.phyport import ArpTable # and simply use it # but # we need: # - filters # - group by VLAN ID # - hostname & TTE fields as well arp_table = list() arp_table_raw = junos_views.junos_arp_table(self.device) arp_table_raw.get() arp_table_items = arp_table_raw.items() for arp_table_entry in arp_table_items: arp_entry = { elem[0]: elem[1] for elem in arp_table_entry[1] } tte = arp_entry.pop('tte') arp_entry['age'] = tte # must compute age based on TTE arp_table.append(arp_entry) return arp_table def get_ntp_peers(self): ntp_table = junos_views.junos_ntp_peers_config_table(self.device) ntp_table.get() ntp_peers = ntp_table.items() if not ntp_peers: return {} return {unicode(peer[0]):{} for peer in ntp_peers} def get_ntp_stats(self): # NTP Peers does not have XML RPC defined # thus we need to retrieve raw text and parse... # :( ntp_stats = list() REGEX = ( '^\s?(\+|\*|x|-)?([a-zA-Z0-9\.+-:]+)' '\s+([a-zA-Z0-9\.]+)\s+([0-9]{1,2})' '\s+(-|u)\s+([0-9h-]+)\s+([0-9]+)' '\s+([0-9]+)\s+([0-9\.]+)\s+([0-9\.-]+)' '\s+([0-9\.]+)\s?$' ) ntp_assoc_output = self.device.cli('show ntp associations no-resolve') ntp_assoc_output_lines = ntp_assoc_output.splitlines() for ntp_assoc_output_line in ntp_assoc_output_lines[3:]: #except last line line_search = re.search(REGEX, ntp_assoc_output_line, re.I) if not line_search: continue # pattern not found line_groups = line_search.groups() try: ntp_stats.append({ 'remote' : unicode(line_groups[1]), 'synchronized' : (line_groups[0] == '*'), 'referenceid' : unicode(line_groups[2]), 'stratum' : int(line_groups[3]), 'type' : unicode(line_groups[4]), 'when' : unicode(line_groups[5]), 'hostpoll' : int(line_groups[6]), 'reachability' : int(line_groups[7]), 'delay' : float(line_groups[8]), 'offset' : float(line_groups[9]), 'jitter' : float(line_groups[10]) }) except Exception: continue # jump to next line return ntp_stats def get_interfaces_ip(self): interfaces_ip = dict() interface_table = junos_views.junos_ip_interfaces_table(self.device) interface_table.get() interface_table_items = interface_table.items() _FAMILY_VMAP_ = { 'inet' : u'ipv4', 'inet6' : u'ipv6' # can add more mappings } for interface_details in interface_table_items: try: ip_address = interface_details[0] address = unicode(ip_address.split('/')[0]) prefix = self._convert(int, ip_address.split('/')[-1], 0) interface = unicode(interface_details[1][0][1]) family_raw = interface_details[1][1][1] family = _FAMILY_VMAP_.get(family_raw) if not family: continue if interface not in interfaces_ip.keys(): interfaces_ip[interface] = dict() if family not in interfaces_ip[interface].keys(): interfaces_ip[interface][family] = dict() if address not in interfaces_ip[interface][family].keys(): interfaces_ip[interface][family][address] = dict() interfaces_ip[interface][family][address][u'prefix_length'] = prefix except Exception: continue return interfaces_ip def get_mac_address_table(self): mac_address_table = list() mac_table = junos_views.junos_mac_address_table(self.device) mac_table.get() mac_table_items = mac_table.items() default_values = { 'mac' : u'', 'interface' : u'', 'vlan' : 0, 'static' : False, 'active' : True, 'moves' : 0, 'last_move' : 0.0 } for mac_table_entry in mac_table_items: mac_entry = default_values.copy() mac_entry.update( {elem[0]: elem[1] for elem in mac_table_entry[1]} ) mac_address_table.append(mac_entry) return mac_address_table def get_route_to(self, destination = '', protocol = ''): routes = {} if not isinstance(destination, str): raise TypeError('Please specify a valid destination!') if not isinstance(protocol, str) or protocol.lower() not in ['static', 'bgp', 'isis']: raise TypeError("Protocol not supported: {protocol}.".format( protocol = protocol )) protocol = protocol.lower() _COMMON_PROTOCOL_FIELDS_ = [ 'destination', 'prefix_length', 'protocol', 'current_active', 'last_active', 'age', 'next_hop', 'outgoing_interface', 'selected_next_hop', 'preference', 'inactive_reason', 'routing_table' ] # identifies the list of fileds common for all protocols _BOOLEAN_FIELDS_ = [ 'current_active', 'selected_next_hop', 'last_active' ] # fields expected to have boolean values _PROTOCOL_SPECIFIC_FIELDS_ = { 'bgp': [ 'local_as', 'remote_as', 'as_path', 'communities', 'local_preference', 'preference2', 'remote_address', 'metric', 'metric2' ], 'isis': [ 'level', 'metric', 'local_as' ] } routes_table = junos_views.junos_protocol_route_table(self.device) try: routes_table.get( destination=destination, protocol=protocol ) except RpcTimeoutError: # on devices with milions of routes # in case the destination is too generic (e.g.: 10/8) # will take very very long to determine all routes and # moreover will return a huge list raise CommandTimeoutException('Too many routes returned! Please try with a longer prefix!') except Exception as e: raise CommandErrorException('Cannot retrieve routes! Reason: {err}'.format(err = e)) routes_items = routes_table.items() for route in routes_items: d = dict() next_hop = route[0] d = {elem[0]: elem[1] for elem in route[1]} destination = d.pop('destination', '') prefix_length = d.pop('prefix_length', 32) destination = '{d}/{p}'.format( d=destination, p=prefix_length ) d.update({key: False for key in _BOOLEAN_FIELDS_ if d.get(key) is None}) as_path = d.get('as_path') if as_path is not None: d['as_path'] = as_path.split(' I ')[0].replace('AS path:', '').replace('I', '').strip() # to be sure that contains only AS Numbers if d.get('inactive_reason') is None: d['inactive_reason'] = u'' communities = d.get('communities') if communities is not None and type(communities) is not list: d['communities'] = [communities] d['next_hop'] = unicode(next_hop) d_keys = d.keys() # fields that are not in _COMMON_PROTOCOL_FIELDS_ are supposed to be protocol specific all_protocol_attributes = {key: d.pop(key) for key in d_keys if key not in _COMMON_PROTOCOL_FIELDS_} protocol_attributes = { key: value for key, value in all_protocol_attributes.iteritems() \ if key in _PROTOCOL_SPECIFIC_FIELDS_.get(protocol) } d['protocol_attributes'] = protocol_attributes if destination not in routes.keys(): routes[destination] = list() routes[destination].append(d) return routes def get_snmp_information(self): snmp_information = dict() _AUTHORIZATION_MODE_MAP_ = { 'read-only': u'ro', 'read-write': u'rw' } snmp_config = junos_views.junos_snmp_config_table(self.device) snmp_config.get() snmp_items = snmp_config.items() if not snmp_items: return snmp_information communities = list() for snmp_config_out in snmp_items: community_name = snmp_config_out[0] community_details = snmp_config_out[1] communities.append({ c[0]: c[1] for c in community_details }) snmp_information = { 'contact': self._convert(unicode, communities[0].get('contact')), 'location': self._convert(unicode, communities[0].get('location')), 'chassis_id': self._convert(unicode, communities[0].get('chassis')), 'community': {} } for snmp_entry in communities: name = self._convert(unicode, snmp_entry.get('name')) authorization = self._convert(unicode, snmp_entry.get('authorization')) snmp_information['community'][name] = { 'mode': _AUTHORIZATION_MODE_MAP_.get(authorization, u''), 'acl': u'' } return snmp_information def get_probes_config(self): probes = dict() probes_table = junos_views.junos_rpm_probes_config_table(self.device) probes_table.get() probes_table_items = probes_table.items() for probe_test in probes_table_items: test_name = unicode(probe_test[0]) test_details = { p[0]: p[1] for p in probe_test[1] } probe_name = self._convert(unicode, test_details.pop('probe_name')) target = self._convert(unicode, test_details.pop('target', '')) test_interval = self._convert(int, test_details.pop('test_interval', '0')) probe_count = self._convert(int, test_details.pop('probe_count', '0')) probe_type = self._convert(unicode, test_details.pop('probe_type', '')) source = self._convert(unicode, test_details.pop('source_address', '')) if probe_name not in probes.keys(): probes[probe_name] = dict() probes[probe_name][test_name] = { 'probe_type' : probe_type, 'target' : target, 'source' : source, 'probe_count' : probe_count, 'test_interval' : test_interval } return probes def get_probes_results(self): probes_results = dict() probes_results_table = junos_views.junos_rpm_probes_results_table(self.device) probes_results_table.get() probes_results_items = probes_results_table.items() for probe_result in probes_results_items: probe_name = unicode(probe_result[0]) test_results = { p[0]: p[1] for p in probe_result[1] } for test_param_name, test_param_value in test_results.iteritems(): if isinstance(test_param_value, float): test_results[test_param_name] = test_param_value * 1e-3 # convert from useconds to mseconds test_name = test_results.pop('test_name', '') source = test_results.get('source', u'') if source is None: test_results['source'] = u'' if probe_name not in probes_results.keys(): probes_results[probe_name] = dict() probes_results[probe_name][test_name] = test_results return probes_results def traceroute(self, destination, source='', ttl=0, timeout=0): traceroute_result = dict() # calling form RPC does not work properly :( # but defined junos_route_instance_table just in case source_str = '' maxttl_str = '' wait_str = '' if source: source_str = 'source {source}'.format(source=source) if ttl: maxttl_str = 'ttl {ttl}'.format(ttl=ttl) if timeout: wait_str = 'wait {timeout}'.format(timeout=timeout) traceroute_command = 'traceroute {destination} {source} {maxttl} {wait}'.format( destination=destination, source=source_str, maxttl=maxttl_str, wait=wait_str ) traceroute_rpc = E('command', traceroute_command) rpc_reply = self.device._conn.rpc(traceroute_rpc)._NCElement__doc # make direct RPC call via NETCONF traceroute_results = rpc_reply.find('.//traceroute-results') traceroute_success = traceroute_results.find('traceroute-success') traceroute_failure = self._find_txt(traceroute_results, 'traceroute-failure', '') error_message = self._find_txt(traceroute_results, 'rpc-error/error-message', '') error = '' if traceroute_failure and error_message: return {'error': '{}: {}'.format(traceroute_failure, error_message)} traceroute_result['success'] = dict() for hop in traceroute_results.findall('hop'): ttl_value = self._convert(int, self._find_txt(hop, 'ttl-value'), 1) if ttl_value not in traceroute_result['success']: traceroute_result['success'][ttl_value] = {'probes': {}} for probe in hop.findall('probe-result'): probe_index = self._convert(int, self._find_txt(probe, 'probe-index'), 0) ip_address = unicode(self._find_txt(probe, 'ip-address', u'*')) host_name = unicode(self._find_txt(probe, 'host-name', u'*')) rtt = self._convert(float, self._find_txt(probe, 'rtt'), 0) * 1e-3 # ms traceroute_result['success'][ttl_value]['probes'][probe_index] = { 'ip_address': ip_address, 'host_name': host_name, 'rtt': rtt } return traceroute_result def get_users(self): users = dict() _JUNOS_CLASS_CISCO_PRIVILEGE_LEVEL_MAP = { 'super-user': 15, 'superuser': 15, 'operator': 5, 'read-only': 1, 'unauthorized': 0 } _DEFAULT_USER_DETAILS = { 'level': 0, 'password': '', 'sshkeys': [] } users_table = junos_views.junos_users_table(self.device) users_table.get() users_items = users_table.items() for user_entry in users_items: username = user_entry[0] user_details = _DEFAULT_USER_DETAILS.copy() user_details.update({ d[0]: d[1] for d in user_entry[1] if d[1] }) user_class = user_details.pop('class', '') level = _JUNOS_CLASS_CISCO_PRIVILEGE_LEVEL_MAP.get(user_class, 0) user_details.update({ 'level': level }) user_details['sshkeys'] = [ user_details.pop(key) for key in ['ssh_rsa', 'ssh_dsa', 'ssh_ecdsa'] if user_details.get(key, '') ] users[username] = user_details return users
class EzncDriver(ngage.plugins.DriverPlugin): """ driver for junos-eznc pip install junos-eznc """ plugin_type = 'eznc' def _do_init(self): config = self.config self.host = config.get('host') self.port = config.get('port', 22) if not self.port: self.port = 22 self.user = config.get('user') self.password = config.get('password') self.dev = Device(self.host, port=self.port, user=self.user, password=self.password) def _do_open(self): try: self.dev.open() self.dev.bind(cu=Config) except ConnectAuthError: raise AuthenticationError def _do_close(self): self.dev.close() def _do_pull(self): options = {'format': 'text'} config = self.dev.rpc.get_config(filter_xml=None, options=options) config = config.text.encode('ascii', 'replace') return config def _do_push(self, fname, **kwargs): try: self.dev.cu.load(path=fname, format='text') # bogus exception on warnings except ConfigLoadError as e: errs = [] for err in e.errs: # skip warnings if not err['severity'] or err['severity'] == 'warning': continue # expand multiple errors split by newlines errs = errs + e.message.split('\n') if errs: if len(errs) == 1: raise ConfigError(errs[0]) else: raise ConfigError(errs) def _do_diff(self, index=0): return self.dev.cu.diff(index) def _do_lock(self): self.dev.cu.lock() def _do_unlock(self): self.dev.cu.unlock() def _do_commit(self, **kwargs): self.dev.cu.commit() def _do_check(self): self.dev.cu.commit_check() def _do_rollback(self, index=0): self.dev.cu.rollback(index)
def main(): hosts = config.get('hosts') for host in hosts: dev = Device(host=host, user=user, password=password) # Open the connection & config try: print("Opening connnection to: {}".format(host)) dev.open() except Exception as err: print("Cannot connect to device: {}".format(err)) return dev.bind(cu=Config) # Lock the configuration, load changes, commit print("Locking the configuration on: {}".format(host)) try: dev.cu.lock() except LockError: print("Error: Unable to lock configuration on: {}".format(host)) dev.close() return print("Loading configuration changes on: {}".format(host)) try: set_commands = """ delete policy-options prefix-list edge-block delete policy-options prefix-list edge-block-exceptions """ dev.cu.load(set_commands, format='set') dev.cu.load(template_path=template, template_vars=config, format='text') except ValueError as err: print(err.message) except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') print("Unable to load config changes: {}".format(rpc_msg)) print("Unlocking the configuration on: {}".format(host)) try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock config on: {}".format(host)) dev.close() return print("Committing the configuration on: {}".format(host)) try: dev.cu.commit() # print(dev.cu.diff()) except CommitError: print("Error: Unable to commit configuration on: {}".format(host)) print("Unlocking the configuration on: {}".format(host)) try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock config on: {}".format(host)) dev.close() return print "Unlocking the configuration on:", host try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock config on: {}".format(host)) print("Closing connection to: {}".format(host)) dev.close()
'ge-0/0/1': '72.114.255.3/19', 'ge-0/0/2': '72.114.255.34/19', 'ge-0/0/3': '72.114.196.0/19' } if_config_check = {'ge-0/0/1': '', 'ge-0/0/2': 'passive', 'ge-0/0/3': ''} if_area = { 'ge-0/0/1': 'area 0.0.0.20', 'ge-0/0/2': 'area 0.0.0.20', 'ge-0/0/3': 'area 0.0.0.20' } var_dict = { 'if_config': if_config, 'if_config_check': if_config_check, 'if_area': if_area } try: device.open() device.bind(conf=Config) device.conf.load(template_path='template_ospf.conf', template_vars=var_dict, merge=True) success = device.conf.commit() print("Success : {}".format(success)) except (RpcError, ConnectError) as err: print("\nError: " + repr(err)) finally: device.close()
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf') def test_scp_console(self): dev = Device(host='1.1.1.1', mode='telnet') self.assertRaises(RuntimeError, SCP, dev) @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') @patch('paramiko.SSHClient') @patch('paramiko.proxy.ProxyCommand') def test_scp_proxycommand(self, mock_proxy, mock_paramiko, mock_connect, open_mock, os_mock): os_mock.path.exists.return_value = True # self.dev._sshconf_path = '/home/rsherman/.ssh/config' with SCP(self.dev) as scp: scp.get('addrbook.conf') mock_proxy.assert_called_once() def test_scp_progress(self): scp = SCP(self.dev) print (scp._scp_progress('test', 100, 50)) @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh): mock_scpclient.return_value = None def fn(file, total, tfd): pass package = 'test.tgz' with SCP(self.dev, progress=fn) as scp: scp.put(package) self.assertEqual( mock_scpclient.mock_calls[0][2]['progress'].__name__, 'fn') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_user_def_progress_args_2(self, mock_scpclient, mock_put, mock_ssh): mock_scpclient.return_value = None def myprogress(dev, report): print ("host: %s, report: %s" % (dev.hostname, report)) package = 'test.tgz' with SCP(self.dev, progress=myprogress) as scp: scp.put(package) self.assertEqual( mock_scpclient.mock_calls[0][2]['progress'].__name__, '_scp_progress') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient): mock_scpclient.return_value = None package = 'test.tgz' with SCP(self.dev, progress=True) as scp: scp.put(package) self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__, '_scp_progress') @patch('ncclient.manager.connect') @patch('paramiko.SSHClient.connect') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_ssh_private_key_file(self, mock_scpclient, mock_put, mock_sshclient, mock_ncclient): mock_scpclient.return_value = None package = 'test.tgz' dev = Device(host='1.1.1.1', user='******', ssh_private_key_file='/Users/test/testkey') dev.open(gather_facts=False) with SCP(dev) as scp: scp.put(package) self.assertEqual(mock_sshclient.mock_calls[0][2]['key_filename'], '/Users/test/testkey') @contextmanager def capture(self, command, *args, **kwargs): out, sys.stdout = sys.stdout, StringIO() command(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() sys.stdout = out
import sys import os from pprint import pprint from jnpr.junos import Device from jnpr.junos.utils.config import Config import jnpr device = Device(host='10.247.140.4', user='******', password='******' ) device.open() #pprint( device.facts ) device.bind(cfg=Config) try: device.rpc.open_configuration(private=True) except jnpr.junos.exception.RpcError as e: if 'severity: warning' in str(e): print str(e) pass else: raise for line in open("fila"): elhay = Config(device) set_cmd = line elhay.load(set_cmd, format='set') elhay.pdiff() elhay.commit() #for line in open("fila"): # print device.cli(line)
def load_with_pyez(merge_opt, overwrite_opt, format_opt, conf_file, log_file, ip, hostname, username, password): """ Purpose: Perform the actual loading of the config file. Catch any errors. Parameters: format_opt - defines the format of input "set" or "hierarchical" merge_opt - the merge options selection, "loadmerge" overwrite_opt - the overwrite option selection, "loadoverwrite" conf_file - the configuration file name, including path and filename log_file - the log file name, including path and filename ip - ip address of device hostname - device hostname username - username for logging in password - password for username """ dot = "." screen_and_log( ("Applying configuration on {0} ({1}) ".format(hostname, ip)), log_file) screen_and_log(dot, log_file) dev = Device(ip, user=username, password=password) try: dev.open() except ConnectError as err: screen_and_log(("{0}: Cannot connect to device : {1}".format(ip, err)), log_file) return dev.bind(cu=Config) #print("Try locking the configuration...") screen_and_log(dot, log_file) try: dev.cu.lock() except LockError as err: screen_and_log( ("{0}: Unable to lock configuration : {1}".format(ip, err)), log_file) dev.close() return #print("Try loading configuration changes...") screen_and_log(dot, log_file) try: if format is None: dev.cu.load(path=conf_file, merge=merge_opt, overwrite=overwrite_opt) else: dev.cu.load(path=conf_file, merge=merge_opt, format="set") except (ConfigLoadError, Exception) as err: if err.rpc_error['severity'] == 'warning': pass elif 'statement not found' in err.message: pass else: screen_and_log( ("{0}: Unable to load configuration changes : {1}".format( ip, err)), log_file) screen_and_log(("{0}: Unlocking the configuration".format(ip)), log_file) try: dev.cu.unlock() except UnlockError as err: screen_and_log( ("{0}: Unable to unlock configuration : {1}".format( ip, err)), log_file) dev.close() return #print("Try committing the configuration...") screen_and_log(dot, log_file) try: dev.cu.commit() except CommitError as err: screen_and_log( ("{0}: Unable to commit configuration : {1}".format(ip, err)), log_file) screen_and_log(("{0}: Unlocking the configuration".format(ip)), log_file) try: dev.cu.unlock() except UnlockError as err: screen_and_log( ("{0}: Unable to unlock configuration : {1}".format(ip, err)), log_file) dev.close() return #print("Try Unlocking the configuration...") screen_and_log(dot, log_file) try: dev.cu.unlock() except UnlockError as err: screen_and_log( ("{0}: Unable to unlock configuration : {1}".format(ip, err)), log_file) dev.close() return # End the NETCONF session and close the connection dev.close() screen_and_log((" Completed!\n"), log_file)
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.timeout = self.timeout self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff.strip() def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config() def get_facts(self): output = self.device.facts uptime = 0 if 'RE0' in output: uptime = output['RE0']['up_time'] interfaces = junos_views.junos_iface_table(self.device) interfaces.get() interface_list = interfaces.keys() return { 'vendor': u'Juniper', 'model': unicode(output['model']), 'serial_number': unicode(output['serialnumber']), 'os_version': unicode(output['version']), 'hostname': unicode(output['hostname']), 'fqdn': unicode(output['fqdn']), 'uptime': string_parsers.convert_uptime_string_seconds(uptime), 'interface_list': interface_list } def get_interfaces(self): # init result dict result = {} interfaces = junos_views.junos_iface_table(self.device) interfaces.get() # convert all the tuples to our pre-defined dict structure for iface in interfaces.keys(): result[iface] = { 'is_up': interfaces[iface]['is_up'], 'is_enabled': interfaces[iface]['is_enabled'], 'description': interfaces[iface]['description'] or u'', 'last_flapped': interfaces[iface]['last_flapped'] or -1, 'mac_address': unicode(interfaces[iface]['mac_address']) } result[iface]['last_flapped'] = float(result[iface]['last_flapped']) match = re.search(r'\d+', interfaces[iface]['speed'] or '') if match is not None: result[iface]['speed'] = int(match.group(0)) else: result[iface]['speed'] = -1 return result def get_interfaces_counters(self): query = junos_views.junos_iface_counter_table(self.device) query.get() interface_counters = dict() for interface, counters in query.items(): interface_counters[interface] = {k: v or -1 for k, v in counters} return interface_counters @staticmethod def _get_address_family(table): """ Function to derive address family from a junos table name :params table: The name of the routing table :returns: address family """ address_family_mapping = { 'inet': 'ipv4', 'inet6': 'ipv6' } family = table.split('.')[-2] return address_family_mapping[family] def get_bgp_neighbors(self): # Setup the views instances = junos_views.junos_route_instance_table(self.device) uptime_table = junos_views.junos_bgp_uptime_table(self.device) bgp_neigbors = junos_views.junos_bgp_table(self.device) # prepare data bgp_neigbor_data = dict() for instance, instance_data in instances.get().items(): if instance.startswith('__'): # junos internal instances continue instance_name = "global" if instance == 'master' else instance bgp_neigbor_data[instance_name] = dict(peers=dict()) for neighbor, neighbor_data in bgp_neigbors.get(instance=instance).items(): structured_neighbor_data = {k: v for k, v in neighbor_data} peer = neighbor.split('+')[0] bgp_neigbor_data[instance_name]['peers'][peer] = dict() for key in ['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id']: bgp_neigbor_data[instance_name]['peers'][peer][key] = structured_neighbor_data[key] or u'' if 'router_id' not in bgp_neigbor_data[instance_name].keys(): # we only need to set this once bgp_neigbor_data[instance_name]['router_id'] = structured_neighbor_data['local_id'] if structured_neighbor_data['is_up'] is False: # if the session is down there is no table data to parse continue elif isinstance(structured_neighbor_data['tables'], list): for idx, table in enumerate(structured_neighbor_data['tables']): family = self._get_address_family(table) bgp_neigbor_data[instance_name]['peers'][peer][family] = dict() for metric in ['received_prefixes', 'accepted_prefixes', 'sent_prefixes']: bgp_neigbor_data[instance_name]['peers'][peer][family][metric] = structured_neighbor_data[metric][idx] else: family = self._get_address_family(structured_neighbor_data['tables']) bgp_neigbor_data[instance_name]['peers'][peer][family] = dict() bgp_neigbor_data[instance_name]['peers'][peer][family]['received_prefixes'] = structured_neighbor_data['received_prefixes'] bgp_neigbor_data[instance_name]['peers'][peer][family]['accepted_prefixes'] = structured_neighbor_data['accepted_prefixes'] bgp_neigbor_data[instance_name]['peers'][peer][family]['sent_prefixes'] = structured_neighbor_data['sent_prefixes'] for neighbor, uptime in uptime_table.get(instance=instance).items(): bgp_neigbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1] return bgp_neigbor_data def get_lldp_neighbors(self): lldp = junos_views.junos_lldp_table(self.device) lldp.get() result = lldp.items() neighbors = dict() for neigh in result: if neigh[0] not in neighbors.keys(): neighbors[neigh[0]] = list() neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]}) return neighbors
class TestDevice(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_new_console_return(self): dev = Device(host='1.1.1.1', user='******', password='******', port=23, gather_facts=False) self.assertTrue(isinstance(dev, Console)) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError( "Could not open socket to 1.1.1.1:830") from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'why are you trying :)' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_probe_error(self): mock_probe = MagicMock() mock_probe.return_value = None self.dev.probe = mock_probe def fn(): self.dev.open(auto_probe=1) self.assertRaises(EzErrors.ProbeError, fn) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch(builtin_string + '.open', mock): if sys.version > '3': builtin_file = 'io.TextIOWrapper' else: builtin_file = builtin_string + '.file' with patch(builtin_file, MagicMock): handle = open('filename', 'r') self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user='******', password='******', gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) def test_device_master_is_master(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re1', 'master', 'node', 'fwdd', 'member', 'pfem'] self.assertEqual(localdev.master, True) def test_device_master_is_backup(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re0', 'backup'] self.assertEqual(localdev.master, False) def test_device_master_is_re0_only(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = False localdev.facts._cache['RE_hw_mi'] = False localdev.facts._cache['current_re'] = ['re0'] self.assertEqual(localdev.master, True) def test_device_master_is_multi_chassis_non_master1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1', 'lcc1-backup', 'member1-backup'] self.assertEqual(localdev.master, False) def test_device_master_is_multi_chassis_non_master2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0', 'lcc1-master', 'member1-master', 'member1'] self.assertEqual(localdev.master, False) def test_device_master_is_none1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = None self.assertEqual(localdev.master, None) def test_device_master_is_none2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['foo', 'bar'] self.assertEqual(localdev.master, None) @patch('jnpr.junos.device.warnings') def test_device_master_is_old_facts(self, mock_warn): localdev = Device(host='1.1.1.1', user='******', password='******', fact_style='old', gather_facts=False) mock_warn.assert_has_calls([call.warn('fact-style old will be removed ' 'in a future release.', RuntimeWarning)]) self.assertEqual(localdev.master, None) def test_device_master_setter(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) with self.assertRaises(RuntimeError): localdev.master = 'foo' def test_device_re_name_is_re0(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re0', 'backup'] localdev.facts._cache['hostname_info'] = {'re0': 'tapir', 're1': 'tapir1'} self.assertEqual(localdev.re_name, 're0') def test_device_re_name_is_lcc_re1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1', 'lcc1-backup', 'member1-backup'] localdev.facts._cache['hostname_info'] = {'re0': 'mj1'} self.assertEqual(localdev.re_name, 'lcc1-re1') def test_device_re_name_is_re0_only(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['foo'] localdev.facts._cache['hostname_info'] = {'re0': 'mj1'} self.assertEqual(localdev.re_name, 're0') def test_device_re_name_is_none1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = None self.assertEqual(localdev.re_name, None) def test_device_re_name_is_none2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re1', 'master', 'node', 'fwdd', 'member', 'pfem'] localdev.facts._cache['hostname_info'] = None self.assertEqual(localdev.re_name, None) @patch('jnpr.junos.device.warnings') def test_device_re_name_is_old_facts(self, mock_warn): localdev = Device(host='1.1.1.1', user='******', password='******', fact_style='old', gather_facts=False) mock_warn.assert_has_calls([call.warn('fact-style old will be removed ' 'in a future release.', RuntimeWarning)]) self.assertEqual(localdev.re_name, None) def test_device_re_name_setter(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) with self.assertRaises(RuntimeError): localdev.re_name = 'foo' def test_device_repr(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.assertEqual(repr(localdev), 'Device(1.1.1.1)') def test_device_local(self): Device.ON_JUNOS = True localdev = Device() self.assertEqual(localdev._hostname, 'localhost') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._ssh_config = '/home/rsherman/.ssh/config' self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('os.getenv') def test_device__sshconf_lkup_path_not_exists(self, mock_env): mock_env.return_value = '/home/test' self.assertEqual(self.dev._sshconf_lkup(), None) @patch('os.getenv') def test_device__sshconf_lkup_home_not_defined(self, mock_env): mock_env.return_value = None self.assertEqual(self.dev._sshconf_lkup(), None) mock_env.assert_called_with('HOME') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open(self, mock_connect, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device( host='2.2.2.2', user='******', password='******') self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch('jnpr.junos.Device.execute') def test_device_facts(self, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() self.dev.facts._cache['current_re'] = ['re0'] assert self.dev.facts['version'] == facts['version'] @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.factcache.warnings') def test_device_facts_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.dev.facts_refresh(warnings_on_failure=True) self.assertTrue(mock_warnings.warn.called) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_facts_error_exception_on_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_old_style_facts_error_exception_on_error(self, mock_warnings, mock_execute): self.dev._fact_style = 'old' with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) def test_device_facts_refresh_unknown_fact_style(self): self.dev._fact_style = 'bad' with self.assertRaises(RuntimeError): self.dev.facts_refresh() def test_device_facts_refresh_old_fact_style_with_keys(self): self.dev._fact_style = 'old' with self.assertRaises(RuntimeError): self.dev.facts_refresh(keys='domain') def test_device_hostname(self): self.assertEqual(self.dev.hostname, '1.1.1.1') def test_device_user(self): self.assertEqual(self.dev.user, 'test') def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = '******' self.assertEqual(self.dev._auth_password, 'secret') def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_manages(self): self.assertEqual(self.dev.manages, [], 'By default manages will be empty list') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open_normalize(self, mock_connect, mock_execute): mock_connect.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open(gather_facts=False, normalize=True) self.assertEqual(self.dev2.transform, self.dev2._norm_transform) def test_device_set_facts_exception(self): try: self.dev.facts = 'test' except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) def test_device_ofacts_exception(self): with self.assertRaises(RuntimeError): ofacts = self.dev.ofacts def test_device_set_ofacts_exception(self): with self.assertRaises(RuntimeError): self.dev.ofacts = False @patch('jnpr.junos.Device.execute') def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show cli directory', warning=False).tag, 'cli') @patch('jnpr.junos.device.json.loads') def test_device_rpc_json_ex(self, mock_json_loads): self.dev.facts = facts self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) ex = ValueError('Extra data ') ex.message = 'Extra data ' # for py3 as we dont have message thr mock_json_loads.side_effect = [ ex, self._mock_manager(etree.fromstring( '<get-route-information format="json"/>'))] self.dev.rpc.get_route_information({'format': 'json'}) self.assertEqual(mock_json_loads.call_count, 2) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('show system uptime') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show system uptime | match foo | count') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_complex(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show interfaces ge-0/0/0.0 routing-instance all media') self.assertEqual("rpc.get_interface_information(" "routing_instance='all', media=True, " "interface_name='ge-0/0/0.0')", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_invalid(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('foo') self.assertEqual(None, data) @patch('jnpr.junos.Device.execute') def test_device_cli_format_json(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli('show interface terse', warning=False, format='json') self.assertEqual(type(data), dict) self.assertEqual(data['interface-information'][0] ['physical-interface'][0]['oper-status'][0]['data'], 'up') @patch('jnpr.junos.Device.execute') def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('Alarm' in self.dev.cli('show system alarms', warning=False)) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_cli_output_warning(self, mock_warnings, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance ' 'all media', format='xml') ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/' 'address-family[address-family-name="inet"]/' 'interface-address/ifa-local') self.assertTrue('192.168.100.1' in ip) self.assertTrue(mock_warnings.warn.called) rpc_string = "rpc.get_interface_information(routing_instance='all', "\ "media=True, interface_name='ge-0/0/0.0')" self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0]) def test_device_cli_blank_output(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual('', self.dev.cli('show configuration interfaces', warning=False)) def test_device_cli_rpc_reply_with_message(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( '\nprotocol: operation-failed\nerror: device asdf not found\n', self.dev.cli('show interfaces terse asdf', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show system uptime| display xml rpc', warning=False) .tag, 'get-system-uptime-information') def test_device_cli_exception(self): self.dev.rpc.cli = MagicMock(side_effect=AttributeError) val = self.dev.cli('show version') self.assertEqual(val, 'invalid command: show version') @patch('jnpr.junos.Device.execute') def test_device_cli_rpc_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager val = self.dev.cli('foo') self.assertEqual(val, 'invalid command: foo: RpcError') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show system uptime').tag, 'get-system-uptime-information') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc_text(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertIn( '<get-system-uptime-information>', self.dev.display_xml_rpc( 'show system uptime', format='text')) @patch('jnpr.junos.Device.execute') def test_device_display_xml_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show foo'), 'invalid command: show foo| display xml rpc') def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag, 'directory-list') def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>', to_py=self._do_nothing), 'Nothing') # This test is for the commented out rpc-error code # def test_device_execute_exception(self): # self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) # self.assertRaises(RpcError, self.dev.execute, # '<load-configuration-error/>') @patch('jnpr.junos.device.warnings') def test_device_execute_unknown_exception(self, mock_warnings): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.execute, '<get-software-information/>') def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) def test_device_execute_permission_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises( EzErrors.PermissionError, self.dev.rpc.get_permission_denied) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_execute_unopened(self): self.dev.connected = False self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None) def test_device_execute_timeout(self): self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError) self.assertRaises( EzErrors.RpcTimeoutError, self.dev.rpc.get_rpc_timeout) def test_device_execute_closed(self): self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError) self.assertRaises( EzErrors.ConnectClosedError, self.dev.rpc.get_rpc_close) self.assertFalse(self.dev.connected) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.__doc__, 'get-software-information') def test_device_probe_timeout_zero(self): with patch('jnpr.junos.device.socket'): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch('jnpr.junos.device.socket'): self.assertTrue(self.dev.probe(1), 'probe fn is not working for' ' timeout greater than zero') def test_device_probe_timeout_exception(self): with patch('jnpr.junos.device.socket') as mock_socket: with patch('jnpr.junos.device.time.sleep') as mock_time: mock_socket.socket.return_value.close.side_effect \ = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic_mock' self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock') def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = 'Test' self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, 'Test') def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template( 'tests/unit/templates/config-example.xml') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example.xml') except: raise self.assertEqual(template.render({'host_name': '1', 'domain_name': '2'}), 'system {\n host-name 1;\n domain-name 2;\n}') def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name='close') self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) @patch('ncclient.manager.connect') def test_device_context_manager(self, mock_connect): mock_connect.side_effect = self._mock_manager try: with Device(host='3.3.3.3', user='******', password='******', gather_facts=False) as dev: self.assertTrue(dev.connected) dev._conn = MagicMock(name='_conn') dev._conn.connected = True def close_conn(): dev.connected = False dev.close = MagicMock(name='close') dev.close.side_effect = close_conn raise RpcError except Exception as e: self.assertIsInstance(e, RpcError) self.assertFalse(dev.connected) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) with open(fpath) as fp: foo = fp.read() if fname == 'get-rpc-error.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif fname == 'get-permission-denied.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif (fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.xml' or fname == 'load-configuration-error.xml' or fname == 'show-configuration-interfaces.xml' or fname == 'show-interfaces-terse-asdf.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply()) elif (fname == 'show-configuration.xml' or fname == 'show-system-alarms.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc elif fname == 'show-interface-terse.json': rpc_reply = json.loads(foo) elif fname == 'get-route-information.json': rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply()) else: rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs and 'normalize' not in kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') if args[0].text == 'show interface terse': return self._read_file('show-interface-terse.json') elif args[0].text == 'show configuration': return self._read_file('show-configuration.xml') elif args[0].text == 'show system alarms': return self._read_file('show-system-alarms.xml') elif args[0].text == 'show system uptime| display xml rpc': return self._read_file('show-system-uptime-rpc.xml') elif args[0].text == 'show configuration interfaces': return self._read_file('show-configuration-interfaces.xml') elif args[0].text == 'show interfaces terse asdf': return self._read_file('show-interfaces-terse-asdf.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media': return self._read_file( 'show-interfaces-routing-instance-media.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media| display ' \ 'xml rpc': return self._read_file( 'show-interfaces-routing-instance-media-rpc.xml') else: raise RpcError else: if args[0].attrib.get('format') == 'json': return self._read_file(args[0].tag + '.json') return self._read_file(args[0].tag + '.xml') def _do_nothing(self, *args, **kwargs): return 'Nothing'
class pybot_jrouter(object): ROBOT_LIBRARY_SCOPE = 'TEST SUITE' ROBOT_LISTENER_API_VERSION = 2 # ----------------------------------------------------------------------- # CONSTRUCTOR # ----------------------------------------------------------------------- def __init__(self,**kvargs): """ Constructor method. It takes a user, password and a target (port is optional) arguments to create an instance of a JunOS device that will be used by RF """ # Setting credentials self.user = kvargs['user'] self.target = kvargs['target'] self.password = kvargs['password'] try: self.port = int(kvargs['port']) except KeyError: self.port = 22 self.ROBOT_LIBRARY_LISTENER = self self.max_retries = 2 self._conn = Device(user=self.user, host=self.target, password=self.password, port=self.port, gather_facts=False) # ----------------------------------------------------------------------- # OVERLOADS # ----------------------------------------------------------------------- def __repr__ (self): """ Function that returns a representation of an instance of a JunOS device used by RF """ return "pybot_jrouter: user=%s, target=%s, password=%s, port=%s, connection=%s" % (self.user, self.target, self.password, self.port, self._conn) # ----------------------------------------------------------------------- # FUNCTIONS START HERE # ----------------------------------------------------------------------- def open_connection(self): """ Function that opens a connection to a JunOS device """ try: self._conn.open(auto_probe=10) self._conn.timeout = 120*120 return self except ConnectError as c_error: print ("WARN Connection problems %s target: %s port: %s" % (c_error, self.target, self.port)) raise ContinuableError("Connection problems %s target: %s port: %s" %(c_error, self.target, self.port)) def close_connection(self): """ Function that closes a connection to a JunOS device """ try: self._conn.close() return self except ConnectError as c_error: print ("WARN Connection problems %s" %c_error) raise ContinuableError("Connection problems %s" %c_error) def load_configuration_from_file(self, synchronize=True, overwrite=False, **kvargs): """ Function that load configuration on router from a file path : where the configuration file is located format: possible values 'set' or 'xml' or 'bracket' (so far only format 'set' is supported) """ #overwrite = kvargs.pop ('overwrite',False) args = dict(data='') args.update(kvargs) if overwrite: return self.load_configuration(overwrite=True, **args) else: return self.load_configuration(overwrite=False, **args) def load_configuration_from_template(self, commit_comment='pybot_jrouter_load_configuration_from_template', format='set', conf_mode='exclusive', overwrite=False, merge=False, synchronize=True, force_synchronize=False, full=False, print_conf_diff=False, print_conf_detail=False, **kvargs): """ # General Options: # - format can be text/set/xml # - print_conf_diff will print the diff if desired # - print_conf_detail will print the committed configuration if desired # Configuration Options: # - conf_mode: can be exclusive/private/dynamic/batch # Load Options: # - overwrite: Determines if the contents completely replace the existing configuration. Default is False # - merge: If set to True will set the load-config action to merge the default load-config action is 'replace' # Commit Options: # - kvargs synchronize: Default True. On dual control plane systems, requests that the candidate configuration on one control plane be copied to the other control plane, checked for correct syntax, and committed on both Routing Engines. Default is True. # - kvargs force_synchronize: Default False. On dual control plane systems, forces the candidate configuration on one control plane to be copied to the other control plane. Default is False # - kvargs full: Default False. When True requires all the daemons to check and evaluate the new configuration """ print ("*INFO* Host %s|load_configuration_from_template|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail)) synchronize = True force_synchronize = False full = False if 'force_synchronize' in kvargs.keys(): force_synchronize = kvargs['force_synchronize'] if 'synchronize' in kvargs.keys(): synchronize = kvargs['synchronize'] if 'full' in kvargs.keys(): full = kvargs['full'] ##Hidden variable: DO NOT USE DO NOT EDIT #It will be set to True ONLY if routers.load_configuration_from_template_in_parallel is executed if 'parallel' in kvargs.keys(): parallel = kvargs['parallel'] else: parallel = False if force_synchronize: synchronize = True print ("*INFO* Host %s|load_configuration_from_template|Force Synchronized Commit requested" % (self.target)) if synchronize: print ("*INFO* Host %s|load_configuration_from_template|Synchronized Commit requested" % (self.target)) if full: print ("*INFO* Host %s|load_configuration_from_template|Commit Full requested" % (self.target)) print ("*INFO* Host %s|load_configuration_from_template|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite)) if format == 'set' and overwrite: overwrite = False print ("*WARN* Host %s|load_configuration_from_template|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target)) yaml_file = kvargs['template_vars'] # Loading files and rendering myvars = yaml.load(open(yaml_file).read()) loadResp = '' commitResp = False print ("*INFO* Host %s|load_configuration_from_template|Initializing variables. template_path=%s." % (self.target, kvargs['jinja2_file'])) try: #Unlock/close configuration is managed by Config context manager with Config(self._conn, mode=conf_mode) as candidate: begin_load_datetime = datetime.now() if overwrite: loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=True, merge=merge) else: loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=False, merge=merge) finish_load_datetime = datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration_from_template|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) begin_commit_datetime = datetime.now() if print_conf_detail: try: #begin_commit_datetime=datetime.now() commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True) #finish_commit_datetime=datetime.now() print ('*INFO* Host %s|load_configuration_from_template|Configuration to be committed: %s' % (self.target, etree.tostring(commitResp))) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the committed configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error)) return False else: begin_commit_datetime = datetime.now() commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False) finish_commit_datetime = datetime.now() except LockError as lockError: print ("*WARN* Host %s|load_configuration_from_template|Problems locking configuration: %s" % (self.target, lockError)) if parallel: return "Exception %s:" %lockError else: raise FatalError("Host %s|load_configuration_from_template|Unable to lock configuration.....exiting: %s" % (self.target, lockError)) except (RpcError, RpcTimeoutError) as rpcError: #warnings severity is already being ignored in the Config context manager print ("*WARN* Host %s|load_configuration_from_template|Problems opening configuration: %s" % (self.target, rpcError)) if parallel: return "Exception %s:" %rpcError else: raise FatalError("Host %s|load_configuration_from_template|Unable to open configuration.....exiting: %s" % (self.target, rpcError)) except ConfigLoadError as configError: print( "*WARN* Host %s|load_configuration_from_template|Template %s|Problems loading the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], configError)) if print_conf_diff: try: print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) if parallel: return "Exception %s:" %configError else: raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to load the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], configError)) except CommitError as commitError: print ("*WARN* Host %s|load_configuration_from_template|Template %s|Problems committing the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], commitError)) if parallel: return "Exception %s:" %commitError else: raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to commit the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], commitError)) except UnlockError as unlockError: print ("*WARN* Host %s|load_configuration_from_template|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError)) if parallel: return "Exception %s:" %unlockError else: raise FatalError("Host %s|load_configuration_from_template|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError)) except Exception as error: if 'Opening and ending tag mismatch: routing-engine ' in error: print ('*INFO* Host %s|load_configuration_from_template|%s' %(self.target, error)) pass return True else: print ("*WARN* Host %s|load_configuration_from_template|An unhandled exception occurred: %s.....exiting" % (self.target, error)) if parallel: return "Exception %s:" %error else: raise FatalError("Host %s|load_configuration_from_template|Unhandled Exception occurred.....exiting: %s" % (self.target, error)) diff_load_time = finish_load_datetime - begin_load_datetime diff_commit_time = finish_commit_datetime - begin_commit_datetime total_time = finish_commit_datetime - finish_load_datetime print ('*INFO* Host %s|load_configuration_from_template|Configuration successfully committed|Template: %s|Load Time: %s|Commit Time: %s| Total Time: %s' % (self.target, kvargs['jinja2_file'], self.pretty_time_delta(diff_load_time.seconds), self.pretty_time_delta(diff_commit_time.seconds), self.pretty_time_delta(total_time.seconds))) return True def load_configuration(self, commit_comment ='pybot_jrouter_load_configuration', path=None, format='set', conf_mode='exclusive', overwrite=False, merge=False, synchronize=True, force_synchronize=False, full=False, print_conf_diff=False, print_conf_detail=False, **kvargs): """ Function that load configuration on a JunOS device **kvargs format:set|text|xml data: data to load in the router """ print ("*INFO* Host %s|load_configuration|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail)) data = kvargs['data'] format = kvargs['format'] if 'force_synchronize' in kvargs.keys(): force_synchronize = kvargs['force_synchronize'] if 'synchronize' in kvargs.keys(): synchronize = kvargs['synchronize'] if 'full' in kvargs.keys(): full = kvargs['full'] if force_synchronize: synchronize = True print ("*INFO* Host %s|load_configuration|Force Synchronized Commit requested" % (self.target)) if synchronize: print ("*INFO* Host %s|load_configuration|Synchronized Commit requested" % (self.target)) if full: print ("*INFO* Host %s|load_configuration|Commit Full requested" % (self.target)) print ("*INFO* Host %s|load_configuration|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite)) if format == 'set' and overwrite: overwrite = False print ("*WARN* Host %s|load_configuration|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target)) loadResp = '' commitResp = False print ("*INFO* Host %s|load_configuration|Initializing variables. path=%s." % (self.target,path)) print ("*INFO* Host %s|load_configuration|Initializing variables. data=%s." % (self.target,data)) try: #Unlock/close configuration is managed by Config context manager with Config(self._conn, mode=conf_mode) as candidate: #begin_load_datetime=datetime.now() if ((data == "") and (path != None)): if overwrite: loadResp=candidate.load(path=path, format=format, overwrite=True, merge=merge) else: loadResp=candidate.load(path=path, format=format, overwrite=False, merge=merge) #finish_load_datetime=datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) else: if overwrite: loadResp=candidate.load(data, format=format, overwrite=True, merge=merge) else: loadResp=candidate.load(data, format=format, overwrite=False, merge=merge) #finish_load_datetime=datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) #begin_commit_datetime=datetime.now() if print_conf_detail: try: #begin_commit_datetime=datetime.now() commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True) #finish_commit_datetime=datetime.now() print ('*INFO* Host %s|load_configuration|Configuration to be committed: %s' % (self.target, etree.tostring(commitResp))) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the commited configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error)) return False else: #begin_commit_datetime=datetime.now() commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False) #finish_commit_datetime=datetime.now() except LockError as lockError: print ("*WARN* Host %s|load_configuration|Problems locking configuration: %s" % (self.target, lockError)) raise FatalError("Host %s|load_configuration|Unable to lock configuration.....exiting: %s" % (self.target, lockError)) except (RpcError,RpcTimeoutError) as rpcError: #warnings severity is already being ignored in the Config context manager print ("*WARN* Host %s|load_configuration|Problems opening configuration: %s" % (self.target, rpcError)) raise FatalError("Host %s|load_configuration|Unable to open configuration.....exiting: %s" % (self.target, rpcError)) except ConfigLoadError as configError: print ("*WARN* Host %s|load_configuration|Problems loading the configuration: %s.....exiting" % (self.target, configError)) if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) raise FatalError("Host %s|load_configuration|Unable to load the configuration.....exiting: %s" % (self.target, configError)) except CommitError as commitError: print ("*WARN* Host %s|load_configuration|Problems committing the configuration: %s.....exiting" % (self.target, commitError)) raise FatalError("Host %s|load_configuration|Unable to commit the configuration.....exiting: %s" % (self.target, commitError)) except UnlockError as unlockError: print ("*WARN* Host %s|load_configuration|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError)) raise FatalError("Host %s|load_configuration|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError)) except Exception as error: if 'Opening and ending tag mismatch: routing-engine ' in error: print ('*INFO* Host %s|load_configuration|%s' % (self.target, error)) pass return True else: print ("*WARN* Host %s|load_configuration|An unhandled exception occurred: %s.....exiting" % (self.target, error)) raise FatalError("Host %s|load_configuration|Unhandled Exception occurred.....exiting: %s" % (self.target, error)) print ('*INFO* Host %s|load_configuration|Configuration successfully committed' % (self.target)) #diff_load_time=begin_load_datetime-finish_load_datetime #diff_commit_time=begin_commit_datetime-finish_commit_datetime return True def jsnap(self, **kvargs): """ Function that makes use of JSNAP """ variables = BuiltIn().get_variables() # Assigning kvargs section = None if 'section' in kvargs.keys(): section = kvargs['section'] tag = kvargs['tag'] snaptype = kvargs['snaptype'] test = kvargs['test'] mode = kvargs['mode'] output_directory = variables['${path}'] test_case = variables['${testname}'] tmp_dir = tempfile.mkdtemp(prefix='_') dirpath = output_directory + "/" + tmp_dir + "/" + test_case.replace(" ","_") + "/" + self.target + "/snapshot/" #PARENT_ROOT=os.path.abspath(os.path.join(self.logdir, os.pardir)) #GRANDPA=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir)) if not os.path.exists(dirpath): os.makedirs(dirpath, mode=777) timestamp = datetime.now().strftime("%Y-%m-%d") if snaptype == "snap": if section: cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' -s' + section + ' ' + test else: cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' ' + test print ("Executing: %s" %cmd) jsnap_command = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath) output, errors = jsnap_command.communicate() if ((("Exiting." in errors)) or("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)): print (output) print (errors) raise FatalError("Unable to execute jsnap.....exiting") else: return True print (output, errors) return True elif snaptype == "snapcheck": if section: cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' -s' + section + ' ' + test else: cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' ' + test print ("Executing: %s" %cmd) jsnap_command = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath) output, errors = jsnap_command.communicate() print (output) print (errors) if ((("Exiting." in errors)) or ("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)): print (output) print (errors) raise FatalError("Unable to execute jsnap.....exiting") else: if mode == "strict": if "ERROR" in output or "ERROR" in errors: raise FatalError("ERROR found in jsnap mode strict.....exiting") else: return True else: return True elif snaptype == "check": if section: cmd_check = 'jsnap --'+ snaptype + " " + timestamp + '_pre' + ',' + timestamp + '_post' + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' -s' + section + ' ' + test else: cmd_check = 'jsnap --'+ snaptype + " " + timestamp + '_pre' + ',' + timestamp + '_post' + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' ' + test print ("Executing: %s" %cmd_check) jsnap_command = sub.Popen(cmd_check, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath) output, errors = jsnap_command.communicate() print (output) print (errors) if ((("Exiting." in errors)) or ("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)): print (output) print (errors) raise FatalError("Unable to execute jsnap.....exiting") else: if mode == "strict": if "ERROR" in output or "ERROR" in errors: raise FatalError("ERROR found in jsnap mode strict.....exiting") else: return True else: return True else: raise FatalError("Invalid snap type.....exiting") def rescue_configuration(self, print_diff=False, **kvargs): """ Function that issues Save/Load a Rescue Configuration """ if 'action' in kvargs.keys(): action = kvargs['action'] # Saving rescue configuration if action == 'save': try: self._conn.rpc.request_save_rescue_configuration() except RpcError as err: rpc_error = err.__repr__() print (rpc_error) return self # Checking if this attribute was already attached to Device if hasattr(self._conn, "candidate"): pass else: self._conn.bind(candidate=Config) # Locking configuration try: self._conn.candidate.lock() except LockError as l_error: print ("*WARN* Problems locking configuration: %s" % (l_error)) raise FatalError("Unable to lock configuration.....exiting") # Loading rescue configuration if action == 'load': try: self._conn.rpc.load_configuration({'rescue': 'rescue'}) except RpcError as err: rpc_error = err.__repr__() print (rpc_error) except ConfigLoadError as error: print ("*WARN* Problems loading configuration: %s" % (error)) raise FatalError("Unable to load configuration.....exiting") if print_diff: print ('*INFO* Configuration to be commited %s' % (self._conn.candidate.diff())) try: self._conn.candidate.commit(comment='loading rescue configuration') self._conn.candidate.unlock() return True except (CommitError, LockError) as err: print (err) raise FatalError("Unable to commit or unlock configuration......exiting") def commands_executor(self, **kvargs): """ Function that issues commands """ # Getting RF built-in variables variables = BuiltIn().get_variables() regex = '' xpath = '' if 'xpath' in kvargs.keys(): xpath = kvargs['xpath'] if 'regex' in kvargs.keys(): regex = kvargs['regex'] if 'output_dir' in kvargs.keys(): output_directory = kvargs['output_dir'] else: output_directory = variables['${path}'] command = kvargs['command'] format = kvargs['format'] root_dir = variables['${OUTPUT_DIR}'] test_case = variables['${testname}'] if format == "text": # tmp_dir = tempfile.mkdtemp(prefix='_') # if output_directory == None: # dirpath = "/collector/" + tmp_dir + "/" + timestamp + "/" # else: # dirpath = output_directory + "/" + tmp_dir + "/" + test_case.replace(" ", "_") + "/commands" # Create directory if does not exist # if not os.path.exists(dirpath): # os.makedirs(dirpath, mode=0777) if regex: try: cmd_to_execute = self._conn.rpc.cli(command) except RpcError as err: rpc_error = err.__repr__() print (xmltodict.parse(rpc_error)['rpc-error']['error-message']) raise FatalError("Error executing RPC,exiting...") operations = command.split("|")[1:] result_tmp = cmd_to_execute.text lines = result_tmp.strip().split('\n') for operation in operations: if re.search("count", operation, re.IGNORECASE): print ('*INFO* Count: %s lines' % len(lines)) return len(lines) match = re.search('match "?(.*)"?', operation, re.IGNORECASE) if match: regex = match.group(1).strip() lines_filtered = [] for line in lines: if re.search(regex, line, re.IGNORECASE): lines_filtered.append(line) lines = lines_filtered match = re.search('except "?(.*)"?', operation, re.IGNORECASE) if match: regex = match.group(1).strip() lines_filtered = [] for line in lines: if re.search(regex, line, re.IGNORECASE): pass else: lines_filtered.append(line) lines = lines_filtered text_matches = re.search(regex, cmd_to_execute.text, re.MULTILINE) if text_matches: print (text_matches.groups()) return text_matches.groups() else: print ("Executing: %s" %command) try: cmd_to_execute = self._conn.rpc.cli(command) except RpcError as err: rpc_error = err.__repr__() print (xmltodict.parse(rpc_error)['rpc-error']['error-message']) raise FatalError("Error executing RPC,exiting...") # #print (type(cmd_to_execute)) # if isinstance(cmd_to_execute, bool): # return True # else: # cmd_clean = command.replace(" ", "_").replace('_"', '_').replace('"_', '_').replace('"', '').replace("/", "_") # filename = timestamp2 + '_'+ self.target + "_" + cmd_clean + "." + "txt" # path = os.path.join(dirpath, filename).replace(root_dir, '.') # print ("Saving file as: %s" %path) # print ('*HTML* <a href="%s" target="_blank">%s</a>' % (path, path)) # try: # with open(path, 'w') as file_to_save: # file_to_save.write(cmd_to_execute.text) # return True # except IOError as err: # print (err.errno, err.strerror) # raise FatalError("Error opening File, exiting...") elif format == "xml": if xpath: print ("Executing: %s [%s]" %(command, xpath)) try: cmd_to_execute = self._conn.rpc.cli(command, format='xml') xml_result = etree.tostring(cmd_to_execute) except RpcError as err: rpc_error = err.__repr__() print (xmltodict.parse(rpc_error)['rpc-error']['error-message']) raise FatalError("Error executing RPC, exiting...") xpath_result = cmd_to_execute.xpath(xpath)[0].text.strip() if xpath_result == None: raise FatalError("XPATH malformed, exiting...") else: print (xpath_result) return xpath_result else: try: cmd_to_execute = self._conn.rpc.cli(command, format='xml') xml_result = etree.tostring(cmd_to_execute) except RpcError as err: rpc_error = err.__repr__() print (xmltodict.parse(rpc_error)['rpc-error']['error-message']) raise FatalError("Error executing RPC, exiting...") return xml_result else: raise FatalError("Format not valid, exiting...") def save_config_to_file(self, **kvargs): """ Function that saves a configuration to a file in a JunOS device """ directory = kvargs['directory'] + '/' + timestamp4 print ("*INFO* Saving current configuration...") file_obj = StartShell(self._conn) file_obj.open() got = file_obj.run("cli -c 'show configuration | save " + directory + "_config.txt' ") file_obj.close() print ("*INFO* %s" % (got)) return got[-2].split("'")[1] def rollback(self, commit_comment='__JRouter__', **kvargs): """ Function that performs rollback rollback_num = number """ rollback_num = kvargs['rollback_num'] try: rollback_num = int(rollback_num) if rollback_num > 50: raise FatalError("Sorry. 'rollback_num' must lower than 50") except Exception as e: raise FatalError("Sorry. 'rollback_num' must be an integer.") if hasattr(self._conn, "candidate"): pass else: self._conn.bind(candidate=Config) try: self._conn.candidate.lock() except LockError as l_error: print ("*WARN* Problems locking configuration: %s" % (l_error)) raise FatalError("Unable to lock configuration... exiting") try: print ("Rolling back configuration....") self._conn.candidate.rollback(rollback_num) self._conn.candidate.commit(comment=commit_comment) self._conn.candidate.unlock() return True except RpcError as err: rpc_error = err.__repr__() raise FatalError(xmltodict.parse(rpc_error)['rpc-error']['error-message']) def _is_dual_RE (self): """ Auxiliar function that returns True if the system is dual-RE and both RE are available """ if self._conn.facts['2RE']: return True else: return False def reboot_re (self,**kvargs): """ Function for rebooting backup RE **kvargs role: master/backup """ try: role = kvargs['role'] except KeyError: raise ContinuableError("Missing Key....role") # Dual RE and role backup if self._is_dual_RE () and role == 'backup': try: print ("Rebooting Backup Routing Engine....") self._conn.rpc.request_reboot(other_routing_engine=True) # sleeping to avoid quick return sleep (60) return True except RpcError as err: raise ContinuableError("Error executing RPC... {0}".format(err)) # Single RE or DUAL-RE system capabable with only 1 available RE else: try: print ("Rebooting Master Routing Engine....") self._conn.rpc.request_reboot() self._conn.close () # sleeping to avoid quick return sleep (60) try: self._conn.open(auto_probe=600) return True except ConnectError as c_error: raise ContinuableError("ERROR: Routing Engine is not Online after 10 min" + str(c_error)) except RpcError as err: raise ContinuableError("Error executing RPC... {0}".format(err)) def switchover(self): """ Function to perfom RE switchover """ # We need to verify that backup RE is ready before proceed b_slot = self.get_slot('backup') b_state = self._conn.rpc.get_route_engine_information(slot=b_slot) state = b_state.findtext('route-engine/mastership-state') if (state != "backup"): raise FatalError("Backup RE is not ready") try: self.open_connection() print ('Executing switchover to complete the SW upgrade !!!') switchover_cmd = self._conn.cli("request chassis routing-engine master switch no-confirm", format='xml', warning=False) self.close_connection() except ConnectError as c_error: raise FatalError(c_error) # except TError.TimeoutExpiredError as Terr: # print (Terr) # pass # except NcErrors.SessionCloseError as Serr: # print (Serr) # pass except SocketError as S_err: print (S_err) pass except ConnectClosedError as CC_error: print (CC_error) pass sleep(60) try: # WA for dealing with in band connections print ("Re-opening connection.......") self._conn.open(auto_probe=900) return True except ConnectError as c_error: raise FatalError(c_error) def reboot (self): """ Function for rebooting both RE """ # Dual RE and role backup try: print ("Rebooting Both Routing Engines....") cmd = self._conn.rpc.request_reboot(both_routing_engines=True) # sleeping to avoid quick return sleep (60) return True except RpcError as err: raise FatalError("Error executing RPC... %s" %err) def get_routing_table(self, **kvargs): """ Function that gathers the routing table from a device. It returns the whole routing table if no route is specified. If route is specified, next_hop can be also specified and routing table nexthop output will be compared against it. """ try: tbl = RouteTable(self._conn) except ConnectError as c_error: raise FatalError(c_error) complete_rt = tbl.get() if 'route' in kvargs.keys(): route = kvargs['route'] print ('route', route) if route != 'None': single_rt = tbl.get(route) # Routing Table dictionary rt = {} for item in tbl: # Remove "RouteTableView:" from item = RouteTableView:0.0.0.0/0 destination = str(item).split(":")[1] rt[destination] = [item.nexthop, item.age, item.via, item.protocol] return rt def pretty_time_delta(self, seconds): """ Helper function that returns formatted time """ sign_string = '-' if seconds < 0 else '' seconds = abs(int(seconds)) days, seconds = divmod(seconds, 86400) hours, seconds = divmod(seconds, 3600) minutes, seconds = divmod(seconds, 60) if days > 0: return '%s%dd%dh%dm%ds' % (sign_string, days, hours, minutes, seconds) elif hours > 0: return '%s%dh%dm%ds' % (sign_string, hours, minutes, seconds) elif minutes > 0: return '%s%dm%ds' % (sign_string, minutes, seconds) else: return '%s%ds' % (sign_string, seconds) def get_config(self, xml_filter=None): """ Function that returns a piece of a JunOS device configuration """ if xml_filter is None: cnf = self._conn.rpc.get_config() else: # Should user wants to filter out configuration and extract only a piece of it # e.g. SNMP #cnf = dev.rpc.get_config(filter_xml=etree.XML('<snmp></snmp>')) # interfaces #cnf = dev.rpc.get_config(filter_xml=etree.XML('<configuration><interfaces/></configuration>')) cnf = self._conn.rpc.get_config(filter_xml=etree.XML(xml_filter)) #print (etree.tostring(cnf)) config = etree.tostring(cnf) #print (config) return config
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') @patch('paramiko.SSHClient') @patch('paramiko.proxy.ProxyCommand') def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy): os_mock.path.exists.return_value = True self.dev._sshconf_path = '/home/rsherman/.ssh/config' with SCP(self.dev) as scp: scp.get('addrbook.conf') mock_proxy.assert_called_any() def test_scp_progress(self): scp = SCP(self.dev) print(scp._scp_progress('test', 100, 50)) @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh): mock_scpclient.return_value = None def fn(file, total, tfd): pass package = 'test.tgz' with SCP(self.dev, progress=fn) as scp: scp.put(package) self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__, 'fn') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_user_def_progress_args_2(self, mock_scpclient, mock_put, mock_ssh): mock_scpclient.return_value = None def myprogress(dev, report): print("host: %s, report: %s" % (dev.hostname, report)) package = 'test.tgz' with SCP(self.dev, progress=myprogress) as scp: scp.put(package) self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__, '_scp_progress') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient): mock_scpclient.return_value = None package = 'test.tgz' with SCP(self.dev, progress=True) as scp: scp.put(package) self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__, '_scp_progress') @contextmanager def capture(self, command, *args, **kwargs): out, sys.stdout = sys.stdout, StringIO() command(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() sys.stdout = out
if int(ipaddr) >= ipnet.first and int(ipaddr) <= ipnet.last: return True else: return False parser = argparse.ArgumentParser(description='Process user input') parser.add_argument("--host", dest="hostname", default="",metavar="HOST",help="Specify host to connect to") parser.add_argument("--username", dest="username", metavar="USERNAME",help="Specify the username") parser.add_argument("--password", dest="password", metavar="PASSWORD",help="Specify the password") parser.add_argument("--subnet", dest="subnet", metavar="SUBNET",help="Specify the subnet to check interfaces against") args = parser.parse_args() if args.hostname != "" and args.username != "" and args.password != "": dev = Device(user=args.username, host=args.hostname, password=args.password) dev.bind(cu=Config) dev.open() cfg = dev.rpc.get_config() dd = xmltodict.parse(ET.tostring(cfg,encoding="utf8", method="xml")) if "configuration" in dd: if "interfaces" in dd["configuration"]: if "interface" in dd["configuration"]["interfaces"]: for i in dd["configuration"]["interfaces"]["interface"]: if "unit" in i: if "family" in i["unit"]: if "inet" in i["unit"]["family"]: if "address" in i["unit"]["family"]["inet"]: if "name" in i["unit"]["family"]["inet"]["address"]: int_name = i["name"] test_ip = string.split(i["unit"]["family"]["inet"]["address"]["name"],"/")[0]
class TestDevice(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'cannot open' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'why are you trying :)' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch('__builtin__.open', mock): with patch('__builtin__.file', MagicMock): handle = open('filename', 'r') self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user='******', password='******', gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) def test_device_repr(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.assertEqual(repr(localdev), 'Device(1.1.1.1)') @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_any() @patch('os.getenv') def test_device__sshconf_lkup_path_not_exists(self, mock_env): mock_env.return_value = '/home/test' self.assertEqual(self.dev._sshconf_lkup(), None) @patch('os.getenv') def test_device__sshconf_lkup_home_not_defined(self, mock_env): mock_env.return_value = None self.assertEqual(self.dev._sshconf_lkup(), None) mock_env.assert_called_with('HOME') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open(self, mock_connect, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch('jnpr.junos.Device.execute') def test_device_facts(self, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() assert self.dev.facts['version'] == facts['version'] def test_device_hostname(self): self.assertEqual(self.dev.hostname, '1.1.1.1') def test_device_user(self): self.assertEqual(self.dev.user, 'rick') def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = '******' self.assertEqual(self.dev._password, 'secret') def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_manages(self): self.assertEqual(self.dev.manages, [], 'By default manages will be empty list') def test_device_set_facts_exception(self): try: self.dev.facts = 'test' except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) @patch('jnpr.junos.Device.execute') def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show cli directory').tag, 'cli') @patch('jnpr.junos.Device.execute') def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration')) @patch('jnpr.junos.Device.execute') def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('Alarm' in self.dev.cli('show system alarms')) @patch('jnpr.junos.Device.execute') def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show system uptime | display xml rpc')\ .tag, 'get-system-uptime-information') def test_device_cli_exception(self): self.dev.rpc.cli = MagicMock(side_effect=AttributeError) val = self.dev.cli('show version') self.assertEqual(val, 'invalid command: show version') def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag, 'directory-list') def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>', to_py=self._do_nothing), 'Nothing') def test_device_execute_exception(self): class MyException(Exception): rpc_err = """ <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <error-severity>error</error-severity> <error-info> <bad-element>get-bgp-summary-information</bad-element> </error-info> <error-message>permission denied</error-message> </rpc-error> """ xml = etree.XML(rpc_err) self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(RpcError, self.dev.execute, '<get-software-information/>') def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.func_doc, 'get-software-information') def test_device_probe_timeout_zero(self): with patch('jnpr.junos.device.socket'): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch('jnpr.junos.device.socket'): self.assertTrue(self.dev.probe(1), 'probe fn is not working for' ' timeout greater than zero') def test_device_probe_timeout_exception(self): with patch('jnpr.junos.device.socket') as mock_socket: with patch('jnpr.junos.device.time.sleep') as mock_time: mock_socket.socket.return_value.close.side_effect \ = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic_mock' self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock') def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = 'Test' self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, 'Test') def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' #for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' #for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template('tests/unit/templates/config-example') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example') except: raise self.assertEqual(template.render({'host_name': '1', 'domain_name': '2'}), 'system {\n host-name 1;\n domain-name 2;\n}') def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name='close') self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) foo = open(fpath).read() if (fname == 'get-rpc-error.xml' or fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply()) elif (fname == 'show-configuration.xml' or fname == 'show-system-alarms.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc else: rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') elif args[0].text == 'show configuration': return self._read_file('show-configuration.xml') elif args[0].text == 'show system alarms': return self._read_file('show-system-alarms.xml') elif args[0].text == 'show system uptime | display xml rpc': return self._read_file('show-system-uptime-rpc.xml') else: raise RpcError else: return self._read_file(args[0].tag + '.xml') def _do_nothing(self, *args, **kwargs): return 'Nothing'
class TestScp(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') @patch('paramiko.SSHClient') def test_scp_open(self, mock_connect): from scp import SCPClient self.dev.bind(scp=SCP) assert isinstance(self.dev.scp.open(), SCPClient) @patch('paramiko.SSHClient') def test_scp_close(self, mock_connect): self.dev.bind(scp=SCP) self.dev.scp.open() self.assertEqual(self.dev.scp.close(), None) @patch('paramiko.SSHClient') def test_scp_context(self, mock_connect): with SCP(self.dev) as scp: scp.get('addrbook.conf') @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') @patch('paramiko.SSHClient') @patch('paramiko.proxy.ProxyCommand') def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy): os_mock.path.exists.return_value = True self.dev._sshconf_path = '/home/rsherman/.ssh/config' with SCP(self.dev) as scp: scp.get('addrbook.conf') mock_proxy.assert_called_any() def test_scp_progress(self): scp = SCP(self.dev) print scp._scp_progress('test', 100, 50) @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh): mock_scpclient.return_value = None def fn(file, total, tfd): pass package = 'test.tgz' with SCP(self.dev, progress=fn) as scp: scp.put(package) self.assertEqual( mock_scpclient.mock_calls[0][2]['progress'].func_name, 'fn') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') @patch('scp.SCPClient.__init__') def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient): mock_scpclient.return_value = None package = 'test.tgz' with SCP(self.dev, progress=True) as scp: scp.put(package) self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].func_name, '_scp_progress') @contextmanager def capture(self, command, *args, **kwargs): out, sys.stdout = sys.stdout, StringIO() command(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() sys.stdout = out
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.timeout = self.timeout self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff.strip() def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config() def get_facts(self): output = self.device.facts uptime = 0 if 'RE0' in output: uptime = output['RE0']['up_time'] interfaces = junos_views.junos_iface_table(self.device) interfaces.get() interface_list = interfaces.keys() return { 'vendor': u'Juniper', 'model': unicode(output['model']), 'serial_number': unicode(output['serialnumber']), 'os_version': unicode(output['version']), 'hostname': unicode(output['hostname']), 'fqdn': unicode(output['fqdn']), 'uptime': string_parsers.convert_uptime_string_seconds(uptime), 'interface_list': interface_list } def get_interfaces(self): # init result dict result = {} interfaces = junos_views.junos_iface_table(self.device) interfaces.get() # convert all the tuples to our pre-defined dict structure for iface in interfaces.keys(): result[iface] = { 'is_up': interfaces[iface]['is_up'], 'is_enabled': interfaces[iface]['is_enabled'], 'description': interfaces[iface]['description'] or u'', 'last_flapped': interfaces[iface]['last_flapped'] or -1, 'mac_address': unicode(interfaces[iface]['mac_address']) } result[iface]['last_flapped'] = float(result[iface]['last_flapped']) match = re.search(r'\d+', interfaces[iface]['speed'] or '') if match is not None: result[iface]['speed'] = int(match.group(0)) else: result[iface]['speed'] = -1 return result def get_interfaces_counters(self): query = junos_views.junos_iface_counter_table(self.device) query.get() interface_counters = dict() for interface, counters in query.items(): interface_counters[interface] = {k: v or -1 for k, v in counters} return interface_counters def get_environment(self): environment = junos_views.junos_enviroment_table(self.device) routing_engine = junos_views.junos_routing_engine_table(self.device) temperature_thresholds = junos_views.junos_temperature_thresholds(self.device) environment.get() routing_engine.get() temperature_thresholds.get() environment_data = dict() for sensor_object, object_data in environment.items(): structured_object_data = {k: v for k, v in object_data} if structured_object_data['class'] == 'Power': # Create a dict for the 'power' key try: environment_data['power'][sensor_object] = dict() except KeyError: environment_data['power'] = dict() environment_data['power'][sensor_object] = dict() # Set these values to -1, because Junos does not provide them environment_data['power'][sensor_object]['capacity'] = -1.0 environment_data['power'][sensor_object]['output'] = -1.0 if structured_object_data['class'] == 'Fans': # Create a dict for the 'fans' key try: environment_data['fans'][sensor_object] = dict() except KeyError: environment_data['fans'] = dict() environment_data['fans'][sensor_object] = dict() if structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Power': # If status is Failed, Absent or Testing, set status to False. environment_data['power'][sensor_object]['status'] = True elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Power': environment_data['power'][sensor_object]['status'] = False elif structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Fans': # If status is Failed, Absent or Testing, set status to False. environment_data['fans'][sensor_object]['status'] = True elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Fans': environment_data['fans'][sensor_object]['status'] = False for temperature_object, temperature_data in temperature_thresholds.items(): structured_temperature_data = {k: v for k, v in temperature_data} if structured_object_data['class'] == 'Temp': # Create a dict for the 'temperature' key try: environment_data['temperature'][sensor_object] = dict() except KeyError: environment_data['temperature'] = dict() environment_data['temperature'][sensor_object] = dict() environment_data['temperature'][sensor_object]['temperature'] = float(structured_object_data['temperature']) # Set a default value (False) to the key is_critical and is_alert environment_data['temperature'][sensor_object]['is_alert'] = False environment_data['temperature'][sensor_object]['is_critical'] = False # Check if the working temperature is equal to or higher than alerting threshold if structured_temperature_data['red-alarm'] <= structured_object_data['temperature']: environment_data['temperature'][sensor_object]['is_critical'] = True environment_data['temperature'][sensor_object]['is_alert'] = True elif structured_temperature_data['yellow-alarm'] <= structured_object_data['temperature']: environment_data['temperature'][sensor_object]['is_alert'] = True for routing_engine_object, routing_engine_data in routing_engine.items(): structured_routing_engine_data = {k: v for k, v in routing_engine_data} # Create dicts for 'cpu' and 'memory'. try: environment_data['cpu'] = dict() environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() except KeyError: environment_data['cpu'] = dict() environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() # Calculate the CPU usage by using the CPU idle value. environment_data['cpu'][routing_engine_object]['%usage'] = 100 - structured_routing_engine_data['cpu-idle'] environment_data['memory']['available_ram'] = structured_routing_engine_data['memory-dram-size'] # Junos gives us RAM in %, so calculation has to be made. # Sadly, bacause of this, results are not 100% accurate to the truth. environment_data['memory']['used_ram'] = (structured_routing_engine_data['memory-dram-size'] / 100 * structured_routing_engine_data['memory-buffer-utilization']) return environment_data # def get_bgp_neighbors(self): # # # init result dict # result = {} # # instances = junos_views.junos_route_instance_table(self.device) # instances.get() # # for vrf in instances.keys(): # if not vrf.startswith('__'): # # # init result dict for this vrf # result[vrf] = { # 'peers': {}, # 'router_id': None, # 'local_as': None, # } # # # fetch sessions for vrf # bgp = junos_views.junos_bgp_table(self.device) # bgp.get(instance=vrf) # # # assemble result dict # bgp_result = {} # [bgp_result.update({neigh:dict(bgp[neigh])}) for neigh in bgp.keys()] # result[vrf]['peers'] = bgp_result # # return result @staticmethod def _get_address_family(table): """ Function to derive address family from a junos table name :params table: The name of the routing table :returns: address family """ address_family_mapping = { 'inet': 'ipv4', 'inet6': 'ipv6' } family = table.split('.')[-2] return address_family_mapping[family] def _parse_route_stats(self, neighbor): data = {} if not neighbor['is_up']: pass elif isinstance(neighbor['tables'], list): for idx, table in enumerate(neighbor['tables']): family = self._get_address_family(table) data[family] = {} data[family]['received_prefixes'] = neighbor['received_prefixes'][idx] data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'][idx] data[family]['sent_prefixes'] = neighbor['sent_prefixes'][idx] else: family = self._get_address_family(neighbor['tables']) data[family] = {} data[family]['received_prefixes'] = neighbor['received_prefixes'] data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'] data[family]['sent_prefixes'] = neighbor['sent_prefixes'] return data @staticmethod def _parse_value(value): if isinstance(value, basestring): return unicode(value) elif value is None: return u'' else: return value def get_bgp_neighbors(self): instances = junos_views.junos_route_instance_table(self.device) uptime_table = junos_views.junos_bgp_uptime_table(self.device) bgp_neighbors = junos_views.junos_bgp_table(self.device) keys =['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id'] bgp_neighbor_data = {} for instance, instance_data in instances.get().items(): if instance.startswith('__'): # junos internal instances continue instance_name = "global" if instance == 'master' else instance bgp_neighbor_data[instance_name] = {'peers': {}} for neighbor, data in bgp_neighbors.get(instance=instance).items(): neighbor_data = {k: v for k, v in data} peer_ip = neighbor.split('+')[0] if 'router_id' not in bgp_neighbor_data[instance_name]: # we only need to set this once bgp_neighbor_data[instance_name]['router_id'] = unicode(neighbor_data['local_id']) peer = {key:self._parse_value(value) for key, value in neighbor_data.iteritems() if key in keys} peer['address_family'] = self._parse_route_stats(neighbor_data) bgp_neighbor_data[instance_name]['peers'][peer_ip] = peer for neighbor, uptime in uptime_table.get(instance=instance).items(): bgp_neighbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1] for key in bgp_neighbor_data.keys(): if not bgp_neighbor_data[key]['peers']: del bgp_neighbor_data[key] return bgp_neighbor_data def get_lldp_neighbors(self): lldp = junos_views.junos_lldp_table(self.device) lldp.get() result = lldp.items() neighbors = dict() for neigh in result: if neigh[0] not in neighbors.keys(): neighbors[neigh[0]] = list() neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]}) return neighbors
from jnpr.junos import Device from jnpr.junos.utils.config import Config #template variables are added to a dict or dictionary. A dict is simply a key/value store data structure my_variables = {"hostname":"JNPRConfig-ez-set","enc_password":"******","ssh_root_login":"******"} #now lets connect to the device, load the template, and commit the changes #first we instantiate an instance of the device junos_dev = Device(host='172.16.237.128', user='******', password='******' ) #We must bind an empty configuration to the device junos_dev.bind(cu=Config) #now we can connect to the device junos_dev.open() #lets go ahead and load the configuration. We are reading fromt he local directory and specifying the jnpr-config.conf file #the file exension specifies the config type of config stored in the file junos_dev.cu.load(template_path="./set-config.set",merge=True,template_vars=my_variables) #commit and close the config commit_result = junos_dev.cu.commit() #Show that the commit worked True means it worked, false means it failed print commit_result #lastly we close the connection to the device junos_dev.close()
from jnpr.junos import Device from jnpr.junos.utils.config import Config r0 = Device(host='172.16.1.254', user='******', password='******').open() r0.bind(cu=Config) r0.cu from lxml import etree result = r0.cu.load(path='border1-template.set') etree.dump(result)
import paramiko import os, sys from jnpr.junos import Device as Netconf # local import from uac import UAC if len(sys.argv) < 2: print "you must provide a Junos target hostname" sys.exit(1) # going to use paramiko SSHConfig to retrieve the port parameters for a given # host. Doing this because I tend to use jumphosts to get to devices behind # firewalls/etc. This is a pretty useful technique to illustrate: junos_hostname = sys.argv[1] config_file = os.path.join(os.getenv('HOME'),'.ssh/config') ssh_config = paramiko.SSHConfig() ssh_config.parse(open(config_file,'r')) got_lkup = ssh_config.lookup( junos_hostname ) dev = Netconf(user='******',host=got_lkup['hostname'],port=got_lkup['port']) dev.open() dev.bind(uac=UAC) dev.uac.get_users() print "UAC users:" print dev.uac.usernames
class TestDevice(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_new_console_return(self): dev = Device(host='1.1.1.1', user='******', password='******', port=23, gather_facts=False) self.assertTrue(isinstance(dev, Console)) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError( "Could not open socket to 1.1.1.1:830") from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'why are you trying :)' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [currenttime, currenttime + timedelta(minutes=4)] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_probe_error(self): mock_probe = MagicMock() mock_probe.return_value = None self.dev.probe = mock_probe def fn(): self.dev.open(auto_probe=1) self.assertRaises(EzErrors.ProbeError, fn) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch(builtin_string + '.open', mock): if sys.version > '3': builtin_file = 'io.TextIOWrapper' else: builtin_file = builtin_string + '.file' with patch(builtin_file, MagicMock): handle = open('filename', 'r') self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user='******', password='******', gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) def test_device_master_is_master(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re1', 'master', 'node', 'fwdd', 'member', 'pfem'] self.assertEqual(localdev.master, True) def test_device_master_is_backup(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re0', 'backup'] self.assertEqual(localdev.master, False) def test_device_master_is_re0_only(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = False localdev.facts._cache['RE_hw_mi'] = False localdev.facts._cache['current_re'] = ['re0'] self.assertEqual(localdev.master, True) def test_device_master_is_multi_chassis_non_master1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1', 'lcc1-backup', 'member1-backup'] self.assertEqual(localdev.master, False) def test_device_master_is_multi_chassis_non_master2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0', 'lcc1-master', 'member1-master', 'member1'] self.assertEqual(localdev.master, False) def test_device_master_is_none1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = None self.assertEqual(localdev.master, None) def test_device_master_is_none2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['2RE'] = True localdev.facts._cache['current_re'] = ['foo', 'bar'] self.assertEqual(localdev.master, None) @patch('jnpr.junos.device.warnings') def test_device_master_is_old_facts(self, mock_warn): localdev = Device(host='1.1.1.1', user='******', password='******', fact_style='old', gather_facts=False) mock_warn.assert_has_calls([call.warn('fact-style old will be removed ' 'in a future release.', RuntimeWarning)]) self.assertEqual(localdev.master, None) def test_device_master_setter(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) with self.assertRaises(RuntimeError): localdev.master = 'foo' def test_device_re_name_is_re0(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re0', 'backup'] localdev.facts._cache['hostname_info'] = {'re0': 'tapir', 're1': 'tapir1'} self.assertEqual(localdev.re_name, 're0') def test_device_re_name_is_lcc_re1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1', 'lcc1-backup', 'member1-backup'] localdev.facts._cache['hostname_info'] = {'re0': 'mj1'} self.assertEqual(localdev.re_name, 'lcc1-re1') def test_device_re_name_is_re0_only(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['foo'] localdev.facts._cache['hostname_info'] = {'re0': 'mj1'} self.assertEqual(localdev.re_name, 're0') def test_device_re_name_is_none1(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = None self.assertEqual(localdev.re_name, None) def test_device_re_name_is_none2(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) localdev.facts._cache['current_re'] = ['re1', 'master', 'node', 'fwdd', 'member', 'pfem'] localdev.facts._cache['hostname_info'] = None self.assertEqual(localdev.re_name, None) @patch('jnpr.junos.device.warnings') def test_device_re_name_is_old_facts(self, mock_warn): localdev = Device(host='1.1.1.1', user='******', password='******', fact_style='old', gather_facts=False) mock_warn.assert_has_calls([call.warn('fact-style old will be removed ' 'in a future release.', RuntimeWarning)]) self.assertEqual(localdev.re_name, None) def test_device_re_name_setter(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) with self.assertRaises(RuntimeError): localdev.re_name = 'foo' def test_device_repr(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.assertEqual(repr(localdev), 'Device(1.1.1.1)') def test_device_local(self): Device.ON_JUNOS = True localdev = Device() self.assertEqual(localdev._hostname, 'localhost') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._ssh_config = '/home/rsherman/.ssh/config' self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('os.getenv') def test_device__sshconf_lkup_path_not_exists(self, mock_env): mock_env.return_value = '/home/test' self.assertEqual(self.dev._sshconf_lkup(), None) @patch('os.getenv') def test_device__sshconf_lkup_home_not_defined(self, mock_env): mock_env.return_value = None self.assertEqual(self.dev._sshconf_lkup(), None) mock_env.assert_called_with('HOME') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open(self, mock_connect, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device( host='2.2.2.2', user='******', password='******') self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch('jnpr.junos.Device.execute') def test_device_facts(self, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() self.dev.facts._cache['current_re'] = ['re0'] assert self.dev.facts['version'] == facts['version'] @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.factcache.warnings') def test_device_facts_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.dev.facts_refresh(warnings_on_failure=True) self.assertTrue(mock_warnings.warn.called) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_facts_error_exception_on_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_old_style_facts_error_exception_on_error(self, mock_warnings, mock_execute): self.dev._fact_style = 'old' with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) def test_device_facts_refresh_unknown_fact_style(self): self.dev._fact_style = 'bad' with self.assertRaises(RuntimeError): self.dev.facts_refresh() def test_device_facts_refresh_old_fact_style_with_keys(self): self.dev._fact_style = 'old' with self.assertRaises(RuntimeError): self.dev.facts_refresh(keys='domain') def test_device_hostname(self): self.assertEqual(self.dev.hostname, '1.1.1.1') def test_device_user(self): self.assertEqual(self.dev.user, 'test') def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = '******' self.assertEqual(self.dev._auth_password, 'secret') def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_set_timeout_string(self): self.dev.timeout = '10' self.assertEqual(self.dev.timeout, 10) def test_device_set_timeout_invalid_string_value(self): with self.assertRaises(RuntimeError): self.dev.timeout = 'foo' def test_device_set_timeout_invalid_type(self): with self.assertRaises(RuntimeError): self.dev.timeout = [1,2,3,4] def test_device_manages(self): self.assertEqual(self.dev.manages, [], 'By default manages will be empty list') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open_normalize(self, mock_connect, mock_execute): mock_connect.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open(gather_facts=False, normalize=True) self.assertEqual(self.dev2.transform, self.dev2._norm_transform) def test_device_set_facts_exception(self): try: self.dev.facts = 'test' except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) def test_device_ofacts_exception(self): with self.assertRaises(RuntimeError): ofacts = self.dev.ofacts def test_device_set_ofacts_exception(self): with self.assertRaises(RuntimeError): self.dev.ofacts = False @patch('jnpr.junos.Device.execute') def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show cli directory', warning=False).tag, 'cli') @patch('jnpr.junos.device.json.loads') def test_device_rpc_json_ex(self, mock_json_loads): self.dev.facts = facts self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) ex = ValueError('Extra data ') ex.message = 'Extra data ' # for py3 as we dont have message thr mock_json_loads.side_effect = [ ex, self._mock_manager(etree.fromstring( '<get-route-information format="json"/>'))] self.dev.rpc.get_route_information({'format': 'json'}) self.assertEqual(mock_json_loads.call_count, 2) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('show system uptime') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show system uptime | match foo | count') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_complex(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show interfaces ge-0/0/0.0 routing-instance all media') self.assertEqual("rpc.get_interface_information(" "routing_instance='all', media=True, " "interface_name='ge-0/0/0.0')", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_invalid(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('foo') self.assertEqual(None, data) @patch('jnpr.junos.Device.execute') def test_device_cli_format_json(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli('show interface terse', warning=False, format='json') self.assertEqual(type(data), dict) self.assertEqual(data['interface-information'][0] ['physical-interface'][0]['oper-status'][0]['data'], 'up') @patch('jnpr.junos.Device.execute') def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('Alarm' in self.dev.cli('show system alarms', warning=False)) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_cli_output_warning(self, mock_warnings, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance ' 'all media', format='xml') ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/' 'address-family[address-family-name="inet"]/' 'interface-address/ifa-local') self.assertTrue('192.168.100.1' in ip) self.assertTrue(mock_warnings.warn.called) rpc_string = "rpc.get_interface_information(routing_instance='all', "\ "media=True, interface_name='ge-0/0/0.0')" self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0]) def test_device_cli_blank_output(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual('', self.dev.cli('show configuration interfaces', warning=False)) def test_device_cli_rpc_reply_with_message(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( '\nprotocol: operation-failed\nerror: device asdf not found\n', self.dev.cli('show interfaces terse asdf', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show system uptime| display xml rpc', warning=False) .tag, 'get-system-uptime-information') def test_device_cli_exception(self): self.dev.rpc.cli = MagicMock(side_effect=AttributeError) val = self.dev.cli('show version') self.assertEqual(val, 'invalid command: show version') @patch('jnpr.junos.Device.execute') def test_device_cli_rpc_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager val = self.dev.cli('foo') self.assertEqual(val, 'invalid command: foo: RpcError') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show system uptime').tag, 'get-system-uptime-information') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc_text(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertIn( '<get-system-uptime-information>', self.dev.display_xml_rpc( 'show system uptime', format='text')) @patch('jnpr.junos.Device.execute') def test_device_display_xml_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show foo'), 'invalid command: show foo| display xml rpc') def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag, 'directory-list') def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual(self.dev.execute('<get-system-core-dumps/>', to_py=self._do_nothing), 'Nothing') # This test is for the commented out rpc-error code # def test_device_execute_exception(self): # self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) # self.assertRaises(RpcError, self.dev.execute, # '<load-configuration-error/>') @patch('jnpr.junos.device.warnings') def test_device_execute_unknown_exception(self, mock_warnings): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.execute, '<get-software-information/>') def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) def test_device_execute_permission_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises( EzErrors.PermissionError, self.dev.rpc.get_permission_denied) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_execute_unopened(self): self.dev.connected = False self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None) def test_device_execute_timeout(self): self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError) self.assertRaises( EzErrors.RpcTimeoutError, self.dev.rpc.get_rpc_timeout) def test_device_execute_closed(self): self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError) self.assertRaises( EzErrors.ConnectClosedError, self.dev.rpc.get_rpc_close) self.assertFalse(self.dev.connected) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.__doc__, 'get-software-information') def test_device_probe_timeout_zero(self): with patch('jnpr.junos.device.socket'): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch('jnpr.junos.device.socket'): self.assertTrue(self.dev.probe(1), 'probe fn is not working for' ' timeout greater than zero') def test_device_probe_timeout_exception(self): with patch('jnpr.junos.device.socket') as mock_socket: with patch('jnpr.junos.device.time.sleep') as mock_time: mock_socket.socket.return_value.close.side_effect \ = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic_mock' self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock') def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = 'Test' self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, 'Test') def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template( 'tests/unit/templates/config-example.xml') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example.xml') except: raise self.assertEqual(template.render({'host_name': '1', 'domain_name': '2'}), 'system {\n host-name 1;\n domain-name 2;\n}') def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name='close') self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) @patch('ncclient.manager.connect') def test_device_context_manager(self, mock_connect): mock_connect.side_effect = self._mock_manager try: with Device(host='3.3.3.3', user='******', password='******', gather_facts=False) as dev: self.assertTrue(dev.connected) dev._conn = MagicMock(name='_conn') dev._conn.connected = True def close_conn(): dev.connected = False dev.close = MagicMock(name='close') dev.close.side_effect = close_conn raise RpcError except Exception as e: self.assertIsInstance(e, RpcError) self.assertFalse(dev.connected) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) with open(fpath) as fp: foo = fp.read() if fname == 'get-rpc-error.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif fname == 'get-permission-denied.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif (fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.xml' or fname == 'load-configuration-error.xml' or fname == 'show-configuration-interfaces.xml' or fname == 'show-interfaces-terse-asdf.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply()) elif (fname == 'show-configuration.xml' or fname == 'show-system-alarms.xml'): rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc elif fname == 'show-interface-terse.json': rpc_reply = json.loads(foo) elif fname == 'get-route-information.json': rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply()) else: rpc_reply = NCElement(foo, self.dev._conn._device_handler .transform_reply())._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs and 'normalize' not in kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') if args[0].text == 'show interface terse': return self._read_file('show-interface-terse.json') elif args[0].text == 'show configuration': return self._read_file('show-configuration.xml') elif args[0].text == 'show system alarms': return self._read_file('show-system-alarms.xml') elif args[0].text == 'show system uptime| display xml rpc': return self._read_file('show-system-uptime-rpc.xml') elif args[0].text == 'show configuration interfaces': return self._read_file('show-configuration-interfaces.xml') elif args[0].text == 'show interfaces terse asdf': return self._read_file('show-interfaces-terse-asdf.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media': return self._read_file( 'show-interfaces-routing-instance-media.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media| display ' \ 'xml rpc': return self._read_file( 'show-interfaces-routing-instance-media-rpc.xml') else: raise RpcError else: if args[0].attrib.get('format') == 'json': return self._read_file(args[0].tag + '.json') return self._read_file(args[0].tag + '.xml') def _do_nothing(self, *args, **kwargs): return 'Nothing'
def main(): hosts = config.get('hosts') for host in hosts: dev = Device(host=host, user=user, password=password) # Open Connection try: dev.open() except Exception as err: print("Cannot connect to device: {}".format(err)) return dev.bind(cu=Config) # Lock the configuration, load changes, commit print("Locking the configuration on: {}".format(host)) try: dev.cu.lock() except LockError: print("Error: Unable to lock configuration on: {}".format(host)) dev.close() return print("Loading configuration changes on: {}".format(host)) try: # If your devices don't already have NTP configured, comment out # the next 4 lines set_commands = """ delete system ntp """ dev.cu.load(set_commands, format='set') dev.cu.load(template_path=template, template_vars=config, format='text') except ValueError as err: print(err.message) except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') print("Unable to load config changes: {}".format(rpc_msg)) print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close() return print("Committing the configuration on: {}".format(host)) try: dev.cu.commit() # print dev.cu.diff() except CommitError: print("Error: Unable to commit configuration") print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close() return print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print("Error: Unable to unlock configuration") dev.close()
from pprint import pprint as pp from lxml import etree # for the example ... from jnpr.junos import Device as Junos from jnpr.junos.cfg.srx.nat import NatStaticRuleSet from jnpr.junos.utils.config import Config # create a junos device and open a connection jdev = Junos(user='******', password='******', host='vsrx_cyan') jdev.open() # now metabind some resource managers jdev.bind( cu=Config ) jdev.bind( nat=NatStaticRuleSet ) # create a static NAT ruleset called 'outside' and map it on the from-zone "OUTSIDE-DC-STD1" nat = jdev.nat["outside"] nat(zone_from="OUTSIDE-DC-ST1") nat.write() # now create a rule within that ruleset called "foo" to static NAT 198.18.11.5 to 10.0.0.4 # for port 80. Also enable proxy-arp on interface reth0.213" r = nat.rule["foo"] r(match_dst_addr="198.18.11.5", match_dst_port="80", nat_addr="10.0.0.4", nat_port="80") r(proxy_interface="reth0.213") r.write()
from lxml import etree # for the example ... from jnpr.junos import Device as Junos from jnpr.junos.cfg.srx.nat import NatSrcPool, NatSrcRuleSet from jnpr.junos.utils.config import Config # create a junos device and open a connection login = dict(user='******', host='vsrx_cyan', password='******') jdev = Junos(**login) jdev.open() # now metabind some resource managers jdev.bind(cu=Config) jdev.bind(np=NatSrcPool) jdev.bind(nr=NatSrcRuleSet) # create a NAT source pool called 'POOL-A' with # an address range from 198.18.0.1/32 to 198.18.0.10/32 # here showing the technique to change property values # by making a "call" into the resource r = jdev.np["POOL-A"] r(addr_from="198.18.0.1", addr_to="198.18.0.10") r.write() # create a NAT source ruleset called "OUTBOUND_NAT" # for a given zone-context matching on all traffic # using HTTP (port-80), let's assume this is a compelely
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.timeout = 60 self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff.strip() def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config() def get_facts(self): output = self.device.facts uptime = 0 if 'RE0' in output: uptime = output['RE0']['up_time'] interfaces = junos_views.junos_iface_table(self.device) interfaces.get() interface_list = interfaces.keys() return { 'vendor': u'Juniper', 'model': unicode(output['model']), 'serial_number': unicode(output['serialnumber']), 'os_version': unicode(output['version']), 'hostname': unicode(output['hostname']), 'fqdn': unicode(output['fqdn']), 'uptime': string_parsers.convert_uptime_string_seconds(uptime), 'interface_list': interface_list } def get_interfaces(self): # init result dict result = {} interfaces = junos_views.junos_iface_table(self.device) interfaces.get() # convert all the tuples to our pre-defined dict structure for iface in interfaces.keys(): result[iface] = { 'is_up': interfaces[iface]['is_up'], 'is_enabled': interfaces[iface]['is_enabled'], 'description': interfaces[iface]['description'] or u'', 'last_flapped': interfaces[iface]['last_flapped'] or -1, 'mac_address': unicode(interfaces[iface]['mac_address']) } result[iface]['last_flapped'] = float( result[iface]['last_flapped']) match = re.search(r'\d+', interfaces[iface]['speed'] or '') if match is not None: result[iface]['speed'] = int(match.group(0)) else: result[iface]['speed'] = -1 return result # def get_bgp_neighbors(self): # # # init result dict # result = {} # # instances = junos_views.junos_route_instance_table(self.device) # instances.get() # # for vrf in instances.keys(): # if not vrf.startswith('__'): # # # init result dict for this vrf # result[vrf] = { # 'peers': {}, # 'router_id': None, # 'local_as': None, # } # # # fetch sessions for vrf # bgp = junos_views.junos_bgp_table(self.device) # bgp.get(instance=vrf) # # # assemble result dict # bgp_result = {} # [bgp_result.update({neigh:dict(bgp[neigh])}) for neigh in bgp.keys()] # result[vrf]['peers'] = bgp_result # # return result def get_lldp_neighbors(self): lldp = junos_views.junos_lldp_table(self.device) lldp.get() result = lldp.items() neighbors = dict() for neigh in result: if neigh[0] not in neighbors.keys(): neighbors[neigh[0]] = list() neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]}) return neighbors
def main(): dev = Device(host=host) # open a connection with the device and start a NETCONF session try: dev.open() except Exception as err: print "Cannot connect to device:", err return dev.bind( cu=Config ) # Lock the configuration, load configuration changes, and commit print "Locking the configuration" try: dev.cu.lock() except LockError: print "Error: Unable to lock configuration" dev.close() return print "Loading configuration changes" try: dev.cu.load(path=conf_file, merge=True) except ValueError as err: print err.message except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') print "Unable to load configuration changes: ", rpc_msg print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" dev.close() return print "Committing the configuration" try: dev.cu.commit() except CommitError: print "Error: Unable to commit configuration" print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" dev.close() return print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" # End the NETCONF session and close the connection dev.close()
import pdb from pprint import pprint as pp from lxml import etree from lxml.builder import E # for the example ... from jnpr.junos import Device from jnpr.junos.utils import Config # create a junos device and open a connection jdev = Device('jnpr-dc-fw') jdev.open() jdev.bind( cu=Config ) def show_diff_and_rollback(): # dump the diff: print jdev.cu.diff() # [edit system] # - host-name jnpr-dc-fw; # + host-name jeremy; # + domain-name jeremy.com; print "Rolling back...." jdev.cu.rollback() set_commands = """ set system host-name jeremy set system domain-name jeremy.com """
show_help() try: book_name = sys.argv[1] find_addr = sys.argv[2] except: die("You must specify the ip-addr to locate") jdev = Junos(user='******', host='vsrx_x46', password='******') jdev.open() # meta-toolbox the config-utils package onto this object, # this gives us access to: jdev.ez.cu.<functions> jdev.bind(ab=SharedAddrBook) book = jdev.ab[book_name] if not book.exists: die("Book %s does not exist on this device!" % book_name) def do_find_addr(find_addr): print "Searching for address: " + find_addr f = AddrBookFinder(book) r = f.find(find_addr) print "\nAll items:" pp(r.items) print "\nJust matching address items:"