Junos OS

 View Only
last person joined: 2 days ago 

Ask questions and share experiences about Junos OS.
  • 1.  MX960 18.1R1.9 missing curl and python3 installation

    Posted 05-15-2024 13:49

    Hello experts

    I am trying to test previously developed ZTP agent script, written in Shell, on the MX960 18.1R1.9 router. I checked that ZTP is working fine on the platform: the router talks to DHCP server, obtains IP address and agent script location, downloads and executes it as expected. But then I got a big surprise error: curl: not found. I am not sure why the curl installation is missing on the router's platform and wonder how to install it?

    Similar question regarding python3 installation. How the python3 and pip3 can be installed on the platform?

    Thank you



    ------------------------------
    Yan Gorelik
    ------------------------------


  • 2.  RE: MX960 18.1R1.9 missing curl and python3 installation

     
    Posted 05-15-2024 15:35
    Edited by asharp 05-15-2024 15:47

    The feature explorer shows that the curl binary is packed on Junos OS 19.2R1 for the MX960 platform.

    Python 3 support was added to MX960 from Junos OS 20.2 R1 (JET support), 19.4R1 (op, event, commit, snmp added).

    https://www.juniper.net/documentation/us/en/software/junos/automation-scripting/topics/concept/junos-script-automation-python-scripts-overview.html

    You might find, that with 18.1R1.9 you might have to leverage Python 2 to perform the API calls, using something like the following, else look to upgrade to a later version of Junos that supports the features that you are looking for.

    import jcs
    import urllib2
    import httplib
    import json
    from sys import exit
    
    def main():
    
        url = 'http://myurl/foo/bar'
        req = urllib2.Request(url)
        req.add_header('Content-Type', 'application/json')
    
        try:
            response = urllib2.urlopen(req, json.dumps(
                {"mypayload": "myvalule"}))
        except urllib2.HTTPError, e:
            jcs.syslog("external.notice", "HTTPError = %s: %s" %
                       (str(e.code), str(e.reason)))
            exit()
        except urllib2.URLError, e:
            jcs.syslog("external.notice",
                       "URLError = %s" % (str(e.reason)))
            exit()
        except httplib.HTTPException, e:
            jcs.syslog("external.notice", "HTTPException")
            exit()
        except Exception:
            import traceback
            jcs.syslog("external.notice", "Generic Exception = %s" %
                       (traceback.format_exc()))
            exit()
    
        jcs.syslog("external.notice", "Response Code = %s" %
                   (str(response.getcode())))
    
    
    if __name__ == '__main__':
        main()
    

    Regards,



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



  • 3.  RE: MX960 18.1R1.9 missing curl and python3 installation

    Posted 05-15-2024 16:30

    Thank you Andy

    Unfortunately the python2.7 although installed, but not usable:

    root@mx960_2:/var/tmp # which python

    /usr/bin/python

    root@mx960_2:/usr # python

    /usr/bin/python: Operation not permitted.



    ------------------------------
    Yan Gorelik
    ------------------------------



  • 4.  RE: MX960 18.1R1.9 missing curl and python3 installation

     
    Posted 05-15-2024 17:33

    You may need to write an op script and have that called via your ztp, instead.



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



  • 5.  RE: MX960 18.1R1.9 missing curl and python3 installation

    Posted 05-15-2024 20:21

    Thank you Andy for very valuable info.

    I can confirm that op script is working with python2.7.

    In the configuration need to add the op script definition:

    system {
    static-host-mapping {
    httpserver inet 172.22.23.24;
    }
       scripts {
    op {
    file test_script.py;
    }
    language python;
    }
    }

     Then download the python script from HTTP server:

    request system download start http://httpserver/test_script.sh

    Copy it to op script folder:

    file copy /var/tmp/junos_mx_agent_script.py /var/db/scripts/op

    And now I can execute the script from the CLI prompt:

    root@mx960_2> op test.py
    Model: MX960
    Serial number: JN10C82F8AFA
    Version number: 18.1R1.9

     My test_script.py:

    from jnpr.junos import Device  # PyEZ

    with Device() as jdev:
    facts = jdev.facts

    print "Model: %s" % facts['model']
    print "Serial number: %s" % facts['serialnumber']
    print "Version number: %s" % facts['version']


    ------------------------------
    Yan Gorelik
    ------------------------------



  • 6.  RE: MX960 18.1R1.9 missing curl and python3 installation

     
    Posted 05-16-2024 02:34

    There is a configuration knob to permit op scripts to execute Python from a remote device.  I've used this approach in a ZTP deployment before.

    system {
        scripts {
            op {
                allow-url-for-python;
            }
            language python;
        }
    }

    With that configured as part of the initial ZTP configuration sent, you can then also setup an event policy to automatically launch the remote script using the "op url" command, you don't need to actually retrieve the file from the remote server, Junos will handle all of those steps.

    Or you could just launch the script via "op url ....." instead etc.

    event-options {
        generate-event {
            ztp-autoi time-interval 600;
        }
        policy ztp-autoi {
            events ztp-autoi;
            then {
                execute-commands {
                    commands {
                        "op url http://192.168.56.1:3030/demo/scripts/ztp.py";
                    }
                }
            }
        }
    }
    


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



  • 7.  RE: MX960 18.1R1.9 missing curl and python3 installation

    Posted 05-16-2024 13:09

    WOW! It worked!

    Thank you so much!



    ------------------------------
    Yan Gorelik
    ------------------------------



  • 8.  RE: MX960 18.1R1.9 missing curl and python3 installation

    Posted 05-24-2024 12:39
    Edited by Yan Gorelik 05-24-2024 12:43

    Hi Andy

    I wonder, if there is similar elegant way to declare operation for shell script? This is pertaining ZTP process on EX-4550 15.1, which does not have Python installation.

    Thank you.



    ------------------------------
    Yan Gorelik
    ------------------------------



  • 9.  RE: MX960 18.1R1.9 missing curl and python3 installation

     
    Posted 05-24-2024 20:02

    Hi Yan,

    For Junos where Python is not available, or if Python is not preferred, then I would look at SLAX, rather than perhaps going down the shell script route.

    Certainly that would be my approach, and would only look at performing actions via the shell as a last resort.  I have had to do some tasks via the shell, but it is fairly rare for the projects that I work on, and if I have to go down that path it is only due to some very specific conditions that would prevent me performing the task via Python/SLAX/XSLT.  I put XSLT in there as well, since on a few rare occasions, I have had to write some functions for SLAX in XSLT, and I dread going down that path as well since I am much more comfortable programming in SLAX than XSLT, plus it is far easier for a customer to read Python or a SLAX script than if I gave them a bunch of XSLT.

    A lot of the functions that get used in Python on Junos e.g. jcs, all started off in SLAX which is present on pretty much everything that Juniper has released since as far as I can remember.  I first started to develop in SLAX on J2300 routers running Junos 9.1 or thereabouts, so you'll have no issue with having SLAX on EX-4550s.

    Taking jcs:dampen() as an example, the following is the equivalent in Python, SLAX and XSLT.

    Python:
    result = jcs.dampen(tag-string, max, interval)
    
    SLAX:
    var $result = jcs:dampen(tag-string, max, interval);
    
    XSLT:
    <xsl:variable name="result" select="jcs:dampen(tag-string, max, interval)"/>
    

    As you can see there isn't too much of a jump from SLAX to Python or vice-versa.

    I'm trying to avoid making this a very long post, but I think that it will be, so apologies for the amount of information you'll have to read.  Taking the example of ZTP that we have discussed over a number of posts using Python, and running a script from a remote server.  The same can be performed via SLAX.  Take the following example in SLAX.

    So this SLAX script is intended to be executed by JUNOS, but the script is not intended to be placed on the Junos device.  In the same way that we could show that Python can launch a script remotely, as can a SLAX script.

    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 exsl extension = "http://exslt.org/common";
    ns func extension = "http://exslt.org/functions";
    ns curl extension = "http://xml.libslax.org/curl";
    ns ztp = "http://xml.juniper.net/junos/ztp";
    
    import "/var/run/scripts/import/junos.xsl";
    
    var $SYSLOG_TAG = "ztp-config: ";
    var $SYSLOG = "external.notice";
    
    var $authorization = "Basic BLAHBLAHBLAH=";
    
    main <op-script-results> {
    
        if(not( jcs:dampen( $SYSLOG_TAG, 1, 1 ))) {
            expr jcs:syslog( $SYSLOG, $SYSLOG_TAG, "dampen exit OK." );
            <xsl:message terminate="yes">;
        }
    
        var $curl = curl:open();
    
        var $message := {
            <method> "post";
            <header name="Authorization"> $authorization;
            <insecure>;
            <url> "http://192.168.56.1/api/v2/job_templates/10/launch/";
            <content-type> "application/json";
            <contents> '{ "limit": "' _ $hostname _ '" }';
            <format> "text";
        }
        var $launch-results = curl:perform($curl , $message );
    
        expr curl:close($curl);
    }
    
    template syslog-messages( $header, $messages )
    {
        expr jcs:syslog( $SYSLOG, $SYSLOG_TAG, $header );
        for-each( $messages ) {
            expr jcs:syslog( $SYSLOG, $SYSLOG_TAG, "message[ ", ., "]");
        }
    }

    So with the above script situated on some server (I think it was on a Git repo for this particular demonstration I made), but it doesn't matter where the script is placed, just so that it can be reachable from the device that is going to be ZTP'd.  The Junos device gets powered on, it talks to DHCP and eventually gets a new basic configuration file via whichever DHCP options etc., part of that initial ZTP configuration would then include the following configuration:

    event-options {
      generate-event { ztp-autoi time-interval 300; }
      policy ztp-autoi {
        events ztp-autoi;
        then {
          execute-commands {
            commands {
              "op url http://192.168.56.1:3030/demo/scripts/ztp.slax";
            }
          }
        }
      }
    }

    So this configuration sets up an event and an event policy, the event is triggered every 300 seconds, and when the policy sees the event it triggers the execution of the op command with the location of where the above SLAX script is located (on some webserver in this scenario).

    The SLAX script, performs the following actions.

    1. jcs:dampen() - checks to see if the SLAX script is already running, and if it is, then terminate the new execution, this is to avoid having multiple copies of the SLAX script running.
    2. Use cURL to make an API call to Ansible Tower to the callback mechanism, which will trigger Ansible to generate the full device configuration and provision the device with whatever configuration is needed.  As part of the configuration that is generated and pushed to the device, the new configuration will remove the event-policy and event, so that it won't try and get provisioned again later.

    That is all that this particular SLAX script does, albeit with a SYSLOG message being sent using a template, but that is nothing specific to the ZTP process.

    Now of course, this is the approach that I took for this particular project where we were using the callback feature of Anisible Tower/AWX at that particular time, I think that this was on QFX.

    I wouldn't quite know where to start trying to perform this kind of approach via the shell....

    Well I hope that this helps you in some small way moving forward with your project.

    Regards,



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



  • 10.  RE: MX960 18.1R1.9 missing curl and python3 installation

     
    Posted 05-25-2024 19:35

    I forgot to also mention, that there are some great resources available to help get a better understanding of automating Junos.

    Here are some links to free resources.

    Day One: Navigating the Junos XML Hierarchy

    This Week: Mastering Junos Automation Programming

    This Week: Junos Automation Reference for SLAX 1.0

    This Week: Applying Junos Automation

    Although the above are quite old I still use them even now.

    Some more recent publications that might be of interest are:

    Day One: Juniper Ambassadors' Cookbook for 2019

    The above cookbook publication has a section on ZTP with SLAX on EX Series Devices that might be worth taking a look at.

    Other technologies are covered for example SALT, Ansible and PyEZ in the following publications.

    Day One: Automating Junos with SALT

    Day One: Automating Junos with Ansible, edition v2.1

    Day One: Junos PyEZ_Cookbook

    And then there is the other automating stuff, e.g, network verification, 

    Day One: Enabling Automated Network Verifications with JSNAPy

    Day One: Ambassadors' Cookbook for 2017 (This has a chapter on Network Regression Testing with Junos PyEZ).

    Day One: Juniper Ambassadors' for 2018 (There is a chapter on Automating Junos with Salt).

    Finally, there is also a publication on O'Reilly that I have and have used.

    Automating Junos Administration 

    So as you can see there are ample sources of information available out there covering most aspects of automating Junos with one tool or another.

    Regards,



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