Automation

 View Only
last person joined: 6 days ago 

Ask questions and share experiences about Apstra, Paragon, and all things network automation.
Expand all | Collapse all

script or report to list/display route table

  • 1.  script or report to list/display route table

    Posted 01-09-2023 11:20
    Is there some way in space to report on the route table for a device or gather the information to at least report on?

    ------------------------------
    MARK JOHNS
    ------------------------------


  • 2.  RE: script or report to list/display route table

    Posted 01-09-2023 11:27
    Hi Mark,

    Can you please give more insights on what is that you are trying to achieve? And i believe you are talking about Junos Space, right?

    Thanks,
    Adrian.

    ------------------------------
    Teodor Adrian Soroceanu
    ------------------------------



  • 3.  RE: script or report to list/display route table

    Posted 01-09-2023 11:30
    Correct, Junos Space.  I want to get the route table on a device and run a report on it or at least get sent/saved somewhere in a readable format.

    ------------------------------
    MARK JOHNS
    ------------------------------



  • 4.  RE: script or report to list/display route table

    Posted 01-09-2023 12:33
    Hi Mark,

    There is an option to put a slax script in Junos Space under - Image and Scripts, for your case you can yous this slax script found_here . Practicaly you stage the script on the device and execute and you will get a csv with the results. Hope this helps.

    Thanks,
    Adrian.

    ------------------------------
    Teodor Adrian Soroceanu
    ------------------------------



  • 5.  RE: script or report to list/display route table

    Posted 01-09-2023 12:51
    Where is the csv?

    ------------------------------
    MARK JOHNS
    ------------------------------



  • 6.  RE: script or report to list/display route table

    Posted 01-09-2023 13:25

    Hi Mark,

    Under job id you have a button Export CSV:



    ------------------------------
    Teodor Adrian Soroceanu
    ------------------------------



  • 7.  RE: script or report to list/display route table

    Posted 01-09-2023 14:37
    I only need this section then?
    /* Shows similar header as seen in show route brief */
    template show-route-table-header( $table ) {
    var $first-line = $table/table-name _ ": " _ $table/destination-count _
    " destinations, " _ $table/total-route-count _ " routes (" _ $table/active-route-count _
    " active, " _ $table/holddown-route-count _ " holddown, " _ $table/hidden-route-count _
    " hidden)";
    var $second-line = "+ = Active Route, - = Last Active, * = Both";
    expr jcs:output( "\n", $first-line );
    expr jcs:output( $second-line, "\n_\r " );
    }

    template show-route-table-routes( $table ) {
    /* Each route has multiple route entries */
    for-each( $table/rt ) {
    var $destination = {
    if( string-length( ./rt-prefix-length ) ) {
    expr ./rt-destination _ "/" _ ./rt-prefix-length;
    }
    else {
    expr ./rt-destination;
    }

    }
    for-each( ./rt-entry ) {
    /* Grab the protocol specific lines */
    var $lines-rtf = {
    if( ./protocol-name == "BGP" ) {
    call build-bgp-lines( $route = . );
    }
    else if( ./protocol-name == "Local" ) {
    call build-local-lines( $route = . );
    }
    else if( ./protocol-name == "Direct" ) {
    call build-direct-lines( $route = . );
    }
    else {
    call build-other-lines( $route = . );
    }
    }
    var $lines = ext:node-set( $lines-rtf );
    /* First line */
    /* Only show destination for first entry */
    if( position() == 1 ) {
    var $first-line = jcs:printf( "%-20s %s", $destination, $lines/first );
    expr jcs:output( $first-line );
    }
    else {
    var $first-line = jcs:printf( "%-20s %s", "", $lines/first );
    expr jcs:output( $first-line );
    }
    /* Second line */
    var $second-line = jcs:printf( "%-20s %s", "", $lines/second );
    expr jcs:output( $second-line );
    if( string-length( $lines/third ) > 0 ) {
    var $third-line = jcs:printf( "%-20s %s", "", $lines/third );
    expr jcs:output( $third-line );
    }
    if( string-length( $lines/fourth ) > 0 ) {
    var $fourth-line = jcs:printf( "%-20s %s", "", $lines/fourth );
    expr jcs:output( $fourth-line );
    }
    }
    }
    }

    ------------------------------
    MARK JOHNS
    ------------------------------



  • 8.  RE: script or report to list/display route table

    Posted 01-10-2023 16:54
    Tested script and it doesn't seem to be working.  Got error message in job log of:
    Script execution for script route.slax failed on device Mark-Test due to the following reasons: 
    Device ID: 19431543. Src File: route.slax
    <response>
    <progress><![CDATA[]]></progress>
    <message><![CDATA[cd /var/cache/jboss/LocalScript/; /var/www/cgi-bin/runLocalScriptExpect null /var/cache/jboss/LocalScript/route.slax [DeviceUserName] [DevicePassword] 164.154.67.5 null false deviceipmap '{}' 
    spawn juise --ssh-options -oUserKnownHostsFile=/dev/null --ssh-options -oFingerprintHash=md5 --ssh-options -oHostKeyAlgorithms=ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384 /var/cache/jboss/LocalScript/route.slax [DeviceUserName]@164.154.67.5 deviceipmap {}
    /var/cache/jboss/LocalScript/route.slax:93: error: unknown prefix 'ext' in ext:node-set
    ^
    /var/cache/jboss/LocalScript/route.slax: 1 error detected during parsing (0)
    juise: cannot parse: '/var/cache/jboss/LocalScript/route.slax'
    ]]></message>
    <errorcode>0</errorcode>
    <status>SUCCESS</status>
    </response>


    ------------------------------
    MARK JOHNS
    ------------------------------



  • 9.  RE: script or report to list/display route table

     
    Posted 01-15-2023 13:45
    Mark,

    If memory serves me correctly, when using a locally executed SLAX script within Junos Space, it doesn't like multiple <output>...</output>  entries that are generated by using expr jcs:output(...).

    Instead to get the output displayed I recall that it was better to define a single output block that captures all the required output and using jcs:printf(...) instead.  

    It's been a very long time since I last created any SLAX scripts to be executed via Junos Space, so I'll need to look into this some more once I have the opportunity to spin up a Junos Space instance and take a look in the lab.  Hopefully I'll have some time to take a look at this over the next few days so long as I can get something running in our lab.

    Also, note that you would still need to have the import and namespace declarations present in the SLAX script as per the original version, else you'll see errors such as the one you have seen already.

    e.g. 

    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";
    ns ext = "http://xmlsoft.org/XSLT/namespace";
    
    import "../import/junos.xsl";​

    Anyway, I'll take a look at the original SLAX script and do a test conversion to something that can run within Junos Space just as soon as I can, but it may take a few extra days.

    Regards.

    ------------------------------
    Andy Sharp
    ------------------------------



  • 10.  RE: script or report to list/display route table

     
    Posted 01-17-2023 07:11
      |   view attached
    OK, finally figured this out.  Attached is a conversion of the slax script that was described in an earlier post so that it can run as a local slax script within Junos Space.

    Now, this script still doesn't output the data in CSV format, although with some minor reworking of the printf statements you could get it to generate CSV data.

    However, if you are just looking at doing a conversion of say "show route <foo>" to a CSV format, you are probably better off just seeing if looking glass works best for you.  The table view can be exported to CSV, and it supports running commands against multiple devices. 

    Anyway, the SLAX script is attached, if you still need a SLAX script to output results in CSV then I can assist, but it would only output a csv string in the results window, you wouldn't get a packaged .zip archive etc.. unlike say with looking glass.

    The attached script would need to be renamed from a .txt file to a .slax file so that it can be imported into Junos Space.

    Regards.

    ------------------------------
    Andy Sharp
    ------------------------------

    Attachment(s)

    txt
    show-route-brief.slax.txt   9 KB 1 version


  • 11.  RE: script or report to list/display route table

     
    Posted 01-17-2023 12:37
    Hi Mark,

    OK, I took a look at the script and the following is a version that will execute within Junos Space as a locally executed script.

    However this script doesn't output results in CSV.  With a bit of tweaking it would be possible to output the data in CSV.  However, for this scenario, I would have thought it easier to use looking glass instead.  That has the ability to execute commands against one or more devices, and the output can be put into a list view, and then that can be exported to CSV.    The only issue is if you want a CSV structure that is different to that that is produced by looking glass.??

    Anyway, here is the script that I can install into Junos Space and execute against a single device.

     /*
     * Author        : Curtis Call
     * Version       : 1.0
     * Last Modified : October 18, 2010
     * Platform      : all
     * Release       : JUNOS 8.x and above
     *
     * This script mimics the show route brief command except it adds a BGP Next Hop
     * field when appropriate.
     *
     * License       : BSD-Style
     *  Copyright (c) 2010 Curtis Call. All Rights Reserved.
     *  Redistribution and use in source and binary forms, with or without modification, 
     *  are permitted provided that the following conditions are met:
     *  1. Redistributions of source code must retain the above copyright notice, this 
     *  list of conditions and the following disclaimer.
     *  2. Redistributions in binary form must reproduce the above copyright notice, 
     *  this list of conditions and the following disclaimer in the documentation and/or
     *  other materials provided with the distribution.
     *  3. The name of the author may not be used to endorse or promote products derived 
     *  from this software without specific prior written permission.
     *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED 
     *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
     *  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 
     *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
     *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
     *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
     *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
     *  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */ 
    
    version 1.2;
    
    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";
    ns ext = "http://xmlsoft.org/XSLT/namespace";
    
    import "../import/junos.xsl";
    
    /* Junos Space annotations */
    /* @CONTEXT = "/device" */
    /* @NAME = "Route Brief" */
    /* @DESCRIPTION = "show route brief command with BGP next hop" */
    /* @ISLOCAL = "true" */
    
    var $arguments = {
        <argument> {
            <name> "prefix";
            <description> "Destination prefix";
        }
    }
    
    param $prefix;
    
    main <op-script-results> {
        /* open connection */
        var $connection = jcs:open();
    
        /* output block */
        <output> {
            
            /* Pull in route extensive information */
            var $route-extensive-command =  <get-route-information> {
                                                <extensive>;
                                                if( not( jcs:empty( $prefix ) ) ) {
                                                    <destination> $prefix;
                                                }
                                            }
            var $route-extensive = jcs:execute( $connection, $route-extensive-command );
            
            /* Check for errors, bail if we have to */
            if( not( jcs:empty( $route-extensive/..//xnm:error ) ) ) {
                <xsl:message terminate="yes"> "Error retrieving extensive routing information " _ $route-extensive/..//xnm:error/message;
            }
    
            /* Process each routing table */
            for-each( $route-extensive/route-table ) {
                call show-route-table-header( $table=. );
                call show-route-table-routes( $table=. );
            }
        }
    
        /* close connection */
        var $closeResult = jcs:close ( $connection );
    }
    
    /* Shows similar header as seen in show route brief */
    template show-route-table-header( $table ) {
        var $first-line = "\n" _ $table/table-name _ ": " _ $table/destination-count _ 
            " destinations, " _ $table/total-route-count _ " routes (" _ $table/active-route-count _
            " active, " _ $table/holddown-route-count _ " holddown, " _ $table/hidden-route-count _
            " hidden)";
        var $second-line = "+ = Active Route, - = Last Active, * = Both";
        uexpr $first-line _ "\n";
        uexpr $second-line _ "\n";
    }
    
    template show-route-table-routes( $table ) {
        /* Each route has multiple route entries */
        for-each( $table/rt ) {
            var $destination = {
                if( string-length( ./rt-prefix-length ) ) {
                    expr ./rt-destination _ "/" _ ./rt-prefix-length; 
                }
                else {
                    expr ./rt-destination;
                }
            
            }
            for-each( ./rt-entry ) { 
                /* Grab the protocol specific lines */
                var $lines-rtf = {
                    if( ./protocol-name == "BGP" ) {
                        call build-bgp-lines( $route = . );
                    }
                    else if( ./protocol-name == "Local" ) {
                        call build-local-lines( $route = . );
                    }
                    else if( ./protocol-name == "Direct" ) {
                        call build-direct-lines( $route = . );
                    }
                    else {
                        call build-other-lines( $route = . );
                    }
                }
                var $lines = ext:node-set( $lines-rtf );
                /* First line */
                /* Only show destination for first entry */
                if( position() == 1 ) {
                    var $first-line = jcs:printf( "%-20s %s", $destination, $lines/first );
                    /* expr jcs:output( $first-line );*/
                    uexpr $first-line _ "\n";
                }
                else {
                    var $first-line = jcs:printf( "%-20s %s", "", $lines/first ); 
                    /* expr jcs:output( $first-line ); */
                    uexpr $first-line _ "\n";
                }
                /* Second line */
                var $second-line = jcs:printf( "%-20s %s", "", $lines/second ); 
                /* expr jcs:output( $second-line ); */
                uexpr $second-line _ "\n";
                if( string-length( $lines/third ) > 0 ) {
                    var $third-line = jcs:printf( "%-20s %s", "", $lines/third ); 
                    /* expr jcs:output( $third-line ); */
                    uexpr $third-line _ "\n";
                }
                if( string-length( $lines/fourth ) > 0 ) {
                    var $fourth-line = jcs:printf( "%-20s %s", "", $lines/fourth ); 
                    /* expr jcs:output( $fourth-line ); */
                    uexpr $fourth-line _ "\n";
                }
            }
        }
    }
    
    /* Returns a route entry XML hierarchy with <first>, <second>, <third>, and <fourth> elements */
    template build-bgp-lines( $route ) {
        var $age = {
            if( string-length( $route/age ) == 5 ) {
                /* prepend hour field to it */
                expr "00:" _ $route/age;
            }
            else {
                expr $route/age;
            }
        }
        <first> $route/active-tag _ "[" _ $route/protocol-name _ "/" _ $route/preference _ "] " _ $age _ ", localpref " _ $route/local-preference _ ", from " _ $route/gateway;
        <second> "   AS Path: " _ $route/as-path;
        /* Build next-hop string - watch for discard or rejects */
        var $next-hop = {
            if( $route/nh-type == "Discard" ) {
                expr "   Discard";
            }
            else if( $route/nh-type == "Reject" ) {
                expr "   Reject";
            }
            else {
                expr " > to " _ $route/nh[selected-next-hop]/to _ " via " _ $route/nh[selected-next-hop]/via;
            }
        }
        
        /* Only show bgp next-hop for active routes */
        if( $route/current-active and $route/protocol-nh/to ) {
            <third> "   BGP Next-Hop: " _ $route/protocol-nh/to;
            <fourth> $next-hop;   
        }
        else {
            <third> $next-hop;  
        }
    }
    
    /* Returns a route entry XML hierarchy with <first>, <second> elements */
    template build-local-lines( $route ) {
        var $age = {
            if( string-length( $route/age ) == 5 ) {
                /* prepend hour field to it */
                expr "00:" _ $route/age;
            }
            else {
                expr $route/age;
            }
        }
        <first> $route/active-tag _ "[" _ $route/protocol-name _ "/" _ $route/preference _ "] " _ $age;
        /* Catch Reject Next-hops */
        if( $route/nh-type == "Reject" ) {
            <second> "   Reject";
        }
        else {
            <second> "   Local via " _ $route/nh/nh-local-interface;
        }
    }
    
    /* Returns a route entry XML hierarchy with <first>, <second> elements */
    template build-direct-lines( $route ) {
        var $age = {
            if( string-length( $route/age ) == 5 ) {
                /* prepend hour field to it */
                expr "00:" _ $route/age;
            }
            else {
                expr $route/age;
            }
        }
        <first> $route/active-tag _ "[" _ $route/protocol-name _ "/" _ $route/preference _ "] " _ $age;
        <second> " > via " _ $route/nh[selected-next-hop]/via;
    }
    
    /* Returns a route entry XML hierarchy with <first>, <second> elements */
    template build-other-lines( $route ) {
        /* Add metric if it exists */
        var $metric = {
            if( string-length( $route/metric ) > 0 ) {
                expr ", metric " _ $route/metric;
            }
        }
        var $age = {
            if( string-length( $route/age ) == 5 ) {
                /* prepend hour field to it */
                expr "00:" _ $route/age;
            }
            else {
                expr $route/age;
            }
        }
        <first> $route/active-tag _ "[" _ $route/protocol-name _ "/" _ $route/preference _ "] " _ $age _ $metric;
        /* Catch the MultiRecv Type, Discard, and Reject Types */
        if( $route/nh-type == "MultiRecv" ) {
            <second> "   MultiRecv";
        }
        else if( $route/nh-type == "Discard" ) {
            <second> "   Discard";
        }
        else if( $route/nh-type == "Reject" ) {
            <second> "   Reject";
        }
        else {
            <second> " > to " _ $route/nh[selected-next-hop]/to _ " via " _ $route/nh[selected-next-hop]/via;
        }
    }
    ​



    ------------------------------
    Andy Sharp
    ------------------------------