Skip to content

Commit

Permalink
Add /api/run/script
Browse files Browse the repository at this point in the history
  • Loading branch information
gschueler committed Feb 14, 2011
1 parent 2f8ad3f commit 26d1aaf
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 1 deletion.
2 changes: 1 addition & 1 deletion rundeckapp/grails-app/conf/UrlMappings.groovy
Expand Up @@ -22,7 +22,7 @@ class UrlMappings {
"/api/execution/$id/abort" (controller: 'execution', action: 'apiExecutionAbort')

"/api/run/command" (controller: 'scheduledExecution', action: 'apiRunCommand')
// "/api/run/script" (controller: 'scheduledExecution', action: 'runAndForget')
"/api/run/script" (controller: 'scheduledExecution', action: 'apiRunScript')

"/api/projects" (controller: 'framework', action: 'listProjects')
"/api/project/$project?" (controller: 'framework', action: 'getProject')
Expand Down
Expand Up @@ -14,6 +14,7 @@ import org.codehaus.groovy.grails.web.json.JSONElement
import com.dtolabs.rundeck.core.utils.NodeSet
import groovy.xml.MarkupBuilder
import com.dtolabs.client.utils.Constants
import com.dtolabs.utils.Streams

class ScheduledExecutionController {
def Scheduler quartzScheduler
Expand All @@ -31,6 +32,7 @@ class ScheduledExecutionController {
update:'POST',
apiJobsImport:'POST',
apiJobDelete:'DELETE',
apiRunScript:'POST',
deleteBulk:'DELETE'
]

Expand Down Expand Up @@ -2544,6 +2546,67 @@ class ScheduledExecutionController {
params.description=params.description?:""


def results=runAdhoc()
if(results.failed){
results.error=results.message
}
if(results.error){
flash.error=results.error
if(results.scheduledExecution){
flash.errors=[]
results.scheduledExecution.errors.allErrors.each{
flash.errors<<g.message(error:it)
}
}
return chain(controller:'api',action:'error')
}else{
return new ApiController().success{ delegate ->
delegate.'success'{
message("Immediate execution scheduled (${results.id})")
}
delegate.'execution'(id:results.id)
}
}
}


/**
* API: run script: /api/run/script, version 1.2
*/
def apiRunScript={

if(!params.project){
flash.error=g.message(code:'api.error.parameter.required',args:['project'])
return chain(controller:'api',action:'error')
}
if(!params.scriptFile){
flash.error=g.message(code:'api.error.parameter.required',args:['scriptFile'])
return chain(controller:'api',action:'error')
}
//test valid project
Framework framework = frameworkService.getFrameworkFromUserSession(session,request)

def exists=frameworkService.existsFrameworkProject(params.project,framework)
if(!exists){
flash.error=g.message(code:'api.error.item.doesnotexist',args:['project',params.project])
return chain(controller:'api',action:'error')
}

//read attached script content
def file = request.getFile("scriptFile")
if(file.empty) {
flash.error=g.message(code:'api.error.run-script.upload.is-empty')
return chain(controller:'api',action:'error')
}

def script=new String(file.bytes)

//remote any input parameters that should not be used when creating the execution
['options','scheduled'].each{params.remove(it)}
params.workflow=new Workflow(commands:[new CommandExec(adhocLocalString:script, adhocExecution:true, argString:params.argString)])
params.description=params.description?:""


def results=runAdhoc()
if(results.failed){
results.error=results.message
Expand Down
1 change: 1 addition & 0 deletions rundeckapp/grails-app/i18n/messages.properties
Expand Up @@ -255,4 +255,5 @@ api.error.jobs.import.wrong-contenttype=The input was not the expected content t
api.error.jobs.import.missing-file=No file was uploaded
api.error.jobs.import.format.unsupported=The specified format is not supported: {0}
api.error.jobs.import.empty=Jobs Document did not define any jobs, or was invalid
api.error.run-script.upload.is-empty=Input script file was empty
api.success.job.delete.message=Job was successfully deleted: {0}
100 changes: 100 additions & 0 deletions test/api/test-run-script.sh
@@ -0,0 +1,100 @@
#!/bin/bash

# TEST: /api/run/script action

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

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

proj="test"

# accept url argument on commandline, if '-' use default
url="$1"
if [ "-" == "$1" ] ; then
url='http://localhost:4440'
fi
shift
apiurl="${url}/api"
VERSHEADER="X-RUNDECK-API-VERSION: 1.2"

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

if [ ! -f $DIR/cookies ] ; then
# call rundecklogin.sh
sh $DIR/rundecklogin.sh $url
fi

XMLSTARLET=xml


# now submit req
runurl="${apiurl}/run/script"

echo "TEST: /api/run/script GET should fail with wrong HTTP method"
sh $DIR/api-expect-code.sh 405 "${runurl}" "project=" 'parameter "project" is required' && echo "OK" || exit 2

echo "TEST: /api/run/script POST should fail with no project param"
CURL_REQ_OPTS="-X POST" sh $DIR/api-expect-error.sh "${runurl}" "project=" 'parameter "project" is required' && echo "OK" || exit 2

echo "TEST: /api/run/script POST should fail with no scriptFile param"
params="project=${proj}"
CURL_REQ_OPTS="-X POST" sh $DIR/api-expect-error.sh "${runurl}" "${params}" 'parameter "scriptFile" is required' && echo "OK" || exit 2

echo "TEST: /api/run/script POST should fail with empty scriptFile content"
touch $DIR/test.tmp
$CURL --header "$VERSHEADER" -F scriptFile=@$DIR/test.tmp ${runurl}?${params} > $DIR/curl.out
if [ 0 != $? ] ; then
errorMsg "FAIL: failed query request"
exit 2
fi

sh $DIR/api-test-error.sh $DIR/curl.out "Input script file was empty" && echo "OK" || exit 2

####
# echo a script into a temp file
####
cat <<END > $DIR/script.tmp
#!/bin/bash
echo hello
echo @node.name@ > $DIR/script.out
END

#remove script.out if it exists

[ -f $DIR/script.out ] && rm $DIR/script.out

echo "TEST: /api/run/script should succeed and return execution id"
# make api request
$CURL --header "$VERSHEADER" -F scriptFile=@$DIR/script.tmp ${runurl}?${params} > $DIR/curl.out
if [ 0 != $? ] ; then
errorMsg "FAIL: failed query request"
exit 2
fi

sh $DIR/api-test-success.sh $DIR/curl.out || exit 2

execid=$($XMLSTARLET sel -T -t -o "Execution started with ID: " -v "/result/execution/@id" -n $DIR/curl.out)
if [ "" == "${execid}" ] ; then
errorMsg "FAIL: expected execution id in result: ${execid}"
exit 2
fi

##wait for script to execute...
sleep 3

if [ ! -f $DIR/script.out ] ; then
errorMsg "FAIL: Expected script to execute and create script.out file"
exit 2
else
cat $DIR/script.out
rm $DIR/script.out
fi


echo "OK"

rm $DIR/curl.out

0 comments on commit 26d1aaf

Please sign in to comment.