cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2760
Views
10
Helpful
5
Replies

Conditional when statament xml

Trying to create a conditional if(when) with xml, if one loopack then create one loopback else create two loopbacks.

 

 

 

--xml---

 

<Loopback when="{int_mount='one_loopback'}">
<name>{$loopback_id_1}</name>
<ip-vrf>
<ip>
<vrf>
<forwarding>{/vrf_id}</forwarding>
</vrf>
</ip>
</ip-vrf>
<ip>
<address>
<primary>
<address>{$loopback_ip_1}</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>

<Loopback when="{int_mount='two_loopback'}">
<name>{$loopback_id_2}</name>
<ip-vrf>
<ip>
<vrf>
<forwarding>{/vrf_id}</forwarding>
</vrf>
</ip>
</ip-vrf>
<ip>
<address>
<primary>
<address>{$loopback_ip_2}</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>


</interface>

 

 

 

 

 

----Yang--


leaf int_mount {
tailf:info "VPN Type";
type enumeration {
enum one_loopback;
enum two_loopback;
}
mandatory true;
}

 

 

--Python--

 

 

# Creating a template object for the ipvpn service object, which is used for applying the templates
template = ncs.template.Template(service)
# Creating a variables object to store variables to use for templates
variables = ncs.template.Variables()

 

 

self.log.info('Apply template for loopback')
template.apply('loopback-template', variables)

 

 

 

2 Accepted Solutions

Accepted Solutions

There are certain limitations to the Python ternary expression (a = x if b else y) - e.g. it cannot contain elif.

but this is just one way to assign value to the string representing the template name. You can come up with many other ways to go about it.

 

Haaaaving said that, this doesn't seem to me as a good approach altogether.

If I understand correctly, the templates you're using for each loopback have the exact same structure.

and having more and more of those looks like code duplication, which should be avoided.

 

Instead, consider using a list in YANG for the loopbacks, which will contain the loopback number and the information you need for configuring it.

Then you can iterate that list - either in python - apply the template per each iteration, after setting the variables for the current loopback.

Or, you can also iterate the list on the XML template itself - depending on how complex is the logic you need for each loopback.

(I tend to prefer only very simple logic in XML, as it's harder to debug and to maintain, and instead move the logic to python)

View solution in original post

I'd use the debug template to definitively see what is going on when the template is applied:

commit dry-run | debug template.

 

View solution in original post

5 Replies 5

yfherzog
Cisco Employee
Cisco Employee

You didn't mention what's not working (is something not working?).

Are you setting values to loopback_id_1/2 in your python code?

Trying debugging with commit dry-run | debug template

Yes, I am setting values in python code.

 

And manage to provide two options in yang which gives the user possibility to create one or two interfaces. The issue that I m facing now is to allow the user to create more than two interfaces. 

 

 So, for instance, if I have 3x xml templates,   the first one has one loopback en the second has two, etc. I tried to use elif but is not working.

 

Working statement:

template.apply('one_loopback-template' if service.evc_mount == 'one_loopback' else 'two_loopback-template' , variables)

 

 

Not working statement:(Aborted: no registration found for callpoint loopback-servicepoint/service_create of type=external)

template.apply('one_loopback-template' if service.evc_mount == 'one_loopback' elif 'two_loopback-template' else 'three_loopback-template' , variables).

 

Tried also to do the same solution in xml with:  when="{int_mount='one_loopback'}" to loop through one loopback in the xml

 

and when="{int_mount='two_loopback'}"   loop through one and two etc.

 

 

Regards,

 

Bashar

 

 

 

There are certain limitations to the Python ternary expression (a = x if b else y) - e.g. it cannot contain elif.

but this is just one way to assign value to the string representing the template name. You can come up with many other ways to go about it.

 

Haaaaving said that, this doesn't seem to me as a good approach altogether.

If I understand correctly, the templates you're using for each loopback have the exact same structure.

and having more and more of those looks like code duplication, which should be avoided.

 

Instead, consider using a list in YANG for the loopbacks, which will contain the loopback number and the information you need for configuring it.

Then you can iterate that list - either in python - apply the template per each iteration, after setting the variables for the current loopback.

Or, you can also iterate the list on the XML template itself - depending on how complex is the logic you need for each loopback.

(I tend to prefer only very simple logic in XML, as it's harder to debug and to maintain, and instead move the logic to python)

 

 

I tried the foreach function in xml,  is not matching, see  config and debug:

 

 

list interface {
tailf:info "loopback_mount";
key intf-type;
leaf intf-type {
type enumeration {
enum lp01;
enum lp02;
}
}

 

 

<interface xmlns="urn:ios" foreach="{interface}">
<Loopback when="{intf-type='lp01'}">
<name>48</name>
<ip-vrf>
<ip>
<vrf>
<forwarding>{/vrf_id}</forwarding>
</vrf>
</ip>
</ip-vrf>
<ip>
<address>
<primary>
<address>1.1.1.1</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>

<Loopback when="{intf-type='lp02'}">
<name>48</name>
<ip-vrf>
<ip>
<vrf>
<forwarding>{/vrf_id}</forwarding>
</vrf>
</ip>
</ip-vrf>
<ip>
<address>
<primary>
<address>1.1.1.1</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>

<Loopback>
<name>49</name>
<ip-vrf>
<ip>
<vrf>
<forwarding>{/vrf_id}</forwarding>
</vrf>
</ip>
</ip-vrf>
<ip>
<address>
<primary>
<address>2.2.2.2</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>

 

 

debug:

 

admin@ncs(config-interface-mount01)# commit dry-run | debug xpath
2020-07-19T18:09:26.733 xpath: evaluating: /services/vpn_03:vpn_03[vrf_id='88']/device: /ncs:devices/ncs:device/ncs:name
2020-07-19T18:09:26.733 xpath: exists(/devices/device[name='ios0']) = true
2020-07-19T18:09:26.734 xpath: result: /services/vpn_03:vpn_03[vrf_id='88']/device: true [0.000 sec]
2020-07-19T18:09:26.742 xpath: template vpn_03-template: evaluating: /device
2020-07-19T18:09:26.742 xpath: template vpn_03-template: match: /services/vpn_03:vpn_03[vrf_id='88']/device[.='ios0']: ios0
2020-07-19T18:09:26.742 xpath: template vpn_03-template: result: one node [0.000 sec]
2020-07-19T18:09:26.743 xpath: template vpn_03-template: evaluating: interface
2020-07-19T18:09:26.743 xpath: template vpn_03-template: result: no nodes [0.000 sec]
2020-07-19T18:09:26.748 xpath: evaluating: /services/vpn_03:vpn_03[vrf_id='88']/device: /ncs:devices/ncs:device/ncs:name
2020-07-19T18:09:26.748 xpath: exists(/devices/device[name='ios0']) = true
2020-07-19T18:09:26.748 xpath: result: /services/vpn_03:vpn_03[vrf_id='88']/device: true [0.000 sec]
cli {
local-node {
data services {
+ vpn_03 88 {
+ device [ ios0 ];
+ interface evc01;
+ }
}
}

 

 

I'd use the debug template to definitively see what is going on when the template is applied:

commit dry-run | debug template.