mirror of https://github.com/apache/jclouds.git
Merge upstream
This commit is contained in:
commit
e7daafb101
34
README.txt
34
README.txt
|
@ -26,32 +26,30 @@ two abstractions at the moment: compute and blobstore. compute helps you
|
|||
bootstrap machines in the cloud. blobstore helps you manage key-value
|
||||
data.
|
||||
|
||||
our current version is 1.0-beta-8
|
||||
our current version is 1.0-beta-9a
|
||||
our dev version is 1.0-SNAPSHOT
|
||||
|
||||
our compute api supports: aws-ec2, gogrid, cloudservers (generic), cloudservers-us,
|
||||
cloudservers-uk, vcloud (generic), ec2 (generic),
|
||||
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory),
|
||||
cloudservers-uk, vcloud (generic), ec2 (generic), byon,
|
||||
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
||||
cloudsigma-zrh, elasticstack(generic), bluelock-vclouddirector,
|
||||
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
||||
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
|
||||
openhosting-east1, serverlove-z1-man, skalicloud-sdg-my,
|
||||
vcloudexpress (generic), stub (in-memory)
|
||||
openhosting-east1, serverlove-z1-man, skalicloud-sdg-my
|
||||
|
||||
* note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
|
||||
to all of these providers
|
||||
|
||||
our blobstore api supports: aws-s3, cloudfiles (generic), cloudfiles-us, cloudfiles-uk,
|
||||
azureblob, atmos (generic), synaptic-storage,
|
||||
cloudonestorage, s3 (generic), walrus(generic), googlestorage,
|
||||
eucalyptus-partnercloud-s3, swift (generic), transient (in-mem),
|
||||
filesystem (on-disk)
|
||||
our blobstore api supports: aws-s3, cloudfiles-us, cloudfiles-uk, filesystem,
|
||||
azureblob, atmos (generic), synaptic-storage, scaleup-storage,
|
||||
cloudonestorage, walrus(generic), googlestorage,
|
||||
eucalyptus-partnercloud-s3, swift (generic), transient (in-mem)
|
||||
|
||||
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
|
||||
to all of these providers
|
||||
|
||||
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, rimuhosting, openstack nova,
|
||||
azurequeue, simpledb, scaleup-storage as well as a async-http-client
|
||||
azurequeue, simpledb, cloudstack as well as a async-http-client
|
||||
driver in the sandbox
|
||||
|
||||
|
||||
|
@ -61,7 +59,7 @@ If you want access to all jclouds components, include the maven dependency org.j
|
|||
BlobStore Example (Java):
|
||||
// init
|
||||
context = new BlobStoreContextFactory().createContext(
|
||||
"s3",
|
||||
"aws-s3",
|
||||
accesskeyid,
|
||||
secretaccesskey);
|
||||
blobStore = context.getBlobStore();
|
||||
|
@ -84,7 +82,7 @@ BlobStore Example (Clojure):
|
|||
Compute Example (Java):
|
||||
// init
|
||||
context = new ComputeServiceContextFactory().createContext(
|
||||
"ec2",
|
||||
"aws-ec2",
|
||||
accesskeyid,
|
||||
secretaccesskey,
|
||||
ImmutableSet.of(new Log4JLoggingModule(),
|
||||
|
@ -95,28 +93,28 @@ Compute Example (Java):
|
|||
template = client.templateBuilder().osFamily(UBUNTU).smallest().build();
|
||||
|
||||
// these nodes will be accessible via ssh when the call returns
|
||||
nodes = client.runNodesWithTag("mycluster", 2, template);
|
||||
nodes = client.createNodesInGroup("mycluster", 2, template);
|
||||
|
||||
Compute Example (Clojure):
|
||||
(use 'org.jclouds.compute)
|
||||
|
||||
; create a compute service using ssh and log4j extensions
|
||||
(def compute
|
||||
(compute-service "terremark" "user" "password" :ssh :log4j))
|
||||
(compute-service "trmk`-ecloud" "user" "password" :ssh :log4j))
|
||||
|
||||
; use the default node template and launch a couple nodes
|
||||
; these will have your ~/.ssh/id_rsa.pub authorized when complete
|
||||
(with-compute-service [compute]
|
||||
(run-nodes "mycluster" 2))
|
||||
(create-nodes "mycluster" 2))
|
||||
|
||||
Downloads:
|
||||
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-8.zip
|
||||
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-9a.zip
|
||||
* maven repo: http://repo2.maven.org/maven2 (maven central - the default repository)
|
||||
* snapshot repo: https://oss.sonatype.org/content/repositories/snapshots
|
||||
|
||||
Links:
|
||||
* project page: http://code.google.com/p/jclouds/
|
||||
* javadocs (1.0-beta-8): http://jclouds.rimuhosting.com/apidocs/
|
||||
* javadocs (1.0-beta-9a): http://jclouds.rimuhosting.com/apidocs/
|
||||
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
|
||||
* community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds
|
||||
* user group: http://groups.google.com/group/jclouds
|
||||
|
|
|
@ -39,10 +39,5 @@
|
|||
<artifactId>jclouds-allblobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-elb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
<artifactId>googlestorage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>scaleup-storage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>synaptic-storage</artifactId>
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
<artifactId>aws-ec2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>byon</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>ec2</artifactId>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>0.1.42</version>
|
||||
<version>0.1.44</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
provider=bluelock-vcloudirector
|
||||
driver=bluelock
|
||||
identity=user@your_org
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,5 +0,0 @@
|
|||
provider=ec2
|
||||
driver=aws
|
||||
identity=accesscredentialid
|
||||
credential=secretaccesscredential
|
||||
tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id
|
|
@ -1,7 +0,0 @@
|
|||
provider=eucalyptus
|
||||
driver=aws
|
||||
# note you need to change this to the correct endpoint
|
||||
eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus
|
||||
identity=accesskey
|
||||
credential=secret
|
||||
tag=name_of_your_cluster_or_instance
|
|
@ -1,5 +0,0 @@
|
|||
provider=gogrid
|
||||
driver=gogrid
|
||||
identity=apikey
|
||||
credential=secret
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
provider=cloudservers
|
||||
driver=rackspace
|
||||
identity=user
|
||||
credential=your_credential
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
provider=rimuhosting
|
||||
driver=rimuhosting
|
||||
identity=apicredential
|
||||
credential=apicredential
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
provider=trmk-ecloud
|
||||
driver=terremark
|
||||
identity=user@youregistered.com
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,5 +0,0 @@
|
|||
provider=trmk-vcloudexpress
|
||||
driver=terremark
|
||||
identity=user@youregistered.com
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,7 +0,0 @@
|
|||
provider=vcloud
|
||||
driver=vcloud
|
||||
# note you need to change this to the correct endpoint
|
||||
vcloud.endpoint=https://vcloud_host_you_want/api
|
||||
identity=user@your_org
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,126 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<project xmlns:artifact="urn:maven-artifact-ant" name="cargooverssh" default="cargooverssh" basedir=".">
|
||||
<property file="build.properties" />
|
||||
<property name="jclouds.version" value="1.0-SNAPSHOT" />
|
||||
<property name="privatekeyfile" value="${user.home}/.ssh/id_rsa" />
|
||||
<property name="publickeyfile" value="${user.home}/.ssh/id_rsa.pub" />
|
||||
<property name="listenport" value="8080" />
|
||||
<property name="container.zip" value="http://apache.imghat.com//tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.tar.gz" />
|
||||
<property name="warfile" value="build/samples-blazeds.war" />
|
||||
|
||||
<!-- maven must be available before we use it -->
|
||||
<delete dir="build/cargo"/>
|
||||
<mkdir dir="build/cargo"/>
|
||||
|
||||
<get src="http://opensource.become.com/apache//maven/binaries/maven-ant-tasks-2.1.1.jar" dest="build/maven-ant-tasks"/>
|
||||
<get src="http://web-actions.googlecode.com/files/samples-blazeds.war" dest="${warfile}"/>
|
||||
|
||||
<input
|
||||
message="Which provider would you like to use (ec2, cloudservers, vcloud, terremark, rimuhosting)?"
|
||||
validargs="ec2,cloudservers,vcloud,trmk-ecloud,trmk-vcloudexpress,eucalyptus,bluelock-vcdirector,gogrid,rimuhosting"
|
||||
addproperty="provider"
|
||||
/>
|
||||
|
||||
<input
|
||||
message="Which driver does ${provider} use?"
|
||||
validargs="aws,rackspace,vcloud,bluelock,gogrid,terremark,ibmdev,rimuhosting"
|
||||
addproperty="driver"
|
||||
/>
|
||||
|
||||
<!-- initialize maven tasks -->
|
||||
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks"/>
|
||||
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath"/>
|
||||
|
||||
<artifact:localRepository id="local.repository" path="${user.home}/.m2/repository"/>
|
||||
<artifact:remoteRepository id="jclouds.repository" url="http://repo1.maven.org/maven2" />
|
||||
<artifact:remoteRepository id="jclouds-snapshot.repository" url="https://oss.sonatype.org/content/repositories/snapshots"/>
|
||||
|
||||
<!-- Setup maven so that we can get latest version of jclouds, jclouds, and jruby -->
|
||||
<artifact:dependencies pathId="jclouds.classpath">
|
||||
<dependency groupid="org.codehaus.cargo" artifactId="cargo-ant" version="1.0.5"/>
|
||||
<dependency groupid="org.codehaus.cargo" artifactId="cargo-core-container-tomcat" version="1.0.5"/>
|
||||
<dependency groupId="org.jclouds" artifactId="jclouds-${driver}" version="${jclouds.version}"/>
|
||||
<dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="${jclouds.version}"/>
|
||||
<remoteRepository refid="jclouds.repository"/>
|
||||
<remoteRepository refid="jclouds-snapshot.repository"/>
|
||||
<localRepository refid="local.repository"/>
|
||||
</artifact:dependencies>
|
||||
|
||||
<typedef name="compute" classname="org.jclouds.tools.ant.taskdefs.compute.ComputeTask" classpathref="jclouds.classpath" />
|
||||
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jclouds.classpath" />
|
||||
<taskdef resource="cargo.tasks" classpathref="jclouds.classpath"/>
|
||||
|
||||
<input message="What is your identity on ${provider}?" addproperty="identity"/>
|
||||
<input message="What is the credential for ${identity}?" addproperty="credential"/>
|
||||
<input message="What is the tag for the deployment?" addproperty="tag"/>
|
||||
<property name="url" value="compute://${identity}:${credential}@${provider}"/>
|
||||
|
||||
<target name="destroy" description="destroy the nodes ${tag}">
|
||||
<compute actions="destroy" provider="${url}">
|
||||
<nodes tag="${tag}" />
|
||||
</compute>
|
||||
<sleep seconds="5" />
|
||||
</target>
|
||||
|
||||
<target name="create" description="create the nodes ${tag}" >
|
||||
<compute actions="destroy,create" provider="${url}">
|
||||
<nodes tag="${tag}" os="UBUNTU" hardware="SMALLEST"
|
||||
runscript="runscript.sh" openports="22,${listenport}"
|
||||
privatekeyfile="${privatekeyfile}" publickeyfile="${publickeyfile}"
|
||||
hostproperty="host" usernameproperty="username" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="cargooverssh" depends="create" description="run cargo on remote nodes" >
|
||||
<echo message="deploying tomcat and blaze to: http://${host}:${listenport}/samples-blazeds/" />
|
||||
<cargo containerId="tomcat6x" output="build/output.log" log="build/cargo.log" action="start" timeout="600000">
|
||||
<zipurlinstaller installurl="${container.zip}" />
|
||||
<configuration home="build/cargo" type="standalone">
|
||||
<property name="cargo.java.home" value="/usr/lib/jvm/java-6-openjdk"/>
|
||||
<property name="cargo.hostname" value="${host}"/>
|
||||
<property name="cargo.servlet.port" value="${listenport}"/>
|
||||
<property name="cargo.ssh.host" value="${host}"/>
|
||||
<property name="cargo.ssh.username" value="${username}"/>
|
||||
<property name="cargo.ssh.password" value=""/>
|
||||
<property name="cargo.ssh.keyfile" value="${privatekeyfile}"/>
|
||||
<property name="cargo.ssh.remotebase" value="/tmp/cargo"/>
|
||||
<property name="cargo.logging" value="high"/>
|
||||
<deployable type="war" file="${warfile}"/>
|
||||
</configuration>
|
||||
</cargo>
|
||||
</target>
|
||||
|
||||
<target name="justplaincargo" description="run cargo on local machine" >
|
||||
<echo message="deploying tomcat and blaze to: http://localhost:${listenport}/samples-blazeds/" />
|
||||
<cargo containerId="tomcat6x" output="build/output.log" log="build/cargo.log" action="start" timeout="600000">
|
||||
<zipurlinstaller installurl="${container.zip}" />
|
||||
<configuration home="build/cargo" type="standalone">
|
||||
<property name="cargo.servlet.port" value="${listenport}"/>
|
||||
<property name="cargo.logging" value="high"/>
|
||||
<deployable type="war" file="${warfile}"/>
|
||||
</configuration>
|
||||
</cargo>
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -1,29 +0,0 @@
|
|||
#
|
||||
#
|
||||
# Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
#
|
||||
# ====================================================================
|
||||
# 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.
|
||||
# ====================================================================
|
||||
#
|
||||
|
||||
echo nameserver 208.67.222.222 >> /etc/resolv.conf
|
||||
apt-get update -qq
|
||||
apt-get upgrade -y -qq
|
||||
apt-get install -y -qq wget
|
||||
apt-get install -y -qq openjdk-6-jdk
|
||||
wget -q http://mirrors.axint.net/apache/tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.tar.gz
|
||||
tar xzf apache-tomcat-6.0.29.tar.gz
|
||||
mkdir -p /tmp/cargo/containers
|
||||
chmod 1777 /tmp/cargo
|
||||
mv apache-tomcat-6.0.29 /tmp/cargo/containers/tomcat6x
|
|
@ -1,5 +0,0 @@
|
|||
provider=bluelock-vcloudirector
|
||||
driver=bluelock
|
||||
identity=user@your_org
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,5 +0,0 @@
|
|||
provider=ec2
|
||||
driver=aws
|
||||
identity=accesscredentialid
|
||||
credential=secretaccesscredential
|
||||
tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id
|
|
@ -1,7 +0,0 @@
|
|||
provider=eucalyptus
|
||||
driver=aws
|
||||
# note you need to change this to the correct endpoint
|
||||
eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus
|
||||
identity=accesskey
|
||||
credential=secret
|
||||
tag=name_of_your_cluster_or_instance
|
|
@ -1,5 +0,0 @@
|
|||
provider=gogrid
|
||||
driver=gogrid
|
||||
identity=apikey
|
||||
credential=secret
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
provider=cloudservers
|
||||
driver=rackspace
|
||||
identity=user
|
||||
credential=your_credential
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
provider=rimuhosting
|
||||
driver=rimuhosting
|
||||
identity=apicredential
|
||||
credential=apicredential
|
||||
tag=name_of_your_server
|
|
@ -1,5 +0,0 @@
|
|||
service=terremark
|
||||
driver=terremark
|
||||
account=user@youregistered.com
|
||||
key=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,5 +0,0 @@
|
|||
provider=trmk-ecloud
|
||||
driver=terremark
|
||||
identity=user@youregistered.com
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,5 +0,0 @@
|
|||
provider=trmk-vcloudexpress
|
||||
driver=terremark
|
||||
identity=user@youregistered.com
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -1,7 +0,0 @@
|
|||
provider=vcloud
|
||||
driver=vcloud
|
||||
# note you need to change this to the correct endpoint
|
||||
vcloud.endpoint=https://vcloud_host_you_want/api
|
||||
identity=user@your_org
|
||||
credential=password
|
||||
tag=name_of_your_vapp
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<project name="compute" default="dump" basedir="." xmlns:artifact="urn:maven-artifact-ant">
|
||||
<property file="build.properties" />
|
||||
<property name="jclouds.version" value="1.0-SNAPSHOT" />
|
||||
<property name="jclouds.version" value="1.0-beta-9a" />
|
||||
<property name="privatekeyfile" value="${user.home}/.ssh/id_rsa" />
|
||||
<property name="publickeyfile" value="${user.home}/.ssh/id_rsa.pub" />
|
||||
|
||||
|
@ -30,29 +30,21 @@
|
|||
<get src="http://opensource.become.com/apache//maven/binaries/maven-ant-tasks-2.1.1.jar" dest="build/maven-ant-tasks.jar"/>
|
||||
|
||||
<input
|
||||
message="Which provider would you like to use (ec2, cloudservers, vcloud, terremark, rimuhosting)?"
|
||||
validargs="ec2,cloudservers,vcloud,trmk-ecloud,trmk-vcloudexpress,eucalyptus,bluelock-vcdirector,gogrid,rimuhosting"
|
||||
message="Which provider would you like to use (aws-ec2, bluelock-vcdirector, cloudservers-uk, cloudservers-us, cloudsigma-zrh, eucalyptus-partnercloud-ec2, elastichosts-lon-b, elastichosts-lon-p, elastichosts-sat-p, gogrid, openhosting-east1, serverlove-z1-man, skalicloud-sdg-my, slicehost, trmk-ecloud, trmk-vcloudexpress)?"
|
||||
validargs="aws-ec2,bluelock-vcdirector,cloudservers-uk,cloudservers-us,cloudsigma-zrh,eucalyptus-partnercloud-ec2,elastichosts-lon-b,elastichosts-lon-p,elastichosts-sat-p,gogrid,openhosting-east1,serverlove-z1-man,skalicloud-sdg-my,slicehost,trmk-ecloud,trmk-vcloudexpress"
|
||||
addproperty="provider"
|
||||
/>
|
||||
|
||||
<input
|
||||
message="Which driver does ${provider} use?"
|
||||
validargs="aws,rackspace,vcloud,bluelock,gogrid,terremark,ibmdev,rimuhosting"
|
||||
addproperty="driver"
|
||||
/>
|
||||
|
||||
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks.jar" />
|
||||
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
|
||||
|
||||
<artifact:localRepository id="local.repository" path="${user.home}/.m2/repository" />
|
||||
<artifact:remoteRepository id="jclouds.repository" url="http://repo1.maven.org/maven2" />
|
||||
<artifact:remoteRepository id="jclouds-snapshot.repository" url="https://oss.sonatype.org/content/repositories/snapshots" />
|
||||
|
||||
<artifact:dependencies pathId="jclouds.classpath">
|
||||
<dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="${jclouds.version}" />
|
||||
<dependency groupId="org.jclouds" artifactId="jclouds-${driver}" version="${jclouds.version}" />
|
||||
<dependency groupId="org.jclouds.provider" artifactId="${provider}" version="${jclouds.version}" />
|
||||
<localRepository refid="local.repository" />
|
||||
<remoteRepository refid="jclouds.repository" />
|
||||
<remoteRepository refid="jclouds-snapshot.repository" />
|
||||
</artifact:dependencies>
|
||||
|
||||
|
@ -94,9 +86,9 @@
|
|||
<compute actions="list-locations,list-sizes,list-images,list-details" provider="${jclouds.compute.url}" />
|
||||
</target>
|
||||
|
||||
<target name="reboot" depends="reboot-id,reboot-tag" />
|
||||
<target name="reboot" depends="reboot-id,reboot-group" />
|
||||
|
||||
<target name="reboot-id" description="reboot the node ${id}" unless="tag">
|
||||
<target name="reboot-id" description="reboot the node ${id}" unless="group">
|
||||
|
||||
<input
|
||||
message="Which node do you wish to reboot"
|
||||
|
@ -108,21 +100,21 @@
|
|||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="reboot-tag" description="reboot the nodes with tag ${tag}" unless="id" >
|
||||
<target name="reboot-group" description="reboot the nodes with group ${group}" unless="id" >
|
||||
|
||||
<input
|
||||
message="Which tag do you wish to reboot"
|
||||
addproperty="tag"
|
||||
message="Which group do you wish to reboot"
|
||||
addproperty="group"
|
||||
/>
|
||||
|
||||
<compute actions="reboot" provider="${jclouds.compute.url}">
|
||||
<nodes tag="${tag}" />
|
||||
<nodes group="${group}" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="destroy" depends="destroy-id,destroy-tag" />
|
||||
<target name="destroy" depends="destroy-id,destroy-group" />
|
||||
|
||||
<target name="destroy-id" description="destroy the node ${id}" unless="tag">
|
||||
<target name="destroy-id" description="destroy the node ${id}" unless="group">
|
||||
|
||||
<input
|
||||
message="Which node do you wish to destroy"
|
||||
|
@ -134,21 +126,21 @@
|
|||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="destroy-tag" description="destroy the nodes with tag ${tag}" unless="id" >
|
||||
<target name="destroy-group" description="destroy the nodes with group ${group}" unless="id" >
|
||||
|
||||
<input
|
||||
message="Which tag do you wish to destroy"
|
||||
addproperty="tag"
|
||||
message="Which group do you wish to destroy"
|
||||
addproperty="group"
|
||||
/>
|
||||
|
||||
<compute actions="destroy" provider="${jclouds.compute.url}">
|
||||
<nodes tag="${tag}" />
|
||||
<nodes group="${group}" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="get" depends="get-tag,get-id" />
|
||||
<target name="get" depends="get-group,get-id" />
|
||||
|
||||
<target name="get-id" description="get the node ${id}" unless="tag">
|
||||
<target name="get-id" description="get the node ${id}" unless="group">
|
||||
|
||||
<input
|
||||
message="Which node do you wish to get"
|
||||
|
@ -160,32 +152,32 @@
|
|||
</compute>
|
||||
</target>
|
||||
|
||||
<target name="get-tag" description="get the nodes with tag ${tag}" unless="id" >
|
||||
<target name="get-group" description="get the nodes with group ${group}" unless="id" >
|
||||
|
||||
<input
|
||||
message="Which tag do you wish to get"
|
||||
addproperty="tag"
|
||||
message="Which group do you wish to get"
|
||||
addproperty="group"
|
||||
/>
|
||||
|
||||
<compute actions="get" provider="${jclouds.compute.url}">
|
||||
<nodes tag="${tag}" />
|
||||
<nodes group="${group}" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
<property name="location" value="" />
|
||||
<target name="create" description="create the node ${tag}">
|
||||
<target name="create" description="create the node ${group}">
|
||||
<property name="privatekeyfile" value="${user.home}/.ssh/id_rsa" />
|
||||
<property name="publickeyfile" value="${user.home}/.ssh/id_rsa.pub" />
|
||||
<property name="os" value="UBUNTU" />
|
||||
<property name="count" value="1" />
|
||||
|
||||
<input
|
||||
message="What do you want to tag your nodes with?"
|
||||
addproperty="tag"
|
||||
message="What do you want to group your nodes with?"
|
||||
addproperty="group"
|
||||
/>
|
||||
|
||||
<compute actions="create" provider="${jclouds.compute.url}">
|
||||
<nodes privatekeyfile="${privatekeyfile}" publickeyfile="${publickeyfile}" tag="${tag}" count="${count}" os="${os}" hardware="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
<nodes privatekeyfile="${privatekeyfile}" publickeyfile="${publickeyfile}" group="${group}" count="${count}" os="${os}" hardware="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
|
|
|
@ -189,19 +189,19 @@ public class ComputeTask extends Task {
|
|||
private void list(ComputeService computeService) {
|
||||
log("list");
|
||||
for (ComputeMetadata node : computeService.listNodes()) {
|
||||
log(String.format(" location=%s, id=%s, tag=%s", node.getLocation(), node.getProviderId(), node.getName()));
|
||||
log(String.format(" location=%s, id=%s, group=%s", node.getLocation(), node.getProviderId(), node.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void create(ComputeService computeService) throws RunNodesException, IOException {
|
||||
String tag = nodeElement.getTag();
|
||||
String group = nodeElement.getGroup();
|
||||
|
||||
log(String.format("create tag: %s, count: %d, hardware: %s, os: %s", tag, nodeElement.getCount(), nodeElement
|
||||
log(String.format("create group: %s, count: %d, hardware: %s, os: %s", group, nodeElement.getCount(), nodeElement
|
||||
.getHardware(), nodeElement.getOs()));
|
||||
|
||||
Template template = createTemplateFromElement(nodeElement, computeService);
|
||||
|
||||
for (NodeMetadata createdNode : computeService.runNodesWithTag(tag, nodeElement.getCount(), template)) {
|
||||
for (NodeMetadata createdNode : computeService.createNodesInGroup(group, nodeElement.getCount(), template)) {
|
||||
logDetails(computeService, createdNode);
|
||||
addNodeDetailsAsProjectProperties(createdNode);
|
||||
}
|
||||
|
@ -223,8 +223,8 @@ public class ComputeTask extends Task {
|
|||
log(String.format("reboot id: %s", nodeElement.getId()));
|
||||
computeService.rebootNode(nodeElement.getId());
|
||||
} else {
|
||||
log(String.format("reboot tag: %s", nodeElement.getTag()));
|
||||
computeService.rebootNodesMatching(NodePredicates.withTag(nodeElement.getTag()));
|
||||
log(String.format("reboot group: %s", nodeElement.getGroup()));
|
||||
computeService.rebootNodesMatching(NodePredicates.inGroup(nodeElement.getGroup()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,8 +233,8 @@ public class ComputeTask extends Task {
|
|||
log(String.format("destroy id: %s", nodeElement.getId()));
|
||||
computeService.destroyNode(nodeElement.getId());
|
||||
} else {
|
||||
log(String.format("destroy tag: %s", nodeElement.getTag()));
|
||||
computeService.destroyNodesMatching(NodePredicates.withTag(nodeElement.getTag()));
|
||||
log(String.format("destroy group: %s", nodeElement.getGroup()));
|
||||
computeService.destroyNodesMatching(NodePredicates.inGroup(nodeElement.getGroup()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,9 +243,9 @@ public class ComputeTask extends Task {
|
|||
log(String.format("get id: %s", nodeElement.getId()));
|
||||
logDetails(computeService, computeService.getNodeMetadata(nodeElement.getId()));
|
||||
} else {
|
||||
log(String.format("get tag: %s", nodeElement.getTag()));
|
||||
log(String.format("get group: %s", nodeElement.getGroup()));
|
||||
for (ComputeMetadata node : Iterables.filter(computeService.listNodesDetailsMatching(NodePredicates.all()),
|
||||
NodePredicates.withTag(nodeElement.getTag()))) {
|
||||
NodePredicates.inGroup(nodeElement.getGroup()))) {
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
}
|
||||
|
@ -254,8 +254,8 @@ public class ComputeTask extends Task {
|
|||
private void logDetails(ComputeService computeService, ComputeMetadata node) {
|
||||
NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) : computeService
|
||||
.getNodeMetadata(node.getId());
|
||||
log(String.format(" node id=%s, name=%s, tag=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s",
|
||||
metadata.getProviderId(), metadata.getName(), metadata.getTag(), metadata.getLocation(), metadata
|
||||
log(String.format(" node id=%s, name=%s, group=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s",
|
||||
metadata.getProviderId(), metadata.getName(), metadata.getGroup(), metadata.getLocation(), metadata
|
||||
.getState(), ComputeTaskUtils.ipOrEmptyString(metadata.getPublicAddresses()),
|
||||
ipOrEmptyString(metadata.getPrivateAddresses()), metadata.getHardware()));
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.io.File;
|
|||
*/
|
||||
public class NodeElement {
|
||||
private String id;
|
||||
private String tag;
|
||||
private String group;
|
||||
private String hardware;
|
||||
private String os;
|
||||
private String image;
|
||||
|
@ -147,12 +147,12 @@ public class NodeElement {
|
|||
return count;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setPrivatekeyfile(File privatekeyfile) {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
====
|
||||
|
||||
#
|
||||
# The jclouds provider for EMC's Atmos Online Storage (http://www.emccis.com/).
|
||||
# The jclouds API for EMC's Atmos Online Storage (http://www.emccis.com/).
|
||||
#
|
||||
# TODO: Implementation status.
|
||||
# TODO: Supported features.
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<version>1.2.16</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
|
||||
package org.jclouds.atmos.blobstore.config;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.atmos.AtmosAsyncClient;
|
||||
import org.jclouds.atmos.AtmosClient;
|
||||
import org.jclouds.atmos.blobstore.AtmosAsyncBlobStore;
|
||||
|
@ -37,17 +33,9 @@ import org.jclouds.blobstore.attr.ConsistencyModel;
|
|||
import org.jclouds.blobstore.config.BlobStoreMapModule;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.config.JustProviderLocationModule;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
|
@ -64,24 +52,10 @@ public class AtmosBlobStoreContextModule extends AbstractModule {
|
|||
bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL);
|
||||
bind(AsyncBlobStore.class).to(AtmosAsyncBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStore.class).to(AtmosBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStoreContext.class).to(
|
||||
new TypeLiteral<BlobStoreContextImpl<AtmosClient, AtmosAsyncClient>>() {
|
||||
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<AtmosClient, AtmosAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(ContainsValueInListStrategy.class).to(FindMD5InUserMetadata.class);
|
||||
bind(BlobRequestSigner.class).to(AtmosBlobRequestSigner.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
Supplier<Set<? extends Location>> provideLocations(Supplier<Location> defaultLocation) {
|
||||
return Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.of(defaultLocation.get()));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Supplier<Location> provideDefaultLocation(@Provider String providerName) {
|
||||
return Suppliers
|
||||
.<Location> ofInstance(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null));
|
||||
install(new JustProviderLocationModule());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
@Singleton
|
||||
public class ObjectToBlob implements Function<AtmosObject, Blob> {
|
||||
private final Blob.Factory blobFactory;
|
||||
private final Factory blobFactory;
|
||||
private final ObjectToBlobMetadata object2BlobMd;
|
||||
|
||||
@Inject
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
= Bring Your Own Nodes to the jclouds ComputeService =
|
||||
The bring your own node provider (byon) allows you to specify a source which jclouds will read
|
||||
nodes from. Using this, you can have jclouds control your standalone machines, or even cloud
|
||||
hosts that are sitting idle.
|
||||
|
||||
== Constraints ==
|
||||
The byon provider only supports the following functions of ComputeService:
|
||||
* listNodes
|
||||
* listNodesDetailsMatching
|
||||
* getNodeMetadata
|
||||
* runScriptOnNodesMatching
|
||||
|
||||
== How to use the byon provider ==
|
||||
The byon provider requires you supply a list of nodes using a property. Here are
|
||||
the valid properties you can use:
|
||||
* byon.endpoint - url to access the list, can be http://, file://, classpath://
|
||||
* byon.nodes - inline defined yaml in string form.
|
||||
|
||||
Note:
|
||||
|
||||
The identity and credential fields of the ComputeServiceContextFactory are ignored.
|
||||
|
||||
=== Java example ===
|
||||
|
||||
Properties props = new Properties();
|
||||
|
||||
// if you built the yaml string by hand
|
||||
props.setProperty("byon.nodes", stringLiteral);
|
||||
|
||||
// or you can specify an external reference
|
||||
props.setProperty("byon.endpoint", "file://path/to/byon.yaml");
|
||||
|
||||
// or you can specify a file in your classpath
|
||||
props.setProperty("byon.endpoint", "classpath:///byon.yaml");
|
||||
|
||||
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar",
|
||||
ImmutableSet.<Module> of(new JschSshClientModule()), props);
|
||||
|
||||
== File format ==
|
||||
You must define your nodes in yaml, and they must be in a collection called nodes.
|
||||
|
||||
Here are the properties:
|
||||
|
||||
* id - opaque unique id
|
||||
* name - optional; user specified name
|
||||
* description - optional; long description of this node
|
||||
* note this is not yet in jclouds NodeMetadata
|
||||
* hostname - name or ip address to contact the node on
|
||||
* os_arch - ex. x86
|
||||
* os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format
|
||||
ex. rhel, ubuntu, centos, debian, amzn-linux
|
||||
* os_description - long description of the os ex. Ubuntu with lamp stack
|
||||
* os_version - normalized to numbers when possible. ex. for centos: 5.3, ubuntu: 10.10
|
||||
* group - primary group of the machine. ex. hadoop
|
||||
* tags - optional; list of arbitrary tags.
|
||||
* note this list is not yet in jclouds NodeMetadata
|
||||
* username - primary login user. ex. ubuntu, vcloud, toor, root
|
||||
* sudo_password - optional; when a script is run with the "runAsRoot" option true, yet the
|
||||
username is not root, a sudo command is invoked. If sudo_password
|
||||
is set, the contents will be passed to sudo -S.
|
||||
Ex. echo 'foobar'| sudo -S init 5
|
||||
|
||||
one of:
|
||||
|
||||
* credential - RSA private key or password
|
||||
* credential_url - location of plain-text RSA private key or password.
|
||||
ex. file:///home/me/.ssh/id_rsa
|
||||
classpath:///id_rsa
|
||||
|
||||
Note that username and credentials are optional if a CredentialStoreModule is configured in
|
||||
jclouds.
|
||||
|
||||
=== Example File ===
|
||||
|
||||
nodes:
|
||||
- id: i-sdfkjh7
|
||||
name: cluster-1
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-1.mydomain.com
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat with CDH
|
||||
os_version: 5.3
|
||||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2
|
||||
u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ
|
||||
lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o
|
||||
-----END RSA PRIVATE KEY-----
|
||||
sudo_password: go panthers!
|
|
@ -58,7 +58,7 @@
|
|||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<version>1.2.16</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -73,6 +73,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>0.1.44</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.jclouds.byon;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -35,48 +36,57 @@ public class Node {
|
|||
public Node() {
|
||||
}
|
||||
|
||||
public Node(String id, String description, String hostname, String osArch, String osFamily, String osName,
|
||||
String osVersion, String group, List<String> tags, String username, String credential, String sudo_password) {
|
||||
public Node(String id, String name, String description, String hostname, String osArch, String osFamily,
|
||||
String osDescription, String osVersion, String group, List<String> tags, String username,
|
||||
String credential, URI credentialUrl, String sudo_password) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.hostname = hostname;
|
||||
this.os_arch = osArch;
|
||||
this.os_family = osFamily;
|
||||
this.os_name = osName;
|
||||
this.os_description = osDescription;
|
||||
this.os_version = osVersion;
|
||||
this.group = group;
|
||||
this.tags = ImmutableList.copyOf(tags);
|
||||
this.username = username;
|
||||
this.credential = credential;
|
||||
this.credential_url = credentialUrl != null ? credentialUrl.toASCIIString() : null;
|
||||
this.sudo_password = sudo_password;
|
||||
}
|
||||
|
||||
// public due to snakeyaml
|
||||
public String id;
|
||||
public String name;
|
||||
public String description;
|
||||
public String hostname;
|
||||
public String os_arch;
|
||||
public String os_family;
|
||||
public String os_name;
|
||||
public String os_description;
|
||||
public String os_version;
|
||||
public String group;
|
||||
public List<String> tags;
|
||||
public String username;
|
||||
public String credential;
|
||||
public String credential_url;
|
||||
public String sudo_password;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
@ -89,8 +99,8 @@ public class Node {
|
|||
return os_family;
|
||||
}
|
||||
|
||||
public String getOsName() {
|
||||
return os_name;
|
||||
public String getOsDescription() {
|
||||
return os_description;
|
||||
}
|
||||
|
||||
public String getOsVersion() {
|
||||
|
@ -112,6 +122,10 @@ public class Node {
|
|||
return credential;
|
||||
}
|
||||
|
||||
public URI getCredentialUrl() {
|
||||
return credential_url != null ? URI.create(credential_url) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
|
@ -130,10 +144,11 @@ public class Node {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).add("id", id).add("description", description).add("hostname", hostname).add(
|
||||
"osArch", os_arch).add("osFamily", os_family).add("osName", os_name).add("osVersion", os_version).add(
|
||||
"group", group).add("tags", tags).add("username", username).add("hasCredential", credential != null)
|
||||
.add("hasSudoPassword", sudo_password != null).toString();
|
||||
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add(
|
||||
"hostname", hostname).add("osArch", os_arch).add("osFamily", os_family).add("osDescription",
|
||||
os_description).add("osVersion", os_version).add("group", group).add("tags", tags).add("username",
|
||||
username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword",
|
||||
sudo_password != null).toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package org.jclouds.byon.config;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
@ -31,7 +32,9 @@ import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
|
|||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
||||
import org.jclouds.concurrent.SingleThreaded;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -61,10 +64,14 @@ public class BYONComputeServiceContextModule extends
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<Supplier<Location>>() {
|
||||
}).to(OnlyLocationOrFirstZone.class);
|
||||
bind(new TypeLiteral<Supplier<Map<String, Node>>>() {
|
||||
}).to(NodesParsedFromSupplier.class);
|
||||
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||
// TODO make this somehow overridable via user request
|
||||
bind(new TypeLiteral<Function<InputStream, Map<String, Node>>>() {
|
||||
}).to(NodesFromYaml.class);
|
|
@ -21,8 +21,12 @@ package org.jclouds.byon.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -32,11 +36,11 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -46,35 +50,54 @@ import com.google.common.collect.ImmutableSet;
|
|||
*/
|
||||
@Singleton
|
||||
public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<Location> location;
|
||||
private final Map<String, Credentials> credentialStore;
|
||||
private final Function<URI, InputStream> slurp;
|
||||
|
||||
@Inject
|
||||
NodeToNodeMetadata(Supplier<Location> location, Map<String, Credentials> credentialStore) {
|
||||
NodeToNodeMetadata(Supplier<Location> location, Function<URI, InputStream> slurp,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
this.location = checkNotNull(location, "location");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
this.slurp = checkNotNull(slurp, "slurp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(Node from) {
|
||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
builder.ids(from.getId());
|
||||
builder.name(from.getDescription());
|
||||
builder.name(from.getName());
|
||||
builder.location(location.get());
|
||||
builder.tag(from.getGroup());
|
||||
builder.group(from.getGroup());
|
||||
// TODO add tags!
|
||||
builder.operatingSystem(new OperatingSystemBuilder().arch(from.getOsArch()).family(
|
||||
OsFamily.fromValue(from.getOsFamily())).name(from.getOsName()).version(from.getOsVersion()).description(
|
||||
from.getDescription()).build());
|
||||
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
|
||||
.version(from.getOsVersion()).build());
|
||||
builder.state(NodeState.RUNNING);
|
||||
builder.publicAddresses(ImmutableSet.<String> of(from.getHostname()));
|
||||
Credentials creds = new Credentials(from.getUsername(), new String(CryptoStreams.base64(from.getCredential()),
|
||||
Charsets.UTF_8));
|
||||
|
||||
if (from.getUsername() != null) {
|
||||
Credentials creds = null;
|
||||
if (from.getCredentialUrl() != null) {
|
||||
try {
|
||||
creds = new Credentials(from.getUsername(), Strings2.toStringAndClose(slurp.apply(from
|
||||
.getCredentialUrl())));
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "URI could not be read: %s", from.getCredentialUrl());
|
||||
}
|
||||
} else if (from.getCredential() != null) {
|
||||
creds = new Credentials(from.getUsername(), from.getCredential());
|
||||
}
|
||||
if (creds != null)
|
||||
builder.credentials(creds);
|
||||
if (from.getSudoPassword() != null)
|
||||
builder.adminPassword(new String(CryptoStreams.base64(from.getSudoPassword()), Charsets.UTF_8));
|
||||
credentialStore.put("node#" + from.getId(), creds);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
if (from.getSudoPassword() != null)
|
||||
builder.adminPassword(from.getSudoPassword());
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ package org.jclouds.byon.functions;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
@ -33,26 +34,29 @@ import org.yaml.snakeyaml.Yaml;
|
|||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Parses the following syntax.
|
||||
*
|
||||
* <pre>
|
||||
* nodes:
|
||||
* cluster-1:
|
||||
* id: cluster-1
|
||||
* - id: cluster-1:
|
||||
* name: cluster-1
|
||||
* description: xyz
|
||||
* hostname: cluster-1.mydomain.com
|
||||
* os_arch: x86
|
||||
* os_family: linux
|
||||
* os_name: redhat
|
||||
* os_description: redhat
|
||||
* os_version: 5.3
|
||||
* group: hadoop
|
||||
* tags:
|
||||
* - vanilla
|
||||
* username: kelvin
|
||||
* credential: password_or_rsa_in_base64
|
||||
* sudo_password: password_in_base64
|
||||
* credential: password_or_rsa
|
||||
* or
|
||||
* credential_url: password_or_rsa_file ex. resource:///id_rsa will get the classpath /id_rsa; file://path/to/id_rsa
|
||||
* sudo_password: password
|
||||
* </pre>
|
||||
*
|
||||
* @author Kelvin Kakugawa
|
||||
|
@ -65,7 +69,7 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
|||
*
|
||||
*/
|
||||
public static class Config {
|
||||
public Map<String, Node> nodes;
|
||||
public List<Node> nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,12 +81,18 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
|||
constructor.addTypeDescription(nodeDesc);
|
||||
|
||||
TypeDescription configDesc = new TypeDescription(Config.class);
|
||||
configDesc.putMapPropertyType("nodes", String.class, Node.class);
|
||||
configDesc.putListPropertyType("nodes", Node.class);
|
||||
constructor.addTypeDescription(configDesc);
|
||||
|
||||
Yaml yaml = new Yaml(new Loader(constructor));
|
||||
Config config = (Config) yaml.load(source);
|
||||
checkState(config != null, "missing nodes: collection");
|
||||
return config.nodes;
|
||||
checkState(config != null, "missing config: class");
|
||||
checkState(config.nodes != null, "missing nodes: collection");
|
||||
|
||||
return Maps.uniqueIndex(config.nodes, new Function<Node, String>() {
|
||||
public String apply(Node node) {
|
||||
return node.getId();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -35,8 +35,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.location.suppliers.JustProvider;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -50,18 +49,18 @@ import com.google.common.collect.Iterables;
|
|||
public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
|
||||
private final Supplier<Map<String, Node>> nodes;
|
||||
private final NodeToNodeMetadata converter;
|
||||
private final String providerName;
|
||||
private final JustProvider locationSupplier;
|
||||
|
||||
@Inject
|
||||
public BYONComputeServiceAdapter(Supplier<Map<String, Node>> nodes, NodeToNodeMetadata converter,
|
||||
@org.jclouds.location.Provider String providerName) {
|
||||
JustProvider locationSupplier) {
|
||||
this.nodes = checkNotNull(nodes, "nodes");
|
||||
this.converter = checkNotNull(converter, "converter");
|
||||
this.providerName = checkNotNull(providerName, "providerName");
|
||||
this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template,
|
||||
Map<String, Credentials> credentialStore) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
@ -81,9 +80,10 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
return Iterables.transform(nodes.get().values(), converter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<Location> listLocations() {
|
||||
return ImmutableSet.<Location> of(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null));
|
||||
return (Iterable<Location>) locationSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
|
@ -32,6 +32,7 @@ import org.jclouds.logging.Logger;
|
|||
import org.jclouds.util.Strings2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Inject;
|
||||
|
@ -40,7 +41,7 @@ import com.google.inject.name.Named;
|
|||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SupplyFromProviderURIOrNodesProperty implements Supplier<InputStream> {
|
||||
public class SupplyFromProviderURIOrNodesProperty implements Supplier<InputStream>, Function<URI, InputStream> {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final URI url;
|
||||
|
@ -51,7 +52,7 @@ public class SupplyFromProviderURIOrNodesProperty implements Supplier<InputStrea
|
|||
String nodes;
|
||||
|
||||
@Inject
|
||||
SupplyFromProviderURIOrNodesProperty(@Provider URI url) {
|
||||
public SupplyFromProviderURIOrNodesProperty(@Provider URI url) {
|
||||
this.url = checkNotNull(url, "url");
|
||||
}
|
||||
|
||||
|
@ -59,13 +60,7 @@ public class SupplyFromProviderURIOrNodesProperty implements Supplier<InputStrea
|
|||
public InputStream get() {
|
||||
if (nodes != null)
|
||||
return Strings2.toInputStream(nodes);
|
||||
try {
|
||||
return url.toURL().openStream();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "URI could not be read: %s", url);
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
}
|
||||
return apply(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,4 +68,17 @@ public class SupplyFromProviderURIOrNodesProperty implements Supplier<InputStrea
|
|||
return "[url=" + url + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream apply(URI input) {
|
||||
try {
|
||||
if (input.getScheme() != null && input.getScheme().equals("classpath"))
|
||||
return getClass().getResourceAsStream(input.getPath());
|
||||
return input.toURL().openStream();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "URI could not be read: %s", url);
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.byon;
|
||||
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.jclouds.crypto.CryptoStreams.base64;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -31,7 +30,6 @@ import java.util.Map.Entry;
|
|||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.ComputeTestUtils;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
@ -60,19 +58,18 @@ public class BYONComputeServiceLiveTest {
|
|||
|
||||
StringBuilder nodes = new StringBuilder();
|
||||
nodes.append("nodes:\n");
|
||||
nodes.append(" mymachine:\n");
|
||||
nodes.append(" id: mymachine\n");
|
||||
nodes.append(" description: my local machine\n");
|
||||
nodes.append(" - id: mymachine\n");
|
||||
nodes.append(" name: my local machine\n");
|
||||
nodes.append(" hostname: localhost\n");
|
||||
nodes.append(" os_arch: ").append(System.getProperty("os.arch")).append("\n");
|
||||
nodes.append(" os_family: ").append(OsFamily.UNIX).append("\n");
|
||||
nodes.append(" os_name: ").append(System.getProperty("os.name")).append("\n");
|
||||
nodes.append(" os_description: ").append(System.getProperty("os.name")).append("\n");
|
||||
nodes.append(" os_version: ").append(System.getProperty("os.version")).append("\n");
|
||||
nodes.append(" group: ").append("ssh").append("\n");
|
||||
nodes.append(" tags:\n");
|
||||
nodes.append(" - local\n");
|
||||
nodes.append(" username: ").append(System.getProperty("user.name")).append("\n");
|
||||
nodes.append(" credential: ").append(base64(ComputeTestUtils.setupKeyPair().get("private").getBytes()))
|
||||
nodes.append(" credential_url: file://").append(System.getProperty("user.home")).append("/.ssh/id_rsa")
|
||||
.append("\n");
|
||||
|
||||
contextProperties.setProperty("byon.nodes", nodes.toString());
|
|
@ -45,10 +45,18 @@ import com.google.inject.Module;
|
|||
public class BYONComputeServiceTest {
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
public void testNodesParseWithFileUrl() throws Exception {
|
||||
assertNodesParse("file://" + getClass().getResource("/test1.yaml").getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParseWithClasspathUrl() throws Exception {
|
||||
assertNodesParse("classpath:///test1.yaml");
|
||||
}
|
||||
|
||||
private void assertNodesParse(String endpoint) {
|
||||
ComputeServiceContext context = null;
|
||||
try {
|
||||
String endpoint = "file://" + getClass().getResource("/test1.yaml").getPath();
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("byon.endpoint", endpoint);
|
||||
|
@ -65,12 +73,12 @@ public class BYONComputeServiceTest {
|
|||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.id,
|
||||
NodesFromYamlTest.TEST1));
|
||||
|
||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest.TEST1));
|
||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest
|
||||
.expectedNodeMetadataFromResource(endpoint)));
|
||||
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,10 @@ package org.jclouds.byon.functions;
|
|||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -30,8 +32,8 @@ import org.jclouds.compute.domain.OperatingSystemBuilder;
|
|||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
|
@ -44,23 +46,31 @@ import com.google.common.collect.Maps;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class NodeToNodeMetadataTest {
|
||||
public static final Location location = new LocationImpl(LocationScope.PROVIDER, "byon", "byon", null);
|
||||
public static Location expectedLocationFromResource(String resource) {
|
||||
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
||||
}
|
||||
|
||||
public static final NodeMetadata TEST1 = new NodeMetadataBuilder().ids("cluster-1").tag("hadoop").name("xyz").location(
|
||||
location).state(NodeState.RUNNING).operatingSystem(
|
||||
new OperatingSystemBuilder().name("redhat").family(OsFamily.RHEL).arch("x86").version("5.3").description(
|
||||
"xyz").build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials(
|
||||
new Credentials("myUser", "fancyfoot")).adminPassword("sudo").build();
|
||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
||||
Location location = expectedLocationFromResource(resource);
|
||||
|
||||
return new NodeMetadataBuilder().ids("cluster-1").group("hadoop").name("cluster-1").location(location).state(
|
||||
NodeState.RUNNING).operatingSystem(
|
||||
new OperatingSystemBuilder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3")
|
||||
.build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials(
|
||||
new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
|
||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||
|
||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(location), credentialStore);
|
||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(
|
||||
Suppliers.ofInstance(expectedLocationFromResource("location")),
|
||||
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
||||
|
||||
assertEquals(parser.apply(NodesFromYamlTest.TEST1), TEST1);
|
||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", "fancyfoot")));
|
||||
assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource("location"));
|
||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -36,10 +35,15 @@ import com.google.common.collect.ImmutableMap;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class NodesFromYamlTest {
|
||||
public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n").append(
|
||||
"MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n").append(
|
||||
"u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n").append(
|
||||
"lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n")
|
||||
.toString();
|
||||
|
||||
public static final Node TEST1 = new Node("cluster-1", "xyz", "cluster-1.mydomain.com", "x86", "rhel", "redhat",
|
||||
"5.3", "hadoop", ImmutableList.of("vanilla"), "myUser", CryptoStreams.base64("fancyfoot".getBytes()),
|
||||
CryptoStreams.base64("sudo".getBytes()));
|
||||
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||
"cluster-1.mydomain.com", "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"), "myUser",
|
||||
key, null, "happy bear");
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
|
@ -50,6 +54,15 @@ public class NodesFromYamlTest {
|
|||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodesParseWhenCredentialInUrl() throws Exception {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
|
||||
NodesFromYaml parser = new NodesFromYaml();
|
||||
|
||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testMustParseSomething() throws Exception {
|
||||
new NodesFromYaml().apply(Strings2.toInputStream(""));
|
|
@ -37,11 +37,4 @@ public class NodesParsedFromSupplierTest {
|
|||
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYaml()).get();
|
||||
|
||||
}
|
||||
|
||||
public void testCanParseSomething() throws Exception {
|
||||
|
||||
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n first:\n")),
|
||||
new NodesFromYaml()).get();
|
||||
|
||||
}
|
||||
}
|
|
@ -44,6 +44,17 @@ public class SupplyFromProviderURIOrNodesPropertyTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromURIClasspath() throws Exception {
|
||||
|
||||
SupplyFromProviderURIOrNodesProperty supplier = new SupplyFromProviderURIOrNodesProperty(URI
|
||||
.create("classpath:///test1.yaml"));
|
||||
|
||||
assertEquals(Strings2.toStringAndClose(supplier.get()), Strings2.toStringAndClose(getClass().getResourceAsStream(
|
||||
"/test1.yaml")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromProperty() throws Exception {
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
nodes:
|
||||
- id: cluster-1
|
||||
name: cluster-1
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-1.mydomain.com
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat
|
||||
os_version: 5.3
|
||||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2
|
||||
u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ
|
||||
lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o
|
||||
-----END RSA PRIVATE KEY-----
|
||||
sudo_password: happy bear
|
|
@ -0,0 +1,15 @@
|
|||
nodes:
|
||||
- id: cluster-1
|
||||
name: cluster-1
|
||||
description: accounting analytics cluster
|
||||
hostname: cluster-1.mydomain.com
|
||||
os_arch: x86
|
||||
os_family: rhel
|
||||
os_description: redhat
|
||||
os_version: 5.3
|
||||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
username: myUser
|
||||
credential_url: classpath:///testkey.txt
|
||||
sudo_password: happy bear
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2
|
||||
u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ
|
||||
lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -18,8 +18,8 @@
|
|||
====
|
||||
|
||||
#
|
||||
# this is a simple example command line client that creates a bucket, then displays all buckets you own
|
||||
# 1. execute 'mvn install' to build the sample
|
||||
# 2. invoke the jar, passing your aws credentials and the bucket you wish to create
|
||||
# ex.
|
||||
# java -jar target/jclouds-aws-demo-createandlistbuckets-jar-with-dependencies.jar $AWS_USER $AWS_PWD testbucketmeo
|
||||
# The jclouds API for Rackspace's Cloud Files (http://www.rackspacecloud.com/cloud_hosting_products/files/).
|
||||
#
|
||||
# TODO: Implementation status.
|
||||
# TODO: Supported features.
|
||||
# TODO: Usage example.
|
|
@ -17,13 +17,9 @@
|
|||
====================================================================
|
||||
====
|
||||
|
||||
Note that the following are prerequisites:
|
||||
1. Ant 1.7.1 is installed and in your path
|
||||
wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.7.1-bin.zip
|
||||
jar -xf apache-ant-1.7.1-bin.zip
|
||||
chmod 755 apache-ant-1.7.1/bin/*
|
||||
export PATH=apache-ant-1.7.1/bin:$PATH
|
||||
2. jsch 0.1.42 is in $ANT_HOME/lib
|
||||
cd apache-ant-1.7.1/lib
|
||||
wget https://sourceforge.net/projects/jsch/files/jsch/jsch-0.1.42.jar
|
||||
|
||||
#
|
||||
# The jclouds API for Rackspace's Cloud Server (http://www.rackspacecloud.com/cloud_hosting_products/servers/).
|
||||
#
|
||||
# TODO: Implementation status.
|
||||
# TODO: Supported features.
|
||||
# TODO: Usage example.
|
|
@ -79,6 +79,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>0.1.44</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-log4j</artifactId>
|
||||
|
|
|
@ -32,16 +32,7 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.cloudservers.binders.BindAdminPassToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindBackupScheduleToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindConfirmResizeToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindCreateImageToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindRebootTypeToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindResizeFlavorToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindRevertResizeToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindServerNameToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindSharedIpGroupToJsonPayload;
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.cloudservers.domain.BackupSchedule;
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
|
@ -53,13 +44,15 @@ import org.jclouds.cloudservers.options.CreateServerOptions;
|
|||
import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions;
|
||||
import org.jclouds.cloudservers.options.ListOptions;
|
||||
import org.jclouds.cloudservers.options.RebuildServerOptions;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.MapPayloadParam;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
|
@ -123,8 +116,9 @@ public interface CloudServersAsyncClient {
|
|||
@POST
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/servers/{id}/action")
|
||||
ListenableFuture<Void> rebootServer(@PathParam("id") int id,
|
||||
@BinderParam(BindRebootTypeToJsonPayload.class) RebootType rebootType);
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D")
|
||||
ListenableFuture<Void> rebootServer(@PathParam("id") int id, @PayloadParam("type") RebootType rebootType);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#resizeServer
|
||||
|
@ -132,8 +126,9 @@ public interface CloudServersAsyncClient {
|
|||
@POST
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/servers/{id}/action")
|
||||
ListenableFuture<Void> resizeServer(@PathParam("id") int id,
|
||||
@BinderParam(BindResizeFlavorToJsonPayload.class) int flavorId);
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D")
|
||||
ListenableFuture<Void> resizeServer(@PathParam("id") int id, @PayloadParam("flavorId") int flavorId);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#confirmResizeServer
|
||||
|
@ -142,7 +137,8 @@ public interface CloudServersAsyncClient {
|
|||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/servers/{id}/action")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
ListenableFuture<Void> confirmResizeServer(@PathParam("id") @BinderParam(BindConfirmResizeToJsonPayload.class) int id);
|
||||
@Payload("{\"confirmResize\":null}")
|
||||
ListenableFuture<Void> confirmResizeServer(@PathParam("id") int id);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#revertResizeServer
|
||||
|
@ -151,7 +147,8 @@ public interface CloudServersAsyncClient {
|
|||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/servers/{id}/action")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
ListenableFuture<Void> revertResizeServer(@PathParam("id") @BinderParam(BindRevertResizeToJsonPayload.class) int id);
|
||||
@Payload("{\"revertResize\":null}")
|
||||
ListenableFuture<Void> revertResizeServer(@PathParam("id") int id);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#createServer
|
||||
|
@ -162,8 +159,8 @@ public interface CloudServersAsyncClient {
|
|||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/servers")
|
||||
@MapBinder(CreateServerOptions.class)
|
||||
ListenableFuture<Server> createServer(@MapPayloadParam("name") String name, @MapPayloadParam("imageId") int imageId,
|
||||
@MapPayloadParam("flavorId") int flavorId, CreateServerOptions... options);
|
||||
ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageId") int imageId,
|
||||
@PayloadParam("flavorId") int flavorId, CreateServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#rebuildServer
|
||||
|
@ -179,10 +176,11 @@ public interface CloudServersAsyncClient {
|
|||
*/
|
||||
@PUT
|
||||
@Path("/servers/{id}/ips/public/{address}")
|
||||
@MapBinder(BindSharedIpGroupToJsonPayload.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"shareIp\":%7B\"sharedIpGroupId\":{sharedIpGroupId},\"configureServer\":{configureServer}%7D%7D")
|
||||
ListenableFuture<Void> shareIp(@PathParam("address") String addressToShare,
|
||||
@PathParam("id") int serverToTosignBindressTo, @MapPayloadParam("sharedIpGroupId") int sharedIpGroup,
|
||||
@MapPayloadParam("configureServer") boolean configureServer);
|
||||
@PathParam("id") int serverToTosignBindressTo, @PayloadParam("sharedIpGroupId") int sharedIpGroup,
|
||||
@PayloadParam("configureServer") boolean configureServer);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#unshareIp
|
||||
|
@ -198,16 +196,18 @@ public interface CloudServersAsyncClient {
|
|||
*/
|
||||
@PUT
|
||||
@Path("/servers/{id}")
|
||||
ListenableFuture<Void> changeAdminPass(@PathParam("id") int id,
|
||||
@BinderParam(BindAdminPassToJsonPayload.class) String adminPass);
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"server\":%7B\"adminPass\":\"{adminPass}\"%7D%7D")
|
||||
ListenableFuture<Void> changeAdminPass(@PathParam("id") int id, @PayloadParam("adminPass") String adminPass);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#renameServer
|
||||
*/
|
||||
@PUT
|
||||
@Path("/servers/{id}")
|
||||
ListenableFuture<Void> renameServer(@PathParam("id") int id,
|
||||
@BinderParam(BindServerNameToJsonPayload.class) String newName);
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D")
|
||||
ListenableFuture<Void> renameServer(@PathParam("id") int id, @PayloadParam("name") String newName);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#listFlavors
|
||||
|
@ -268,10 +268,11 @@ public interface CloudServersAsyncClient {
|
|||
@Unwrap
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@MapBinder(BindCreateImageToJsonPayload.class)
|
||||
@Path("/images")
|
||||
ListenableFuture<Image> createImageFromServer(@MapPayloadParam("imageName") String imageName,
|
||||
@MapPayloadParam("serverId") int serverId);
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"image\":%7B\"serverId\":{serverId},\"name\":\"{name}\"%7D%7D")
|
||||
ListenableFuture<Image> createImageFromServer(@PayloadParam("name") String imageName,
|
||||
@PayloadParam("serverId") int serverId);
|
||||
|
||||
/**
|
||||
* @see CloudServersClient#listSharedIpGroups
|
||||
|
@ -304,7 +305,7 @@ public interface CloudServersAsyncClient {
|
|||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/shared_ip_groups")
|
||||
@MapBinder(CreateSharedIpGroupOptions.class)
|
||||
ListenableFuture<SharedIpGroup> createSharedIpGroup(@MapPayloadParam("name") String name,
|
||||
ListenableFuture<SharedIpGroup> createSharedIpGroup(@PayloadParam("name") String name,
|
||||
CreateSharedIpGroupOptions... options);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class BindCreateImageToJsonPayload extends BindToJsonPayload {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class CreateImageRequest {
|
||||
final int serverId;
|
||||
final String name;
|
||||
|
||||
private CreateImageRequest(int serverId, String name) {
|
||||
this.serverId = serverId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||
CreateImageRequest createRequest = new CreateImageRequest(Integer
|
||||
.parseInt(checkNotNull(postParams.get("serverId"))), checkNotNull(postParams
|
||||
.get("imageName")));
|
||||
return super.bindToRequest(request, ImmutableMap.of("image", createRequest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||
throw new IllegalArgumentException("image is needs parameters");
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.cloudservers.domain.RebootType;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class BindRebootTypeToJsonPayload extends BindToJsonPayload {
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||
throw new IllegalStateException("Reboot doesn't take map parameters");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||
checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!");
|
||||
return super.bindToRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("type", checkNotNull(
|
||||
toBind, "type"))));
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class BindResizeFlavorToJsonPayload extends BindToJsonPayload {
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||
throw new IllegalStateException("Resize doesn't take map parameters");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||
checkArgument(toBind instanceof Integer, "this binder is only valid for integers!");
|
||||
return super.bindToRequest(request, ImmutableMap.of("resize", ImmutableMap.of("flavorId",
|
||||
(Integer) checkNotNull(toBind, "flavorId"))));
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class BindSharedIpGroupToJsonPayload extends BindToJsonPayload {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class ShareIpRequest {
|
||||
final int sharedIpGroupId;
|
||||
Boolean configureServer;
|
||||
|
||||
private ShareIpRequest(int sharedIpGroupId) {
|
||||
this.sharedIpGroupId = sharedIpGroupId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||
ShareIpRequest createRequest = new ShareIpRequest(Integer.parseInt(checkNotNull(postParams
|
||||
.get("sharedIpGroupId"))));
|
||||
if (Boolean.parseBoolean(checkNotNull(postParams.get("configureServer")))) {
|
||||
createRequest.configureServer = new Boolean(true);
|
||||
}
|
||||
return super.bindToRequest(request, ImmutableMap.of("shareIp", createRequest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||
throw new IllegalStateException("shareIp is needs parameters");
|
||||
}
|
||||
}
|
|
@ -20,14 +20,14 @@
|
|||
package org.jclouds.cloudservers.compute.config;
|
||||
|
||||
import org.jclouds.compute.config.BindComputeStrategiesByClass;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.cloudservers.compute.strategy.CloudServersAddNodeWithTagStrategy;
|
||||
import org.jclouds.cloudservers.compute.strategy.CloudServersCreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.cloudservers.compute.strategy.CloudServersDestroyNodeStrategy;
|
||||
import org.jclouds.cloudservers.compute.strategy.CloudServersGetNodeMetadataStrategy;
|
||||
import org.jclouds.cloudservers.compute.strategy.CloudServersListNodesStrategy;
|
||||
|
@ -41,8 +41,8 @@ import org.jclouds.cloudservers.compute.strategy.CloudServersLifeCycleStrategy;
|
|||
public class CloudServersBindComputeStrategiesByClass extends BindComputeStrategiesByClass {
|
||||
|
||||
@Override
|
||||
protected Class<? extends AddNodeWithTagStrategy> defineAddNodeWithTagStrategy() {
|
||||
return CloudServersAddNodeWithTagStrategy.class;
|
||||
protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() {
|
||||
return CloudServersCreateNodeWithGroupEncodedIntoName.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,13 +21,13 @@ package org.jclouds.cloudservers.compute.config;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.cloudservers.compute.suppliers.CloudServersHardwareSupplier;
|
||||
import org.jclouds.cloudservers.compute.suppliers.CloudServersImageSupplier;
|
||||
import org.jclouds.compute.config.BindComputeSuppliersByClass;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.cloudservers.compute.suppliers.CloudServersHardwareSupplier;
|
||||
import org.jclouds.cloudservers.compute.suppliers.CloudServersImageSupplier;
|
||||
import org.jclouds.location.suppliers.SupplyPredefinedRegions;
|
||||
import org.jclouds.location.suppliers.JustProvider;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
|
@ -49,6 +49,6 @@ public class CloudServersBindComputeSuppliersByClass extends BindComputeSupplier
|
|||
|
||||
@Override
|
||||
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
|
||||
return SupplyPredefinedRegions.class;
|
||||
return JustProvider.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.cloudservers.compute.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -41,8 +40,6 @@ import org.jclouds.compute.domain.NodeState;
|
|||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.config.ProvideRegionsViaProperties;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
|
@ -82,8 +79,6 @@ public class CloudServersComputeServiceDependenciesModule extends AbstractModule
|
|||
bind(new TypeLiteral<RestContext<CloudServersClient, CloudServersAsyncClient>>() {
|
||||
}).to(new TypeLiteral<RestContextImpl<CloudServersClient, CloudServersAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(new TypeLiteral<Set<String>>() {
|
||||
}).annotatedWith(Region.class).toProvider(ProvideRegionsViaProperties.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
package org.jclouds.cloudservers.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
@ -31,6 +31,8 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -41,11 +43,9 @@ import org.jclouds.compute.domain.OperatingSystem;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -109,9 +109,10 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
builder.ids(from.getId() + "");
|
||||
builder.name(from.getName());
|
||||
builder.location(new LocationImpl(LocationScope.HOST, from.getHostId(), from.getHostId(), location.get()));
|
||||
builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description(
|
||||
from.getHostId()).parent(location.get()).build());
|
||||
builder.userMetadata(from.getMetadata());
|
||||
builder.tag(parseTagFromName(from.getName()));
|
||||
builder.group(parseGroupFromName(from.getName()));
|
||||
builder.imageId(from.getImageId() + "");
|
||||
builder.operatingSystem(parseOperatingSystem(from));
|
||||
builder.hardware(parseHardware(from));
|
||||
|
|
|
@ -28,7 +28,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.cloudservers.CloudServersClient;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
|
@ -39,13 +39,13 @@ import com.google.common.base.Function;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||
public class CloudServersCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName {
|
||||
protected final CloudServersClient client;
|
||||
protected final Map<String, Credentials> credentialStore;
|
||||
protected final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client, Map<String, Credentials> credentialStore,
|
||||
protected CloudServersCreateNodeWithGroupEncodedIntoName(CloudServersClient client, Map<String, Credentials> credentialStore,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
|
@ -53,7 +53,7 @@ public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrateg
|
|||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata addNodeWithTag(String tag, String name, Template template) {
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
|
||||
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer
|
||||
.parseInt(template.getHardware().getProviderId()));
|
||||
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
|
|
@ -65,7 +65,7 @@ public class BackupSchedule {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BackupSchedule [daily=" + daily + ", enabled=" + enabled + ", weekly=" + weekly + "]";
|
||||
return "[daily=" + daily + ", enabled=" + enabled + ", weekly=" + weekly + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.cloudservers;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withFile;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup;
|
||||
|
@ -55,8 +54,8 @@ import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
|||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
|
@ -168,8 +167,8 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
|
|||
UnknownHostException {
|
||||
Method method = CloudServersAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
|
||||
createServerOptionsVarargsClass);
|
||||
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1, withSharedIpGroup(2).withSharedIp(
|
||||
"127.0.0.1"));
|
||||
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1,
|
||||
withSharedIpGroup(2).withSharedIp("127.0.0.1"));
|
||||
|
||||
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
||||
|
@ -439,7 +438,8 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
|
|||
|
||||
assertRequestLineEquals(request, "PUT http://serverManagementUrl/servers/2/ips/public/127.0.0.1 HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "");
|
||||
assertPayloadEquals(request, "{\"shareIp\":{\"sharedIpGroupId\":3}}", MediaType.APPLICATION_JSON, false);
|
||||
assertPayloadEquals(request, "{\"shareIp\":{\"sharedIpGroupId\":3,\"configureServer\":false}}",
|
||||
MediaType.APPLICATION_JSON, false);
|
||||
|
||||
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
|
@ -889,16 +889,17 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
|
|||
protected String provider = "cloudservers";
|
||||
|
||||
@Override
|
||||
public RestContextSpec<CloudServersClient, CloudServersAsyncClient> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec(provider, "user", "password", new Properties());
|
||||
public RestContextSpec<?, ?> createContextSpec() {
|
||||
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties getProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PROPERTY_REGIONS, "US");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://auth");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1");
|
||||
return properties;
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(PROPERTY_REGIONS, "US");
|
||||
overrides.setProperty(PROPERTY_API_VERSION, "1");
|
||||
overrides.setProperty(provider + ".endpoint", "https://auth");
|
||||
overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName());
|
||||
return overrides;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindAdminPassToJsonPayload}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BindAdminPassToJsonPayloadTest {
|
||||
|
||||
Injector injector = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testPostIsIncorrect() {
|
||||
BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, ImmutableMap.of("adminPass", "foo"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustBeString() {
|
||||
BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, new File("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrect() {
|
||||
BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, "foo");
|
||||
assertEquals("{\"server\":{\"adminPass\":\"foo\"}}", request.getPayload().getRawContent());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||
public void testNullIsBad() {
|
||||
BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, null);
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindCreateImageToJsonPayload}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BindCreateImageToJsonPayloadTest {
|
||||
|
||||
Injector injector = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustBeMap() {
|
||||
BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, new File("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrect() {
|
||||
BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, ImmutableMap.of("imageName", "foo", "serverId", "2"));
|
||||
assertEquals("{\"image\":{\"serverId\":2,\"name\":\"foo\"}}", request.getPayload()
|
||||
.getRawContent());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||
public void testNullIsBad() {
|
||||
BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, null);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.RebootType;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindRebootTypeToJsonPayload}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BindRebootTypeToJsonPayloadTest {
|
||||
|
||||
Injector injector = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testPostIsIncorrect() {
|
||||
BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, ImmutableMap.of("adminPass", "foo"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustBeRebootType() {
|
||||
BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, new File("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHard() {
|
||||
BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, RebootType.HARD);
|
||||
assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", request.getPayload().getRawContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSoft() {
|
||||
BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, RebootType.SOFT);
|
||||
assertEquals("{\"reboot\":{\"type\":\"SOFT\"}}", request.getPayload().getRawContent());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||
public void testNullIsBad() {
|
||||
BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, null);
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.binders;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindServerNameToJsonPayload}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BindServerNameToJsonPayloadTest {
|
||||
|
||||
Injector injector = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testPostIsIncorrect() {
|
||||
BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, ImmutableMap.of("name", "foo"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustBeString() {
|
||||
BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, new File("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrect() {
|
||||
BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, "foo");
|
||||
assertEquals("{\"server\":{\"name\":\"foo\"}}", request.getPayload().getRawContent());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||
public void testNullIsBad() {
|
||||
BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload();
|
||||
injector.injectMembers(binder);
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||
binder.bindToRequest(request, null);
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.cloudservers.compute;
|
||||
|
||||
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudServersTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||
|
||||
public CloudServersTemplateBuilderLiveTest() {
|
||||
provider = "cloudservers";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||
return new Predicate<OsFamilyVersion64Bit>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(OsFamilyVersion64Bit input) {
|
||||
return (input.family != OsFamily.WINDOWS && !input.is64Bit) || //
|
||||
input.family == OsFamily.RHEL || //
|
||||
(input.family == OsFamily.UBUNTU && input.version.equals("11.04")) || //
|
||||
(input.family == OsFamily.CENTOS && input.version.matches("5.[23]")) || //
|
||||
(input.family == OsFamily.WINDOWS && input.version.equals("2008")) || //
|
||||
(input.family == OsFamily.WINDOWS && input.version.equals("2008 R2") && !input.is64Bit);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -23,16 +23,16 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.cloudservers.functions.ParseFlavorFromJsonResponseTest;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.Volume;
|
||||
import org.jclouds.compute.domain.VolumeBuilder;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.cloudservers.functions.ParseFlavorFromJsonResponseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -42,20 +42,14 @@ import com.google.common.collect.ImmutableList;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class FlavorToHardwareTest {
|
||||
Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null);
|
||||
Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build();
|
||||
|
||||
@Test
|
||||
public void test() throws UnknownHostException {
|
||||
assertEquals(
|
||||
convertFlavor(),
|
||||
new HardwareBuilder()
|
||||
.ids("1")
|
||||
.name("256 MB Server")
|
||||
.processors(ImmutableList.of(new Processor(1.0, 1.0)))
|
||||
.ram(256)
|
||||
.volumes(
|
||||
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true)
|
||||
.bootDevice(true).build())).build());
|
||||
assertEquals(convertFlavor(), new HardwareBuilder().ids("1").name("256 MB Server").processors(
|
||||
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
|
||||
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true).bootDevice(true)
|
||||
.build())).build());
|
||||
}
|
||||
|
||||
public static Hardware convertFlavor() {
|
||||
|
|
|
@ -25,6 +25,10 @@ import java.net.UnknownHostException;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.cloudservers.compute.config.CloudServersComputeServiceDependenciesModule;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.cloudservers.functions.ParseServerFromJsonResponseTest;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -38,12 +42,8 @@ import org.jclouds.compute.domain.Volume;
|
|||
import org.jclouds.compute.domain.VolumeBuilder;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.cloudservers.compute.config.CloudServersComputeServiceDependenciesModule;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.cloudservers.functions.ParseServerFromJsonResponseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
|
@ -56,7 +56,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ServerToNodeMetadataTest {
|
||||
Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null);
|
||||
Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build();
|
||||
|
||||
@Test
|
||||
public void testApplyWhereImageAndHardwareNotFoundButCredentialsFound() throws UnknownHostException {
|
||||
|
@ -68,19 +68,17 @@ public class ServerToNodeMetadataTest {
|
|||
Server server = ParseServerFromJsonResponseTest.parseServer();
|
||||
|
||||
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
|
||||
.<String, Credentials> of("node#1234", creds), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers
|
||||
.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
|
||||
.<String, Credentials> of("node#1234", creds), Suppliers.<Set<? extends Image>> ofInstance(images),
|
||||
Suppliers.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
|
||||
|
||||
NodeMetadata metadata = parser.apply(server);
|
||||
|
||||
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag(
|
||||
"NOTAG#sample-server").imageId("2").id("1234").providerId("1234").name("sample-server").credentials(
|
||||
creds).location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
|
||||
.imageId("2").id("1234").providerId("1234").name("sample-server").credentials(creds).location(
|
||||
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
|
||||
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -97,12 +95,11 @@ public class ServerToNodeMetadataTest {
|
|||
NodeMetadata metadata = parser.apply(server);
|
||||
|
||||
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag(
|
||||
"NOTAG#sample-server").imageId("2").id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
|
||||
.imageId("2").id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
|
||||
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
|
||||
}
|
||||
|
||||
|
@ -121,14 +118,13 @@ public class ServerToNodeMetadataTest {
|
|||
NodeMetadata metadata = parser.apply(server);
|
||||
|
||||
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag(
|
||||
"NOTAG#sample-server").imageId("2").operatingSystem(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
|
||||
true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
|
||||
.imageId("2").operatingSystem(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2")
|
||||
.is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
|
||||
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
|
||||
}
|
||||
|
||||
|
@ -146,17 +142,16 @@ public class ServerToNodeMetadataTest {
|
|||
NodeMetadata metadata = parser.apply(server);
|
||||
|
||||
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag(
|
||||
"NOTAG#sample-server").imageId("2").hardware(
|
||||
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
|
||||
.imageId("2").hardware(
|
||||
new HardwareBuilder().ids("1").name("256 MB Server").processors(
|
||||
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
|
||||
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true)
|
||||
.bootDevice(true).build())).build()).operatingSystem(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
|
||||
true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2")
|
||||
.is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
|
||||
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
====
|
||||
|
||||
#
|
||||
# this is a simple example command line client that creates a lamp server and everything you need to do that in ec2
|
||||
# 1. execute 'mvn install' to build the sample
|
||||
# 2. invoke the jar, passing your aws credentials and the name you wish to create or destroy
|
||||
# ex.
|
||||
# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey create adrianalmighty
|
||||
# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey destroy adrianalmighty
|
||||
# The jclouds API for Amazon's EC2 service (http://aws.amazon.com/ec2/).
|
||||
#
|
||||
# TODO: Implementation status.
|
||||
# TODO: Supported features.
|
||||
# TODO: Usage example.
|
|
@ -82,6 +82,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>0.1.44</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
|
|
|
@ -25,8 +25,6 @@ import org.jclouds.ec2.services.ElasticBlockStoreAsyncClient;
|
|||
import org.jclouds.ec2.services.ElasticIPAddressAsyncClient;
|
||||
import org.jclouds.ec2.services.InstanceAsyncClient;
|
||||
import org.jclouds.ec2.services.KeyPairAsyncClient;
|
||||
import org.jclouds.ec2.services.MonitoringAsyncClient;
|
||||
import org.jclouds.ec2.services.PlacementGroupAsyncClient;
|
||||
import org.jclouds.ec2.services.SecurityGroupAsyncClient;
|
||||
import org.jclouds.ec2.services.WindowsAsyncClient;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
|
@ -69,18 +67,6 @@ public interface EC2AsyncClient {
|
|||
@Delegate
|
||||
SecurityGroupAsyncClient getSecurityGroupServices();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to PlacementGroup services.
|
||||
*/
|
||||
@Delegate
|
||||
PlacementGroupAsyncClient getPlacementGroupServices();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Monitoring services.
|
||||
*/
|
||||
@Delegate
|
||||
MonitoringAsyncClient getMonitoringServices();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Windows services.
|
||||
*/
|
||||
|
|
|
@ -21,17 +21,15 @@ package org.jclouds.ec2;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.ec2.services.AMIClient;
|
||||
import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient;
|
||||
import org.jclouds.ec2.services.ElasticBlockStoreClient;
|
||||
import org.jclouds.ec2.services.ElasticIPAddressClient;
|
||||
import org.jclouds.ec2.services.InstanceClient;
|
||||
import org.jclouds.ec2.services.KeyPairClient;
|
||||
import org.jclouds.ec2.services.MonitoringClient;
|
||||
import org.jclouds.ec2.services.PlacementGroupClient;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.ec2.services.WindowsClient;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
|
||||
/**
|
||||
|
@ -71,18 +69,6 @@ public interface EC2Client {
|
|||
@Delegate
|
||||
SecurityGroupClient getSecurityGroupServices();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to PlacementGroup services.
|
||||
*/
|
||||
@Delegate
|
||||
PlacementGroupClient getPlacementGroupServices();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Monitoring services.
|
||||
*/
|
||||
@Delegate
|
||||
MonitoringClient getMonitoringServices();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Windows services.
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ public class EC2ContextBuilder extends ComputeServiceContextBuilder<EC2Client, E
|
|||
|
||||
@Override
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new EC2RestClientModule());
|
||||
modules.add(EC2RestClientModule.create());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,11 +20,9 @@
|
|||
package org.jclouds.ec2;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -41,10 +39,8 @@ public class EC2PropertiesBuilder extends PropertiesBuilder {
|
|||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
|
||||
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION);
|
||||
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*");
|
||||
properties.setProperty(PROPERTY_EC2_CC_AMIs, "");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@ public class BindBlockDeviceMappingToIndexedFormParams implements Binder {
|
|||
private static final String volumeIdPattern = "BlockDeviceMapping.%d.Ebs.VolumeId";
|
||||
private static final String deleteOnTerminationPattern = "BlockDeviceMapping.%d.Ebs.DeleteOnTermination";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
checkArgument(checkNotNull(input, "input") instanceof Map, "this binder is only valid for Map");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, BlockDevice> blockDeviceMapping = (Map<String, BlockDevice>) input;
|
||||
|
||||
com.google.common.collect.ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package org.jclouds.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -32,7 +30,6 @@ import javax.inject.Provider;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
|
@ -49,7 +46,7 @@ import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
|||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -58,9 +55,6 @@ import org.jclouds.ec2.compute.domain.RegionAndName;
|
|||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.ec2.domain.PlacementGroup.State;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -76,14 +70,12 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
private final EC2Client ec2Client;
|
||||
private final Map<RegionAndName, KeyPair> credentialsMap;
|
||||
private final Map<RegionAndName, String> securityGroupMap;
|
||||
private final Map<RegionAndName, String> placementGroupMap;
|
||||
private final Predicate<PlacementGroup> placementGroupDeleted;
|
||||
|
||||
@Inject
|
||||
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
|
@ -92,9 +84,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
|
@ -102,57 +92,30 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
this.ec2Client = ec2Client;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
this.placementGroupMap = placementGroupMap;
|
||||
this.placementGroupDeleted = placementGroupDeleted;
|
||||
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deletePlacementGroup(String region, String tag) {
|
||||
Preconditions2.checkNotEmpty(tag, "tag");
|
||||
String group = String.format("jclouds#%s#%s", tag, region);
|
||||
void deleteSecurityGroup(String region, String group) {
|
||||
Preconditions2.checkNotEmpty(group, "group");
|
||||
String groupName = String.format("jclouds#%s#%s", group, region);
|
||||
if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupName).size() > 0) {
|
||||
logger.debug(">> deleting securityGroup(%s)", groupName);
|
||||
try {
|
||||
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) {
|
||||
logger.debug(">> deleting placementGroup(%s)", group);
|
||||
try {
|
||||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)),
|
||||
String.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||
placementGroupMap.remove(new RegionAndName(region, group));
|
||||
logger.debug("<< deleted placementGroup(%s)", group);
|
||||
} catch (AWSResponseException e) {
|
||||
if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) {
|
||||
logger.debug("<< inUse placementGroup(%s)", group);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException e) {
|
||||
} catch (HttpResponseException e) {
|
||||
// Eucalyptus does not support placement groups yet.
|
||||
if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider().equals(
|
||||
"eucalyptus")))
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deleteSecurityGroup(String region, String tag) {
|
||||
Preconditions2.checkNotEmpty(tag, "tag");
|
||||
String group = String.format("jclouds#%s#%s", tag, region);
|
||||
if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, group).size() > 0) {
|
||||
logger.debug(">> deleting securityGroup(%s)", group);
|
||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group);
|
||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName);
|
||||
// TODO: test this clear happens
|
||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, group, null, false));
|
||||
logger.debug("<< deleted securityGroup(%s)", group);
|
||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, groupName, null, false));
|
||||
logger.debug("<< deleted securityGroup(%s)", groupName);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("<< inUse securityGroup(%s)", groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deleteKeyPair(String region, String tag) {
|
||||
void deleteKeyPair(String region, String group) {
|
||||
for (KeyPair keyPair : ec2Client.getKeyPairServices().describeKeyPairsInRegion(region)) {
|
||||
if (keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", tag, region, "[0-9a-f]+"))) {
|
||||
if (keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) {
|
||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||
// TODO: test this clear happens
|
||||
|
@ -171,17 +134,20 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
|
||||
Map<String, String> regionTags = Maps.newHashMap();
|
||||
for (NodeMetadata nodeMetadata : deadOnes) {
|
||||
if (nodeMetadata.getTag() != null)
|
||||
regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getTag());
|
||||
if (nodeMetadata.getGroup() != null)
|
||||
regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup());
|
||||
}
|
||||
for (Entry<String, String> regionTag : regionTags.entrySet()) {
|
||||
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
|
||||
deleteSecurityGroup(regionTag.getKey(), regionTag.getValue());
|
||||
deletePlacementGroup(regionTag.getKey(), regionTag.getValue());
|
||||
cleanUpIncidentalResources(regionTag);
|
||||
}
|
||||
return deadOnes;
|
||||
}
|
||||
|
||||
protected void cleanUpIncidentalResources(Entry<String, String> regionTag) {
|
||||
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
|
||||
deleteSecurityGroup(regionTag.getKey(), regionTag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* returns template options, except of type {@link EC2TemplateOptions}.
|
||||
*/
|
||||
|
|
|
@ -23,16 +23,16 @@ import org.jclouds.ec2.compute.strategy.EC2DestroyNodeStrategy;
|
|||
import org.jclouds.ec2.compute.strategy.EC2GetNodeMetadataStrategy;
|
||||
import org.jclouds.ec2.compute.strategy.EC2ListNodesStrategy;
|
||||
import org.jclouds.ec2.compute.strategy.EC2RebootNodeStrategy;
|
||||
import org.jclouds.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.ec2.compute.strategy.EC2CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.ec2.compute.strategy.EC2ResumeNodeStrategy;
|
||||
import org.jclouds.ec2.compute.strategy.EC2SuspendNodeStrategy;
|
||||
import org.jclouds.compute.config.BindComputeStrategiesByClass;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
|
||||
|
@ -41,23 +41,23 @@ import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
|||
*/
|
||||
public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClass {
|
||||
@Override
|
||||
protected Class<? extends RunNodesAndAddToSetStrategy> defineRunNodesAndAddToSetStrategy() {
|
||||
return EC2RunNodesAndAddToSetStrategy.class;
|
||||
protected Class<? extends CreateNodesInGroupThenAddToSet> defineRunNodesAndAddToSetStrategy() {
|
||||
return EC2CreateNodesInGroupThenAddToSet.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* not needed, as {@link EC2RunNodesAndAddToSetStrategy} is used and is already set-based.
|
||||
* not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based.
|
||||
*/
|
||||
@Override
|
||||
protected Class<? extends AddNodeWithTagStrategy> defineAddNodeWithTagStrategy() {
|
||||
protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* not needed, as {@link EC2RunNodesAndAddToSetStrategy} is used and is already set-based.
|
||||
* not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based.
|
||||
*/
|
||||
@Override
|
||||
protected void bindAddNodeWithTagStrategy(Class<? extends AddNodeWithTagStrategy> clazz) {
|
||||
protected void bindAddNodeWithTagStrategy(Class<? extends CreateNodeWithGroupEncodedIntoName> clazz) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,12 +45,16 @@ import com.google.inject.Provides;
|
|||
public class EC2ComputeServiceContextModule extends BaseComputeServiceContextModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new EC2ComputeServiceDependenciesModule());
|
||||
installDependencies();
|
||||
install(new EC2BindComputeStrategiesByClass());
|
||||
install(new EC2BindComputeSuppliersByClass());
|
||||
super.configure();
|
||||
}
|
||||
|
||||
protected void installDependencies(){
|
||||
install(new EC2ComputeServiceDependenciesModule());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<Map<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache(
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.jclouds.ec2.compute.config;
|
|||
import static com.google.common.collect.Iterables.toArray;
|
||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Map;
|
||||
|
@ -31,25 +30,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.ec2.EC2AsyncClient;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.RegionAndIdToImage;
|
||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.InstanceState;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.predicates.InstancePresent;
|
||||
import org.jclouds.ec2.predicates.PlacementGroupAvailable;
|
||||
import org.jclouds.ec2.predicates.PlacementGroupDeleted;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -59,6 +39,21 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
|||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.EC2AsyncClient;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.RegionAndIdToImage;
|
||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.InstanceState;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.predicates.InstancePresent;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
@ -100,20 +95,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
return new RetryablePredicate<RunningInstance>(present, 5000, 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("AVAILABLE")
|
||||
protected Predicate<PlacementGroup> placementGroupAvailable(PlacementGroupAvailable available) {
|
||||
return new RetryablePredicate<PlacementGroup>(available, 60, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("DELETED")
|
||||
protected Predicate<PlacementGroup> placementGroupDeleted(PlacementGroupDeleted deleted) {
|
||||
return new RetryablePredicate<PlacementGroup>(deleted, 60, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class);
|
||||
|
@ -162,14 +143,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
return newLinkedHashMap();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("PLACEMENT")
|
||||
protected final Map<RegionAndName, String> placementGroupMap(CreatePlacementGroupIfNeeded in) {
|
||||
// doesn't seem to clear when someone issues remove(key)
|
||||
// return new MapMaker().makeComputingMap(in);
|
||||
return newLinkedHashMap();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
@ -180,14 +153,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
return toArray(Splitter.on(',').split(amiOwners), String.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named(PROPERTY_EC2_CC_AMIs)
|
||||
String[] ccAmis(@Named(PROPERTY_EC2_CC_AMIs) String ccAmis) {
|
||||
if (ccAmis.trim().equals(""))
|
||||
return new String[] {};
|
||||
return toArray(Splitter.on(',').split(ccAmis), String.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
|
|
@ -40,12 +40,11 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.ec2.compute.strategy.ReviseParsedImage;
|
||||
import org.jclouds.ec2.domain.Image.Architecture;
|
||||
import org.jclouds.ec2.domain.Image.ImageType;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -66,19 +65,16 @@ public class EC2ImageParser implements Function<org.jclouds.ec2.domain.Image, Im
|
|||
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
private final Supplier<Location> defaultLocation;
|
||||
private final String provider;
|
||||
private final Map<OsFamily, Map<String, String>> osVersionMap;
|
||||
private final ReviseParsedImage reviseParsedImage;
|
||||
|
||||
@Inject
|
||||
public
|
||||
EC2ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
||||
public EC2ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
||||
Map<OsFamily, Map<String, String>> osVersionMap, @Memoized Supplier<Set<? extends Location>> locations,
|
||||
Supplier<Location> defaultLocation, @Provider String provider, ReviseParsedImage reviseParsedImage) {
|
||||
Supplier<Location> defaultLocation, ReviseParsedImage reviseParsedImage) {
|
||||
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
|
||||
this.provider = checkNotNull(provider, "provider");
|
||||
this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap");
|
||||
this.reviseParsedImage = checkNotNull(reviseParsedImage, "reviseParsedImage");
|
||||
}
|
||||
|
@ -98,7 +94,7 @@ public class EC2ImageParser implements Function<org.jclouds.ec2.domain.Image, Im
|
|||
|
||||
OperatingSystemBuilder osBuilder = new OperatingSystemBuilder();
|
||||
osBuilder.is64Bit(from.getArchitecture() == Architecture.X86_64);
|
||||
OsFamily family = parseOsFamilyOrUnrecognized(provider, from.getImageLocation());
|
||||
OsFamily family = parseOsFamilyOrUnrecognized(from.getImageLocation());
|
||||
osBuilder.family(family);
|
||||
osBuilder.version(ComputeServiceUtils.parseVersionOrReturnEmptyString(family, from.getImageLocation(),
|
||||
osVersionMap));
|
||||
|
@ -120,8 +116,8 @@ public class EC2ImageParser implements Function<org.jclouds.ec2.domain.Image, Im
|
|||
}));
|
||||
} catch (NoSuchElementException e) {
|
||||
System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from.getId(), locations);
|
||||
builder.location(new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(), defaultLocation
|
||||
.get().getParent()));
|
||||
builder.location(new LocationBuilder().scope(LocationScope.REGION).id(from.getRegion()).description(
|
||||
from.getRegion()).parent(defaultLocation.get()).build());
|
||||
}
|
||||
builder.operatingSystem(osBuilder.build());
|
||||
return builder.build();
|
||||
|
|
|
@ -89,8 +89,8 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
String providerId = checkNotNull(instance, "instance").getId();
|
||||
builder.providerId(providerId);
|
||||
builder.id(instance.getRegion() + "/" + providerId);
|
||||
String tag = getTagForInstance(instance);
|
||||
builder.tag(tag);
|
||||
String group = getGroupForInstance(instance);
|
||||
builder.group(group);
|
||||
builder.credentials(credentialStore.get("node#" + instance.getRegion() + "/" + providerId));
|
||||
builder.state(instanceToNodeState.get(instance.getInstanceState()));
|
||||
builder.publicAddresses(NullSafeCollections.nullSafeSet(instance.getIpAddress()));
|
||||
|
@ -157,10 +157,10 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getTagForInstance(final RunningInstance instance) {
|
||||
String tag = String.format("NOTAG#%s", instance.getId());// default
|
||||
String getGroupForInstance(final RunningInstance instance) {
|
||||
String group = null;
|
||||
try {
|
||||
tag = Iterables.getOnlyElement(Iterables.filter(instance.getGroupIds(), new Predicate<String>() {
|
||||
group = Iterables.getOnlyElement(Iterables.filter(instance.getGroupIds(), new Predicate<String>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
|
@ -169,13 +169,13 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
|
||||
})).substring(8).replaceAll("#" + instance.getRegion() + "$", "");
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.debug("no tag parsed from %s's groups: %s", instance.getId(), instance.getGroupIds());
|
||||
logger.debug("no group parsed from %s's security groups: %s", instance.getId(), instance.getGroupIds());
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger
|
||||
.debug("too many groups match %s; %s's groups: %s", "jclouds#", instance.getId(), instance
|
||||
.debug("too many groups match %s; %s's security groups: %s", "jclouds#", instance.getId(), instance
|
||||
.getGroupIds());
|
||||
}
|
||||
return tag;
|
||||
return group;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -69,13 +69,10 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
|
|||
eTo.securityGroups(eFrom.getGroupIds());
|
||||
if (eFrom.getKeyPair() != null)
|
||||
eTo.keyPair(eFrom.getKeyPair());
|
||||
if (eFrom.getBlockDeviceMappings().size() > 0)
|
||||
eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings());
|
||||
if (!eFrom.shouldAutomaticallyCreateKeyPair())
|
||||
eTo.noKeyPair();
|
||||
if (eFrom.getSubnetId() != null)
|
||||
eTo.subnetId(eFrom.getSubnetId());
|
||||
eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings());
|
||||
if (eFrom.isMonitoringEnabled())
|
||||
eTo.enableMonitoring();
|
||||
if (eFrom.getUserData() != null)
|
||||
eTo.userData(eFrom.getUserData());
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -65,10 +64,6 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
private Set<String> groupIds = ImmutableSet.of();
|
||||
private String keyPair = null;
|
||||
private boolean noKeyPair;
|
||||
private boolean monitoringEnabled;
|
||||
private String placementGroup = null;
|
||||
private boolean noPlacementGroup;
|
||||
private String subnetId;
|
||||
private byte[] userData;
|
||||
private Set<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.of();
|
||||
|
||||
|
@ -93,16 +88,6 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Cloudwatch monitoring
|
||||
*
|
||||
* @see CloudWatchClient
|
||||
*/
|
||||
public EC2TemplateOptions enableMonitoring() {
|
||||
this.monitoringEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unencoded data
|
||||
*/
|
||||
|
@ -133,68 +118,38 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the keypair used to run instances with
|
||||
*/
|
||||
public EC2TemplateOptions placementGroup(String placementGroup) {
|
||||
checkNotNull(placementGroup, "use noPlacementGroup option to request boot without a keypair");
|
||||
checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup");
|
||||
Preconditions2.checkNotEmpty(placementGroup, "placementGroup must be non-empty");
|
||||
this.placementGroup = placementGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use a keypair on instances
|
||||
*/
|
||||
public EC2TemplateOptions noPlacementGroup() {
|
||||
checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup");
|
||||
this.noPlacementGroup = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the subnetId used to run instances in
|
||||
*/
|
||||
public EC2TemplateOptions subnetId(String subnetId) {
|
||||
checkNotNull(subnetId, "subnetId cannot be null");
|
||||
Preconditions2.checkNotEmpty(subnetId, "subnetId must be non-empty");
|
||||
this.subnetId = subnetId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the block device mappings to be used to run the instance
|
||||
*/
|
||||
public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
|
||||
@Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) {
|
||||
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
checkNotNull(snapshotId, "snapshotId cannot be null");
|
||||
Preconditions2.checkNotEmpty(snapshotId, "snapshotId must be non-empty");
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib,
|
||||
deleteOnTermination);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the block device mappings to be used to run the instance
|
||||
*/
|
||||
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, Integer sizeInGib,
|
||||
@Nullable Boolean deleteOnTermination) {
|
||||
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) {
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
checkNotNull(sizeInGib, "sizeInGib cannot be null");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapNewVolumeToDevice mapping = new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -207,11 +162,12 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
checkNotNull(virtualName, "virtualName cannot be null");
|
||||
Preconditions2.checkNotEmpty(virtualName, "virtualName must be non-empty");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapEphemeralDeviceToDevice mapping = new MapEphemeralDeviceToDevice(deviceName, virtualName);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -222,11 +178,12 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
UnmapDeviceNamed mapping = new UnmapDeviceNamed(deviceName);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -239,6 +196,47 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
}
|
||||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see EC2TemplateOptions#blockDeviceMappings
|
||||
*/
|
||||
public static EC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.blockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEBSSnapshotToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
|
||||
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapNewVolumeToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib,
|
||||
boolean deleteOnTermination) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#unmapDeviceNamed
|
||||
*/
|
||||
public static EC2TemplateOptions unmapDeviceNamed(String deviceName) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.unmapDeviceNamed(deviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#securityGroups(Iterable<String>)
|
||||
|
@ -280,30 +278,6 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return EC2TemplateOptions.class.cast(options.noKeyPair());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#placementGroup
|
||||
*/
|
||||
public static EC2TemplateOptions placementGroup(String placementGroup) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.placementGroup(placementGroup));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#noPlacementGroup
|
||||
*/
|
||||
public static EC2TemplateOptions noPlacementGroup() {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.noPlacementGroup());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#enableMonitoring
|
||||
*/
|
||||
public static EC2TemplateOptions enableMonitoring() {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.enableMonitoring());
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts
|
||||
|
@ -353,13 +327,6 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return EC2TemplateOptions.class.cast(options.withMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withSubnetId
|
||||
*/
|
||||
public static EC2TemplateOptions subnetId(String subnetId) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.subnetId(subnetId));
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
@ -509,34 +476,6 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return !noKeyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return placementGroup to use when running the instance or null, to generate a placementGroup.
|
||||
*/
|
||||
public String getPlacementGroup() {
|
||||
return placementGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true (default) if we are supposed to use a placementGroup
|
||||
*/
|
||||
public boolean shouldAutomaticallyCreatePlacementGroup() {
|
||||
return !noPlacementGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true (default) if we are supposed to enable cloudwatch
|
||||
*/
|
||||
public boolean isMonitoringEnabled() {
|
||||
return monitoringEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return subnetId to use when running the instance or null.
|
||||
*/
|
||||
public String getSubnetId() {
|
||||
return subnetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return unencoded user data.
|
||||
*/
|
||||
|
@ -559,11 +498,7 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode());
|
||||
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
|
||||
result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode());
|
||||
result = prime * result + (monitoringEnabled ? 1231 : 1237);
|
||||
result = prime * result + (noKeyPair ? 1231 : 1237);
|
||||
result = prime * result + (noPlacementGroup ? 1231 : 1237);
|
||||
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
|
||||
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
|
||||
result = prime * result + Arrays.hashCode(userData);
|
||||
return result;
|
||||
}
|
||||
|
@ -592,22 +527,7 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
return false;
|
||||
} else if (!keyPair.equals(other.keyPair))
|
||||
return false;
|
||||
if (monitoringEnabled != other.monitoringEnabled)
|
||||
return false;
|
||||
if (noKeyPair != other.noKeyPair)
|
||||
return false;
|
||||
if (noPlacementGroup != other.noPlacementGroup)
|
||||
return false;
|
||||
if (placementGroup == null) {
|
||||
if (other.placementGroup != null)
|
||||
return false;
|
||||
} else if (!placementGroup.equals(other.placementGroup))
|
||||
return false;
|
||||
if (subnetId == null) {
|
||||
if (other.subnetId != null)
|
||||
return false;
|
||||
} else if (!subnetId.equals(other.subnetId))
|
||||
return false;
|
||||
|
||||
if (!Arrays.equals(userData, other.userData))
|
||||
return false;
|
||||
|
||||
|
@ -616,11 +536,7 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair
|
||||
+ ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + placementGroup + ", noPlacementGroup="
|
||||
+ noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + Arrays.toString(userData)
|
||||
+ ", blockDeviceMappings=" + blockDeviceMappings + "]";
|
||||
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", userData="
|
||||
+ Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.ec2.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||
|
||||
@VisibleForTesting
|
||||
public final Map<RegionAndName, KeyPair> credentialsMap;
|
||||
@VisibleForTesting
|
||||
public final Map<RegionAndName, String> securityGroupMap;
|
||||
@VisibleForTesting
|
||||
public final CreateUniqueKeyPair createUniqueKeyPair;
|
||||
@VisibleForTesting
|
||||
public final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded;
|
||||
private final javax.inject.Provider<RunInstancesOptions> optionsProvider;
|
||||
|
||||
@Inject
|
||||
public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map<RegionAndName, KeyPair> credentialsMap,
|
||||
@Named("SECURITY") Map<RegionAndName, String> securityGroupMap, CreateUniqueKeyPair createUniqueKeyPair,
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded,
|
||||
javax.inject.Provider<RunInstancesOptions> optionsProvider) {
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
this.createUniqueKeyPair = createUniqueKeyPair;
|
||||
this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded;
|
||||
this.optionsProvider = optionsProvider;
|
||||
}
|
||||
|
||||
public RunInstancesOptions execute(String region, String tag, Template template) {
|
||||
|
||||
RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId());
|
||||
|
||||
String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions());
|
||||
|
||||
addSecurityGroups(region, tag, template, instanceOptions);
|
||||
if (template.getOptions() instanceof EC2TemplateOptions) {
|
||||
|
||||
if (keyPairName != null)
|
||||
instanceOptions.withKeyName(keyPairName);
|
||||
|
||||
byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData();
|
||||
|
||||
if (userData != null)
|
||||
instanceOptions.withUserData(userData);
|
||||
|
||||
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
|
||||
.getBlockDeviceMappings();
|
||||
if (blockDeviceMappings.size() > 0) {
|
||||
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
|
||||
"BlockDeviceMapping only available on ebs boot");
|
||||
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
}
|
||||
return instanceOptions;
|
||||
}
|
||||
|
||||
protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) {
|
||||
Set<String> groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions());
|
||||
instanceOptions.withSecurityGroups(groups);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) {
|
||||
String keyPairName = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
if (options instanceof EC2TemplateOptions) {
|
||||
keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
|
||||
if (keyPairName == null)
|
||||
shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
|
||||
.shouldAutomaticallyCreateKeyPair();
|
||||
}
|
||||
if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
|
||||
RegionAndName regionAndName = new RegionAndName(region, tag);
|
||||
KeyPair keyPair = createUniqueKeyPair.apply(regionAndName);
|
||||
// get or create incidental resources
|
||||
// TODO race condition. we were using MapMaker, but it doesn't seem to
|
||||
// refresh properly
|
||||
// when
|
||||
// another thread
|
||||
// deletes a key
|
||||
credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair);
|
||||
keyPairName = keyPair.getKeyName();
|
||||
}
|
||||
return keyPairName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) {
|
||||
Set<String> groups = Sets.newLinkedHashSet();
|
||||
|
||||
if (tag != null) {
|
||||
String markerGroup = String.format("jclouds#%s#%s", tag, region);
|
||||
groups.add(markerGroup);
|
||||
|
||||
RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup;
|
||||
|
||||
if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
|
||||
false);
|
||||
groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds());
|
||||
|
||||
} else {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options
|
||||
.getInboundPorts(), true);
|
||||
}
|
||||
|
||||
if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) {
|
||||
securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, createSecurityGroupIfNeeded
|
||||
.apply(regionNameAndIngessRulesForMarkerGroup));
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
// allows us to mock this method
|
||||
@VisibleForTesting
|
||||
public javax.inject.Provider<RunInstancesOptions> getOptionsProvider() {
|
||||
return optionsProvider;
|
||||
}
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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 org.jclouds.ec2.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||
@VisibleForTesting
|
||||
final String provider;
|
||||
@VisibleForTesting
|
||||
final Map<RegionAndName, KeyPair> credentialsMap;
|
||||
@VisibleForTesting
|
||||
final Map<RegionAndName, String> securityGroupMap;
|
||||
@VisibleForTesting
|
||||
final Map<RegionAndName, String> placementGroupMap;
|
||||
@VisibleForTesting
|
||||
final CreateUniqueKeyPair createUniqueKeyPair;
|
||||
@VisibleForTesting
|
||||
final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded;
|
||||
@VisibleForTesting
|
||||
final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded;
|
||||
|
||||
@Inject
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(@Provider String provider,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair,
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded,
|
||||
CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) {
|
||||
this.provider = provider;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
this.placementGroupMap = placementGroupMap;
|
||||
this.createUniqueKeyPair = createUniqueKeyPair;
|
||||
this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded;
|
||||
this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded;
|
||||
}
|
||||
|
||||
// this method only exists so that we can mock
|
||||
String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public RunInstancesOptions execute(String region, String tag, Template template) {
|
||||
|
||||
RunInstancesOptions instanceOptions = asType(template.getHardware().getId());
|
||||
|
||||
String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions());
|
||||
|
||||
String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise(
|
||||
region, tag, template.getOptions()) : null;
|
||||
|
||||
String subnetId = EC2TemplateOptions.class.cast(template.getOptions()).getSubnetId();
|
||||
|
||||
if (subnetId != null) {
|
||||
instanceOptions.withSubnetId(subnetId);
|
||||
} else {
|
||||
Set<String> groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions());
|
||||
instanceOptions.withSecurityGroups(groups);
|
||||
}
|
||||
|
||||
if (keyPairName != null)
|
||||
instanceOptions.withKeyName(keyPairName);
|
||||
|
||||
if (placementGroupName != null)
|
||||
instanceOptions.inPlacementGroup(placementGroupName);
|
||||
|
||||
byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData();
|
||||
|
||||
if (userData != null)
|
||||
instanceOptions.withUserData(userData);
|
||||
|
||||
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
|
||||
.getBlockDeviceMappings();
|
||||
if (blockDeviceMappings != null && blockDeviceMappings.size() > 0) {
|
||||
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
|
||||
"BlockDeviceMapping only available on ebs boot");
|
||||
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
return instanceOptions;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) {
|
||||
String keyPairName = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
if (options instanceof EC2TemplateOptions) {
|
||||
keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
|
||||
if (keyPairName == null)
|
||||
shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
|
||||
.shouldAutomaticallyCreateKeyPair();
|
||||
}
|
||||
if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
|
||||
RegionAndName regionAndName = new RegionAndName(region, tag);
|
||||
KeyPair keyPair = createUniqueKeyPair.apply(regionAndName);
|
||||
// get or create incidental resources
|
||||
// TODO race condition. we were using MapMaker, but it doesn't seem to
|
||||
// refresh properly
|
||||
// when
|
||||
// another thread
|
||||
// deletes a key
|
||||
credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair);
|
||||
keyPairName = keyPair.getKeyName();
|
||||
}
|
||||
return keyPairName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) {
|
||||
String placementGroupName = null;
|
||||
boolean shouldAutomaticallyCreatePlacementGroup = true;
|
||||
if (options instanceof EC2TemplateOptions) {
|
||||
placementGroupName = EC2TemplateOptions.class.cast(options).getPlacementGroup();
|
||||
if (placementGroupName == null)
|
||||
shouldAutomaticallyCreatePlacementGroup = EC2TemplateOptions.class.cast(options)
|
||||
.shouldAutomaticallyCreatePlacementGroup();
|
||||
}
|
||||
if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) {
|
||||
placementGroupName = String.format("jclouds#%s#%s", tag, region);
|
||||
RegionAndName regionAndName = new RegionAndName(region, placementGroupName);
|
||||
if (!placementGroupMap.containsKey(regionAndName)) {
|
||||
placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName));
|
||||
}
|
||||
}
|
||||
return placementGroupName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) {
|
||||
Set<String> groups = Sets.newLinkedHashSet();
|
||||
|
||||
if (tag != null) {
|
||||
String markerGroup = String.format("jclouds#%s#%s", tag, region);
|
||||
groups.add(markerGroup);
|
||||
|
||||
RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup;
|
||||
|
||||
if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
|
||||
false);
|
||||
groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds());
|
||||
|
||||
} else {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup,
|
||||
options.getInboundPorts(), true);
|
||||
}
|
||||
|
||||
if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) {
|
||||
securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup,
|
||||
createSecurityGroupIfNeeded.apply(regionNameAndIngessRulesForMarkerGroup));
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
}
|
|
@ -38,12 +38,10 @@ import org.jclouds.compute.config.CustomizationResponse;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.Reservation;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -52,6 +50,7 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
|
@ -61,7 +60,7 @@ import com.google.common.collect.Multimap;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
||||
public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThenAddToSet {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -70,7 +69,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
@VisibleForTesting
|
||||
final EC2Client client;
|
||||
@VisibleForTesting
|
||||
final CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
|
||||
final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
|
||||
@VisibleForTesting
|
||||
final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
|
||||
@VisibleForTesting
|
||||
|
@ -80,9 +79,9 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
final Map<String, Credentials> credentialStore;
|
||||
|
||||
@Inject
|
||||
EC2RunNodesAndAddToSetStrategy(
|
||||
EC2CreateNodesInGroupThenAddToSet(
|
||||
EC2Client client,
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||
|
@ -97,52 +96,65 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||
public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||
|
||||
Reservation<? extends RunningInstance> reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag,
|
||||
count, template);
|
||||
|
||||
Iterable<String> ids = transform(reservation, instanceToId);
|
||||
Iterable<? extends RunningInstance> started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group, count,
|
||||
template);
|
||||
Iterable<String> ids = transform(started, instanceToId);
|
||||
|
||||
String idsString = Joiner.on(',').join(ids);
|
||||
if (Iterables.size(ids) > 0) {
|
||||
logger.debug("<< started instances(%s)", idsString);
|
||||
all(reservation, instancePresent);
|
||||
all(started, instancePresent);
|
||||
logger.debug("<< present instances(%s)", idsString);
|
||||
populateCredentials(reservation);
|
||||
populateCredentials(started);
|
||||
}
|
||||
|
||||
return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(reservation,
|
||||
return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(started,
|
||||
runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
|
||||
}
|
||||
|
||||
protected void populateCredentials(Reservation<? extends RunningInstance> reservation) {
|
||||
RunningInstance instance1 = Iterables.get(reservation, 0);
|
||||
Credentials credentials = instanceToCredentials.apply(instance1);
|
||||
protected void populateCredentials(Iterable<? extends RunningInstance> started) {
|
||||
Credentials credentials = null;
|
||||
for (RunningInstance instance : started) {
|
||||
credentials = instanceToCredentials.apply(instance);
|
||||
if (credentials != null)
|
||||
for (RunningInstance instance : reservation)
|
||||
break;
|
||||
}
|
||||
if (credentials != null)
|
||||
for (RunningInstance instance : started)
|
||||
credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials);
|
||||
|
||||
}
|
||||
|
||||
// TODO write test for this
|
||||
@VisibleForTesting
|
||||
Reservation<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count,
|
||||
Iterable<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String group, int count,
|
||||
Template template) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
|
||||
String zone = getZoneFromLocationOrNull(template.getLocation());
|
||||
|
||||
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region,
|
||||
tag, template);
|
||||
group, template);
|
||||
|
||||
if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled())
|
||||
instanceOptions.enableMonitoring();
|
||||
int countStarted = 0;
|
||||
int tries = 0;
|
||||
Iterable<? extends RunningInstance> started = ImmutableSet.<RunningInstance> of();
|
||||
|
||||
while (countStarted < count && tries++ < count) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template
|
||||
.getImage().getProviderId(), instanceOptions.buildFormParameters());
|
||||
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region,
|
||||
zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters());
|
||||
|
||||
return client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1,
|
||||
count, instanceOptions);
|
||||
started = Iterables.concat(started, client.getInstanceServices().runInstancesInRegion(region, zone,
|
||||
template.getImage().getProviderId(), 1, count - countStarted, instanceOptions));
|
||||
|
||||
countStarted = Iterables.size(started);
|
||||
if (countStarted < count)
|
||||
logger.debug(">> not enough instances (%d/%d) started, attempting again", countStarted, count);
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
}
|
|
@ -81,12 +81,13 @@ public class EC2ListNodesStrategy implements ListNodesStrategy {
|
|||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
|
||||
Iterable<Set<? extends Reservation<? extends RunningInstance>>> reservations = transformParallel(
|
||||
Iterable<? extends Set<? extends Reservation<? extends RunningInstance>>> reservations = transformParallel(
|
||||
regions, new Function<String, Future<Set<? extends Reservation<? extends RunningInstance>>>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Future<Set<? extends Reservation<? extends RunningInstance>>> apply(String from) {
|
||||
return client.getInstanceServices().describeInstancesInRegion(from);
|
||||
return (Future<Set<? extends Reservation<? extends RunningInstance>>>) client.getInstanceServices().describeInstancesInRegion(from);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "reservations");
|
||||
|
|
|
@ -19,37 +19,19 @@
|
|||
|
||||
package org.jclouds.ec2.compute.suppliers;
|
||||
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Sets.newLinkedHashSet;
|
||||
import static org.jclouds.compute.predicates.ImagePredicates.any;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.t1_micro;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
|
||||
import static org.jclouds.compute.predicates.ImagePredicates.any;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
@ -59,41 +41,10 @@ import com.google.common.collect.ImmutableSet;
|
|||
*/
|
||||
@Singleton
|
||||
public class EC2HardwareSupplier implements Supplier<Set<? extends Hardware>> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
private final String[] ccAmis;
|
||||
private final String providerName;
|
||||
|
||||
@Inject
|
||||
EC2HardwareSupplier(@Memoized Supplier<Set<? extends Location>> locations, @Provider String providerName,
|
||||
@Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) {
|
||||
this.locations = locations;
|
||||
this.ccAmis = ccAmis;
|
||||
this.providerName = providerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Hardware> get() {
|
||||
Set<Hardware> sizes = newLinkedHashSet();
|
||||
for (String ccAmi : ccAmis) {
|
||||
final String region = ccAmi.split("/")[0];
|
||||
Location location = find(locations.get(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getScope() == LocationScope.REGION && input.getId().equals(region);
|
||||
}
|
||||
|
||||
});
|
||||
sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build());
|
||||
}
|
||||
// TODO move logic to dependent module
|
||||
sizes.addAll(ImmutableSet.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large()
|
||||
.build(),
|
||||
!"aws-ec2".equals(providerName) ? m1_small().supportsImage(any()).build() : m1_small().build(),
|
||||
m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), m2_4xlarge().build()));
|
||||
return sizes;
|
||||
return ImmutableSet.<Hardware> of(m1_small().supportsImage(any()).build(), c1_medium().build(), c1_xlarge()
|
||||
.build(), m1_large().build(), m1_xlarge().build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,31 +38,27 @@ package org.jclouds.ec2.compute.suppliers;
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||
import static com.google.common.collect.Maps.uniqueIndex;
|
||||
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.ownedBy;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
|
||||
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.functions.EC2ImageParser;
|
||||
import org.jclouds.ec2.compute.strategy.DescribeImagesParallel;
|
||||
import org.jclouds.ec2.options.DescribeImagesOptions;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
|
@ -84,18 +80,15 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
|||
|
||||
private final Set<String> regions;
|
||||
private final DescribeImagesParallel describer;
|
||||
private final String[] ccAmis;
|
||||
private final String[] amiOwners;
|
||||
private final EC2ImageParser parser;
|
||||
private final Map<RegionAndName, Image> images;
|
||||
|
||||
@Inject
|
||||
RegionAndNameToImageSupplier(@Region Set<String> regions, DescribeImagesParallel describer,
|
||||
@Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners,
|
||||
final EC2ImageParser parser, final Map<RegionAndName, Image> images) {
|
||||
protected RegionAndNameToImageSupplier(@Region Set<String> regions, DescribeImagesParallel describer,
|
||||
@Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, EC2ImageParser parser, Map<RegionAndName, Image> images) {
|
||||
this.regions = regions;
|
||||
this.describer = describer;
|
||||
this.ccAmis = ccAmis;
|
||||
this.amiOwners = amiOwners;
|
||||
this.parser = parser;
|
||||
this.images = images;
|
||||
|
@ -108,12 +101,11 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
|||
} else {
|
||||
logger.debug(">> providing images");
|
||||
|
||||
Iterable<Entry<String, DescribeImagesOptions>> queries = concat(
|
||||
getDescribeQueriesForOwnersInRegions(regions, amiOwners).entrySet(), ccAmisToDescribeQueries(ccAmis)
|
||||
.entrySet());
|
||||
Iterable<Entry<String, DescribeImagesOptions>> queries = getDescribeQueriesForOwnersInRegions(regions,
|
||||
amiOwners);
|
||||
|
||||
Iterable<? extends Image> parsedImages = filter(transform(describer.apply(queries), parser),
|
||||
Predicates.notNull());
|
||||
Iterable<? extends Image> parsedImages = filter(transform(describer.apply(queries), parser), Predicates
|
||||
.notNull());
|
||||
|
||||
images.putAll(uniqueIndex(parsedImages, new Function<Image, RegionAndName>() {
|
||||
|
||||
|
@ -129,24 +121,16 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
|
|||
return images;
|
||||
}
|
||||
|
||||
private static Map<String, DescribeImagesOptions> ccAmisToDescribeQueries(String[] ccAmis) {
|
||||
Map<String, DescribeImagesOptions> queries = newLinkedHashMap();
|
||||
for (String from : ccAmis) {
|
||||
queries.put(from.split("/")[0], imageIds(from.split("/")[1]));
|
||||
}
|
||||
return queries;
|
||||
}
|
||||
|
||||
private static Map<String, DescribeImagesOptions> getDescribeQueriesForOwnersInRegions(Set<String> regions,
|
||||
final String[] amiOwners) {
|
||||
final DescribeImagesOptions options = getOptionsForOwners(amiOwners);
|
||||
public Iterable<Entry<String, DescribeImagesOptions>> getDescribeQueriesForOwnersInRegions(Set<String> regions,
|
||||
String[] amiOwners) {
|
||||
DescribeImagesOptions options = getOptionsForOwners(amiOwners);
|
||||
Builder<String, DescribeImagesOptions> builder = ImmutableMap.<String, DescribeImagesOptions> builder();
|
||||
for (String region : regions)
|
||||
builder.put(region, options);
|
||||
return builder.build();
|
||||
return builder.build().entrySet();
|
||||
}
|
||||
|
||||
private static DescribeImagesOptions getOptionsForOwners(final String[] amiOwners) {
|
||||
public static DescribeImagesOptions getOptionsForOwners(String[] amiOwners) {
|
||||
final DescribeImagesOptions options;
|
||||
if (amiOwners.length == 1 && amiOwners[0].equals("*"))
|
||||
options = new DescribeImagesOptions();
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
|
||||
package org.jclouds.ec2.config;
|
||||
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -42,10 +45,6 @@ import org.jclouds.ec2.services.InstanceAsyncClient;
|
|||
import org.jclouds.ec2.services.InstanceClient;
|
||||
import org.jclouds.ec2.services.KeyPairAsyncClient;
|
||||
import org.jclouds.ec2.services.KeyPairClient;
|
||||
import org.jclouds.ec2.services.MonitoringAsyncClient;
|
||||
import org.jclouds.ec2.services.MonitoringClient;
|
||||
import org.jclouds.ec2.services.PlacementGroupAsyncClient;
|
||||
import org.jclouds.ec2.services.PlacementGroupClient;
|
||||
import org.jclouds.ec2.services.SecurityGroupAsyncClient;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.ec2.services.WindowsAsyncClient;
|
||||
|
@ -55,8 +54,16 @@ import org.jclouds.location.Region;
|
|||
import org.jclouds.location.Zone;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.inject.ConfigurationException;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* Configures the EC2 connection.
|
||||
|
@ -65,7 +72,8 @@ import com.google.common.collect.ImmutableMap.Builder;
|
|||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class EC2RestClientModule extends WithZonesFormSigningRestClientModule<EC2Client, EC2AsyncClient> {
|
||||
public class EC2RestClientModule<S extends EC2Client, A extends EC2AsyncClient> extends
|
||||
WithZonesFormSigningRestClientModule<S, A> {
|
||||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
|
||||
.put(AMIClient.class, AMIAsyncClient.class)//
|
||||
|
@ -73,15 +81,17 @@ public class EC2RestClientModule extends WithZonesFormSigningRestClientModule<EC
|
|||
.put(InstanceClient.class, InstanceAsyncClient.class)//
|
||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
|
||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
|
||||
.put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)//
|
||||
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
|
||||
.put(WindowsClient.class, WindowsAsyncClient.class)//
|
||||
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
|
||||
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
||||
.build();
|
||||
|
||||
public EC2RestClientModule() {
|
||||
super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
|
||||
public static EC2RestClientModule<EC2Client, EC2AsyncClient> create() {
|
||||
return new EC2RestClientModule<EC2Client, EC2AsyncClient>(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
|
||||
}
|
||||
|
||||
public EC2RestClientModule(Class<S> sync, Class<A> async, Map<Class<?>, Class<?>> delegateMap) {
|
||||
super(sync, async, delegateMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,20 +107,32 @@ public class EC2RestClientModule extends WithZonesFormSigningRestClientModule<EC
|
|||
@Singleton
|
||||
public static class RegionIdsToURI implements javax.inject.Provider<Map<String, URI>> {
|
||||
private final AvailabilityZoneAndRegionClient client;
|
||||
private final Injector injector;
|
||||
|
||||
@Inject
|
||||
public RegionIdsToURI(EC2Client client) {
|
||||
public RegionIdsToURI(EC2Client client, Injector injector) {
|
||||
this.client = client.getAvailabilityZoneAndRegionServices();
|
||||
this.injector = injector;
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Region
|
||||
@Override
|
||||
public Map<String, URI> get() {
|
||||
return client.describeRegions();
|
||||
try {
|
||||
String regionString = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGIONS)));
|
||||
Set<String> regions = ImmutableSet.copyOf(Splitter.on(',').split(regionString));
|
||||
if (regions.size() > 0)
|
||||
return Maps.filterKeys(client.describeRegions(), Predicates.in(regions));
|
||||
} catch (ConfigurationException e) {
|
||||
// this happens if regions property isn't set
|
||||
// services not run by AWS may not have regions, so this is ok.
|
||||
}
|
||||
return client.describeRegions();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
|
||||
private final AvailabilityZoneAndRegionClient client;
|
||||
|
|
|
@ -37,7 +37,6 @@ public class BlockDevice {
|
|||
private final boolean deleteOnTermination;
|
||||
|
||||
public BlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) {
|
||||
super();
|
||||
this.volumeId = volumeId;
|
||||
this.attachmentStatus = attachmentStatus;
|
||||
this.attachTime = attachTime;
|
||||
|
|
|
@ -42,15 +42,15 @@ public class BlockDeviceMapping {
|
|||
private static final Integer VOLUME_SIZE_MIN_VALUE = 1;
|
||||
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
|
||||
|
||||
public BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId,
|
||||
BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId,
|
||||
@Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) {
|
||||
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
|
||||
|
||||
if (sizeInGib != null) {
|
||||
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE),
|
||||
String.format("Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
|
||||
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), String.format(
|
||||
"Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
|
||||
}
|
||||
this.deviceName = deviceName;
|
||||
this.virtualName = virtualName;
|
||||
|
@ -88,7 +88,12 @@ public class BlockDeviceMapping {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((deleteOnTermination == null) ? 0 : deleteOnTermination.hashCode());
|
||||
result = prime * result + ((deviceName == null) ? 0 : deviceName.hashCode());
|
||||
result = prime * result + ((noDevice == null) ? 0 : noDevice.hashCode());
|
||||
result = prime * result + ((sizeInGib == null) ? 0 : sizeInGib.hashCode());
|
||||
result = prime * result + ((snapshotId == null) ? 0 : snapshotId.hashCode());
|
||||
result = prime * result + ((virtualName == null) ? 0 : virtualName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -101,19 +106,44 @@ public class BlockDeviceMapping {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BlockDeviceMapping other = (BlockDeviceMapping) obj;
|
||||
if (deleteOnTermination == null) {
|
||||
if (other.deleteOnTermination != null)
|
||||
return false;
|
||||
} else if (!deleteOnTermination.equals(other.deleteOnTermination))
|
||||
return false;
|
||||
if (deviceName == null) {
|
||||
if (other.deviceName != null)
|
||||
return false;
|
||||
} else if (!deviceName.equals(other.deviceName))
|
||||
return false;
|
||||
if (noDevice == null) {
|
||||
if (other.noDevice != null)
|
||||
return false;
|
||||
} else if (!noDevice.equals(other.noDevice))
|
||||
return false;
|
||||
if (sizeInGib == null) {
|
||||
if (other.sizeInGib != null)
|
||||
return false;
|
||||
} else if (!sizeInGib.equals(other.sizeInGib))
|
||||
return false;
|
||||
if (snapshotId == null) {
|
||||
if (other.snapshotId != null)
|
||||
return false;
|
||||
} else if (!snapshotId.equals(other.snapshotId))
|
||||
return false;
|
||||
if (virtualName == null) {
|
||||
if (other.virtualName != null)
|
||||
return false;
|
||||
} else if (!virtualName.equals(other.virtualName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockDeviceMapping [deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId="
|
||||
+ snapshotId + ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination="
|
||||
+ deleteOnTermination + "]";
|
||||
return "[deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" + snapshotId
|
||||
+ ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" + deleteOnTermination
|
||||
+ "]";
|
||||
}
|
||||
|
||||
public static class MapEBSSnapshotToDevice extends BlockDeviceMapping {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue