12-06-2019 06:51 AM
Hello.
I'm trying to set up BGP config via YDK with the following example:
import logging from ydk.services import CodecService, CRUDService from ydk.providers import CodecServiceProvider, NetconfServiceProvider from ydk.models.openconfig import openconfig_bgp as oc_bgp from ydk.models.openconfig import openconfig_bgp_types as oc_bgp_types from ydk.filters import YFilter logger = logging.getLogger('ydk') logger.setLevel(logging.INFO) handler = logging.StreamHandler() formatter = logging.Formatter(("%(asctime)s - %(name)s - " "%(levelname)s - %(message)s")) handler.setFormatter(formatter) logger.addHandler(handler) DEVICES = { 'junos': { 'ip': '10.10.30.4', 'pass': 'Juniper' }, 'xr': { 'ip': '10.10.30.5', 'pass': 'admin' }, 'xe': { 'ip': '10.10.30.6', 'pass': 'admin' } } def config_bgp(bgp): """Add config data to bgp object.""" # global configuration bgp.global_.config.as_ = 65001 afi_safi = bgp.global_.afi_safis.AfiSafi() afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST() afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST() afi_safi.config.enabled = True bgp.global_.afi_safis.afi_safi.append(afi_safi) # configure IBGP peer group peer_group = bgp.peer_groups.PeerGroup() peer_group.peer_group_name = "EBGP" peer_group.config.peer_group_name = "EBGP" peer_group.config.peer_as = 65002 peer_group.transport.config.local_address = "Loopback0" afi_safi = peer_group.afi_safis.AfiSafi() afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST() afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST() afi_safi.config.enabled = True # afi_safi.apply_policy.config.import_policy.append("POLICY3") # afi_safi.apply_policy.config.export_policy.append("POLICY1") peer_group.afi_safis.afi_safi.append(afi_safi) bgp.peer_groups.peer_group.append(peer_group) # configure IBGP neighbor neighbor = bgp.neighbors.Neighbor() neighbor.neighbor_address = '2001:db8:e:1::1' neighbor.config.neighbor_address = '2001:db8:e:1::1' neighbor.config.peer_group = "EBGP" bgp.neighbors.neighbor.append(neighbor) if __name__ == '__main__': # provider = CodecServiceProvider(type='xml') # codec = CodecService() bgp = oc_bgp.Bgp() bgp.yfilter = YFilter.replace config_bgp(bgp) # print(codec.encode(provider, native)) device = DEVICES['xe'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) crud = CRUDService() crud.create(provider, bgp)
In the log output I see that everything went well:
2019-12-06 17:48:16,921 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.6 2019-12-06 17:48:16,933 - ydk - INFO - Connected to 10.10.30.6 on port 830 using ssh with timeout of -1 2019-12-06 17:48:16,934 - ydk - INFO - Executing CRUD create operation on [openconfig-bgp:bgp] 2019-12-06 17:48:16,934 - ydk - INFO - Executing 'edit-config' RPC on [openconfig-bgp:bgp] 2019-12-06 17:48:17,014 - ydk - INFO - ============= Sending RPC to device ============= <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <running/> </target> <config><bgp xmlns="http://openconfig.net/yang/bgp" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="replace"> <global> <config> <as>65001</as> </config> <afi-safis> <afi-safi> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <config> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <enabled>true</enabled> </config> </afi-safi> </afi-safis> </global> <neighbors> <neighbor> <neighbor-address>2001:db8:e:1::1</neighbor-address> <config> <peer-group>EBGP</peer-group> <neighbor-address>2001:db8:e:1::1</neighbor-address> </config> </neighbor> </neighbors> <peer-groups> <peer-group> <peer-group-name>EBGP</peer-group-name> <config> <peer-group-name>EBGP</peer-group-name> <peer-as>65002</peer-as> </config> <transport> <config> <local-address>Loopback0</local-address> </config> </transport> <afi-safis> <afi-safi> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <config> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <enabled>true</enabled> </config> </afi-safi> </afi-safis> </peer-group> </peer-groups> </bgp> </config> </edit-config> </rpc> 2019-12-06 17:48:17,418 - ydk - INFO - ============= Received RPC from device ============= <?xml version="1.0" encoding="UTF-8"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2"> <ok/> </rpc-reply> 2019-12-06 17:48:17,418 - ydk - INFO - Operation succeeded 2019-12-06 17:48:17,424 - ydk - INFO - Disconnected from device
But there is no BGP config on the device afterward
CSR6#show run | se bgp CSR6#
Solved! Go to Solution.
12-10-2019 01:36 PM - edited 12-10-2019 02:33 PM
Could you please rerun this script with logging level DEBUG and attach the log to the post so I could understand why the YDK failed to get XE configuration.
Note. Because the filter for the NetconfService.get_config() is not specified, the YDK attempts to retrieve full configuration of the device. The returned result in this case is class Config instance, which is alias of EntityCollection class.
I do not understand, why later on you try to call codec.decode(), which expects as a parameter string value of payload. I guess you wanted to get result as XML and then print it. In this case the last operator should be:
xml_list = codec.encode(pr, config.entities(), pretty=True)
print("\nGOT DEVICE CONFIGURATION:\n%s" % '\n'.join(xml_list))
I executed such script on CiscoDevNet IOS XE sandbox router and got it working just fine (see attached log file)
12-11-2019 10:50 AM
Kirill
You get all python objects in the line:
config = netconf.get_config(provider, Datastore.running)
But they are placed into Config class, which is EntityCollection instance. Please check its API and use examples here. In order to get list of entities (python objects) simply run:
list_of_entities = config.entities()
12-06-2019 10:11 AM - edited 12-06-2019 10:53 AM
This is similar to XRv9K NETCONF 1.1. The issue that you are observing is not related to YDK. As I can see in the log, the YDK worked perfectly well.
I believe you cannot configure BGP on Cisco routers using standard openconfig models. For this you should use proprietary Cisco models and/or openconfig-network-instance.
It is also possible that your particular device does not include BGP routing as a feature. You can try to do the BGP configuration on your device using CLI just to see if it is supported.
12-09-2019 05:52 AM
It works really strange for me.
I've configured BGP process manually:
CSR6#show run | se bgp router bgp 6 bgp router-id 10.10.30.6 bgp log-neighbor-changes neighbor 10.10.30.5 remote-as 5
And then did get-config via ydk. This is what I've got:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2"> <data> <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native"> <version>16.9</version> <boot-start-marker/> <boot-end-marker/> <service> <timestamps> <debug> <datetime> <msec/> </datetime> </debug> <log> <datetime> <msec/> </datetime> </log> </timestamps> </service> <platform> <console xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-platform"> <output>serial</output> </console> </platform> <hostname>CSR6</hostname> <enable> <password> <secret>admin</secret> </password> </enable> <username> <name>admin</name> <privilege>15</privilege> <password> <encryption>0</encryption> <password>admin</password> </password> </username> <username> <name>horseinthesky</name> <privilege>15</privilege> </username> <ip> <domain> <name>lab.local</name> </domain> <forward-protocol> <protocol>nd</protocol> </forward-protocol> <route> <ip-route-interface-forwarding-list> <prefix>0.0.0.0</prefix> <mask>0.0.0.0</mask> <fwd-list> <fwd>10.10.30.254</fwd> </fwd-list> </ip-route-interface-forwarding-list> </route> <ssh> <pubkey-chain> <username> <name>horseinthesky</name> <key-hash> <key-type>ssh-rsa</key-type> <key-hash-value>D13E140448650E64A6778D40057326E8 horseinthesky@Kappa</key-hash-value> </key-hash> </username> </pubkey-chain> </ssh> <http xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-http"> <authentication> <local/> </authentication> <server>true</server> <secure-server>true</secure-server> </http> </ip> <ipv6> <unicast-routing/> </ipv6> <interface> <GigabitEthernet> <name>1</name> <description>DON'T TOUCH ME</description> <ip> <address> <primary> <address>10.10.30.6</address> <mask>255.255.255.0</mask> </primary> </address> </ip> <mop> <enabled>false</enabled> <sysid>false</sysid> </mop> <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet"> <auto>true</auto> </negotiation> </GigabitEthernet> <GigabitEthernet> <name>2</name> <description>Configured via ydk</description> <ip> <address> <primary> <address>172.16.1.0</address> <mask>255.255.255.254</mask> </primary> </address> </ip> <ipv6> <address> <prefix-list> <prefix>2001:DB8::1:0/127</prefix> </prefix-list> </address> </ipv6> <load-interval>30</load-interval> <mtu>9192</mtu> <speed xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet"> <value-1000/> </speed> <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet"> <auto>false</auto> </negotiation> </GigabitEthernet> <GigabitEthernet> <name>3</name> <shutdown/> <mop> <enabled>false</enabled> <sysid>false</sysid> </mop> <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet"> <auto>true</auto> </negotiation> </GigabitEthernet> <GigabitEthernet> <name>4</name> <shutdown/> <mop> <enabled>false</enabled> <sysid>false</sysid> </mop> <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet"> <auto>true</auto> </negotiation> </GigabitEthernet> <Loopback> <name>0</name> <ip> <address> <primary> <address>1.1.1.6</address> <mask>255.255.255.255</mask> </primary> </address> </ip> </Loopback> </interface> <control-plane/> <login> <on-success> <log/> </on-success> </login> <multilink> <bundle-name xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ppp">authenticated</bundle-name> </multilink> <redundancy/> <spanning-tree> <extend xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-spanning-tree"> <system-id/> </extend> </spanning-tree> <subscriber> <templating/> </subscriber> <crypto> <pki xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-crypto"> <trustpoint> <id>TP-self-signed-835353984</id> <enrollment> <selfsigned/> </enrollment> <revocation-check>none</revocation-check> <rsakeypair> <key-label>TP-self-signed-835353984</key-label> </rsakeypair> <subject-name>cn=IOS-Self-Signed-Certificate-835353984</subject-name> </trustpoint> <certificate> <chain> <name>TP-self-signed-835353984</name> <certificate> <serial>01</serial> <certtype>self-signed</certtype> </certificate> </chain> </certificate> </pki> </crypto> <router> <bgp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-bgp"> <id>6</id> <bgp> <router-id> <ip-id>10.10.30.6</ip-id> </router-id> </bgp> <neighbor> <id>10.10.30.5</id> <remote-as>5</remote-as> </neighbor> </bgp> </router> <license> <udi> <pid>CSR1000V</pid> <sn>9SVCRC7X9CJ</sn> </udi> </license> <line> <console> <first>0</first> <exec-timeout> <minutes>0</minutes> <seconds>0</seconds> </exec-timeout> <logging> <synchronous/> </logging> <privilege> <level> <number>15</number> </level> </privilege> <stopbits>1</stopbits> <transport> <output> <output>none</output> </output> </transport> </console> <vty> <first>0</first> <last>4</last> <exec-timeout> <minutes>0</minutes> <seconds>0</seconds> </exec-timeout> <logging> <synchronous/> </logging> <login> <local/> </login> <privilege> <level> <number>15</number> </level> </privilege> <transport> <input> <input>telnet</input> <input>ssh</input> </input> </transport> </vty> </line> <diagnostic xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-diagnostics"> <bootup> <level>minimal</level> </bootup> </diagnostic> </native> <licensing xmlns="http://cisco.com/ns/yang/cisco-smart-license"> <config> <enable>false</enable> <privacy> <hostname>false</hostname> <version>false</version> </privacy> <utility> <utility-enable>false</utility-enable> </utility> </config> </licensing> <bgp xmlns="http://openconfig.net/yang/bgp"> <global> <config> <as>65001</as> </config> <afi-safis> <afi-safi> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <config> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <enabled>true</enabled> </config> </afi-safi> </afi-safis> </global> <neighbors> <neighbor> <neighbor-address>2001:db8:e:1::1</neighbor-address> <config> <peer-group>EBGP</peer-group> <neighbor-address>2001:db8:e:1::1</neighbor-address> </config> </neighbor> </neighbors> <peer-groups> <peer-group> <peer-group-name>EBGP</peer-group-name> <config> <peer-group-name>EBGP</peer-group-name> <peer-as>65002</peer-as> </config> <transport> <config> <local-address>Loopback0</local-address> </config> </transport> <afi-safis> <afi-safi> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <config> <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name> <enabled>true</enabled> </config> </afi-safi> </afi-safis> </peer-group> </peer-groups> </bgp> <interfaces xmlns="http://openconfig.net/yang/interfaces"> <interface> <name>GigabitEthernet1</name> <config> <name>GigabitEthernet1</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <description>DON'T TOUCH ME</description> <enabled>true</enabled> </config> <subinterfaces> <subinterface> <index>0</index> <config> <index>0</index> <description>DON'T TOUCH ME</description> <enabled>true</enabled> </config> <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip"> <addresses> <address> <ip>10.10.30.6</ip> <config> <ip>10.10.30.6</ip> <prefix-length>24</prefix-length> </config> </address> </addresses> </ipv4> <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip"> <config> <enabled>false</enabled> </config> </ipv6> </subinterface> </subinterfaces> <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet"> <config> <mac-address>50:00:00:08:00:00</mac-address> <auto-negotiate>true</auto-negotiate> </config> </ethernet> </interface> <interface> <name>GigabitEthernet2</name> <config> <name>GigabitEthernet2</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <mtu>9192</mtu> <description>Configured via ydk</description> <enabled>true</enabled> </config> <subinterfaces> <subinterface> <index>0</index> <config> <index>0</index> <description>Configured via ydk</description> <enabled>true</enabled> </config> <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip"> <addresses> <address> <ip>172.16.1.0</ip> <config> <ip>172.16.1.0</ip> <prefix-length>31</prefix-length> </config> </address> </addresses> </ipv4> <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip"> <addresses> <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <error-type>application</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message xml:lang="en">application protocol error</error-message> <error-info> <bad-element>address</bad-element> </error-info> </rpc-error> </addresses> <config> <enabled>false</enabled> </config> </ipv6> </subinterface> </subinterfaces> <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet"> <config> <mac-address>50:00:00:08:00:01</mac-address> <auto-negotiate>false</auto-negotiate> <port-speed>SPEED_1GB</port-speed> </config> </ethernet> </interface> <interface> <name>GigabitEthernet3</name> <config> <name>GigabitEthernet3</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>false</enabled> </config> <subinterfaces> <subinterface> <index>0</index> <config> <index>0</index> <enabled>false</enabled> </config> <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip"> <config> <enabled>false</enabled> </config> </ipv6> </subinterface> </subinterfaces> <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet"> <config> <mac-address>50:00:00:08:00:02</mac-address> <auto-negotiate>true</auto-negotiate> </config> </ethernet> </interface> <interface> <name>GigabitEthernet4</name> <config> <name>GigabitEthernet4</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>false</enabled> </config> <subinterfaces> <subinterface> <index>0</index> <config> <index>0</index> <enabled>false</enabled> </config> <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip"> <config> <enabled>false</enabled> </config> </ipv6> </subinterface> </subinterfaces> <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet"> <config> <mac-address>50:00:00:08:00:03</mac-address> <auto-negotiate>true</auto-negotiate> </config> </ethernet> </interface> <interface> <name>Loopback0</name> <config> <name>Loopback0</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type> <enabled>true</enabled> </config> <subinterfaces> <subinterface> <index>0</index> <config> <index>0</index> <enabled>true</enabled> </config> <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip"> <addresses> <address> <ip>1.1.1.6</ip> <config> <ip>1.1.1.6</ip> <prefix-length>32</prefix-length> </config> </address> </addresses> </ipv4> <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip"> <config> <enabled>false</enabled> </config> </ipv6> </subinterface> </subinterfaces> </interface> </interfaces> <network-instances xmlns="http://openconfig.net/yang/network-instance"> <network-instance> <name>default</name> <config> <name>default</name> <type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:DEFAULT_INSTANCE</type> <description>default-vrf [read-only]</description> </config> <tables> <table> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family> <config> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family> </config> </table> <table> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family> <config> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family> </config> </table> <table> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family> <config> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family> </config> </table> <table> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family> <config> <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol> <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family> </config> </table> </tables> <protocols> <protocol> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>6</name> <config> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>6</name> </config> <bgp> <global> <config> <as>6</as> <router-id>10.10.30.6</router-id> </config> <graceful-restart> <config> <enabled>false</enabled> </config> </graceful-restart> <route-selection-options> <config> <always-compare-med>false</always-compare-med> <external-compare-router-id>false</external-compare-router-id> </config> </route-selection-options> </global> <neighbors> <neighbor> <neighbor-address>10.10.30.5</neighbor-address> <config> <neighbor-address>10.10.30.5</neighbor-address> <peer-as>5</peer-as> </config> <timers> <config> <hold-time>180.0</hold-time> <keepalive-interval>60.0</keepalive-interval> </config> </timers> <ebgp-multihop> <config> <enabled>true</enabled> </config> </ebgp-multihop> </neighbor> </neighbors> </bgp> </protocol> <protocol> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier> <name>DEFAULT</name> <config> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier> <name>DEFAULT</name> </config> <static-routes> <static> <prefix>0.0.0.0/0</prefix> <config> <prefix>0.0.0.0/0</prefix> </config> <next-hops> <next-hop> <index>10.10.30.254</index> <config> <index>10.10.30.254</index> <next-hop>10.10.30.254</next-hop> </config> </next-hop> </next-hops> </static> </static-routes> </protocol> <protocol> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier> <name>DEFAULT</name> <config> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier> <name>DEFAULT</name> </config> </protocol> </protocols> </network-instance> </network-instances> <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"> <interface> <name>GigabitEthernet1</name> <description>DON'T TOUCH ME</description> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>true</enabled> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> <address> <ip>10.10.30.6</ip> <netmask>255.255.255.0</netmask> </address> </ipv4> <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> </interface> <interface> <name>GigabitEthernet2</name> <description>Configured via ydk</description> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>true</enabled> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> <address> <ip>172.16.1.0</ip> <netmask>255.255.255.254</netmask> </address> </ipv4> <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <error-type>application</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message xml:lang="en">application protocol error</error-message> <error-info> <bad-element>address</bad-element> </error-info> </rpc-error> </ipv6> </interface> <interface> <name>GigabitEthernet3</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>false</enabled> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> </interface> <interface> <name>GigabitEthernet4</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> <enabled>false</enabled> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> </interface> <interface> <name>Loopback0</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type> <enabled>true</enabled> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> <address> <ip>1.1.1.6</ip> <netmask>255.255.255.255</netmask> </address> </ipv4> <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/> </interface> </interfaces> <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing"> <routing-instance> <name>default</name> <description>default-vrf [read-only]</description> <routing-protocols> <routing-protocol> <type>static</type> <name>1</name> <static-routes> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ipv4-unicast-routing"> <route> <destination-prefix>0.0.0.0/0</destination-prefix> <next-hop> <next-hop-address>10.10.30.254</next-hop-address> </next-hop> </route> </ipv4> </static-routes> </routing-protocol> </routing-protocols> </routing-instance> </routing> </data> </rpc-reply>
So, you can see my manual BGP config in Native model and Openconfig config in Openconfig BGP model which is not displayed in the config on the device itself.
I understand it is not about YDK but do you know how it is processed on the device?
12-09-2019 08:48 AM
It all depends on device capabilities to implement certain YANG models. From my personal experience I know that BGP can be configured only by using Cisco native models, but it can be partially read using openconfig models too. The main reason behind that concept is that BGP configuration on Cisco devices is much more complex than openconfig models can describe.
For further investigation on this subject please refer to specific router software documentation and/or Cisco TAC support.
12-10-2019 05:01 AM
I wanted to experiment with CodecService and to transform received config to Python object via decode method:
import logging from ydk.services import NetconfService, Datastore, CodecService from ydk.providers import NetconfServiceProvider, CodecServiceProvider logger = logging.getLogger('ydk') logger.setLevel(logging.INFO) handler = logging.StreamHandler() formatter = logging.Formatter(("%(asctime)s - %(name)s - " "%(levelname)s - %(message)s")) handler.setFormatter(formatter) logger.addHandler(handler) DEVICES = { 'junos': { 'ip': '10.10.30.4', 'pass': 'Juniper' }, 'xr': { 'ip': '10.10.30.5', 'pass': 'admin' }, 'xe': { 'ip': '10.10.30.6', 'pass': 'admin' } } if __name__ == '__main__': device = DEVICES['xe'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) netconf = NetconfService() config = netconf.get_config(provider, Datastore.running) codec = CodecService() pr = CodecServiceProvider(type='xml') cfg = codec.decode(pr, config)
But after it gets RPC-Reply with config it fails:
... <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing"> <routing-instance> <name>default</name> <description>default-vrf [read-only]</description> <routing-protocols> <routing-protocol> <type>static</type> <name>1</name> <static-routes> <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ipv4-unicast-routing"> <route> <destination-prefix>0.0.0.0/0</destination-prefix> <next-hop> <next-hop-address>10.10.30.254</next-hop-address> </next-hop> </route> </ipv4> </static-routes> </routing-protocol> </routing-protocols> </routing-instance> </routing> </data> </rpc-reply> Traceback (most recent call last): File "test.py", line 41, in <module> config = netconf.get_config(provider, Datastore.running) File "/usr/local/lib/python3.6/dist-packages/ydk/services/netconf_service.py", line 108, in get_config return _ns_get(provider, source, read_filter, self._ns.get_config) File "/usr/local/lib/python3.6/dist-packages/ydk/services/netconf_service.py", line 153, in _ns_get return _read_entities(provider, get_config=is_config) File "/usr/lib/python3.6/contextlib.py", line 99, in __exit__ self.gen.throw(type, value, traceback) File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 82, in handle_runtime_error _raise(_exc) File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 54, in _raise exec("raise exc from None") File "<string>", line 1, in <module> ydk.errors.YServiceProviderError: application protocol error 2019-12-10 16:00:44,024 - ydk - INFO - Disconnected from device
What is wrong with this one?
12-10-2019 01:36 PM - edited 12-10-2019 02:33 PM
Could you please rerun this script with logging level DEBUG and attach the log to the post so I could understand why the YDK failed to get XE configuration.
Note. Because the filter for the NetconfService.get_config() is not specified, the YDK attempts to retrieve full configuration of the device. The returned result in this case is class Config instance, which is alias of EntityCollection class.
I do not understand, why later on you try to call codec.decode(), which expects as a parameter string value of payload. I guess you wanted to get result as XML and then print it. In this case the last operator should be:
xml_list = codec.encode(pr, config.entities(), pretty=True)
print("\nGOT DEVICE CONFIGURATION:\n%s" % '\n'.join(xml_list))
I executed such script on CiscoDevNet IOS XE sandbox router and got it working just fine (see attached log file)
12-11-2019 12:26 AM
12-11-2019 10:50 AM
Kirill
You get all python objects in the line:
config = netconf.get_config(provider, Datastore.running)
But they are placed into Config class, which is EntityCollection instance. Please check its API and use examples here. In order to get list of entities (python objects) simply run:
list_of_entities = config.entities()
12-11-2019 11:58 PM
Aha, got it. I've just looked into this object and I could discover these objects. This is really convenient.
12-11-2019 01:08 AM
But with XR it didn't work out.
The script
import logging from ydk.services import NetconfService, Datastore, CodecService from ydk.providers import NetconfServiceProvider, CodecServiceProvider logger = logging.getLogger('ydk') logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() formatter = logging.Formatter(("%(asctime)s - %(name)s - " "%(levelname)s - %(message)s")) handler.setFormatter(formatter) logger.addHandler(handler) DEVICES = { 'junos': { 'ip': '10.10.30.4', 'pass': 'Juniper' }, 'xr': { 'ip': '10.10.30.5', 'pass': 'admin' }, 'xe': { 'ip': '10.10.30.6', 'pass': 'admin' } } if __name__ == '__main__': device = DEVICES['xr'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) netconf = NetconfService() config = netconf.get_config(provider, Datastore.running) codec = CodecService() pr = CodecServiceProvider(type='xml') xml_list = codec.encode(pr, config.entities(), pretty=True) print('\nGOT DEVICE CONFIGURATION:\n{}'.format('\n'.join(xml_list)))
DEBUG is attached.
12-11-2019 11:15 AM
The YDK did receive device configuration, but then failed to convert it to entities due to error in this part of reply:
<vm xmlns="http://www.cisco.com/ns/yang/Cisco-IOS-XR-sysadmin-vm">
<config>
<memory>
<admin>0</admin>
<rp>0</rp>
<lc>0</lc>
</memory>
<cpu>
<assign/>
</cpu>
</config>
</vm>
In particular, it did not like that 'assign' has empty string value. However the model requires it to have some string value, which complies with the pattern:
ydk.errors.YModelError: Value "" does not satisfy the constraint "0(-[0-9]+)?/[0-9]+(-[0-9]+)?" (range, length, or pattern). Path: /Cisco-IOS-XR-sysadmin-vm:vm/config/cpu/assign
Most likely it is an error in the pattern (model error), but it could be a bug in Netconf server on the device, which should not include the 'assign' node into reply.
I am not sure if there is clean workaround for this issue in YDK. One kludgy way - manually change model in device repository in the way that it allows empty string for the 'assign' node.
12-11-2019 01:13 AM
12-11-2019 03:20 PM
Opened a bug YDK fails to decode RPC received from Juniper device.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide