cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1214
Views
25
Helpful
2
Replies

Template foreach not working as expected

Steven Li
Level 1
Level 1

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?

1 Accepted Solution

Accepted Solutions

ramkraja
Cisco Employee
Cisco Employee

                 <?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

 

View solution in original post

2 Replies 2

ramkraja
Cisco Employee
Cisco Employee

                 <?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

 

Thanks, this helped me a lot.