Skip to content

Commit

Permalink
Migrate secrets to credentials plugin and add custom Maven Repository
Browse files Browse the repository at this point in the history
  • Loading branch information
welandaz committed Sep 5, 2024
1 parent 4610ed4 commit 69f8f7c
Show file tree
Hide file tree
Showing 20 changed files with 564 additions and 148 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package hudson.plugin.gradle;

import org.jenkinsci.test.acceptance.plugins.credentials.CredentialsPage;
import org.jenkinsci.test.acceptance.plugins.credentials.ManagedCredentials;
import org.jenkinsci.test.acceptance.plugins.credentials.StringCredentials;
import org.jenkinsci.test.acceptance.plugins.credentials.UserPwdCredential;
import org.jenkinsci.test.acceptance.po.Jenkins;
import org.jenkinsci.test.acceptance.po.JenkinsConfig;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.net.URI;
import java.util.UUID;

public class BuildScansInjectionSettings extends JenkinsConfig {

Expand All @@ -18,8 +25,8 @@ public class BuildScansInjectionSettings extends JenkinsConfig {
private static final String DEVELOCITY_PLUGIN_VERSION_FIELD = "gradlePluginVersion";
private static final String DEVELOCITY_EXTENSION_VERSION_FIELD = "mavenExtensionVersion";
private static final String GIT_REPOSITORY_FILTERS_FIELD = "vcsRepositoryFilter";
private static final String DEVELOCITY_ACCESS_KEY_FIELD = "accessKey";
private static final String DEVELOCITY_GRADLE_PLUGIN_REPOSITORY_PASSWORD_FIELD = "gradlePluginRepositoryPassword";
private static final String DEVELOCITY_ACCESS_KEY_CREDENTIAL_ID_FIELD = "accessKeyCredentialId";
private static final String DEVELOCITY_GRADLE_PLUGIN_REPOSITORY_CREDENTIAL_ID_FIELD = "gradlePluginRepositoryCredentialId";

public BuildScansInjectionSettings(Jenkins jenkins) {
super(jenkins);
Expand Down Expand Up @@ -54,11 +61,42 @@ public void clickCheckForGradleEnterpriseErrors() {
}

public void setGradleEnterpriseAccessKey(String accessKey) {
setBuildScansInjectionFormValue(DEVELOCITY_ACCESS_KEY_FIELD, accessKey);
JenkinsConfig configPage = jenkins.getConfigPage();
configPage.configure();

CredentialsPage credentialsPage = new CredentialsPage(jenkins, ManagedCredentials.DEFAULT_DOMAIN);
credentialsPage.open();

StringCredentials stringCredentials = credentialsPage.add(StringCredentials.class);
stringCredentials.setId(UUID.randomUUID().toString());
stringCredentials.secret.set(accessKey);

String credentialDescription = "Gradle Plugin Repository Password";
stringCredentials.description.set(credentialDescription);

credentialsPage.create();

setBuildScansInjectionFormSelect(DEVELOCITY_ACCESS_KEY_CREDENTIAL_ID_FIELD, credentialDescription);
}

public void setGradleEnterpriseGradlePluginRepoPassword(String password) {
setBuildScansInjectionFormValue(DEVELOCITY_GRADLE_PLUGIN_REPOSITORY_PASSWORD_FIELD, password);
JenkinsConfig configPage = jenkins.getConfigPage();
configPage.configure();

CredentialsPage credentialsPage = new CredentialsPage(jenkins, ManagedCredentials.DEFAULT_DOMAIN);
credentialsPage.open();

UserPwdCredential usernamePasswordCredentials = credentialsPage.add(UserPwdCredential.class);
usernamePasswordCredentials.setId(UUID.randomUUID().toString());
usernamePasswordCredentials.username.set("johndoe");
usernamePasswordCredentials.password.set(password);

String credentialDescription = "Gradle Plugin Repository Password";
usernamePasswordCredentials.description.set(credentialDescription);

credentialsPage.create();

setBuildScansInjectionFormSelect(DEVELOCITY_GRADLE_PLUGIN_REPOSITORY_CREDENTIAL_ID_FIELD, credentialDescription);
}

public void setGradleEnterprisePluginVersion(String version) {
Expand All @@ -84,6 +122,16 @@ private void setBuildScansInjectionFormValue(String field, String value) {
driver.findElement(xpath).sendKeys(value);
}

private void setBuildScansInjectionFormSelect(String field, String value) {
ensureConfigPage();

By xpath = By.xpath(String.format(XPATH, INJECTION_CONFIG_PATH + field));
WebElement webElement = driver.findElement(xpath);

Select select = new Select(webElement);
select.selectByVisibleText(value);
}

private String getBuildScansInjectionFormValue(String field) {
ensureConfigPage();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ protected final void enableBuildScansForMaven() {
}

protected final void setGradlePluginRepositoryPassword(String password) {
updateBuildScansInjectionSettings(settings -> {
settings.setGradleEnterpriseGradlePluginRepoPassword(password);
});
updateBuildScansInjectionSettings(settings -> settings.setGradleEnterpriseGradlePluginRepoPassword(password));
}

private void updateBuildScansInjectionSettings(Consumer<BuildScansInjectionSettings> spec) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package hudson.plugins.gradle.injection;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.EnvVars;
import hudson.Extension;
Expand All @@ -12,6 +14,7 @@
import hudson.plugins.gradle.DevelocityLogger;
import hudson.plugins.gradle.injection.token.ShortLivedTokenClient;
import hudson.util.Secret;
import org.jenkinsci.plugins.plaincredentials.StringCredentials;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -40,8 +43,18 @@ public BuildScanEnvironmentContributor(ShortLivedTokenClient tokenClient) {

@Override
public void buildEnvironmentFor(@Nonnull Run run, @Nonnull EnvVars envs, @Nonnull TaskListener listener) {
Secret secretKey = InjectionConfig.get().getAccessKey();
Secret secretPassword = InjectionConfig.get().getGradlePluginRepositoryPassword();
String accessKeyCredentialId = InjectionConfig.get().getAccessKeyCredentialId();
String gradlePluginRepositoryCredentialId = InjectionConfig.get().getGradlePluginRepositoryCredentialId();

Secret secretKey = Optional.ofNullable(accessKeyCredentialId)
.map(it -> CredentialsProvider.findCredentialById(it, StringCredentials.class, run))
.map(StringCredentials::getSecret)
.orElse(null);
Secret secretPassword = Optional.ofNullable(gradlePluginRepositoryCredentialId)
.map(it -> CredentialsProvider.findCredentialById(it, StandardUsernamePasswordCredentials.class, run))
.map(StandardUsernamePasswordCredentials::getPassword)
.orElse(null);

if ((secretKey == null && secretPassword == null) || alreadyExecuted(run)) {
return;
}
Expand Down Expand Up @@ -75,20 +88,20 @@ public void buildEnvironmentFor(@Nonnull Run run, @Nonnull EnvVars envs, @Nonnul
return null;
}
return allKeys.find(hostname)
.map(k ->
tokenClient.get(serverUrl, k, InjectionConfig.get().getShortLivedTokenExpiry()))
.filter(Optional::isPresent)
.map(k -> Secret.fromString(k.get().getRaw()))
.orElse(null);
.map(k ->
tokenClient.get(serverUrl, k, InjectionConfig.get().getShortLivedTokenExpiry()))
.filter(Optional::isPresent)
.map(k -> Secret.fromString(k.get().getRaw()))
.orElse(null);
}

// We're not sure exactly which DV URL will be effectively used so as best effort:
// let's translate all access keys to short-lived tokens
List<DevelocityAccessCredentials.HostnameAccessKey> shortLivedTokens = allKeys.stream()
.map(k -> tokenClient.get("https://" + k.getHostname(), k, InjectionConfig.get().getShortLivedTokenExpiry()))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
.map(k -> tokenClient.get("https://" + k.getHostname(), k, InjectionConfig.get().getShortLivedTokenExpiry()))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());

return shortLivedTokens.isEmpty() ? null : Secret.fromString(DevelocityAccessCredentials.of(shortLivedTokens).getRaw());
}
Expand Down Expand Up @@ -138,8 +151,8 @@ private static DevelocityParametersAction of(DevelocityLogger logger, @Nullable
return DevelocityParametersAction.empty();
}
return new DevelocityParametersAction(
values,
Stream.of(GRADLE_ENTERPRISE_ACCESS_KEY, DEVELOCITY_ACCESS_KEY, GRADLE_PLUGIN_REPOSITORY_PASSWORD).collect(Collectors.toSet())
values,
Stream.of(GRADLE_ENTERPRISE_ACCESS_KEY, DEVELOCITY_ACCESS_KEY, GRADLE_PLUGIN_REPOSITORY_PASSWORD).collect(Collectors.toSet())
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package hudson.plugins.gradle.injection;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import com.cloudbees.plugins.credentials.common.UsernameCredentials;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
Expand All @@ -10,6 +13,7 @@
import hudson.remoting.VirtualChannel;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -119,8 +123,9 @@ private void injectEnvironmentVariables(InjectionConfig config, Node node) {
EnvUtil.setEnvVar(node, InitScriptVariables.GRADLE_PLUGIN_REPOSITORY_URL, pluginRepositoryUrl);
}

if (config.getGradlePluginRepositoryUsername() != null) {
EnvUtil.setEnvVar(node, InitScriptVariables.GRADLE_PLUGIN_REPOSITORY_USERNAME, config.getGradlePluginRepositoryUsername());
String repositoryUsername = getRepositoryUsername(config.getGradlePluginRepositoryCredentialId());
if (repositoryUsername != null) {
EnvUtil.setEnvVar(node, InitScriptVariables.GRADLE_PLUGIN_REPOSITORY_USERNAME, repositoryUsername);
} else {
EnvUtil.removeEnvVar(node, InitScriptVariables.GRADLE_PLUGIN_REPOSITORY_USERNAME);
}
Expand Down Expand Up @@ -165,6 +170,17 @@ private static FilePath getInitScriptFile(VirtualChannel channel, String initScr
return new FilePath(channel, filePath(initScriptDirectory, GRADLE_INIT_FILE));
}

private static String getRepositoryUsername(String gradlePluginRepositoryCredentialId) {
List<StandardUsernamePasswordCredentials> allCredentials
= CredentialsProvider.lookupCredentialsInItem(StandardUsernamePasswordCredentials.class, null, null);

return allCredentials.stream()
.filter(it -> it.getId().equals(gradlePluginRepositoryCredentialId))
.findFirst()
.map(UsernameCredentials::getUsername)
.orElse(null);
}

private static String filePath(String... parts) {
return String.join("/", parts);
}
Expand Down
Loading

0 comments on commit 69f8f7c

Please sign in to comment.