def commit(self, confirmed=False, check=False, timeout=None, comment=None, synchronize=False, at_time=None): """Commit the candidate configuration as the device's new current configuration. Depends on the `:candidate` capability. A confirmed commit (i.e. if *confirmed* is `True`) is reverted if there is no followup commit within the *timeout* interval. If no timeout is specified the confirm timeout defaults to 600 seconds (10 minutes). A confirming commit may have the *confirmed* parameter but this is not required. Depends on the `:confirmed-commit` capability. :confirmed: whether this is a confirmed commit :timeout: specifies the confirm timeout in seconds """ obj = new_ele('commit-configuration') if confirmed: sub_ele(obj, 'confirmed') if check: sub_ele(obj, 'check') if synchronize: sub_ele(obj, 'synchronize') if at_time: subele = sub_ele(obj, 'at-time') subele.text = str(at_time) if comment: subele = sub_ele(obj, 'log') subele.text = str(comment) if timeout: subele = sub_ele(obj, 'confirm-timeout') subele.text = str(timeout) return self.rpc(obj)
def _create_rpc_request(self, rpc_name, **params): """ This function is devoted to create a raw RPC request message in XML format. Any further additional rpc-input can be passed towards, if netconf agent has this input list, called 'options'. Switches is used for connectVNF rpc in order to set the switches where the vnf should be connected. :param rpc_name: rpc name :type rpc_name: str :param options: additional RPC input in the specific <options> tag :type options: dict :param switches: set the switches where the vnf should be connected :type switches: list :param params: input params for the RPC using param's name as XML tag name :type params: dict :return: raw RPC message in XML format (lxml library) :rtype: :class:`lxml.etree.ElementTree` """ # create the desired xml element xsd_fetch = new_ele(rpc_name) # set the namespace of your rpc xsd_fetch.set('xmlns', self.RPC_NAMESPACE) # set input params self.__parse_rpc_params(xsd_fetch, params) # we need to remove the confusing netconf namespaces with our own function rpc_request = self.__remove_namespace(xsd_fetch, self.NETCONF_NAMESPACE) # show how the created rpc message looks like if self.debug: print "Generated raw RPC message:\n", etree.tostring( rpc_request, pretty_print=True) return rpc_request
def device_get(self, filters={}): dev_conf = { 'product-name': '', 'product-model': '', 'software-version': '' } try: self.device_connect() sw_info = new_ele('get-software-information') res = self._nc_manager.rpc(sw_info) dev_conf['product-name'] = self.get_xpath_data( res, '//software-information/product-name') dev_conf['product-model'] = self.get_xpath_data( res, '//software-information/product-model') dev_conf['software-version'] = self.get_xpath_data( res, '//software-information/junos-version') if not dev_conf.get('software-version'): ele = self.get_xpath_data( res, "//software-information/package-information[name='junos-version']", True) if ele: dev_conf['software-version'] = ele.find('comment').text except Exception as e: if self._logger: self._logger.error( "could not fetch config from router %s: %s" % (self.management_ip, e.message)) return dev_conf
def connect(host, user, password): conn = manager.connect(host=host, username=user, password=password, timeout=10, hostkey_verify=False) conn.lock() root = new_ele('config') configuration = sub_ele(root, 'configuration') system = sub_ele(configuration, 'system') location = sub_ele(system, 'location') sub_ele(location, 'building').text = "Main Campus, A" sub_ele(location, 'floor').text = "5" sub_ele(location, 'rack').text = "27" send_config = conn.edit_config(config=root) print send_config.tostring check_config = conn.validate() print check_config.tostring compare_config = conn.compare_configuration() print compare_config.tostring conn.commit() conn.unlock() conn.close_session()
def invoke(self, mc, ns, expr): pfxmap = nsmap(ns) config = new_ele("config", nsmap=pfxmap) (target, rest) = XpathParser(expr, pfxmap).build_tree_on(config) self.modify_target(ns, target, rest) reply = mc.edit_config(config, test_option=ns.test, target=ns.db) return reply._root[0]
def map_obj_to_ele(want): element = new_ele('system') login = sub_ele(element, 'login', {'replace': 'replace'}) for item in want: if item['state'] != 'present': operation = 'delete' else: operation = 'replace' user = sub_ele(login, 'user', {'operation': operation}) sub_ele(user, 'name').text = item['name'] if operation == 'replace': sub_ele(user, 'class').text = item['role'] if item.get('full_name'): sub_ele(user, 'full-name').text = item['full_name'] if item.get('sshkey'): auth = sub_ele(user, 'authentication') ssh_rsa = sub_ele(auth, 'ssh-rsa') key = sub_ele(ssh_rsa, 'name').text = item['sshkey'] return element
def invoke(self, mc, *ignored): caps = list(mc.server_capabilities) hello = new_ele("hello") xcaps = sub_ele(hello, "capabilities") for cap in caps: sub_ele(xcaps, "capability").text = cap return hello
def connect(host, port, user, password): conn = manager.connect(host=host, port=port, username=user, password=password, timeout=60, device_params={'name': 'junos'}, hostkey_verify=False) conn.lock() root = new_ele('config') configuration = sub_ele(root, 'configuration') system = sub_ele(configuration, 'system') location = sub_ele(system, 'location') sub_ele(location, 'building').text = "Main Campus, A" sub_ele(location, 'floor').text = "5" sub_ele(location, 'rack').text = "27" #print(to_xml(root, pretty_print=True)) edit_config_result = conn.edit_config(config=root) logging.info(edit_config_result) validate_result = conn.validate() logging.info(validate_result) compare_config_result = conn.compare_configuration() logging.info(compare_config_result) conn.commit() conn.unlock() conn.close_session()
def test_iosxe_transform_edit_config(self): node = new_ele("edit-config") node.append( validated_element(CFG_BROKEN, ("config", qualify("config")))) node = self.obj.transform_edit_config(node) config_nodes = node.findall('./config') self.assertTrue(len(config_nodes) == 0)
def get_device_config(self): try: with manager.connect(host=self.management_ip, port=22, username=self.user_creds['username'], password=self.user_creds['password'], timeout=10, device_params={'name': 'junos'}, unknown_host_cb=lambda x, y: True) as m: sw_info = new_ele('get-software-information') res = m.rpc(sw_info) pname = res.xpath( '//software-information/product-name')[0].text pmodel = res.xpath( '//software-information/product-model')[0].text ele = res.xpath("//software-information/package-information" "[name='junos-version']")[0] jversion = ele.find('comment').text dev_conf = {} dev_conf['product-name'] = pname dev_conf['product-model'] = pmodel dev_conf['software-version'] = jversion return dev_conf except Exception as e: if self._logger: self._logger.error( "could not fetch config from router %s: %s" % (self.management_ip, e.message)) return {}
def interface_update(self, name, unit, attributes=None, vlan_members=None): content = to_ele(""" <interface> <name>{interface}</name> <unit> <name>{unit}</name> <family> <ethernet-switching> </ethernet-switching> </family> </unit> </interface> """.format(interface=name, unit=unit)) ethernet_switching_node = first(content.xpath("//ethernet-switching")) for attribute in (attributes if attributes is not None else []): ethernet_switching_node.append(attribute) if vlan_members: vlan = new_ele("vlan") for attribute in vlan_members: vlan.append(attribute) ethernet_switching_node.append(vlan) return content
def device_get(self, filters = {}): dev_conf = { 'product-name' : '', 'product-model': '', 'software-version': '' } try: self.device_connect() sw_info = new_ele('get-software-information') res = self._nc_manager.rpc(sw_info) dev_conf['product-name'] = self.get_xpath_data(res, '//software-information/product-name') dev_conf['product-model'] = self.get_xpath_data(res, '//software-information/product-model') dev_conf['software-version'] = self.get_xpath_data(res, '//software-information/junos-version') if not dev_conf.get('software-version'): ele = self.get_xpath_data(res, "//software-information/package-information[name='junos-version']", True) if ele: dev_conf['software-version'] = ele.find('comment').text except Exception as e: if self._logger: self._logger.error("could not fetch config from router %s: %s" % ( self.management_ip, e.message)) return dev_conf
def main(): """Test code that is testing NETCONF.""" conn = manager.connect( host="srx2.lasthop.io", username="******", password=getpass(), device_params={"name": "junos"}, hostkey_verify=False, allow_agent=False, look_for_keys=False, port=830, timeout=60, ) ipdb.set_trace() rpc = new_ele("get-software-information") nc_out = conn.rpc(rpc) # It is an XML like thing print(nc_out.tostring.decode()) print(nc_out.find(".//product-name")) print(nc_out.find(".//product-name").text) print(nc_out.find(".//product-model").text) config = conn.get_config(source="running") config_xml = config.data_xml print(config_xml)
def connect(host, port, user, password): conn = manager.connect(host=host, port=port, username=user, password=password, timeout=60, device_params={'name': 'junos'}, hostkey_verify=False) conn.lock() root = new_ele('config') configuration = sub_ele(root, 'configuration') system = sub_ele(configuration, 'system') location = sub_ele(system, 'location') sub_ele(location, 'building').text = "Main Campus, A" sub_ele(location, 'floor').text = "5" sub_ele(location, 'rack').text = "27" edit_config_result = conn.edit_config(config=root) logging.info(edit_config_result) validate_result = conn.validate() logging.info(validate_result) compare_config_result = conn.compare_configuration() logging.info(compare_config_result) conn.commit() conn.unlock() conn.close_session()
def commit(self, confirmed=False, check=False, timeout=None, comment=None, synchronize=False, at_time=None): """ Commit the candidate configuration as the device's new current configuration. Depends on the `:candidate` capability. A confirmed commit (i.e. if *confirmed* is `True`) is reverted if there is no followup commit within the *timeout* interval. If no timeout is specified the confirm timeout defaults to 600 seconds (10 minutes). A confirming commit may have the *confirmed* parameter but this is not required. Depends on the `:confirmed-commit` capability. :param confirmed: whether this is a confirmed commit :param check: Check correctness of syntax :param timeout: specifies the confirm timeout in seconds :param comment: Message to write to commit log :param synchronize: Synchronize commit on remote peers :param at_time: Time at which to activate configuration changes :return: Received rpc response from remote host """ obj = new_ele('commit-configuration') if confirmed: sub_ele(obj, 'confirmed') if check: sub_ele(obj, 'check') if synchronize: sub_ele(obj, 'synchronize') if at_time: subele = sub_ele(obj, 'at-time') subele.text = str(at_time) if comment: subele = sub_ele(obj, 'log') subele.text = str(comment) if timeout: subele = sub_ele(obj, 'confirm-timeout') subele.text = str(timeout) return self.rpc(obj)
def interface_update(name, unit, attributes=None, vlan_members=None): content = to_ele(""" <interface> <name>{}</name> <unit> <name>{}</name> <family> <ethernet-switching> </ethernet-switching> </family> </unit> </interface> """.format(name, unit)) ethernet_switching_node = first(content.xpath("//ethernet-switching")) for attribute in (attributes if attributes is not None else []): ethernet_switching_node.append(attribute) if vlan_members: vlan = new_ele("vlan") for attribute in vlan_members: vlan.append(attribute) ethernet_switching_node.append(vlan) return content
def invoke(self, mc, ns, filename="-"): data = etree.parse(sys.stdin if filename == "-" else open(filename, "r")) config = new_ele("config") config.append(data.getroot()) reply = mc.edit_config(config, test_option=ns.test, target=ns.db) return reply._root[0]
def conn(username, passwd, port): for router, n in zip(routers, range(1, 5)): with manager.connect(host=router, username=username, password=passwd, port=port, timeout=10, device_params={'name': 'junos'}, hostkey_verify=False) as dev: if dev: print(f'{router} - connected.') #configure hostname hostname = new_ele('system') sub_ele(hostname, 'host-name').text = f'router{n}' #lock config dev.lock() #load hostname configuration dev.load_configuration(config=hostname) #validate configuration dev.validate() #commit confirm configuration dev.commit(confirmed=True, timeout='300') #unlock configuration dev.unlock()
def invoke(self, mc, ns, filename="-"): data = etree.parse(sys.stdin if filename == "-" else open(filename, "r")) copy = new_ele("copy-config") sub_ele(sub_ele(copy, "target"), ns.db) sub_ele(sub_ele(copy, "source"), "config").append(data.getroot()) reply = mc.rpc(copy) return reply._root[0]
def query(self, *args): filter_node = new_ele("filter") conf = sub_ele(filter_node, "configuration") for arg in args: conf.append(arg()) return self.netconf.get_config( source="candidate" if self.in_transaction else "running", filter=filter_node)
def _wrap(self, subele): # internal use ele = new_ele("rpc", {"message-id": self._id}, **self._device_handler.get_xml_extra_prefix_kwargs()) # ele.append(subele) _append(ele, subele) #print to_xml(ele) return to_xml(ele)
def get_configuration(module, compare=False, format='xml', rollback='0'): if format not in CONFIG_FORMATS: module.fail_json(msg='invalid config format specified') xattrs = {'format': format} if compare: validate_rollback_id(rollback) xattrs['compare'] = 'rollback' xattrs['rollback'] = str(rollback) return send_request(module, new_ele('get-configuration', xattrs))
def request(self, source): """Validate the contents of the specified configuration. *source* is the name of the configuration datastore being validated or `config` element containing the configuration subtree to be validated :seealso: :ref:`srctarget_params` """ node = new_ele("validate") if type(source) is str: src = util.datastore_or_url("source", source, self._assert) else: validated_element(source, ("config", qualify("config"))) src = new_ele("source") src.append(source) node.append(src) return self._request(node)
def ifaces(self): ''' Parses and returns the output of show interfaces terse. ''' node = new_ele('command', {'format': 'xml'}) node.text = 'show interface terse' query = self._conn.rpc(node) ret = [i.text.replace('\n', '') for i in query.xpath('//name')] return ret
def main(): """main entry point for Ansible module """ argument_spec = dict( rpc=dict(required=True), args=dict(type='dict'), output=dict(default='xml', choices=['xml', 'json', 'text']), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) result = {'changed': False} rpc = str(module.params['rpc']).replace('_', '-') if all((module.check_mode, not rpc.startswith('get'))): module.fail_json(msg='invalid rpc for running in check_mode') args = module.params['args'] or {} xattrs = {'format': module.params['output']} element = new_ele(module.params['rpc'], xattrs) for key, value in iteritems(args): key = str(key).replace('_', '-') if isinstance(value, list): for item in value: child = sub_ele(element, key) if item is not True: child.text = item else: child = sub_ele(element, key) if value is not True: child.text = value reply = send_request(module, element) result['xml'] = str(to_xml(reply)) if module.params['output'] == 'text': reply = to_ele(reply) data = reply.xpath('//output') result['output'] = data[0].text.strip() result['output_lines'] = result['output'].split('\n') elif module.params['output'] == 'json': reply = to_ele(reply) data = reply.xpath('//rpc-reply') result['output'] = module.from_json(data[0].text.strip()) else: result['output'] = str(to_xml(reply)).split('\n') module.exit_json(**result)
def _push(self, configuration): config = new_ele('config') config.append(configuration.root) self.logger.info("Sending edit : {}".format(to_xml(config))) try: self.netconf.edit_config(target="candidate", config=config) except RPCError as e: self.logger.info("An RPCError was raised : {}".format(e)) raise
def get_resource_config(connection, config_filter=None, attrib=None): if attrib is None: attrib = {"inherit": "inherit"} get_ele = new_ele("get-configuration", attrib) if config_filter: get_ele.append(to_ele(config_filter)) return connection.execute_rpc(tostring(get_ele))
def get_device_info(self): device_info = dict() device_info['network_os'] = 'junos' ele = new_ele('get-software-information') data = self.execute_rpc(to_xml(ele)) reply = to_ele(data) sw_info = reply.find('.//software-information') device_info['network_os_version'] = self.get_text(sw_info, 'junos-version') device_info['network_os_hostname'] = self.get_text(sw_info, 'host-name') device_info['network_os_model'] = self.get_text(sw_info, 'product-model') return device_info
def get_device_info(self): device_info = dict() device_info['network_os'] = 'ce' ele = new_ele('get-software-information') data = self.execute_rpc(to_xml(ele)) reply = to_ele(to_bytes(data, errors='surrogate_or_strict')) sw_info = reply.find('.//software-information') device_info['network_os_version'] = self.get_text(sw_info, 'ce-version') device_info['network_os_hostname'] = self.get_text(sw_info, 'host-name') device_info['network_os_model'] = self.get_text(sw_info, 'product-model') return device_info
def serial(self): ''' Returns the chassis serial number. ''' xpath = 'chassis-inventory/chassis/serial-number[1]' nc_query = self._conn.rpc( new_ele('get-chassis-inventory') ) query = self._query( cache_attr='inventory', xpath=xpath, nc_query=nc_query ) return query
class NetconfMethods (netconf_server.NetconfMethods): #build the config nc_config = new_ele('config') configuration = sub_ele(nc_config, 'configuration') system = sub_ele(configuration, 'system') location = sub_ele(system, 'location') sub_ele(location, 'building').text = "Main Campus, A" sub_ele(location, 'floor').text = "5" sub_ele(location, 'rack').text = "27" #<netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"> #<schemas/> #</netconf-state> @classmethod def rpc_get (cls, unused_session, rpc, *unused_params): #return etree.Element("ok") #return cls.nc_config root = etree.Element('data') child1 = etree.SubElement(root, 'device', xmlns="http://ipv6lab.beuth-hochschule.de/led") #for element in elementCollections: #listOfElements = ['1', '2', '3'] #for ele in listOfElements: #set for ele in uuid_set: child2 = etree.SubElement(child1, "device-id") child3 = etree.SubElement(child2, "uuid") child3.text = ele child4 = etree.SubElement(child1, "device-category") child4.text = device_category #newtree = etree.tostring(root, encoding='utf-8') #newtree = newtree.decode("utf-8") #print newtree return root def rpc_hubble (self, unused_session, rpc, *unused_params): return etree.Element("okidoki") def rpc_get_schema(self, unused_session, rpc, *unused_params): root = etree.Element("data", xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring") root.text = etree.CDATA(yangModel) print (command_dict) return root
def model(self): ''' Returns the chassis description. ''' xpath = 'chassis-inventory/chassis/description[1]' nc_query = self._conn.rpc( new_ele('get-chassis-inventory') ) query = self._query( cache_attr='inventory', xpath=xpath, nc_query=nc_query ) return query
def commit_configuration(module, confirm=False, check=False, comment=None, confirm_timeout=None): obj = new_ele('commit-configuration') if confirm: sub_ele(obj, 'confirmed') if check: sub_ele(obj, 'check') if comment: children(obj, ('log', str(comment))) if confirm_timeout: children(obj, ('confirm-timeout', int(confirm_timeout))) return send_request(module, obj)
def get_device_info(self): device_info = dict() device_info["network_os"] = "junos" ele = new_ele("get-software-information") data = self.execute_rpc(to_xml(ele)) reply = to_ele(data) sw_info = reply.find(".//software-information") device_info["network_os_version"] = self.get_text( sw_info, "junos-version") device_info["network_os_hostname"] = self.get_text( sw_info, "host-name") device_info["network_os_model"] = self.get_text( sw_info, "product-model") return device_info
def test_get_config(self): print ' ' print '********* ' + sys._getframe().f_code.co_name + ' *********' nc = NetconfClient(self.host, self.port, self.username, self.password) config = nc.get_config() self.assertTrue(config != None, 'Configuration must be set.') print 'Configuration obtained:\n'\ + etree.tostring(config, pretty_print=True, encoding=unicode) self.assertNotEquals(None, config) config_filter = new_ele('configuration') system_ele = sub_ele(config_filter, 'system') sub_ele(system_ele, 'license') config = nc.get_config(config_filter) self.assertTrue(config != None, 'Filtered configuration must be set.') print 'Filtered configuration obtained:\n'\ + etree.tostring(config, pretty_print=True, encoding=unicode)
def run(self, tmp=None, task_vars=None): if self._play_context.connection != 'local': return dict( fail=True, msg='invalid connection specified, expected connection=local, ' 'got %s' % self._play_context.connection) provider = self.load_provider() pc = copy.deepcopy(self._play_context) pc.network_os = 'junos' if self._task.action in ('junos_command', 'junos_netconf', 'junos_config', '_junos_template'): pc.connection = 'network_cli' pc.port = provider['port'] or self._play_context.port or 22 else: pc.connection = 'netconf' pc.port = provider['port'] or self._play_context.port or 830 pc.remote_user = provider[ 'username'] or self._play_context.connection_user pc.password = provider['password'] or self._play_context.password pc.private_key_file = provider[ 'ssh_keyfile'] or self._play_context.private_key_file socket_path = self._get_socket_path(pc) if not os.path.exists(socket_path): # start the connection if it isn't started connection = self._shared_loader_obj.connection_loader.get( 'persistent', pc, sys.stdin) if pc.connection == 'network_cli': rc, out, err = connection.exec_command('show version') display.vvv('%s %s %s' % (rc, out, err)) if pc.connection == 'netconf': # <get-software-information /> req = new_ele('get-software-information') connection.exec_command(to_xml(req)) task_vars['ansible_socket'] = socket_path return super(ActionModule, self).run(tmp, task_vars)
def load_configuration(module, candidate=None, action='merge', rollback=None, format='xml'): if all((candidate is None, rollback is None)): module.fail_json(msg='one of candidate or rollback must be specified') elif all((candidate is not None, rollback is not None)): module.fail_json(msg='candidate and rollback are mutually exclusive') if format not in FORMATS: module.fail_json(msg='invalid format specified') if format == 'json' and action not in JSON_ACTIONS: module.fail_json(msg='invalid action for format json') elif format in ('text', 'xml') and action not in ACTIONS: module.fail_json(msg='invalid action format %s' % format) if action == 'set' and not format == 'text': module.fail_json(msg='format must be text when action is set') if rollback is not None: validate_rollback_id(rollback) xattrs = {'rollback': str(rollback)} else: xattrs = {'action': action, 'format': format} obj = new_ele('load-configuration', xattrs) if candidate is not None: lookup = { 'xml': 'configuration', 'text': 'configuration-text', 'set': 'configuration-set', 'json': 'configuration-json' } if action == 'set': cfg = sub_ele(obj, 'configuration-set') cfg.text = '\n'.join(candidate) else: cfg = sub_ele(obj, lookup[format]) cfg.append(candidate) return send_request(module, obj)
def all_vlans(): return new_ele("vlans")
def __interfaces_filter(): config_filter = new_ele('configuration') sub_ele(config_filter, 'interfaces') return config_filter
def query(self, *args): filter_node = new_ele("filter") conf = sub_ele(filter_node, "configuration") for arg in args: conf.append(arg()) return self.netconf.get_config(source="candidate" if self.in_transaction else "running", filter=filter_node)
def __security_ipsec_filter(): config_filter = new_ele('configuration') sec = sub_ele(config_filter, 'security') sub_ele(sec, 'ipsec') return config_filter
def all_interfaces(): return new_ele("interfaces")
def __security_policies_filter(): config_filter = new_ele('configuration') sec = sub_ele(config_filter, 'security') sub_ele(sec, 'policies') return config_filter
def __init__(self): self.root = new_ele("configuration") self.vlans_root = None self.interfaces_root = None self.protocols_root = None self.sub_protocol_roots = {}