def unset_interface_auto_negotiation_state(self, interface_id): config = self.query(one_interface(interface_id)) interface_node = self.get_interface_config(interface_id, config) if interface_node is None: self._get_physical_interface(interface_id) return auto_negotiation_present = first(interface_node.xpath('ether-options/auto-negotiation')) is not None no_auto_negotiation_present = first(interface_node.xpath('ether-options/no-auto-negotiation')) is not None if auto_negotiation_present or no_auto_negotiation_present: content = to_ele(""" <interface> <name>{0}</name> </interface> """.format(interface_id)) ether_options = to_ele("<ether-options/>") if auto_negotiation_present: ether_options.append(to_ele("<auto-negotiation operation=\"delete\"/>")) elif no_auto_negotiation_present: ether_options.append(to_ele("<no-auto-negotiation operation=\"delete\"/>")) update = Update() content.append(ether_options) update.add_interface(content) self._push_interface_update(interface_id, update)
def set_access_vlan(self, interface_id, vlan): update_attributes = [] update_vlan_members = [] config = self.query(all_interfaces, all_vlans) self.get_vlan_config(vlan, config) interface_node = self.get_interface_config(interface_id, config) interface = self.node_to_interface(interface_node, config) if interface.port_mode == TRUNK: raise InterfaceInWrongPortMode("trunk") elif self.get_port_mode(interface_node) is None: update_attributes.append(self.custom_strategies.set_interface_port_mode_update_element("access")) if interface.access_vlan != vlan: for members in interface_node.xpath("unit/family/ethernet-switching/vlan/members"): update_vlan_members.append(to_ele('<members operation="delete">{}</members>'.format(members.text))) update_vlan_members.append(to_ele("<members>{}</members>".format(vlan))) if update_attributes or update_vlan_members: update = Update() update.add_interface(interface_update(interface_id, "0", update_attributes, update_vlan_members)) try: self._push(update) except RPCError as e: if "No vlan matches vlan tag" in e.message: raise UnknownVlan(vlan) raise
def add_enslave_to_bond_operations(self, update, interface, bond): ether_options = [ to_ele("<auto-negotiation/>"), to_ele(""" <ieee-802.3ad> <bundle>{0}</bundle> </ieee-802.3ad> """.format(bond.interface.name))] update.add_interface(interface_replace(interface, *ether_options))
def vlan_update(number, description): content = to_ele(""" <vlan> <name>VLAN{0}</name> <vlan-id>{0}</vlan-id> </vlan> """.format(number)) if description is not None: content.append(to_ele("<description>{}</description>".format(description))) return content
def set_interface_auto_negotiation_state(self, interface_id, negotiation_state): content = to_ele(""" <interface> <name>{0}</name> </interface> """.format(interface_id)) if negotiation_state == ON: content.append(to_ele("<ether-options><auto-negotiation></ether-options>")) else: content.append(to_ele("<ether-options><no-auto-negotiation></ether-options>")) update = Update() update.add_interface(content) self._push_interface_update(interface_id, update)
def exec_command(self, request): """Sends the request to the node and returns the reply The method accepts two forms of request. The first form is as a byte string that represents xml string be send over netconf session. The second form is a json-rpc (2.0) byte string. """ try: obj = json.loads(to_text(request, errors='surrogate_or_strict')) if 'jsonrpc' in obj: if self._netconf: out = self._exec_rpc(obj) else: out = self.internal_error("netconf plugin is not supported for network_os %s" % self._play_context.network_os) return 0, to_bytes(out, errors='surrogate_or_strict'), b'' else: err = self.invalid_request(obj) return 1, b'', to_bytes(err, errors='surrogate_or_strict') except (ValueError, TypeError): # to_ele operates on native strings request = to_native(request, errors='surrogate_or_strict') req = to_ele(request) if req is None: return 1, b'', b'unable to parse request' try: reply = self._manager.rpc(req) except RPCError as exc: return 1, b'', to_bytes(to_xml(exc.xml), errors='surrogate_or_strict') return 0, to_bytes(reply.data_xml, errors='surrogate_or_strict'), b''
def rpc(self, cmd): """ Write the XML cmd and return the response as XML object. :cmd: <str> of the XML command. if the :cmd: is not XML, then this routine will perform the brackets; i.e. if given 'get-software-information', this routine will turn it into '<get-software-information/>' NOTES: The return XML object is the first child element after the <rpc-reply>. There is also no error-checking performing by this routine. """ if not cmd.startswith('<'): cmd = '<{0}/>'.format(cmd) rpc = six.b('<rpc>{0}</rpc>'.format(cmd)) logger.info('Calling rpc: %s' % rpc) self._tty.rawwrite(rpc) rsp = self._receive() rsp = rsp.decode('utf-8') if isinstance(rsp, bytes) else rsp reply = RPCReply(rsp) errors = reply.errors if len(errors) > 1: raise RPCError(to_ele(reply._raw), errs=errors) elif len(errors) == 1: raise reply.error return rsp
def interface_state_update(name, state): interface_state = """<disable />""" if state is OFF else """<disable operation="delete" />""" return to_ele(""" <interface> <name>{}</name> {} </interface>""".format(name, interface_state))
def configure_native_vlan(self, interface_id, vlan): update_attributes = [] config = self.query(all_interfaces, all_vlans) self.get_vlan_config(vlan, config) interface_node = self.get_interface_config(interface_id, config) interface = self.node_to_interface(interface_node, config) actual_port_mode = self.get_port_mode(interface_node) if actual_port_mode is ACCESS: raise InterfaceInWrongPortMode("access") elif actual_port_mode is None: update_attributes.append(self.custom_strategies.set_interface_port_mode_update_element("trunk")) if vlan in interface.trunk_vlans: raise VlanAlreadyInTrunk(vlan) elif interface.trunk_native_vlan != vlan: update_attributes.append(to_ele("<native-vlan-id>{}</native-vlan-id>".format(vlan))) if update_attributes: update = Update() update.add_interface(interface_update(interface_id, "0", update_attributes)) try: self._push(update) except RPCError as e: if "No vlan matches vlan tag" in e.message: raise UnknownVlan(vlan) raise
def bond_lacp_options(): return to_ele(""" <lacp> <active/> <periodic>slow</periodic> </lacp> """)
def handle_raw_dispatch(self, raw): if 'routing-engine' in raw: raw = re.sub(r'<ok/>', '</routing-engine>\n<ok/>', raw) return raw # check if error is during capabilites exchange itself elif re.search('\<rpc-reply\>.*?\</rpc-reply\>.*\</hello\>?', raw, re.M | re.S): errs = re.findall( '\<rpc-error\>.*?\</rpc-error\>', raw, re.M | re.S) err_list = [] if errs: add_ns = """ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="*"> <xsl:element name="{local-name()}" namespace="urn:ietf:params:xml:ns:netconf:base:1.0"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>""" for err in errs: doc = etree.ElementTree(etree.XML(err)) # Adding namespace using xslt xslt = etree.XSLT(etree.XML(add_ns)) transformed_xml = etree.XML(etree.tostring(xslt(doc))) err_list.append(RPCError(transformed_xml)) return RPCError(to_ele("<rpc-reply>"+''.join(errs)+"</rpc-reply>"), err_list) else: return False
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 m(): return to_ele(""" <interfaces> <interface> <name>{}</name> </interface> </interfaces> """.format(interface_id))
def m(): return to_ele(""" <interfaces> <interface> <name>%s</name> </interface> </interfaces> """ % interface_id)
def m(): return to_ele(""" <vlans> <vlan> <name>{}</name> </vlan> </vlans> """.format(vlan_name))
def rstp_protocol_interfaces(): return to_ele(""" <protocols> <rstp> <interface /> </rstp> </protocols> """)
def m(): return to_ele(""" <vlans> <vlan> <name>%s</name> </vlan> </vlans> """ % vlan_name)
def _matches(self, other): otherxml = other if not isinstance(other, basestring) else to_ele(other) try: self.compare_nodes(self.expected, otherxml) return True except AssertionError as e: self.last_error = e return False
def m(): return to_ele(""" <vlans> <vlan> <vlan-id>{}</vlan-id> </vlan> </vlans> """.format(vlan_id))
def interface_unit_interface_removal(interface, unit): return to_ele(""" <interface> <name>{}</name> <unit operation="delete"> <name>{}</name> </unit> </interface> """.format(interface, unit))
def free_from_bond_operation(interface_name): return to_ele(""" <interface> <name>{0}</name> <ether-options> <ieee-802.3ad operation=\"delete\" /> </ether-options> </interface> """.format(interface_name))
def _list_physical_interfaces(self): terse = self.netconf.rpc(to_ele(""" <get-interface-information> <terse/> </get-interface-information> """)) return [_PhysicalInterface(i.xpath("name")[0].text.strip(), shutdown=i.xpath("admin-status")[0].text.strip() == "down") for i in terse.xpath("interface-information/physical-interface")]
def reset_interface(self, interface_id): content = to_ele(""" <interface operation=\"delete\"> <name>{0}</name> </interface> """.format(interface_id)) update = Update() update.add_interface(content) self._push_interface_update(interface_id, update)
def rpc(self, name): """RPC to be execute on remote device :name: Name of rpc in string format""" try: obj = to_ele(name) resp = self.m.rpc(obj) return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml except RPCError as exc: msg = exc.data_xml if hasattr(exc, 'data_xml') else exc.xml raise Exception(to_xml(msg))
def enable_lldp(self, interface_id, enabled): config = self.query(one_interface(interface_id), one_protocol_interface("lldp", interface_id)) self.get_interface_config(interface_id, config) update_ele = None disabled_node = first(config.xpath("data/configuration/protocols/lldp/interface/name" "[text()=\"{0:s}\"]/../disable".format(interface_id))) if enabled: update_ele = protocol_interface_update(interface_id) if disabled_node is not None: update_ele.append(to_ele('<disable operation="delete"/>')) elif not enabled and disabled_node is None: update_ele = protocol_interface_update(interface_id) update_ele.append(to_ele('<disable/>')) if update_ele is not None: update = Update() update.add_protocol_interface("lldp", update_ele) self._push(update)
def craft_members_modification_to_remove_vlan(interface_node, vlan_name, number): members_modifications = [] for vlan_members_node in interface_node.xpath("unit/family/ethernet-switching/vlan/members"): if vlan_members_node.text == vlan_name: members_modifications.append(to_ele("<members operation=\"delete\">{}</members>".format(vlan_members_node.text))) else: vlan_list = parse_range(vlan_members_node.text) if number in vlan_list: members_modifications.append(to_ele("<members operation=\"delete\">{}</members>".format(vlan_members_node.text))) below = vlan_list[:vlan_list.index(number)] if len(below) > 0: members_modifications.append(to_ele("<members>{}</members>".format(to_range(below)))) above = vlan_list[vlan_list.index(number) + 1:] if len(above) > 0: members_modifications.append(to_ele("<members>{}</members>".format(to_range(above)))) return members_modifications
def remove_native_vlan(self, interface_id): interface = self.get_interface(interface_id) if interface.trunk_native_vlan is None: raise NativeVlanNotSet(interface_id) update = Update() update.add_interface(interface_update(interface_id, "0", [to_ele("<native-vlan-id operation=\"delete\" />")])) self._push(update)
def m(): return to_ele(""" <protocols> <{protocol}> <interface> <name>{}</name> </interface> </{protocol}> </protocols> """.format(interface_id, protocol=protocol))
def interface_main_update(name, attributes): content = to_ele(""" <interface> <name>{}</name> </interface> """.format(name)) for attribute in (attributes if attributes is not None else []): content.append(attribute) return content
def interface_speed_update(interface_name, speed): return to_ele(""" <interface> <name>{0}</name> <ether-options> <speed> <ethernet-{1}/> </speed> </ether-options> </interface> """.format(interface_name, speed))
def _callback(call, handler='edit_config', target='running', source='startup', mgr=None): try: call = ET.tostring(call) if handler == 'get': call_element = xml_.to_ele(call) return ET.fromstring(str(mgr.dispatch(call_element))) if handler == 'edit_config': mgr.edit_config(target=target, config=call) if handler == 'delete_config': mgr.delete_config(target=target) if handler == 'copy_config': mgr.copy_config(target=target, source=source) except (ncclient.transport.TransportError, ncclient.transport.SessionCloseError, ncclient.transport.SSHError, ncclient.transport.AuthenticationError, ncclient.transport.SSHUnknownHostError) as error: logging.error(error) raise DeviceCommError
def execute_action(self, path): # Code to execute an action on NSO using NETCONF content = self.load_config_file(path) print(content) with manager.connect(host=self.config.host, port=self.config.netconf_port, username=self.config.username, password=self.config.password, hostkey_verify=False, allow_agent=False, look_for_keys=False) as m: c = m.dispatch(to_ele(content)) if c.ok: if c.data_ele.findall('.//{http://com/example/l3vpn}success' )[0].text.lower() != "true": print("Action Failed!\n{}".format( etree.tostring(c.data_ele, pretty_print=True).decode('utf-8'))) exit(1) return etree.tostring(c.data_ele, pretty_print=True).decode('utf-8') raise Exception( f'Error occured while executing the action: {content}.')
def main(): with manager.connect( host=constants.NC_HOST, port=constants.NC_PORT, username=constants.DEVICE_USERNAME, password=constants.DEVICE_PASSWORD, timeout=30, hostkey_verify=False, ) as nc, open("netconf_cfg/provision.yml") as f: yaml = YAML(typ="safe") data = yaml.load(f) xml = utils.dict_to_xml(data, root="config") print(f"Sending RPC:\n{P(xml)}") xml_str = etree.tostring(xml).decode('utf-8') nc_reply = nc.edit_config(xml_str, target="running") print(f"Received RPC reply:\n{P(nc_reply.xml)}") print("Saving configuration") nc_reply = nc.dispatch(xml_.to_ele(constants.NC_SAVE_CONFIG_RPC)) if nc_reply.ok: print("Running config was saved to startup successfully") else: print("Failed to save running config to startup")
def interface_update(self, name, unit, attributes=None, vlan_members=None): content = to_ele(""" <interface> <name>{interface}</name> <unit> <name>{unit}</name> <family> <bridge> </bridge> </family> </unit> </interface> """.format(interface=name, unit=unit)) bridge = first(content.xpath("//bridge")) for attribute in (attributes if attributes is not None else []): bridge.append(attribute) if vlan_members: for attribute in vlan_members: bridge.append(attribute) return content
def exec_command(self, cmd, in_data=None, sudoable=True): """Sends the request to the node and returns the reply The method accepts two forms of request. The first form is as a byte string that represents xml string be send over netconf session. The second form is a json-rpc (2.0) byte string. """ if self._manager: # to_ele operates on native strings request = to_ele(to_native(cmd, errors="surrogate_or_strict")) if request is None: return "unable to parse request" try: reply = self._manager.rpc(request) except RPCError as exc: error = self.internal_error(data=to_text( to_xml(exc.xml), errors="surrogate_or_strict")) return json.dumps(error) return reply.data_xml else: return super(Connection, self).exec_command(cmd, in_data, sudoable)
def set_trunk_mode(self, interface_id): update_attributes = [] config = self.query(one_interface(interface_id), self.custom_strategies.all_vlans) interface_node = self.get_interface_config(interface_id, config) interface = self.node_to_interface(interface_node, config) if interface.port_mode is ACCESS or interface.port_mode is None: update_attributes.append( self.custom_strategies.get_interface_port_mode_update_element( "trunk")) if interface.access_vlan is not None: update_attributes.append(to_ele('<vlan operation="delete" />')) if len(update_attributes) > 0: update = Update() update.add_interface( self.custom_strategies.interface_update( interface_id, "0", update_attributes)) self._push_interface_update(interface_id, update)
def exec_command(self, request): """Sends the request to the node and returns the reply The method accepts two forms of request. The first form is as a byte string that represents xml string be send over netconf session. The second form is a json-rpc (2.0) byte string. """ try: obj = json.loads(to_text(request, errors='surrogate_or_strict')) if 'jsonrpc' in obj: if self._netconf: out = self._exec_rpc(obj) else: out = self.internal_error( "netconf plugin is not supported for network_os %s" % self._play_context.network_os) return 0, to_bytes(out, errors='surrogate_or_strict'), b'' else: err = self.invalid_request(obj) return 1, b'', to_bytes(err, errors='surrogate_or_strict') except (ValueError, TypeError): # to_ele operates on native strings request = to_native(request, errors='surrogate_or_strict') req = to_ele(request) if req is None: return 1, b'', b'unable to parse request' try: reply = self._manager.rpc(req) except RPCError as exc: return 1, b'', to_bytes(to_xml(exc.xml), errors='surrogate_or_strict') return 0, to_bytes(reply.data_xml, errors='surrogate_or_strict'), b''
def load_configuration(self, format='xml', action='merge', target='candidate', config=None): """ Load given configuration on device :param format: Format of configuration (xml, text, set) :param action: Action to be performed (merge, replace, override, update) :param target: The name of the configuration datastore being edited :param config: The configuration to be loaded on remote host in string format :return: Received rpc response from remote host in string format """ if config: if format == 'xml': config = to_ele(config) try: return self.m.load_configuration(format=format, action=action, target=target, config=config).data_xml except RPCError as exc: raise Exception(to_xml(exc.xml))
def save_config(host, username, password, port='830'): from ncclient.xml_ import to_ele RPC = open('./save_config.xml', 'r').read() with manager.connect(host=host, port=port, username=username, password=password, hostkey_verify=False) as router: netconf_reply = router.dispatch(to_ele(RPC)) pretty_print_xml(netconf_reply.xml)
def get_interface_port_mode_update_element(self, mode): return to_ele("<port-mode>{}</port-mode>".format(mode))
def __init__(self, raw): self._raw = raw self._root_ele = to_ele(raw)
def get_vlan_member_update_element(self, vlan): return to_ele("<members>{}</members>".format(vlan))
#! /data/Python_envs/Python3/bin/python3 from ncclient import manager, xml_ RTR1_MGR = manager.connect(host='csr1.test.lab', port=830, username='******', password='******', hostkey_verify=False, device_params={'name': 'csr'}) SAVE = """ <cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/> """ reply = RTR1_MGR.dispatch(xml_.to_ele(SAVE)) print(reply) RTR1_MGR.close_session()
def add_vrrp_group(self, vlan_number, group_id, ips=None, priority=None, hello_interval=None, dead_interval=None, track_id=None, track_decrement=None): config = self.query(one_interface_vlan(vlan_number)) if len(config.xpath( "data/configuration/interfaces/interface/unit")) < 1: raise UnknownVlan(vlan_number) adresses = [ IPNetwork(addr_node.text) for addr_node in config.xpath( "data/configuration/interfaces/interface/unit/family/inet/address/name" ) ] parent_address = self._get_address_that_contains_all_ips(adresses, ips) vrrp_node = to_ele(""" <vrrp-group> <name>{group_id}</name> <priority>{priority}</priority> <preempt> <hold-time>{preempt_hold_time}</hold-time> </preempt> <accept-data/> <authentication-type>simple</authentication-type> <authentication-key>{auth}</authentication-key> <track> <route> <route_address>{tracking}</route_address> <routing-instance>default</routing-instance> <priority-cost>{tracking_decrement}</priority-cost> </route> </track> </vrrp-group>""".format(vlan_number=vlan_number, parent_address=parent_address, group_id=group_id, vip=ips[0], preempt_hold_time=PREEMPT_HOLD_TIME, priority=priority, auth="VLAN{}".format(vlan_number), tracking=track_id, tracking_decrement=track_decrement)) for ip in ips: vrrp_node.append( to_ele("<virtual-address>{}</virtual-address>".format(ip))) update = Update() update.add_interface( irb_address_update(vlan_number, parent_address, children=[vrrp_node])) self._push(update)
def vlan_interface_update(self, vlan_id, description): vlan_node = self.vlan_update(vlan_id, description) vlan_node.append( to_ele("<routing-interface>irb.{}</routing-interface>".format( vlan_id))) return vlan_node
the License. All rights not expressly granted by the License are reserved. Unless required by applicable law or agreed to separately in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ __author__ = "Hank Preston <*****@*****.**>" __contributors__ = "Bryan Byrne <*****@*****.**>" __copyright__ = "Copyright (c) 2019 Cisco and/or its affiliates." __license__ = "Cisco Sample Code License, Version 1.0" from device_info import ios_xe1 from ncclient import manager, xml_ if __name__ == '__main__': with manager.connect(host=ios_xe1["address"], port=ios_xe1["port"], username=ios_xe1["username"], password=ios_xe1["password"], hostkey_verify=False) as m: # Build XML Payload for the RPC save_body = '<cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/>' # Send the RPC to the Device save_rpc = m.dispatch(xml_.to_ele(save_body)) # Print the NETCONF Reply print(save_rpc)
def protocol_interface_update(name): return to_ele(""" <interface> <name>{}</name> </interface> """.format(name))
def test_embedded_notification_list_insert_and_delete(mgr, notification_cleanup): mgr.dispatch( to_ele(""" <create-subscription xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"> <filter> <list-foo-changed xmlns="urn:ietf:params:xml:ns:yang:test-service-test-notification" /> </filter> </create-subscription> """)) # Add a couple elements and send a notification for each assert get_notification_list(mgr) == {} set_notification_list_item(mgr, "Notification1", "Notification Message1") set_notification_list_item(mgr, "Notification2", "Notification Message2") assert get_notification_list(mgr) == { "Notification1": { "foo": "Notification Message1" }, "Notification2": { "foo": "Notification Message2" }, } generate_test_notification_list_foo_string_notif("Notification1", "Notification Message") results = find_notifications_matching( mgr, ("/notif:notification" "/test-notification:notification-from-list" "/test-notification:notification-from-list" "/test-notification:list-foo-changed" "/test-notification:new-value"), ) assert results[0].text == "Notification Message" generate_test_notification_list_foo_string_notif("Notification2", "Notification Message2") results = find_notifications_matching( mgr, ("/notif:notification" "/test-notification:notification-from-list" "/test-notification:notification-from-list" "/test-notification:list-foo-changed" "/test-notification:new-value"), ) assert results[0].text == "Notification Message2" # Delete the elements and try sending a notification clear_notification_list_item(mgr, "Notification1") clear_notification_list_item(mgr, "Notification2") assert get_notification_list(mgr) == {} with pytest.raises(AssertionError): generate_test_notification_list_foo_string_notif( "Notification1", "Notification Message1") # Add a new element and send a notification set_notification_list_item(mgr, "Notification99", "Notification Message") assert get_notification_list(mgr) == { "Notification99": { "foo": "Notification Message" } } generate_test_notification_list_foo_string_notif("Notification99", "Notification Message") results = find_notifications_matching( mgr, ("/notif:notification" "/test-notification:notification-from-list" "/test-notification:notification-from-list" "/test-notification:list-foo-changed" "/test-notification:new-value"), ) assert results[0].text == "Notification Message" clear_notification_list_item(mgr, "Notification99") assert get_notification_list(mgr) == {} # Add a couple elements back with the same keys and verify notifications work assert get_notification_list(mgr) == {} set_notification_list_item(mgr, "Notification1", "Notification Message1") set_notification_list_item(mgr, "Notification2", "Notification Message2") assert get_notification_list(mgr) == { "Notification1": { "foo": "Notification Message1" }, "Notification2": { "foo": "Notification Message2" }, } generate_test_notification_list_foo_string_notif("Notification1", "Notification Message1") results = find_notifications_matching( mgr, ("/notif:notification" "/test-notification:notification-from-list" "/test-notification:notification-from-list" "/test-notification:list-foo-changed" "/test-notification:new-value"), ) assert results[0].text == "Notification Message1" generate_test_notification_list_foo_string_notif("Notification2", "Notification Message2") results = find_notifications_matching( mgr, ("/notif:notification" "/test-notification:notification-from-list" "/test-notification:notification-from-list" "/test-notification:list-foo-changed" "/test-notification:new-value"), ) assert results[0].text == "Notification Message2" # Clear list again and verify notifications can't be sent for old elements clear_notification_list_item(mgr, "Notification1") clear_notification_list_item(mgr, "Notification2") assert get_notification_list(mgr) == {} with pytest.raises(AssertionError): generate_test_notification_list_foo_string_notif( "Notification1", "Notification Message1")
def execrpc(hostip, uname, passw, rpc): conn=manager.connect(host=hostip,port=22,username=uname,password=passw, timeout=60,hostkey_verify=False, device_params={'name':'default'}) rpcreply = conn.dispatch(to_ele(rpc)) print(rpcreply) conn.close_session()
def add_protocol_interface(self, protocol, interface): if protocol not in self.sub_protocol_roots: self.sub_protocol_roots[protocol] = to_ele( "<{0}></{0}>".format(protocol)) self.add_protocol(self.sub_protocol_roots[protocol]) self.sub_protocol_roots[protocol].append(interface)
<commands> <command>interface ethernet %s</command> <command>description %s</command> <command>switchport access vlan %s</command> </commands> </nc:edit-config> """ % (interface, description, vlan) return (interface_rpc) eos = manager.connect(host="10.83.28.203", port="830", timeout=30, username="******", password="******", hostkey_verify=False) rpc = vlan_rpc(vlan_id, vlan_name) # print(rpc) rpcreply = eos.dispatch(to_ele(rpc)) print(rpcreply) # print(rpcreply.ok) rpc = interface_rpc(interface, interface_description, vlan_id) # print(rpc) rpcreply = eos.dispatch(to_ele(rpc)) print(rpcreply) # print(rpcreply.ok) eos.close_session()
RUNNING = True if NC_CANDIDATE in m.server_capabilities: CANDIDATE = True # # Main operations # # TODO: get_running/get_oper are a bit samey, could be done better # if args.save_config: save_config_rpc = ''' <copy xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-rpc"> <_source>running-config</_source> <_destination>startup-config</_destination> </copy>''' result = m.dispatch(to_ele(save_config_rpc)) parsed = etree.fromstring(result._raw.encode()) print(parsed.xpath('//*[local-name()="result"]')[0].text) elif args.get_running: if isinstance(args.filter, list): for f in args.filter: get_running_config(m, filter=f, xpath=None) else: get_running_config(m, xpath=args.xpath, filter=args.filter) elif args.get_oper: if isinstance(args.filter, list): for f in args.filter: get(m, filter=f, xpath=None) else: get(m, filter=args.filter, xpath=args.xpath)
def get_vlan_member_update_element(self, vlan): return to_ele("<vlan-id-list>{}</vlan-id-list>".format(vlan))
def __init__(self, expected): self.expected = to_ele(expected) self.last_error = None
def vlan_removal(self, name): return to_ele(""" <domain operation="delete"> <name>{}</name> </domain>""".format(name))
def describe_mismatch(self, item, mismatch_description): itemxml = item if not isinstance(item, basestring) else to_ele(item) mismatch_description.append_text("WAS : \n" + to_xml(itemxml, pretty_print=True) + "\n\n") mismatch_description.append_text("IN WHICH : " + str(self.last_error))
</interface> </interfaces> </config> ''' InterfaceName = 'TenGigabitEthernet1/0/6' configChanges = configChanges.format(intName=InterfaceName, access_Vlan='10') #print(configChanges) editconfig = m.edit_config(target='running', config=configChanges) print(editconfig) save_body = """ <cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/> """ netconf_reply = m.dispatch(xml_.to_ele(save_body)) filterXml = ''' <filter> <interfaces xmlns="http://openconfig.net/yang/interfaces"> <interface> <name>{intName}</name> </interface> </interfaces> </filter> ''' filterXml = filterXml.format(intName=InterfaceName) runningConfig = m.get_config(source='running', filter=filterXml).data_xml dom = xml.dom.minidom.parseString( runningConfig) #or xml.dom.minidom.parse(c) pretty_xml_as_string = dom.toprettyxml() print(pretty_xml_as_string)
def save_running_config(): rpc_body = '''<cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/>''' netconf_reply = m.dispatch(xml_.to_ele(rpc_body)) print("Did it work? {}".format(netconf_reply.ok))
def interface_speed(speed): return to_ele(""" <speed> <ethernet-{0}/> </speed> """.format(speed))
from ncclient import manager, xml_ #calling manager.connect from ncclient module to connect to Cisco CSR1000v #you need enter the specific values of your CSR device here csr_manager = manager.connect(host='hostname/IP address', port=830, username='******', password='******', hostkey_verify=False, device_params={'name': 'csr'}) #template that matches save-config schema on CSR device save_Running = """ <cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/> """ #command/reply being pushed/pulled to RPC API CSR_Reply = csr_manager.dispatch(xml_.to_ele(save_Running)) #printig rpc-reply to terminial print(CSR_Reply) #closing session csr_manager.close_session()