08-15-2019 10:53 PM
I have created service model to test template <?foreach {expression}?>...<?end?>:
The service yang:
list ST{ key "ovc"; uses ncs:service-data; ncs:servicepoint "ST-servicepoint"; leaf ovc { type string; tailf:info "ST service ID"; mandatory true; } leaf device { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } tailf:info "Device name"; mandatory true; } leaf interfaceId { type string; tailf:info "Interface ID"; } list unit { key "logicalInterfaceId"; leaf logicalInterfaceId { type string; tailf:info "Logical interface ID"; } } }
Config template:
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="ST-servicepoint"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>{/device}</name> <config> <configuration xmlns="http://xml.juniper.net/xnm/1.1/xnm"> <interfaces> <interface> <name>{/interfaceId}</name> <?foreach {/unit}?> <unit> <name>{/unit/logicalInterfaceId}</name> <description>{/unit/logicalInterfaceId}</description> <vlan-tags> <outer>{/unit/logicalInterfaceId}</outer> <inner>{/unit/logicalInterfaceId}</inner> </vlan-tags> <encapsulation>vlan-ccc</encapsulation> </unit> <?end?> </interface> </interfaces> </configuration> </config> </device> </devices> </config-template>
Test data:
{ "ST:ST": { "ovc": "ST001", "device": "j2", "interfaceId": "xe-0/0/2", "unit": [{"logicalInterfaceId":"1"}, {"logicalInterfaceId":"2"}, {"logicalInterfaceId":"3"}] } }
Config result:
admin@ncs# show running-config devices device j2 config junos:configuration interfaces interface xe-0/0/2 devices device j2 config junos:configuration interfaces interface xe-0/0/2 unit 1 description 123 encapsulation vlan-ccc vlan-tags outer 123 vlan-tags inner 123 ! unit 2 description 123 encapsulation vlan-ccc vlan-tags outer 123 vlan-tags inner 123 ! unit 3 description 123 encapsulation vlan-ccc vlan-tags outer 123 vlan-tags inner 123 ! ! ! !
The above result is not what I expected.
The expected result is:
admin@ncs# show running-config devices device j2 config junos:configuration interfaces interface xe-0/0/2 devices device j2 config junos:configuration interfaces interface xe-0/0/2 unit 1 description 1 encapsulation vlan-ccc vlan-tags outer 1 vlan-tags inner 1 ! unit 2 description 2 encapsulation vlan-ccc vlan-tags outer 2 vlan-tags inner 2 ! unit 3 description 3 encapsulation vlan-ccc vlan-tags outer 3 vlan-tags inner 3 ! ! ! !
What is wrong?
Solved! Go to Solution.
08-16-2019 01:52 AM
<?foreach {/unit}?> <unit> <name>{/unit/logicalInterfaceId}</name> <description>{/unit/logicalInterfaceId}</description> <vlan-tags> <outer>{/unit/logicalInterfaceId}</outer> <inner>{/unit/logicalInterfaceId}</inner> </vlan-tags> <encapsulation>vlan-ccc</encapsulation> </unit> <?end?>
Hello,
Your foreach expression is "/unit". This means that the context for xpath expressions used within the foreach expression will be at the "unit" list. So, inside the foreach expression, you should use only the key leaf's name to refer to the key value in the service model - ie., just
<name>{logicalInterfaceId}</name>
instead of
<name>{/unit/logicalInterfaceId}</name>
The way you have it now, it will get the key values of *all* the instances, and concatenate them to get the value for the expression. This is what you see.
Pro Tip: You can use the "debug template" pipe flag to see exactly what is done when applying a template. ie., do "commit dry-run | debug template" or "commit | debug template", and you can follow what NSO does when you apply a template.
/Ram
08-16-2019 01:52 AM
<?foreach {/unit}?> <unit> <name>{/unit/logicalInterfaceId}</name> <description>{/unit/logicalInterfaceId}</description> <vlan-tags> <outer>{/unit/logicalInterfaceId}</outer> <inner>{/unit/logicalInterfaceId}</inner> </vlan-tags> <encapsulation>vlan-ccc</encapsulation> </unit> <?end?>
Hello,
Your foreach expression is "/unit". This means that the context for xpath expressions used within the foreach expression will be at the "unit" list. So, inside the foreach expression, you should use only the key leaf's name to refer to the key value in the service model - ie., just
<name>{logicalInterfaceId}</name>
instead of
<name>{/unit/logicalInterfaceId}</name>
The way you have it now, it will get the key values of *all* the instances, and concatenate them to get the value for the expression. This is what you see.
Pro Tip: You can use the "debug template" pipe flag to see exactly what is done when applying a template. ie., do "commit dry-run | debug template" or "commit | debug template", and you can follow what NSO does when you apply a template.
/Ram
11-11-2019 11:51 AM
Thanks, this helped me 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