From 548e9b8bbf7910227e416417d498a505cd847d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Sun, 9 Jun 2013 00:42:18 +0200 Subject: [PATCH] [JENKINS-18282] Introduce get-node CLI command --- .../main/java/hudson/cli/GetNodeCommand.java | 60 +++++++++ .../cli/handlers/NodeOptionHandler.java | 68 ++++++++++ .../resources/hudson/cli/Messages.properties | 2 + .../java/hudson/cli/GetNodeCommandTest.java | 122 ++++++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 core/src/main/java/hudson/cli/GetNodeCommand.java create mode 100644 core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java create mode 100644 test/src/test/java/hudson/cli/GetNodeCommandTest.java diff --git a/core/src/main/java/hudson/cli/GetNodeCommand.java b/core/src/main/java/hudson/cli/GetNodeCommand.java new file mode 100644 index 0000000000..e2bf3410da --- /dev/null +++ b/core/src/main/java/hudson/cli/GetNodeCommand.java @@ -0,0 +1,60 @@ +/* + * The MIT License + * + * Copyright (c) 2013, Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.Extension; +import hudson.model.Node; + +import java.io.IOException; + +import jenkins.model.Jenkins; + +import org.kohsuke.args4j.Argument; + +/** + * @author ogondza + * @since XXX + */ +@Extension +public class GetNodeCommand extends CLICommand { + + @Argument(metaVar="NODE", usage="Name of the node", required=true) + public Node node; + + @Override + public String getShortDescription() { + + return Messages.GetNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws IOException { + + node.checkPermission(Jenkins.ADMINISTER); + + Jenkins.XSTREAM2.toXMLUTF8(node, stdout); + + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java new file mode 100644 index 0000000000..24e7a5aed6 --- /dev/null +++ b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java @@ -0,0 +1,68 @@ +/* + * The MIT License + * + * Copyright (c) 2013, Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli.handlers; + +import hudson.model.Node; +import jenkins.model.Jenkins; + +import org.kohsuke.MetaInfServices; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; + +/** + * Refers to {@link Node} by its name. + * + * @author ogondza + * @since XXX + */ +@MetaInfServices +public class NodeOptionHandler extends OptionHandler { + + public NodeOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { + + super(parser, option, setter); + } + + @Override + public int parseArguments(Parameters params) throws CmdLineException { + + String nodeName = params.getParameter(0); + + final Node node = Jenkins.getInstance().getNode(nodeName); + if (node == null) throw new CmdLineException(owner, "No such node '" + nodeName + "'"); + + setter.addValue(node); + return 1; + } + + @Override + public String getDefaultMetaVariable() { + + return "NODE"; + } +} diff --git a/core/src/main/resources/hudson/cli/Messages.properties b/core/src/main/resources/hudson/cli/Messages.properties index b57837eca4..4b71adcca7 100644 --- a/core/src/main/resources/hudson/cli/Messages.properties +++ b/core/src/main/resources/hudson/cli/Messages.properties @@ -44,6 +44,8 @@ VersionCommand.ShortDescription=\ Outputs the current version. GetJobCommand.ShortDescription=\ Dumps the job definition XML to stdout +GetNodeCommand.ShortDescription=\ + Dumps the node definition XML to stdout SetBuildDisplayNameCommand.ShortDescription=\ Sets the displayName of a build WhoAmICommand.ShortDescription=\ diff --git a/test/src/test/java/hudson/cli/GetNodeCommandTest.java b/test/src/test/java/hudson/cli/GetNodeCommandTest.java new file mode 100644 index 0000000000..26be160250 --- /dev/null +++ b/test/src/test/java/hudson/cli/GetNodeCommandTest.java @@ -0,0 +1,122 @@ +/* + * The MIT License + * + * Copyright 2013 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.cli; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.text.IsEmptyString.isEmptyString; +import hudson.model.User; +import hudson.security.Permission; +import hudson.security.GlobalMatrixAuthorizationStrategy; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Locale; + +import jenkins.model.Jenkins; + +import org.apache.commons.io.input.NullInputStream; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +public class GetNodeCommandTest { + + private final ByteArrayOutputStream out = new ByteArrayOutputStream(); + private final ByteArrayOutputStream err = new ByteArrayOutputStream(); + + private GetNodeCommand command; + + @Rule public final JenkinsRule j = new JenkinsRule(); + + @Before public void setUp() { + + command = new GetNodeCommand(); + } + + @Test public void getNodeShouldFailWithoutAdministerPermision() throws Exception { + + forUser("user"); + + j.createSlave("MySlave", null, null); + + final int result = execute("MySlave"); + + assertThat(err.toString(), containsString("user is missing the Administer permission")); + assertThat("No output expected", out.toString(), isEmptyString()); + assertThat("Command is expected to fail", result, equalTo(-1)); + } + + @Test public void getNodeShouldYieldConfigXml() throws Exception { + + forUser("administrator"); + + j.createSlave("MySlave", null, null); + + final int result = execute("MySlave"); + + assertThat(out.toString(), startsWith("")); + assertThat(out.toString(), containsString("MySlave")); + assertThat("No error output expected", err.toString(), isEmptyString()); + assertThat("Command is expected to succeed", result, equalTo(0)); + } + + @Test public void getNodeShouldFailIfNodeDoesNotExist() throws Exception { + + forUser("administrator"); + + final int result = execute("MySlave"); + + assertThat(err.toString(), containsString("No such node 'MySlave'")); + assertThat("No output expected", out.toString(), isEmptyString()); + assertThat("Command is expected to fail", result, equalTo(-1)); + } + + private void forUser(final String user) { + + JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm(); + realm.addGroups("user", "group"); + realm.addGroups("administrator", "administrator"); + j.jenkins.setSecurityRealm(realm); + + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + auth.add(Permission.READ, "group"); + auth.add(Jenkins.ADMINISTER, "administrator"); + j.jenkins.setAuthorizationStrategy(auth); + + command.setTransportAuth(User.get(user).impersonate()); + } + + private int execute(final String... args) { + + return command.main( + Arrays.asList(args), Locale.ENGLISH, new NullInputStream(0), new PrintStream(out), new PrintStream(err) + ); + } +} -- GitLab