12-11-2019 04:41 AM
I'm trying to configure BGP on Juniper vMX 19.2R1.8 using one of the examples in YDK repo:
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.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' } } 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, bgp)) device = DEVICES['junos'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) crud = CRUDService() crud.create(provider, bgp)
But it fails with the following exception:
2019-12-11 14:45:18,263 - ydk - ERROR - Path 'openconfig-bgp:bgp' is invalid 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.YInvalidArgumentError: Path is invalid: openconfig-bgp:bgp
Full DEBUG is in the attachments.
Solved! Go to Solution.
12-24-2019 02:46 PM
Here is the error:
2019-12-24 16:07:22,933 - ydk - ERROR - Data is invalid according to the yang model. Libyang error: Invalid keyword "[1-9][0-9]{1,2}|[1-9])|\*)"".
This is the same as this. It appears because Juniper incorrectly used escape character '\*' when modified the pattern string from original standard openconfig model. The correct use of escape character would be '\\*' or put the pattern string in single quotes. Although it is not YDK issue, I have added escape of this combination in our fork of Libyang. Please recompile the core YDK library and python package to get corrected version of Libyang and then repeat your script.
cd ydk-gen
python3 generate.py --core --cpp -is
python3 generate.py --core --python -is
12-14-2019 08:23 PM
The analysis of debug log showed that YDK (libyang) failed to parse openconfig-yang-types.yang module.
2019-12-11 14:45:18,261 - ydk - DEBUG - Path found with revision: /home/horseinthesky/.ydk/10.10.30.4/openconfig-yang-types.yang
2019-12-11 14:45:18,261 - ydk - ERROR - Data is invalid according to the yang model. Libyang error: Invalid keyword "[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}"".
2019-12-11 14:45:18,261 - ydk - ERROR - Data is invalid according to the yang model. Libyang error: Module "openconfig-yang-types" parsing failed.
That is actually the libyang defect, which I opened and then resolved in the fork specific for YDK.
Please recompile the libydk and try to run the script again:
cd ydk-gen
./generate.py --core --cpp -is
./generate.py --core -is
12-15-2019 05:28 AM
12-15-2019 09:31 AM
It is device configuration error:
2019-12-15 16:22:17,926 - ydk - DEBUG - Netconf SSH Client: processing reply
2019-12-15 16:22:17,926 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0"?>
<nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
<nc:rpc-error>
<nc:error-type>protocol</nc:error-type>
<nc:error-tag>operation-failed</nc:error-tag>
<nc:error-severity>error</nc:error-severity>
<nc:error-message>
No type match found for union for node neighbor-address
</nc:error-message>
</nc:rpc-error>
<nc:rpc-error>
<nc:error-type>protocol</nc:error-type>
<nc:error-tag>operation-failed</nc:error-tag>
<nc:error-severity>error</nc:error-severity>
<nc:error-message>neighbor-address: '2001:db8:e:1::1': invalid value</nc:error-message>
<nc:error-info>
<nc:bad-element>2001:db8:e:1::1</nc:bad-element>
</nc:error-info>
</nc:rpc-error>
<load-error-count>1</load-error-count>
</nc:rpc-reply>
Seems like Netconf did not understand IPv6 address.
The YDK worked perfectly well.
12-23-2019 02:06 AM
JTAC answered to me:
I have discussed this issue with Engineering team. The recommandation is to start using openconfig-network-instances here because starting from 18.4R1 there have been certain changes. Network instance based BGP neighbor PATH should be used. This helps identify whgich VRF or global instance BGP neighbor belongs, which older version of OCST model was premature and did not provide this capability. "I tried this XML-RPC and it worked fine on latest Junos. <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <edit-config> <target> <candidate></candidate> </target> <config> <network-instances xmlns="http://openconfig.net/yang/network-instance"> <network-instance> <name>d</name> <protocols> <protocol> <identifier>bgp</identifier> <name>bgp</name> <bgp> <neighbors> <neighbor> <neighbor-address>10.10.30.6</neighbor-address> </neighbor> </neighbors> </bgp> </protocol> </protocols> </network-instance> </network-instances> </config> </edit-config> </rpc>
I tried to do it like this:
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_network_instance as oc_ni from ydk.models.openconfig import openconfig_bgp_types as oc_bgp_types from ydk.filters import YFilter from devices import DEVICES 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) def config_bgp(bgp): """Add config data to bgp object.""" # global configuration bgp.global_.config.as_ = 5 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 = 6 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 = '10.10.30.6' neighbor.config.neighbor_address = '10.10.30.6' neighbor.config.peer_group = "EBGP" bgp.neighbors.neighbor.append(neighbor) if __name__ == '__main__': # provider = CodecServiceProvider(type='xml') # codec = CodecService() bgp = oc_ni.NetworkInstances.NetworkInstance.Protocols.Protocol.Bgp() # bgp.yfilter = YFilter.replace config_bgp(bgp) # print(codec.encode(provider, bgp)) device = DEVICES['junos'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) crud = CRUDService() crud.create(provider, bgp)
But got the following exception:
2019-12-23 13:06:11,205 - ydk - DEBUG - Trace: Password authentication (host 10.10.30.4, user admin) 2019-12-23 13:06:11,288 - ydk - DEBUG - Trace: Writing message (session ): <?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> 2019-12-23 13:06:11,776 - ydk - DEBUG - Trace: Received message (session ): <!-- No zombies were killed during the creation of this user interface --> <!-- user admin, class j-super-user --> <nc:hello xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:capabilities> <nc:capability>urn:ietf:params:netconf:base:1.0</nc:capability> <nc:capability>urn:ietf:params:netconf:capability:candidate:1.0</nc:capability> <nc:capability>urn:ietf:params:netconf:capability:confirmed-commit:1.0</nc:capability> <nc:capability>urn:ietf:params:netconf:capability:validate:1.0</nc:capability> <nc:capability>urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file</nc:capability> <nc:capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01</nc:capability> <nc:capability>urn:ietf:params:xml:ns:netconf:capability:candidate:1.0</nc:capability> <nc:capability>urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0</nc:capability> <nc:capability>urn:ietf:params:xml:ns:netconf:capability:validate:1.0</nc:capability> <nc:capability>urn:ietf:params:xml:ns:netconf:capability:url:1.0?scheme=http,ftp,file</nc:capability> <nc:capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15</nc:capability> <nc:capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</nc:capability> <nc:capability>http://xml.juniper.net/netconf/junos/1.0</nc:capability> <nc:capability>http://xml.juniper.net/dmi/system/1.0</nc:capability> </nc:capabilities> <nc:session-id>59296</nc:session-id> </nc:hello> 2019-12-23 13:06:11,776 - ydk - DEBUG - NetconfSSHClient: NC session status: 1 2019-12-23 13:06:11,776 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.4 2019-12-23 13:06:11,776 - ydk - DEBUG - Creating libyang context in path: /home/horseinthesky/.ydk/10.10.30.4 2019-12-23 13:06:11,776 - ydk - DEBUG - [libyang] Extension plugin "/usr/local/lib/libyang/libyang_ext_test.so" successfully loaded. 2019-12-23 13:06:11,777 - ydk - DEBUG - [libyang] Extension plugin "/usr/local/lib/libyang/metadata.so" successfully loaded. 2019-12-23 13:06:11,777 - ydk - DEBUG - [libyang] Extension plugin "/usr/local/lib/libyang/nacm.so" successfully loaded. 2019-12-23 13:06:11,777 - ydk - DEBUG - [libyang] Reading module "ietf-yang-metadata". 2019-12-23 13:06:11,777 - ydk - DEBUG - [libyang] Module "ietf-yang-metadata@2016-08-05" successfully parsed as implemented. 2019-12-23 13:06:11,778 - ydk - DEBUG - [libyang] Reading module "yang". 2019-12-23 13:06:11,778 - ydk - DEBUG - [libyang] Resolving "yang" unresolved schema nodes and their constraints... 2019-12-23 13:06:11,778 - ydk - DEBUG - [libyang] All "yang" schema nodes and constraints resolved. 2019-12-23 13:06:11,778 - ydk - DEBUG - [libyang] Module "yang@2017-02-20" successfully parsed as implemented. 2019-12-23 13:06:11,779 - ydk - DEBUG - [libyang] Reading module "ietf-inet-types". 2019-12-23 13:06:11,779 - ydk - DEBUG - [libyang] Resolving derived type "union" failed, it will be attempted later. 2019-12-23 13:06:11,779 - ydk - DEBUG - [libyang] Resolving derived type "union" failed, it will be attempted later. 2019-12-23 13:06:11,779 - ydk - DEBUG - [libyang] Resolving derived type "union" failed, it will be attempted later. 2019-12-23 13:06:11,779 - ydk - DEBUG - [libyang] Resolving derived type "union" failed, it will be attempted later. 2019-12-23 13:06:11,780 - ydk - DEBUG - [libyang] Resolving "ietf-inet-types" unresolved schema nodes and their constraints... 2019-12-23 13:06:11,780 - ydk - DEBUG - [libyang] All "ietf-inet-types" schema nodes and constraints resolved. 2019-12-23 13:06:11,780 - ydk - DEBUG - [libyang] Module "ietf-inet-types@2013-07-15" successfully parsed as implemented. 2019-12-23 13:06:11,781 - ydk - DEBUG - [libyang] Reading module "ietf-yang-types". 2019-12-23 13:06:11,781 - ydk - DEBUG - [libyang] Module "ietf-yang-types@2013-07-15" successfully parsed as implemented. 2019-12-23 13:06:11,781 - ydk - DEBUG - [libyang] Reading module "ietf-datastores". 2019-12-23 13:06:11,781 - ydk - DEBUG - [libyang] Module "ietf-datastores@2017-08-17" successfully parsed as implemented. 2019-12-23 13:06:11,782 - ydk - DEBUG - [libyang] Reading module "ietf-yang-library". 2019-12-23 13:06:11,783 - ydk - DEBUG - [libyang] Module "ietf-yang-library@2017-08-17" successfully parsed as implemented. 2019-12-23 13:06:11,783 - ydk - DEBUG - Loading module 'ydk', revision '2016-02-26' 2019-12-23 13:06:11,783 - ydk - DEBUG - Getting module 'ydk' submodule 'none' 2019-12-23 13:06:11,783 - ydk - DEBUG - Looking for file in folder: /home/horseinthesky/.ydk/10.10.30.4 2019-12-23 13:06:11,783 - ydk - DEBUG - Opening file '/home/horseinthesky/.ydk/10.10.30.4/ydk@2016-02-26.yang' 2019-12-23 13:06:11,783 - ydk - DEBUG - Path found with revision: /home/horseinthesky/.ydk/10.10.30.4/ydk@2016-02-26.yang 2019-12-23 13:06:11,785 - ydk - DEBUG - [libyang] Module "ydk@2016-02-26" successfully parsed as implemented. 2019-12-23 13:06:11,785 - ydk - DEBUG - Loading module 'ietf-netconf', revision '2011-06-01' 2019-12-23 13:06:11,785 - ydk - DEBUG - Getting module 'ietf-netconf' submodule 'none' 2019-12-23 13:06:11,786 - ydk - DEBUG - Looking for file in folder: /home/horseinthesky/.ydk/10.10.30.4 2019-12-23 13:06:11,786 - ydk - DEBUG - Opening file '/home/horseinthesky/.ydk/10.10.30.4/ietf-netconf@2011-06-01.yang' 2019-12-23 13:06:11,786 - ydk - DEBUG - Path found with revision: /home/horseinthesky/.ydk/10.10.30.4/ietf-netconf@2011-06-01.yang 2019-12-23 13:06:11,787 - ydk - DEBUG - [libyang] Module "ietf-netconf@2011-06-01" successfully parsed as implemented. 2019-12-23 13:06:11,787 - ydk - DEBUG - Populating new module schema 'ietf-yang-metadata' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'yang' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ietf-inet-types' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ietf-yang-types' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ietf-datastores' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ietf-yang-library' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ydk' 2019-12-23 13:06:11,788 - ydk - DEBUG - Populating new module schema 'ietf-netconf' 2019-12-23 13:06:11,788 - ydk - INFO - Connected to 10.10.30.4 on port 830 using ssh with timeout of -1 2019-12-23 13:06:11,788 - ydk - INFO - Executing CRUD create operation on [bgp] 2019-12-23 13:06:11,788 - ydk - INFO - Executing 'edit-config' RPC on [bgp] Traceback (most recent call last): File "test.py", line 74, 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.YInvalidArgumentError: ancestor for entity cannot be nullptr as one of the ancestors is a list. Path: bgp 2019-12-23 13:06:11,861 - ydk - INFO - Disconnected from device 2019-12-23 13:06:11,863 - ydk - DEBUG - Trace: Writing message (session 59296): <?xml version="1.0" encoding="UTF-8"?> <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <close-session/> </rpc> 2019-12-23 13:06:11,877 - ydk - DEBUG - Trace: Received message (session 59296): <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <nc:ok/> </nc:rpc-reply>
12-23-2019 10:14 AM - edited 12-23-2019 10:32 AM
That is expected result, because you missed building of network_instance and protocol lists. Besides, you need to start building python object from the top level entity to assure proper child-parent relationships in the entity hierarchy. It should be something like this:
nis = oc_ni.NetworkInstances()
ni = oc_ni.NetworkInstances.NetworkInstance() # list element has 1 key
ni.name = 'default' # must define network instance key
nis.network_instance.append(ni) # must add network instance to the list
pr = oc_ni.NetworkInstances.NetworkInstance.Protocols.Protocol() # list element has 2 keys
pr.name = 'BGP-5' # must define protocol key
from ydk.models.openconfig import openconfig_policy_type as oc_policy
pr.identifier = oc_policy.BGP() # must define protocol key
ni.protocols.protocol.append(pr) # must add protocol to the list
# Also need to define protocol.config attributes
pr.config.name = 'BGP-5'
pr.config.identifier = oc_policy.BGP()
pr.config.enabled = True
bgp = pr.bgp # bgp is attribute of protocol and has already been instantiated above
config_bgp(bgp)
# Sanity check before CRUD operation (could be skipped)
codec_provider = CodecServiceProvider(type='xml')
codec = CodecService()
nis_xml = codec.encode(codec_provider, nis)
# Then in actual router configuration you can use non-top level entity 'bgp'
# or top level entity 'nis'; the Netconf RPC will be the same.
When building entities, I strongly suggest you to learn better corresponding model bundle API. You can learn it directly from source or leverage existing documentation.
12-24-2019 05:09 AM
Ok, using CodecService I was able to build the RPC:
<network-instances xmlns="http://openconfig.net/yang/network-instance"> <network-instance> <name>default</name> <protocols> <protocol> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>BGP-5</name> <config> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>BGP-5</name> <enabled>true</enabled> </config> <bgp> <global> <config> <as>5</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>10.10.30.6</neighbor-address> <config> <peer-group>EBGP</peer-group> <neighbor-address>10.10.30.6</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>6</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> </protocol> </protocols> </network-instance> </network-instances>
Seems valid.
The full script:
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_network_instance as oc_ni from ydk.models.openconfig import openconfig_policy_types as oc_policy from ydk.models.openconfig import openconfig_bgp_types as oc_bgp_types from ydk.filters import YFilter from devices import DEVICES 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) def config_bgp(bgp): """Add config data to bgp object.""" # global configuration bgp.global_.config.as_ = 5 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 = 6 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 = '10.10.30.6' neighbor.config.neighbor_address = '10.10.30.6' neighbor.config.peer_group = "EBGP" bgp.neighbors.neighbor.append(neighbor) if __name__ == '__main__': nis = oc_ni.NetworkInstances() ni = oc_ni.NetworkInstances.NetworkInstance() # list element has 1 key ni.name = 'default' # must define network instance key nis.network_instance.append(ni) # must add network instance to the list pr = oc_ni.NetworkInstances.NetworkInstance.Protocols.Protocol() # list element has 2 keys pr.name = 'BGP-5' # must define protocol key pr.identifier = oc_policy.BGP() # must define protocol key ni.protocols.protocol.append(pr) # must add protocol to the list # Also need to define protocol.config attributes pr.config.name = 'BGP-5' pr.config.identifier = oc_policy.BGP() pr.config.enabled = True bgp = pr.bgp # bgp is attribute of protocol and has already been instantiated above config_bgp(bgp) # codec = CodecService() # pr = CodecServiceProvider(type='xml') # print(codec.encode(pr, nis)) device = DEVICES['junos'] provider = NetconfServiceProvider( address=device['ip'], port=830, username='admin', password=device['pass'], protocol='ssh' ) crud = CRUDService() crud.create(provider, nis)
But it fails before sending RPC. DEBUG is attached.
12-24-2019 02:46 PM
Here is the error:
2019-12-24 16:07:22,933 - ydk - ERROR - Data is invalid according to the yang model. Libyang error: Invalid keyword "[1-9][0-9]{1,2}|[1-9])|\*)"".
This is the same as this. It appears because Juniper incorrectly used escape character '\*' when modified the pattern string from original standard openconfig model. The correct use of escape character would be '\\*' or put the pattern string in single quotes. Although it is not YDK issue, I have added escape of this combination in our fork of Libyang. Please recompile the core YDK library and python package to get corrected version of Libyang and then repeat your script.
cd ydk-gen
python3 generate.py --core --cpp -is
python3 generate.py --core --python -is
12-25-2019 12:28 AM
I've checked openconfig repo for https://github.com/openconfig/public/blob/master/release/models/vlan/openconfig-vlan-types.yang
It is updated on the 20th of April and RFC7950, Chapter 6.1.3 isn't there still.
Your fix made it able to send the RPC but it's behavior is similar to CSR1000v: it accepts it and sends ok as a reply.
2019-12-25 11:17:56,676 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.4 2019-12-25 11:17:56,686 - ydk - INFO - Connected to 10.10.30.4 on port 830 using ssh with timeout of -1 2019-12-25 11:17:56,686 - ydk - INFO - Executing CRUD create operation on [openconfig-network-instance:network-instances] 2019-12-25 11:17:56,687 - ydk - INFO - Executing 'edit-config' RPC on [openconfig-network-instance:network-instances] 2019-12-25 11:17:56,814 - 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><network-instances xmlns="http://openconfig.net/yang/network-instance" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="merge"> <network-instance> <name>default</name> <protocols> <protocol> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>BGP-5</name> <config> <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier> <name>BGP-5</name> <enabled>true</enabled> </config> <bgp> <global> <config> <as>5</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>10.10.30.6</neighbor-address> <config> <peer-group>EBGP</peer-group> <neighbor-address>10.10.30.6</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>6</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> </protocol> </protocols> </network-instance> </network-instances> </config> </edit-config> </rpc> 2019-12-25 11:17:57,253 - ydk - INFO - ============= Received RPC from device ============= <?xml version="1.0"?> <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1"> <nc:ok/> </nc:rpc-reply> 2019-12-25 11:17:57,253 - ydk - INFO - Executing 'commit' RPC 2019-12-25 11:17:57,254 - ydk - INFO - ============= Sending RPC to device ============= <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><commit xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/> </rpc> 2019-12-25 11:17:58,110 - ydk - INFO - ============= Received RPC from device ============= <?xml version="1.0"?> <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2"> <nc:ok/> </nc:rpc-reply> 2019-12-25 11:17:58,110 - ydk - INFO - Operation succeeded 2019-12-25 11:17:58,118 - ydk - INFO - Disconnected from device
But it creates this section pf config:
root> show configuration openconfig-network-instance:network-instances network-instance default { protocols { protocol oc-pol-types:BGP BGP-5 { config { identifier BGP; name BGP-5; enabled true; ## Warning: 'enabled' is deprecated } bgp { global { config { as 5; } afi-safis { afi-safi oc-bgp-types:IPV6_UNICAST { config { afi-safi-name IPV6_UNICAST; enabled true; } } } } neighbors { neighbor 10.10.30.6 { config { peer-group EBGP; neighbor-address 10.10.30.6; } } } peer-groups { peer-group EBGP { config { peer-group-name EBGP; peer-as 6; } transport { config { local-address Loopback0; } } afi-safis { afi-safi oc-bgp-types:IPV6_UNICAST { config { afi-safi-name IPV6_UNICAST; enabled true; } } } } } } } } }
And I don't know how to use it
root> show bgp summary BGP is not running
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