Showing results for 
Search instead for 
Did you mean: 
Cisco Employee

foreach loop using python variable in nso template

I have a 'python-and-template' service package called dummy
Is it possible to run a foreach loop in the template using a variable passed from python

Here is my template. Note the variable $ACL_RULES in the template:

<config-template xmlns="">
<devices xmlns="" foreach="{/devices}">
<ip xmlns="urn:ios">
<?foreach {$ACL_RULES}?>

and here is the file:


# -*- mode: python; python-indent: 4 -*-
import ncs
from ncs.application import Service

class ServiceCallbacks(Service):
def cb_create(self, tctx, root, service, proplist):'Service create(service=', service._path, ')')

vars = ncs.template.Variables()
vars.add('ACL_RULES', service.acl_rules)
template = ncs.template.Template(service)
template.apply('dummy-template', vars)

class Main(ncs.application.Application):
def setup(self):'Main RUNNING')
self.register_service('dummy-servicepoint', ServiceCallbacks)
def teardown(self):'Main FINISHED')

service.acl_rules is type leaf-list from yang.

But when i do a package reload from the ncs cli i am getting the following error:


[dummy-template.xml:11 Invalid parameters for processing instruction foreach.]


I my case i could have directly used the yang leaf list called acl_rules, but i want to use the python variable ACL_RULES.

Is there a way iteration can be done in template using python variable?

Cisco Employee

Unfortunately, you cannot process a Python list (or Java) in a template variable - $ACL_RULES.


Recall that in the interface from code (Python, Java) the variable passed is a simple _STRING_.. not a data structure of any kind.  Since you can use various languages for your create_cb/action_cb it would require an interesting design to handle list structures from each of the languages to input into variable.

As you point out, if the acl_rules are a list in the service yang, the template processing can take knowledge of it being a list and loop on the available entries in the list. 

Generally, you would loop in your python code and apply the same template with the $ACL_RULE set to a single item in the list.

It is possible from your python code, although may not be worth the work, to write your ACL_RULES into a list in CDB, and then have your template point to the new list (instead of the list in the service) or change context at that point in the template to point at your new list. Then you could use the same for-each for that list.