My approach when writing some application for reading configuration of device is as follows:
So far this worked for me. I hit the wall when I want to take all routes (dynamic/static/connected) and its next hop from Cisco_IOS_XR_ip_rib_ipv4_oper model. My LAB XR has 10 000 routes across several VRFs. When I create the Rib() root object from rib oper model and pass it to crud read method, it takes 10 minutes to take the output. And the output contains lots of information I dont actually need. What I need is just all the routes from all VRFs and its next hops, nothing more. Is it somehow possible to get just these? I tried to go down the Cisco_IOS_XR_ip_rib_ipv4_oper hiearchy and just pass to crud.read the deep nested object (Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName.Routes.
Route
). But I always hit the exception (attachment). Or is there some other approach how to accomplish that the XR device will not send me all the info in Cisco_IOS_XR_ip_rib_ipv4_oper model and just the routes and its next hop?
Thanks a lot for all inputs
Solved! Go to Solution.
Basically, when using nested classes with lists as parents, you need to populate the keys for the parent lists. Try the below:
Note: You may need a workaround for the error mentioned here: CRUD read error on Cisco_IOS_XR_ip_rib_ipv4_oper
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ip_rib_ipv4_oper
from ydk.providers import NetconfServiceProvider
rib = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib()
vrf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf()
vrf.vrf_name='default'
af = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af()
af.af_name = 'IPv4'
saf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf()
saf.saf_name='Unicast'
table_name = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName()
table_name.route_table_name = 'default'
route = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName.Routes.Route()
route.address='0.0.0.0'
table_name.routes.route.append(route)
saf.ip_rib_route_table_names.ip_rib_route_table_name.append(table_name)
af.safs.saf.append(saf)
vrf.afs.af.append(af)
rib.vrfs.vrf.append(vrf)
provider = NetconfServiceProvider(address="10.33.94.147",
port=830,
username="admin",
password="admin",
protocol="ssh",
timeout = 600)
# create CRUD service
crud = CRUDService()
rib_oper = crud.read(provider, route)
print(rib_oper)
provider.close()
Anton,
Can you provide your sample code also?
Cheers,
Einar
Thanks a lot! You can find the code in attachment.
PS: I tried many combinations to pass just the final Route() class to crud.read function. During that I noticed that I can go down to class till I hit the YList type. For example in Cisco_IOS_XR_ip_rib_ipv4_oper this works OK: rib_oper = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf(). But when I try to pass to method this: rib_oper = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs() then I got the same exception
Basically, when using nested classes with lists as parents, you need to populate the keys for the parent lists. Try the below:
Note: You may need a workaround for the error mentioned here: CRUD read error on Cisco_IOS_XR_ip_rib_ipv4_oper
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ip_rib_ipv4_oper
from ydk.providers import NetconfServiceProvider
rib = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib()
vrf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf()
vrf.vrf_name='default'
af = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af()
af.af_name = 'IPv4'
saf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf()
saf.saf_name='Unicast'
table_name = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName()
table_name.route_table_name = 'default'
route = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName.Routes.Route()
route.address='0.0.0.0'
table_name.routes.route.append(route)
saf.ip_rib_route_table_names.ip_rib_route_table_name.append(table_name)
af.safs.saf.append(saf)
vrf.afs.af.append(af)
rib.vrfs.vrf.append(vrf)
provider = NetconfServiceProvider(address="10.33.94.147",
port=830,
username="admin",
password="admin",
protocol="ssh",
timeout = 600)
# create CRUD service
crud = CRUDService()
rib_oper = crud.read(provider, route)
print(rib_oper)
provider.close()
Hi,
thanks a lot for your inputs! I tested the code you pasted and still it takes about 10 minutes and the device is sending everything it has for that model I am sharing with you the code and also the output. I little bit filtered just the routes and some other stuff. But you can see it collects everything, routes from every VRF, etc...
Any other ideas are highly welcome
Thanks for attaching your script, Anton. Looks like you are still using the top level object as the filter used for crud.read. Can you try changing the crud.read call to the below?
rib = crud.read(provider, route)
Ahhh my mistake, thanks a lot your code is working like charm :-) Hopefully I can have one last annoying Q on this
Is it possible to take all route addresses from specific VRF? I was able to achieve this by creating the "whole" Route() object but that contains lots of information I dont actually need (attribute_identity, client_id, diversion,...) as I need just the address parameter. I was lookin for some "wildcard" like route.address = "*" but I dont think such exist
Thanks a lot for your support
You're in luck as a wild card for all route addresses is available . If we just do not set the route address, it fetches all the routes.
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ip_rib_ipv4_oper
from ydk.providers import NetconfServiceProvider
rib = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib()
vrf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf()
vrf.vrf_name='default'
af = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af()
af.af_name = 'IPv4'
saf = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf()
saf.saf_name='Unicast'
table_name = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName()
table_name.route_table_name = 'default'
route = Cisco_IOS_XR_ip_rib_ipv4_oper.Rib.Vrfs.Vrf.Afs.Af.Safs.Saf.IpRibRouteTableNames.IpRibRouteTableName.Routes.Route()
#route.address='0.0.0.0' # Do not set the route address
table_name.routes.route.append(route)
saf.ip_rib_route_table_names.ip_rib_route_table_name.append(table_name)
af.safs.saf.append(saf)
vrf.afs.af.append(af)
rib.vrfs.vrf.append(vrf)
provider = NetconfServiceProvider(address="localhost",
port=1220,
username="admin",
password="admin",
protocol="ssh",
timeout = 600)
# create CRUD service
crud = CRUDService()
rib_oper = crud.read(provider, route)
print(rib_oper)
provider.close()
Yep but this fetches also all information from the whole Route() object and I want just the address from all routes No wildcard for that?
IIRC, set the address of the Route object to an instance of the special type “ydk.types.Empty”
Cheers,
Einar
Thank you guys!! Its not Empty type but READ() type. But you kind of lead me to it
Ok, good! Sorry, I got the wrong type