12-06-2019 06:50 AM
Hello.
I'm experimenting with ydk-examples from https://github.com/CiscoDevNet/ydk-py-samples and got stuck in something.
I'm trying to deploy this config on XRv9K
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)
I get this:
2019-12-06 17:40:48,225 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.5 2019-12-06 17:40:48,234 - ydk - INFO - Connected to 10.10.30.5 on port 830 using ssh with timeout of -1 2019-12-06 17:40:48,234 - ydk - INFO - Executing CRUD create operation on [openconfig-bgp:bgp] 2019-12-06 17:40:48,234 - ydk - INFO - Executing 'edit-config' RPC on [openconfig-bgp:bgp] 2019-12-06 17:40:48,285 - 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> <candidate/> </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:40:48,468 - ydk - INFO - ============= Received RPC from device ============= <?xml version="1.0"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <rpc-error> <error-type>protocol</error-type> <error-tag>unknown-namespace</error-tag> <error-severity>error</error-severity> <error-info> <bad-element>bgp</bad-element> <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace> </error-info> </rpc-error> </rpc-reply> 2019-12-06 17:40:48,469 - ydk - ERROR - RPC error occurred: <?xml version="1.0"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <rpc-error> <error-type>protocol</error-type> <error-tag>unknown-namespace</error-tag> <error-severity>error</error-severity> <error-info> <bad-element>bgp</bad-element> <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace> </error-info> </rpc-error> </rpc-reply> Traceback (most recent call last): File "openconfig_bgp.py", line 86, in <module> crud.create(provider, bgp) File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 112, in helper return func(self, provider, entity, *args, **kwargs) File "/usr/local/lib/python3.6/dist-packages/ydk/services/crud_service.py", line 49, in create return _crud_update(provider, entity, self._crud.create) File "/usr/local/lib/python3.6/dist-packages/ydk/services/crud_service.py", line 70, in _crud_update return crud_call(provider, entity) 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: RPC error occurred; check log file for details 2019-12-06 17:40:48,536 - ydk - INFO - Disconnected from device
If I set logging level to DEBUG I see that YDK is sending both base 1.0 and base 1.1 capabilities:
<?xml version="1.0" encoding="UTF-8"?> <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <capabilities> <capability>urn:ietf:params:netconf:base:1.0</capability> <capability>urn:ietf:params:netconf:base:1.1</capability> <capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability> <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability> <capability>urn:ietf:params:netconf:capability:startup:1.0</capability> <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability> </capabilities> </hello>
XRv9K sending only base 1.1 capability:
<capabilities> <capability>urn:ietf:params:netconf:base:1.1</capability> <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability> <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability> <capability>urn:ietf:params:netconf:capability:validate:1.1</capability> <capability>urn:ietf:params:netconf:capability:confirmed-commit:1.1</capability> <capability>urn:ietf:params:netconf:capability:notification:1.0</capability> <capability>urn:ietf:params:netconf:capability:interleave:1.0</capability>
So it is supposed that only 1.1 framing format is possible.
But in the output above I can see that YDK is sending edit-config RPC with base 1.0 namespace:
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
How can I fix that?
12-06-2019 09:31 AM
The issue is not related to YANG-1.1 support. Look at the error message:
ydk.errors.YServiceProviderError: RPC error occurred; check log file for details
And details in the log:
2019-12-06 17:40:48,468 - ydk - INFO - ============= Received RPC from device ============= <?xml version="1.0"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <rpc-error> <error-type>protocol</error-type> <error-tag>unknown-namespace</error-tag> <error-severity>error</error-severity> <error-info> <bad-element>bgp</bad-element> <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace> </error-info> </rpc-error> </rpc-reply>
This means that Netconf does not know how to translate 'bgp' node to router configuration commands.
I think that BGP on Cisco routers can be configured only by using Cisco proprietary YANG models. The Cisco routers do not support openconfig models for device configuration; these models can be used only for reading configuration.
12-06-2019 12:31 PM
I'll try to send the same RPC by hand tomorrow but for now, I am pretty confused about why YDK uses Netconf 1.0 framing to send RPC when the device said that it only capable of 1.0?!
12-06-2019 02:55 PM
As I understand the Netconf 1.0 and 1.1 uses the same framing; the version 1.1 just has some additional capabilities. More info about differences you can find here. Please do not confuse Netconf version and IETF YANG model namespaces. The last all have '*:base:1.0' namespaces defined in RFC 6241.
The CRUD and Netconf Services implementation in YDK currently use only Netconf 1.0 capabilities. However, the Netconf client, which is implemented in C and C++ code, does implement both 1.0 and 1.1 versions, meaning that the RPCs compliant with version 1.1 still can be successfully processed.
The YDK also includes Executor Service, which allows to build and execute RPCs based on ietf_netconf.yang model. That means, you can include into RPC any constructs defined in the model. You can find multiple examples of how to use Executor Service in unit tests included in ydk-gen repository.
12-10-2019 04:58 AM
Actually if I try to send RPC with ]]>]]> at the end XRv9k will close the session because of wrong framing.
The right way to do it in 1.1 is the following:
#85 <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="4"> <commit/> </rpc> ##
But any way it doesn't work I guess because XRv9K doesn't support openconfig-bgp model for the config =(
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