View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.aws.status;
17  
18  import static com.google.common.base.Preconditions.checkState;
19  
20  import java.io.File;
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.SortedSet;
27  
28  import org.apache.commons.io.FileUtils;
29  import org.codehaus.plexus.util.StringUtils;
30  import org.junit.Test;
31  import org.kuali.common.aws.EncryptedAwsCredentials;
32  import org.kuali.common.aws.ec2.api.EC2Service;
33  import org.kuali.common.aws.ec2.impl.DefaultEC2Service;
34  import org.kuali.common.aws.ec2.model.EC2ServiceContext;
35  import org.kuali.common.util.file.CanonicalFile;
36  import org.kuali.common.util.log.LoggerUtils;
37  import org.kuali.common.util.wait.DefaultWaitService;
38  import org.kuali.common.util.wait.WaitService;
39  import org.slf4j.Logger;
40  
41  import com.amazonaws.auth.AWSCredentials;
42  import com.amazonaws.services.ec2.model.Instance;
43  import com.amazonaws.services.ec2.model.Tag;
44  import com.google.common.base.Joiner;
45  import com.google.common.base.Optional;
46  import com.google.common.collect.Lists;
47  import com.google.common.collect.Maps;
48  import com.google.common.collect.Sets;
49  
50  public class GetStatusTest {
51  
52  	private static final Logger logger = LoggerUtils.make();
53  	private static final Joiner JOINER = Joiner.on(',');
54  	private static final Joiner LINES = Joiner.on('\n');
55  	public static final String OUTPUT_PATH = "./target/env/aws.csv";
56  
57  	@Test
58  	public void test() {
59  		try {
60  			Map<String, List<Instance>> map = getMap();
61  			List<String> lines = getLines(map);
62  			File file = new CanonicalFile(OUTPUT_PATH);
63  			FileUtils.write(file, LINES.join(lines));
64  			logger.info(String.format("created -> %s", file));
65  		} catch (Exception e) {
66  			e.printStackTrace();
67  		}
68  	}
69  
70  	protected List<String> getLines(Map<String, List<Instance>> map) {
71  		SortedSet<String> projects = Sets.newTreeSet(map.keySet());
72  		String header = "project,env,dns,type";
73  		List<String> lines = Lists.newArrayList();
74  		for (String project : projects) {
75  			List<Instance> instances = map.get(project);
76  			lines.addAll(getLines(project, instances));
77  		}
78  		lines.add(0, header);
79  		return lines;
80  	}
81  
82  	protected List<String> getLines(String project, List<Instance> instances) {
83  		Collections.sort(instances, new InstanceComparator());
84  		List<String> lines = Lists.newArrayList();
85  		for (Instance instance : instances) {
86  			lines.add(getLine(project, instance));
87  		}
88  		return lines;
89  	}
90  
91  	protected String getLine(String project, Instance instance) {
92  		Tag name = getRequiredTag(instance, "Name");
93  		List<String> tokens = Lists.newArrayList();
94  		tokens.add(project);
95  		tokens.add(name.getValue());
96  		tokens.add(instance.getPublicDnsName());
97  		tokens.add(instance.getInstanceType());
98  		return JOINER.join(tokens);
99  	}
100 
101 	private class InstanceComparator implements Comparator<Instance> {
102 
103 		@Override
104 		public int compare(Instance one, Instance two) {
105 			Tag t1 = getRequiredTag(one, "Name");
106 			Tag t2 = getRequiredTag(two, "Name");
107 			Integer i1 = Integer.parseInt(t1.getValue().substring(3));
108 			Integer i2 = Integer.parseInt(t2.getValue().substring(3));
109 			return Double.compare(i1, i2);
110 		}
111 
112 	}
113 
114 	protected List<Instance> filter(List<Instance> instances) {
115 		List<Instance> filtered = Lists.newArrayList();
116 		for (Instance instance : instances) {
117 			boolean env = isDeployEnvironment(instance);
118 			if (env) {
119 				filtered.add(instance);
120 			}
121 		}
122 		return filtered;
123 	}
124 
125 	protected static Tag getRequiredTag(Instance instance, String key) {
126 		Optional<Tag> optional = getTag(instance, key);
127 		checkState(optional.isPresent(), "Required tag [%s] is not present for instance [%s]", key, instance.getInstanceId());
128 		return optional.get();
129 	}
130 
131 	protected static Optional<Tag> getTag(Instance instance, String key) {
132 		List<Tag> tags = instance.getTags();
133 		for (Tag tag : tags) {
134 			if (key.equals(tag.getKey())) {
135 				return Optional.of(tag);
136 			}
137 		}
138 		return Optional.absent();
139 	}
140 
141 	protected boolean isDeployEnvironment(Instance instance) {
142 		Optional<Tag> tag = getTag(instance, "Name");
143 		if (!tag.isPresent()) {
144 			return false;
145 		}
146 		String value = tag.get().getValue();
147 		return value.startsWith("env");
148 	}
149 
150 	protected String getProjectName(String accessKey) {
151 		for (EncryptedAwsCredentials credentials : EncryptedAwsCredentials.values()) {
152 			if (accessKey.equals(credentials.getAWSAccessKeyId())) {
153 				return credentials.name().toLowerCase();
154 			}
155 		}
156 		throw new IllegalArgumentException(String.format("Unable to locate a name for [%s]", accessKey));
157 	}
158 
159 	protected Map<String, List<Instance>> getMap() {
160 		List<AWSCredentials> creds = Auth.getCredentials();
161 		logger.info(String.format("Using %s sets of AWS credentials", creds.size()));
162 		WaitService ws = new DefaultWaitService();
163 		Map<String, List<Instance>> instances = Maps.newHashMap();
164 		for (AWSCredentials credentials : creds) {
165 			EC2ServiceContext context = EC2ServiceContext.create(credentials);
166 			EC2Service service = new DefaultEC2Service(context, ws);
167 			List<Instance> list = Lists.newArrayList(service.getInstances());
168 			Iterator<Instance> itr = list.iterator();
169 			while (itr.hasNext()) {
170 				Instance i = itr.next();
171 				if (!service.isOnline(i.getInstanceId())) {
172 					itr.remove();
173 				}
174 			}
175 			String projectName = getProjectName(credentials.getAWSAccessKeyId());
176 			instances.put(projectName, list);
177 			logger.debug(String.format("Located %s instances for %s", list.size(), projectName));
178 		}
179 		for (String key : instances.keySet()) {
180 			List<Instance> list = instances.get(key);
181 			List<Instance> filtered = filter(list);
182 			logger.info(String.format("%s -> %s environments", StringUtils.rightPad(key, 12), filtered.size()));
183 			instances.put(key, filtered);
184 		}
185 		return instances;
186 	}
187 }