com.amazonaws.codedeploy.AWSClients.java Source code

Java tutorial

Introduction

Here is the source code for com.amazonaws.codedeploy.AWSClients.java

Source

/*
 * Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 * 
 *  http://aws.amazon.com/apache2.0
 * 
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package com.amazonaws.codedeploy;

import static org.apache.commons.lang.StringUtils.isEmpty;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.UUID;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.codedeploy.AmazonCodeDeployClient;
import com.amazonaws.services.codedeploy.model.GetApplicationRequest;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClient;
import com.amazonaws.services.identitymanagement.model.GetUserResult;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;

/**
 * @author gibbon
 */
public class AWSClients {
    /**
     * Index in the colon-separated ARN that contains the account id
     * Sample ARN: arn:aws:iam::123456789012:user/David
     **/
    private static final int ARN_ACCOUNT_ID_INDEX = 4;

    public final AmazonCodeDeployClient codedeploy;
    public final AmazonS3Client s3;

    private final String region;
    private final String proxyHost;
    private final int proxyPort;

    public AWSClients(String region, AWSCredentials credentials, String proxyHost, int proxyPort) {
        this.region = region;
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;

        //setup proxy connection:
        ClientConfiguration clientCfg = new ClientConfiguration();
        if (proxyHost != null && proxyPort > 0) {
            clientCfg.setProxyHost(proxyHost);
            clientCfg.setProxyPort(proxyPort);
        }

        this.s3 = credentials != null ? new AmazonS3Client(credentials, clientCfg) : new AmazonS3Client(clientCfg);
        this.codedeploy = credentials != null ? new AmazonCodeDeployClient(credentials, clientCfg)
                : new AmazonCodeDeployClient(clientCfg);
        codedeploy.setRegion(Region.getRegion(Regions.fromName(this.region)));
        s3.setRegion(Region.getRegion(Regions.fromName(this.region)));
    }

    public static AWSClients fromDefaultCredentialChain(String region, String proxyHost, int proxyPort) {
        return new AWSClients(region, null, proxyHost, proxyPort);
    }

    public static AWSClients fromIAMRole(String region, String iamRole, String externalId, String proxyHost,
            int proxyPort) {
        return new AWSClients(region, getCredentials(iamRole, externalId), proxyHost, proxyPort);
    }

    public static AWSClients fromBasicCredentials(String region, String awsAccessKey, String awsSecretKey,
            String proxyHost, int proxyPort) {
        return new AWSClients(region, new BasicAWSCredentials(awsAccessKey, awsSecretKey), proxyHost, proxyPort);
    }

    /**
     * Via the default provider chain (i.e., global keys for this Jenkins instance),  return the account ID for the
     * currently authenticated user.
     * @return 12-digit account id
     */
    public static String getAccountId(String proxyHost, int proxyPort) {

        String arn = "";
        try {
            ClientConfiguration clientCfg = new ClientConfiguration();
            if (proxyHost != null && proxyPort > 0) {
                clientCfg.setProxyHost(proxyHost);
                clientCfg.setProxyPort(proxyPort);
            }
            AmazonIdentityManagementClient iam = new AmazonIdentityManagementClient(clientCfg);
            GetUserResult user = iam.getUser();
            arn = user.getUser().getArn();
        } catch (AmazonServiceException e) {
            if (e.getErrorCode().compareTo("AccessDenied") == 0) {
                String msg = e.getMessage();
                int arnIdx = msg.indexOf("arn:aws");
                if (arnIdx != -1) {
                    int arnSpace = msg.indexOf(" ", arnIdx);
                    arn = msg.substring(arnIdx, arnSpace);
                }
            }
        }

        String accountId = arn.split(":")[ARN_ACCOUNT_ID_INDEX];
        return accountId;
    }

    public void testConnection(String s3bucket, String codeDeployApplication) throws Exception {
        String testKey = "tmp-" + UUID.randomUUID() + ".txt";
        s3.putObject(s3bucket, testKey, createTestFile());

        codedeploy.getApplication(new GetApplicationRequest().withApplicationName(codeDeployApplication));
    }

    private File createTestFile() throws IOException {
        File file = File.createTempFile("codedeploy-jenkins-plugin", ".txt");
        file.deleteOnExit();

        Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
        writer.write("");
        writer.close();

        return file;
    }

    private static AWSCredentials getCredentials(String iamRole, String externalId) {
        if (isEmpty(iamRole))
            return null;

        AWSSecurityTokenServiceClient sts = new AWSSecurityTokenServiceClient();

        int credsDuration = (int) (AWSCodeDeployPublisher.DEFAULT_TIMEOUT_SECONDS
                * AWSCodeDeployPublisher.DEFAULT_POLLING_FREQUENCY_SECONDS);

        if (credsDuration > 3600) {
            credsDuration = 3600;
        }

        AssumeRoleResult assumeRoleResult = sts.assumeRole(new AssumeRoleRequest().withRoleArn(iamRole)
                .withExternalId(externalId).withDurationSeconds(credsDuration)
                .withRoleSessionName(AWSCodeDeployPublisher.ROLE_SESSION_NAME));

        Credentials stsCredentials = assumeRoleResult.getCredentials();
        BasicSessionCredentials credentials = new BasicSessionCredentials(stsCredentials.getAccessKeyId(),
                stsCredentials.getSecretAccessKey(), stsCredentials.getSessionToken());

        return credentials;
    }

    public int getProxyPort() {
        return proxyPort;
    }

    public String getProxyHost() {
        return proxyHost;
    }
}