diff --git a/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSource.java b/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSource.java index 1124ee3e..5875983e 100644 --- a/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSource.java +++ b/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSource.java @@ -23,10 +23,8 @@ */ package com.dtolabs.rundeck.plugin.resources.ec2; -import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.*; import com.amazonaws.ClientConfiguration; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.auth.BasicSessionCredentials; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient; import com.amazonaws.services.securitytoken.model.*; import com.dtolabs.rundeck.core.common.*; @@ -42,12 +40,10 @@ import java.io.*; import java.util.*; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; import static com.dtolabs.rundeck.plugin.resources.ec2.EC2ResourceModelSourceFactory.SYNCHRONOUS_LOAD; @@ -85,6 +81,9 @@ public class EC2ResourceModelSource implements ResourceModelSource { Future futureResult = null; final Properties mapping = new Properties(); final String assumeRoleArn; + final String assumeRoleArnCombinedWithExtId; + AWSCredentialsProvider awsCredentialsProvider; + final String externalId; int pageResults; @@ -158,6 +157,7 @@ public EC2ResourceModelSource(final Properties configuration, final Services ser this.pageResults = Integer.parseInt(configuration.getProperty(EC2ResourceModelSourceFactory.MAX_RESULTS)); this.httpProxyHost = configuration.getProperty(EC2ResourceModelSourceFactory.HTTP_PROXY_HOST); this.assumeRoleArn = configuration.getProperty(EC2ResourceModelSourceFactory.ROLE_ARN); + this.assumeRoleArnCombinedWithExtId = configuration.getProperty(EC2ResourceModelSourceFactory.ROLE_ARN_COMBINED_WITH_EXT_ID); this.externalId = configuration.getProperty(EC2ResourceModelSourceFactory.EXTERNAL_ID); int proxyPort = 80; @@ -224,22 +224,20 @@ private void initialize() { Collections.addAll(params, filterParams.split(";")); } loadMapping(); - if (this.credentials == null && assumeRoleArn != null) { - AWSSecurityTokenServiceClient sts_client = new AWSSecurityTokenServiceClient(clientConfiguration); - // sts_client.setEndpoint("sts-endpoint.amazonaws.com"); - AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest(); - assumeRoleRequest.setRoleArn(assumeRoleArn); - if(externalId!=null){ - assumeRoleRequest.setExternalId(externalId); + + if (this.credentials == null) { + if(this.externalId != null && this.assumeRoleArnCombinedWithExtId != null){ + this.credentials = createAwsCredentials(null, this.assumeRoleArnCombinedWithExtId, this.externalId); + } + + if(assumeRoleArn != null) { + AWSCredentialsProvider provider = null; + if(this.credentials != null){ + provider = new AWSStaticCredentialsProvider(credentials); + } + + credentials = createAwsCredentials(provider, assumeRoleArn, null); } - assumeRoleRequest.setRoleSessionName("RundeckEC2ResourceModelSourceSession"); - AssumeRoleResult assumeRoleResult = sts_client.assumeRole(assumeRoleRequest); - Credentials assumeCredentials = assumeRoleResult.getCredentials(); - credentials = new BasicSessionCredentials( - assumeCredentials.getAccessKeyId(), - assumeCredentials.getSecretAccessKey(), - assumeCredentials.getSessionToken() - ); } mapper = new InstanceToNodeMapper(this.credentials, mapping, clientConfiguration, pageResults); @@ -249,6 +247,29 @@ private void initialize() { mapper.setRunningStateOnly(runningOnly); } + private AWSCredentials createAwsCredentials(AWSCredentialsProvider provider, String assumeRoleArn, String externalId) { + AWSSecurityTokenServiceClient sts_client; + + if (provider != null) { + sts_client = new AWSSecurityTokenServiceClient(provider, clientConfiguration); + } else { + sts_client = new AWSSecurityTokenServiceClient(clientConfiguration); + } + // sts_client.setEndpoint("sts-endpoint.amazonaws.com"); + AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest(); + assumeRoleRequest.setRoleArn(assumeRoleArn); + if(externalId!=null){ + assumeRoleRequest.setExternalId(externalId); + } + assumeRoleRequest.setRoleSessionName("RundeckEC2ResourceModelSourceSession"); + AssumeRoleResult assumeRoleResult = sts_client.assumeRole(assumeRoleRequest); + Credentials assumeCredentials = assumeRoleResult.getCredentials(); + return new BasicSessionCredentials( + assumeCredentials.getAccessKeyId(), + assumeCredentials.getSecretAccessKey(), + assumeCredentials.getSessionToken() + ); + } public synchronized INodeSet getNodes() throws ResourceModelSourceException { checkFuture(); diff --git a/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSourceFactory.java b/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSourceFactory.java index 8fcd48f8..c7bd1f8f 100644 --- a/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSourceFactory.java +++ b/src/main/java/com/dtolabs/rundeck/plugin/resources/ec2/EC2ResourceModelSourceFactory.java @@ -29,7 +29,6 @@ import com.dtolabs.rundeck.core.resources.ResourceModelSource; import com.dtolabs.rundeck.core.resources.ResourceModelSourceFactory; import com.dtolabs.rundeck.plugins.util.DescriptionBuilder; -import com.dtolabs.rundeck.plugins.util.PropertyBuilder; import org.rundeck.app.spi.Services; import java.io.File; @@ -62,6 +61,7 @@ public class EC2ResourceModelSourceFactory implements ResourceModelSourceFactory public static final String SECRET_KEY = "secretKey"; public static final String SECRET_KEY_STORAGE_PATH = "secretKeyStoragePath"; public static final String ROLE_ARN = "assumeRoleArn"; + public static final String ROLE_ARN_COMBINED_WITH_EXT_ID = "assumeRoleArnCombinedWithExternalId"; public static final String EXTERNAL_ID = "externalId"; public static final String REGION = "region"; public static final String MAPPING_FILE = "mappingFile";