Network Automation using YANG Models across XE, XR, & NX

Create Service

Navigate to Runtime Packages Directory

  1. On your CentOS host, navigate to the runtime package directory.

                    
                        cd /home/pod00user/nso-run/packages/
                        

    An ls would show your current NEDs/packages.

Create Service Template

  1. In this packages directory is where you will create your custom service. Issue the NSO command below to create your template directory structure dynamically.

                    
                        ncs-make-package --service-skeleton template buildgre
                        

  2. Next you need to create the YANG service model. In this lab, the default .yang template example will be removed and we will use our own.

                    
                        cd /home/pod00user/nso-run/packages/buildgre/src/yang/
                        rm -rf /home/pod00user/nso-run/packages/buildgre/src/yang/buildgre.yang
                    
                
  3. Using the YANG service model below, copy and create the new buildgre.yang file.

                    
                        cat <<EOF >> /home/pod00user/nso-run/packages/buildgre/src/yang/buildgre.yang
                        module buildgre {
                          namespace "http://com/example/buildgre";
                          prefix buildgre;
    
                          import ietf-inet-types {
                            prefix inet;
                          }
                          import tailf-ncs {
                            prefix ncs;
                          }
                          import tailf-common {
                            prefix tailf;
                          }
    
                          augment /ncs:services {
                            list buildgre {
                              key name;
    
                              uses ncs:service-data;
                              ncs:servicepoint "buildgre";
    
                              leaf name {
                                tailf:info "Service Instance Name";
                                  type string;
                              }
    
                              leaf device1 {
                                tailf:info "Tunnel Router #1";
                                mandatory true;
    
                                type leafref {
                                  path "/ncs:devices/ncs:device/ncs:name";
                                }
                              }
    
                              leaf tunnel-number {
                                tailf:info "Tunnel Interface ID";
                                mandatory true;
    
                                type uint32 {
                                  range "1..255";
                                }
                              }
    
                              leaf tunnel-inf-ip1 {
                                tailf:info "Tunnel Router #1 Interface IP";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "20\.0\.0\.[0-9]+";
                                }
                              }
    
                              leaf tunnel-inf-mask1 {
                                tailf:info "Tunnel Router #1 Interface Mask";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "255\.255\.255\.0";
                                }
                              }
    
                              leaf tunnel-src-ip1 {
                                tailf:info "Tunnel Router #1 IP Address (Source)";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "10\.1\.1\.[0-9]+";
                                }
                              }
    
                              leaf tunnel-dest-ip1 {
                                tailf:info "Tunnel Router #2 IP Address (Destination)";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "10\.1\.1\.[0-9]+";
                                }
                              }
    
                              leaf device2 {
                                tailf:info "Tunnel Router #2";
                                mandatory true;
    
                                type leafref {
                                  path "/ncs:devices/ncs:device/ncs:name";
                                }
                              }
    
                              leaf tunnel-inf-ip2 {
                                tailf:info "Tunnel Router #2 Interface IP";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "20\.0\.0\.[0-9]+";
                                }
                              }
    
                              leaf tunnel-inf-mask2 {
                                tailf:info "Tunnel Router #2 Interface Mask";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "255\.255\.255\.0";
                                }
                              }
    
                              leaf tunnel-src-ip2 {
                                tailf:info "Tunnel Router #2 IP Address (Source)";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "10\.1\.1\.[0-9]+";
                                }
                              }
    
                              leaf tunnel-dest-ip2 {
                                tailf:info "Tunnel Router #1 IP Address (Destination)";
                                mandatory true;
    
                                type inet:ipv4-address {
                                  pattern "10\.1\.1\.[0-9]+";
                                }
                              }
                            }
                          }
                        }
                        EOF
                    
                
  4. How do you know that YANG model is valid?

    You can rely on a tool you may have learned in this lab: pyang

    Issue pyang buildgre.yang to valid the YANG model.

                    
                        pyang buildgre.yang
                    
                

    Your output should be similar to the below:

                    
                        [pod00user@ciscolive-pod00-centos yang]$ pyang buildgre.yang
                        /home/pod00user/nso-4.6.1/src/ncs/yang/tailf-ncs-devices.yang:22: warning: imported module tailf-ncs-monitoring not used
                        [pod00user@ciscolive-pod00-centos yang]$
                    
                
  5. With a valid YANG model, you need to make go back one level in the directory structure to formally issue make to compile your new package.

                    
                        cd /home/pod00user/nso-run/packages/buildgre/src/
                        make
                    
                

    The output you should have gotten is similar to the below. If you did not, please talk to an instructor.

                    
                        [pod00user@ciscolive-pod00-centos yang]$ cd /home/pod00user/nso-run/packages/buildgre/src/
                        [pod00user@ciscolive-pod00-centos src]$ make
                        mkdir -p ../load-dir
                        /home/pod00user/nso-4.6.1//bin/ncsc  `ls buildgre-ann.yang  > /dev/null 2>&1 && echo "-a buildgre-ann.yang"` \
                                      -c -o ../load-dir/buildgre.fxs yang/buildgre.yang
                        yang/buildgre.yang:55:32: warning: illegal character after \
                        yang/buildgre.yang:55:35: warning: illegal character after \
                        yang/buildgre.yang:55:38: warning: illegal character after \
                        yang/buildgre.yang:64:33: warning: illegal character after \
                        yang/buildgre.yang:64:38: warning: illegal character after \
                        yang/buildgre.yang:64:43: warning: illegal character after \
                        yang/buildgre.yang:73:32: warning: illegal character after \
                        yang/buildgre.yang:73:35: warning: illegal character after \
                        yang/buildgre.yang:73:38: warning: illegal character after \
                        yang/buildgre.yang:82:32: warning: illegal character after \
                        yang/buildgre.yang:82:35: warning: illegal character after \
                        yang/buildgre.yang:82:38: warning: illegal character after \
                        yang/buildgre.yang:101:32: warning: illegal character after \
                        yang/buildgre.yang:101:35: warning: illegal character after \
                        yang/buildgre.yang:101:38: warning: illegal character after \
                        yang/buildgre.yang:110:33: warning: illegal character after \
                        yang/buildgre.yang:110:38: warning: illegal character after \
                        yang/buildgre.yang:110:43: warning: illegal character after \
                        yang/buildgre.yang:119:32: warning: illegal character after \
                        yang/buildgre.yang:119:35: warning: illegal character after \
                        yang/buildgre.yang:119:38: warning: illegal character after \
                        yang/buildgre.yang:128:32: warning: illegal character after \
                        yang/buildgre.yang:128:35: warning: illegal character after \
                        yang/buildgre.yang:128:38: warning: illegal character after \
                        [pod00user@ciscolive-pod00-centos src]$
                    
                
  6. NSO requires a corresponding XML service template built based on the device NEDs. In this case, that means your IOS-XE and IOS-XR NEDs. A default, generic, template was created when you created your skeleton service. Lets remove that like we did the generic YANG model above.

                    
                        cd /home/pod00user/nso-run/packages/buildgre/templates/
                        rm -rf buildgre-template.xml
                    
                
  7. Insert the XML template below using the copy feature. Take note that the XML template has to align to the YANG model that you used above to compile into a package. What this means is that the XML parameters for a leaf's value must be the leaf variables from the YANG model. For example, the first device variable name was device1 and you'll that corresponding below in the XML template.

                    
                        cat <<EOF >> /home/pod{{ '%02d' % pod }}user/nso-run/packages/buildgre/templates/buildgre-template.xml
                        <config-template xmlns="http://tail-f.com/ns/config/1.0"
                             servicepoint="buildgre">
                          <devices xmlns="http://tail-f.com/ns/ncs">
                            <device>
                             <name>{/device1}</name>
                             <config>
                               <interface xmlns="urn:ios">
                                 <Tunnel>
                                   <name>{/tunnel-number}</name>
                                   <ip>
                                     <address>
                                       <primary>
                                         <address>{/tunnel-inf-ip1}</address>
                                         <mask>{/tunnel-inf-mask1}</mask>
                                       </primary>
                                     </address>
                                     <mtu>1400</mtu>
                                   </ip>
                                   <tunnel>
                                     <source>{/tunnel-src-ip1}</source>
                                     <destination>{/tunnel-dest-ip1}</destination>
                                   </tunnel>
                                 </Tunnel>
                               </interface>
                             </config>
                            </device>
                            <device>
                             <name>{/device2}</name>
                             <config>
                               <interface xmlns="http://tail-f.com/ned/cisco-ios-xr">
                                 <tunnel-ip>
                                   <id>{/tunnel-number}</id>
                                   <mtu>1400</mtu>
                                   <ipv4>
                                     <address>
                                       <ip>{/tunnel-inf-ip2}</ip>
                                       <mask>{/tunnel-inf-mask2}</mask>
                                     </address>
                                   </ipv4>
                                   <tunnel>
                                     <mode>
                                       <gre>ipv4</gre>
                                     </mode>
                                     <source>{/tunnel-src-ip2}</source>
                                     <destination>{/tunnel-dest-ip2}</destination>
                                   </tunnel>
                                 </tunnel-ip>
                               </interface>
                             </config>
                           </device>
                          </devices>
                        </config-template>
                        EOF
                    
                
  8. Now, return to your NSO instance by SSH'ing back into it using the copy feature below and password admin.

                    
                        ssh admin@localhost -p 2024
                    
                
  9. Issue switch_cli to change CLI modes.

                    
                        switch cli
                    
                
  10. With your customer service built, you need to reload the available packages to make it available to your NSO instance. You do this again by issuing the package reload command.

                    
                        packages reload
                    
                

    Your output should look similar to the below. Please notify an instructor if it does not.

                    
                        admin@ncs# packages reload
    
                        >>> System upgrade is starting.
                        >>> Sessions in configure mode must exit to operational mode.
                        >>> No configuration changes can be performed until upgrade has completed.
                        >>> System upgrade has completed successfully.
                        reload-result {
                            package buildgre
                            result true
                        }
                        reload-result {
                            package cisco-ios
                            result true
                        }
                        reload-result {
                            package cisco-iosxr
                            result true
                        }
                        reload-result {
                            package cisco-nx
                            result true
                        }
                        admin@ncs#
                        System message at 2018-06-11 22:42:09...
                            Subsystem stopped: ncs-dp-4-cisco-nx:NexusDp
                        admin@ncs#
                        System message at 2018-06-11 22:42:09...
                            Subsystem stopped: ncs-dp-3-cisco-ios:IOSDp
                        admin@ncs#
                        System message at 2018-06-11 22:42:09...
                            Subsystem started: ncs-dp-5-cisco-ios:IOSDp
                        admin@ncs#
                        System message at 2018-06-11 22:42:09...
                            Subsystem started: ncs-dp-6-cisco-nx:NexusDp
                        admin@ncs#