I'm trying to instantiate a service through Maapi.
I am using this code.
from ncs import maapi
from ncs.application import Service
from ncs.dp import Action
import _ncs.error
class ApplyTemplate(Action):
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
self.log.info('invoke action %s with template %s' % (name, input.name))
def apply_template(t, i):
template = ncs.template.Template(t, i.context_node)
vars = ncs.template.Variables()
for v in i.variable:
vars.add(v.name, v.value)
template.apply(i.name, vars)
do_apply = False
m = maapi.Maapi()
if uinfo.actx_thandle != -1:
# When invoked from the CLI we get a transaction
# Note: unless we are in configure mode it will be read-only
m.attach2(0, 0, uinfo.actx_thandle)
trans = maapi.Transaction(m, uinfo.actx_thandle)
else:
# Start write transaction and apply it at end
trans = m.start_write_trans(usid=uinfo.usid)
do_apply = True
try:
apply_template(trans, input)
except _ncs.error.Error as e:
if e.confd_errno == ncs.ERR_NOT_WRITABLE:
# Happens when invoked from the CLI and not in configure mode,
# assume user wants us to start a separate transaction and
# apply the template there.
m.detach(uinfo.actx_thandle)
trans = m.start_write_trans(usid=uinfo.usid)
do_apply = True
apply_template(trans, input)
else:
raise e
if do_apply:
trans.apply()I found this project on Github.
#https://github.com/NSO-developer/apply-config-template
The code runs without error however when I enter the CLI no service has been created.
Likewise, I am a bit confused on what you are attempting to do.
Generally, templates are generated from the CDB config schema (device config, service instance config, etc.) that you want to parameterize and applied via the template.apply mechanism. Applying the template sets the CDB config specified in the template in you transaction. Applying the transaction, then commits those changes.
Although it seems feasible via some python code, I've not seen a case where the config template is generated 'on-the-fly' and then applied in an action execution, and certainly haven't seen any maapi methods for that specifically.
In your code below - 'i.name' will be the name the template ('i.name'.xml filename) expected to be found in your packages/<service>/template directory:
template.apply(i.name, vars)
Here's an example of applying a template in a transaction:
@Action.action
def cb_action(self, uinfo, name, kp, input, output):
self.log.info('action name: ', name)
# open read/write transaction
with ncs.maapi.single_write_trans('admin', 'UP') as t:
vars = ncs.template.Variables()
vars.add('DEVICE', input.device)
vars.add('HNAME', input.hname)
vars.add('DNAME', input.dname)
# when calling a template it needs a context node, normally, for a service
# this is the service node. Here we want context to point to devices tree...
root = ncs.maagic.get_root(t)
context_node = root.ncs__devices
# create a Template object, passing in the context node
tmpl = ncs.template.Template(context_node)
# apply the template.
tmpl.apply('tempBar-template', vars)
# commit transaction including template config changes
t.apply()
$ cat tempBar-template.xml
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<devices xmlns="http://tail-f.com/ns/ncs">
<device>
<name>{$DEVICE}</name>
<config>
<!-- juniper stuff -->
<configuration xmlns="http://xml.juniper.net/xnm/1.1/xnm">
<system>
<host-name>{$HNAME}</host-name>
<domain-name>{$DNAME}</domain-name>
</system>
</configuration>
<!-- juniper stuff -->
</config>
</device>
</devices>
</config-template>