From 5f023b042f85a9cbb893551cd9c3b21a2daf58bf Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Fri, 1 Dec 2023 11:41:35 +0000 Subject: [PATCH] Fix proxy handling --- .../jenkins/pipeline/SauceConnectStep.java | 37 ++++++++++++++----- .../plugins/sauce_ondemand/BrowserAxis.java | 4 +- .../sauce_ondemand/JenkinsSauceREST.java | 21 +++++------ .../plugins/sauce_ondemand/PluginImpl.java | 2 +- .../SauceOnDemandBuildAction.java | 4 +- .../SauceOnDemandBuildWrapper.java | 18 ++++++--- .../SauceOnDemandReportPublisher.java | 4 +- .../SauceParameterDefinition.java | 4 +- .../sauce_ondemand/SauceParameterValue.java | 2 +- .../sauce_ondemand/SauceTestResultsById.java | 7 +++- .../credentials/SauceCredentials.java | 7 ++-- .../sauce_ondemand/SauceBuildWrapperTest.java | 2 +- .../sauce_ondemand/mocks/MockSauceREST.java | 2 +- 13 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/saucelabs/jenkins/pipeline/SauceConnectStep.java b/src/main/java/com/saucelabs/jenkins/pipeline/SauceConnectStep.java index f1a355f0..3d1eb40c 100644 --- a/src/main/java/com/saucelabs/jenkins/pipeline/SauceConnectStep.java +++ b/src/main/java/com/saucelabs/jenkins/pipeline/SauceConnectStep.java @@ -8,6 +8,7 @@ import com.saucelabs.jenkins.HudsonSauceManagerFactory; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.ProxyConfiguration; import hudson.Util; import hudson.model.Computer; import hudson.model.Item; @@ -21,11 +22,14 @@ import hudson.plugins.sauce_ondemand.SauceOnDemandBuildWrapper; import hudson.plugins.sauce_ondemand.credentials.SauceCredentials; import hudson.util.ListBoxModel; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; + +import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.workflow.steps.BodyExecution; @@ -66,7 +70,8 @@ public StepExecution start(StepContext context) throws Exception { useGeneratedTunnelIdentifier, verboseLogging, sauceConnectPath, - useLatestSauceConnect + useLatestSauceConnect, + Jenkins.get().getProxy() ); } @@ -154,8 +159,9 @@ private static final class SauceStartConnectHandler extends MasterToSlaveCallabl private final Boolean verboseLogging; private final String sauceConnectPath; private final Boolean useLatestSauceConnect; + private final ProxyConfiguration proxy; - SauceStartConnectHandler(SauceCredentials sauceCredentials, int port, String options, TaskListener listener, Boolean verboseLogging, String sauceConnectPath, Boolean useLatestSauceConnect) { + SauceStartConnectHandler(SauceCredentials sauceCredentials, int port, String options, TaskListener listener, Boolean verboseLogging, String sauceConnectPath, Boolean useLatestSauceConnect, ProxyConfiguration proxy) { this.sauceCredentials = sauceCredentials; this.port = port; this.options = options; @@ -163,12 +169,13 @@ private static final class SauceStartConnectHandler extends MasterToSlaveCallabl this.verboseLogging = verboseLogging; this.sauceConnectPath = sauceConnectPath; this.useLatestSauceConnect = useLatestSauceConnect; + this.proxy = proxy; } @Override public Void call() throws AbstractSauceTunnelManager.SauceConnectException { SauceConnectFourManager sauceTunnelManager = getSauceTunnelManager(); - sauceTunnelManager.setSauceRest(sauceCredentials.getSauceREST()); + sauceTunnelManager.setSauceRest(sauceCredentials.getSauceREST(proxy)); sauceTunnelManager.setUseLatestSauceConnect(useLatestSauceConnect); sauceTunnelManager.openConnection( sauceCredentials.getUsername(), @@ -190,17 +197,19 @@ private static final class SauceStopConnectHandler extends MasterToSlaveCallable private final SauceCredentials sauceCredentials; private final String options; private final TaskListener listener; + private final ProxyConfiguration proxy; - SauceStopConnectHandler(SauceCredentials sauceCredentials, String options, TaskListener listener) { + SauceStopConnectHandler(SauceCredentials sauceCredentials, String options, TaskListener listener, ProxyConfiguration proxy) { this.sauceCredentials = sauceCredentials; this.options = options; this.listener = listener; + this.proxy = proxy; } @Override public Void call() throws AbstractSauceTunnelManager.SauceConnectException { SauceConnectFourManager sauceTunnelManager = getSauceTunnelManager(); - sauceTunnelManager.setSauceRest(sauceCredentials.getSauceREST()); + sauceTunnelManager.setSauceRest(sauceCredentials.getSauceREST(proxy)); sauceTunnelManager.closeTunnelsForPlan( sauceCredentials.getUsername(), options, @@ -219,6 +228,7 @@ public static class SauceConnectStepExecution extends StepExecution { private final boolean useLatestSauceConnect; private static final long serialVersionUID = 1L; + private final ProxyConfiguration proxy; private BodyExecution body; @@ -229,7 +239,8 @@ public SauceConnectStepExecution( boolean useGeneratedTunnelIdentifier, boolean verboseLogging, String sauceConnectPath, - boolean useLatestSauceConnect + boolean useLatestSauceConnect, + ProxyConfiguration proxy ) { super(context); this.globalOptions = globalOptions; @@ -238,6 +249,7 @@ public SauceConnectStepExecution( this.verboseLogging = verboseLogging; this.sauceConnectPath = sauceConnectPath; this.useLatestSauceConnect = useLatestSauceConnect; + this.proxy = proxy; } @Override @@ -290,13 +302,14 @@ public boolean start() throws Exception { listener, verboseLogging, sauceConnectPath, - useLatestSauceConnect + useLatestSauceConnect, + proxy ); computer.getChannel().call(handler); body = getContext().newBodyInvoker() .withContext(EnvironmentExpander.merge(getContext().get(EnvironmentExpander.class), new ExpanderImpl(overrides))) - .withCallback(new Callback(sauceCredentials, options)) + .withCallback(new Callback(sauceCredentials, options, proxy)) .withDisplayName("Sauce Connect") .start(); @@ -320,10 +333,13 @@ private static final class Callback extends BodyExecutionCallback.TailCall { private final String options; private final SauceCredentials sauceCredentials; + private final ProxyConfiguration proxy; + - Callback(SauceCredentials sauceCredentials, String options) { + Callback(SauceCredentials sauceCredentials, String options, ProxyConfiguration proxy) { this.sauceCredentials = sauceCredentials; this.options = options; + this.proxy = proxy; } @Override protected void finished(StepContext context) throws Exception { @@ -333,7 +349,8 @@ private static final class Callback extends BodyExecutionCallback.TailCall { SauceStopConnectHandler stopConnectHandler = new SauceStopConnectHandler( sauceCredentials, options, - listener + listener, + proxy ); computer.getChannel().call(stopConnectHandler); } diff --git a/src/main/java/hudson/plugins/sauce_ondemand/BrowserAxis.java b/src/main/java/hudson/plugins/sauce_ondemand/BrowserAxis.java index ae10b8c2..ce669d73 100755 --- a/src/main/java/hudson/plugins/sauce_ondemand/BrowserAxis.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/BrowserAxis.java @@ -30,6 +30,8 @@ import hudson.matrix.MatrixBuild; import hudson.matrix.MatrixProject; import hudson.plugins.sauce_ondemand.credentials.SauceCredentials; +import jenkins.model.Jenkins; + import java.util.List; import java.util.Map; @@ -42,7 +44,7 @@ public abstract class BrowserAxis extends Axis { /** Handles the retrieval of browsers from Sauce Labs. */ - protected static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST)); + protected static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST, Jenkins.get().getProxy())); private transient MatrixProject project; public BrowserAxis(List values) { diff --git a/src/main/java/hudson/plugins/sauce_ondemand/JenkinsSauceREST.java b/src/main/java/hudson/plugins/sauce_ondemand/JenkinsSauceREST.java index 6826f3ab..37031cd9 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/JenkinsSauceREST.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/JenkinsSauceREST.java @@ -29,8 +29,8 @@ public class JenkinsSauceREST extends SauceREST { "Jenkins/" + Jenkins.VERSION + " " + "JenkinsSauceOnDemand/" + BuildUtils.getCurrentVersion(); private String server = getSauceRestUrlFromEnv(); - public JenkinsSauceREST(String username, String accessKey, DataCenter dataCenter) { - super(username, accessKey, dataCenter, getJenkinsPluginHttpConfig(dataCenter)); + public JenkinsSauceREST(String username, String accessKey, DataCenter dataCenter, ProxyConfiguration proxy) { + super(username, accessKey, dataCenter, getJenkinsPluginHttpConfig(dataCenter, proxy)); if (server == null) { server = dataCenter.server(); } @@ -44,24 +44,23 @@ private static String getSauceRestUrlFromEnv() { return srUrl; } - private static HttpClientConfig getJenkinsPluginHttpConfig(DataCenter dataCenter) { + private static HttpClientConfig getJenkinsPluginHttpConfig(DataCenter dataCenter, ProxyConfiguration proxyConfig) { String server = getSauceRestUrlFromEnv(); if (server == null) { server = dataCenter.server(); } Proxy proxy = null; Authenticator auth = Authenticator.NONE; - ProxyConfiguration pc = Jenkins.get().getProxy(); - if (pc != null) { + if (proxyConfig != null) { String host = Objects.requireNonNull(buildURL(server)).getHost(); - proxy = pc.createProxy(host); + proxy = proxyConfig.createProxy(host); - if (pc.getUserName() != null - && !pc.getUserName().isEmpty() - && pc.getSecretPassword() != null - && !pc.getSecretPassword().getPlainText().isEmpty()) { - auth = new ProxyAuthenticator(pc.getUserName(), pc.getSecretPassword().getPlainText()); + if (proxyConfig.getUserName() != null + && !proxyConfig.getUserName().isEmpty() + && proxyConfig.getSecretPassword() != null + && !proxyConfig.getSecretPassword().getPlainText().isEmpty()) { + auth = new ProxyAuthenticator(proxyConfig.getUserName(), proxyConfig.getSecretPassword().getPlainText()); } } UserAgentInterceptor ua = new UserAgentInterceptor(userAgent); diff --git a/src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java b/src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java index 34fa33b5..ad91c542 100755 --- a/src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java @@ -54,7 +54,7 @@ public class PluginImpl extends Plugin implements Describable { /** Handles the retrieval of browsers from Sauce Labs. */ static final BrowserFactory BROWSER_FACTORY = - BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST)); + BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST, null)); private static final Logger logger = Logger.getLogger(PluginImpl.class.getName()); /** Username to access Sauce OnDemand. */ @Deprecated private transient String username; diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildAction.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildAction.java index c608dd88..3c6a3405 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildAction.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildAction.java @@ -34,6 +34,8 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import javax.servlet.ServletException; + +import jenkins.model.Jenkins; import jenkins.model.RunAction2; import jenkins.tasks.SimpleBuildStep; import jenkins.util.Timer; @@ -440,7 +442,7 @@ protected JenkinsSauceREST getSauceREST() { DataCenter dc = DataCenter.fromString(dataCenter); - return new JenkinsSauceREST(username, accessKey, dc); + return new JenkinsSauceREST(username, accessKey, dc, Jenkins.get().getProxy()); } public SauceTestResultsById getById(String id) { diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildWrapper.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildWrapper.java index bfa8981c..5706e405 100755 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildWrapper.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandBuildWrapper.java @@ -37,6 +37,7 @@ import hudson.EnvVars; import hudson.Extension; import hudson.Launcher; +import hudson.ProxyConfiguration; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; @@ -428,7 +429,9 @@ public Environment setUp( credentials.getApiKey().getPlainText(), dc, maxRetries, - retryWaitTime); + retryWaitTime, + Jenkins.get().getProxy() + ); if (launchSauceConnectOnSlave) { listener @@ -684,7 +687,7 @@ public boolean tearDown(AbstractBuild build, BuildListener listener) SauceCredentials.getSauceCredentials( build, SauceOnDemandBuildWrapper.this); // get credentials JenkinsSauceREST sauceREST = - credentials.getSauceREST(); // use credentials to get sauceRest + credentials.getSauceREST(Jenkins.get().getProxy()); // use credentials to get sauceRest SauceConnectEndpoint ep = sauceREST.getSauceConnectEndpoint(); if (isEnableSauceConnect() && isUseGeneratedTunnelIdentifier()) { @@ -1103,7 +1106,8 @@ private static final class SauceConnectHandler private final String username; private final String key; private final DataCenter dataCenter; - private final BuildListener listener; + private final ProxyConfiguration proxy; + private final BuildListener listener; private final boolean verboseLogging; private final String sauceConnectPath; private int maxRetries; @@ -1123,7 +1127,8 @@ public SauceConnectHandler( String apiKey, DataCenter dataCenter, String maxRetries, - String retryWaitTime) { + String retryWaitTime, + ProxyConfiguration proxy) { this.options = resolvedOptions; this.workingDirectory = workingDirectory; this.useLatestSauceConnect = useLatestSauceConnect; @@ -1131,7 +1136,8 @@ public SauceConnectHandler( this.username = username; this.key = apiKey; this.dataCenter = dataCenter; - this.port = sauceOnDemandBuildWrapper.getPort(env); + this.proxy = proxy; + this.port = sauceOnDemandBuildWrapper.getPort(env); this.verboseLogging = sauceOnDemandBuildWrapper.isVerboseLogging(); this.sauceConnectPath = sauceOnDemandBuildWrapper.getSauceConnectPath(); this.sauceConnectJar = sauceConnectJar; @@ -1171,7 +1177,7 @@ public SauceConnectHandler call() throws AbstractSauceTunnelManager.SauceConnect ((HudsonSauceConnectFourManager) sauceTunnelManager) .setUseLatestSauceConnect(useLatestSauceConnect); } - sauceTunnelManager.setSauceRest(new JenkinsSauceREST(username, key, dataCenter)); + sauceTunnelManager.setSauceRest(new JenkinsSauceREST(username, key, dataCenter, proxy)); if (StringUtils.isBlank(username)) { listener.getLogger().println("Username not set, not starting Sauce Connect"); } else if (StringUtils.isBlank(key)) { diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandReportPublisher.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandReportPublisher.java index 3b204d1a..47e1c3a5 100755 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandReportPublisher.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceOnDemandReportPublisher.java @@ -58,6 +58,8 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; + +import jenkins.model.Jenkins; import org.json.JSONException; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; @@ -399,7 +401,7 @@ private boolean isDisableUsageStats() { } protected JenkinsSauceREST getSauceREST(Run build) { - return SauceOnDemandBuildAction.getSauceBuildAction(build).getCredentials().getSauceREST(); + return SauceOnDemandBuildAction.getSauceBuildAction(build).getCredentials().getSauceREST(Jenkins.get().getProxy()); } /** diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterDefinition.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterDefinition.java index dcab53d1..a8a051b0 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterDefinition.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterDefinition.java @@ -11,6 +11,8 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + +import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.json.JSONException; import org.kohsuke.stapler.DataBoundConstructor; @@ -27,7 +29,7 @@ public class SauceParameterDefinition extends ParameterDefinition { private static final Logger logger = Logger.getLogger(SauceParameterDefinition.class.getName()); /** Handles the retrieval of browsers from Sauce Labs. */ - private static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST)); + private static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST, Jenkins.get().getProxy())); @DataBoundConstructor public SauceParameterDefinition() { diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterValue.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterValue.java index aa6b7cfd..23d80e04 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterValue.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceParameterValue.java @@ -17,7 +17,7 @@ public class SauceParameterValue extends ParameterValue { /** Handles the retrieval of browsers from Sauce Labs. */ - private static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST)); + private static final BrowserFactory BROWSER_FACTORY = BrowserFactory.getInstance(new JenkinsSauceREST(null, null, DataCenter.US_WEST, null)); private final String selectedBrowsersString; diff --git a/src/main/java/hudson/plugins/sauce_ondemand/SauceTestResultsById.java b/src/main/java/hudson/plugins/sauce_ondemand/SauceTestResultsById.java index b077205b..f2944546 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/SauceTestResultsById.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/SauceTestResultsById.java @@ -7,6 +7,8 @@ import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; + +import jenkins.model.Jenkins; import org.json.JSONException; /** */ @@ -40,7 +42,10 @@ public SauceTestResultsById(String id, SauceCredentials credentials) { new JenkinsSauceREST( credentials.getUsername(), credentials.getPassword().getPlainText(), - DataCenter.fromString(credentials.getRestEndpointName()))); + DataCenter.fromString(credentials.getRestEndpointName()), + Jenkins.get().getProxy() + ) + ); } public String getId() { diff --git a/src/main/java/hudson/plugins/sauce_ondemand/credentials/SauceCredentials.java b/src/main/java/hudson/plugins/sauce_ondemand/credentials/SauceCredentials.java index 692dc2f3..1f48b746 100644 --- a/src/main/java/hudson/plugins/sauce_ondemand/credentials/SauceCredentials.java +++ b/src/main/java/hudson/plugins/sauce_ondemand/credentials/SauceCredentials.java @@ -21,6 +21,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.ProxyConfiguration; import hudson.model.AbstractBuild; import hudson.model.AbstractDescribableImpl; import hudson.model.AbstractProject; @@ -171,9 +172,9 @@ public static SauceCredentials getSauceCredentials(AbstractBuild build, SauceOnD return getCredentialsById(build.getProject(), credentialId); } - public JenkinsSauceREST getSauceREST() { + public JenkinsSauceREST getSauceREST(ProxyConfiguration proxy) { DataCenter dc = DataCenter.fromString(getRestEndpointName()); - JenkinsSauceREST sauceREST = new JenkinsSauceREST(getUsername(), getPassword().getPlainText(), dc); + JenkinsSauceREST sauceREST = new JenkinsSauceREST(getUsername(), getPassword().getPlainText(), dc, proxy); return sauceREST; } @@ -193,7 +194,7 @@ public FormValidation doCheckApiKey(@QueryParameter String value, @QueryParamete DataCenter dc = DataCenter.fromString(dataCenter); - JenkinsSauceREST rest = new JenkinsSauceREST(username, value, dc); + JenkinsSauceREST rest = new JenkinsSauceREST(username, value, dc, Jenkins.get().getProxy()); AccountsEndpoint users = rest.getAccountsEndpoint(); // If unauthorized getUser returns an empty string. try { diff --git a/src/test/java/hudson/plugins/sauce_ondemand/SauceBuildWrapperTest.java b/src/test/java/hudson/plugins/sauce_ondemand/SauceBuildWrapperTest.java index 326ad842..83fd84ff 100644 --- a/src/test/java/hudson/plugins/sauce_ondemand/SauceBuildWrapperTest.java +++ b/src/test/java/hudson/plugins/sauce_ondemand/SauceBuildWrapperTest.java @@ -81,7 +81,7 @@ public void setUp() throws Exception { this.credentialsId = SauceCredentials.migrateToCredentials("fakeuser", "fakekey", null, "unittest"); - JenkinsSauceREST sauceRest = new JenkinsSauceREST("username", "access key", DataCenter.US_WEST); + JenkinsSauceREST sauceRest = new JenkinsSauceREST("username", "access key", DataCenter.US_WEST, null); PluginImpl plugin = PluginImpl.get(); assertNotNull(plugin); // Reset connection string every run diff --git a/src/test/java/hudson/plugins/sauce_ondemand/mocks/MockSauceREST.java b/src/test/java/hudson/plugins/sauce_ondemand/mocks/MockSauceREST.java index 22f63393..a6f7aa1d 100644 --- a/src/test/java/hudson/plugins/sauce_ondemand/mocks/MockSauceREST.java +++ b/src/test/java/hudson/plugins/sauce_ondemand/mocks/MockSauceREST.java @@ -7,7 +7,7 @@ public class MockSauceREST extends JenkinsSauceREST { public MockSauceREST() { - super("fake", "", DataCenter.US_WEST); + super("fake", "", DataCenter.US_WEST, null); } public String retrieveResults(URL restEndpoint) {