cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2538
Views
10
Helpful
11
Replies

How can I crud-read just specific deep nested class in the YDK hierarchy?

Anton Abik
Level 4
Level 4

My approach when writing some application for reading configuration of device is as follows:

  1. I create root object of the hierarchy. (as en example from Cisco_IOS_XR_infra_syslog_cfg module I create Syslog() )
  2. put the object to crud.read method as a parameter
  3. iterate / take what is needed from the crud read object output.

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

1 Accepted Solution

Accepted Solutions

abhirame
Cisco Employee
Cisco Employee

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()

View solution in original post

11 Replies 11

einarnn
Cisco Employee
Cisco Employee

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

abhirame
Cisco Employee
Cisco Employee

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