fr.xebia.demo.amazon.aws.AmazonAwsShutdowner.java Source code

Java tutorial

Introduction

Here is the source code for fr.xebia.demo.amazon.aws.AmazonAwsShutdowner.java

Source

/*
 * Copyright 2008-2010 Xebia and 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 fr.xebia.demo.amazon.aws;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

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

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DeleteSnapshotRequest;
import com.amazonaws.services.ec2.model.DeregisterImageRequest;
import com.amazonaws.services.ec2.model.DescribeImagesRequest;
import com.amazonaws.services.ec2.model.DescribeSnapshotsRequest;
import com.amazonaws.services.ec2.model.Image;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.Snapshot;
import com.amazonaws.services.ec2.model.StopInstancesRequest;
import com.amazonaws.services.ec2.model.TagDescription;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancing;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
import com.amazonaws.services.rds.AmazonRDS;
import com.amazonaws.services.rds.AmazonRDSClient;
import com.amazonaws.services.rds.model.DBInstance;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;

public class AmazonAwsShutdowner {

    private static final String TAG_DO_NOT_DEREGISTER = "do-not-deregister";

    public static final Function<Instance, String> TO_INSTANCE_ID_FUNCTION = new Function<Instance, String>() {
        @Override
        public String apply(Instance instance) {
            return instance.getInstanceId();
        }
    };

    public static final Function<Image, String> TO_IMAGE_ID_FUNCTION = new Function<Image, String>() {
        @Override
        public String apply(Image image) {
            return image.getImageId();
        }
    };

    private static final String TAG_DO_NOT_TERMINATE = "do-not-terminate";

    private static final String TAG_DO_NOT_STOP = "do-not-stop";

    public static void main(String[] args) throws Exception {
        AmazonAwsShutdowner amazonAwsShutdowner = new AmazonAwsShutdowner();
        amazonAwsShutdowner.test();

    }

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    private AmazonEC2 ec2;

    private AmazonRDS rds;

    private AmazonElasticLoadBalancing elb;

    public AmazonAwsShutdowner() throws IOException {
        InputStream credentialsAsStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("AwsCredentials.properties");
        Preconditions.checkNotNull(credentialsAsStream,
                "File 'AwsCredentials.properties' NOT found in the classpath");
        AWSCredentials credentials = new PropertiesCredentials(credentialsAsStream);
        ec2 = new AmazonEC2Client(credentials);
        ec2.setEndpoint("ec2.eu-west-1.amazonaws.com");
        rds = new AmazonRDSClient(credentials);
        rds.setEndpoint("rds.eu-west-1.amazonaws.com");
        elb = new AmazonElasticLoadBalancingClient(credentials);
        elb.setEndpoint("elasticloadbalancing.eu-west-1.amazonaws.com");
    }

    public void test() {
        String ownerId = "self";

        boolean dryRun = true;

        // RETRIEVE TAGS
        Map<String, Map<String, String>> tagsByResourceId = new MapMaker()
                .makeComputingMap(new Function<String, Map<String, String>>() {
                    @Override
                    public Map<String, String> apply(String input) {
                        return Maps.newHashMap();
                    }
                });

        for (TagDescription tagDescription : ec2.describeTags().getTags()) {
            tagsByResourceId.get(tagDescription.getResourceId()).put(tagDescription.getKey(),
                    tagDescription.getValue());
        }

        // RDS INSTANCEs
        for (DBInstance dbInstance : rds.describeDBInstances().getDBInstances()) {
            Map<String, String> instanceTags = tagsByResourceId.get(dbInstance.getDBInstanceIdentifier());
            logger.debug("Tags for " + dbInstance + ": " + instanceTags);

        }

        // EC2 INSTANCES
        List<Instance> instancesAlreadyNotStarted = Lists.newArrayList();
        List<Instance> instancesToStop = Lists.newArrayList();
        List<Instance> instancesToTerminate = Lists.newArrayList();
        List<Instance> instancesToKeepUnchanged = Lists.newArrayList();
        for (Reservation reservation : ec2.describeInstances().getReservations()) {
            for (Instance instance : reservation.getInstances()) {
                Map<String, String> instanceTags = tagsByResourceId.get(instance.getInstanceId());
                logger.debug("Tags for {}: {}", instance, instanceTags);
                if ("terminated".equals(instance.getState().getName())) {
                    instancesToKeepUnchanged.add(instance);
                } else if (instanceTags.containsKey(TAG_DO_NOT_STOP)) {
                    instancesToKeepUnchanged.add(instance);
                } else if (instanceTags.containsKey(TAG_DO_NOT_TERMINATE)) {
                    if ("started".equals(instance.getState().getName())) {
                        instancesToStop.add(instance);
                    } else {
                        instancesAlreadyNotStarted.add(instance);
                    }
                } else {
                    instancesToTerminate.add(instance);
                }
            }
        }
        System.out.println("EC2 INSTANCES");
        if (dryRun) {
            System.out.println("DRY RUN Terminate:" + instancesToTerminate);
            System.out.println("DRY RUN Stop:" + instancesToStop);
            System.out.println("DRY RUN No need to stop:" + instancesAlreadyNotStarted);
            System.out.println("DRY RUN Keep unchanged:" + instancesToKeepUnchanged);
        } else {
            System.out.println("Terminate:" + instancesToTerminate);
            if (!instancesToTerminate.isEmpty()) {
                ec2.terminateInstances(new TerminateInstancesRequest(
                        Lists.transform(instancesToTerminate, TO_INSTANCE_ID_FUNCTION)));
            }
            System.out.println("Stop:" + instancesToStop);
            if (!instancesToStop.isEmpty()) {
                ec2.stopInstances(
                        new StopInstancesRequest(Lists.transform(instancesToStop, TO_INSTANCE_ID_FUNCTION)));
            }
            System.out.println("No need to stop:" + instancesAlreadyNotStarted);
            System.out.println("Keep unchanged:" + instancesToKeepUnchanged);
        }

        // AMIs
        System.out.println("AMIs");
        List<Image> imagesToDeRegister = Lists.newArrayList();
        List<Image> imagesToKeep = Lists.newArrayList();
        for (Image image : ec2.describeImages(new DescribeImagesRequest().withOwners(ownerId)).getImages()) {
            Map<String, String> imageTags = tagsByResourceId.get(image.getImageId());
            logger.debug("Tags for {}: {}", image, imageTags);
            if (imageTags.containsKey(TAG_DO_NOT_DEREGISTER)) {
                imagesToKeep.add(image);
            } else {
                imagesToDeRegister.add(image);
            }
        }
        if (dryRun) {
            System.out.println("DRY RUN Deregister:" + imagesToDeRegister);
            System.out.println("DRY RUN Keep:" + imagesToKeep);

        } else {
            System.out.println("Deregister:" + imagesToDeRegister);
            for (Image image : imagesToDeRegister) {
                ec2.deregisterImage(new DeregisterImageRequest(image.getImageId()));
            }
            System.out.println("Keep:" + imagesToKeep);
        }

        List<String> imageIdsToKeep = Lists.transform(imagesToKeep, TO_IMAGE_ID_FUNCTION);

        // SNAPSHOTS
        System.out.println("SNAPSHOTs");
        for (Snapshot snapshot : ec2.describeSnapshots(new DescribeSnapshotsRequest().withOwnerIds(ownerId))
                .getSnapshots()) {

            if (snapshot.getDescription().contains("Created by CreateImage")) {
                boolean associatedWithAnImageToKeep = false;
                for (String imageIdToKeep : imageIdsToKeep) {
                    if (snapshot.getDescription().contains(imageIdToKeep)) {
                        associatedWithAnImageToKeep = true;
                        break;
                    }
                }
                if (associatedWithAnImageToKeep) {
                    System.out.println("Keep: " + snapshot);
                } else {
                    if (dryRun) {
                        System.out.println("DRY RUN delete: " + snapshot);
                    } else {
                        System.out.println("Delete: " + snapshot);
                        ec2.deleteSnapshot(new DeleteSnapshotRequest(snapshot.getSnapshotId()));
                    }
                }
            }
        }
        // ELASTIC LOAD BALANCERs
        // no tags on elb
    }

}