11-12-2019 01:38 AM
Guys,
Here's a newbie problem. In my NSO inventory there are a number of switches, let's say ten:
rslaski@ncs# show running-config devices device | include hostname nx:hostname LEAF1111 nx:hostname LEAF1112 nx:hostname LEAF1113 nx:hostname LEAF1114 nx:hostname LEAF1115 nx:hostname LEAF1116 nx:hostname LEAF2221 nx:hostname LEAF2222 nx:hostname LEAF2223 nx:hostname LEAF2224
These devices then needs to be allocated to different DCs, so I have a 'datacenter' dictionary configured, which contains 'dc' list, which in turn contains 'leaf' list:
container datacenters { list dc { key dc-id; leaf dc-id { type uint32 { } } list leaf { key name; leaf name { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } } } }
In my example four devices have been allocated to 'dc 111', and two to 'dc 222':
datacenters dc 111 leaf-node LEAF1111 ! leaf-node LEAF1112 ! leaf-node LEAF1113 ! leaf-node LEAF1114 ! ! dc 222 leaf-node LEAF2221 ! leaf-node LEAF2222
Now inside my RSL namespace module in SRV hierarchy I've created L2 network service that should be applicable to a subset of devices in one particular DC:
container SRV { list L2 { uses ncs:service-data; ncs:servicepoint "L2"; key name; leaf name { tailf:info "L2 service name"; type string; } list dc { key dc-id; leaf dc-id { type leafref { path "/RSL:datacenters/dc/dc-id"; } } container ports { list access-leaf { key node; leaf node { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } } } } } }
And the sample service configuration follows:
SRV L2 test2 dc 111 ports access-leaf LEAF1111 access-leaf LEAF1112
Now I would like to apply constraints so that both:
- YANG model valiates that the device referenced in the service model in a particular dc has been referenced in dc dictionary
- NSO command completion displays only devices relevant to the particular dc
Without any constraints, any device can be used for a service:
rslaski@ncs# config t Entering configuration mode terminal rslaski@ncs(config)# TMPL L2 test2 syntax error: unknown command rslaski@ncs(config-L2-test2)# dc 111 rslaski@ncs(config-dc-111)# ports rslaski@ncs(config-ports)# access-leaf ? Possible completions: LEAF1111 LEAF1112 LEAF1113 LEAF1114 LEAF1115 LEAF1116 LEAF2221 LEAF2222 LEAF2223 LEAF2224
In above example I need to add validation stuff that would limit the devices to the devices present only in 'dc 111':
rslaski@ncs(config-ports)# access-leaf ? Possible completions: LEAF1111 LEAF1112 LEAF1113 LEAF1114
I've tried applying various 'when' and 'tailf:display-when' conditions to "SRV / L2 / dc / ports / access-leaf / node" but I got stuck. Any ideas to help me with that?
thanks,
robert
Solved! Go to Solution.
11-12-2019 03:32 AM
Hi,
You can do this with must expressions, but perhaps it is easiest to tweak your leafref paths.
You have "/devices/device/name" as the target for the leaf 'node' -
leaf node { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } }
This is too broad, as you experienced. You can constrain it to only those devices that are used inside a dc, like so:
leaf node { type leafref { path "deref(../../../dc-id)/../leaf/name"; } }
The 'deref' statement "dereferences" the path that it's argument points to. In this case, you are dereferencing the 'dc-id' leaf, which in turn points to /datacenters/dc. Now you have the particular datacenter instance, and from there, you can refer to the "leaf"s in that instance.
/Ram
11-12-2019 03:20 AM
Not sure if there is a neater way to do this, but you should be able to achieve the effect you are after by setting a "must" constraint under the "node" leaf in the SRV container. The constraint would require the value of the current node to match a deref path that points to the list of leaf names defined within the DC.
I think the leaf configuration would end up looking something like the below:
leaf node { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } must "current() = deref(../../../dc-id)/../leaf/name" }
The deref statement follows the path statement in dc-id, and we then navigate from there to find the list of device names within that dc. If the value of the current node does not match one of these names, YANG validation will fail.
If the models are in different modules, you will also need to import the module with the datacenters container into the SRV module. You would also need to prefix "leaf" and "name" in the must constraint with the module name, otherwise you will get a YANG error when you try to make the package.
11-12-2019 03:32 AM
Hi,
You can do this with must expressions, but perhaps it is easiest to tweak your leafref paths.
You have "/devices/device/name" as the target for the leaf 'node' -
leaf node { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } }
This is too broad, as you experienced. You can constrain it to only those devices that are used inside a dc, like so:
leaf node { type leafref { path "deref(../../../dc-id)/../leaf/name"; } }
The 'deref' statement "dereferences" the path that it's argument points to. In this case, you are dereferencing the 'dc-id' leaf, which in turn points to /datacenters/dc. Now you have the particular datacenter instance, and from there, you can refer to the "leaf"s in that instance.
/Ram
11-13-2019 11:23 AM
Yes, this solution works. The other one is also good one, however it's two line code compared to single one ;-)
Thanks a lot!
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