Skip to content

Commit

Permalink
* Handles V4 Regions
Browse files Browse the repository at this point in the history
    * Handles Parameters (skipping Validation if necessary)
    * Fixes missing version
    * Made incompatible with previous version
  • Loading branch information
aldrinleal committed Nov 30, 2015
1 parent 3dbdf53 commit a6f4f8f
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 64 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Jenkins Plugin for AWS Elastic Beanstalk Deployments
## TODO LIST

* Update Docs
* Unit Tests (I know, I know)
* Implement a better deployment pipeline using a Chain of Responsibility
* Support Job DSL and Workflow Plugins
* Ensure parameters are properly dealt
Expand Down
22 changes: 21 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</parent>

<groupId>br.com.ingenieux.jenkins.plugins</groupId>
<artifactId>awseb-deployment</artifactId>
<artifactId>awseb-deployment-plugin</artifactId>
<version>0.0.4-SNAPSHOT</version>
<packaging>hpi</packaging>

Expand Down Expand Up @@ -77,6 +77,14 @@
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jenkins-ci.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<compatibleSinceVersion>0.0.4</compatibleSinceVersion>
</configuration>
</plugin>
</plugins>
</build>

Expand All @@ -97,6 +105,18 @@
<artifactId>aws-java-sdk</artifactId>
<version>1.10.26</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>1.625.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.26</version>
<scope>test</scope>
</dependency>
</dependencies>

<!-- get every artifact through repo.jenkins-ci.org, which proxies all the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.internal.StaticCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3;
import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials;
import com.cloudbees.plugins.credentials.CredentialsMatchers;
import com.cloudbees.plugins.credentials.CredentialsProvider;
Expand All @@ -34,11 +34,11 @@ public class AWSClientFactory implements Constants {

private String region;

protected AWSClientFactory(AWSCredentialsProvider creds, ClientConfiguration clientConfiguration,
private AWSClientFactory(AWSCredentialsProvider creds, ClientConfiguration clientConfiguration,
String region) {
this.creds = creds;
this.clientConfiguration = clientConfiguration;
this.region = region;
this.region = region.toLowerCase();
}

@SuppressWarnings("unchecked")
Expand All @@ -47,7 +47,16 @@ public <T> T getService(Class<T> serviceClazz)
InvocationTargetException, InstantiationException {

Class<?> paramTypes[] = new Class<?>[]{AWSCredentialsProvider.class, ClientConfiguration.class};
Object params[] = new Object[]{creds, clientConfiguration};

ClientConfiguration newClientConfiguration = new ClientConfiguration(this.clientConfiguration);

if (AmazonS3.class.isAssignableFrom(serviceClazz)) {
newClientConfiguration = newClientConfiguration.withSignerOverride("AWSS3V4SignerType");
} else {
newClientConfiguration = newClientConfiguration.withSignerOverride(null);
}

Object params[] = new Object[]{creds, newClientConfiguration};

T resultObj = (T) ConstructorUtils.invokeConstructor(serviceClazz, params, paramTypes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.amazonaws.services.elasticbeanstalk.model.DescribeEnvironmentsResult;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials;
import com.cloudbees.plugins.credentials.CredentialsNameProvider;
import com.cloudbees.plugins.credentials.CredentialsProvider;
Expand All @@ -54,7 +53,7 @@
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

import javax.security.auth.login.CredentialNotFoundException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand All @@ -78,6 +77,29 @@ public AWSEBDeploymentBuilder(String credentialId, String awsRegion, String appl
this.zeroDowntime = zeroDowntime;
}

/**
* Copy Factory
*
* @param r replacer
* @return replaced copy
*/
public AWSEBDeploymentBuilder replacedCopy(Utils.Replacer r) {
return new AWSEBDeploymentBuilder(
r.r(this.getCredentialId()),
r.r(this.getAwsRegion()),
r.r(this.getApplicationName()),
r.r(this.getEnvironmentName()),
r.r(this.getBucketName()),
r.r(this.getKeyPrefix()),
r.r(this.getVersionLabelFormat()),
r.r(this.getRootObject()),
r.r(this.getIncludes()),
r.r(this.getExcludes()),
this.isZeroDowntime()
);
}


/**
* Credentials name
*/
Expand Down Expand Up @@ -219,8 +241,8 @@ public String getDisplayName() {
}

public FormValidation doCheckAwsRegion(@QueryParameter String value) {
if (-1 != value.indexOf("${"))
return FormValidation.ok();
if (value.contains("$"))
return FormValidation.warning("Validation skipped due to parameter usage ('$')");

if (! value.matches("^\\p{Alpha}{2}-(?:gov-)?\\p{Alpha}{4,}-\\d$")) {
return FormValidation.error("Doesn't look like a region, like {place}-{cardinal}-{number}");
Expand All @@ -229,8 +251,8 @@ public FormValidation doCheckAwsRegion(@QueryParameter String value) {
}

public FormValidation doCheckApplicationName(@QueryParameter String value) {
if (-1 != value.indexOf("${"))
return FormValidation.ok();
if (value.contains("$"))
return FormValidation.warning("Validation skipped due to parameter usage ('$')");

int valueLen = value.length();
if (valueLen == 0 || valueLen > 100) {
Expand All @@ -240,16 +262,22 @@ public FormValidation doCheckApplicationName(@QueryParameter String value) {
}

public FormValidation doCheckEnvironmentName(@QueryParameter String value) {
if (-1 != value.indexOf("${"))
return FormValidation.ok();
if (value.contains("$"))
return FormValidation.warning("Validation skipped due to parameter usage ('$')");

if (! value.matches("^\\p{Alpha}[\\p{Alnum}\\-]{0,22}$") || value.endsWith("-")) {
return FormValidation.error("Doesn't look like an environment name. Must be from 4 to 23 characters in length. The name can contain only letters, numbers, and hyphens. It cannot start or end with a hyphen");
}
return FormValidation.ok();
}

public FormValidation doValidateCredentials(@QueryParameter("credentialId") final String credentialId, @QueryParameter final String awsRegion) {
public FormValidation doValidateCredentials(@QueryParameter("credentialId") final String credentialId,
@QueryParameter final String awsRegion) {
for (String value : Arrays.asList(credentialId, awsRegion)) {
if (value.contains("$"))
return FormValidation.warning("Validation skipped due to parameter usage ('$')");
}

try {
LoggerWriter loggerWriter = LoggerWriter.get();

Expand Down Expand Up @@ -293,11 +321,16 @@ public FormValidation doValidateCoordinates(@QueryParameter("credentialId") Stri
@QueryParameter("awsRegion") String awsRegion,
@QueryParameter("applicationName") String applicationName,
@QueryParameter("environmentName") String environmentName) throws Exception {
for (String value : Arrays.asList(credentialId, awsRegion, applicationName, environmentName)) {
if (value.contains("$"))
return FormValidation.warning("Validation skipped due to parameter usage ('$')");
}

AWSClientFactory clientFactory = AWSClientFactory.getClientFactory(credentialId, awsRegion);

AWSElasticBeanstalk awsElasticBeanstalk = clientFactory.getService(AWSElasticBeanstalkClient.class);

DescribeEnvironmentsResult describeEnvironmentsResult = awsElasticBeanstalk.describeEnvironments(new DescribeEnvironmentsRequest().withEnvironmentNames(environmentName));
DescribeEnvironmentsResult describeEnvironmentsResult = awsElasticBeanstalk.describeEnvironments(new DescribeEnvironmentsRequest().withApplicationName(applicationName).withEnvironmentNames(environmentName));

if (1 == describeEnvironmentsResult.getEnvironments().size()) {
String environmentId = describeEnvironmentsResult.getEnvironments().get(0).getEnvironmentId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

Expand Down Expand Up @@ -149,7 +149,7 @@ private void validateEnvironmentStatus(String environmentId) throws Exception {
log("Checking health of environment %s attempt %d/%s", environmentId, nAttempt, DeployerContext.MAX_ATTEMPTS);

List<EnvironmentDescription> environments = c.awseb.describeEnvironments(new DescribeEnvironmentsRequest()
.withEnvironmentIds(Arrays.asList(environmentId))).getEnvironments();
.withEnvironmentIds(Collections.singletonList(environmentId))).getEnvironments();

if (environments.size() != 1) {
throw new InvalidEnvironmentsSizeException(c.applicationName, c.environmentName);
Expand Down Expand Up @@ -215,11 +215,11 @@ private void uploadArchive() throws Exception {
}

private void validateParameters() throws InvalidParametersException {
c.keyPrefix = Utils.getValue(c.deployerConfig.getKeyPrefix(), c.env);
c.bucketName = Utils.getValue(c.deployerConfig.getBucketName(), c.env);
c.applicationName = Utils.getValue(c.deployerConfig.getApplicationName(), c.env);
c.versionLabel = Utils.getValue(c.deployerConfig.getVersionLabelFormat(), c.env);
c.environmentName = Utils.getValue(c.deployerConfig.getEnvironmentName(), c.env);
c.keyPrefix = c.deployerConfig.getKeyPrefix();
c.bucketName = c.deployerConfig.getBucketName();
c.applicationName = c.deployerConfig.getApplicationName();
c.versionLabel = c.deployerConfig.getVersionLabelFormat();
c.environmentName = c.deployerConfig.getEnvironmentName();

if (isBlank(c.environmentName)) {
throw new InvalidParametersException("Empty/blank environmentName parameter");
Expand All @@ -242,6 +242,7 @@ private String[] generateEnvironmentNames() {
List<String> environmentNames = new ArrayList<String>() {{
add(c.environmentName);
}};

if (c.deployerConfig.isZeroDowntime()) {
String newEnvironmentName = c.environmentName.length() <= DeployerContext.MAX_ENVIRONMENT_NAME_LENGTH - 2 ?
c.environmentName : c.environmentName.substring(0, c.environmentName.length() - 2);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ public class DeployerContext implements Constants {

final Launcher launcher;

final Utils.Replacer replacer;

final FilePath rootFileObject;

AmazonS3 s3;

AWSElasticBeanstalk awseb;

final FilePath rootFileObject;

String keyPrefix;

String bucketName;
Expand All @@ -57,20 +59,24 @@ public class DeployerContext implements Constants {

String s3ObjectPath;

final EnvVars env;
EnvVars env;

String environmentName;

final BuildListener listener;
BuildListener listener;

public DeployerContext(AWSEBDeploymentBuilder builder,
public DeployerContext(AWSEBDeploymentBuilder o,
AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
this.deployerConfig = builder;
this.env = build.getEnvironment(listener);

this.replacer = new Utils.Replacer(this.env);

this.deployerConfig = o.replacedCopy(this.replacer);

this.logger = listener.getLogger();
this.env = build.getEnvironment(listener);
this.launcher = launcher;
this.listener = listener;

this.rootFileObject = new FilePath(build.getWorkspace(), Utils.getValue(deployerConfig.getRootObject(), this.env));
}
this.rootFileObject = new FilePath(build.getWorkspace(), this.deployerConfig.getRootObject());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ public static String formatPath(String mask, Object... args) {
return strip(String.format(mask, args).replaceAll("/{2,}", ""));
}

public static String getValue(String value, EnvVars env) {
return strip(Util.replaceMacro(value, env));
public static class Replacer {
final EnvVars envVars;

public Replacer(EnvVars envVars) {
this.envVars = envVars;
}

public String r(String value) {
return strip(Util.replaceMacro(value, envVars));
}
}

private static String strip(String str) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
awseb-deployerContext-plugin.version=${project.version}
awseb-deployer-plugin.version=${project.version}

0 comments on commit a6f4f8f

Please sign in to comment.