def load_configuration_from_template(self, commit_comment='pybot_jrouter_load_configuration_from_template', format='set', conf_mode='exclusive', overwrite=False, merge=False, synchronize=True, force_synchronize=False, full=False, print_conf_diff=False, print_conf_detail=False, **kvargs): """ # General Options: # - format can be text/set/xml # - print_conf_diff will print the diff if desired # - print_conf_detail will print the committed configuration if desired # Configuration Options: # - conf_mode: can be exclusive/private/dynamic/batch # Load Options: # - overwrite: Determines if the contents completely replace the existing configuration. Default is False # - merge: If set to True will set the load-config action to merge the default load-config action is 'replace' # Commit Options: # - kvargs synchronize: Default True. On dual control plane systems, requests that the candidate configuration on one control plane be copied to the other control plane, checked for correct syntax, and committed on both Routing Engines. Default is True. # - kvargs force_synchronize: Default False. On dual control plane systems, forces the candidate configuration on one control plane to be copied to the other control plane. Default is False # - kvargs full: Default False. When True requires all the daemons to check and evaluate the new configuration """ print ("*INFO* Host %s|load_configuration_from_template|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail)) synchronize = True force_synchronize = False full = False if 'force_synchronize' in kvargs.keys(): force_synchronize = kvargs['force_synchronize'] if 'synchronize' in kvargs.keys(): synchronize = kvargs['synchronize'] if 'full' in kvargs.keys(): full = kvargs['full'] ##Hidden variable: DO NOT USE DO NOT EDIT #It will be set to True ONLY if routers.load_configuration_from_template_in_parallel is executed if 'parallel' in kvargs.keys(): parallel = kvargs['parallel'] else: parallel = False if force_synchronize: synchronize = True print ("*INFO* Host %s|load_configuration_from_template|Force Synchronized Commit requested" % (self.target)) if synchronize: print ("*INFO* Host %s|load_configuration_from_template|Synchronized Commit requested" % (self.target)) if full: print ("*INFO* Host %s|load_configuration_from_template|Commit Full requested" % (self.target)) print ("*INFO* Host %s|load_configuration_from_template|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite)) if format == 'set' and overwrite: overwrite = False print ("*WARN* Host %s|load_configuration_from_template|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target)) yaml_file = kvargs['template_vars'] # Loading files and rendering myvars = yaml.load(open(yaml_file).read()) loadResp = '' commitResp = False print ("*INFO* Host %s|load_configuration_from_template|Initializing variables. template_path=%s." % (self.target, kvargs['jinja2_file'])) try: #Unlock/close configuration is managed by Config context manager with Config(self._conn, mode=conf_mode) as candidate: begin_load_datetime = datetime.now() if overwrite: loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=True, merge=merge) else: loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=False, merge=merge) finish_load_datetime = datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration_from_template|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) begin_commit_datetime = datetime.now() if print_conf_detail: try: #begin_commit_datetime=datetime.now() commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True) #finish_commit_datetime=datetime.now() print ('*INFO* Host %s|load_configuration_from_template|Configuration to be committed: %s' % (self.target, etree.tostring(commitResp))) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the committed configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error)) return False else: begin_commit_datetime = datetime.now() commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False) finish_commit_datetime = datetime.now() except LockError as lockError: print ("*WARN* Host %s|load_configuration_from_template|Problems locking configuration: %s" % (self.target, lockError)) if parallel: return "Exception %s:" %lockError else: raise FatalError("Host %s|load_configuration_from_template|Unable to lock configuration.....exiting: %s" % (self.target, lockError)) except (RpcError, RpcTimeoutError) as rpcError: #warnings severity is already being ignored in the Config context manager print ("*WARN* Host %s|load_configuration_from_template|Problems opening configuration: %s" % (self.target, rpcError)) if parallel: return "Exception %s:" %rpcError else: raise FatalError("Host %s|load_configuration_from_template|Unable to open configuration.....exiting: %s" % (self.target, rpcError)) except ConfigLoadError as configError: print( "*WARN* Host %s|load_configuration_from_template|Template %s|Problems loading the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], configError)) if print_conf_diff: try: print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) if parallel: return "Exception %s:" %configError else: raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to load the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], configError)) except CommitError as commitError: print ("*WARN* Host %s|load_configuration_from_template|Template %s|Problems committing the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], commitError)) if parallel: return "Exception %s:" %commitError else: raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to commit the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], commitError)) except UnlockError as unlockError: print ("*WARN* Host %s|load_configuration_from_template|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError)) if parallel: return "Exception %s:" %unlockError else: raise FatalError("Host %s|load_configuration_from_template|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError)) except Exception as error: if 'Opening and ending tag mismatch: routing-engine ' in error: print ('*INFO* Host %s|load_configuration_from_template|%s' %(self.target, error)) pass return True else: print ("*WARN* Host %s|load_configuration_from_template|An unhandled exception occurred: %s.....exiting" % (self.target, error)) if parallel: return "Exception %s:" %error else: raise FatalError("Host %s|load_configuration_from_template|Unhandled Exception occurred.....exiting: %s" % (self.target, error)) diff_load_time = finish_load_datetime - begin_load_datetime diff_commit_time = finish_commit_datetime - begin_commit_datetime total_time = finish_commit_datetime - finish_load_datetime print ('*INFO* Host %s|load_configuration_from_template|Configuration successfully committed|Template: %s|Load Time: %s|Commit Time: %s| Total Time: %s' % (self.target, kvargs['jinja2_file'], self.pretty_time_delta(diff_load_time.seconds), self.pretty_time_delta(diff_commit_time.seconds), self.pretty_time_delta(total_time.seconds))) return True
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 getdevice(ip_address, username, password): """ Retrieve and return device class. """ device = Device(host=ip_address, user=username, password=password) device.open() return device if __name__ == '__main__': 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"
dev_ip_address = '192.168.124.39' dev_username = '******' dev_password = '******' dev = Device(host=dev_ip_address, user=dev_username, passwd=dev_password, mode='telnet', port='23') try: dev.open() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) sys.exit(1) except Exception as err: print (err) sys.exit(1) with Config(dev, mode='private') as cu: cu.load(url="ftp://<username:pwd>@192.168.127.238/bootstrap_ssh.conf", overwrite=True) #cu.pdiff() cu.commit() for i in xrange(40, 0, -1): time.sleep(1) dev_ssh = Device(host=dev_ip_address, user=dev_username, passwd=dev_password, port='22') try: dev_ssh.open() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) sys.exit(1) except Exception as err:
#----------------------------------------------------------------------------------------------------------------------- # 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()
#!/usr/bin/python from jnpr.junos import Device from jnpr.junos.utils.config import Config if __name__ == '__main__': data = 'set system services netconf traceoptions file test.log' with Device(host='172.25.11.1', user='******', passwd='lab123') as dev: with Config(dev, mode="exclusive") as conf: conf.load(data, format='set', merge=False, overwrite=False) diff = conf.diff() if diff is None: print("Configuration already up to date.") else: print(diff) conf.commit()
fh = fp = open('hosts.txt', 'r') line = fp.readline() while line: h = line.split(" ") hosts[h[0]]=h[1] line = fp.readline() cfbase=args.fname jfile = "jtemplates/"+cfbase+".j2" for x in hosts.keys(): '''Connect to device''' print 'Connecting to {0}...'.format(x) dev = Device(host=hosts[x], user=args.username, password=args.password) dev.open(gather_facts=False) cfg = Config(dev) yfile = "ytemplates/"+x+"_"+cfbase+".yaml" s=open(yfile).read() myvars=yaml.load(s) cfg.load(template_path=str(jfile), template_vars=myvars, format='set') if cfg.commit_check(): if cfg.commit: print 'Committing...' cfg.commit(timeout=300) print 'Successfully Committed' else: print 'Commit Failed' else: print 'Commit Check Failed' dev.close()
''' bgpasn = helpers.fetch_value("bgpasn", 1) bgp_detail.update({name: {'bgpasn': bgpasn}}) for name, value in vqfxDict.iteritems(): print "\n##### Configuring: " + name + " #####\n" print "Configuring Below Device " + name + "\nHost IP: " + value[ 'host'] + "\n" + "Host Port: " + value['port'] + "\n" # Access the device using pyez netconf and fetch Serial Number print "Connecting to the device....\n" dev = helpers.device_connect(value['host'], value['port']) dev.open() # Clear the previous configs if any with Config(dev, mode='private') as cu: del_interface = "delete protocols bgp" cu.load(del_interface, format='set', ignore_warning=True) cu.pdiff() cu.commit() with Config(dev, mode='private') as cu: del_interface = "delete protocols lldp" cu.load(del_interface, format='set', ignore_warning=True) cu.pdiff() cu.commit() with Config(dev, mode='private') as cu: del_interface = "delete routing-options" cu.load(del_interface, format='set', ignore_warning=True) cu.pdiff()
from jnpr.junos import Device from jnpr.junos.utils.config import Config from getpass import getpass srx1 = Device(host="srx1.lasthop.io", user="******", password=getpass()) srx1.open() cfg = Config(srx1) cfg.lock() cfg.load("set system host-name test123", format="set", merge=True) print(cfg.diff()) cfg.commit(comment="Changing the hostname") cfg.unlock()
def test_config_mode_ephemeral_default(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='ephemeral') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(ephemeral=True)
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'))
from jnpr.junos import Device from jnpr.junos.utils.config import Config logon_creds = { 'host': '10.4.4.41', 'user': '******', 'password': '******' } print("\nConnecting to Juniper...\n") junos_device = Device(**logon_creds) junos_device.open() junos_device.timeout = 300 # Create a configurator for the device cfg = Config(junos_device) print("Setting hostname using set notation...") new_hostname = input('Enter the new hostname: ') cfg.load(f"set system host-name {new_hostname}", format="set", merge=True) print("Current config differences: ") config_difference = cfg.diff() if not config_difference: print('No configuration changes to bemade.') else: print(config_difference) confirm_commit = input('Confirm commit for these changes. (y/n): ') if confirm_commit is 'y': print("Performing commit...") cfg.commit()
def campus_underlay(self, device_ips, spine_ips): helpers = Helpers() vqfxDict = {} hosts_dict = {} link_layer_list = list() link_layer_map = {} bgp_detail = {} for spine_ip in spine_ips: ''' BGP INFORMATION FETCHED IP IS NONE. WILL BE ASSIGNED LATER ''' dev = helpers.device_connect(spine_ip) dev.open() on_box_hostname = dev.facts["hostname"] bgpasn = helpers.fetch_value("bgpasn", 1) bgp_detail.update({on_box_hostname: {'bgpasn': bgpasn}}) dev.close() print list(bgp_detail.keys()) for spine_ip in spine_ips: # Access the device using pyez netconf and fetch Serial Number dev = helpers.device_connect(spine_ip) dev.open() on_box_hostname = dev.facts["hostname"] # Fetch the link layer information interfaces = list() remote_connections = list() ints_list = list() bgp_list = list() interfaces_dict = {} print "Fetching LINK LAYER CONNECTIVITY INFORMATION" cli_lldp = dev.rpc.get_lldp_neighbors_information() print "links" for lldp in cli_lldp.findall("lldp-neighbor-information"): ''' LINK LAYER CONNECTIVITY INFORMATION APPENDED ''' local_port = lldp.findtext("lldp-local-interface") if local_port is None: local_port = lldp.findtext("lldp-local-port-id") local_port = local_port else: local_port = local_port.split(".") local_port = local_port[0] with Config(dev, mode='private') as cu: del_interface = "delete interfaces " + local_port + " unit 0 family inet" cu.load(del_interface, format='set', ignore_warning=True) cu.pdiff() cu.commit() remote_chassis = lldp.findtext("lldp-remote-chassis-id") remote_system = lldp.findtext("lldp-remote-system-name") print on_box_hostname + "**" + remote_system if remote_system in list(set(bgp_detail.keys())): interfaces.append(local_port) remote_connections.append(remote_system) remote_port = lldp.findtext("lldp-remote-port-description") remote_port = remote_port.split(".") remote_port = remote_port[0] link_layer_list.append({ 'local_system': on_box_hostname, 'local_port': local_port, 'local_ip': 'None', 'remote_ip': 'None', 'remote_system': remote_system, 'remote_port': remote_port, 'broadcast': 'None' }) ''' INTERFACES INFORMATION FETCHED IP IS NONE. WILL BE ASSIGNED LATER ''' print "Fetching INTERFACES INFORMATION" description = "to_" + remote_system local_port = local_port.strip() description = description.strip() ints_list.append({ 'physical_interface': local_port, 'description': description, 'ip_address': "None" }) ''' BGP INFORMATION FETCHED IP IS NONE. WILL BE ASSIGNED LATER ''' print "Fetching BGP INFORMATION" local_as = bgp_detail[on_box_hostname]["bgpasn"] bgp_router_id = helpers.fetch_value("bgp_router_id", 1) for remote_connection in remote_connections: print remote_connection print bgp_detail remote_as = bgp_detail[remote_connection]["bgpasn"] print remote_as bgp_list.append({ 'remote_as': remote_as, 'remote_peer': 'None', 'remote_description': remote_connection }) ''' INTERFACES,BGP,BGP_ROUTER_ID,BGPASN,ROUTER_FILTER INFORMATION APPENDED IPs ARE NONE. WILL BE ASSIGNED LATER ''' interfaces_dict.update({ on_box_hostname: { 'interfaces': ints_list, 'bgp_router_id': bgp_router_id, 'bgpasn': local_as, 'bgp': bgp_list, 'route_filter': [], 'overlay_peers': [], 'vlans': [10, 20, 30, 40] } }) hosts_dict.update(interfaces_dict) dev.close() ''' LINK LAYER MAP: LINK INFO: LOCAL(PORT,IP,HOST) & REMOTE(PORT,IP,HOST) REMOVE DUPLICATES: DUPLICATES EXIST BCOS SAME LINK INFO FOUND IN BOTH LOCAL AND REMOTE HOST ''' print "Creating LINK LAYER MAP: LOCAL(PORT,IP,HOST) & REMOTE(PORT,IP,HOST)" link_layer_map.update({'link_layer': link_layer_list}) links = link_layer_map["link_layer"] for link in links: for rlink in links: if link["local_system"] + link["local_port"] == rlink[ "remote_system"] + rlink["remote_port"]: if link["remote_system"] + link["remote_port"] == rlink[ "local_system"] + rlink["local_port"]: links.remove(rlink) ''' GENERATE IPS FOR CONNECTED INTERFACES BASED ON: IP START & IP END, NETMASK, ALREADY USED IP ''' print "GENERATE IPS FOR CONNECTED INTERFACES BASED ON: IP START & IP END, NETMASK, ALREADY USED IP" for link in links: interface_ip = helpers.fetch_value("interface_ip", 1) print "return value" print interface_ip ip = IPCalculator(interface_ip) ip_detail = ip.__repr__() hostrange = ip_detail["hostrange"] hostrange = hostrange.split("-") broadcast = ip_detail["broadcast"] cidr = ip_detail["cidr"] link['local_ip'] = hostrange[0] + "/" + str(cidr) print "local_ip" print link['local_ip'] link['remote_ip'] = hostrange[1] + "/" + str(cidr) print "remote_ip" print link['remote_ip'] link['broadcast'] = broadcast + "/" + str(cidr) print "broadcast" print link['broadcast'] ''' ASSIGN THE GENERATED IPs TO THE INTERFACES CONFIG ''' print "ASSIGN THE GENERATED IPs TO THE INTERFACES CONFIG" for key, vals in hosts_dict.iteritems(): hostname = key for key, vals in vals.iteritems(): if key == "interfaces": for val in vals: interface = val["physical_interface"] for link in links: if hostname == link[ "local_system"] and interface == link[ "local_port"]: val["ip_address"] = link["local_ip"] elif hostname == link[ "remote_system"] and interface == link[ "remote_port"]: val["ip_address"] = link["remote_ip"] ''' ASSIGN THE GENERATED IPs TO THE "BGP CONFIG,ROUTE FILTERS CONFIG" ''' print "ASSIGN THE GENERATED IPs to BGP CONFIG,ROUTE FILTERS CONFIG" for key, values in hosts_dict.iteritems(): hostname = key filter_list = list() for key, vals in values.iteritems(): if key == "bgp": for val in vals: bgp_remote_host = val["remote_description"] for link in links: if hostname == link[ "local_system"] and bgp_remote_host == link[ "remote_system"]: val["remote_peer"] = link["remote_ip"].replace( "/30", "") filter_list.append(val["remote_peer"] + "/32") elif hostname == link[ "remote_system"] and bgp_remote_host == link[ "local_system"]: val["remote_peer"] = link["local_ip"].replace( "/30", "") filter_list.append(val["remote_peer"] + "/32") for filter in filter_list: values['route_filter'].append(filter) ''' ASSIGN THE GENERATED IPs TO THE "BGP CONFIG,ROUTE FILTERS CONFIG" ''' print "ASSIGN THE GENERATED IPs to BGP CONFIG,ROUTE FILTERS CONFIG" for key, values in hosts_dict.iteritems(): hostname = key filter_list = list() for key, vals in values.iteritems(): if key == "bgp": for val in vals: bgp_remote_host = val["remote_description"] print bgp_remote_host print hosts_dict[bgp_remote_host]["bgp_router_id"] filter_list.append( hosts_dict[bgp_remote_host]["bgp_router_id"]) for filter in filter_list: values['overlay_peers'].append(filter) print hosts_dict ''' CONFIG TEMPLATE ''' template_filename = "QFX_eBGP.conf" complete_path = os.path.join(os.getcwd(), 'Config') template_file = complete_path + "/" + template_filename for spine_ip in spine_ips: helpers.load_template_config(spine_ip, hosts_dict, template_file) ''' CONFIG TEMPLATE ''' template_filename = "QFX_iBGP.conf" complete_path = os.path.join(os.getcwd(), 'Config') template_file = complete_path + "/" + template_filename for spine_ip in spine_ips: helpers.load_template_config(spine_ip, hosts_dict, template_file) ''' CONFIG TEMPLATE ''' template_filename = "QFX_vlans.conf" complete_path = os.path.join(os.getcwd(), 'Config') template_file = complete_path + "/" + template_filename for spine_ip in spine_ips: helpers.load_template_config(spine_ip, hosts_dict, template_file) ''' CONFIG TEMPLATE ''' template_filename = "QFX_routing_instance.conf" complete_path = os.path.join(os.getcwd(), 'Config') template_file = complete_path + "/" + template_filename for spine_ip in spine_ips: helpers.load_template_config(spine_ip, hosts_dict, template_file) ''' CONFIG TEMPLATE ''' template_filename = "QFX_ae.conf" complete_path = os.path.join(os.getcwd(), 'Config') template_file = complete_path + "/" + template_filename for spine_ip in spine_ips: helpers.load_template_config(spine_ip, hosts_dict, template_file)
def load_configuration(self, commit_comment ='pybot_jrouter_load_configuration', path=None, format='set', conf_mode='exclusive', overwrite=False, merge=False, synchronize=True, force_synchronize=False, full=False, print_conf_diff=False, print_conf_detail=False, **kvargs): """ Function that load configuration on a JunOS device **kvargs format:set|text|xml data: data to load in the router """ print ("*INFO* Host %s|load_configuration|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail)) data = kvargs['data'] format = kvargs['format'] if 'force_synchronize' in kvargs.keys(): force_synchronize = kvargs['force_synchronize'] if 'synchronize' in kvargs.keys(): synchronize = kvargs['synchronize'] if 'full' in kvargs.keys(): full = kvargs['full'] if force_synchronize: synchronize = True print ("*INFO* Host %s|load_configuration|Force Synchronized Commit requested" % (self.target)) if synchronize: print ("*INFO* Host %s|load_configuration|Synchronized Commit requested" % (self.target)) if full: print ("*INFO* Host %s|load_configuration|Commit Full requested" % (self.target)) print ("*INFO* Host %s|load_configuration|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite)) if format == 'set' and overwrite: overwrite = False print ("*WARN* Host %s|load_configuration|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target)) loadResp = '' commitResp = False print ("*INFO* Host %s|load_configuration|Initializing variables. path=%s." % (self.target,path)) print ("*INFO* Host %s|load_configuration|Initializing variables. data=%s." % (self.target,data)) try: #Unlock/close configuration is managed by Config context manager with Config(self._conn, mode=conf_mode) as candidate: #begin_load_datetime=datetime.now() if ((data == "") and (path != None)): if overwrite: loadResp=candidate.load(path=path, format=format, overwrite=True, merge=merge) else: loadResp=candidate.load(path=path, format=format, overwrite=False, merge=merge) #finish_load_datetime=datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) else: if overwrite: loadResp=candidate.load(data, format=format, overwrite=True, merge=merge) else: loadResp=candidate.load(data, format=format, overwrite=False, merge=merge) #finish_load_datetime=datetime.now() if loadResp.find("ok") is None: print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp))) return False if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) #begin_commit_datetime=datetime.now() if print_conf_detail: try: #begin_commit_datetime=datetime.now() commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True) #finish_commit_datetime=datetime.now() print ('*INFO* Host %s|load_configuration|Configuration to be committed: %s' % (self.target, etree.tostring(commitResp))) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the commited configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error)) return False else: #begin_commit_datetime=datetime.now() commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False) #finish_commit_datetime=datetime.now() except LockError as lockError: print ("*WARN* Host %s|load_configuration|Problems locking configuration: %s" % (self.target, lockError)) raise FatalError("Host %s|load_configuration|Unable to lock configuration.....exiting: %s" % (self.target, lockError)) except (RpcError,RpcTimeoutError) as rpcError: #warnings severity is already being ignored in the Config context manager print ("*WARN* Host %s|load_configuration|Problems opening configuration: %s" % (self.target, rpcError)) raise FatalError("Host %s|load_configuration|Unable to open configuration.....exiting: %s" % (self.target, rpcError)) except ConfigLoadError as configError: print ("*WARN* Host %s|load_configuration|Problems loading the configuration: %s.....exiting" % (self.target, configError)) if print_conf_diff: try: print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed %s' % (self.target, candidate.diff())) except lxml.etree.XMLSyntaxError as error: print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error)) raise FatalError("Host %s|load_configuration|Unable to load the configuration.....exiting: %s" % (self.target, configError)) except CommitError as commitError: print ("*WARN* Host %s|load_configuration|Problems committing the configuration: %s.....exiting" % (self.target, commitError)) raise FatalError("Host %s|load_configuration|Unable to commit the configuration.....exiting: %s" % (self.target, commitError)) except UnlockError as unlockError: print ("*WARN* Host %s|load_configuration|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError)) raise FatalError("Host %s|load_configuration|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError)) except Exception as error: if 'Opening and ending tag mismatch: routing-engine ' in error: print ('*INFO* Host %s|load_configuration|%s' % (self.target, error)) pass return True else: print ("*WARN* Host %s|load_configuration|An unhandled exception occurred: %s.....exiting" % (self.target, error)) raise FatalError("Host %s|load_configuration|Unhandled Exception occurred.....exiting: %s" % (self.target, error)) print ('*INFO* Host %s|load_configuration|Configuration successfully committed' % (self.target)) #diff_load_time=begin_load_datetime-finish_load_datetime #diff_commit_time=begin_commit_datetime-finish_commit_datetime return True
args, unknown = parser.parse_known_args() device = args.device user = args.user password = args.password command = args.command open_result = None try: dev = Device(host=device, user=user, password=password, gather_facts=False) open_result = dev.open() print("Open connection ... {}".format(open_result.connected)) conf = Config(dev) print("Load config ...") lock_response = conf.lock() print("Locking config ... {}".format(lock_response)) rollback_response = conf.rollback() print("Rollback config ... {}".format(rollback_response)) load_result = conf.load(command, format='set', ignore_warning=['statement not found']) load_result_tostring = etree.tostring(load_result, encoding='unicode', pretty_print=True) print("Load command ... \n{}".format(load_result_tostring))
def verifyandconfigure(yamlp,THIS_DIR,username,password): for load in yamlp: for eqp in load.values(): key = eqp[0]["Address"] print(key) yamload = eqp[1]["Tasks"] for task in yamload: dev = Device(str(key),user =username,passwd = password,port=22) dev.open() for task in yamload: if task["name"] == "l2agg" or task["name"] == "l3agg": data = dev.rpc.get_config(filter_xml='chassis/aggregated-devices') if data.findtext(".//device-count") == None: print("Error: chassis aggregated-devices ethernet device-count should be configured to add aggrgates") exit() elif task["aggnumber"] >= int(data.findtext(".//device-count")): print("Error: Aggregated-devices ethernet device-count configured is %s less than aggnumber in task %s at device %s" %(str(data.findtext(".//device-count")), task["name"] , key)) exit() for interface in task["interfaces"]: xml="<configuration><interfaces><interface><name>"+interface+"</name></interface></interfaces></configuration>" data2 = dev.rpc.get_config(filter_xml=etree.XML(xml)) if data2.findtext(".//interface") != None: print("Error: interface %s in task %s at device %s has current configuration" %(interface,task["name"] , key)) exit() elif task["name"] == "l2agg" or task["name"] == "l3irb" and "QFX" in dev.facts["RE0"]["model"]: data = dev.rpc.get_vlan_information() if "QFX" in dev.facts["RE0"]["model"]: for vlan in task["vlans"]: found = False for vl in data.findall(".//l2ng-l2ald-vlan-instance-group"): if str(vl.find(".//l2ng-l2rtb-vlan-name").text) == vlan["vlname"] and int(vl.find(".//l2ng-l2rtb-vlan-tag").text) == vlan["vlnumber"]: found = True break if found == False: create = False for tas in yamload: if tas["name"] =="createvlans": for v in tas["vlans"]: if v["vlname"] == vlan["vlname"] and v["vlnumber"] == vlan["vlnumber"]: create = True break if create == False: print("Vlan %s in task %s for device %s has to be created"%(vlan,task["name"],key)) exit() elif task["name"] == "aggaddintf": for interface in task["interfaces"]: xml="<configuration><interfaces><interface><name>"+interface+"</name></interface></interfaces></configuration>" data2 = dev.rpc.get_config(filter_xml=etree.XML(xml)) if data2.findtext(".//interface") != None: print("Error: interface %s in task %s at device %s has current configuration" %(interface,task["name"] , key)) exit() elif task["name"] == "aggdelintf": for interface in task["interfaces"]: xml="<configuration><interfaces><interface><name>"+interface+"</name></interface></interfaces></configuration>" data2 = dev.rpc.get_config(filter_xml=etree.XML(xml)) if data2.findtext(".//bundle") != str("ae"+str(task["aggnumber"])): print("Error: Interface %s is not configured under aggregate %s at task %s at device %s"%(interface,task["aggnumber"],task["name"],key)) exit() if "MX" in dev.facts["RE0"]["model"]: TEMPLATE_ENVIRONMENT = Environment(autoescape=False,loader=FileSystemLoader(THIS_DIR),trim_blocks=False) conf = TEMPLATE_ENVIRONMENT.get_template("MX.j2").render(eqp[1]) with Config(dev, mode='private') as cu: cu.load(conf, format='set') cu.pdiff() cu.commit() print("CONF loaded successfully in %s"%key) dev.close() elif "QFX" in dev.facts["RE0"]["model"]: TEMPLATE_ENVIRONMENT = Environment(autoescape=False,loader=FileSystemLoader(THIS_DIR),trim_blocks=False) conf = TEMPLATE_ENVIRONMENT.get_template("QFX.j2").render(eqp[1]) with Config(dev, mode='private') as cu: cu.load(conf, format='set') cu.pdiff() cu.commit() print("CONF loaded successfully in %s"%key) dev.close() else: print("Unsupported Platform")
def install_config(path=None, **kwargs): ''' Installs the given configuration file into the candidate configuration. Commits the changes if the commit checks or throws an error. path (required) Path where the configuration/template file is present. If the file has a ``.conf`` extension, the content is treated as text format. If the file has a ``.xml`` extension, the content is treated as XML format. If the file has a ``.set`` extension, the content is treated as Junos OS ``set`` commands. mode : exclusive The mode in which the configuration is locked. Can be one of ``private``, ``dynamic``, ``batch``, ``exclusive``. dev_timeout : 30 Set NETCONF RPC timeout. Can be used for commands which take a while to execute. overwrite : False Set to ``True`` if you want this file is to completely replace the configuration file. replace : False Specify whether the configuration file uses ``replace:`` statements. If ``True``, only those statements under the ``replace`` tag will be changed. format Determines the format of the contents update : False Compare a complete loaded configuration against the candidate configuration. For each hierarchy level or configuration object that is different in the two configurations, the version in the loaded configuration replaces the version in the candidate configuration. When the configuration is later committed, only system processes that are affected by the changed configuration elements parse the new configuration. This action is supported from PyEZ 2.1. comment Provide a comment for the commit confirm Provide time in minutes for commit confirmation. If this option is specified, the commit will be rolled back in the specified amount of time unless the commit is confirmed. diffs_file Path to the file where the diff (difference in old configuration and the committed configuration) will be stored. Note that the file will be stored on the proxy minion. To push the files to the master use :py:func:`cp.push <salt.modules.cp.push>`. template_vars Variables to be passed into the template processing engine in addition to those present in pillar, the minion configuration, grains, etc. You may reference these variables in your template like so: .. code-block:: jinja {{ template_vars["var_name"] }} CLI Examples: .. code-block:: bash salt 'device_name' junos.install_config 'salt://production/network/routers/config.set' salt 'device_name' junos.install_config 'salt://templates/replace_config.conf' replace=True comment='Committed via SaltStack' salt 'device_name' junos.install_config 'salt://my_new_configuration.conf' dev_timeout=300 diffs_file='/usystem/confs/old_config.conf' overwrite=True salt 'device_name' junos.install_config 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}' ''' conn = __proxy__['junos.conn']() ret = dict() ret['out'] = True if path is None: ret['message'] = \ 'Please provide the salt path where the configuration is present' ret['out'] = False return ret op = dict() if '__pub_arg' in kwargs: if kwargs['__pub_arg']: if isinstance(kwargs['__pub_arg'][-1], dict): op.update(kwargs['__pub_arg'][-1]) else: op.update(kwargs) template_vars = dict() if "template_vars" in op: template_vars = op["template_vars"] template_cached_path = salt.utils.files.mkstemp() __salt__['cp.get_template'](path, template_cached_path, template_vars=template_vars) if not os.path.isfile(template_cached_path): ret['message'] = 'Invalid file path.' ret['out'] = False return ret if os.path.getsize(template_cached_path) == 0: ret['message'] = 'Template failed to render' ret['out'] = False return ret write_diff = '' if 'diffs_file' in op and op['diffs_file'] is not None: write_diff = op['diffs_file'] del op['diffs_file'] op['path'] = template_cached_path if 'format' not in op: if path.endswith('set'): template_format = 'set' elif path.endswith('xml'): template_format = 'xml' else: template_format = 'text' op['format'] = template_format if 'replace' in op and op['replace']: op['merge'] = False del op['replace'] elif 'overwrite' in op and op['overwrite']: op['overwrite'] = True elif 'overwrite' in op and not op['overwrite']: op['merge'] = True del op['overwrite'] db_mode = op.pop('mode', 'exclusive') with Config(conn, mode=db_mode) as cu: try: cu.load(**op) except Exception as exception: ret['message'] = 'Could not load configuration due to : "{0}"'.format( exception) ret['format'] = template_format ret['out'] = False return ret finally: salt.utils.files.safe_rm(template_cached_path) config_diff = cu.diff() if config_diff is None: ret['message'] = 'Configuration already applied!' ret['out'] = True return ret commit_params = {} if 'confirm' in op: commit_params['confirm'] = op['confirm'] if 'comment' in op: commit_params['comment'] = op['comment'] try: check = cu.commit_check() except Exception as exception: ret['message'] = \ 'Commit check threw the following exception: "{0}"'\ .format(exception) ret['out'] = False return ret if check: try: cu.commit(**commit_params) ret['message'] = 'Successfully loaded and committed!' except Exception as exception: ret['message'] = \ 'Commit check successful but commit failed with "{0}"'\ .format(exception) ret['out'] = False return ret else: ret['message'] = 'Loaded configuration but commit check failed.' ret['out'] = False cu.rollback() try: if write_diff and config_diff is not None: with salt.utils.files.fopen(write_diff, 'w') as fp: fp.write(salt.utils.stringutils.to_str(config_diff)) except Exception as exception: ret['message'] = 'Could not write into diffs_file due to: "{0}"'.format( exception) ret['out'] = False return ret
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)
def push_config(conf_string, ip, user, pw): dev = get_device_reference(ip, user, pw) # try to determine the format of our config_string config_format = 'set' if re.search(r'^\s*<.*>$', conf_string, re.MULTILINE): config_format = 'xml' elif re.search(r'^\s*(set|delete|replace|rename)\s', conf_string): config_format = 'set' elif re.search(r'^[a-z:]*\s*\w+\s+{', conf_string, re.I) and re.search( r'.*}\s*$', conf_string): config_format = 'text' logger.debug("using format: " + config_format) 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(conf_string, format=config_format) 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: try: cu.commit_check() logger.debug("Committing config!") cu.commit(comment="Commit via wistar") except CommitError as ce: logger.debug("Could not load config!") cu.rollback() logger.debug(repr(ce)) return False else: # nothing to commit logger.debug("Nothing to commit - no diff found") return True 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_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)
for line in f: vqfx = line.split(" ", 1)[0] if "vqfx" in vqfx and "pfe" not in vqfx: vqfxDict[vqfx] = {} m = re.search('\w*.*ansible_host=(\w*.*?) ', line) host = m.group(1) vqfxDict[vqfx]['host'] = host m = re.search('\w*.*ansible_port=(\w*.*?) ', line) port = m.group(1) vqfxDict[vqfx]['port'] = port print vqfxDict for key, value in vqfxDict.iteritems(): print "\n##### Configuring: " + key + " #####\n" print "host " + value['host'] print "port " + value['port'] dev = Device(host=value['host'], user='******', password='******', port=value['port']) dev.open() pprint(dev.facts) cu = Config(dev) cmd = "set system host-name " + key cu.load(cmd, format='set') cu.commit() dev.close()
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)
from jinja2 import Template from yaml import load from jnpr.junos import Device from jnpr.junos.utils.config import Config f = open('configure_appformix/network_devices.yml', 'r') my_vars = load(f.read()) f.close() f = open('configure_junos/telemetry.j2') my_template = Template(f.read()) f.close() f = open('configure_junos/telemetry.conf', 'w') f.write(my_template.render(my_vars)) f.close() for item in my_vars['jti']['devices']: device = Device(host=item['out_of_band'], user=my_vars['jti']['username'], password=my_vars['jti']['password']) device.open() cfg = Config(device) cfg.load(path='configure_junos/telemetry.conf', format='set') cfg.commit() device.close() print 'configured device ' + item[ 'out_of_band'] + ' with telemetry server ip ' + my_vars['jti'][ 'telemetry_server_ip']
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))
def install_config(path=None, **kwargs): """ Installs the given configuration file into the candidate configuration. Commits the changes if the commit checks or throws an error. path (required) Path where the configuration/template file is present. If the file has a ``.conf`` extension, the content is treated as text format. If the file has a ``.xml`` extension, the content is treated as XML format. If the file has a ``.set`` extension, the content is treated as Junos OS ``set`` commands. mode : exclusive The mode in which the configuration is locked. Can be one of ``private``, ``dynamic``, ``batch``, ``exclusive``. dev_timeout : 30 Set NETCONF RPC timeout. Can be used for commands which take a while to execute. overwrite : False Set to ``True`` if you want this file is to completely replace the configuration file. replace : False Specify whether the configuration file uses ``replace:`` statements. If ``True``, only those statements under the ``replace`` tag will be changed. format Determines the format of the contents update : False Compare a complete loaded configuration against the candidate configuration. For each hierarchy level or configuration object that is different in the two configurations, the version in the loaded configuration replaces the version in the candidate configuration. When the configuration is later committed, only system processes that are affected by the changed configuration elements parse the new configuration. This action is supported from PyEZ 2.1. comment Provide a comment for the commit confirm Provide time in minutes for commit confirmation. If this option is specified, the commit will be rolled back in the specified amount of time unless the commit is confirmed. diffs_file Path to the file where the diff (difference in old configuration and the committed configuration) will be stored. Note that the file will be stored on the proxy minion. To push the files to the master use :py:func:`cp.push <salt.modules.cp.push>`. template_vars Variables to be passed into the template processing engine in addition to those present in pillar, the minion configuration, grains, etc. You may reference these variables in your template like so: .. code-block:: jinja {{ template_vars["var_name"] }} CLI Examples: .. code-block:: bash salt 'device_name' junos.install_config 'salt://production/network/routers/config.set' salt 'device_name' junos.install_config 'salt://templates/replace_config.conf' replace=True comment='Committed via SaltStack' salt 'device_name' junos.install_config 'salt://my_new_configuration.conf' dev_timeout=300 diffs_file='/salt/confs/old_config.conf' overwrite=True salt 'device_name' junos.install_config 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}' """ conn = __proxy__["junos.conn"]() ret = {} ret["out"] = True if path is None: ret["message"] = "Please provide the salt path where the configuration is present" ret["out"] = False return ret op = {} if "__pub_arg" in kwargs: if kwargs["__pub_arg"]: if isinstance(kwargs["__pub_arg"][-1], dict): op.update(kwargs["__pub_arg"][-1]) else: op.update(kwargs) test = op.pop("test", False) template_vars = {} if "template_vars" in op: template_vars = op["template_vars"] try: template_cached_path = salt.utils.files.mkstemp() __salt__["cp.get_template"](path, template_cached_path, template_vars=template_vars) except Exception as ex: # pylint: disable=broad-except ret["message"] = ( "Salt failed to render the template, please check file path and syntax." "\nError: {0}".format(str(ex))) ret["out"] = False return ret if not os.path.isfile(template_cached_path): ret["message"] = "Invalid file path." ret["out"] = False return ret if os.path.getsize(template_cached_path) == 0: ret["message"] = "Template failed to render" ret["out"] = False return ret write_diff = "" if "diffs_file" in op and op["diffs_file"] is not None: write_diff = op["diffs_file"] del op["diffs_file"] op["path"] = template_cached_path if "format" not in op: if path.endswith("set"): template_format = "set" elif path.endswith("xml"): template_format = "xml" else: template_format = "text" op["format"] = template_format if "replace" in op and op["replace"]: op["merge"] = False del op["replace"] elif "overwrite" in op and op["overwrite"]: op["overwrite"] = True elif "overwrite" in op and not op["overwrite"]: op["merge"] = True del op["overwrite"] db_mode = op.pop("mode", "exclusive") if write_diff and db_mode == "dynamic": ret["message"] = "Write diff is not supported with dynamic configuration mode" ret["out"] = False return ret try: with Config(conn, mode=db_mode) as cu: try: cu.load(**op) except Exception as exception: # pylint: disable=broad-except ret["message"] = 'Could not load configuration due to : "{0}"'.format( exception) ret["format"] = op["format"] ret["out"] = False return ret finally: salt.utils.files.safe_rm(template_cached_path) if db_mode != "dynamic": config_diff = cu.diff() if config_diff is None: ret["message"] = "Configuration already applied!" ret["out"] = True return ret commit_params = {} if "confirm" in op: commit_params["confirm"] = op["confirm"] if "comment" in op: commit_params["comment"] = op["comment"] # Assume commit_check succeeds and initialize variable check check = True if db_mode != "dynamic": try: check = cu.commit_check() except Exception as exception: # pylint: disable=broad-except ret["message"] = 'Commit check threw the following exception: "{0}"'.format( exception) ret["out"] = False return ret if check and not test: try: cu.commit(**commit_params) ret["message"] = "Successfully loaded and committed!" except Exception as exception: # pylint: disable=broad-except ret["message"] = 'Commit check successful but commit failed with "{0}"'.format( exception) ret["out"] = False return ret elif not check: cu.rollback() ret["message"] = "Loaded configuration but commit check failed, hence rolling back configuration." ret["out"] = False else: cu.rollback() ret["message"] = "Commit check passed, but skipping commit for dry-run and rolling back configuration." ret["out"] = True try: if write_diff and config_diff is not None: with salt.utils.files.fopen(write_diff, "w") as fp: fp.write(salt.utils.stringutils.to_str(config_diff)) except Exception as exception: # pylint: disable=broad-except ret["message"] = 'Could not write into diffs_file due to: "{0}"'.format( exception) ret["out"] = False except ValueError: ret["message"] = "Invalid mode. Modes supported: private, dynamic, batch, exclusive" ret["out"] = False except LockError as ex: log.error("Configuration database is locked") ret["message"] = ex.message ret["out"] = False return ret
def get_vlan_vni(message, **kwargs): # Get previous values temp = re.search(r'set vlans v(\d+) vxlan vni (\d+)', message) vni_num = int(temp.group(2)) vlan_num = int(temp.group(1)) print(kwargs, file=sys.stderr) r = requests.get('http://config-server:9000/api/v2/device-group/%s/' % kwargs['device_group'], verify=False) #print(r.status_code, file=sys.stderr) if r.status_code != 200: return False device_group_info = r.json() devices_list = device_group_info['devices'] d = requests.get('http://config-server:9000/api/v2/device/%s/' % kwargs['device_id'], verify=False) if d.status_code != 200: return False device_info = d.json() device_name = device_info['device-id'] for dev in devices_list: if dev != device_name: rd = requests.get('http://config-server:9000/api/v2/device/%s/' % dev, verify=False) if r.status_code != 200: return False devices_info = rd.json() hostname = devices_info['host'] userid = devices_info['authentication']['password']['username'] password = devices_info['authentication']['password']['password'] dev = Device(host=hostname, user=userid, password=password, normalize=True) dev.open() sw = dev.cli("show vlans v%s" % vlan_num, warning=False) try: tmp = re.search(r'default-switch\s+v(\d*)\s+', sw) vlan = int(tmp.group(1)) except: vlan = None print(vlan) if (vlan is vlan_num): print("VNI configuration exists") else: cu = Config(dev) config = """ set vlans v{0} vlan-id {0} set vlans v{0} vxlan vni {1} set vlans v{0} l3-interface irb.{0} set vlans v{0} description "Tenant_1 - brdige domain id {0}" set protocols evpn extended-vni-list {1} set policy-options policy-statement OVERLAY-IMPORT term vni-Tenant_1-v{0} from community com-vni-Tenant_1-v{0} set policy-options policy-statement OVERLAY-IMPORT term vni-Tenant_1-v{0} then accept set policy-options community com-vni-Tenant_1-v{0} members target:1:{0} set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} then community add com-vni-Tenant_1-v{0} set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} then accept set policy-options policy-statement TENANT_1-EXPORT term vni-Tenant_1-v{0} from interface irb.{0} set policy-options policy-statement TENANT_1-IMPORT term vni-Tenant_1-v{0} from community com-vni-Tenant_1-v{0} set policy-options policy-statement TENANT_1-IMPORT term vni-Tenant_1-v{0} then accept """.format(vlan_num, vni_num) cu.load(config, format='set') if cu.commit_check(): res = cu.commit() print("Added config") else: print("commit check failed") return False else: print("Local device") return True
def send_config_from_file(self, path): with open(path) as f: with Config(self.pyez_connection) as cu: cu.load(f.read(), format='set') cu.commit()
import os import sys import jnpr.junos from jnpr.junos import Device from jnpr.junos.utils.config import Config import yaml host = raw_input('Enter Hostname or IP address of Device: ') r0 = Device(host=Host, user='******', password='******').open() data = yaml.load(open('protocol_data.yml')) r0.cu = Config(r0) r0cu.load(template_path='protocol_temp.j2', template_vars=data, format='text') r0.cu.pdiff() if r0.cu.commit_check(): cu.commit() else: cu.rollback() r0.close()
#----------------------------------------------------------------------------------------------------------------------- # 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()
# CONTACT: [email protected]; [email protected]; [email protected]; [email protected]; [email protected] # # CREATED: 2015-11-11 # # VERSION: 1 # # USAGE: enable_lldp_all_devices.py # ----------------------------------------------------------------------------------------------------------------------- from jnpr.junos import Device # import the class Device from jnpr.junos.utils.config import Config # import the class Config import yaml interface_file_contents = open( 'configuration_management/interfaces.yml').read() interface_variables = yaml.load(interface_file_contents) device_file_contents = open('configuration_management/device_list.yml').read() device_list = yaml.load(device_file_contents) for device in device_list: print device dev = Device(host=device, user="******", password="******") dev.open() cfg = Config(dev) # cfg is the candidate configuration cfg.rollback() cfg.load(template_path='configuration_management/template_lldp.j2', template_vars=interface_variables, format='set') cfg.pdiff() cfg.commit()