Automation

last person joined: 3 days ago 

Ask questions and share experiences about Apstra, Paragon, and all things network automation.
  • 1.  About importing libraries

    Posted 04-07-2015 13:41

    Hello,

     

    I'm beginning Junos automation using SLAX and I'd like to create a library of common RPC calls which I can then import into my scripts. What is the best way to go about doing this? I tried putting a bunch of variables in my library file, declaring the same namespace in the library file and script file, then importing the library into the script, but I don't see how to access variables from the library in the script. I would think something like "var $myvar = mynamespace:$mylibraryvar;" would work, but it doesn't. Are import files limited to functions and templates or is using variables possible?

     

    Thanks!



  • 2.  RE: About importing libraries

    Posted 04-08-2015 06:20

    Hi Chris.

    I have only ever used library files for consolidating commonly-used functions/templates.

     

    I don't believe that you can import a file with variable declarations per your example.

    (i.e. with namespaces prepended).

     

    FWIW, SLAX vars are automatically scoped, and their contents don't exist beyond the "{}" they're declared in.    So if you tried to pre-assign values to vars in a template, those values cease to exist as soon as you return from the template...

     

    One application of that type of approach might be to use a template call at top-ot-script to emit an xml nodeset that contains data you'd need to reference in other parts of your script. (E.g. read in script initialization data from an apply-group in the config, etc)

     

    /doug



  • 3.  RE: About importing libraries

    Posted 04-08-2015 10:05

    Hi Doug,

     

    I'm glad you confirmed my suspicions regarding how imports work and what stays in scope. The documentation on this (at least on the libslax site) is not very clear and you could be led to conclude that using the import keyword works the same way as the #include keyword in C/C++.

     

    I kind of wonder if what I'm trying to do is either an oversight of the SLAX language designers or a restriction on the XSLT language.

     

    Is it possible to use templates or functions in a similar way to return the node set I need? e.g. instead of using something like:

     

    $somevar = <get-ospf-neighbor-information>;

     

    I could use a template:

     

    ns ospfstuff = "http://xml.juniper.net/ospfstuff";

    template ospfstuff:get-ospf-neighbor-information() { <get-ospf-neighbor-information>; }

     

    I could then reference this in my "main" script using namespace notation:

     

    ns ospfstuff = "http://xml.juniper.net/ospfstuff";
    
    import "./ospfstuff.slax";
    
    var $conn = jcs:open();
    
    var $ospf-info := { call ospfstuff:get-ospf-neighbor-information(); }
    
    var $ospf-rpc = jcs:execute($conn, $ospf-info);
    
    

     

    What are your thoughts?

     

    Chris



  • 4.  RE: About importing libraries

    Posted 04-08-2015 15:48

    Looking better. Here are my thoughts...

     

    The libslax docs can be somewhat terse.  I recommend grabbing the following "This Week" docs from juniper online:

    • "This Week: Junos Automation Reference for SLAX 1.0" by Curtis Call
    • "This Week: Applying Junos Automation" by Curtis Call

    The Junos Automation Reference doc has a much more detailed description of the import function (and all other SLAX operators, functions and templates.    The Applying Automation guide has some really good, clear examples.

     

    Use of templates in your example is close... but won't work like you have them.

     

    Here's a notional file to import:

    /* Your file ospfstuff.slax would look something like this: */
    
    /* it would have the same "boilerplate" at top-of-file like any other, including
     * you ns declarations, etc.
     * then, just be a collection of your various "ospf" functions and templates.
     */
     
    version 1.0;
    
    /* standard namespace declarations */
    ns junos = "http://xml.juniper.net/junos/*/junos";
    ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
    ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
    
    /* exslt, as needed */
    ns func extension = "http://exslt.org/functions";
    ns str = "http://exslt.org/strings";
    ns date extension = "http://exslt.org/dates-and-times";
    
    /* this library or others, as needed */
    ns ospfstuff extension = "http://xml.juniper.net/ospfstuff";
    
    /* 
     * End of boilerplate. Functions & templates from here on out...
     */
     
    
    /*****************************************************************/
    template ospfstuff:get-ospf-neighbor-information($con) {
      var $rpc = <get-ospf-neighbor-information>;
      var $res = jcs:execute($con,$rpc);
      /* 
       * check $res/..//xnm:error and do the needful.
       * if OK, then emit the XML RTF back to the caller. 
       */
      copy-of $res;
    }
    /*****************************************************************/
    
    /*****************************************************************/
    template ospfstuff:get-ospf-statistics-information($con) {
      var $rpc = <get-ospf-statistics-information>;
      var $res = jcs:execute($con,$rpc);
      /* 
       * check $res/..//xnm:error and do the needful.
       * if OK, then emit the XML RTF back to the caller. 
       */
      copy-of $res;
    }
    /*****************************************************************/
    
    /*****************************************************************/
    template ospfstuff:get-ospf-database-information($con) {
      var $rpc = <get-ospf-database-information>;
      var $res = jcs:execute($con,$rpc);
      /* 
       * check $res/..//xnm:error and do the needful.
       * if OK, then emit the XML RTF back to the caller. 
       */
      copy-of $res;
    }
    /*****************************************************************/
    
    /* 
     *  Etc, etc.
     *  Turtles all the way down.
     */
     

     

    After you imported that into your "main", you could then do something like this in your "main" slax file...:

     

    version 1.1;  /* or version 1.0 if you prefer */
    
    /* 
     * usual boilerplate and ns declarations go here 
     * This example probably has typoes in it.  Good luck.
     */
    
    import "../lib/ospfstuff.slax"
    
    match / {
    	var $con = jcs:open();
    	/* check status */
    
    	/* build up xml nodeset containing ospf neighbor data */
    	var $ospf-nbr-info := { call ospfstuff:get-ospf-neighbor-information($con) };
    	
    	/* build up xml nodeset containing ospf database data */
    	var $ospf-database-info := { call ospfstuff:get-ospf-database-information($con) };
    	
    	/* etc  */
    	
    	/* Now have fun with the data we collected */
    	expr jcs:output("Neighbor is ", $ospf-nbr-info/ospf-neighbor/neighbor-address);
    	
    	for-each ($ospf-database-info/ospf-database) {
    		expr jcs:output("LSA type: ", ./lsa-type, "\t LSA ID: ", ./lsa-id);
    	}
    	
    	/* etc */
    }

     

     

    Does that clarify ?

     

    /doug

     



  • 5.  RE: About importing libraries

    Posted 04-09-2015 07:26

    That got it, sorta! I get output but I'm not able to traverse the node set, only print everything to the screen. Any ideas on that? It also answers another question I was going to ask, which was whether it is possible to pass variables between the "main" SLAX file and any imported files.

     

    I've downloaded both books and will look further into the import command.

     

    Thanks so much!

     



  • 6.  RE: About importing libraries
    Best Answer

    Posted 04-09-2015 13:55

    Just tested on a vsrx  The attached files do work as expected.

     

    regress@vsrx-3> op ospdtest
    Neighbor is 192.168.100.2
    LSA type: Router         LSA ID: 10.200.0.3
    LSA type: Router         LSA ID: 10.200.0.4
    LSA type: Network        LSA ID: 192.168.100.1
    LSA type: OpaqArea       LSA ID: 1.0.0.1
    LSA type: OpaqArea       LSA ID: 1.0.0.1
    
    regress@vsrx-3>
    

     



  • 7.  RE: About importing libraries

    Posted 04-13-2015 07:34

    Looks like I was experiencing a PEBKAC error...  My XPath expression was wrong, so I was barking up the wrong tree (I'm here all week folks!). Once I fixed it, I got the output I was expecting. Thanks!