08-07-2024 02:57 PM - edited 08-07-2024 07:41 PM
Hello Cisco Community,
I’m currently working on an NSO project where I’m trying to manage network fabrics and devices using a service package. The goal is to create a fabric and have the service point code automatically populate the devices within the model using static data initially, with plans to integrate with Nautobot for dynamic device retrieval later on.
Overview
Our design involves creating a top-level service for the fabric, which is supposed to automatically create and configure associated devices as part of the service instantiation process. When we create a fabric, we expect the service point code to populate the devices within the model, based on static data or retrieved from Nautobot.
However, during a commit dry-run, we encounter an “empty node” error, indicating that the template variables for the devices are not being resolved correctly.
We are trying to determine if there is a way to implement this design effectively within NSO, or if there are limitations in the platform that prevent this approach.
Thank you for your support!YANG Model
module nfaas-fabric {
namespace "http://example.com/nfaas-fabric";
prefix nfaas-fab;
yang-version 1.1;
import ietf-inet-types {
prefix inet;
}
import tailf-ncs {
prefix ncs;
}
description "Fabric management for NFaaS";
revision 2024-07-29 {
description "Fabric management service.";
}
augment "/ncs:services" {
list fabric {
key "name";
leaf name {
type string;
description "Name of the fabric";
}
uses ncs:service-data;
ncs:servicepoint nfaas-fabric-servicepoint;
container devices {
list device {
key "name";
leaf name {
type string;
description "Name of the device";
}
leaf address {
type inet:ipv4-address;
description "Management IP address of the device";
}
leaf ned-id {
type string;
description "NED ID of the device";
}
}
}
}
}
}
Python Code
# -*- mode: python; python-indent: 4 -*-
import ncs
from ncs.application import Service
class NfaasFabricServiceCallbacks(Service):
.create
def cb_create(self, tctx, root, service, proplist):
self.log.info(f"Creating fabric: {service.name}")
# Static data for a single device
devices = [
{"name": "DLF03.FAB00.EWR00", "address": "10.0.0.10", "ned_id": "test"}
# More devices can be added here
]
# Iterate over each device and apply the template
for device in devices:
if device["name"] not in root.ncs__devices.device:
self.log.info(f"Device: {device}")
vars = ncs.template.Variables()
vars.add('device-name', device["name"])
vars.add('device-address', device["address"])
vars.add('device-ned-id', device["ned_id"])
self.log.info(f"Vars: {vars}")
template = ncs.template.Template(service)
template.apply('nfaas-fabric-template', vars)
self.log.info(f"Device {device['name']} added to fabric {service.name}")
else:
self.log.info(f"Device {device['name']} already exists in NSO")
class NfaasFabric(ncs.application.Application):
def setup(self):
self.log.info('NFaaS Fabric Service RUNNING')
self.register_service('nfaas-fabric-servicepoint', NfaasFabricServiceCallbacks)
def teardown(self):
self.log.info('NFaaS Fabric Service FINISHED')
XML Template
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<services xmlns="http://tail-f.com/ns/ncs">
<fabric xmlns="http://example.com/nfaas-fabric">
<name>{/name}</name> <!-- Ensure the context is set correctly for the 'name' -->
<devices>
<device tags="create">
<name>{device-name}</name>
<address>{device-address}</address>
<ned-id>{device-ned-id}</ned-id>
</device>
</devices>
</fabric>
</services>
</config-template>
CLI Output
admin@ncs# config
Entering configuration mode terminal
admin@ncs(config)# services fabric FAB00.EWR00
admin@ncs(config-fabric-FAB00.EWR00)# commit dry-run outformat xml | debug template nfaas-fabric-template
Evaluating "/name" (from file "nfaas-fabric-template.xml", line 4)
Context node: /services/nfaas-fab:fabric[name='FAB00.EWR00']
Result:
For /services/nfaas-fab:fabric[name='FAB00.EWR00'], it evaluates to "FAB00.EWR00"
Operation 'merge' on existing node: /services/nfaas-fab:fabric[name='FAB00.EWR00'] (from file "nfaas-fabric-template.xml", line 4)
Evaluating "device-name" (from file "nfaas-fabric-template.xml", line 7)
Context node: /services/nfaas-fab:fabric[name='FAB00.EWR00']
Result: empty node - skipping siblings
result-xml {
local-node {
data <services xmlns="http://tail-f.com/ns/ncs">
<fabric xmlns="http://example.com/nfaas-fabric">
<name>FAB00.EWR00</name>
</fabric>
</services>
}
}
admin@ncs(config-fabric-FAB00.EWR00)#
Solved! Go to Solution.
08-07-2024 08:19 PM
Resolved!
08-07-2024 08:19 PM
Resolved!
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide