What You’ll Learn

What You’ll Need

The NSO service that this tutorial will use as an example is the SVI Verify Example. It is already installed on the system install server (10.10.20.49) in the reservable Sandbox. The main parts of the service YANG model are as follows:

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

    key name;
    leaf name {
      tailf:info "Unique service id";
      tailf:cli-allow-range;
      type string;
    }
    // gives us linkage to selftest
    uses selftest:selftest-result;
    uses ncs:service-data;
    ncs:servicepoint svi_verify_example-servicepoint;
  
   list switches {
        key "id";
        leaf id{
          tailf:info "Switches identifier";
          type string;
        }
        leaf switch-device {
          mandatory true;
          type leafref {
            path "/ncs:devices/ncs:device/ncs:name";
          }
        }
      }
   list firewalls {
        key "id";
        leaf id{
          tailf:info "firewalls identifier";
          type string;
        }
        leaf firewall-device {
          mandatory true;
          type leafref {
            path "/ncs:devices/ncs:device/ncs:name";
          }
        }
      }
      
      leaf vlan-id {
        type uint16;
        mandatory true;
      }
      leaf vlan-name{
        type string;
        mandatory true;
      }

  }
}

Basically, there are two sets of devices that will be configured in the service:

Another two values that are required to make the SVI service work are a VLAN ID and a VLAN name. These input values are then fed into the configuration template:

<config-template xmlns="http://tail-f.com/ns/config/1.0">
  <devices xmlns="http://tail-f.com/ns/ncs">
    <?foreach {/switches}?>
    <device>
      <name>{switch-device}</name>
      <config>
        <vlan xmlns="http://tail-f.com/ned/cisco-nx">
          <vlan-list>
            <id>{/vlan-id}</id>
            <name>{/vlan-name}</name>
          </vlan-list>
        </vlan>
        <interface xmlns="http://tail-f.com/ned/cisco-nx">
          <Vlan>
            <name>{/vlan-id}</name>
            <description>{/vlan-name}</description>
            <ip>
              <address>
                <ipaddr>172.16.107.2/24</ipaddr>
              </address>
              <redirects>false</redirects>
              <router>
                <ospf>
                  <name>1</name>
                  <area>0.0.0.0</area>
                </ospf>
              </router>
            </ip>
            <ipv6>
              <redirects>false</redirects>
            </ipv6>
            <hsrp>
              <hsrp-list>
                <id>10</id>
                <addr_type>ipv4</addr_type>
                <ip>
                  <address>172.16.107.1</address>
                </ip>
              </hsrp-list>
            </hsrp>
          </Vlan>
        </interface>
      </config>
    </device>
    <?end?>    <!-- end foreach {/endpoint} -->
  </devices>


  <devices xmlns="http://tail-f.com/ns/ncs">
    <?foreach {/firewalls}?>
    <device>
      <name>{firewall-device}</name>
      <config>
        <object xmlns="http://cisco.com/ned/asa">
          <network>
            <name>INSIDE-{/vlan-name}</name>
            <subnet>
              <address>172.16.107.0</address>
              <mask>255.255.255.0</mask>
            </subnet>
          </network>
        </object>
        <object-group xmlns="http://cisco.com/ned/asa">
          <network>
            <id>INSIDE-NETWORKS</id>
            <network-object>
              <id>object INSIDE-{/vlan-name}</id>
            </network-object>
          </network>
        </object-group>
      </config>
    </device>
    <?end?>    <!-- end foreach {/endpoint} -->
  </devices>
</config-template>

A couple of things to be aware of in the template are:

NSO services act as the blueprint for deploying and maintaining configuration. The available inputs to define the service are structured by the YANG model. Depending on which service is deployed in your instance, the inputs and structure of the service will be different.

The easiest way to explore an NSO service after looking at the YANG model and template is to explore in the NSO CLI. It is easier because the NSO CLI mimics the IOS CLI that network engineers are used to using and can use the interactive prompt with the ? to see the available options.

Configuring the CLI

Once you log into the NSO reservable Sandbox system install server (10.10.20.49), enter the NSO CLI and the configuration mode:

ncs_cli
conf

Because the name of the service is svi_verify_example, you will start with that command, with the input first-instance. Even though it is an open string field, it is a best practice to have the service instances named as something clear so that at a glance the configuration purpose is clear. Next, the required input vlan-id has a sample value of 1337, and the required input vlan-name has a sample value of SVI-DEMO.

developer@ncs(config)# svi_verify_example first-instance vlan-id ?
Possible completions:
  <unsignedShort>
developer@ncs(config)# svi_verify_example first-instance vlan-id 1337 vlan-name ?
Possible completions:
  <string>
developer@ncs(config)# svi_verify_example first-instance vlan-id 1337 vlan-name SVI-DEMO
developer@ncs(config-svi_verify_example-first-instance)#

While you are still in the first-instance CLI subtree (developer@ncs(config-svi_verify_example-first-instance)), you can add the switches.

developer@ncs(config-svi_verify_example-first-instance)# ?
Possible completions:
  check-sync           Check if device config is according to
                       the service
  commit-queue
  deep-check-sync      Check if device config is according to
                       the service
  firewalls
  get-modifications    Get the data this service created
  log
  re-deploy            Run/Dry-run the service logic again
  reactive-re-deploy   Reactive re-deploy of service logic
  switches
  touch                Mark the service as changed
  un-deploy            Undo the effects of the service
  vlan-id
  vlan-name
  ---
  commit               Commit current set of changes
  describe             Display transparent command information
  exit                 Exit from current mode
  help                 Provide help information
  no                   Negate a command or set its defaults
  pwd                  Display current mode path
  rload                Load configuration from an ASCII file or
                       from terminal, relative to current
                       location
  top                  Exit to top level and optionally run
                       command
developer@ncs(config-svi_verify_example-first-instance)#

Because the switches input is a list, define the unique key for the YANG list with something memorable and easy to identify like switches first-sw:

developer@ncs(config-svi_verify_example-first-instance)# switches ?
Possible completions:
  Switches identifier

The leaf-ref referring to the device list is called switch-device, so after inputting that, you will notice a list of all the devices in the device list if you do a ?. You can use tab complete to type in the name of dist-sw01:

developer@ncs(config-svi_verify_example-first-instance)# switches first-sw ?
Possible completions:
  switch-device  <cr>
developer@ncs(config-svi_verify_example-first-instance)# switches first-sw switch-device ?
Possible completions:
  core-rtr01       core-rtr02  dist-rtr01
  dist-rtr02       dist-sw01   dist-sw02
  edge-firewall01  edge-sw01   internet-rtr01
developer@ncs(config-svi_verify_example-first-instance)# switches first-sw switch-device dist-sw01
developer@ncs(config-switches-first-sw)#

Now you will need to go up one layer in the CLI tree to add a second switch to the service instance list. If you ever forget where you are within the CLI structure, you can use the pwd command; use that command and exit to go up one layer to add a second switch:

developer@ncs(config-switches-first-sw)# pwd
Current submode path:
  svi_verify_example first-instance \ switches first-sw
developer@ncs(config-switches-first-sw)# exit
developer@ncs(config-svi_verify_example-first-instance)# switches second-sw switch-device dist-sw02
developer@ncs(config-switches-second-sw)#

Just like before, to add the firewalls, you will need to type exit to go up one layer and enter in one or more firewalls. In this example, you will just add edge-firewall01:

developer@ncs(config-switches-second-sw)# exit
developer@ncs(config-svi_verify_example-first-instance)# firewalls first-fw firewall-device edge-firewall01
developer@ncs(config-firewalls-first-fw)#

Now you can issue a commit dry-run outformat native to see all the commands that will be sent to the devices:

developer@ncs(config-firewalls-first-fw)# commit dry-run outformat native
native {
    device {
        name dist-sw01
        data vlan 1337
              name SVI-DEMO
             !
             interface Vlan1337
              no shutdown
              description SVI-DEMO
              ip address 172.16.107.2/24
              no ip redirects
              ip router ospf 1 area 0.0.0.0
              no ipv6 redirects
              hsrp 10 ipv4
               ip 172.16.107.1
              exit
             exit
    }
    device {
        name dist-sw02
        data vlan 1337
              name SVI-DEMO
             !
             interface Vlan1337
              no shutdown
              description SVI-DEMO
              ip address 172.16.107.2/24
              no ip redirects
              ip router ospf 1 area 0.0.0.0
              no ipv6 redirects
              hsrp 10 ipv4
               ip 172.16.107.1
              exit
             exit
    }
    device {
        name edge-firewall01
        data forward-reference enable
             object network INSIDE-SVI-DEMO
              subnet 172.16.107.0 255.255.255.0
             exit
             object-group network INSIDE-NETWORKS
              network-object object INSIDE-SVI-DEMO
             !
             no forward-reference enable
    }
}
developer@ncs(config-firewalls-first-fw)#

Finally, to actually send the commands to the devices, issue a commit and end to go back to the enable level:

developer@ncs(config-firewalls-first-fw)# commit
Commit complete.
developer@ncs(config-firewalls-first-fw)# end
developer@ncs#

One of the more powerful features of NSO is interacting with existing services, whether that is updating it or removing it.

First, you can verify the service is present by issuing a show running-config svi_verify_example command:

developer@ncs# show running-config svi_verify_example
svi_verify_example first-instance
 switches first-sw
  switch-device dist-sw01
 !
 switches second-sw
  switch-device dist-sw02
 !
 firewalls first-fw
  firewall-device edge-firewall01
 !
 vlan-id   1337
 vlan-name SVI-DEMO
!
developer@ncs#

To modify a service instance, go into the conf mode and enter the svi_verify_example first-instance subtree.

developer@ncs# conf
Entering configuration mode terminal
developer@ncs(config)# svi_verify_example first-instance
developer@ncs(config-svi_verify_example-first-instance)# vlan-id 777
developer@ncs(config-svi_verify_example-first-instance)# commit dry-run outformat native
native {
    device {
        name dist-sw01
        data no vlan 1337
             vlan 777
              name SVI-DEMO
             !
             no interface Vlan1337
             interface Vlan777
              no shutdown
              description SVI-DEMO
              ip address 172.16.107.2/24
              no ip redirects
              ip router ospf 1 area 0.0.0.0
              no ipv6 redirects
              hsrp 10 ipv4
               ip 172.16.107.1
              exit
             exit
    }
    device {
        name dist-sw02
        data no vlan 1337
             vlan 777
              name SVI-DEMO
             !
             no interface Vlan1337
             interface Vlan777
              no shutdown
              description SVI-DEMO
              ip address 172.16.107.2/24
              no ip redirects
              ip router ospf 1 area 0.0.0.0
              no ipv6 redirects
              hsrp 10 ipv4
               ip 172.16.107.1
              exit
             exit
    }
}
developer@ncs(config-svi_verify_example-first-instance)#

Notice that this time, the ASA configuration did not change, because changing the VLAN ID had no impact on the ASA configuration. Go ahead and commit that change and end.

developer@ncs(config-svi_verify_example-first-instance)# commit
Commit complete.
developer@ncs(config-svi_verify_example-first-instance)# end
developer@ncs#

Update the values of vlan-id to 777, but keep the VLAN name the same.

Removing an NSO Service Instance

Removing an NSO service instance is similar to removing IOS configuration. You simply put a no command in front of the command.

Enter in conf mode and enter a no svi_verify_example first-instance to remove your service instance and all the configuration associated with it. See the configuration being removed before committing with a commit dry-run outformat native:

developer@ncs#
developer@ncs# conf
Entering configuration mode terminal
developer@ncs(config)# no svi_verify_example ?
Possible completions:
  first-instance  <cr>
developer@ncs(config)# no svi_verify_example first-instance
developer@ncs(config)# commit dry-run outformat native
native {
    device {
        name dist-sw01
        data no vlan 777
             no interface Vlan777
    }
    device {
        name dist-sw02
        data no vlan 777
             no interface Vlan777
    }
    device {
        name edge-firewall01
        data forward-reference enable
             object-group network INSIDE-NETWORKS
              no network-object object INSIDE-SVI-DEMO
             !
             no object network INSIDE-SVI-DEMO
             no forward-reference enable
    }
}
developer@ncs(config)# commit
Commit complete.
developer@ncs(config)#

The service instance has now been completely removed.

Learn More