1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }