Junos Automation (Scripting)
Highlighted
Junos Automation (Scripting)

Slax script to download file

‎06-26-2018 08:44 AM

- Goal is to execute a SLAX script from Junos Space to simply download a file to an SRX from a repo that has basic auth. Basic auth is sufficient for the requirements. The SLAX script is running from Space and not copied/run locally to the SRX.

 

We have tested 3 methods so far and have hit stumbling blocks on each.

1. slax script uses jcs:invoke to run the "file copy" command specifying the source https URL and destination. However, we don't see an argument in the command to specify username/pw for basic auth. Running the command on the SRX in the CLI it will prompt for username/pwd. Is there a way to pass this through the SLAX script? 

 

2. slax script also using jcs:invoke to run the "request system download" command that allows for username:password, however it comes back with host not reachable even though it is. 

 

3. slax script with import of the curl extension and running curl:single($url, $options) where options contains the header info . We can run a typical curl command (curl -O -H"Authorization: Basic ##" "https://url/filename") from another device and it works but we are unaware of how to translate that into the curl extension for SLAX. The slax script will run but it only displays the content of the file. 

9 REPLIES 9
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎06-26-2018 01:46 PM

Sounds like you want to use the jcs:curl support in slax. 

You didn't say what the version of Junos was on the SRXes.   curl support is as recent as libslax 1.1 and Junos 14.2. (So, older than that and jcs:curl is off the table.)

 

See if the examples here help:

https://www.juniper.net/documentation/en_US/junos/topics/reference/general/junos-script-automation-l...

 

Lastly: for future reference, the quickest way to get help fixing a broken script is to post the code -- not just a description of the error.

 

hth

/doug

--
"There he goes. One of God's own prototypes. A high-powered mutant of some kind never even considered for mass production. Too weird to live, and too rare to die." --HST
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎06-27-2018 07:44 AM

The article you referenced is what we used for our 3rd test in which we imported the curl extension and ran curl:single. 

 

Note taken on posting the code....I didn't post code b/c it was very short and the actual line of code was included. Below I have included the simple script based on the example in the article. In short we just we are confused on translating a typical curl command to the slax extension such as the following:

(curl -O -H"Authorization: Basic *********" "https://testdomain.com/test.txt")

 

version 1.1;

ns curl extension = "http://xml.libslax.org/curl";

param $url = "https://testdomain.com/test.txt";

match / {
    <op-script-results> {
        var $options = {
            <header name="Authorization"> "Basic ************";
		
        }
        var $results = curl:single($url, $options);
        message "completed: " _ $results/headers/message;
        <curl> {
            copy-of $results;
        }
    }
}
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

[ Edited ]
‎06-27-2018 07:58 AM

OK.   Here's an example from a slax script that uses REST calls into Space.  This is just a fragment, but I think it shows a complete-but-concise example of how the Authorization stuff is made to work:

param $username;
param $password;
param $DEVNAME;

mvar $JSESSIONID;
mvar $JSESSIONIDSSO;

match / {
    /* hardcoded URL: this assumes we're running locally on the space appliance */
    var $url = jspace:server("localhost:8080", "/api/space/user-management/login");

    var $creds = concat($username,':',$password);
    var $authorization = "Basic " _ string(slax:base64-encode($creds));

    var $auth-params := {
        <url> $url;
        <method> "post";
        <insecure>;
        <header name="Authorization"> $authorization;
    }

    /* open session.*/
    var $curl = curl:open();

    /* Authenticate & get JSESSIONIDSSO, JSESSIONID */
    var $auth-resp = curl:perform($curl, $auth-params);

    /* No sense continuing if we get an error code. */
    if ($auth-resp/headers/code != 200) {
        expr jcs:output("Something wrong. Return code = ", $code);
        terminate;
    }

    /* Pull out cookie list to extract into named vars */
    var $cookies = $auth-resp/headers/header[@name="Set-Cookie"];
    set $JSESSIONID = jspace:extractcookie($cookies,'JSESSIONID');
    set $JSESSIONIDSSO = jspace:extractcookie($cookies,'JSESSIONIDSSO');

    expr jcs:output("DEBUG: JSESSIONID = ", $JSESSIONID);
    expr jcs:output("DEBUG: JSESSIONIDSSO = ", $JSESSIONIDSSO);

    var $rawdata = $auth-resp/raw-data;

/*
 * We have our session and tokens; now we can do our other API calls.
 */


N.B - I didn't not write the above code.  I got this from the indefatigable Andy Sharp, then modified it to meet my needs.  Any thanks go to Andy.   (Ignore the calls using jspace: namespace -- those are just custom slax functions and not really germane to the example -- so not included in this snip)

 

HTH.

/doug

--
"There he goes. One of God's own prototypes. A high-powered mutant of some kind never even considered for mass production. Too weird to live, and too rare to die." --HST
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎06-27-2018 12:20 PM

We didn't have any issues with the header and authorization but we were still unable to determine how to implement the --output option for curl using the curl extension in slax......

 

So we modified the scrit for it to download the file via <request-shell-execute> using traditional curl command. Obviously you can insert variables where needed. However the downside is it does not support HTTPS:( curl: (1) Protocol "https" not supported or disabled in libcurl)

 

 

version 1.0;
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";
import "../import/junos.xsl";

var $local = jcs:open();
match / {
    <op-script-results> {
        var $rpc = {
            <request-shell-execute> {
                <command> "curl -H 'Authorization: Basic **************' http://testdomain.com/test.txt -o /var/tmp/shelltest.txt";
            }
        }
        var $result = jcs:execute($local,$rpc);
        copy-of $result;
        expr jcs:close($local);
    }
}
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

[ Edited ]
‎06-27-2018 02:09 PM

If you used the slax curl() approach, is the file returned as base64-encoded?
If so then, could you just use slax:base64-decode() to translate/save the returned data ?

/doug

--
"There he goes. One of God's own prototypes. A high-powered mutant of some kind never even considered for mass production. Too weird to live, and too rare to die." --HST
Junos Automation (Scripting)

Re: Slax script to download file

‎06-28-2018 08:51 AM

The file was never downloaded becuase we couldn't specify the --output option. The log in space showed the following:

Which is why we went with the execute curl in shell.

Script execution output details: 
<op-script-results><curl><results><url>https://testdomain.com/test.txt</url><curl-success/><raw-headers>HTTP/1.1 200 OK&#13;
Content-Length: 4&#13;
Content-Type: application/octet-stream&#13;
Last-Modified: Thu, 21 Jun 2018 19:17:25 GMT&#13;
Accept-Ranges: bytes&#13;
ETag: "48e8bd7c949d41:0"&#13;
Server: Microsoft-IIS/10.0&#13;
Set-Cookie: BasicAuthentication=1; expires=Wed, 27-Jun-2018 16:25:46 GMT; path=/&#13;
X-Powered-By: ASP.NET&#13;
Set-Cookie: ARRAffinity=2e5dd814a4cb78f8a5825d56c5879cd18fa384d20597b10f3c685ffe2cff1f53;Path=/;HttpOnly;Domain=testdomain.com&#13;
Date: Wed, 27 Jun 2018 15:25:46 GMT&#13;
&#13;
</raw-headers><headers><version>HTTP/1.1</version><code>200</code><message>OK</message><header name="Content-Length">4</header><header name="Content-Type">application/octet-stream</header><header name="Last-Modified">Thu, 21 Jun 2018 19:17:25 GMT</header><header name="Accept-Ranges">bytes</header><header name="ETag">"48e8bd7c949d41:0"</header><header name="Server">Microsoft-IIS/10.0</header><header name="Set-Cookie">BasicAuthentication=1; expires=Wed, 27-Jun-2018 16:25:46 GMT; path=/</header><header name="X-Powered-By">ASP.NET</header><header name="Set-Cookie">ARRAffinity=2e5dd814a4cb78f8a5825d56c5879cd18fa384d20597b10f3c685ffe2cff1f53;Path=/;HttpOnly;Domain=testdomain.com</header><header name="Date">Wed, 27 Jun 2018 15:25:46 GMT</header></headers><raw-data>test</raw-data></results></curl></op-script-results>
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎06-30-2018 10:54 AM

Just thought of sharing this pointer on “Automatically Save and Offload Support Information”

 

https://forums.juniper.net/t5/Automation/Scripting-How-To-Automatically-save-and-offload-support/ta-...

 

-Python JNCIE 3X [SP|DC|ENT] JNCIP-SEC JNCDS 3X [ WAN | DC|SEC] JNCIS-Cloud JNCIS-DevOps CCIP ITIL
#Please mark my solution as accepted if it helped, Kudos are appreciated as well.
Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎07-19-2018 04:44 AM

Not sure it will help you but here's a code snippet from one of our scripts to do a file transfer from the router to an FTP server

var $filename = "/var/tmp/myfile.txt" ;
var $ftpurl = "ftp://x.x.x.x" ;

/* output the text to the local file system */
var $writing = <file-put> {
 <filename> $filename ;
 <permission> "666";
 <encoding> "ascii" ;
 <delete-if-exist>;
 <file-contents> $routes;
}
var $result-writing = jcs:execute($connection, $writing ) ;

/* copy the file to the ftp server */ 
var $copy := {
 <file-copy> {
  <source> $filename ;
  <destination> $ftpurl ;
 }
}
copy-of jcs:execute( $connection, $copy );

 

The documentation at https://www.juniper.net/documentation/en_US/junos/topics/concept/junos-software-formats-filenames-ur... seems to indicate the file copy command with http supports authentication:

http://hostname/path/filename—File on an HTTP server. You can also specify hostname as username@hostname or username:password@hostname. If a password is required and you omit it, you are prompted for it.

Note: You cannot specify a HTTP(s) URL for a file as a destination, because HTTP(s) URLs are not writable. However you can specify HTTP(s) URL for a file as a source.

Highlighted
Junos Automation (Scripting)

Re: Slax script to download file

‎07-19-2018 05:50 AM

Late reply I've been ooo for a bit.

Thanks for referencing that post. It has spawned some additional ideas for us for automation. 

 

Feedback