def setDescription(ipAddress, interface, junosUsername, junosPassword, description): dev = Device(host=ipAddress, user=junosUsername, password=junosPassword, port=22) try: dev.open(auto_probe=5) except: return {"Error": "Connection refused"} dev.timeout=120 conf=Config(dev) configString = 'set interfaces '+ str(interface)+' description \"'+description+'\"' try: conf.load(configString, format='set') except: dev.close() return {"Error": "Failed to load config"} try: conf.commit() except: try: #if the commit failes, we try to rollback the changes conf.rollback(rb_id=0) except: dev.close() dev.close() return {"Error": "Failed to commit config"} return {"Success": "Successfully commited interface description"}
def config_set_roll_loop(host_name, user_name, password, rollbackloop_timer): #function definition try: #try/except block for exception handling print "Started executing the script" counter = 0 #Start config mode config_set = ''' set interfaces xe-0/0/30 enable set interfaces xe-0/0/31 enable set interfaces xe-0/0/32 enable ''' #Paste config replacing above 3 lines in set format dev = Device(host=host_name, user=user_name, password=password) dev.open() dev.timeout = 300 config = Config(dev) config.load(config_set, format="set", merge=True) config.commit(timeout=60) time.sleep(60) print "Committed the config, rollback loop will be initiated" while True: config.rollback(1) config.commit(timeout=60) counter += 1 print "Round %s" % counter time.sleep(rollbackloop_timer) dev.close() except KeyboardInterrupt: print "\nProgram terminated from key board" except: print "\nError occurred while testing, validate parameters entered"
def trunkVLANdelete(ipAddress, interface, junosUsername, junosPassword, vlan): dev = Device(host=ipAddress, user=junosUsername, password=junosPassword, port=22) try: dev.open(auto_probe=5) except: return {"Error": "Connection refused"} dev.timeout=120 conf=Config(dev) #deletes the vlans configString = 'delete interfaces {}.0 family ethernet-switching vlan members {}'.format(interface, vlan) try: conf.load(configString, format='set') except: dev.close() return {"Error": "Failed to load config"} try: conf.commit() except: try: #if the commit failes, we try to rollback the changes conf.rollback(rb_id=0) except: dev.close() dev.close() return {"Error": "Failed to commit config"} return {"Success": "Successfully commited interface description"}
class JuniperObject(object): def __init__(self, jnp_dev): self.conn = jnp_dev self.config = None self.ports = {} self.routes = {} def __get_ports(self): self.ports = EthPortTable(self.conn) self.ports.get() def __get_routes(self): self.routes = RouteTable(self.conn) self.routes.get() def config_mode(self): self.config = Config(self.conn) self.config.lock() def send_command(self, command, cmd_format, cmd_merge): self.config.load(command, format=cmd_format, merge=cmd_merge) def file_command(self, file_path, file_format, file_merge): self.config.load(path=file_path, format=file_format, merge=file_merge) def get_diff(self): return self.config.diff() def commit(self, comment=None): self.config.commit(comment=comment) def rollback(self): self.config.rollback(0) def unlock(self): self.config.unlock() def show_all_interfaces(self): self.__get_ports() print "Juniper SRX Interface Statistics" for my_key in self.ports.keys(): print "---------------------------------" print my_key + ":" print "Operational Status: " + self.ports[my_key]['oper'] print "Packets In: " + self.ports[my_key]['rx_packets'] print "Packets Out: " + self.ports[my_key]['tx_packets'] def show_all_routes(self): self.__get_routes() print "Juniper SRX Routing Table" for my_key in self.routes.keys(): print "---------------------------------" print my_key + ":" print " Next Hop: {}".format(self.routes[my_key]['nexthop']) print " Age: {}".format(self.routes[my_key]['age']) print " via: {}".format(self.routes[my_key]['via']) print " Protocol: {}".format(self.routes[my_key]['protocol'])
def pyez_commit(task: Task, ) -> Result: device = task.host.get_connection(CONNECTION_NAME, task.nornir.config) device.timeout = 300 config = Config(device) if config.commit_check() == True: config.commit() else: config.rollback() config.unlock() return Result(host=task.host, result=f"Successfully committed")
def provision(conn, junosConfig, config_format): log.debug("entered provision") log.debug("config mode set to %s", config_format) loadResult = None if (conn == None): log.error("the NETCONF session to the router is not open") return False if (junosConfig == None): log.error("no configuration found") return False log.debug("instantiating config object ...") co = Config(conn) try: if (config_format == "xml"): loadResult = co.load(junosConfig, "xml") elif (config_format == "text"): loadResult = co.load(junosConfig, "text") elif (config_format == "set"): loadResult = co.load(junosConfig, "set") if (loadResult): if (co.commit_check()): print("the configuration has been validated") print("") print("presenting the diff:") print("") co.pdiff() print("") print("committing the configuration ...") print("") co.commit() return True else: return False except Exception as e: log.error("could not provision the router") log.error(e.message) log.error("rolling back the configuration ...") co.rollback() return False
def commitconfig(commitcheck, device, username, password): commit_config = raw_input('Would you like to commit? ') if commitcheck == True and commit_config.lower() == 'y': connect_to_devices = connect_to_router(device, username, password) cu = Config(connect_to_devices) cu.commit() print 'config has been successfully commited' else: connect_to_devices = connect_to_router(device, username, password) cu = Config(connect_to_devices) cu.rollback() print 'config had to be rolledback'
def commit_check_rollback(host): try: with Device(host=host) as dev: cu = Config(dev) diff = cu.diff() print ("On {} device are {} diferencies between acticve and candidate".format(host, diff )) if diff: cu.rollback() except ConnectRefusedError: print("{}: Error - Device connection refused!".format(host)) except ConnectTimeoutError: print("%s: Error - Device connection time out!" % host) except ConnectAuthError: print("%s: Error - Authentication failure!" % host)
def instantiate_config_object(dev, config_format, config_text): """Instantiate an object from Config() and attempt to apply the configuration changes""" config_dev = Config(dev) try: config_dev.lock() config_dev.load(config_text, format=config_format) except ConfigLoadError as err: LOGGER.info(err) print("Errors detected, rolling back the change and disconnecting\n") config_dev.rollback() config_dev.unlock() dev.close() return None return config_dev
def run(self): """Triggered by start call in calling function.""" def printer(message): with self.printlock: print self.hostname + ': ' + message dev = Device(host=self.hostname, user=self.userid, password=self.pwd, port=22) cu = Config(dev) try: printer('Connecting to device') dev.open() except Exception as err: printer("Cannot connect to device: {}".format(err)) self.state[self.hostname] = 'No_connect' return printer("Locking the configuration") try: cu.lock() except LockError as err: printer("ERROR: Unable to lock configuration: {}".format(err)) printer("Closing connection") self.state[self.hostname] = 'No_lock' dev.close() return try: printer("Rolling back the configuration") cu.rollback(rb_id = self.rbid) printer("Committing the configuration") cu.commit() self.state[self.hostname] = 'Rolled_back' except CommitError as err: printer("ERROR: Unable to commit configuration: {}".format(err)) printer("Unlocking the configuration") self.state[self.hostname] = 'No_commit' try: cu.unlock() except UnlockError as err: printer("ERROR: Unable to unlock configuration: {}".format(err)) printer("Closing the connection") dev.close() return printer("Closing the connection") dev.close() return
def main(): ''' Exercise using Juniper's PyEZ to make changes to device in various ways ''' pwd = getpass('Enter 88newclass: ') ip_addr = raw_input("\nIP: 184.105.247.76\nEnter Juniper SRX IP: ") ip_addr = ip_addr.strip() juniper_srx = { "host": ip_addr, "user": '******', "password": pwd } print "\n\nConnecting to Juniper SRX...\n" # create device object with all the arguments in the dictionary a_device = Device(**juniper_srx) a_device.open() cfg = Config(a_device) print "Setting hostname using set notation" cfg.load("set system host-name test1", format="set", merge=True) print "Current config differences: " print cfg.diff() print "Performing rollback" cfg.rollback(0) print "\nSetting hostname using {} notation (external file)" cfg.load(path='load_hostname.conf', format='text', merge=True) print "Current config differences: " print cfg.diff() print "Performing commit: " cfg.commit() print "\nSetting hostname using XML (external file)" cfg.load(path="load_hostname.xml", format="xml", merge=True) print "Current config differences: " print cfg.diff() print "Performing commit: " cfg.commit() print
def push_config_element(xml_data, dev, overwrite=False): logger.debug(etree.tostring(xml_data, pretty_print=True)) cu = Config(dev) try: cu.lock() except LockError as le: logger.debug("Could not lock database!") logger.debug(str(le)) dev.close() return False try: cu.load(xml_data, overwrite=overwrite) except Exception as e: logger.debug("Could not load configuration") logger.debug(str(e)) dev.close() return False diff = cu.diff() logger.debug(diff) if diff is not None: # nothing to commit try: cu.commit_check() logger.debug("Committing config!") cu.commit(comment="Commit via wistar") logger.debug("Committed successfully!") except CommitError as ce: logger.debug("Could not load config!") cu.rollback() else: logger.debug("Nothing to commit") try: logger.debug("Unlocking database!") cu.unlock() except UnlockError as ue: logger.debug("Could not unlock database") logger.debug(str(ue)) return False logger.debug("Closing device handle") dev.close() return True
def test_load_config(self): from jnpr.junos.utils.config import Config cu = Config(self.dev) data = """interfaces { ge-1/0/0 { description "MPLS interface"; unit 0 { family mpls; } } } """ cu.load(data, format='text') self.assertTrue(cu.commit_check()) if cu.commit_check(): cu.rollback()
def main(): ''' Exercise using Juniper's PyEZ to make changes to device in various ways ''' pwd = getpass() ip_addr = raw_input("Enter Juniper SRX IP: ") ip_addr = ip_addr.strip() juniper_srx = { "host": ip_addr, "user": "******", "password": pwd } print "\n\nConnecting to Juniper SRX...\n" a_device = Device(**juniper_srx) a_device.open() cfg = Config(a_device) print "Setting hostname using set notation" cfg.load("set system host-name test1", format="set", merge=True) print "Current config differences: " print cfg.diff() print "Performing rollback" cfg.rollback(0) print "\nSetting hostname using {} notation (external file)" cfg.load(path="load_hostname.conf", format="text", merge=True) print "Current config differences: " print cfg.diff() print "Performing commit" cfg.commit() print "\nSetting hostname using XML (external file)" cfg.load(path="load_hostname.xml", format="xml", merge=True) print "Current config differences: " print cfg.diff() print "Performing commit" cfg.commit() print
def main(): ''' Exercise using Juniper's PyEZ to make changes to device in various ways ''' pwd = getpass() try: ip_addr = raw_input("Enter Juniper SRX IP: ") except NameError: ip_addr = input("Enter Juniper SRX IP: ") ip_addr = ip_addr.strip() juniper_srx = {"host": ip_addr, "user": "******", "password": pwd} print("\n\nConnecting to Juniper SRX...\n") a_device = Device(**juniper_srx) a_device.open() cfg = Config(a_device) print("Setting hostname using set notation") cfg.load("set system host-name test1", format="set", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing rollback") cfg.rollback(0) print("\nSetting hostname using {} notation (external file)") cfg.load(path="load_hostname.conf", format="text", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing commit") cfg.commit() print("\nSetting hostname using XML (external file)") cfg.load(path="load_hostname.xml", format="xml", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing commit") cfg.commit() print()
def rollback_changed(devices, failed): for router in devices: logger.error(f"Rolling back {router}") try: with Device( host=router, user=cfg["USER"], ssh_private_key_file=cfg["KEY"], port=22, ) as dev: conf = Config(dev, mode="private") conf.rollback(rb_id=1) conf.commit(comment=f"Rolled back, failure on {failed}") except Exception as exc: logger.critical( f"PyEZ configuration exception while rolling back, {exc}") sys.exit(2)
def get_max_rate(self): """Set an invalid value for rate-limit and process the exception.""" # configuration object for Junos device cfg = Config(self.dev) # make sure no config change is pending before our set command diff = cfg.diff() if diff is not None: msg = 'Uncommitted change found: %s' % str(diff) raise RuntimeError(msg) # try to set a invalid (too large) value for rate-limit set_cmd = 'set system services ssh rate-limit ' + str(self.test_value) try: cfg.load(set_cmd, format='set') # Config load should raise exception if the test value is invalid. # If we got here, it means the device accepted the (apparently # valid) rate-limit, so roll back the change and assume the # test value is the maximum allowed rate limit cfg.rollback() msg = 'Test configuration loaded without error, actual max ' msg += 'rate limit may be higher than the test value ' msg += '%s.' % str(self.test_value) self.results['warnings'].append(msg) self.results['rate_max'] = self.test_value if self.test_value < self.desired_rate_limit: self.results['rate_limit'] = self.test_value else: self.results['rate_limit'] = self.desired_rate_limit except ConfigLoadError as err: self.results['exception_message'] = err.message # catch the expected ConfigLoadError from the invalid rate-limit match = re.search(r'\(\d+\.\.(\d+)\)', err.message) if match is not None: max_str = int(match.group(1)) reported_max = int(max_str) self.results['rate_max'] = reported_max if reported_max < self.desired_rate_limit: self.results['rate_limit'] = reported_max else: self.results['rate_limit'] = self.desired_rate_limit else: msg = 'Regex match expected but not found in caught ' msg += 'exception: %s' % str(err) raise ValueError(msg)
def main(): """Juniper PYEZ config operations.""" password = getpass() my_route = { 'prefix': '1.1.2.0/24', 'next_hop': '10.220.88.1' } new_route_xml = generate_route_template(my_route) # Establish NETCONF connection a_device = Device(host='184.105.247.76', user='******', password=password) print print a_device.open() # Create config object cfg = Config(a_device) cfg.lock() # Configure XML print "Configuring static routes using XML... (merge)" cfg.load(new_route_xml, format="xml", merge=True) print "Config differences..." print '-' * 50 print cfg.diff() print "Committing changes..." cfg.commit() display_static_routes(a_device) # Route to discard my_route = dict(prefix='1.1.3.0/24', next_hop='10.220.88.1') new_route_xml = generate_route_template(my_route) print "Configuring static routes using XML... (merge)" cfg.load(new_route_xml, format="xml", merge=True) print "Config differences..." print '-' * 50 print cfg.diff() cfg.rollback(0) display_static_routes(a_device) cfg.unlock()
def main(): juniper_srx = { "host": "184.105.247.76", "user": "******", "password": "******" } print("\n\nConnecting to Juniper SRX...\n") a_device = Device(**juniper_srx) a_device.open() cfg = Config(a_device) print("Setting hostname using set notation") cfg.load("set system host-name thisismytestname", format="set", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing rollback") cfg.rollback(0) print("\nSetting hostname using {} notation (external file)") cfg.load(path="load_hostname.conf", format="text", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing commit") cfg.commit() print("\nSetting hostname using XML (external file)") cfg.load(path="load_hostname.xml", format="xml", merge=True) print("Current config differences: ") print(cfg.diff()) print("Performing commit") cfg.commit() print()
def main(): dev = Device() # 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 cu = Config(dev) # Lock the configuration print "Locking the configuration" try: cu.lock() except LockError: print "Error: Unable to lock configuration" dev.close() return try: print "Rolling back the configuration" cu.rollback(rb_id=1) print "Committing the configuration" cu.commit() except ValueError as err: print err.message except CommitError: print "Error: Unable to commit configuration" except Exception as err: if err.rsp.find('.//ok') is None: rpc_msg = err.rsp.findtext('.//error-message') print "Unable to rollback configuration changes: ", rpc_msg finally: print "Unlocking the configuration" try: cu.unlock() except UnlockError: print "Error: Unable to unlock configuration" dev.close() return
def junos_config(host=None, user=None, password=None, port=830, auto_probe=30, set_cmds=None, commit=True): try: dev = Device(host=host, user=user, password=password, port=port, auto_probe=auto_probe) dev.open() conf = Config(dev) conf.lock() conf.load(set_cmds, format='set') if commit and conf.diff(): result = conf.diff() conf.commit() result += "\n\n Nova configuração aplicada." conf.unlock() elif not commit: result = conf.diff() conf.rollback() conf.unlock() result += "\n\n Esta configuração não sera aplicada." else: result = "Configuração já está atualizada." conf.unlock() except ConnectAuthError: result = "Erro de autenticação!" except ConnectTimeoutError: result = "Conexão NETCONF atingiu o tempo limite de conexão!" except (ConfigLoadError, CommitError) as err: result = f"Problema ao carregar nova configuração: {err}" except Exception as err: result = f"Erro: {err}" finally: dev.close() return result
def main(): ''' Main function ''' a_device = remote_conn(HOST, USER, PWD) if not a_device: sys.exit('Fix the above errors. Exiting...') print a_device.facts cfg = Config(a_device) cfg.lock() print 'Set hostname using set format' set_hostname(cfg, 'pytest-gmaz', 'set') print 'Show differences' print cfg.diff() print 'Rollback' cfg.rollback(0) print 'Check if rollback is ok' print cfg.diff() print 'Set hostname using cfg file' set_hostname(cfg, 'hostname.conf', 'text') print 'Show differences' print cfg.diff() print 'Commit' cfg.commit(comment='Text hostname commit by gmazioli') print 'Set hostname using external XML' set_hostname(cfg, 'hostname.xml', 'xml') print 'Show differences' print cfg.diff() print 'Commit' cfg.commit(comment='XML hostname commit by gmazioli') print 'Reverting changes and doing the final commit' set_hostname(cfg, 'pynet-jnpr-srx1', 'set') cfg.commit(comment='System commit by gmazioli') cfg.unlock()
def main(): pwd = getpass() juniper = { "host": "50.76.53.27", "user": "******", "password": pwd } a_device = Device(**juniper) a_device.open() cfg = Config(a_device) print "Changing hostname with set command" cfg_load = cfg.load("set system host-name batz-jnpr-srx1", format ="set", merge=True) print cfg.diff() print print "Doing rollback" cfg.rollback(0) print "Changing hostname with conf method " cfg_load_conf = cfg.load(path='hostname.conf', format='text', merge=True) print cfg.diff() print print "Doing rollback" cfg.rollback(0) print "Changing hostname with xml method" cfg_load_xml = cfg.load(path='hostname.xml', format='xml', merge=True) print cfg.diff() print print "Doing changes" cfg.commit() print
def main(): ''' I will test the case with applying config for 1 minute ''' pwd = getpass() ip_addr = raw_input('''Enter Juniper SRX IP"(184.105.247.76)": ''') ip_addr = ip_addr.strip() juniper_srx = { "host": ip_addr, "user": "******", "password": pwd } try: a_device = Device(**juniper_srx) a_device.open() cfg = Config(a_device) cfg.lock() cfg.load(path="exercice4_config.xml" , format="xml", merge=True) print "#"*80 print "Displaying the differences between the running config and the candidate config:" print "#"*80 cfg.pdiff() print "+"*80 print "Applying config" print "+"*80 cfg.commit(comment="Applying config from exercice4_config.xml") print "-"*80 print "reverting config back" cfg.rollback(1) cfg.pdiff() cfg.commit() print "-"*80 print "\n"*2 print except: print print "Authentication Error" print
def config_devices(sconf): for d in sconf['devices']: dev = Device(host=d['ip'], user=d['user'], password=d['pass']) try: dev.open() except ConnectError as err: print("ERROR Cannot connect to device: {0}".format(err)) exit() except Exception as err: print("ERROR while connecting to device - " + str(err)) exit() try: cfg = Config(dev, mode='private') except Exception as err: print("[ERROR] Cannot open configuration - " + str(err)) dev.close() sys.exit() try: cfg.lock() except Exception as err: print("[ERROR] Cannot lock configuration - " + str(err)) dev.close() sys.exit() logvars = {'log_server': sconf['log_server'], 'src_log': d['src']} cfg.load(template_path=str('jinja_templates/junos.conf.j2'), template_vars=logvars, format='set') try: cfg.commit(comment="Device sending log to cloudyjsyslog") except Exception as err: print("[ERROR] Cannot commit configuration - " + str(err)) print("[ERROR] Rollback and exit") cfg.rollback() dev.close() sys.exit() dev.close()
def main(): pwd = getpass() a_device = Device(host='184.105.247.76', user='******', password=pwd) a_device.open() print "\n***** Device Facts *****\n" pprint(a_device.facts) print "\n***** Config Change...****\n" cfg = Config(a_device) cfg.lock() print "Config is locked..." cfg.load(path='srx_hostname.conf', format='text', merge=True) print "Config change is uploaded.." cfg.pdiff() answer = raw_input("Do you want to rollback(y/n): ") if answer in ['y', 'Y', 'yes', 'YES']: print "Rollback is in progress..." cfg.rollback(0) cfg.commit() cfg.pdiff() else: pass cfg.unlock()
def main(): pwd = getpass() srx = { "hostname": "srx1.twb-tech.com", "host": "184.105.247.76", "user": "******", "password": pwd } srx_device = Device(**srx) srx_device.open() print("\nThe current timeout is {} seconds.".format(srx_device.timeout)) srx_device.timeout = 120 print("\nThe updated timeout is {} seconds.".format(srx_device.timeout)) print("\n") pprint(srx_device.facts) print("\n") cfg = Config(srx_device) cfg.load("set system host-name testsrx", format="set", merge=True) print(cfg.diff()) cfg.rollback(0) print("\nROLLED BACK... DENIED") cfg.load("set system host-name testsrx", format="set", merge=True) print(cfg.diff()) cfg.commit() print("\ntestsrx COMMITED") cfg.load("set system host-name pynet-jnpr-srx1", format="set", merge=True) print(cfg.diff()) cfg.commit() print("\nBACK TO NORM with pynet-jnpr-srx1")
def updateDeviceConfiguration(self): ''' Device Connection should be open by now, no need to connect again ''' logger.debug('updateDeviceConfiguration for %s' % (self.deviceLogStr)) config = self.getDeviceConfig() configurationUnit = Config(self.deviceConnectionHandle) try: configurationUnit.lock() logger.debug('Lock config for %s' % (self.deviceLogStr)) except LockError as exc: logger.error( 'updateDeviceConfiguration failed for %s, LockError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) raise DeviceRpcFailed( 'updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) try: # make sure no changes are taken from CLI candidate config left over configurationUnit.rollback() logger.debug('Rollback any other config for %s' % (self.deviceLogStr)) configurationUnit.load(config, format='text') logger.debug('Load generated config as candidate, for %s' % (self.deviceLogStr)) #print configurationUnit.diff() #print configurationUnit.commit_check() configurationUnit.commit() logger.info('Committed twoStage config for %s' % (self.deviceLogStr)) except CommitError as exc: #TODO: eznc Error handling is not giving helpful error message logger.error( 'updateDeviceConfiguration failed for %s, CommitError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) configurationUnit.rollback() raise DeviceRpcFailed( 'updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) except Exception as exc: logger.error('updateDeviceConfiguration failed for %s, %s' % (self.deviceLogStr, exc)) logger.debug('StackTrace: %s' % (traceback.format_exc())) configurationUnit.rollback() raise DeviceRpcFailed( 'updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) finally: configurationUnit.unlock() logger.debug('Unlock config for %s' % (self.deviceLogStr))
def updateDeviceConfiguration(self): ''' Device Connection should be open by now, no need to connect again ''' logger.debug('updateDeviceConfiguration for %s' % (self.deviceLogStr)) l3ClosMediation = L3ClosMediation(conf = self._conf) config = l3ClosMediation.createLeafConfigFor2Stage(self.device) # l3ClosMediation used seperate db sessions to create device config # expire device from current session for lazy load with committed data self._session.expire(self.device) configurationUnit = Config(self.deviceConnectionHandle) try: configurationUnit.lock() logger.debug('Lock config for %s' % (self.deviceLogStr)) except LockError as exc: logger.error('updateDeviceConfiguration failed for %s, LockError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) raise DeviceError(exc) try: # make sure no changes are taken from CLI candidate config left over configurationUnit.rollback() logger.debug('Rollback any other config for %s' % (self.deviceLogStr)) configurationUnit.load(config, format='text') logger.debug('Load generated config as candidate, for %s' % (self.deviceLogStr)) #print configurationUnit.diff() #print configurationUnit.commit_check() configurationUnit.commit() logger.info('Committed twoStage config for %s' % (self.deviceLogStr)) except CommitError as exc: #TODO: eznc Error handling is not giving helpful error message logger.error('updateDeviceConfiguration failed for %s, CommitError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) configurationUnit.rollback() raise DeviceError(exc) except Exception as exc: logger.error('updateDeviceConfiguration failed for %s, %s' % (self.deviceLogStr, exc)) logger.debug('StackTrace: %s' % (traceback.format_exc())) configurationUnit.rollback() raise DeviceError(exc) finally: configurationUnit.unlock() logger.debug('Unlock config for %s' % (self.deviceLogStr))
def updateDeviceConfiguration(self): ''' Device Connection should be open by now, no need to connect again ''' logger.debug('updateDeviceConfiguration for %s' % (self.deviceLogStr)) config = self.getDeviceConfig() configurationUnit = Config(self.deviceConnectionHandle) try: configurationUnit.lock() logger.debug('Lock config for %s' % (self.deviceLogStr)) except LockError as exc: logger.error('updateDeviceConfiguration failed for %s, LockError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) raise DeviceRpcFailed('updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) try: # make sure no changes are taken from CLI candidate config left over configurationUnit.rollback() logger.debug('Rollback any other config for %s' % (self.deviceLogStr)) configurationUnit.load(config, format='text') logger.debug('Load generated config as candidate, for %s' % (self.deviceLogStr)) #print configurationUnit.diff() #print configurationUnit.commit_check() configurationUnit.commit() logger.info('Committed twoStage config for %s' % (self.deviceLogStr)) except CommitError as exc: #TODO: eznc Error handling is not giving helpful error message logger.error('updateDeviceConfiguration failed for %s, CommitError: %s, %s, %s' % (self.deviceLogStr, exc, exc.errs, exc.rpc_error)) configurationUnit.rollback() raise DeviceRpcFailed('updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) except Exception as exc: logger.error('updateDeviceConfiguration failed for %s, %s' % (self.deviceLogStr, exc)) logger.debug('StackTrace: %s' % (traceback.format_exc())) configurationUnit.rollback() raise DeviceRpcFailed('updateDeviceConfiguration failed for %s' % (self.deviceLogStr), exc) finally: configurationUnit.unlock() logger.debug('Unlock config for %s' % (self.deviceLogStr))
class TestConfig(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() self.conf = Config(self.dev) @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_config_constructor(self): self.assertTrue(isinstance(self.conf._dev, Device)) def test_config_confirm_true(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=True) self.conf.rpc.commit_configuration\ .assert_called_with(confirmed=True) def test_config_commit_confirm(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=10) self.conf.rpc.commit_configuration\ .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True}) def test_config_commit_comment(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(comment='Test') self.conf.rpc.commit_configuration.assert_called_with(log='Test') def test_config_commit_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(synchronize=True) def test_config_commit_force_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(force_sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(**{'synchronize': True, 'force-synchronize': True}) def test_config_commit_timeout(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(timeout=60) self.conf.rpc.commit_configuration\ .assert_called_with(dev_timeout=60) def test_config_commit_full(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(full=True) self.conf.rpc.commit_configuration\ .assert_called_with(full=True) def test_config_commit_detail(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<mockdetail/>' self.assertEqual('<mockdetail/>', self.conf.commit(detail=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}) def test_config_commit_combination(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<moredetail/>' self.assertEqual( '<moredetail/>', self.conf.commit( detail=True, force_sync=True, full=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}, **{'synchronize': True, 'full': True, 'force-synchronize': True}) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_commit_xml_exception(self, mock_jxml): class MyException(Exception): xml = etree.fromstring('<test/>') self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(CommitError, self.conf.commit) def test_config_commit_exception(self): class MyException(Exception): pass self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(MyException, self.conf.commit) def test_config_commit_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit) def test_commit_check(self): self.conf.rpc.commit_configuration = MagicMock() self.assertTrue(self.conf.commit_check()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_commit_check_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException) # with self.assertRaises(AttributeError): self.conf.commit_check() def test_config_commit_check_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit_check()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit_check) def test_config_diff(self): self.conf.rpc.get_configuration = MagicMock() self.conf.diff() self.conf.rpc.get_configuration.\ assert_called_with( {'compare': 'rollback', 'rollback': '0', 'format': 'text'}) def test_config_diff_exception_severity_warning(self): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>mgd: statement must contain additional statements</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) self.conf.rpc.get_configuration = MagicMock( side_effect=RpcError(rsp=rsp)) self.assertEqual(self.conf.diff(), "Unable to parse diff from response!") def test_config_diff_exception_severity_warning_still_raise(self): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>statement not found</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) self.conf.rpc.get_configuration = MagicMock( side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, self.conf.diff) def test_config_pdiff(self): self.conf.diff = MagicMock(return_value='Stuff') self.conf.pdiff() self.conf.diff.assert_called_once_with(0) def test_config_load(self): self.assertRaises(RuntimeError, self.conf.load) def test_config_load_vargs_len(self): self.assertRaises(RuntimeError, self.conf.load, 'test.xml') def test_config_load_len_with_format_set(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertEqual(self.conf.load('test.xml', format='set'), 'rpc_contents') def test_config_load_len_with_format_xml(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') xmldata = """<snmp> <community> <name>iBGP</name> </community> </snmp>""" self.assertEqual(self.conf.load(xmldata, format='xml'), 'rpc_contents') def test_config_load_len_with_format_text(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') textdata = """policy-options { prefix-list TEST1-NETS { 100.0.0.0/24; } policy-statement TEST1-NETS { term TEST1 { from { prefix-list TEST1-NETS; } then accept; } term REJECT { then reject; } } }""" self.assertEqual(self.conf.load(textdata), 'rpc_contents') def test_config_load_with_format_json(self): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load('test.json', format='json') self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') @patch(builtin_string + '.open') def test_config_load_with_format_json_from_file_ext(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load(path='test.json') self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') @patch(builtin_string + '.open') def test_config_load_update(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load(path='test.conf', update=True) self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') def test_config_load_update_merge_overwrite(self): self.assertRaises(ValueError, self.conf.load, path='test.jnpr', update=True, merge=True, overwrite=True) @patch(builtin_string + '.open') def test_config_load_lformat_byext_ValueError(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, path='test.jnpr') def test_config_load_lset_format_ValueError(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, 'test.xml', format='set', overwrite=True) @patch(builtin_string + '.open') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_path_xml(self, mock_etree, mock_open): self.conf.dev.Template = MagicMock() mock_etree.return_value = 'rpc_contents' self.conf.rpc.load_config = \ MagicMock(return_value=mock_etree.return_value) self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents') @patch(builtin_string + '.open') def test_config_load_path_text(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.conf') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') @patch(builtin_string + '.open') def test_config_load_path_set(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.set') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') @patch(builtin_string + '.open') def test_config_load_try_load_rpcerror(self, mock_open): ex = ConfigLoadError( rsp=etree.fromstring(( """<load-configuration-results> <rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error> </load-configuration-results>"""))) self.conf.rpc.load_config = MagicMock(side_effect=ex) self.assertRaises(ConfigLoadError, self.conf.load, path='config.conf') @patch(builtin_string + '.open') def test_config_load_try_load_rpctimeouterror(self, mock_open): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.load_config = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.load, path='config.conf') @patch(builtin_string + '.open') def test_config_try_load_exception(self, mock_open): class OtherException(Exception): pass self.conf.rpc.load_config = MagicMock(side_effect=OtherException()) self.assertRaises(OtherException, self.conf.load, path='config.conf') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_template_path(self, mock_etree): self.conf.rpc.load_config = MagicMock() self.conf.dev.Template = MagicMock() self.conf.load(template_path='test.xml') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_template(self): class Temp: filename = 'abc.xml' render = MagicMock(return_value='<test/>') self.conf.rpc.load_config = MagicMock() self.conf.load(template=Temp) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_diff_exception(self): self.conf.rpc.get_configuration = MagicMock() self.assertRaises(ValueError, self.conf.diff, 51) self.assertRaises(ValueError, self.conf.diff, -1) def test_config_lock(self): self.conf.rpc.lock_configuration = MagicMock() self.assertTrue(self.conf.lock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_lock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.lock_configuration = MagicMock(side_effect=ex) self.assertRaises(LockError, self.conf.lock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_lock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException) self.assertRaises(LockError, self.conf.lock) def test_config_unlock(self): self.conf.rpc.unlock_configuration = MagicMock() self.assertTrue(self.conf.unlock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_unlock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex) self.assertRaises(UnlockError, self.conf.unlock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_unlock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException) self.assertRaises(UnlockError, self.conf.unlock) def test_config_rollback(self): self.conf.rpc.load_configuration = MagicMock() self.assertTrue(self.conf.rollback()) def test_config_rollback_exception(self): self.conf.rpc.load_configuration = MagicMock() self.assertRaises(ValueError, self.conf.rollback, 51) self.assertRaises(ValueError, self.conf.rollback, -1) @patch('jnpr.junos.Device.execute') def test_rescue_action_save(self, mock_exec): self.dev.request_save_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('save')) @patch('jnpr.junos.Device.execute') def test_rescue_action_get_exception(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception) self.assertTrue(self.conf.rescue('get') is None) @patch('jnpr.junos.Device.execute') def test_rescue_action_get(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock() self.dev.rpc.get_rescue_information.return_value = 1 self.assertEqual(self.conf.rescue('get', format='xml'), 1) @patch('jnpr.junos.Device.execute') def test_rescue_action_delete(self, mock_exec): self.dev.rpc.request_delete_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('delete')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload(self, mock_exec): self.dev.rpc.load_configuration = MagicMock() self.dev.rpc.load_configuration.return_value = True self.assertTrue(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload_exception(self, mock_exec): self.dev.rpc.load_configuration = MagicMock(side_effect=Exception) self.assertFalse(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_unsupported_action(self, mock_exec): self.assertRaises(ValueError, self.conf.rescue, 'abc') def test_config_load_lset_from_rexp_xml(self): self.conf.rpc.load_config = MagicMock() conf = """<snmp><name>iBGP</name></snmp>""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_lset_from_rexp_json(self): self.conf.rpc.load_config = MagicMock() conf = """{ "configuration" : { "system" : { "services" : { "telnet" : [null] } } } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') def test_config_load_lset_from_rexp_set(self): self.conf.rpc.load_config = MagicMock() conf = """set system domain-name englab.nitin.net""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_set_delete(self): self.conf.rpc.load_config = MagicMock() conf = """delete snmp""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_conf(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') def test_config_load_lset_from_rexp_conf_replace_tag(self): self.conf.rpc.load_config = MagicMock() conf = """replace: snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'replace') def test_config_load_lset_from_rexp_error(self): self.conf.rpc.load_config = MagicMock() conf = """test>""" self.assertRaises(RuntimeError, self.conf.load, conf) def test_load_merge_true(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf, merge=True) self.assertFalse('action' in self.conf.rpc.load_config.call_args[1]) def test_commit_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.dev.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.commit) def test_commit_check_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.dev.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.commit_check) def test_commit_configuration_multi_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) try: self.dev.rpc.commit_configuration() except Exception as ex: self.assertTrue(isinstance(ex, RpcError)) if ncclient.__version__ > (0, 4, 5): self.assertEqual(ex.message, "error: interface-range 'axp' is not defined\n" "error: interface-ranges expansion failed") self.assertEqual(ex.errs, [{'source': None, 'message': "interface-range 'axp' is not defined", 'bad_element': None, 'severity': 'error', 'edit_path': None}, {'source': None, 'message': 'interface-ranges expansion failed', 'bad_element': None, 'severity': 'error', 'edit_path': None}]) else: self.assertEqual(ex.message, "interface-range 'axp' is not defined") @patch('jnpr.junos.utils.config.Config.lock') @patch('jnpr.junos.utils.config.Config.unlock') def test_config_mode_exclusive(self, mock_unlock, mock_lock): with Config(self.dev, mode='exclusive') as conf: conf.rpc.load_config = MagicMock() conf.load('conf', format='set') self.assertTrue(mock_lock.called and mock_unlock.called) @patch('jnpr.junos.Device.execute') def test_config_mode_batch(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(batch=True) @patch('jnpr.junos.Device.execute') def test_config_mode_private(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='private') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(private=True) @patch('jnpr.junos.Device.execute') def test_config_mode_dynamic(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='dynamic') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(dynamic=True) @patch('jnpr.junos.Device.execute') def test_config_mode_close_configuration_ex(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() ex = RpcError(rsp='ok') ex.message = 'Configuration database is not open' self.dev.rpc.close_configuration = MagicMock(side_effect=ex) try: with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') except Exception as ex: self.assertTrue(isinstance(ex, RpcError)) self.assertTrue(self.dev.rpc.close_configuration.called) @patch('jnpr.junos.Device.execute') def test_config_mode_undefined(self, mock_exec): try: with Config(self.dev, mode='unknown') as conf: conf.load('conf', format='set') except Exception as ex: self.assertTrue(isinstance(ex, ValueError)) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.utils.config.warnings') def test_config_mode_batch_open_configuration_ex(self, mock_warnings, mock_exec): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>syntax error</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) obj = RpcError(rsp=rsp) self.dev.rpc.open_configuration = MagicMock(side_effect=obj) with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(batch=True) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.utils.config.warnings') def test_config_mode_private_open_configuration_ex(self, mock_warnings, mock_exec): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>syntax error</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) obj = RpcError(rsp=rsp) self.dev.rpc.open_configuration = MagicMock(side_effect=obj) with Config(self.dev, mode='private') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(private=True) def test__enter__private_exception_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.open_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, Config.__enter__, Config(self.dev, mode='private')) def test__enter__private_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='private')) def test__enter__dyanamic_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='dynamic')) def test__enter__batch_exception_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.open_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, Config.__enter__, Config(self.dev, mode='batch')) def test__enter__batch_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='batch')) def _read_file(self, fname): fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) foo = open(fpath).read() # specific to multi rpc error if fname == 'commit-configuration.xml': raw = etree.XML(foo) obj = RPCReply(raw) obj.parse() if ncclient.__version__ > (0, 4, 5): raise RPCError(etree.XML(foo), errs=obj._errors) else: raise RPCError(etree.XML(foo)) 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: return self._read_file(args[0].tag + '.xml')
import sys import time import datetime from pprint import pprint from jnpr.junos import Device from jnpr.junos.utils.config import Config from jnpr.junos import exception as EzErrors counter = 0 while True: #Start config mode dev = Device(host='vienne-re0.ultralab.juniper.net', user='******', password='******') dev.open() dev.timeout = 600 cu = Config(dev) cu.rollback(1) cu.commit(timeout=600) counter += 1 print "Round %s" % counter time.sleep(60)
ip = resolve_host(hostname) if ip: juniper_device = Device(host=ip,user=os.getenv("USER"),password=password,port='22') # open the device defined instance juniper_device.open() # open configuration method config = Config(juniper_device) # open configuration lock method allowing only one configuration try: config.lock() except LockError: print "Error: Unable to lock configuration" juniper_device.close() sys.exit(0) # rollback any configuration that might be in candidate configuration config.rollback(0) try: config.load(path=args.commands, format=args.configuration_choice, merge="True") # Merge = "False" would implies a replace action. A # replace action, however, requires that the configuration file have a # 'replace:' statement in it print configuration diff from devices # perspective. To load a jinja template: # cu.load(template_path=conf_file, template_vars=config, merge=True) except ValueError as err: print err.message print config.diff() print hostname print "Proceed with commit?:(yes or no)" process_response()
class Netconf(object): def __init__(self): if not HAS_PYEZ: raise NetworkError( msg='junos-eznc >= 1.2.2 is required but does not appear to be installed. ' 'It can be installed using `pip install junos-eznc`' ) if not HAS_JXMLEASE: raise NetworkError( msg='jxmlease is required but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`' ) self.device = None self.config = None self._locked = False self._connected = False self.default_output = 'xml' def raise_exc(self, msg): if self.device: if self._locked: self.config.unlock() self.disconnect() raise NetworkError(msg) def connect(self, params, **kwargs): host = params['host'] kwargs = dict() kwargs['port'] = params.get('port') or 830 kwargs['user'] = params['username'] if params['password']: kwargs['passwd'] = params['password'] if params['ssh_keyfile']: kwargs['ssh_private_key_file'] = params['ssh_keyfile'] kwargs['gather_facts'] = False try: self.device = Device(host, **kwargs) self.device.open() except ConnectError: exc = get_exception() self.raise_exc('unable to connect to %s: %s' % (host, str(exc))) self.config = Config(self.device) self._connected = True def disconnect(self): try: self.device.close() except AttributeError: pass self._connected = False ### Command methods ### def run_commands(self, commands): responses = list() for cmd in commands: meth = getattr(self, cmd.args.get('command_type')) responses.append(meth(str(cmd), output=cmd.output)) for index, cmd in enumerate(commands): if cmd.output == 'xml': responses[index] = xml_to_json(responses[index]) elif cmd.args.get('command_type') == 'rpc': responses[index] = str(responses[index].text).strip() elif 'RpcError' in responses[index]: raise NetworkError(responses[index]) return responses def cli(self, commands, output='xml'): '''Send commands to the device.''' try: return self.device.cli(commands, format=output, warning=False) except (ValueError, RpcError): exc = get_exception() self.raise_exc('Unable to get cli output: %s' % str(exc)) def rpc(self, command, output='xml'): name, kwargs = rpc_args(command) meth = getattr(self.device.rpc, name) reply = meth({'format': output}, **kwargs) return reply ### Config methods ### def get_config(self, config_format="text"): if config_format not in SUPPORTED_CONFIG_FORMATS: self.raise_exc(msg='invalid config format. Valid options are ' '%s' % ', '.join(SUPPORTED_CONFIG_FORMATS)) ele = self.rpc('get_configuration', output=config_format) if config_format == 'text': return unicode(ele.text).strip() else: return ele def load_config(self, config, commit=False, replace=False, confirm=None, comment=None, config_format='text', overwrite=False): if all([replace, overwrite]): self.raise_exc('setting both replace and overwrite to True is invalid') if replace: merge = False overwrite = False elif overwrite: merge = True overwrite = False else: merge = True overwrite = False if overwrite and config_format == 'set': self.raise_exc('replace cannot be True when config_format is `set`') self.lock_config() try: candidate = '\n'.join(config) self.config.load(candidate, format=config_format, merge=merge, overwrite=overwrite) except ConfigLoadError: exc = get_exception() self.raise_exc('Unable to load config: %s' % str(exc)) diff = self.config.diff() self.check_config() if all((commit, diff)): self.commit_config(comment=comment, confirm=confirm) self.unlock_config() return diff def save_config(self): raise NotImplementedError ### end of Config ### def get_facts(self, refresh=True): if refresh: self.device.facts_refresh() return self.device.facts def unlock_config(self): try: self.config.unlock() self._locked = False except UnlockError: exc = get_exception() raise NetworkError('unable to unlock config: %s' % str(exc)) def lock_config(self): try: self.config.lock() self._locked = True except LockError: exc = get_exception() raise NetworkError('unable to lock config: %s' % str(exc)) def check_config(self): if not self.config.commit_check(): self.raise_exc(msg='Commit check failed') def commit_config(self, comment=None, confirm=None): try: kwargs = dict(comment=comment) if confirm and confirm > 0: kwargs['confirm'] = confirm return self.config.commit(**kwargs) except CommitError: exc = get_exception() raise NetworkError('unable to commit config: %s' % str(exc)) def confirm_commit(self, checkonly=False): try: resp = self.rpc('get_commit_information') needs_confirm = 'commit confirmed, rollback' in resp[0][4].text if checkonly: return needs_confirm return self.commit_config() except IndexError: # if there is no comment tag, the system is not in a commit # confirmed state so just return pass def rollback_config(self, identifier, commit=True, comment=None): self.lock_config() try: self.config.rollback(identifier) except ValueError: exc = get_exception() self.raise_exc('Unable to rollback config: $s' % str(exc)) diff = self.config.diff() if commit: self.commit_config(comment=comment) self.unlock_config() return diff
class TestConfig(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') self.conf = Config(self.dev) def test_config_constructor(self): self.assertTrue(isinstance(self.conf._dev, Device)) def test_config_confirm(self): self.conf.rpc.commit_configuration = MagicMock() self.assertTrue(self.conf.commit(confirm=True)) def test_config_commit_confirm_timeout(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=10) self.conf.rpc.commit_configuration\ .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True}) def test_config_commit_comment(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(comment='Test') self.conf.rpc.commit_configuration.assert_called_with(log='Test') @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_commit_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(AttributeError, self.conf.commit) def test_config_commit_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit) def test_commit_check(self): self.conf.rpc.commit_configuration = MagicMock() self.assertTrue(self.conf.commit_check()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_commit_check_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException) # with self.assertRaises(AttributeError): self.conf.commit_check() def test_config_commit_check_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit_check()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit_check) def test_config_diff(self): self.conf.rpc.get_configuration = MagicMock() self.conf.diff() self.conf.rpc.get_configuration.\ assert_called_with({'compare': 'rollback', 'rollback': '0', 'format': 'text'}) def test_config_pdiff(self): self.conf.diff = MagicMock(return_value='Stuff') self.conf.pdiff() print self.conf.diff.call_args self.conf.diff.assert_called_once_with(0) def test_config_load(self): self.assertRaises(RuntimeError, self.conf.load) def test_config_load_vargs_len(self): self.assertRaises(RuntimeError, self.conf.load, 'test.xml') def test_config_load_len_with_format(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertEqual(self.conf.load('test.xml', format='set'), 'rpc_contents') @patch('__builtin__.open') def test_config_load_lformat_byext_ValueError(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, path='test.jnpr') def test_config_load_lset_format_ValueError(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, 'test.xml', format='set', overwrite=True) @patch('__builtin__.open') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_path_xml(self, mock_etree, mock_open): self.conf.dev.Template = MagicMock() mock_etree.return_value = 'rpc_contents' self.conf.rpc.load_config = \ MagicMock(return_value=mock_etree.return_value) self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents') @patch('__builtin__.open') def test_config_load_path_text(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.conf') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') @patch('__builtin__.open') def test_config_load_path_set(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.set') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_template_path(self): self.conf.rpc.load_config = MagicMock() self.conf.dev.Template = MagicMock() self.conf.load(template_path='test.xml') self.conf.dev.Template.assert_called_with('test.xml') def test_config_load_template(self): class Temp: filename = 'abc.xml' render = MagicMock() self.conf.rpc.load_config = MagicMock() self.conf.load(template=Temp) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_diff_exception(self): self.conf.rpc.get_configuration = MagicMock() self.assertRaises(ValueError, self.conf.diff, 51) self.assertRaises(ValueError, self.conf.diff, -1) def test_config_lock(self): self.conf.rpc.lock_configuration = MagicMock() self.assertTrue(self.conf.lock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_lock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.lock_configuration = MagicMock(side_effect=ex) self.assertRaises(LockError, self.conf.lock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_lock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException) self.assertRaises(LockError, self.conf.lock) def test_config_unlock(self): self.conf.rpc.unlock_configuration = MagicMock() self.assertTrue(self.conf.unlock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_unlock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex) self.assertRaises(UnlockError, self.conf.unlock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_unlock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException) self.assertRaises(UnlockError, self.conf.unlock) def test_config_rollback(self): self.conf.rpc.load_configuration = MagicMock() self.assertTrue(self.conf.rollback()) def test_config_rollback_exception(self): self.conf.rpc.load_configuration = MagicMock() self.assertRaises(ValueError, self.conf.rollback, 51) self.assertRaises(ValueError, self.conf.rollback, -1)
class TestConfig(unittest.TestCase): def setUp(self): self.dev = Device(host='1.1.1.1') self.conf = Config(self.dev) def test_config_constructor(self): self.assertTrue(isinstance(self.conf._dev, Device)) def test_config_confirm_true(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=True) self.conf.rpc.commit_configuration\ .assert_called_with(confirmed=True) def test_config_commit_confirm(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=10) self.conf.rpc.commit_configuration\ .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True}) def test_config_commit_comment(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(comment='Test') self.conf.rpc.commit_configuration.assert_called_with(log='Test') def test_config_commit_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(synchronize=True) def test_config_commit_force_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(force_sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(**{'synchronize': True, 'force-synchronize': True}) def test_config_commit_timeout(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(timeout=60) self.conf.rpc.commit_configuration\ .assert_called_with(dev_timeout=60) def test_config_commit_full(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(full=True) self.conf.rpc.commit_configuration\ .assert_called_with(full=True) def test_config_commit_detail(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<mockdetail/>' self.assertEqual('<mockdetail/>', self.conf.commit(detail=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}) def test_config_commit_combination(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<moredetail/>' self.assertEqual('<moredetail/>', self.conf.commit(detail=True, force_sync=True, full=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}, **{'synchronize': True, 'full': True, 'force-synchronize': True}) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_commit_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(AttributeError, self.conf.commit) def test_config_commit_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit) def test_commit_check(self): self.conf.rpc.commit_configuration = MagicMock() self.assertTrue(self.conf.commit_check()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_commit_check_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException) # with self.assertRaises(AttributeError): self.conf.commit_check() def test_config_commit_check_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit_check()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit_check) def test_config_diff(self): self.conf.rpc.get_configuration = MagicMock() self.conf.diff() self.conf.rpc.get_configuration.\ assert_called_with( {'compare': 'rollback', 'rollback': '0', 'format': 'text'}) def test_config_pdiff(self): self.conf.diff = MagicMock(return_value='Stuff') self.conf.pdiff() self.conf.diff.assert_called_once_with(0) def test_config_load(self): self.assertRaises(RuntimeError, self.conf.load) def test_config_load_vargs_len(self): self.assertRaises(RuntimeError, self.conf.load, 'test.xml') def test_config_load_len_with_format_set(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertEqual(self.conf.load('test.xml', format='set'), 'rpc_contents') def test_config_load_len_with_format_xml(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') xmldata = """<snmp> <community> <name>iBGP</name> </community> </snmp>""" self.assertEqual(self.conf.load(xmldata, format='xml'), 'rpc_contents') @patch('__builtin__.open') def test_config_load_lformat_byext_ValueError(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, path='test.jnpr') def test_config_load_lset_format_ValueError(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, 'test.xml', format='set', overwrite=True) @patch('__builtin__.open') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_path_xml(self, mock_etree, mock_open): self.conf.dev.Template = MagicMock() mock_etree.return_value = 'rpc_contents' self.conf.rpc.load_config = \ MagicMock(return_value=mock_etree.return_value) self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents') @patch('__builtin__.open') def test_config_load_path_text(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.conf') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') @patch('__builtin__.open') def test_config_load_path_set(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.set') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') @patch('__builtin__.open') def test_config_load_try_load_rpcerror(self, mock_open): ex = ConfigLoadError( rsp=etree.fromstring(( """<load-configuration-results> <rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error> </load-configuration-results>"""))) self.conf.rpc.load_config = MagicMock(side_effect=ex) self.assertRaises(ConfigLoadError, self.conf.load, path='config.conf') @patch('__builtin__.open') def test_config_try_load_exception(self, mock_open): class OtherException(Exception): pass self.conf.rpc.load_config = MagicMock(side_effect=OtherException()) self.assertRaises(OtherException, self.conf.load, path='config.conf') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_template_path(self, mock_etree): self.conf.rpc.load_config = MagicMock() self.conf.dev.Template = MagicMock() self.conf.load(template_path='test.xml') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_template(self): class Temp: filename = 'abc.xml' render = MagicMock(return_value='<test/>') self.conf.rpc.load_config = MagicMock() self.conf.load(template=Temp) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_diff_exception(self): self.conf.rpc.get_configuration = MagicMock() self.assertRaises(ValueError, self.conf.diff, 51) self.assertRaises(ValueError, self.conf.diff, -1) def test_config_lock(self): self.conf.rpc.lock_configuration = MagicMock() self.assertTrue(self.conf.lock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_lock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.lock_configuration = MagicMock(side_effect=ex) self.assertRaises(LockError, self.conf.lock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_lock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException) self.assertRaises(LockError, self.conf.lock) def test_config_unlock(self): self.conf.rpc.unlock_configuration = MagicMock() self.assertTrue(self.conf.unlock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_unlock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex) self.assertRaises(UnlockError, self.conf.unlock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_unlock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException) self.assertRaises(UnlockError, self.conf.unlock) def test_config_rollback(self): self.conf.rpc.load_configuration = MagicMock() self.assertTrue(self.conf.rollback()) def test_config_rollback_exception(self): self.conf.rpc.load_configuration = MagicMock() self.assertRaises(ValueError, self.conf.rollback, 51) self.assertRaises(ValueError, self.conf.rollback, -1) @patch('jnpr.junos.Device.execute') def test_rescue_action_save(self, mock_exec): self.dev.request_save_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('save')) @patch('jnpr.junos.Device.execute') def test_rescue_action_get_exception(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception) self.assertTrue(self.conf.rescue('get') is None) @patch('jnpr.junos.Device.execute') def test_rescue_action_get(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock() self.dev.rpc.get_rescue_information.return_value = 1 self.assertEqual(self.conf.rescue('get', format='xml'), 1) @patch('jnpr.junos.Device.execute') def test_rescue_action_delete(self, mock_exec): self.dev.rpc.request_delete_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('delete')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload(self, mock_exec): self.dev.rpc.load_configuration = MagicMock() self.dev.rpc.load_configuration.return_value = True self.assertTrue(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload_exception(self, mock_exec): self.dev.rpc.load_configuration = MagicMock(side_effect=Exception) self.assertFalse(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_unsupported_action(self, mock_exec): self.assertRaises(ValueError, self.conf.rescue, 'abc') def test_config_load_lset_from_rexp_xml(self): self.conf.rpc.load_config = MagicMock() conf = """<snmp><name>iBGP</name></snmp>""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_lset_from_rexp_set(self): self.conf.rpc.load_config = MagicMock() conf = """set system domain-name englab.nitin.net""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_set_delete(self): self.conf.rpc.load_config = MagicMock() conf = """delete snmp""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_conf(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') def test_config_load_lset_from_rexp_conf_replace_tag(self): self.conf.rpc.load_config = MagicMock() conf = """replace: snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'replace') def test_config_load_lset_from_rexp_error(self): self.conf.rpc.load_config = MagicMock() conf = """nitin>""" self.assertRaises(RuntimeError, self.conf.load, conf) def test_load_merge_true(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf, merge=True) self.assertFalse('action' in self.conf.rpc.load_config.call_args[1]) def test_commit_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.dev.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.commit)
def apply_template(self, template): print self.dev conf_string = template.strip() print conf_string if re.search(r"^<", conf_string): print "Found a encoded string" conf_string = self.unescape(conf_string) print conf_string # try to determine the format of our config_string config_format = "set" if re.search(r"^\s*<.*>$", conf_string, re.MULTILINE): print "found xml style config" config_format = "xml" elif re.search(r"^\s*(set|delete|replace|rename)\s", conf_string): print "found set style config" config_format = "set" elif re.search(r"^[a-z:]*\s*\w+\s+{", conf_string, re.I) and re.search(r".*}\s*$", conf_string): print "found a text style config" config_format = "text" print "using format: " + config_format cu = Config(self.dev) try: cu.lock() except LockError as le: print "Could not lock database!" print str(le) self.dev.close() return "Failed to lock configuration database! %s" % str(le) try: print "loading config" cu.load(conf_string, format=config_format) except Exception as e: print "Could not load configuration" print str(e) try: cu.unlock() except UnlockError as ue: print str(ue) self.dev.close() return "Failed, could not load the configuration template. %s" % str(e) diff = cu.diff() print diff if diff is not None: try: cu.commit_check() print "Committing config!" cu.commit(comment="Commit via a_frame") except CommitError as ce: print "Could not load config! %s" % str(ce) cu.rollback() try: print "Unlocking database!" cu.unlock() except UnlockError as ue: print "Could not unlock database" print str(ue) print repr(ce) self.dev.close() return "Failed, commit check failed. %s" % str(ce) else: # nothing to commit print "Nothing to commit - no diff found" cu.unlock() self.dev.close() return "Nothing to commit!" try: print "Unlocking database!" cu.unlock() except UnlockError as ue: print "Could not unlock database" print str(ue) self.dev.close() return "Committed, but could not unlock db" print "Closing device handle" self.dev.close() return "Completed with diff: %s" % diff
class NetconfJuniperSess(SessBase): """netconfセッション用クラス """ def __init__(self, server, user_login, pass_login, logger_name, netconf_port=830, rpc_timeout=20): self.server = server self.user_login = user_login self.pass_login = pass_login self.logger = logging.getLogger(logger_name) self.netconf_port = netconf_port self.rpc_timeout = rpc_timeout self.closed = True self.acl_name = 'SNMP-ACCESS' self.last_acl = list() def open(self): """サーバに接続 """ self.dev = Device( host=self.server.ipaddr, user=self.user_login, password=self.pass_login, ) self.dev.open(gather_facts=False) if self.dev.connected: # デフォルト30秒を更新 setattr(self.dev, 'timeout', self.rpc_timeout) self.cu = Config(self.dev) self.closed = False self.write_log(self.logger, 'info', "%s (%s): 接続しました." % (self.server.ipaddr, self.server.model, )) else: raise RuntimeError("%s: %s: unable to connect." % (self.__class__.__name__, self.server.ipaddr)) def get_snmp_acl(self, **kw): """ SNMPアクセスリストを取得 >>> for pl in PrefListTable(self.dev).get(): ... if pl.name == 'SNMP-ACCESS': ... pp.pprint(json.loads(pl.entries.to_json())) ... { u'10.0.0.1/32': { u'prefix': u'10.0.0.1/32'}, u'172.25.8.0/24': { u'prefix': u'172.25.8.0/24'}, u'172.31.30.0/24': { u'prefix': u'172.31.30.0/24'}, u'192.168.11.0/24': { u'prefix': u'192.168.11.0/24'}} """ set_last_acl = kw.get('set_last_acl', True) acl = list() for pl in PrefListTable(self.dev).get(): if pl.name == self.acl_name: # prefix-list name がマッチしたらエントリを取得 acl = map(IPv4Network, pl.entries.keys()) break # 取得できなかった場合はカラのリストを返す if set_last_acl: self.last_acl = acl return acl def update_snmp_acl(self, acl_diff_dict, **kw): """ SNMPアクセスリストを更新 """ if not os.access(template_path, os.R_OK): self.close(error_msg="テンプレートファイルを開けません.: %s" % (template_path, )) raise IOError('failed!') if kw.get('prompt', False): # 確認プロンプトを表示 reply = raw_input("変更しますか? ") if not re.match('\s*(y|yes|)\s*$', reply.rstrip(), re.I): self.write_log(self.logger, 'info', "%s: 更新をキャンセルします." % (self.server.ipaddr, )) self.close() return False new_acl = list(set(self.last_acl) - set(acl_diff_dict['del'])) + acl_diff_dict['add'] template_vars = dict([ ('acl_dict', dict([ (self.acl_name, [ n.with_prefixlen for n in new_acl ]), ])), ]) # 新しいACLを機器にロードする self.cu.lock() self.cu.load(template_path=template_path, template_vars=template_vars) return self.get_snmp_acl(set_last_acl=False) def save_exit_config(self, **kw): """ コミット or ロールバック """ if kw.get('prompt', False): # 確認プロンプトを表示 if not re.match('\s*(y|yes|)\s*$', raw_input("保存しますか? ").rstrip(), re.I): self.write_log(self.logger, 'info', "%s: ロールバックします." % (self.server.ipaddr, )) self.cu.rollback() current_acl = self.get_snmp_acl(set_last_acl=False) failed = set(current_acl) != set(self.last_acl) if failed: self.close(error_msg="正常にロールバックできませんでした.: %s%s" % ( self.last_acl, current_acl, )) raise RuntimeError('failed!') self.close() return # コミット self.cu.commit() self.cu.unlock() self.write_log(self.logger, 'debug', "%s: コミットしました." % (self.server.ipaddr, )) def close(self, error_msg=None): """ セッション終了 """ if self.closed: return self.dev.close() if error_msg: self.write_log(self.logger, 'error', "%s: %s" % (self.server.ipaddr, error_msg)) else: self.write_log(self.logger, 'debug', "%s: セッションを閉じました." % (self.server.ipaddr, )) self.closed = True
# Create a Config instance cfg = Config(a_device) # Lock the Juniper device while you are doing the config changes cfg.lock() # 1. Load config via load-set command cfg.load("set system host-name juniper-test-name", format="set", merge=True) # Show the differences between running-config and candidate config print cfg.diff() # cfg.commit() # Rollback the candidate config changes cfg.rollback(0) # 2. Load new config via 'test_config.conf' file (using curly braces) # Create test_config.conf file first in the currently-running Linux directory cfg.load(path="test_config.conf", format="text", merge=True) # Show the differences between running-config and candidate config print cfg.diff() cfg.rollback(0) # 3. Load new config via 'test_config.xml' file (in XML format) # Create test_config.xml file first in the currently-running Linux directory cfg.load(path="test_config.xml", format="xml", merge=True)
E('filter', E('name', 'test'), E('term', E('name', 'term1'), E('from', E('source-address', E('name', '1.1.1.1/32') ) ) ) ) ) ) #cu.load(data, format='xml') cu.load(data) print "\nconfig# show | compare" cu.pdiff() if cu.commit_check(): print "\nCommiting..\n" # cu.commit(comment="Configuring ge-1/0/1 interfaces") cu.commit(sync=True) else: cu.rollback() print "Rolling back the configuration" cu.rollback(rb_id=1) cu.commit(detail=True)
#----------------------------------------------------------------------------------------------------------------------- # DESCRIPTION: # Use PyEZ to enable LLDP on a subset of interfaces for a specific device. # # CONTACT: [email protected]; [email protected]; [email protected]; [email protected]; [email protected] # # CREATED: 2015-11-11 # # VERSION: 1 # # USAGE: enable_lldp.py # ----------------------------------------------------------------------------------------------------------------------- from jnpr.junos import Device # import the class Device from jnpr.junos.utils.config import Config # import the class Config import yaml s=open('configuration_management/interfaces.yml').read() #s is a string my_variables=yaml.load(s) # my_variables is a dictionary a_device=Device (host="172.30.179.113", user="******", password="******") a_device.open() cfg=Config(a_device) # cfg is the candidate configuration cfg.rollback() cfg.load(template_path='configuration_management/template_lldp.j2', template_vars=my_variables, format='set') cfg.pdiff() cfg.commit()
class Netconf(object): def __init__(self): if not HAS_PYEZ: raise NetworkError( msg= 'junos-eznc >= 1.2.2 is required but does not appear to be installed. ' 'It can be installed using `pip install junos-eznc`') if not HAS_JXMLEASE: raise NetworkError( msg='jxmlease is required but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`') self.device = None self.config = None self._locked = False self._connected = False self.default_output = 'xml' def raise_exc(self, msg): if self.device: if self._locked: self.config.unlock() self.disconnect() raise NetworkError(msg) def connect(self, params, **kwargs): host = params['host'] kwargs = dict() kwargs['port'] = params.get('port') or 830 kwargs['user'] = params['username'] if params['password']: kwargs['passwd'] = params['password'] if params['ssh_keyfile']: kwargs['ssh_private_key_file'] = params['ssh_keyfile'] kwargs['gather_facts'] = False try: self.device = Device(host, **kwargs) self.device.open() except ConnectError: exc = get_exception() self.raise_exc('unable to connect to %s: %s' % (host, str(exc))) self.config = Config(self.device) self._connected = True def disconnect(self): try: self.device.close() except AttributeError: pass self._connected = False ### Command methods ### def run_commands(self, commands): responses = list() for cmd in commands: meth = getattr(self, cmd.args.get('command_type')) responses.append(meth(str(cmd), output=cmd.output)) for index, cmd in enumerate(commands): if cmd.output == 'xml': responses[index] = etree.tostring(responses[index]) elif cmd.args.get('command_type') == 'rpc': responses[index] = str(responses[index].text).strip() return responses def cli(self, commands, output='xml'): '''Send commands to the device.''' try: return self.device.cli(commands, format=output, warning=False) except (ValueError, RpcError): exc = get_exception() self.raise_exc('Unable to get cli output: %s' % str(exc)) def rpc(self, command, output='xml'): name, kwargs = rpc_args(command) meth = getattr(self.device.rpc, name) reply = meth({'format': output}, **kwargs) return reply ### Config methods ### def get_config(self, config_format="text"): if config_format not in SUPPORTED_CONFIG_FORMATS: self.raise_exc(msg='invalid config format. Valid options are ' '%s' % ', '.join(SUPPORTED_CONFIG_FORMATS)) ele = self.rpc('get_configuration', output=config_format) if config_format == 'text': return str(ele.text).strip() else: return ele def load_config(self, config, commit=False, replace=False, confirm=None, comment=None, config_format='text'): if replace: merge = False overwrite = True else: merge = True overwrite = False if overwrite and config_format == 'set': self.raise_exc( 'replace cannot be True when config_format is `set`') self.lock_config() try: candidate = '\n'.join(config) self.config.load(candidate, format=config_format, merge=merge, overwrite=overwrite) except ConfigLoadError: exc = get_exception() self.raise_exc('Unable to load config: %s' % str(exc)) diff = self.config.diff() self.check_config() if all((commit, diff)): self.commit_config(comment=comment, confirm=confirm) self.unlock_config() return diff def save_config(self): raise NotImplementedError ### end of Config ### def get_facts(self, refresh=True): if refresh: self.device.facts_refresh() return self.device.facts def unlock_config(self): try: self.config.unlock() self._locked = False except UnlockError: exc = get_exception() raise NetworkError('unable to unlock config: %s' % str(exc)) def lock_config(self): try: self.config.lock() self._locked = True except LockError: exc = get_exception() raise NetworkError('unable to lock config: %s' % str(exc)) def check_config(self): if not self.config.commit_check(): self.raise_exc(msg='Commit check failed') def commit_config(self, comment=None, confirm=None): try: kwargs = dict(comment=comment) if confirm and confirm > 0: kwargs['confirm'] = confirm return self.config.commit(**kwargs) except CommitError: exc = get_exception() raise NetworkError('unable to commit config: %s' % str(exc)) def confirm_commit(self, checkonly=False): try: resp = self.rpc('get_commit_information') needs_confirm = 'commit confirmed, rollback' in resp[0][4].text if checkonly: return needs_confirm return self.commit_config() except IndexError: # if there is no comment tag, the system is not in a commit # confirmed state so just return pass def rollback_config(self, identifier, commit=True, comment=None): self.lock_config() try: self.config.rollback(identifier) except ValueError: exc = get_exception() self.raise_exc('Unable to rollback config: $s' % str(exc)) diff = self.config.diff() if commit: self.commit_config(comment=comment) self.unlock_config() return diff
class Netconf(object): def __init__(self, module): self.module = module self.device = None self.config = None self._locked = False def _fail(self, msg): if self.device: if self._locked: self.config.unlock() self.disconnect() self.module.fail_json(msg=msg) def connect(self, **kwargs): try: host = self.module.params['host'] port = self.module.params['port'] or 830 user = self.module.params['username'] passwd = self.module.params['password'] key_filename = self.module.params['ssh_keyfile'] self.device = Device(host, user=user, passwd=passwd, port=port, gather_facts=False, ssh_private_key_file=key_filename).open() self.config = Config(self.device) except Exception: exc = get_exception() self._fail('unable to connect to %s: %s' % (host, str(exc))) def run_commands(self, commands, **kwargs): response = list() fmt = kwargs.get('format') or 'xml' for cmd in to_list(commands): try: resp = self.device.cli(command=cmd, format=fmt) response.append(resp) except (ValueError, RpcError): exc = get_exception() self._fail('Unable to get cli output: %s' % str(exc)) except Exception: exc = get_exception() self._fail('Uncaught exception - please report: %s' % str(exc)) return response def unlock_config(self): try: self.config.unlock() self._locked = False except UnlockError: exc = get_exception() self.module.log('unable to unlock config: {0}'.format(str(exc))) def lock_config(self): try: self.config.lock() self._locked = True except LockError: exc = get_exception() self.module.log('unable to lock config: {0}'.format(str(exc))) def check_config(self): if not self.config.commit_check(): self._fail(msg='Commit check failed') def commit_config(self, comment=None, confirm=None): try: kwargs = dict(comment=comment) if confirm and confirm > 0: kwargs['confirm'] = confirm return self.config.commit(**kwargs) except CommitError: exc = get_exception() msg = 'Unable to commit configuration: {0}'.format(str(exc)) self._fail(msg=msg) def load_config(self, candidate, action='replace', comment=None, confirm=None, format='text', commit=True): merge = action == 'merge' overwrite = action == 'overwrite' self.lock_config() try: self.config.load(candidate, format=format, merge=merge, overwrite=overwrite) except ConfigLoadError: exc = get_exception() msg = 'Unable to load config: {0}'.format(str(exc)) self._fail(msg=msg) diff = self.config.diff() self.check_config() if commit and diff: self.commit_config(comment=comment, confirm=confirm) self.unlock_config() return diff def rollback_config(self, identifier, commit=True, comment=None): self.lock_config() try: result = self.config.rollback(identifier) except Exception: exc = get_exception() msg = 'Unable to rollback config: {0}'.format(str(exc)) self._fail(msg=msg) diff = self.config.diff() if commit: self.commit_config(comment=comment) self.unlock_config() return diff def disconnect(self): if self.device: self.device.close() def get_facts(self, refresh=True): if refresh: self.device.facts_refresh() return self.device.facts def get_config(self, config_format="text"): if config_format not in ['text', 'set', 'xml']: msg = 'invalid config format... must be one of xml, text, set' self._fail(msg=msg) ele = self.rpc('get_configuration', format=config_format) if config_format in ['text', 'set']: return str(ele.text).strip() elif config_format == "xml": return ele def rpc(self, name, format='xml', **kwargs): meth = getattr(self.device.rpc, name) reply = meth({'format': format}, **kwargs) return reply
from jnpr.junos import Device from jnpr.junos.utils.config import Config switch = {'host': '10.10.10.150', 'user': '******', 'pw': ''} device = Device(host=switch['host'], user=switch['user'], password=switch['pw']) device.open() config = Config(device) payload = """vlans{ vlan101{ vlan-id 101; } } """ config.lock() config.load(payload, format='text') config.pdiff() if config.commit_check() == True: config.commit() else: config.rollback() config.unlock() device.close()
def provision(host, **kwargs): # host = kwargs['host'] username = kwargs["username"] password = kwargs["password"] port = kwargs["port"] compareconfig = kwargs["compareconfig"] configuration = kwargs["configuration"] waitconfirm = kwargs[b"waitconfirm"] print colored("-------------------------------------------------------------------------------\n", "yellow") print colored("Start committing configuration to: ", "cyan") + colored("%s" % host["address"], "yellow") logging.info("Start committing configuration to %s" % host["address"]) dev = Device( host=host["address"], username=username, password=password, port=port, timeout=5, device_params={"name": "junos"}, hostkey_verify=False, ) try: logging.info("Connecting to %s" % host) # logging.debug("Connecting to %s" % host) dev.open() except jnpr.junos.exception.ConnectAuthError as err: logging.info("Wrong username or password while connecting to %s." % host["address"]) print colored("Wrong username or password while connecting to %s.", "red") % host["address"] host["status"] = CONNECTION_FAILED return except jnpr.junos.exception.ConnectUnknownHostError as err: logging.info("Wrong hostname: %s." % host["address"]) print "Host: " + colored("%s" % host["address"], "red") + " not found. Wrong FQDN?" host["status"] = CONNECTION_FAILED return except jnpr.junos.exception.ConnectRefusedError as err: logging.info("NETCONF session to %s failed." % host["address"]) print "Host: " + colored("NETCONF session to %s failed", "red") % host["address"] host["status"] = CONNECTION_FAILED return except jnpr.junos.exception.ConnectTimeoutError as err: logging.info("Time-out error. Could not open socket to: %s." % host["address"]) print "Time-out error. Could not open socket to : " + colored("%s" % host["address"], "red") host["status"] = CONNECTION_FAILED return # Create an instance of Config cu = Config(dev) logging.debug("Acquiring lock to %s." % host) # lock the device try: cu.lock() except jnpr.junos.exception.LockError as err: logging.info("Error: unable to lock configuration in %s." % host["address"]) print colored("Error: unable to lock configuration in %s", "red") % host["address"] host["status"] = UNABLE_TO_LOCK dev.close() return # parse configuration file and load commands. Handle exceptions accordingly for line in configuration: if line[0] != "#": logging.debug("Loading command: %s in %s " % (line.rstrip("\n"), host["address"])) try: cu.load(line, format="set", merge=False) except jnpr.junos.exception.ConfigLoadError as err: logging.info( "Failed loading command '%s' with severity %s in %s." % (line.rstrip("\n"), err.errs["severity"], host["address"]) ) print colored("Loading command failed with severity: %s", "red") % err.errs["severity"] host["status"] = COMMIT_FAILED_WARNING if err.errs["severity"] == "error": cu.rollback() logging.info("Commit failed. Rolling back in %s and exiting the script" % host["address"]) logging.debug("Commit failed with %s rolling back in %s" % (err, host["address"])) print colored("Exiting, configuration rolled-back", "red") host["status"] = COMMIT_FAILED_ERROR cu.unlock() dev.close() sys.exit(1) # print "show|compare" results to stdout if requested if compareconfig != "true": print colored("\n'show | compare' output:", "blue") print cu.diff() if waitconfirm == b"true": if kwargs["first_host"] == b"true": ack = raw_input("Proceed with commiting? [y/n]: ") else: ack = "yes" else: ack = "yes" if ack == "y" or ack == "yes": try: cu.commit(comment="This is netconf jprovision script") logging.info("Committing to %s succeded." % host["address"]) logging.debug("Committing to %s succeded." % host["address"]) print colored("Succeeded", "green") if not str(host["status"]): host["status"] = SUCCESSFUL except jnpr.junos.exception.CommitError as err: cu.rollback() logging.info("Commit failed rolling back in %s" % host["address"]) logging.debug("Commit failed with %s rolling back in %s" % (err, host["address"])) print colored("Configuration rolled-back due to commit error", "red") host["status"] = COMMIT_FAILED_ERROR elif ack == "n" or ack == "no": logging.info("User aborted commiting") sys.stdout.write("User aborted, rolling back and exiting.\n") cu.rollback() host["status"] = COMMIT_ABORTED sys.exit(0) cu.unlock() dev.close() logging.info("Finished.")
cu = Config(dev) data = """interfaces { ge-1/0/1 { description "MPLS interface"; unit 0 { family mpls; } } ge-1/0/2 { description "MPLS interface"; unit 0 { family mpls; } } } protocols { mpls { interface ge-1/0/1; interface ge-1/0/2; } } """ cu.load(data, format='text') cu.pdiff() if cu.commit_check(): cu.commit() else: cu.rollback() dev.close()
ip_addr = raw_input('Enter IP address: ') user = raw_input('Enter the username: '******'-' * 30 print 'Rollback' myconfig.rollback(0) print "Test using config method" print "-" * 30 myconfig.load(path="test_hostname.conf", format="text", merge=True) print "Print difference" print myconfig.diff() print "commit changes" myconfig.commit(comment="Testing conf commit BE") print "Test using xml method" print "-" * 30 myconfig.load(path="test_hostname.xml", format="xml", merge=True) print "Print difference" print myconfig.diff() print "commit changes"
f2=open('configuration_builder/template.j2') s2=f2.read() template=Template(s2) print 'Start configuration building' for ex in my_vars: print 'generate config file for device '+ex["host_name"]+' : conf_file_build_phase_'+ex["host_name"]+'.conf' conffile=open('conf_file_build_phase_'+ex["host_name"]+'.conf','w') conffile.write(template.render(ex)) conffile.close() print 'done' print 'applying the conf to the devices ...' for ex in my_vars: dev = Device(host=ex["management_ip"], user='******', password='******') dev.open() cfg=Config(dev) cfg.rollback() # Execute Rollback to prevent commit change from old config session #cfg.load(template_path='template_for_ex.j2', template_vars=my_vars, format='text') cfg.load(path='conf_file_build_phase_'+ex["host_name"]+'.conf', format='text') if cfg.commit() == True: print ('configuration commited on ' + dev.facts["hostname"]) else: print ('commit failed on ' + dev.facts["hostname"]) dev.close() print ('done')
#----------------------------------------------------------------------------------------------------------------------- # DESCRIPTION: # Use PyEZ to automatically merge a variables YML file and a Jinja2 template and update the candidate configuration on # a device. # # CONTACT: [email protected]; [email protected]; [email protected]; [email protected]; [email protected] # # CREATED: 2015-11-11 # # VERSION: 1 # # USAGE: conf_int_with_vlan.py # ----------------------------------------------------------------------------------------------------------------------- from jnpr.junos import Device from jnpr.junos.utils.config import Config import yaml ip = raw_input("ip address of the device:") a_device = Device(host=ip, user="******", password="******") a_device.open() cfg = Config(a_device) cfg.rollback() s = open('configuration_management/list_int_vlan.yml').read() myvars = yaml.load(s) cfg.load(template_path='configuration_management/template_int_vlan.j2', template_vars=myvars, format='set') cfg.pdiff() #cfg.commit() cfg.rollback()
def run(self): # import pdb; pdb.set_trace() # dbg dev = Device(host=self.host, user=self.user, password=self.passw) try: dev.open(auto_probe=7) except: self.result += "Could not connect to host\n" return if not self.mode: self.result += "A mode of operation must be specified" elif self.mode == "configure": confc = Config(dev) if self.action == "commit": self.result += confc.commit(confirm=True, comment="Commited " + str( datetime.datetime.now() ) + " by jCnC") elif self.action == "commit_check": if confc.commit_check(): self.result += "Commit Check Succeeds" else: self.result += "Commit Check Failed" elif self.action == "diff": x = int(self.param) self.result += confc.diff() #self.param) elif self.action == "load": self.result += confc.load(path=param, overwrite=True, format='conf') elif self.action == "lock": self.result += confc.lock() elif self.action == "rescue": self.result += confc.rescue(param) elif self.action == "rollback": self.result += confc.rollback(param) elif self.action == "save": shell = self.start_shell() stdin, stdout, stderr = shell.exec_command("cli show configuration | cat") config = "" for line in stdout.readlines(): self.result += line config += line ## check for host dir, create if not found hostpath = self.host if not os.path.exists(hostpath): os.makedirs(hostpath) hostpath += "/configuration" ## copy file into directory with open(hostpath, 'w') as output: output.write(config) shell.exec_command("rm /tmp/configuration\n") shell.close elif self.action == "unlock": self.result += confc.unlock() else: self.result += "Configuration Action not found" elif self.mode == "software": softw = SW(dev) if self.action == "install": hash = str('') with open(param+'.md5') as hashfile: hash = hashfile.read() hashfile.closed() self.action += softw.install(param, remote_path='/var/tmp', progress=dev, validate=False, checksum=hash, cleanfs=False, no_copy=False, timout=1800) elif action == "rollback": self.action += softw.rollback() elif self.mode == "cli": shell = self.start_shell() if self.action == "terminal": stdin, stdout, stderr = shell.exec_command("cli") stdin.write(self.param + '\n') stdin.write("exit\n") stdin.flush() for line in stdout.readlines(): self.result += line elif self.action == "file": self.result += "\n" stdin, stdout, stderr = shell.exec_command("cli") cfile = open(self.param, 'r') for line in cfile: stdin.write(line + '\n') stdin.write("exit\n") data = stdout.readlines() for line in data: self.result += "\n" + line shell.close() elif self.mode == "info": shell = self.start_shell() if self.action == "alarms": stdin, stdout, stderr = shell.exec_command("cli show chassis alarms") data = stdout.readlines() for line in data: self.result += line elif self.action == "active_ports": stdin, stdout, stderr = shell.exec_command('cli show interfaces terse | grep -v "\.0" | grep -v down') data = stdout.readlines() for line in data: self.result += line elif self.action == "inactive_ports": stdin, stdout, stderr = shell.exec_command('cli show interfaces terse | grep -v "\.0" | grep down') data = stdout.readlines() for line in data: self.result += line else: self.result += "Information Action not found" shell.close() else: self.result = "Operation Mode not found" dev.close() self.result += "\n"