cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2115
Views
10
Helpful
6
Replies

Best Practice: Is this example of stacked service

tsiemers1
Spotlight
Spotlight

Hello, Looking for some guidance if this is a good example of where to use a stacked service.  

We have a scenario where we have a service that pushes out l2vpn configuration. One of the requirements of the service is that the QoS policy maps are on the router. We have another service for QoS that we were pushing a this time separately.

Would this be a good use case of a stacked service? We would like to some how inside the l2vpn service call the qos service if the router doesn't have it and apply the qos config before the l2vpn config.

The QoS service config shouldn't be tied to to the l2vpn service since the QoS could be used by more than this one service.

If I was to create a stacked service that called the create on both the l2vpn service and QoS service would the QoS be created as its own service that isn't tied to the l2vpn config or the upper stacked service? If that makes sense. 

The scenario for the qos would be that in the future the qos might need to be updated for increased bandwidth and when we do a redeploy it should only affect the qos service data.

Otherwise we are at this point just using two api calls to call them one at a time from a front end.

Thanks

6 Replies 6

vleijon
Cisco Employee
Cisco Employee

Hi

 

I think that looks like a great example of when to use a stacked service.

 

Generally I would say that a lower service in a stacked service should be testable, so that it is meaningful to write test cases for it in isolation, and that certainly seems to be the case here. It should also be less abstract than the higher service, another condition that seems fulfilled here.

 

 

Does anybody have an updated examples of this. I must be missing something simple and not seeing anything in the examples or the guides.

I was trying to follow the example https://community.cisco.com/t5/nso-developer-hub-documents/nso-stacked-services-example/ta-p/3653190

but wasn't able to get it running.

Below is the example I was trying to run just to get an understanding but it will not accept the xml template.

When I do a reload I get the following error:

reload-result {
package stacked_parent
result false
info [stacked_parent-template.xml:4 Unknown element: 'stacked_child']

Am I referencing the stacked_child wrong in the stacked_parent template?

tree of the /var/opt/ncs/packages

tree -L 1 /var/opt/ncs/packages
├── stacked_child ├── stacked_parent

First Package (stacked_parent):

stacked_parent/
├── load-dir
│   └── stacked_parent.fxs
├── package-meta-data.xml
├── python
│   └── stacked_parent
│   ├── __init__.py
│   └── main.py
├── README
├── src
│   ├── java
│   │   └── src
│   ├── Makefile
│   └── yang
│   └── stacked_parent.yang
├── templates
│   └── stacked_parent-template.xml

Yang:

module stacked_parent {

  namespace "http://example.com/stacked_parent";
  prefix stacked_parent;

  import ietf-inet-types {
    prefix inet;
  }
  import tailf-common {
    prefix tailf;
  }
  import tailf-ncs {
    prefix ncs;
  }

  description
    "Bla bla...";

  revision 2016-01-01 {
    description
      "Initial revision.";
  }

  list stacked_parent {
    description "This is an RFS skeleton service";

    key name;
    leaf name {
      tailf:info "Unique service id";
      tailf:cli-allow-range;
      type string;
    }

    uses ncs:service-data;
    ncs:servicepoint stacked_parent-servicepoint;

    // may replace this with other ways of refering to the devices.
    leaf-list device {
      type leafref {
        path "/ncs:devices/ncs:device/ncs:name";
      }
    }

    // replace with your own stuff here
    leaf pmap {
      type string;
    }
    leaf description {
      type string;
    }
  }
}

Template:

<config-template xmlns="http://tail-f.com/ns/config/1.0"
   servicepoint="stacked_parent-servicepoint">
  <services xmlns="http://tail-f.com/ns/ncs">
    <stacked_child xmls="http://example.com/stacked_child">
      <name>stackedtest</name>
      <pmap>{/pmap}</pmap>
      <description>{/description}</description>
    </stacked_child>
  </services>
</config-template>

Second Package (stacked_child)

stacked_child/
├── load-dir
│   └── stacked_child.fxs
├── package-meta-data.xml
├── python
│   └── stacked_child
│   ├── __init__.py
│   └── main.py
├── README
├── src
│   ├── java
│   │   └── src
│   ├── Makefile
│   └── yang
│   └── stacked_child.yang
├── templates
│   └── stacked_child-template.xml

Yang:

module stacked_child {

  namespace "http://example.com/stacked_child";
  prefix stacked_child;

  import ietf-inet-types {
    prefix inet;
  }
  import tailf-common {
    prefix tailf;
  }
  import tailf-ncs {
    prefix ncs;
  }

  description
    "Bla bla...";

  revision 2016-01-01 {
    description
      "Initial revision.";
  }

  list stacked_child {
    description "This is an RFS skeleton service";

    key name;
    leaf name {
      tailf:info "Unique service id";
      tailf:cli-allow-range;
      type string;
    }

    uses ncs:service-data;
    ncs:servicepoint stacked_child-servicepoint;

    // may replace this with other ways of refering to the devices.
    leaf-list device {
      type leafref {
        path "/ncs:devices/ncs:device/ncs:name";
      }
    }

    // replace with your own stuff here
    leaf pmap {
      type string;
    }
    leaf description {
      type string;
    }
  }
}

Template:

<config-template xmlns="http://tail-f.com/ns/config/1.0">
  <devices xmlns="http://tail-f.com/ns/ncs">
    <device>
      <name>{/device}</name>
      <config>
        <policy-map xmlns="urn:ios">
          <name>{/pmap}</name>
          <description>{/description}</description>
        </policy-map>
      </config>
    </device>
  </devices>
</config-template>

Seems as your template is looking for stacked child under /services, while in the stacked child yang model, it's a list directly under root.

 

You can just create an instance of stacked child and do: show run path to stacked child | display xml (or show conf | display xml, before committing the instance), and then use that as the starting point to your template.

 

Edit: noticed now that you already mentioned it on a later reply.

lightfep1
Level 1
Level 1

We included our policy that is tied to the customer's service as part of the service deployment. This allows for cleaner add's and removals as customer services come and go. This way when the last service is removed using that policy it will be removed from the route, this is helping with keeping the router configs cleaner. This was a problem we had before we started automating this process.   

 

If you are looking at a parent/child Policy map style you could put part in it's own "service" or template and control it from there and then only include the part that controls the bandwidth or is specific to the customer's service in the l2vpn deployment. 

 

Even if it is part of the service, as soon as you update the template, the next time you deploy it on that router the policy will be updated or you can do a "touch" on an existing service to have it update. 

tsiemers1
Spotlight
Spotlight

Thanks. I will give the stacked service a try.

Thanks for the replies. Had to remove the xml line

 

<services xmlns="http://tail-f.com/ns/ncs"

and reference the child service directly since I wasn't using "

augment /ncs:services {

in the yang.

 

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the NSO Developer community: