Skip to content

Instantly share code, notes, and snippets.

@gschueler
Created January 18, 2011 04:07
Show Gist options
  • Save gschueler/783971 to your computer and use it in GitHub Desktop.
Save gschueler/783971 to your computer and use it in GitHub Desktop.
How to run a rundeck job using curl

Run a Job using Curl

This document describes how to use CURL to interact with the RunDeck server to invoke a Job to run.

The steps are as follows:

  1. Authenticate to the RunDeck server and acquire a session cookie.

  2. Submit run request for particular Job ID, sending session cookie.

  3. Authenticate


The following script logs in with default admin username/pass to localhost:4440, and saves the cookies into "cookies" file. It fails if http request fails, or user unauthorized.

The request submits j_username and j_password params to the url $SERVERURL/j_security_check. The response should be a redirect (302) to the root path of the server. Otherwise the response will be a redirect to $SERVERURL/user/error.

#!/bin/bash

#usage: runjob.sh <server URL | - > <job ID>

errorMsg() {
   echo "$*" 1>&2
}

DIR=$(cd `dirname $0` && pwd)

# accept url argument on commandline, if '-' use default
url=$1
if [ "-" == "$url" ] ; then
    url='http://localhost:4440'
fi
loginurl="${url}/j_security_check"

# curl opts to use a cookie jar, and follow redirects, showing only errors
CURLOPTS=-s -S -L -c $DIR/cookies -b $DIR/cookies

#curl command to use with opts
CURL=curl $CURLOPTS

# submit login request
echo "Login..."
$CURL -d j_username=admin -d j_password=admin $loginurl > $DIR/curl.out 
if [ 0 != $? ] ; then
    errorMsg "failed login request to ${loginurl}"
    exit 2
fi

# make sure result doesn't contain the login form again, implying login failed
grep 'j_security_check' -q $DIR/curl.out 
if [ 0 == $? ] ; then
    errorMsg "login was not successful"
    exit 2
fi

echo "Login OK"
  1. Submit run request for job

The request to run the job is submitted to $SERVERURL/scheduledExecution/runJobByName.xml. The responses for the run request are in XML, so a tool like xmlstarlet is useful.

The job to be run can be specified in two ways

  1. Specify the Job ID, using an id parameter.
  2. Specify the Job name, and optional group, using the jobName and groupPath parameters.

If the specified job name and group do not uniquely identify a job, then an error response will be returned.

The job can accept arguments specified with the extra.argString parameter.

Additionally, nodeset filters defined in the job can be overridden. To do so, include a parameter extra.doNodeDispatch=true. As well as filter parameters of the form: extra.node(Include|Exclude)[filter]=value. Where "filter" is one of "" (blank, indicating hostname), "name","tags","osFamily", etc.. As well, extra.nodeThreadcount and extra.nodeKeepgoing can be specified.

The XML response will either be a success response, or error response.

Error response:

<response error='true'>
    <error>
        <message>error message</message>
    </error>
</response>

A success response will include information about the successful execution request:

<response success='true'>
    <success>
        <message>success message</message>
    </success>
    <succeeded count="x">
        <execution>
            <id>..</id>
            <name>job name</name>
            <url>...</url>
        </execution>
    </succeeded>
</response>

The <id> element will contain the ID of the execution, and the <url> element will contain the URL (relative to the $SERVERURL) for viewing the output.

Here is the continuation of the previous shell script to submit the run request:

XMLSTARLET=xml

# now submit req
jobid=$3
params="id=${jobid}"
runurl="${url}/scheduledExecution/runJobByName.xml"
echo "Submit job..."
# get nodes page
$CURL ${runurl}?${params} > $DIR/curl.out
if [ 0 != $? ] ; then
    errorMsg "failed nodes request"
    exit 2
fi

#test curl.out for valid xml
$XMLSTARLET val -w $DIR/curl.out > /dev/null 2>&1
if [ 0 != $? ] ; then
    errorMsg "ERROR: Response was not valid xml"
    exit 2
fi

#test for expected /result element
$XMLSTARLET el $DIR/curl.out | grep -e '^result' -q
if [ 0 != $? ] ; then
    errorMsg "ERROR: Response did not contain expected result"
    exit 2
fi

#If <result error="true"> then an error occured.
waserror=$($XMLSTARLET sel -T -t -v "/result/@error" $DIR/curl.out)
if [ "true" == "$waserror" ] ; then
    errorMsg "Server reported an error: "
    $XMLSTARLET sel -T -t -v "/result/error/message" -n  $DIR/curl.out
    exit 2
fi

#If <response success='true'> then request succeeded.
wassuccess=$($XMLSTARLET sel -T -t -v "/result/@success" $DIR/curl.out)
if [ "true" == "$wassuccess" ] ; then
    echo "Job submitted successfully."
    $XMLSTARLET sel -T -t -v "/result/success/message" -n  $DIR/curl.out
    
    #echo execution id
    $XMLSTARLET sel -T -t -o "Execution ID: " -v "/result/succeeded/execution/id" -n $DIR/curl.out
    
    #echo job name
    $XMLSTARLET sel -T -t -o "Job name: " -v "/result/succeeded/execution/name" -n $DIR/curl.out
    
    #echo execution URL, which is relative to base server URL
    $XMLSTARLET sel -T -t  -o "Output url: $url" -v "/result/succeeded/execution/url" -n $DIR/curl.out
    
    #echo all on one line
    $XMLSTARLET sel -T -t -m "/result/succeeded/execution" -o "[" -v "id" -o "] " -v "name" -o ' &lt;' -v "url" -o '&gt;' -n $DIR/curl.out
fi

#rm $DIR/curl.out
rm $DIR/cookies
@sebastianwahn
Copy link

The first problem with the -S comes from the fact that bash has a problem with the line CURLOPTS=-s -S -L -c $DIR/cookies -b $DIR/cookies.
If you encapsulate the parameters with "" it will work: CURLOPTS="-s -S -L -c $DIR/cookies -b $DIR/cookies".

Second, the endpoint ${url}/scheduledExecution/runJobByName.xml isn't supported anymore in never versions of rundeck.
You can use the API which is mentioned under Run-Job-API.

Third, the xml command is not found, due to the fact that this tool is missing on your machine (can be maybe installed; or replace it with grep).

Maybe my answer is a little bit late, but it could still help you or others when using the above script. Maybe the script could also be updated for current versions of rundeck.

@nilroy
Copy link

nilroy commented Apr 20, 2016

Hi,
I am trying to do the same thing with rest-client ruby gem. Like this
x = RestClient.post 'https:/my_rundeck/j_security_check', :j_username => "user", :j_password => "password", :accept => :json
But the POST request always returns RestClient::Found: 302 Found and the response is a nil object.

I know this might not be the correct place of posting this question. But still if anybody has been able to do this please help.

Br
Nilanjan

@Dmitry1987
Copy link

It is better to run jobs using auth token:
http://your-rundeck:8080/api/16/job/a5434f6d-8c66-4c6c-a854-f7ff34f3cc6/run?authtoken=******************

we did it with nodejs script and i'm now composing a curl string to run from somewhere else. got to this page while googling for example of using POST with arguments :)

@Sir-Will
Copy link

@Dmitry1987 can you post a snippet of your nodejs script?
I would like to run a job via nodejs too, just don't know how to do it yet.

@zhjchen
Copy link

zhjchen commented Sep 28, 2017

curl -X POST http://your-rundeck:8080/api/16/job/a5434f6d-8c66-4c6c-a854-f7ff34f3cc6/run?authtoken=******************

It returned the job definition in response. Is it able to disable it ?

@seraph777
Copy link

Hello everybody,

I did this curl -X POST http://10.14.91.17:4440/api/21/job/d6a2cace-d5a1-45b7-b1d5-e424ac0f68b4/run?authtoken=4shBx4TqSOsmXXXXXXXXXXXX

but I Receive this message:


Not authorized for action "Run" for Job ID d6a2cace-d5a1-45b7-b1d5-e424ac0f68b4

Could you help to solve this ?

@fossouo
Copy link

fossouo commented Nov 23, 2017

Hello @seraph777
you need to setup acl for that user or acl base on the token.

BR
Donald F.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment