Skip to content

Commit

Permalink
Merge branch 'JENKINS-14964' of https://github.com/agudian/scriptler-…
Browse files Browse the repository at this point in the history
…plugin into agudian-JENKINS-14964
  • Loading branch information
imod committed Feb 10, 2014
2 parents ec2e01c + c6e3712 commit dbb18c4
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 2 deletions.
Expand Up @@ -40,7 +40,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.ServletException;
Expand Down Expand Up @@ -105,7 +108,7 @@ public String getIconFileName() {
public String getUrlName() {
return "scriptler";
}

public boolean disableRemoteCatalog() {
return getConfiguration().isDisbableRemoteCatalog();
}
Expand Down Expand Up @@ -473,6 +476,82 @@ public void doTriggerScript(StaplerRequest req, StaplerResponse rsp, @QueryParam
req.setAttribute("readOnly", !isChangeScriptAllowed);
req.getView(this, "runscript.jelly").forward(req, rsp);
}

/**
* Trigger/run/execute the script on a slave and directly forward the result/output to the response.
*
* @param req
* request
* @param rsp
* response
* @param script
* the script code (groovy)
* @param node
* the node, to execute the code on, defaults to {@value #MASTER}
* @param contentType
* the contentType to use in the response, defaults to text/plain
* @throws IOException
* @throws ServletException
*/
public void doRun(StaplerRequest req, StaplerResponse rsp, @QueryParameter(fixEmpty = true) String script,
@QueryParameter(fixEmpty = true) String node, @QueryParameter(fixEmpty = true) String contentType)
throws IOException, ServletException {

checkPermission(getRequiredPermissionForRunScript());

String id = req.getRestOfPath();
if (id.startsWith("/")) {
id = id.substring(1);
}

if (StringUtils.isEmpty(id)) {
throw new RuntimeException("Please specify a script id. Use /scriptler/run/<yourScriptId>");
}

Script tempScript = ScriptHelper.getScript(id, true);

if (tempScript == null) {
throw new RuntimeException("Unknown script: " + id + ". Use /scriptler/run/<yourScriptId>");
}

final boolean isAdmin = Jenkins.getInstance().getACL().hasPermission(Jenkins.ADMINISTER);
final boolean isChangeScriptAllowed = isAdmin || allowRunScriptEdit();

if (script == null || !isChangeScriptAllowed) {
// use original script
script = tempScript.script;
}

Parameter[] paramArray = prepareParameters(req, tempScript);

rsp.setContentType(contentType == null ? "text/plain" : contentType);

final String[] slaves = resolveSlaveNames(node == null ? MASTER : node);
if (slaves.length > 1) {
rsp.getOutputStream().print(ScriptHelper.runScript(slaves, script, paramArray));
}
else {
rsp.getOutputStream().print(ScriptHelper.runScript(slaves[0], script, paramArray));
}
}

@SuppressWarnings("unchecked")
private Parameter[] prepareParameters(StaplerRequest req, Script tempScript) {
// retain default parameter values
Map<String, Parameter> params = new HashMap<String, Parameter>();
for (Parameter param : tempScript.getParameters()) {
params.put(param.getName(), param);
}

// overwrite parameters that are passed as parameters
for (Map.Entry<String, String[]> param : (Set<Map.Entry<String, String[]>>) req.getParameterMap().entrySet()) {
if (params.containsKey(param.getKey())) {
params.put(param.getKey(), new Parameter(param.getKey(), param.getValue()[0]));
}
}
Parameter[] paramArray = params.values().toArray(new Parameter[params.size()]);
return paramArray;
}

private String[] resolveSlaveNames(String nameAlias) {
List<String> slaves = null;
Expand Down
Expand Up @@ -21,7 +21,8 @@
# THE SOFTWARE.

title=Run a script
intro=Please select a slave you would like to run the script on. You can also modify the script to your needs, the changes will not effect the stored version of it!
intro=Please select a slave you would like to run the script on. You can also modify the script to your needs, the changes will not effect the stored version of it!<br /><br />\
You can also run a script using GET or POST to the URL /scriptler/run/&lt;your-script-id&gt; with the optional parameters node, script (alternative script text), contentType, and the parameters defined for your stored script.
executiononclient=This execution happens in the slave agent JVM...
SelectionNode=Select a node
ParametersDescription=Define script parameters
Expand Down
@@ -0,0 +1,64 @@
package org.jenkinsci.plugins.scriptler.restapi;

import static org.junit.Assert.assertEquals;
import hudson.model.FileParameterValue.FileItemImpl;

import java.io.File;
import java.net.URLEncoder;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;
import org.jenkinsci.plugins.scriptler.ScriptlerManagementHelper;
import org.jenkinsci.plugins.scriptler.ScriptlerManagment;
import org.jenkinsci.plugins.scriptler.config.Parameter;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.Page;

public class ScriptlerRestApiTest {

private static final String SCRIPT_ID = "dummy.groovy";

@Rule
public JenkinsRule j = new JenkinsRule();

@Before
public void setup() throws Exception {
final ScriptlerManagment scriptler = j.getInstance().getExtensionList(ScriptlerManagment.class).get(0);
ScriptlerManagementHelper helper = new ScriptlerManagementHelper(scriptler);
File f = new File(SCRIPT_ID);
FileUtils.writeStringToFile(f, "print \"hello $arg1, this is $arg2.\"");
FileItem fi = new FileItemImpl(f);
helper.saveScript(fi, true, SCRIPT_ID);

scriptler.getConfiguration().getScriptById(SCRIPT_ID)
.setParameters(new Parameter[]{ new Parameter("arg1", "world"), new Parameter("arg2", "scriptler") });
}

@Test
public void testSuccessWithDefaults() throws Exception {
Page goTo = j.createWebClient().goTo("scriptler/run/dummy.groovy", "text/plain");
j.assertGoodStatus(goTo);

assertEquals("hello world, this is scriptler.", goTo.getWebResponse().getContentAsString());
}

@Test
public void testSuccessWithAllChanged() throws Exception {
Page goTo = j.createWebClient()
.goTo("scriptler/run/dummy.groovy?script=" + URLEncoder.encode("print \"welcome, $arg1 and $arg2!\"",
"UTF-8") + "&arg1=foo&arg2=bar&contentType=application/foobar", "application/foobar");
j.assertGoodStatus(goTo);

assertEquals("welcome, foo and bar!", goTo.getWebResponse().getContentAsString());
}

@Test(expected = FailingHttpStatusCodeException.class)
public void testUnknownScript() throws Exception {
j.createWebClient().goTo("scriptler/run/unknown.groovy", "text/plain");
}
}

0 comments on commit dbb18c4

Please sign in to comment.