Policy package prototype
Yang
module policy {
yang-version 1.1;
namespace "http://example.com/policy";
prefix policy;
import tailf-common { prefix tailf; }
import tailf-ncs { prefix ncs; }
description "Per-device prefix-set + route-policy with comma-separated prefixes.";
revision 2025-07-18 { description "Final version using prefix-set-template.xml"; }
list policy {
key name;
uses ncs:service-data;
ncs:servicepoint "policy-servicepoint";
leaf name { type string; }
list device {
key device-name;
min-elements 1;
leaf device-name {
type leafref { path "/ncs:devices/ncs:device/ncs:name"; }
}
list prefix-set {
key name;
leaf name { type string; }
leaf prefixes {
type string;
mandatory true;
tailf:info "Comma-separated prefixes (e.g. 10.0.0.0/24,10.1.0.0/24)";
}
}
list route-policy {
key name;
min-elements 1;
description "At least one route-policy required per device.";
leaf name { type string; }
leaf prefix-set-ref {
type leafref { path "../../prefix-set/name"; }
mandatory true;
}
}
}
}
}
python
# -*- mode: python; python-indent: 4 -*-
import ncs
from ncs.application import Service, Application
class ServiceCallbacks(Service):
@Service.create
def cb_create(self, tctx, root, service, proplist):
self.log.info(f"Service create: {service.name}")
tmpl = ncs.template.Template(service)
for dev in service.device:
dev_name = dev.device_name
self.log.info(f"Processing device: {dev_name}")
# === prefix-set: split by comma, apply existing template ===
for ps in dev.prefix_set:
ps_name = ps.name
prefixes = [p.strip() for p in ps.prefixes.split(',') if p.strip()]
for prefix in prefixes:
vars_ps = ncs.template.Variables()
vars_ps.add('DEVICE_NAME', dev_name)
vars_ps.add('PS_NAME', ps_name)
vars_ps.add('PREFIX', prefix)
tmpl.apply('prefix-set-template', vars_ps)
# === route-policy ===
for rp in dev.route_policy:
ps_name = rp.prefix_set_ref
definition = f"""if destination in {ps_name} then
pass
else
drop
endif"""
vars_rp = ncs.template.Variables()
vars_rp.add('DEVICE_NAME', dev_name)
vars_rp.add('RP_NAME', rp.name)
vars_rp.add('DEFINITION', definition)
tmpl.apply('route-policy-template', vars_rp)
class Policy(Application):
def setup(self):
self.log.info('Policy package RUNNING')
self.register_service('policy-servicepoint', ServiceCallbacks)
def teardown(self):
self.log.info('Policy package STOPPING')