Goal

This tutorial demonstrates the pre-configuration needed for the Application CLI Extension Tutorial. The necessary steps are:

  • Write an XML file based on the XSD extensions schema file defining its configuration and EXEC commands
  • Run the XSLT convertor tool using a browser or any available XSLT interpreter against the XML file you have written
  • Install the newly created XSD file to your connected device
  • Show the newly installed Application CLI Extension commands on your connected device

Requirements/Prerequisites

These steps assume that you have a network element running a network operating system (NOS).

Steps In Detail

Define a onePK Application CLI Command

The following resources are provided at: <SDK Location>/python/tutorials/applmgmt/

  • cli_ext_schema.xsd - You define CLI commands in an XML file following the format of this schema file.
  • xml2xsd-convertor.xslt - You convert your XML file using the XSLT converter tool to generate an application-specific XSD file.
  • cli_ext_tutorial_app.xml - This XML properties file is defined for this tutorial and is based on the schema provided (cli_ext_schema.xsd)
  • cli_ext_tutorial_app.xsd - This is the application-specific XSD file for this tutorial, converted from cli_ext_tutorial_app.xml using xml2xsd-convertor.xslt. This XSD file is used to install the new application CLIs in the network element.

Note : All these resources listed above have been provided in this tutorial, including the XSD file, which is the end-result of this configuration tutorial.

  • To install the XSD file directly, jump to step Install the Application-Specific XSD File.
  • To define a new CLI command by writing an XML file, converting and installing the resulting XSD file, perform the following steps:

Describe the CLI Command in XML

To define a CLI command for a onePK application, you write the command in an XML file based on the format used in the cli_ext_schema.xsd file. For this tutorial, the following XML file has been defined:

<?xml version="1.0" encoding="UTF-8"?>
<!--
config
    app-category name <name>
 
    app-stats <stat>
          user user-count <count> 
          price amount <amount>
          

show 
          sh onep application cli_tutorial_app v0.2 <config-domain> [<instance-name>] app-category
          sh onep application cli_tutorial_app v0.2 <config-domain> [<instance-name>] statistics
          
-->
<?xml-stylesheet type="text/xsl" href="xml2xsd-convertor.xslt"?>
<cli_ext:application app-name="cli_tutorial_app" version="0.2" description="Cli Extension Tutorial Application" app-namespace-prefix="demo" app-mode-prompt-prefix="demo" app-namespace="http://www.cisco.com/demo_app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cli_ext="http://www.cisco.com/onep/cli_ext:0.1" xsi:schemaLocation="http://www.cisco.com/onep/cli_ext:0.1 cli_ext_schema.xsd">
  <cli_ext:config-cmds>
    <cli_ext:scalar-cmd name="app_category_cmd">
      <cli_ext:keyword>
        <cli_ext:name>app-category</cli_ext:name>
        <cli_ext:help>config onep app category name</cli_ext:help>
      </cli_ext:keyword>
      <cli_ext:param>
                <cli_ext:name>name</cli_ext:name>
                <cli_ext:help>string</cli_ext:help>
                <cli_ext:type>
                                <cli_ext:string/>
                </cli_ext:type>
          </cli_ext:param>
    </cli_ext:scalar-cmd>
     <cli_ext:list-cmd name="app_stat_cmd">
                <cli_ext:param>
                         <cli_ext:name>app-stats</cli_ext:name>
                                <cli_ext:help>add app statistics</cli_ext:help>
                                <cli_ext:type>
                                        <cli_ext:string/>
                                </cli_ext:type>
                                </cli_ext:param>
        <cli_ext:mode mode-prompt="stat">
        <cli_ext:scalar-cmd name="users_cmd">
                <cli_ext:keyword>
                        <cli_ext:name>users</cli_ext:name>
                        <cli_ext:help>Number of users</cli_ext:help>
                </cli_ext:keyword>
                <cli_ext:param>
                        <cli_ext:name>count</cli_ext:name>
                        <cli_ext:help>count</cli_ext:help>
                        <cli_ext:type>
                                <cli_ext:integer/>
                        </cli_ext:type>
                </cli_ext:param>
                </cli_ext:scalar-cmd>
                <cli_ext:scalar-cmd name="price_cmd">
                <cli_ext:keyword>
                        <cli_ext:name>price</cli_ext:name>
                        <cli_ext:help>purchase price</cli_ext:help>
                </cli_ext:keyword>
                <cli_ext:param>
                        <cli_ext:name>amount</cli_ext:name>
                        <cli_ext:help>number</cli_ext:help>
                        <cli_ext:type>
                                <cli_ext:integer/>
                        </cli_ext:type>
                </cli_ext:param>
                </cli_ext:scalar-cmd>
                </cli_ext:mode>
                </cli_ext:list-cmd>
  </cli_ext:config-cmds>
  <cli_ext:show-cmds>
        <cli_ext:exec-cmd name="show_category_cmd">
                        <cli_ext:keyword>
                                <cli_ext:name>app-category</cli_ext:name>
                                <cli_ext:help>show onep app's category name</cli_ext:help>
                        </cli_ext:keyword>
        </cli_ext:exec-cmd>
        <cli_ext:exec-cmd name="show_stat_cmd">
                        <cli_ext:keyword>
                                <cli_ext:name>statistics</cli_ext:name>
                                <cli_ext:help>onep app statistics</cli_ext:help>
                        </cli_ext:keyword>
        </cli_ext:exec-cmd>
  </cli_ext:show-cmds>
  
  <cli_ext:exec-cmds>
                <cli_ext:exec-cmd name="clear_stat_cmd">
                        <cli_ext:keyword>
                                <cli_ext:name>clear</cli_ext:name>
                                <cli_ext:help>clear</cli_ext:help>
                        </cli_ext:keyword>
                        <cli_ext:keyword>
                                <cli_ext:name>statistics</cli_ext:name>
                                <cli_ext:help>statistics</cli_ext:help>
                        </cli_ext:keyword>
                
                </cli_ext:exec-cmd>
        </cli_ext:exec-cmds>
</cli_ext:application>

Validate the XML file

This is a manual step. You will need to validate your XML file against the cli_ext_schema.xsd file, ensuring that your command definition follows the XSD format. You can use any tool to validate your XML; the following example shows how to use xmllint on the command line:

xmllint -noout -schema cli_ext_schema.xsd cli_ext_tutorial_app.xml

Convert XML to XSD

Make sure your XML and XSLT (xml2xsd-convertor.xslt) files are present in same location. Then open the XML file in a browser and the XML file is converted to the XSD file format. Save this XSD file. The one used for this tutorial is "cli_ext_tutorial_app.xsd" shown below:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  xmlns="http://www.cisco.com/demo_app:0.2" xmlns:demo="http://www.cisco.com/demo_app:0.2" xmlns:cli_ext="http://www.cisco.com/onep/cli_ext:0.1" targetNamespace="http://www.cisco.com/demo_app:0.2" elementFormDefault="qualified" attributeFormDefault="unqualified"  xml:lang="en">
    
    <xs:import namespace="http://www.cisco.com/onep/cli_ext:0.1" schemaLocation="cli_ext_schema.xsd"/>  
    <xs:annotation>
        <xs:appinfo>xslt version 0.1</xs:appinfo>
        <xs:documentation>
      This schema was by cli-extension ssl.
    </xs:documentation>
    </xs:annotation>
    
    <xs:element name="cli_tutorial_app">
    <xs:annotation>
        <xs:documentation>Cli Extension Tutorial Application</xs:documentation>
    </xs:annotation>
    <xs:complexType>
        <xs:sequence>
    
    
     <!--start config-cmds-->
    <xs:element name="config_data" minOccurs="0">
    <xs:complexType>
        <xs:sequence>
         
    
    <xs:element name="node_info_cmd" minOccurs="0">
        <xs:complexType>
            <xs:sequence>
            
                
        <xs:element name="no" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Negate a command or set a command's default</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
                
                <xs:element name="node_info" type="node_info_type" />
              
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    
            <xs:choice minOccurs="0" maxOccurs="unbounded">
    
            <xs:element name="app_category_cmd">
                <xs:complexType>
                    <xs:sequence>
                        
        <xs:element name="no" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Negate a command or set a command's default</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
        <xs:element name="app-category" >
        
            <xs:annotation>
                <xs:documentation>config onep app category name</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
        <xs:element name="name" type="xs:string">
        
            <xs:annotation>
                <xs:documentation>string</xs:documentation>
            </xs:annotation> 
        
         </xs:element> 
         
        
                </xs:sequence>
                
            </xs:complexType>
        </xs:element>
         

        <!--start list-cmd app_stat_cmd-->
        <xs:element name="app_stat_cmd" maxOccurs="unbounded">
            <xs:complexType>
                <xs:sequence>
            
        <xs:element name="no" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Negate a command or set a command's default</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
            <xs:element name="app-stats">
             
                <xs:annotation>
                    <xs:documentation>add app statistics</xs:documentation>
                </xs:annotation>
           
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:string">
                            <xs:attribute name="key" type="xs:boolean" fixed="true"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
                
       </xs:element> 
           
              <xs:choice minOccurs="0" maxOccurs="unbounded" >
             
            <xs:element name="users_cmd">
                <xs:complexType>
                    <xs:sequence>
                        
        <xs:element name="no" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Negate a command or set a command's default</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
        <xs:element name="users" >
        
            <xs:annotation>
                <xs:documentation>Number of users</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
        <xs:element name="count" type="xs:integer">
        
            <xs:annotation>
                <xs:documentation>count</xs:documentation>
            </xs:annotation> 
        
         </xs:element> 
         
        
                </xs:sequence>
                
            </xs:complexType>
        </xs:element>
         

            <xs:element name="price_cmd">
                <xs:complexType>
                    <xs:sequence>
                        
        <xs:element name="no" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Negate a command or set a command's default</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
        <xs:element name="price" >
        
            <xs:annotation>
                <xs:documentation>purchase price</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
        <xs:element name="amount" type="xs:integer">
        
            <xs:annotation>
                <xs:documentation>number</xs:documentation>
            </xs:annotation> 
        
         </xs:element> 
         
        
                </xs:sequence>
                
            </xs:complexType>
        </xs:element>
         
             
            </xs:choice>
             
        
                    </xs:sequence>
                    
                    <xs:attribute name="mode_prompt" type="xs:string" default="stat"/>
                     
                </xs:complexType>
            </xs:element>
      
        
        
     <!--end list-cmd app_stat_cmd-->

            </xs:choice>
        </xs:sequence>      
    </xs:complexType>
    </xs:element>
     <!--end config-cmds-->

   
     <xs:element name="exec" minOccurs="0">
        <xs:complexType>
            <xs:sequence>
                <xs:choice maxOccurs="unbounded">
                
                        <xs:element name="node_info" type="node_info_type"/>

    
     <!--start show-cmds -->
    
    <xs:element name="show_category_cmd" minOccurs="0">
    <xs:complexType>
        <xs:sequence>
        
        <xs:element name="show">
            <xs:annotation>
                <xs:documentation>Show running system information</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
        <xs:element name="app-category" >
        
            <xs:annotation>
                <xs:documentation>show onep app's category name</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
       
       </xs:sequence>      
    </xs:complexType>
     </xs:element>  
    
    <xs:element name="show_stat_cmd" minOccurs="0">
    <xs:complexType>
        <xs:sequence>
        
        <xs:element name="show">
            <xs:annotation>
                <xs:documentation>Show running system information</xs:documentation>
            </xs:annotation>
            <xs:complexType/>
        </xs:element>
    
        <xs:element name="statistics" >
        
            <xs:annotation>
                <xs:documentation>onep app statistics</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
       
       </xs:sequence>      
    </xs:complexType>
     </xs:element>  
    
     <!--end show-cmds -->

     <!--start exec-cmds-->
    
    <xs:element name="clear_stat_cmd" minOccurs="0">
    <xs:complexType>
        <xs:sequence>
       
        <xs:element name="clear" >
        
            <xs:annotation>
                <xs:documentation>clear</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
        <xs:element name="statistics" >
        
            <xs:annotation>
                <xs:documentation>statistics</xs:documentation>
            </xs:annotation>
        
            <xs:complexType/>
         </xs:element> 
        
       
       </xs:sequence>      
    </xs:complexType>
     </xs:element>  
    
     <!--end exec-cmds-->

                 </xs:choice>
            </xs:sequence>
        </xs:complexType>
     </xs:element>

        </xs:sequence>
        <xs:attribute name="version" use="optional" fixed="0.2"/>
        <xs:attribute name="app-mode-prompt-prefix" use="optional" fixed="demo"/>
    </xs:complexType>
    </xs:element>
    
    <xs:complexType name="node_info_type">
        <xs:sequence>
            <xs:element name="v0.2">
                <xs:annotation>
                    <xs:documentation>application version</xs:documentation>
                </xs:annotation>
                <xs:complexType/>
            </xs:element>
       
           <xs:element name="config-domain" type="xs:string">
                <xs:annotation>
                    <xs:documentation>Identifies where the application is running</xs:documentation>
                </xs:annotation>
            </xs:element>
            
            <xs:element name="instance-name" type="xs:string" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>instance name</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    
    
    </xs:schema>
    

Using Conversion Tools for XML -> XSD

Make sure your XML and XSLT (xml2xsd-convertor.xslt) files are present in same location. Use one of the following options to run the XSLT convertor tool on your XML file:

  • Using XMLSpy
    • Open the xml2xsd-convertor.xslt file in XMLSpy.
    • Choose the menu option XSL/XSL Query -> XSL Transformation
    • Choose the valid application XML file, in this case, cli_ext_tutorial_app.xml, then click OK.
    • Save the file to cli_ext_tutorial_app.xsd.
  • Using a Browser

    For all browsers: paste the following lines to the application XML file and replace the href with the correct location to the XSLT file if it is not in the same folder as the XML file.

    <?xml-stylesheet type="test/xsl" href="xml2xsd-convertor.xslt"?>

    Then open the XML file in a browser and the XML file is converted to the XSD file format. Save this XSD file. The one used for this tutorial is "cli_ext_tutorial_app.xsd"

    • Using Firefox
      • Open the application XML file using the File menu.
      • Save to an application-name.xsd. file name.
    • Using IE (v8.0)
      • Open the application XML file using the File menu or use CRTL-O.
      • Choose Developer Tools from the Tools menu.
      • Choose Script. The XSD is shown on the left tab. Save to an application-name.xsd. file name.
    • Using Chrome
      • Run the Chrome application with the allow file access from files parameter open Google/Chrome.app -- arg --allow-file-access-from-files.
      • Open the XML file using the File menu.
      • Save to an application-name.xsd. file name.
    • Running XSLT in a Webtool XSLT TryIt Editor
      • Paste your XML and XSD data in the respective frames in the web page.
      • Use the Edit and Click Me button to display your results.

Install the Application-Specific XSD File

To install the XSD file on your connected network element, copy the XSD file to the network element's filesystem. Then issue the following CLI commands:

Router#copy scp:<path to xsd> bootflash:<file name>

After copying the file, issue an install CLI command so that the XSD file can be inserted into the network element's CLI tree. The install EXEC command syntax is as follows:

Router#onep install <xsd-location> <config-domain>

For applications running in a local VM the config-domain is the VM's name. For applications running remotely, the config-domain is just a name, and thus it is the remote application that denotes (although it must match the local configuration) the domain in which group resides at connection time.

The command returns an error if the XSD file cannot be used to insert the CLI commands in the switch CLI tree. The new application CLIs are available on the connected device if the command is succesful. The XSD file can be removed from the device once the command succeeds. New commands are available even if the device reboots or if there is a switchover.

To determine which application CLIs have been installed, use the following show command:

Router#show onep cli-extensions applications

You can use the following uninstall command to delete application CLI commands from the device. The uninstall EXEC command syntax is as follows:

Router#onep uninstall <app-name> <app-version> <config-domain>

The application name and the version are retrieved from the application XSD file. The config_domain is the config-domain used in the XSD install.

Application-Specific Commands Usage

All application CLI commands are inserted into an application-specific submode. An example of how a CLI command definition is displayed is as follows:

config t
  onep applications domain1
    cli_tutorial_app v0.2 instance1
    app-category name routing
    app-stats routing-stats
    users user-count 20
    price amount 1

show command:
sh onep application cli_tutorial_app v0.2 domain1 instance1 app-category

Result

Congratulations! You have now completed the configuration required to run Application CLI Extension applications and are now ready to run the Application CLI Extension Tutorial.