1 package org.kuali.maven.ec2;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.Properties;
8
9 import org.apache.commons.codec.binary.Base64;
10 import org.apache.commons.io.IOUtils;
11 import org.apache.maven.plugin.MojoExecutionException;
12 import org.apache.maven.project.MavenProject;
13 import org.codehaus.plexus.util.StringUtils;
14 import org.kuali.maven.common.PropertiesUtils;
15 import org.kuali.maven.common.ResourceUtils;
16
17 import com.amazonaws.services.ec2.AmazonEC2;
18 import com.amazonaws.services.ec2.model.CreateTagsRequest;
19 import com.amazonaws.services.ec2.model.Instance;
20 import com.amazonaws.services.ec2.model.InstanceType;
21 import com.amazonaws.services.ec2.model.Reservation;
22 import com.amazonaws.services.ec2.model.RunInstancesRequest;
23 import com.amazonaws.services.ec2.model.RunInstancesResult;
24 import com.amazonaws.services.ec2.model.Tag;
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public class LaunchMojo extends AbstractEC2Mojo {
39
40
41
42
43
44
45
46 private MavenProject project;
47
48
49
50
51
52
53
54 private String ami;
55
56
57
58
59
60
61
62 private String key;
63
64
65
66
67
68
69
70 private String type;
71
72
73
74
75
76
77 private List<String> securityGroups;
78
79
80
81
82
83
84 private String userData;
85
86
87
88
89
90
91
92 private String userDataFile;
93
94
95
96
97
98
99
100 private boolean filterUserData;
101
102
103
104
105
106
107 private String encoding;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 private List<Tag> tags;
129
130
131
132
133
134
135 private boolean wait;
136
137
138
139
140
141
142 private int waitTimeout;
143
144
145
146
147
148
149 private String state;
150
151 @Override
152 public void execute() throws MojoExecutionException {
153 AmazonEC2 client = getEC2Client();
154 RunInstancesRequest request = getRequest();
155 Instance i = getInstance(client, request);
156 handleTags(client, i, tags);
157 wait(client, i);
158 Instance running = getInstance(client, i.getInstanceId());
159 Properties props = project.getProperties();
160 props.setProperty("ec2.instance.id", running.getInstanceId());
161 props.setProperty("ec2.instance.name", getTagValue(running, "Name"));
162 }
163
164 protected RunInstancesRequest getRequest() throws MojoExecutionException {
165 RunInstancesRequest request = new RunInstancesRequest();
166 request.setMaxCount(1);
167 request.setMinCount(1);
168 request.setImageId(ami);
169 request.setKeyName(key);
170 request.setInstanceType(InstanceType.fromValue(type));
171 request.setSecurityGroups(securityGroups);
172 String data = getUserData(userData, userDataFile, encoding);
173 request.setUserData(data);
174 return request;
175 }
176
177 protected Instance getInstance(AmazonEC2 client, RunInstancesRequest request) {
178 RunInstancesResult result = client.runInstances(request);
179 Reservation r = result.getReservation();
180 List<Instance> instances = r.getInstances();
181 return instances.get(0);
182 }
183
184 protected void wait(AmazonEC2 client, Instance i) throws MojoExecutionException {
185 if (wait) {
186 getLog().info("Waiting up to " + waitTimeout + " seconds for " + i.getInstanceId() + " to start");
187 waitForState(client, i.getInstanceId(), state, waitTimeout);
188 Instance running = getInstance(client, i.getInstanceId());
189 String id = i.getInstanceId();
190 String dns = running.getPublicDnsName();
191 getLog().info("EC2 Instance: " + getTagValue(running, "Name") + " (" + id + ") " + dns);
192 Properties props = project.getProperties();
193 props.setProperty("ec2.instance.dns", running.getPublicDnsName());
194 } else {
195 getLog().info("Launched " + i.getInstanceId());
196 }
197 }
198
199 protected void handleTags(AmazonEC2 client, Instance instance, List<Tag> tags) {
200 if (isEmpty(tags)) {
201 return;
202 }
203 CreateTagsRequest request = new CreateTagsRequest();
204 request.setResources(Collections.singletonList(instance.getInstanceId()));
205 request.setTags(tags);
206 client.createTags(request);
207 }
208
209 protected String getUserData(String data, String location, String encoding) throws MojoExecutionException {
210 String s = data;
211 if (!StringUtils.isBlank(location)) {
212 try {
213 s = getString(location, encoding);
214 } catch (IOException e) {
215 throw new MojoExecutionException("Error reading from " + location, e);
216 }
217 }
218 if (StringUtils.isBlank(s)) {
219 return null;
220 }
221 if (filterUserData) {
222 PropertiesUtils pu = new PropertiesUtils();
223 Properties properties = pu.getMavenProperties(project);
224 s = pu.getResolvedValue(s, properties);
225 }
226 getLog().debug("filteredUserData=" + s);
227 byte[] bytes = Base64.encodeBase64(s.getBytes());
228 String base64 = new String(bytes);
229 getLog().debug("base64Encoded=" + base64);
230 return base64;
231 }
232
233 protected String getString(String location, String encoding) throws IOException {
234 InputStream in = null;
235 try {
236 ResourceUtils ru = new ResourceUtils();
237 in = ru.getInputStream(location);
238 return IOUtils.toString(in, encoding);
239 } finally {
240 IOUtils.closeQuietly(in);
241 }
242 }
243
244 public String getAmi() {
245 return ami;
246 }
247
248 public void setAmi(String ami) {
249 this.ami = ami;
250 }
251
252 public String getKey() {
253 return key;
254 }
255
256 public void setKey(String key) {
257 this.key = key;
258 }
259
260 public String getType() {
261 return type;
262 }
263
264 public void setType(String type) {
265 this.type = type;
266 }
267
268 public List<String> getSecurityGroups() {
269 return securityGroups;
270 }
271
272 public void setSecurityGroups(List<String> securityGroups) {
273 this.securityGroups = securityGroups;
274 }
275
276 public String getUserData() {
277 return userData;
278 }
279
280 public void setUserData(String userData) {
281 this.userData = userData;
282 }
283
284 public String getEncoding() {
285 return encoding;
286 }
287
288 public void setEncoding(String encoding) {
289 this.encoding = encoding;
290 }
291
292 public boolean isFilterUserData() {
293 return filterUserData;
294 }
295
296 public void setFilterUserData(boolean filterUserData) {
297 this.filterUserData = filterUserData;
298 }
299
300 public MavenProject getProject() {
301 return project;
302 }
303
304 public List<Tag> getTags() {
305 return tags;
306 }
307
308 public void setTags(List<Tag> tags) {
309 this.tags = tags;
310 }
311
312 public boolean isWait() {
313 return wait;
314 }
315
316 public void setWait(boolean wait) {
317 this.wait = wait;
318 }
319
320 public int getWaitTimeout() {
321 return waitTimeout;
322 }
323
324 public void setWaitTimeout(int waitTimeout) {
325 this.waitTimeout = waitTimeout;
326 }
327
328 public String getState() {
329 return state;
330 }
331
332 public void setState(String state) {
333 this.state = state;
334 }
335
336 public String getUserDataFile() {
337 return userDataFile;
338 }
339
340 public void setUserDataFile(String userDataFile) {
341 this.userDataFile = userDataFile;
342 }
343 }