Skip to content

Commit

Permalink
Merge branch 'feature/JENKINS-33401-credentials-migration' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
prospero238 committed Jan 7, 2017
2 parents 5eb7d9b + 4ba4aee commit 4856908
Show file tree
Hide file tree
Showing 7 changed files with 416 additions and 22 deletions.
100 changes: 81 additions & 19 deletions pom.xml
Expand Up @@ -62,8 +62,8 @@
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-aggregator</artifactId>
<version>${workflow.version}</version>
<artifactId>workflow-cps</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -73,18 +73,18 @@
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>${workflow.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.0-beta</version>
<classifier>no_aop</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand All @@ -95,6 +95,42 @@
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.kohsuke.stapler</groupId>
<artifactId>stapler</artifactId>
<version>1.234</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>remoting</artifactId>
<version>2.49</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.3.04</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>htmlunit</artifactId>
<version>2.6-jenkins-6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
Expand All @@ -105,26 +141,19 @@
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.178</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
Expand All @@ -138,6 +167,12 @@
<version>2.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand All @@ -150,6 +185,12 @@
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
Expand All @@ -160,11 +201,13 @@
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.12.1.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.13</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.exparity</groupId>
Expand Down Expand Up @@ -215,6 +258,25 @@
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<systemProperties>
<systemProperty>
<name>logback.configurationFile</name>
<value>${logback.configuration.file}</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<logback.configuration.file></logback.configuration.file>
</properties>
</profile>
</profiles>
</project>
Expand Up @@ -60,6 +60,12 @@ public abstract class AbstractLiquibaseBuilder extends Builder implements Simple
private Boolean useIncludedDriver;
private String credentialsId;


@Deprecated
protected transient String username;
@Deprecated
protected transient String password;

@Deprecated
public AbstractLiquibaseBuilder(String databaseEngine,
String changeLogFile,
Expand Down Expand Up @@ -391,5 +397,31 @@ public void setCredentialsId(String credentialsId) {
this.credentialsId = credentialsId;
}

@DataBoundSetter
public void setUsername(String username) {
this.username = username;
}

@DataBoundSetter
public void setPassword(String password) {
this.password = password;
}

@Deprecated
public String getUsername() {
return username;
}
@Deprecated
public String getPassword() {
return password;
}

public void clearLegacyCredentials() {
username=null;
password=null;
}

public boolean hasLegacyCredentials() {
return !Strings.isNullOrEmpty(username);
}
}
Expand Up @@ -14,11 +14,11 @@
import liquibase.exception.LiquibaseException;
import liquibase.exception.MigrationFailedException;

import java.util.logging.Logger;

import org.jenkinsci.plugins.liquibase.common.LiquibaseCommand;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Jenkins builder which evaluates liquibase changesets.
Expand All @@ -28,7 +28,7 @@ public class ChangesetEvaluator extends AbstractLiquibaseBuilder {
@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

private static final Logger LOG = LoggerFactory.getLogger(ChangesetEvaluator.class);
private static final Logger LOG = Logger.getLogger(ChangesetEvaluator.class.getName());

protected boolean testRollbacks;
private boolean dropAll;
Expand Down
@@ -0,0 +1,106 @@
package org.jenkinsci.plugins.liquibase.evaluator;

import hudson.Extension;
import hudson.model.Describable;
import hudson.model.Item;
import hudson.model.ModelObject;
import hudson.model.Project;
import hudson.model.listeners.ItemListener;
import hudson.util.DescribableList;
import jenkins.model.Jenkins;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.cloudbees.plugins.credentials.Credentials;
import com.cloudbees.plugins.credentials.CredentialsScope;
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
import com.cloudbees.plugins.credentials.domains.Domain;
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
import com.google.common.base.Strings;

/**
* Migrates projects that had been using old username/password fields to use credentials.
*/
public class CredentialsMigrator {

private static final Logger LOG = Logger.getLogger(CredentialsMigrator.class.getName());

@Extension
static final public class ItemListenerImpl extends ItemListener {
@Override
public void onLoaded() {
CredentialsMigrator.migrateLegacyCredentials();
}
}
static void migrateLegacyCredentials() {
LOG.finest("credentials migrator invoked");

Jenkins instance = Jenkins.getInstance();
if (instance != null) {
List<Project> projects = instance.getItems(Project.class);
for (Project project : projects) {
DescribableList buildersList = project.getBuildersList();
Describable describable = buildersList.get(AbstractLiquibaseBuilder.class);
if (describable != null) {
AbstractLiquibaseBuilder liquibaseBuilder = (AbstractLiquibaseBuilder) describable;
migrateCredentials(project, liquibaseBuilder);
}
}
}
}

protected static void migrateCredentials(Item project, AbstractLiquibaseBuilder liquibaseBuilder) {
if (liquibaseBuilder.hasLegacyCredentials()) {
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("found builder needing credentials migration. project:" +
project.getDisplayName());
}
try {
String plainTextPassword = Strings.nullToEmpty(liquibaseBuilder.getPassword());
String credentialsId = createCredentials(liquibaseBuilder.getUsername(),
plainTextPassword,
project);
liquibaseBuilder.setCredentialsId(credentialsId);
liquibaseBuilder.clearLegacyCredentials();
project.save();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private static String createCredentials(String username, String password, ModelObject project) throws IOException {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("creating new credential for project:" + project.getDisplayName());
}

String credentialsId = UUID.randomUUID().toString();
String description = "migrated from " + project.getDisplayName();
Credentials credentialsToCreate = new UsernamePasswordCredentialsImpl(
CredentialsScope.GLOBAL,
credentialsId,
description,
username,
password
);

SystemCredentialsProvider credentialsProvider = SystemCredentialsProvider.getInstance();
Map<Domain, List<Credentials>> credentialsMap = credentialsProvider.getDomainCredentialsMap();

Domain global = Domain.global();
if (credentialsMap.get(global) == null) {
credentialsMap.put(global, Collections.<Credentials>emptyList());
}
credentialsMap.get(global).add(credentialsToCreate);
credentialsProvider.setDomainCredentialsMap(credentialsMap);
credentialsProvider.save();

return credentialsId;
}
}
37 changes: 37 additions & 0 deletions src/test/resources/scripted-upgrade-test/oldauth_job_config.xml
@@ -0,0 +1,37 @@
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<org.jenkinsci.plugins.liquibase.evaluator.ChangesetEvaluator plugin="liquibase-runner@1.1.0">
<databaseEngine>H2</databaseEngine>
<changeLogFile>@CHANGELOG_FILEPATH@</changeLogFile>
<url>jdbc:h2:file:@H2_FILE@</url>
<defaultSchemaName></defaultSchemaName>
<contexts></contexts>
<liquibasePropertiesPath></liquibasePropertiesPath>
<classpath></classpath>
<driverClassname></driverClassname>
<labels></labels>
<changeLogParameters></changeLogParameters>
<basePath>@BASE_PATH@</basePath>
<useIncludedDriver>true</useIncludedDriver>
<username>sa</username>
<password></password>
<testRollbacks>true</testRollbacks>
<dropAll>true</dropAll>
<tagOnSuccessfulBuild>false</tagOnSuccessfulBuild>
</org.jenkinsci.plugins.liquibase.evaluator.ChangesetEvaluator>
</builders>
<publishers/>
<buildWrappers/>
</project>

0 comments on commit 4856908

Please sign in to comment.