01-24-2020 01:59 PM
Hello developers,
I'm coming back with the old problem of referencing different types of interfaces (ex. 'Ethernet' and 'GigabitEthernet' on devices. However in my current deployment I have the same interface type ('Ethernet') on different device types, served by different NEDs (Cisco Nexus and Arista, in my case), and for both I would like to get a list of available Ethernet interfaces.
So, if we apply the same type of solution as usually posted here (choice + condition), we end up with somethink like that:
container interface { tailf:cli-add-mode; choice choice_interface { case nexus { leaf-list NX_Ethernet { when "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:module[1]/ncs:name='tailf-ned-cisco-nx'"; tailf:cli-list-syntax; type leafref { path "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:config/nx:interface/nx:Ethernet/nx:name"; } } } case arista { leaf-list AR_Ethernet { when "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:module[1]/ncs:name='tailf-ned-arista-dcs'"; tailf:cli-list-syntax; type leafref { path "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:config/dcs:interface/dcs:Ethernet/dcs:name"; } } } } }
The code works pretty fine, exept the fact the interface names ('AR_Ethernet' and 'NX_Ethernet') do not reflect real interface names (which is 'Ethernet' in both cases), because we can't have the same object name at the same hierarchy level:
TMPL AC RSL_t4 dc 20900 ports access-leaf AR_LEAF131 interface AR_Ethernet 3 ! ! ! ! dc 24246 ports access-leaf NX_LEAF111 interface NX_Ethernet 1/1 ! ! ! ! ! !
So another solution came to me: add another container hierarchy level, hide those objects with 'tailf:cli-drop-node-name', and insert 'Ethernet' leaf-lists below:
container interface { choice choice_interface { case nexus { container NX_Ethernet { tailf:cli-drop-node-name; when "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:module[1]/ncs:name='tailf-ned-cisco-nx'"; leaf-list Ethernet { tailf:cli-list-syntax; type leafref { path "/ncs:devices/ncs:device[ncs:name=current()/../../../node]/ncs:config/nx:interface/nx:Ethernet/nx:name"; } } } } case arista { container AR_Ethernet { tailf:cli-drop-node-name; when "/ncs:devices/ncs:device[ncs:name=current()/../../node]/ncs:module[1]/ncs:name='tailf-ned-arista-dcs'"; leaf-list Ethernet { tailf:cli-list-syntax; type leafref { path "/ncs:devices/ncs:device[ncs:name=current()/../../../node]/ncs:config/dcs:interface/dcs:Ethernet/dcs:name"; } } } } } }
This one allows to configure objects in a desired way (by just referencing 'interface Ethernet xxx' in both cases):
rslaski@ncs(config)# show conf TMPL AC RSL_t4 dc 20900 ports access-leaf AR_LEAF131 interface Ethernet 3 ! ! ! dc 24246 ports access-leaf NX_LEAF111 interface Ethernet 1/1 ! ! ! ! !
However inside the xpath we have those intermediate objects ('AR_Ethernet', and 'NX_Ethernet') visible, so I have to change a lot with all the code I have written so far:
rslaski@ncs(config)# show full-configuration TMPL AC RSL_t4 | display xpath /TMPL/AC[name='RSL_t4']/dc[dc-id='20900']/ports/access-leaf[node='AR_LEAF131']/interface/AR_Ethernet/Ethernet [ 3 ] /TMPL/AC[name='RSL_t4']/dc[dc-id='24246']/ports/access-leaf[node='NX_LEAF111']/interface/NX_Ethernet/Ethernet [ 1/1 ]
So my question: is there another, more elegant solution to this problem?
thanks,
robert
01-29-2020 04:55 AM
01-29-2020 09:26 AM
No super good ideas.
One thing that might be interesting, if you use a lot of xpath, is the | operator that joins two node-sets - so if you have two alternatives you can merge them together. Depending on what you do that may simplify your logic.
01-30-2020 04:30 AM
You may try to move your restriction deeper into the leaf-list. One option may be to make the leaf-list type a union of leafrefs; but that requires YANG 1.1 plus I am not sure how much it is supported by NSO.
Another option, if you are willing to give up leafref, is to type the leaf-list as plain string and then validate it; for validation you can use a bit complex must statement like
leaf-list interface {
type string;
must "deref(../node)/../ncs:config/nx:interface/nx:Ethernet[nx:name = current()]" +
"or deref(../node)/../ncs:config/dcs:interface/dcs:Ethernet[dcs:name = current()]";
}
I’m not sure about the performance though, especially if the leaf-list may have many instances. If that becomes a problem, you may resort to custom validation callbacks.
01-31-2020 07:43 AM
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