jp.classmethod.aws.gradle.cloudformation.AmazonCloudFormationPluginExtension.java Source code

Java tutorial

Introduction

Here is the source code for jp.classmethod.aws.gradle.cloudformation.AmazonCloudFormationPluginExtension.java

Source

/*
 * Copyright 2015-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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 jp.classmethod.aws.gradle.cloudformation;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import lombok.Getter;
import lombok.Setter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.gradle.api.GradleException;
import org.gradle.api.Project;

import com.amazonaws.AmazonClientException;
import com.amazonaws.services.cloudformation.AmazonCloudFormationClient;
import com.amazonaws.services.cloudformation.model.AmazonCloudFormationException;
import com.amazonaws.services.cloudformation.model.Capability;
import com.amazonaws.services.cloudformation.model.DescribeStackResourcesRequest;
import com.amazonaws.services.cloudformation.model.DescribeStackResourcesResult;
import com.amazonaws.services.cloudformation.model.DescribeStacksRequest;
import com.amazonaws.services.cloudformation.model.DescribeStacksResult;
import com.amazonaws.services.cloudformation.model.Output;
import com.amazonaws.services.cloudformation.model.Parameter;
import com.amazonaws.services.cloudformation.model.Stack;
import com.amazonaws.services.cloudformation.model.StackResource;
import com.amazonaws.services.cloudformation.model.ValidateTemplateRequest;

import jp.classmethod.aws.gradle.common.BaseRegionAwarePluginExtension;

public class AmazonCloudFormationPluginExtension
        extends BaseRegionAwarePluginExtension<AmazonCloudFormationClient> {

    private static Logger logger = LoggerFactory.getLogger(AmazonCloudFormationPluginExtension.class);

    public static final String NAME = "cloudFormation";

    @Getter
    @Setter
    private String stackName;

    @Getter
    @Setter
    private Map<?, ?> stackParams = new HashMap<>();

    @Getter
    @Setter
    private Map<?, ?> stackTags = new HashMap<>();

    @Getter
    @Setter
    private String templateURL;

    @Getter
    @Setter
    private String onFailure;

    @Getter
    @Setter
    private File templateFile;

    @Getter
    @Setter
    private String templateBucket;

    @Getter
    @Setter
    private String templateKeyPrefix;

    @Getter
    @Setter
    private String stackPolicyURL;

    @Getter
    @Setter
    private File stackPolicyFile;

    @Getter
    @Setter
    private String stackPolicyBucket;

    @Getter
    @Setter
    private String stackPolicyKeyPrefix;

    @Getter
    @Setter
    private boolean capabilityIam;

    @Getter
    @Setter
    private Capability useCapabilityIam;

    public AmazonCloudFormationPluginExtension(Project project) {
        super(project, AmazonCloudFormationClient.class);
    }

    public Optional<Stack> getStack() {
        return getStack(stackName);
    }

    public Optional<Stack> getStack(String stackName) {
        if (getProject().getGradle().getStartParameter().isOffline() == false) {
            try {
                DescribeStacksResult describeStacksResult = getClient()
                        .describeStacks(new DescribeStacksRequest().withStackName(stackName));
                List<Stack> stacks = describeStacksResult.getStacks();
                if (stacks.isEmpty() == false) {
                    return stacks.stream().findAny();
                }
            } catch (AmazonCloudFormationException e) {
                if ("ValidationError".equals(e.getErrorCode())) {
                    return Optional.empty();
                } else {
                    throw new GradleException(e.getMessage(), e);
                }
            }
        }
        return Optional.empty();
    }

    public List<Parameter> getStackParameters() {
        return getStackParameters(stackName);
    }

    public List<Parameter> getStackParameters(String stackName) {
        if (getProject().getGradle().getStartParameter().isOffline() == false) {
            Optional<Stack> stack = getStack(stackName);
            return stack.map(Stack::getParameters).orElse(Collections.emptyList());
        }
        logger.info("offline mode: return empty parameters");
        return Collections.emptyList();
    }

    public List<Output> getStackOutputs() {
        return getStackOutputs(stackName);
    }

    public List<Output> getStackOutputs(String stackName) {
        if (getProject().getGradle().getStartParameter().isOffline() == false) {
            Optional<Stack> stack = getStack(stackName);
            return stack.map(Stack::getOutputs).orElse(Collections.emptyList());
        }
        logger.info("offline mode: return empty outputs");
        return Collections.emptyList();
    }

    public List<StackResource> getStackResources() {
        return getStackResources(stackName);
    }

    public List<StackResource> getStackResources(String stackName) {
        if (getProject().getGradle().getStartParameter().isOffline() == false) {
            try {
                DescribeStackResourcesResult describeStackResourcesResult = getClient()
                        .describeStackResources(new DescribeStackResourcesRequest().withStackName(stackName));
                return describeStackResourcesResult.getStackResources();
            } catch (AmazonCloudFormationException e) {
                if ("ValidationError".equals(e.getErrorCode())) {
                    return Collections.emptyList();
                } else {
                    throw new GradleException(e.getMessage(), e);
                }
            }
        }
        logger.info("offline mode: return empty resources");
        return Collections.emptyList();
    }

    public String getStackParameterValue(String key) {
        return getStackParameterValue(stackName, key);
    }

    public String getStackParameterValue(String stackName, String key) {
        return findStackParameterValue(stackName, key);
    }

    public String findStackParameterValue(String stackName, String key) {
        Optional<Parameter> param = getStackParameters(stackName).stream()
                .filter(p -> p.getParameterKey().equals(key)).findAny();
        if (param.isPresent() == false) {
            logger.warn("WARN: param {} for stack {} is not found", key, stackName);
        }
        return param.map(Parameter::getParameterValue).orElse(null);
    }

    public String getStackOutputValue(String key) {
        return getStackOutputValue(stackName, key);
    }

    public String getStackOutputValue(String stackName, String key) {
        return findStackOutputValue(stackName, key);
    }

    public String findStackOutputValue(String stackName, String key) {
        Optional<Output> output = getStackOutputs(stackName).stream().filter(p -> p.getOutputKey().equals(key))
                .findAny();
        if (output.isPresent() == false) {
            logger.warn("WARN: output {} for stack {} is not found", key, stackName);
        }
        return output.map(Output::getOutputValue).orElse(null);
    }

    public String getPhysicalResourceId(String logicalResourceId) {
        return getPhysicalResourceId(stackName, logicalResourceId);
    }

    public String getPhysicalResourceId(String stackName, String logicalResourceId) {
        return findPhysicalResourceId(stackName, logicalResourceId);
    }

    public String findPhysicalResourceId(String stackName, String logicalResourceId) {
        Optional<StackResource> physicalResource = getStackResources(stackName).stream()
                .filter(r -> r.getLogicalResourceId().equals(logicalResourceId)).findAny();
        if (physicalResource.isPresent() == false) {
            logger.warn("WARN: physical resource {} for stack {} is not found", logicalResourceId, stackName);
        }
        return physicalResource.map(StackResource::getPhysicalResourceId).orElse(null);
    }

    public boolean isValidTemplateBody(String templateBody) {
        try {
            ValidateTemplateRequest validateTemplateRequest = new ValidateTemplateRequest()
                    .withTemplateBody(templateBody);
            getClient().validateTemplate(validateTemplateRequest);
            return true;
        } catch (AmazonClientException e) {
            logger.error("validateTemplateBody failed: {}", e.getMessage());
            return false;
        }
    }

    public boolean isValidTemplateUrl(String templateUrl) {
        try {
            ValidateTemplateRequest validateTemplateRequest = new ValidateTemplateRequest()
                    .withTemplateURL(templateUrl);
            getClient().validateTemplate(validateTemplateRequest);
            return true;
        } catch (AmazonClientException e) {
            logger.error("validateTemplateUrl failed: {}", e.getMessage());
            return false;
        }
    }

    public List<Parameter> toParameters(Map<String, String> map) {
        return map.entrySet().stream()
                .map(e -> new Parameter().withParameterKey(e.getKey()).withParameterValue(e.getValue()))
                .collect(Collectors.toList());
    }

    public Map<String, String> toMap(List<Parameter> parameters) {
        return parameters.stream()
                .collect(Collectors.toMap(Parameter::getParameterKey, Parameter::getParameterValue));
    }
}