View Javadoc

1   /**
2    *
3    * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4    *
5    * ====================================================================
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   * ====================================================================
18   */
19  package org.jclouds.compute.options;
20  
21  import static com.google.common.base.Preconditions.checkArgument;
22  import static com.google.common.base.Preconditions.checkNotNull;
23  
24  import java.io.IOException;
25  import java.util.Arrays;
26  
27  import org.jclouds.domain.Credentials;
28  import org.jclouds.io.Payload;
29  import org.jclouds.scriptbuilder.domain.Statement;
30  import org.jclouds.scriptbuilder.domain.Statements;
31  import org.jclouds.util.Strings2;
32  
33  import com.google.common.base.Throwables;
34  
35  /**
36   * Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
37   * Usage</h2> The recommended way to instantiate a TemplateOptions object is to statically import
38   * TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
39   * needed):
40   * <p/>
41   * <code>
42   * import static org.jclouds.compute.options.TemplateOptions.Builder.*;
43   * <p/>
44   * ComputeService client = // get connection
45   * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
46   * Set<? extends NodeMetadata> set = client.runNodesWithTag(tag, 2, templateBuilder.build());
47   * <code>
48   * 
49   * @author Adrian Cole
50   */
51  public class TemplateOptions extends RunScriptOptions {
52  
53     public static final TemplateOptions NONE = new ImmutableTemplateOptions(new TemplateOptions());
54  
55     public static class ImmutableTemplateOptions extends TemplateOptions {
56        private final TemplateOptions delegate;
57  
58        public ImmutableTemplateOptions(TemplateOptions delegate) {
59           this.delegate = delegate;
60        }
61  
62        @Override
63        public String toString() {
64           return delegate.toString();
65        }
66  
67        @Override
68        public <T extends TemplateOptions> T as(Class<T> clazz) {
69           return delegate.as(clazz);
70        }
71  
72        @Override
73        public TemplateOptions authorizePublicKey(String publicKey) {
74           throw new IllegalArgumentException("authorizePublicKey is immutable");
75        }
76  
77        @Override
78        public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
79           throw new IllegalArgumentException("blockUntilRunning is immutable");
80        }
81  
82        @Override
83        public int[] getInboundPorts() {
84           return delegate.getInboundPorts();
85        }
86  
87        @Override
88        public String getPrivateKey() {
89           return delegate.getPrivateKey();
90        }
91  
92        @Override
93        public String getPublicKey() {
94           return delegate.getPublicKey();
95        }
96  
97        @Override
98        public Statement getRunScript() {
99           return delegate.getRunScript();
100       }
101 
102       @Override
103       public boolean shouldBlockUntilRunning() {
104          return delegate.shouldBlockUntilRunning();
105       }
106 
107       @Override
108       public TemplateOptions inboundPorts(int... ports) {
109          throw new IllegalArgumentException("ports is immutable");
110       }
111 
112       @Override
113       public TemplateOptions installPrivateKey(String privateKey) {
114          throw new IllegalArgumentException("privateKey is immutable");
115       }
116 
117       @Override
118       public boolean isIncludeMetadata() {
119          return delegate.isIncludeMetadata();
120       }
121 
122       @Override
123       public TemplateOptions runScript(byte[] script) {
124          throw new IllegalArgumentException("withMetadata is immutable");
125       }
126 
127       @Override
128       public TemplateOptions withMetadata() {
129          throw new IllegalArgumentException("withMetadata is immutable");
130       }
131 
132    }
133 
134    protected int[] inboundPorts = new int[] { 22 };
135 
136    protected Statement script;
137 
138    protected String privateKey;
139 
140    protected String publicKey;
141 
142    protected boolean includeMetadata;
143 
144    protected boolean blockUntilRunning = true;
145 
146    public int[] getInboundPorts() {
147       return inboundPorts;
148    }
149 
150    public Statement getRunScript() {
151       return script;
152    }
153 
154    public String getPrivateKey() {
155       return privateKey;
156    }
157 
158    public String getPublicKey() {
159       return publicKey;
160    }
161 
162    public boolean isIncludeMetadata() {
163       return includeMetadata;
164    }
165 
166    public boolean shouldBlockUntilRunning() {
167       return blockUntilRunning;
168    }
169 
170    public <T extends TemplateOptions> T as(Class<T> clazz) {
171       return clazz.cast(this);
172    }
173 
174    /**
175     * This script will be executed as the root user upon system startup. This script gets a
176     * prologue, so no #!/bin/bash required, path set up, etc
177     * <p/>
178     * please use alternative that uses the {@link org.jclouds.scriptbuilder.domain.Statement} object
179     * 
180     * @see org.jclouds.io.Payloads
181     */
182    @Deprecated
183    public TemplateOptions runScript(byte[] script) {
184       return runScript(Statements.exec(new String(checkNotNull(script, "script"))));
185    }
186 
187    /**
188     * This script will be executed as the root user upon system startup. This script gets a
189     * prologue, so no #!/bin/bash required, path set up, etc
190     * 
191     * @see org.jclouds.io.Payloads
192     */
193    public TemplateOptions runScript(Payload script) {
194       try {
195          return runScript(Statements.exec(Strings2.toStringAndClose(checkNotNull(script, "script").getInput())));
196       } catch (IOException e) {
197          Throwables.propagate(e);
198          return this;
199       }
200    }
201 
202    public TemplateOptions runScript(Statement script) {
203       this.script = checkNotNull(script, "script");
204       return this;
205    }
206 
207    /**
208     * replaces the rsa ssh key used at login.
209     */
210    public TemplateOptions installPrivateKey(String privateKey) {
211       checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"),
212                "key should start with -----BEGIN RSA PRIVATE KEY-----");
213       this.privateKey = privateKey;
214       return this;
215    }
216 
217    /**
218     * replaces the rsa ssh key used at login.
219     * <p/>
220     * please use alternative that uses {@link java.lang.String}
221     * 
222     * @see org.jclouds.io.Payloads
223     */
224    @Deprecated
225    public TemplateOptions installPrivateKey(Payload privateKey) {
226       try {
227          return installPrivateKey(Strings2.toStringAndClose(checkNotNull(privateKey, "privateKey").getInput()));
228       } catch (IOException e) {
229          Throwables.propagate(e);
230          return this;
231       }
232    }
233 
234    public TemplateOptions dontAuthorizePublicKey() {
235       this.publicKey = null;
236       return this;
237    }
238 
239    /**
240     * authorize an rsa ssh key.
241     */
242    public TemplateOptions authorizePublicKey(String publicKey) {
243       checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"), "key should start with ssh-rsa");
244       this.publicKey = publicKey;
245       return this;
246    }
247 
248    /**
249     * authorize an rsa ssh key.
250     * <p/>
251     * please use alternative that uses {@link java.lang.String}
252     * 
253     * @see org.jclouds.io.Payloads
254     */
255    @Deprecated
256    public TemplateOptions authorizePublicKey(Payload publicKey) {
257       try {
258          return authorizePublicKey(Strings2.toStringAndClose(checkNotNull(publicKey, "publicKey").getInput()));
259       } catch (IOException e) {
260          Throwables.propagate(e);
261          return this;
262       }
263    }
264 
265    /**
266     * Opens the set of ports to public access.
267     */
268    public TemplateOptions inboundPorts(int... ports) {
269       for (int port : ports)
270          checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535");
271       this.inboundPorts = ports;
272       return this;
273    }
274 
275    public TemplateOptions withMetadata() {
276       this.includeMetadata = true;
277       return this;
278    }
279 
280    public static class Builder extends org.jclouds.compute.options.RunScriptOptions.Builder {
281 
282       public static TemplateOptions nameTask(String name) {
283          TemplateOptions options = new TemplateOptions();
284          return options.nameTask(name);
285       }
286 
287       public static TemplateOptions overrideCredentialsWith(Credentials credentials) {
288          TemplateOptions options = new TemplateOptions();
289          return options.withOverridingCredentials(credentials);
290       }
291 
292       public static TemplateOptions runAsRoot(boolean value) {
293          TemplateOptions options = new TemplateOptions();
294          return options.runAsRoot(value);
295       }
296 
297       /**
298        * @see TemplateOptions#blockOnPort
299        */
300       public static TemplateOptions blockOnPort(int port, int seconds) {
301          TemplateOptions options = new TemplateOptions();
302          return options.blockOnPort(port, seconds);
303       }
304 
305       /**
306        * @see TemplateOptions#inboundPorts
307        */
308       public static TemplateOptions inboundPorts(int... ports) {
309          TemplateOptions options = new TemplateOptions();
310          return options.inboundPorts(ports);
311       }
312 
313       /**
314        * @see TemplateOptions#blockUntilRunning
315        */
316       public static TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
317          TemplateOptions options = new TemplateOptions();
318          return options.blockUntilRunning(blockUntilRunning);
319       }
320 
321       /**
322        * please use alternative that uses the {@link org.jclouds.io.Payload} object
323        * 
324        * @see org.jclouds.io.Payloads
325        * @see #runScript(Payload)
326        */
327       @Deprecated
328       public static TemplateOptions runScript(byte[] script) {
329          TemplateOptions options = new TemplateOptions();
330          return options.runScript(script);
331       }
332 
333       /**
334        * @see TemplateOptions#runScript
335        * @see org.jclouds.io.Payloads
336        */
337       public static TemplateOptions runScript(Payload script) {
338          TemplateOptions options = new TemplateOptions();
339          return options.runScript(script);
340       }
341 
342       /**
343        * @see TemplateOptions#runScript
344        * @see org.jclouds.io.Payloads
345        */
346       public static TemplateOptions runScript(Statement script) {
347          TemplateOptions options = new TemplateOptions();
348          return options.runScript(script);
349       }
350 
351       /**
352        * please use alternative that uses the {@link org.jclouds.io.Payload} object
353        * 
354        * @see org.jclouds.io.Payloads
355        * @see #installPrivateKey(Payload)
356        */
357       @Deprecated
358       public static TemplateOptions installPrivateKey(String rsaKey) {
359          TemplateOptions options = new TemplateOptions();
360          return options.installPrivateKey(rsaKey);
361       }
362 
363       /**
364        * @see TemplateOptions#installPrivateKey
365        * @see org.jclouds.io.Payloads
366        */
367       public static TemplateOptions installPrivateKey(Payload rsaKey) {
368          TemplateOptions options = new TemplateOptions();
369          return options.installPrivateKey(rsaKey);
370       }
371 
372       /**
373        * please use alternative that uses the {@link org.jclouds.io.Payload} object
374        * 
375        * @see org.jclouds.io.Payloads
376        * @see #authorizePublicKey(Payload)
377        */
378       @Deprecated
379       public static TemplateOptions authorizePublicKey(String rsaKey) {
380          TemplateOptions options = new TemplateOptions();
381          return options.authorizePublicKey(rsaKey);
382       }
383 
384       /**
385        * @see TemplateOptions#authorizePublicKey(Payload)
386        * @see org.jclouds.io.Payloads
387        */
388       public static TemplateOptions authorizePublicKey(Payload rsaKey) {
389          TemplateOptions options = new TemplateOptions();
390          return options.authorizePublicKey(rsaKey);
391       }
392 
393       public static TemplateOptions withDetails() {
394          TemplateOptions options = new TemplateOptions();
395          return options.withMetadata();
396       }
397 
398       public static TemplateOptions blockOnComplete(boolean value) {
399          TemplateOptions options = new TemplateOptions();
400          return options.blockOnComplete(value);
401       }
402 
403    }
404 
405    @Override
406    public String toString() {
407       return "[inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey="
408                + (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning
409                + ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds
410                + ", metadata/details: " + includeMetadata + "]";
411    }
412 
413    public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
414       this.blockUntilRunning = blockUntilRunning;
415       if (!blockUntilRunning)
416          port = seconds = -1;
417       return this;
418    }
419 
420    @Override
421    public int hashCode() {
422       final int prime = 31;
423       int result = 1;
424       result = prime * result + (blockUntilRunning ? 1231 : 1237);
425       result = prime * result + Arrays.hashCode(inboundPorts);
426       result = prime * result + (includeMetadata ? 1231 : 1237);
427       result = prime * result + port;
428       result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
429       result = prime * result + ((publicKey == null) ? 0 : publicKey.hashCode());
430       result = prime * result + ((script == null) ? 0 : script.hashCode());
431       result = prime * result + seconds;
432       return result;
433    }
434 
435    @Override
436    public boolean equals(Object obj) {
437       if (this == obj)
438          return true;
439       if (obj == null)
440          return false;
441       if (getClass() != obj.getClass())
442          return false;
443       TemplateOptions other = (TemplateOptions) obj;
444       if (blockUntilRunning != other.blockUntilRunning)
445          return false;
446       if (!Arrays.equals(inboundPorts, other.inboundPorts))
447          return false;
448       if (includeMetadata != other.includeMetadata)
449          return false;
450       if (port != other.port)
451          return false;
452       if (privateKey == null) {
453          if (other.privateKey != null)
454             return false;
455       } else if (!privateKey.equals(other.privateKey))
456          return false;
457       if (publicKey == null) {
458          if (other.publicKey != null)
459             return false;
460       } else if (!publicKey.equals(other.publicKey))
461          return false;
462       if (script == null) {
463          if (other.script != null)
464             return false;
465       } else if (!script.equals(other.script))
466          return false;
467       if (seconds != other.seconds)
468          return false;
469       return true;
470    }
471 
472    @Override
473    public TemplateOptions blockOnPort(int port, int seconds) {
474       return TemplateOptions.class.cast(super.blockOnPort(port, seconds));
475    }
476 
477    @Override
478    public TemplateOptions nameTask(String name) {
479       return TemplateOptions.class.cast(super.nameTask(name));
480    }
481 
482    @Override
483    public TemplateOptions runAsRoot(boolean runAsRoot) {
484       return TemplateOptions.class.cast(super.runAsRoot(runAsRoot));
485    }
486 
487    @Override
488    public TemplateOptions withOverridingCredentials(Credentials overridingCredentials) {
489       return TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials));
490    }
491 
492    @Override
493    public TemplateOptions blockOnComplete(boolean blockOnComplete) {
494       return TemplateOptions.class.cast(super.blockOnComplete(blockOnComplete));
495    }
496 }