Skip to content

Commit

Permalink
Merge pull request #5153 from caseyduquettesc/casey-master
Browse files Browse the repository at this point in the history
Add system property to override inbound TCP agent address
  • Loading branch information
MarkEWaite authored Jan 8, 2021
2 parents 17afd3e + 5750874 commit 3d297b3
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 2 deletions.
27 changes: 27 additions & 0 deletions core/src/main/java/hudson/slaves/JNLPLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import jenkins.model.Jenkins;
import jenkins.slaves.RemotingWorkDirSettings;
import jenkins.util.SystemProperties;
import jenkins.util.java.JavaUtils;
import jenkins.websocket.WebSockets;
import org.jenkinsci.Symbol;
Expand Down Expand Up @@ -76,6 +77,13 @@ public class JNLPLauncher extends ComputerLauncher {

private boolean webSocket;

/**
* @see #getInboundAgentUrl()
*/
@NonNull
@Restricted(NoExternalUse.class)
public static final String CUSTOM_INBOUND_URL_PROPERTY = "jenkins.agent.inboundUrl";

/**
* Constructor.
* @param tunnel Tunnel settings
Expand Down Expand Up @@ -249,4 +257,23 @@ public FormValidation doCheckWebSocket(@QueryParameter boolean webSocket, @Query
public boolean isJavaWebStartSupported() {
return JavaUtils.isRunningWithJava8OrBelow();
}

/**
* Overrides the url that inbound TCP agents should connect to
* as advertised in the agent.jnlp file. If not set, the default
* behavior is unchanged and returns the root URL.
*
* This enables using a private address for inbound tcp agents,
* separate from Jenkins root URL.
*
* @see <a href="https://issues.jenkins-ci.org/browse/JENKINS-63222">JENKINS-63222</a>
*/
@Restricted(NoExternalUse.class)
public static String getInboundAgentUrl() {
String url = SystemProperties.getString(CUSTOM_INBOUND_URL_PROPERTY);
if (url == null || url.isEmpty()) {
return Jenkins.get().getRootUrl();
}
return url;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson">
<l:view contentType="application/x-java-jnlp-file">
<j:set var="rootURL" value="${app.rootUrl}" />
<j:invokeStatic var="rootURL" className="hudson.slaves.JNLPLauncher" method="getInboundAgentUrl" />

<!--
See http://www.dallaway.com/acad/webstart/ for obtaining the certificate.
Expand Down
2 changes: 1 addition & 1 deletion test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ THE SOFTWARE.
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>2.68</version>
<version>2.69</version>
<scope>test</scope>
<exclusions>
<exclusion>
Expand Down
105 changes: 105 additions & 0 deletions test/src/test/java/hudson/slaves/AgentInboundUrlTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* The MIT License
*
* Copyright (c) 2021, Snap, Inc., Casey Duquette
*
* 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.slaves;

import com.gargoylesoftware.htmlunit.xml.XmlPage;
import hudson.Util;
import hudson.model.Computer;
import hudson.model.Node;
import hudson.model.Slave;
import jenkins.model.Jenkins;
import org.dom4j.Document;
import org.dom4j.io.DOMReader;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.FlagRule;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.LoggerRule;
import org.jvnet.hudson.test.MockAuthorizationStrategy;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* Tests of {@link JNLPLauncher} using a custom inbound agent url.
*/
public class AgentInboundUrlTest {
@Rule
public JenkinsRule j = new JenkinsRule();

@Rule
public LoggerRule logging = new LoggerRule().record(Slave.class, Level.FINE);

// Override the inbound agent url
private static final String customInboundUrl = "http://localhost:8080/jenkins";

@Rule
public final FlagRule<String> customInboundUrlRule = FlagRule.systemProperty(JNLPLauncher.CUSTOM_INBOUND_URL_PROPERTY, customInboundUrl);

@Issue("JENKINS-63222")
@Test
public void testInboundAgentUrlOverride() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
MockAuthorizationStrategy authorizationStrategy = new MockAuthorizationStrategy();
authorizationStrategy.grant(Jenkins.ADMINISTER).everywhere().toEveryone();
j.jenkins.setAuthorizationStrategy(authorizationStrategy);

// Create an agent
addTestAgent();

// parse the JNLP page into DOM to inspect the jnlp url argument.
JenkinsRule.WebClient agent = j.createWebClient();
XmlPage jnlp = (XmlPage) agent.goTo("computer/test/jenkins-agent.jnlp", "application/x-java-jnlp-file");
Document dom = new DOMReader().read(jnlp.getXmlDocument());
Object arg = dom.selectSingleNode("//application-desc/argument[3]/following-sibling::argument[1]");
String val = ((org.dom4j.Element) arg).getText();
assertEquals(customInboundUrl, val);
}

/**
* Adds an Inbound TCP agent to the system and returns it.
*/
private void addTestAgent() throws Exception {
addTestAgent(new JNLPLauncher(false));
}

/**
* Adds an Inbound TCP agent to the system and returns it.
*/
private void addTestAgent(ComputerLauncher launcher) throws Exception {
List<Node> agents = new ArrayList<>(j.jenkins.getNodes());
File dir = Util.createTempDir();
agents.add(new DumbSlave("test", "dummy", dir.getAbsolutePath(), "1", Node.Mode.NORMAL, "",
launcher, RetentionStrategy.INSTANCE, new ArrayList<>()));
j.jenkins.setNodes(agents);
Computer c = j.jenkins.getComputer("test");
assertNotNull(c);
}
}

0 comments on commit 3d297b3

Please sign in to comment.