mirror of https://github.com/apache/jclouds.git
Merge commit 'a3a97d02b83e613944ca4c1ecc278bc60015daf3' from upstream
This commit is contained in:
commit
dcc97a5387
|
@ -9,3 +9,4 @@ test-output/
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
|
TAGS
|
||||||
|
|
|
@ -30,7 +30,7 @@ our current version is 1.0-beta-9c
|
||||||
our dev version is 1.0-SNAPSHOT
|
our dev version is 1.0-SNAPSHOT
|
||||||
|
|
||||||
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
||||||
cloudservers-uk, vcloud (generic), ec2 (generic), byon,
|
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
|
||||||
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
||||||
cloudsigma-zrh, elasticstack(generic), bluelock-vclouddirector,
|
cloudsigma-zrh, elasticstack(generic), bluelock-vclouddirector,
|
||||||
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
||||||
|
@ -49,6 +49,11 @@ our blobstore api supports: aws-s3, cloudfiles-us, cloudfiles-uk, filesystem,
|
||||||
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
|
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
|
||||||
to all of these providers
|
to all of these providers
|
||||||
|
|
||||||
|
our loadbalancer api supports: cloudloadbalancers-us
|
||||||
|
|
||||||
|
* note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
|
||||||
|
to all of these providers
|
||||||
|
|
||||||
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, rimuhosting, openstack nova,
|
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, rimuhosting, openstack nova,
|
||||||
azurequeue, simpledb, cloudstack as well as a async-http-client
|
azurequeue, simpledb, cloudstack as well as a async-http-client
|
||||||
driver in the sandbox
|
driver in the sandbox
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
<artifactId>jclouds-all</artifactId>
|
<artifactId>jclouds-all</artifactId>
|
||||||
<name>all</name>
|
<name>all</name>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-allloadbalancer</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-allcompute</artifactId>
|
<artifactId>jclouds-allcompute</artifactId>
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
<artifactId>jclouds-allcompute</artifactId>
|
<artifactId>jclouds-allcompute</artifactId>
|
||||||
<name>allcompute</name>
|
<name>allcompute</name>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.provider</groupId>
|
||||||
|
<artifactId>savvis-symphonyvpdc</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.provider</groupId>
|
<groupId>org.jclouds.provider</groupId>
|
||||||
<artifactId>eucalyptus-partnercloud-ec2</artifactId>
|
<artifactId>eucalyptus-partnercloud-ec2</artifactId>
|
||||||
|
@ -44,6 +49,11 @@
|
||||||
<artifactId>aws-ec2</artifactId>
|
<artifactId>aws-ec2</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.api</groupId>
|
||||||
|
<artifactId>nova</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.api</groupId>
|
<groupId>org.jclouds.api</groupId>
|
||||||
<artifactId>byon</artifactId>
|
<artifactId>byon</artifactId>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>jclouds-allloadbalancer</artifactId>
|
||||||
|
<name>allloadbalancer</name>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.provider</groupId>
|
||||||
|
<artifactId>cloudloadbalancers-us</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -2,7 +2,7 @@
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
|
||||||
====================================================================
|
====================================================================
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -28,9 +28,12 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../../project/pom.xml</relativePath>
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.jclouds.api</groupId>
|
<groupId>org.jclouds.api</groupId>
|
||||||
<artifactId>atmos</artifactId>
|
<artifactId>atmos</artifactId>
|
||||||
<name>jclouds atmos components</name>
|
<name>jclouds atmos components</name>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer>
|
<test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer>
|
||||||
<test.atmos.endpoint>https://accesspoint.atmos.com</test.atmos.endpoint>
|
<test.atmos.endpoint>https://accesspoint.atmos.com</test.atmos.endpoint>
|
||||||
|
@ -38,6 +41,7 @@
|
||||||
<test.atmos.identity>FIXME</test.atmos.identity>
|
<test.atmos.identity>FIXME</test.atmos.identity>
|
||||||
<test.atmos.credential>FIXME</test.atmos.credential>
|
<test.atmos.credential>FIXME</test.atmos.credential>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
@ -126,4 +130,20 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.atmos.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -65,6 +65,8 @@ Here are the properties:
|
||||||
* description - optional; long description of this node
|
* description - optional; long description of this node
|
||||||
* note this is not yet in jclouds NodeMetadata
|
* note this is not yet in jclouds NodeMetadata
|
||||||
* hostname - name or ip address to contact the node on
|
* hostname - name or ip address to contact the node on
|
||||||
|
* location_id - optional; correlates to a ZONE-scoped Location
|
||||||
|
* note that if present for one node, must be present for all
|
||||||
* os_arch - ex. x86
|
* os_arch - ex. x86
|
||||||
* os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format
|
* os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format
|
||||||
ex. rhel, ubuntu, centos, debian, amzn-linux
|
ex. rhel, ubuntu, centos, debian, amzn-linux
|
||||||
|
@ -96,6 +98,7 @@ nodes:
|
||||||
name: cluster-1
|
name: cluster-1
|
||||||
description: accounting analytics cluster
|
description: accounting analytics cluster
|
||||||
hostname: cluster-1.mydomain.com
|
hostname: cluster-1.mydomain.com
|
||||||
|
location_id: virginia
|
||||||
os_arch: x86
|
os_arch: x86
|
||||||
os_family: rhel
|
os_family: rhel
|
||||||
os_description: redhat with CDH
|
os_description: redhat with CDH
|
||||||
|
|
|
@ -28,9 +28,12 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../../project/pom.xml</relativePath>
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.jclouds.api</groupId>
|
<groupId>org.jclouds.api</groupId>
|
||||||
<artifactId>byon</artifactId>
|
<artifactId>byon</artifactId>
|
||||||
<name>jclouds bring your own node provider</name>
|
<name>jclouds bring your own node provider</name>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.byon.endpoint>file://c:/test.txt</test.byon.endpoint>
|
<test.byon.endpoint>file://c:/test.txt</test.byon.endpoint>
|
||||||
<test.byon.sudo-password> </test.byon.sudo-password>
|
<test.byon.sudo-password> </test.byon.sudo-password>
|
||||||
|
@ -81,7 +84,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.6</version>
|
<version>1.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -120,4 +123,20 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.byon.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -20,60 +20,170 @@ package org.jclouds.byon;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Node {
|
public class Node {
|
||||||
// public due to snakeyaml
|
public static Builder builder() {
|
||||||
public Node() {
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node(String id, String name, String description, String hostname, String osArch, String osFamily,
|
public static class Builder {
|
||||||
String osDescription, String osVersion, String group, List<String> tags, String username,
|
private String id;
|
||||||
String credential, URI credentialUrl, String sudo_password) {
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private String hostname;
|
||||||
|
private String locationId;
|
||||||
|
private String osArch;
|
||||||
|
private String osFamily;
|
||||||
|
private String osDescription;
|
||||||
|
private String osVersion;
|
||||||
|
private boolean os64Bit;
|
||||||
|
private String group;
|
||||||
|
private Set<String> tags = ImmutableSet.of();
|
||||||
|
private String username;
|
||||||
|
private String credential;
|
||||||
|
private URI credentialUrl;
|
||||||
|
private String sudoPassword;
|
||||||
|
|
||||||
|
public Builder id(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hostname(String hostname) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder locationId(String locationId) {
|
||||||
|
this.locationId = locationId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder osArch(String osArch) {
|
||||||
|
this.osArch = osArch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder osFamily(String osFamily) {
|
||||||
|
this.osFamily = osFamily;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder osDescription(String osDescription) {
|
||||||
|
this.osDescription = osDescription;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder osVersion(String osVersion) {
|
||||||
|
this.osVersion = osVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder os64Bit(boolean os64Bit) {
|
||||||
|
this.os64Bit = os64Bit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder group(String group) {
|
||||||
|
this.group = group;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder tags(Iterable<String> tags) {
|
||||||
|
this.tags = ImmutableSet.copyOf(tags);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder username(String username) {
|
||||||
|
this.username = username;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder credential(String credential) {
|
||||||
|
this.credential = credential;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder credentialUrl(URI credentialUrl) {
|
||||||
|
this.credentialUrl = credentialUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder sudoPassword(String sudoPassword) {
|
||||||
|
this.sudoPassword = sudoPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node build() {
|
||||||
|
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
|
||||||
|
os64Bit, group, tags, username, credential, credentialUrl, sudoPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(String id, String name, String description, String hostname, String locationId, String osArch,
|
||||||
|
String osFamily, String osDescription, String osVersion, boolean os64Bit, String group,
|
||||||
|
Iterable<String> tags, String username, String credential, URI credentialUrl, String sudoPassword) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.os_arch = osArch;
|
this.locationId = locationId;
|
||||||
this.os_family = osFamily;
|
this.osArch = osArch;
|
||||||
this.os_description = osDescription;
|
this.osFamily = osFamily;
|
||||||
this.os_version = osVersion;
|
this.osDescription = osDescription;
|
||||||
|
this.osVersion = osVersion;
|
||||||
|
this.os64Bit = os64Bit;
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.tags = ImmutableList.copyOf(tags);
|
this.tags = ImmutableSet.copyOf(tags);
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.credential = credential;
|
this.credential = credential;
|
||||||
this.credential_url = credentialUrl != null ? credentialUrl.toASCIIString() : null;
|
this.credentialUrl = credentialUrl;
|
||||||
this.sudo_password = sudo_password;
|
this.sudoPassword = sudoPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public due to snakeyaml
|
private final String id;
|
||||||
public String id;
|
private final String name;
|
||||||
public String name;
|
private final String description;
|
||||||
public String description;
|
private final String hostname;
|
||||||
public String hostname;
|
private final String locationId;
|
||||||
public String os_arch;
|
private final String osArch;
|
||||||
public String os_family;
|
private final String osFamily;
|
||||||
public String os_description;
|
private final String osDescription;
|
||||||
public String os_version;
|
private final String osVersion;
|
||||||
public String group;
|
private final boolean os64Bit;
|
||||||
public List<String> tags;
|
private final String group;
|
||||||
public String username;
|
private final Set<String> tags;
|
||||||
public String credential;
|
private final String username;
|
||||||
public String credential_url;
|
private final String credential;
|
||||||
public String sudo_password;
|
private final URI credentialUrl;
|
||||||
|
private final String sudoPassword;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLocationId() {
|
||||||
|
return locationId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -91,19 +201,23 @@ public class Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsArch() {
|
public String getOsArch() {
|
||||||
return os_arch;
|
return osArch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsFamily() {
|
public String getOsFamily() {
|
||||||
return os_family;
|
return osFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsDescription() {
|
public String getOsDescription() {
|
||||||
return os_description;
|
return osDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsVersion() {
|
public String getOsVersion() {
|
||||||
return os_version;
|
return osVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOs64Bit() {
|
||||||
|
return os64Bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getTags() {
|
public Set<String> getTags() {
|
||||||
|
@ -122,7 +236,11 @@ public class Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getCredentialUrl() {
|
public URI getCredentialUrl() {
|
||||||
return credential_url != null ? URI.create(credential_url) : null;
|
return credentialUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSudoPassword() {
|
||||||
|
return sudoPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,10 +248,6 @@ public class Node {
|
||||||
return Objects.hashCode(id);
|
return Objects.hashCode(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSudoPassword() {
|
|
||||||
return sudo_password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object that) {
|
public boolean equals(Object that) {
|
||||||
if (that == null)
|
if (that == null)
|
||||||
|
@ -144,10 +258,11 @@ public class Node {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add(
|
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",
|
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
|
||||||
os_description).add("osVersion", os_version).add("group", group).add("tags", tags).add("username",
|
"osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit).add("group", group)
|
||||||
username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword",
|
.add("tags", tags).add("username", username).add("hasCredential",
|
||||||
sudo_password != null).toString();
|
credential != null || credentialUrl != null).add("hasSudoPassword", sudoPassword != null)
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.util.Map;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
import org.jclouds.byon.functions.NodesFromYaml;
|
import org.jclouds.byon.functions.NodesFromYamlStream;
|
||||||
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
||||||
import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
|
import org.jclouds.byon.suppliers.NodesParsedFromSupplier;
|
||||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||||
|
@ -44,7 +44,7 @@ import com.google.inject.TypeLiteral;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings( { "rawtypes", "unchecked" })
|
@SuppressWarnings("unchecked")
|
||||||
@SingleThreaded
|
@SingleThreaded
|
||||||
public class BYONComputeServiceContextModule extends
|
public class BYONComputeServiceContextModule extends
|
||||||
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
|
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
|
||||||
|
@ -53,7 +53,6 @@ public class BYONComputeServiceContextModule extends
|
||||||
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
|
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Supplier provideApi(Supplier<Map<String, Node>> in) {
|
Supplier provideApi(Supplier<Map<String, Node>> in) {
|
||||||
|
@ -73,7 +72,7 @@ public class BYONComputeServiceContextModule extends
|
||||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
// TODO make this somehow overridable via user request
|
// TODO make this somehow overridable via user request
|
||||||
bind(new TypeLiteral<Function<InputStream, Map<String, Node>>>() {
|
bind(new TypeLiteral<Function<InputStream, Map<String, Node>>>() {
|
||||||
}).to(NodesFromYaml.class);
|
}).to(NodesFromYamlStream.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.byon.config;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* designates the module configures a {@code Map<String, Node>}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target(TYPE)
|
||||||
|
public @interface ConfiguresNodeStore {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.byon.config;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.byon.domain.YamlNode;
|
||||||
|
import org.jclouds.collect.TransformingMap;
|
||||||
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ConfiguresNodeStore
|
||||||
|
@Beta
|
||||||
|
public class YamlNodeStoreModule extends AbstractModule {
|
||||||
|
private static final Map<String, InputSupplier<InputStream>> BACKING = new ConcurrentHashMap<String, InputSupplier<InputStream>>();
|
||||||
|
private final Map<String, InputStream> backing;
|
||||||
|
|
||||||
|
public YamlNodeStoreModule(Map<String, InputStream> backing) {
|
||||||
|
this.backing = backing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public YamlNodeStoreModule() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(new TypeLiteral<Function<YamlNode, InputStream>>() {
|
||||||
|
}).toInstance(org.jclouds.byon.domain.YamlNode.yamlNodeToInputStream);
|
||||||
|
bind(new TypeLiteral<Function<InputStream, YamlNode>>() {
|
||||||
|
}).toInstance(org.jclouds.byon.domain.YamlNode.inputStreamToYamlNode);
|
||||||
|
bind(new TypeLiteral<Function<Node, YamlNode>>() {
|
||||||
|
}).toInstance(org.jclouds.byon.domain.YamlNode.nodeToYamlNode);
|
||||||
|
bind(new TypeLiteral<Function<YamlNode, Node>>() {
|
||||||
|
}).toInstance(org.jclouds.byon.domain.YamlNode.toNode);
|
||||||
|
if (backing != null) {
|
||||||
|
bind(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
|
}).toInstance(backing);
|
||||||
|
} else {
|
||||||
|
bind(new TypeLiteral<Map<String, InputSupplier<InputStream>>>() {
|
||||||
|
}).toInstance(BACKING);
|
||||||
|
bind(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
|
}).to(new TypeLiteral<CopyInputStreamInputSupplierMap>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Map<String, Node> provideNodeStore(Map<String, YamlNode> backing,
|
||||||
|
Function<Node, YamlNode> yamlSerializer, Function<YamlNode, Node> yamlDeserializer) {
|
||||||
|
return new TransformingMap<String, YamlNode, Node>(backing, yamlDeserializer, yamlSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Map<String, YamlNode> provideYamlStore(Map<String, InputStream> backing,
|
||||||
|
Function<YamlNode, InputStream> yamlSerializer, Function<InputStream, YamlNode> yamlDeserializer) {
|
||||||
|
return new TransformingMap<String, InputStream, YamlNode>(backing, yamlDeserializer, yamlSerializer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.byon.domain;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.util.Strings2;
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Loader;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes to the following
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* id: cluster-1
|
||||||
|
* name: cluster-1
|
||||||
|
* description: xyz
|
||||||
|
* hostname: cluster-1.mydomain.com
|
||||||
|
* location_id: virginia
|
||||||
|
* os_arch: x86
|
||||||
|
* os_family: linux
|
||||||
|
* os_description: redhat
|
||||||
|
* os_version: 5.3
|
||||||
|
* os_64bit: 5.3
|
||||||
|
* group: hadoop
|
||||||
|
* tags:
|
||||||
|
* - vanilla
|
||||||
|
* username: kelvin
|
||||||
|
* 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
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class YamlNode {
|
||||||
|
public String id;
|
||||||
|
public String name;
|
||||||
|
public String description;
|
||||||
|
public String hostname;
|
||||||
|
public String location_id;
|
||||||
|
public String os_arch;
|
||||||
|
public String os_family;
|
||||||
|
public String os_description;
|
||||||
|
public String os_version;
|
||||||
|
public boolean os_64bit;
|
||||||
|
public String group;
|
||||||
|
public List<String> tags = Lists.newArrayList();
|
||||||
|
public String username;
|
||||||
|
public String credential;
|
||||||
|
public String credential_url;
|
||||||
|
public String sudo_password;
|
||||||
|
|
||||||
|
public static Function<YamlNode, Node> toNode = new Function<YamlNode, Node>() {
|
||||||
|
@Override
|
||||||
|
public Node apply(YamlNode arg0) {
|
||||||
|
if (arg0 == null)
|
||||||
|
return null;
|
||||||
|
return Node.builder().id(arg0.id).name(arg0.name).description(arg0.description).locationId(arg0.location_id)
|
||||||
|
.hostname(arg0.hostname).osArch(arg0.os_arch).osFamily(arg0.os_family).osDescription(
|
||||||
|
arg0.os_description).osVersion(arg0.os_version).os64Bit(arg0.os_64bit).group(arg0.group)
|
||||||
|
.tags(arg0.tags).username(arg0.username).credential(arg0.credential).credentialUrl(
|
||||||
|
arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword(
|
||||||
|
arg0.sudo_password).build();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Node toNode() {
|
||||||
|
return toNode.apply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<InputStream, YamlNode> inputStreamToYamlNode = new Function<InputStream, YamlNode>() {
|
||||||
|
@Override
|
||||||
|
public YamlNode apply(InputStream in) {
|
||||||
|
if (in == null)
|
||||||
|
return null;
|
||||||
|
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
|
||||||
|
// constructor
|
||||||
|
try {
|
||||||
|
return (YamlNode) new Yaml(new Loader(new Constructor(YamlNode.class))).load(in);
|
||||||
|
} finally {
|
||||||
|
Closeables.closeQuietly(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static YamlNode fromYaml(InputStream in) {
|
||||||
|
return inputStreamToYamlNode.apply(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<YamlNode, InputStream> yamlNodeToInputStream = new Function<YamlNode, InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream apply(YamlNode in) {
|
||||||
|
if (in == null)
|
||||||
|
return null;
|
||||||
|
Builder<String, Object> prettier = ImmutableMap.<String, Object> builder();
|
||||||
|
if (in.id != null)
|
||||||
|
prettier.put("id", in.id);
|
||||||
|
if (in.name != null)
|
||||||
|
prettier.put("name", in.name);
|
||||||
|
if (in.description != null)
|
||||||
|
prettier.put("description", in.description);
|
||||||
|
if (in.hostname != null)
|
||||||
|
prettier.put("hostname", in.hostname);
|
||||||
|
if (in.location_id != null)
|
||||||
|
prettier.put("location_id", in.location_id);
|
||||||
|
if (in.os_arch != null)
|
||||||
|
prettier.put("os_arch", in.os_arch);
|
||||||
|
if (in.os_family != null)
|
||||||
|
prettier.put("os_family", in.os_family);
|
||||||
|
if (in.os_description != null)
|
||||||
|
prettier.put("os_description", in.os_description);
|
||||||
|
if (in.os_version != null)
|
||||||
|
prettier.put("os_version", in.os_version);
|
||||||
|
if (in.os_64bit)
|
||||||
|
prettier.put("os_64bit", in.os_64bit);
|
||||||
|
if (in.group != null)
|
||||||
|
prettier.put("group", in.group);
|
||||||
|
if (in.tags.size() != 0)
|
||||||
|
prettier.put("tags", in.tags);
|
||||||
|
if (in.username != null)
|
||||||
|
prettier.put("username", in.username);
|
||||||
|
if (in.credential != null)
|
||||||
|
prettier.put("credential", in.credential);
|
||||||
|
if (in.credential_url != null)
|
||||||
|
prettier.put("credential_url", in.credential_url);
|
||||||
|
if (in.sudo_password != null)
|
||||||
|
prettier.put("sudo_password", in.sudo_password);
|
||||||
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
return Strings2.toInputStream(new Yaml(options).dump(prettier.build()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public InputStream toYaml() {
|
||||||
|
return yamlNodeToInputStream.apply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static YamlNode fromNode(Node in) {
|
||||||
|
return nodeToYamlNode.apply(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<Node, YamlNode> nodeToYamlNode = new Function<Node, YamlNode>() {
|
||||||
|
@Override
|
||||||
|
public YamlNode apply(Node arg0) {
|
||||||
|
if (arg0 == null)
|
||||||
|
return null;
|
||||||
|
YamlNode yaml = new YamlNode();
|
||||||
|
yaml.id = arg0.getId();
|
||||||
|
yaml.name = arg0.getName();
|
||||||
|
yaml.description = arg0.getDescription();
|
||||||
|
yaml.hostname = arg0.getHostname();
|
||||||
|
yaml.location_id = arg0.getLocationId();
|
||||||
|
yaml.os_arch = arg0.getOsArch();
|
||||||
|
yaml.os_family = arg0.getOsFamily();
|
||||||
|
yaml.os_description = arg0.getOsDescription();
|
||||||
|
yaml.os_version = arg0.getOsVersion();
|
||||||
|
yaml.os_64bit = arg0.isOs64Bit();
|
||||||
|
yaml.group = arg0.getGroup();
|
||||||
|
yaml.tags = ImmutableList.copyOf(arg0.getTags());
|
||||||
|
yaml.username = arg0.getUsername();
|
||||||
|
yaml.credential = arg0.getCredential();
|
||||||
|
yaml.credential_url = arg0.getCredentialUrl() != null ? arg0.getCredentialUrl().toASCIIString() : null;
|
||||||
|
yaml.sudo_password = arg0.getSudoPassword();
|
||||||
|
return yaml;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -24,25 +24,32 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -50,16 +57,19 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||||
@Resource
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final Supplier<Location> location;
|
private final Supplier<Location> location;
|
||||||
|
private final Supplier<Set<? extends Location>> locations;
|
||||||
private final Map<String, Credentials> credentialStore;
|
private final Map<String, Credentials> credentialStore;
|
||||||
private final Function<URI, InputStream> slurp;
|
private final Function<URI, InputStream> slurp;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NodeToNodeMetadata(Supplier<Location> location, Function<URI, InputStream> slurp,
|
NodeToNodeMetadata(Supplier<Location> location, @Memoized Supplier<Set<? extends Location>> locations,
|
||||||
Map<String, Credentials> credentialStore) {
|
Function<URI, InputStream> slurp, Map<String, Credentials> credentialStore) {
|
||||||
this.location = checkNotNull(location, "location");
|
this.location = checkNotNull(location, "location");
|
||||||
|
this.locations = checkNotNull(locations, "locations");
|
||||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||||
this.slurp = checkNotNull(slurp, "slurp");
|
this.slurp = checkNotNull(slurp, "slurp");
|
||||||
}
|
}
|
||||||
|
@ -69,10 +79,10 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
builder.ids(from.getId());
|
builder.ids(from.getId());
|
||||||
builder.name(from.getName());
|
builder.name(from.getName());
|
||||||
builder.location(location.get());
|
builder.location(findLocationWithId(from.getLocationId()));
|
||||||
builder.group(from.getGroup());
|
builder.group(from.getGroup());
|
||||||
// TODO add tags!
|
builder.tags(from.getTags());
|
||||||
builder.operatingSystem(new OperatingSystemBuilder().arch(from.getOsArch()).family(
|
builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family(
|
||||||
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
|
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
|
||||||
.version(from.getOsVersion()).build());
|
.version(from.getOsVersion()).build());
|
||||||
builder.state(NodeState.RUNNING);
|
builder.state(NodeState.RUNNING);
|
||||||
|
@ -99,4 +109,24 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||||
builder.adminPassword(from.getSudoPassword());
|
builder.adminPassword(from.getSudoPassword());
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Location findLocationWithId(final String locationId) {
|
||||||
|
if (locationId == null)
|
||||||
|
return location.get();
|
||||||
|
try {
|
||||||
|
Location location = Iterables.find(locations.get(), new Predicate<Location>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Location input) {
|
||||||
|
return input.getId().equals(locationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return location;
|
||||||
|
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
|
||||||
|
return location.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,14 @@ import java.util.Map;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.byon.Node;
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.byon.domain.YamlNode;
|
||||||
import org.yaml.snakeyaml.Loader;
|
import org.yaml.snakeyaml.Loader;
|
||||||
import org.yaml.snakeyaml.TypeDescription;
|
import org.yaml.snakeyaml.TypeDescription;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +46,7 @@ import com.google.common.collect.Maps;
|
||||||
* name: cluster-1
|
* name: cluster-1
|
||||||
* description: xyz
|
* description: xyz
|
||||||
* hostname: cluster-1.mydomain.com
|
* hostname: cluster-1.mydomain.com
|
||||||
|
* location_id: virginia
|
||||||
* os_arch: x86
|
* os_arch: x86
|
||||||
* os_family: linux
|
* os_family: linux
|
||||||
* os_description: redhat
|
* os_description: redhat
|
||||||
|
@ -59,36 +62,39 @@ import com.google.common.collect.Maps;
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Kelvin Kakugawa
|
* @author Kelvin Kakugawa
|
||||||
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
public class NodesFromYamlStream implements Function<InputStream, Map<String, Node>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-safe config class for YAML
|
* Type-safe config class for YAML
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static class Config {
|
public static class Config {
|
||||||
public List<Node> nodes;
|
public List<YamlNode> nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Node> apply(InputStream source) {
|
public Map<String, Node> apply(InputStream source) {
|
||||||
|
|
||||||
Constructor constructor = new Constructor(Config.class);
|
Constructor constructor = new Constructor(Config.class);
|
||||||
|
|
||||||
TypeDescription nodeDesc = new TypeDescription(Node.class);
|
TypeDescription nodeDesc = new TypeDescription(YamlNode.class);
|
||||||
nodeDesc.putListPropertyType("tags", String.class);
|
nodeDesc.putListPropertyType("tags", String.class);
|
||||||
constructor.addTypeDescription(nodeDesc);
|
constructor.addTypeDescription(nodeDesc);
|
||||||
|
|
||||||
TypeDescription configDesc = new TypeDescription(Config.class);
|
TypeDescription configDesc = new TypeDescription(Config.class);
|
||||||
configDesc.putListPropertyType("nodes", Node.class);
|
configDesc.putListPropertyType("nodes", YamlNode.class);
|
||||||
constructor.addTypeDescription(configDesc);
|
constructor.addTypeDescription(configDesc);
|
||||||
|
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
|
||||||
|
// constructor
|
||||||
Yaml yaml = new Yaml(new Loader(constructor));
|
Yaml yaml = new Yaml(new Loader(constructor));
|
||||||
Config config = (Config) yaml.load(source);
|
Config config = (Config) yaml.load(source);
|
||||||
checkState(config != null, "missing config: class");
|
checkState(config != null, "missing config: class");
|
||||||
checkState(config.nodes != null, "missing nodes: collection");
|
checkState(config.nodes != null, "missing nodes: collection");
|
||||||
|
|
||||||
return Maps.uniqueIndex(config.nodes, new Function<Node, String>() {
|
return Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode), new Function<Node, String>() {
|
||||||
public String apply(Node node) {
|
public String apply(Node node) {
|
||||||
return node.getId();
|
return node.getId();
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ package org.jclouds.byon.internal;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -34,11 +35,16 @@ import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LocationBuilder;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.location.suppliers.JustProvider;
|
import org.jclouds.location.suppliers.JustProvider;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -59,8 +65,8 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template,
|
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name,
|
||||||
Map<String, Credentials> credentialStore) {
|
Template template, Map<String, Credentials> credentialStore) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +85,26 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
return Iterables.transform(nodes.get().values(), converter);
|
return Iterables.transform(nodes.get().values(), converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Location> listLocations() {
|
public Iterable<Location> listLocations() {
|
||||||
return (Iterable<Location>) locationSupplier.get();
|
Builder<Location> locations = ImmutableSet.builder();
|
||||||
|
Location provider = Iterables.getOnlyElement(locationSupplier.get());
|
||||||
|
Set<String> zones = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(nodes.get().values(),
|
||||||
|
new Function<Node, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(Node arg0) {
|
||||||
|
return arg0.getLocationId();
|
||||||
|
}
|
||||||
|
}), Predicates.notNull()));
|
||||||
|
if (zones.size() == 0)
|
||||||
|
return locations.add(provider).build();
|
||||||
|
else
|
||||||
|
for (String zone : zones) {
|
||||||
|
locations.add(new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(provider)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
return locations.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,16 +18,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.byon;
|
package org.jclouds.byon;
|
||||||
|
|
||||||
|
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedNodeMetadataFromResource;
|
||||||
|
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedProviderLocationFromResource;
|
||||||
|
import static org.jclouds.byon.functions.NodeToNodeMetadataTest.zoneCalled;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.byon.functions.NodeToNodeMetadataTest;
|
|
||||||
import org.jclouds.byon.functions.NodesFromYamlTest;
|
import org.jclouds.byon.functions.NodesFromYamlTest;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -56,6 +59,7 @@ public class BYONComputeServiceTest {
|
||||||
private void assertNodesParse(String endpoint) {
|
private void assertNodesParse(String endpoint) {
|
||||||
ComputeServiceContext context = null;
|
ComputeServiceContext context = null;
|
||||||
try {
|
try {
|
||||||
|
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("byon.endpoint", endpoint);
|
props.setProperty("byon.endpoint", endpoint);
|
||||||
|
@ -69,12 +73,45 @@ public class BYONComputeServiceTest {
|
||||||
.getApi();
|
.getApi();
|
||||||
|
|
||||||
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||||
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.id,
|
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST1.getId(),
|
||||||
NodesFromYamlTest.TEST1));
|
NodesFromYamlTest.TEST1));
|
||||||
|
|
||||||
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest
|
assertEquals(context.getComputeService().listNodes(), ImmutableSet
|
||||||
.expectedNodeMetadataFromResource(endpoint)));
|
.of(expectedNodeMetadataFromResource(endpoint)));
|
||||||
|
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(providerLocation));
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNodesWithLocations() {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
String endpoint = "file://" + getClass().getResource("/test_location.yaml").getPath();
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty("byon.endpoint", endpoint);
|
||||||
|
context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet
|
||||||
|
.<Module> of(new JschSshClientModule()), props);
|
||||||
|
|
||||||
|
assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint));
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Supplier<Map<String, Node>> supplier = (Supplier<Map<String, Node>>) context.getProviderSpecificContext()
|
||||||
|
.getApi();
|
||||||
|
|
||||||
|
assertEquals(supplier.get().size(), context.getComputeService().listNodes().size());
|
||||||
|
assertEquals(supplier.get(), ImmutableMap.<String, Node> of(NodesFromYamlTest.TEST2.getId(),
|
||||||
|
NodesFromYamlTest.TEST2, NodesFromYamlTest.TEST3.getId(), NodesFromYamlTest.TEST3));
|
||||||
|
Location providerLocation = expectedProviderLocationFromResource(endpoint);
|
||||||
|
|
||||||
|
Location virginia = zoneCalled("virginia", providerLocation);
|
||||||
|
Location maryland = zoneCalled("maryland", providerLocation);
|
||||||
|
|
||||||
|
assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(expectedNodeMetadataFromResource(1,
|
||||||
|
endpoint, virginia), expectedNodeMetadataFromResource(2, endpoint, maryland)));
|
||||||
|
|
||||||
|
assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(virginia, maryland));
|
||||||
} finally {
|
} finally {
|
||||||
if (context != null)
|
if (context != null)
|
||||||
context.close();
|
context.close();
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.byon.config;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.jclouds.byon.Node;
|
||||||
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
|
import org.jclouds.util.Strings2;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", singleThreaded = true)
|
||||||
|
public class YamlNodeStoreModuleTest {
|
||||||
|
Yaml json = createInjector().getInstance(Yaml.class);
|
||||||
|
|
||||||
|
@DataProvider(name = "names")
|
||||||
|
public Object[][] createData() {
|
||||||
|
return new Object[][] { { "instance1", "bear" }, { "instance2", "apple" }, { "instance2", "francis" },
|
||||||
|
{ "instance4", "robot" } };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "names")
|
||||||
|
public void deleteObject(String id, String name) throws InterruptedException, IOException {
|
||||||
|
Injector injector = createInjector();
|
||||||
|
Map<String, InputStream> map = getMap(injector);
|
||||||
|
check(map, getStore(injector), "i-20312", id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedMapWithValue() throws IOException {
|
||||||
|
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
|
||||||
|
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
|
||||||
|
|
||||||
|
map.put("test", new ByteArrayInputStream("id: instance1\nname: instancename\n".getBytes()));
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjectorWithProvidedMap(map)), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedConsistentAcrossRepeatedWrites() throws IOException {
|
||||||
|
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
|
||||||
|
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
|
||||||
|
|
||||||
|
Injector injector = createInjectorWithProvidedMap(map);
|
||||||
|
assertEquals(injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
|
})), map);
|
||||||
|
Map<String, Node> store = getStore(injector);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
check(map, store, "test" + i, "instance1" + i, "instancename" + i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testProvidedConsistentAcrossMultipleInjectors() throws IOException {
|
||||||
|
Map<String, InputStream> map = new CopyInputStreamInputSupplierMap(
|
||||||
|
new ConcurrentHashMap<String, InputSupplier<InputStream>>());
|
||||||
|
|
||||||
|
put(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjectorWithProvidedMap(map)), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjectorWithProvidedMap(map)), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDefaultConsistentAcrossMultipleInjectors() throws IOException {
|
||||||
|
Map<String, InputStream> map = getMap(createInjector());
|
||||||
|
|
||||||
|
put(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
|
checkConsistent(map, getStore(createInjector()), "test", "instance1", "instancename");
|
||||||
|
remove(map, getStore(createInjector()), "test");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Node> getStore(Injector injector) {
|
||||||
|
return injector.getInstance(Key.get(new TypeLiteral<Map<String, Node>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, InputStream> getMap(Injector injector) {
|
||||||
|
return injector.getInstance(Key.get(new TypeLiteral<Map<String, InputStream>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector createInjectorWithProvidedMap(Map<String, InputStream> map) {
|
||||||
|
return Guice.createInjector(new YamlNodeStoreModule(map));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector createInjector() {
|
||||||
|
return Guice.createInjector(new YamlNodeStoreModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void check(Map<String, InputStream> map, Map<String, Node> store, String key, String id, String name)
|
||||||
|
throws IOException {
|
||||||
|
put(map, store, key, id, name);
|
||||||
|
checkConsistent(map, store, key, id, name);
|
||||||
|
remove(map, store, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void remove(Map<String, InputStream> map, Map<String, Node> store, String key) {
|
||||||
|
store.remove(key);
|
||||||
|
assertEquals(store.size(), 0);
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
assertEquals(store.get(key), null);
|
||||||
|
assertEquals(map.get(key), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkConsistent(Map<String, InputStream> map, Map<String, Node> store, String key, String id,
|
||||||
|
String name) throws IOException {
|
||||||
|
assertEquals(store.size(), 1);
|
||||||
|
assertEquals(map.size(), 1);
|
||||||
|
// checkRepeatedRead
|
||||||
|
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
|
||||||
|
assertEquals(store.get(key), Node.builder().id(id).name(name).build());
|
||||||
|
// checkRepeatedRead
|
||||||
|
checkToYaml(map, key, id, name);
|
||||||
|
checkToYaml(map, key, id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkToYaml(Map<String, InputStream> map, String key, String id, String name) throws IOException {
|
||||||
|
assertEquals(Strings2.toStringAndClose(map.get(key)), String.format("id: %s\nname: %s\n", id, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void put(Map<String, InputStream> map, Map<String, Node> store, String key, String id, String name) {
|
||||||
|
assertEquals(store.size(), 0);
|
||||||
|
assertEquals(map.size(), 0);
|
||||||
|
store.put(key, Node.builder().id(id).name(name).build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,12 +22,13 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
@ -45,31 +46,51 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class NodeToNodeMetadataTest {
|
public class NodeToNodeMetadataTest {
|
||||||
public static Location expectedLocationFromResource(String resource) {
|
public static Location expectedProviderLocationFromResource(String resource) {
|
||||||
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
public static Location zoneCalled(String zone, Location parent) {
|
||||||
Location location = expectedLocationFromResource(resource);
|
return new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(parent).build();
|
||||||
|
}
|
||||||
|
|
||||||
return new NodeMetadataBuilder().ids("cluster-1").group("hadoop").name("cluster-1").location(location).state(
|
String resource = "location";
|
||||||
NodeState.RUNNING).operatingSystem(
|
|
||||||
new OperatingSystemBuilder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3")
|
Location provider = expectedProviderLocationFromResource(resource);
|
||||||
.build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials(
|
|
||||||
new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build();
|
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(provider), Suppliers
|
||||||
|
.<Set<? extends Location>> ofInstance(ImmutableSet.of(provider, zoneCalled("virginia", provider))),
|
||||||
|
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
||||||
|
|
||||||
|
public static NodeMetadata expectedNodeMetadataFromResource(String resource) {
|
||||||
|
return expectedNodeMetadataFromResource(resource, expectedProviderLocationFromResource(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeMetadata expectedNodeMetadataFromResource(String resource, Location location) {
|
||||||
|
return expectedNodeMetadataFromResource(1, resource, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location) {
|
||||||
|
return new NodeMetadataBuilder().ids("cluster-" + id).group("hadoop").name("cluster-" + id).location(location)
|
||||||
|
.state(NodeState.RUNNING).operatingSystem(
|
||||||
|
OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86")
|
||||||
|
.version("5.3").build()).publicAddresses(
|
||||||
|
ImmutableSet.of("cluster-" + id + ".mydomain.com")).credentials(
|
||||||
|
new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParse() throws Exception {
|
public void testNodesParse() throws Exception {
|
||||||
|
assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource(resource, provider));
|
||||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
NodeToNodeMetadata parser = new NodeToNodeMetadata(
|
|
||||||
Suppliers.ofInstance(expectedLocationFromResource("location")),
|
|
||||||
new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore);
|
|
||||||
|
|
||||||
assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource("location"));
|
|
||||||
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNodesParseLocation() throws Exception {
|
||||||
|
assertEquals(parser.apply(NodesFromYamlTest.TEST2), expectedNodeMetadataFromResource(resource, zoneCalled(
|
||||||
|
"virginia", provider)));
|
||||||
|
assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,29 +41,47 @@ public class NodesFromYamlTest {
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
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",
|
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, "hadoop", ImmutableList.of("vanilla"),
|
||||||
key, null, "happy bear");
|
"myUser", key, null, "happy bear");
|
||||||
|
|
||||||
|
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||||
|
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, "hadoop",
|
||||||
|
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||||
|
|
||||||
|
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
|
||||||
|
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, "hadoop",
|
||||||
|
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParse() throws Exception {
|
public void testNodesParse() throws Exception {
|
||||||
|
|
||||||
InputStream is = getClass().getResourceAsStream("/test1.yaml");
|
InputStream is = getClass().getResourceAsStream("/test1.yaml");
|
||||||
NodesFromYaml parser = new NodesFromYaml();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNodesParseLocation() throws Exception {
|
||||||
|
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
||||||
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
|
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParseWhenCredentialInUrl() throws Exception {
|
public void testNodesParseWhenCredentialInUrl() throws Exception {
|
||||||
|
|
||||||
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
|
InputStream is = getClass().getResourceAsStream("/test_with_url.yaml");
|
||||||
NodesFromYaml parser = new NodesFromYaml();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMustParseSomething() throws Exception {
|
public void testMustParseSomething() throws Exception {
|
||||||
new NodesFromYaml().apply(Strings2.toInputStream(""));
|
new NodesFromYamlStream().apply(Strings2.toInputStream(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.byon.suppliers;
|
package org.jclouds.byon.suppliers;
|
||||||
|
|
||||||
import org.jclouds.byon.functions.NodesFromYaml;
|
import org.jclouds.byon.functions.NodesFromYamlStream;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class NodesParsedFromSupplierTest {
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMustParseSomething() throws Exception {
|
public void testMustParseSomething() throws Exception {
|
||||||
|
|
||||||
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYaml()).get();
|
new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYamlStream()).get();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
nodes:
|
||||||
|
- id: cluster-1
|
||||||
|
name: cluster-1
|
||||||
|
description: accounting analytics cluster
|
||||||
|
hostname: cluster-1.mydomain.com
|
||||||
|
location_id: virginia
|
||||||
|
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
|
||||||
|
|
||||||
|
- id: cluster-2
|
||||||
|
name: cluster-2
|
||||||
|
description: accounting analytics cluster
|
||||||
|
hostname: cluster-2.mydomain.com
|
||||||
|
location_id: maryland
|
||||||
|
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
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<artifactId>cloudfiles</artifactId>
|
<artifactId>cloudfiles</artifactId>
|
||||||
<name>jcloud cloudfiles api</name>
|
<name>jcloud cloudfiles api</name>
|
||||||
<description>jclouds components to access an implementation of CloudFiles</description>
|
<description>jclouds components to access an implementation of CloudFiles</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
|
<test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
|
||||||
|
@ -145,6 +146,21 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.cloudfiles.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,12 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../../project/pom.xml</relativePath>
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.jclouds.api</groupId>
|
<groupId>org.jclouds.api</groupId>
|
||||||
<artifactId>cloudservers</artifactId>
|
<artifactId>cloudservers</artifactId>
|
||||||
<name>jcloud cloudservers api</name>
|
<name>jcloud cloudservers api</name>
|
||||||
<description>jclouds components to access an implementation of CloudServers</description>
|
<description>jclouds components to access an implementation of CloudServers</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.cloudservers.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers.endpoint>
|
<test.cloudservers.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers.endpoint>
|
||||||
|
@ -145,6 +147,21 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.cloudservers.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,11 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.cloudservers.domain.BackupSchedule;
|
import org.jclouds.cloudservers.domain.BackupSchedule;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
|
@ -37,17 +39,19 @@ import com.google.common.collect.ImmutableMap;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BindBackupScheduleToJsonPayload extends BindToJsonPayload {
|
public class BindBackupScheduleToJsonPayload extends BindToJsonPayload {
|
||||||
|
@Inject
|
||||||
|
public BindBackupScheduleToJsonPayload(Json jsonBinder) {
|
||||||
|
super(jsonBinder);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Replace Backup Schedule needs an BackupSchedule object, not a Map");
|
||||||
"Replace Backup Schedule needs an BackupSchedule object, not a Map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||||
checkArgument(toBind instanceof BackupSchedule,
|
checkArgument(toBind instanceof BackupSchedule, "this binder is only valid for BackupSchedules!");
|
||||||
"this binder is only valid for BackupSchedules!");
|
|
||||||
return super.bindToRequest(request, ImmutableMap.of("backupSchedule", toBind));
|
return super.bindToRequest(request, ImmutableMap.of("backupSchedule", toBind));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.cloudservers.domain.Addresses;
|
||||||
import org.jclouds.encryption.internal.Base64;
|
import org.jclouds.encryption.internal.Base64;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.cloudservers.domain.Addresses;
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -40,7 +43,9 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateServerOptions extends BindToJsonPayload {
|
public class CreateServerOptions implements MapBinder {
|
||||||
|
@Inject
|
||||||
|
private BindToJsonPayload jsonBinder;
|
||||||
|
|
||||||
static class File {
|
static class File {
|
||||||
private final String path;
|
private final String path;
|
||||||
|
@ -50,11 +55,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
this.path = checkNotNull(path, "path");
|
this.path = checkNotNull(path, "path");
|
||||||
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
||||||
checkArgument(path.getBytes().length < 255, String.format(
|
checkArgument(path.getBytes().length < 255, String.format(
|
||||||
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
|
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path.getBytes().length));
|
||||||
.getBytes().length));
|
|
||||||
checkArgument(contents.length < 10 * 1024, String.format(
|
checkArgument(contents.length < 10 * 1024, String.format(
|
||||||
"maximum size of the file is 10KB. Contents specified is %d bytes",
|
"maximum size of the file is 10KB. Contents specified is %d bytes", contents.length));
|
||||||
contents.length));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContents() {
|
public String getContents() {
|
||||||
|
@ -92,10 +95,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
|
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"), "name parameter not present"),
|
||||||
"name parameter not present"), Integer.parseInt(checkNotNull(postParams
|
Integer.parseInt(checkNotNull(postParams.get("imageId"), "imageId parameter not present")), Integer
|
||||||
.get("imageId"), "imageId parameter not present")), Integer.parseInt(checkNotNull(
|
.parseInt(checkNotNull(postParams.get("flavorId"), "flavorId parameter not present")));
|
||||||
postParams.get("flavorId"), "flavorId parameter not present")));
|
|
||||||
if (metadata.size() > 0)
|
if (metadata.size() > 0)
|
||||||
server.metadata = metadata;
|
server.metadata = metadata;
|
||||||
if (files.size() > 0)
|
if (files.size() > 0)
|
||||||
|
@ -162,19 +164,15 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
*/
|
*/
|
||||||
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
||||||
checkNotNull(metadata, "metadata");
|
checkNotNull(metadata, "metadata");
|
||||||
checkArgument(metadata.size() <= 5,
|
checkArgument(metadata.size() <= 5, "you cannot have more then 5 metadata values. You specified: "
|
||||||
"you cannot have more then 5 metadata values. You specified: " + metadata.size());
|
+ metadata.size());
|
||||||
for (Entry<String, String> entry : metadata.entrySet()) {
|
for (Entry<String, String> entry : metadata.entrySet()) {
|
||||||
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
||||||
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes",
|
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes", entry.getKey(), entry
|
||||||
entry.getKey(), entry.getKey().getBytes().length));
|
.getKey().getBytes().length));
|
||||||
checkArgument(
|
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
||||||
entry.getKey().getBytes().length < 255,
|
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes", entry
|
||||||
String
|
.getKey(), entry.getValue(), entry.getValue().getBytes().length));
|
||||||
.format(
|
|
||||||
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes",
|
|
||||||
entry.getKey(), entry.getValue(),
|
|
||||||
entry.getValue().getBytes().length));
|
|
||||||
}
|
}
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
|
@ -196,8 +194,7 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
* sharedIpGroupId is also supplied.
|
* sharedIpGroupId is also supplied.
|
||||||
*/
|
*/
|
||||||
public CreateServerOptions withSharedIp(String publicIp) {
|
public CreateServerOptions withSharedIp(String publicIp) {
|
||||||
checkState(sharedIpGroupId != null,
|
checkState(sharedIpGroupId != null, "sharedIp is invalid unless a shared ip group is specified.");
|
||||||
"sharedIp is invalid unless a shared ip group is specified.");
|
|
||||||
this.publicIp = checkNotNull(publicIp, "ip");
|
this.publicIp = checkNotNull(publicIp, "ip");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -237,4 +234,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||||
|
return jsonBinder.bindToRequest(request, input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -36,7 +38,10 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateSharedIpGroupOptions extends BindToJsonPayload {
|
public class CreateSharedIpGroupOptions implements MapBinder {
|
||||||
|
@Inject
|
||||||
|
private BindToJsonPayload jsonBinder;
|
||||||
|
|
||||||
Integer serverId;
|
Integer serverId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -53,9 +58,8 @@ public class CreateSharedIpGroupOptions extends BindToJsonPayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
SharedIpGroupRequest createRequest = new SharedIpGroupRequest(checkNotNull(postParams
|
SharedIpGroupRequest createRequest = new SharedIpGroupRequest(checkNotNull(postParams.get("name")), serverId);
|
||||||
.get("name")), serverId);
|
return jsonBinder.bindToRequest(request, ImmutableMap.of("sharedIpGroup", createRequest));
|
||||||
return super.bindToRequest(request, ImmutableMap.of("sharedIpGroup", createRequest));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,4 +88,5 @@ public class CreateSharedIpGroupOptions extends BindToJsonPayload {
|
||||||
return options.withServer(id);
|
return options.withServer(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,10 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -34,7 +37,9 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RebuildServerOptions extends BindToJsonPayload {
|
public class RebuildServerOptions implements MapBinder {
|
||||||
|
@Inject
|
||||||
|
private BindToJsonPayload jsonBinder;
|
||||||
Integer imageId;
|
Integer imageId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,7 +47,7 @@ public class RebuildServerOptions extends BindToJsonPayload {
|
||||||
Map<String, Integer> image = Maps.newHashMap();
|
Map<String, Integer> image = Maps.newHashMap();
|
||||||
if (imageId != null)
|
if (imageId != null)
|
||||||
image.put("imageId", imageId);
|
image.put("imageId", imageId);
|
||||||
return super.bindToRequest(request, ImmutableMap.of("rebuild", image));
|
return jsonBinder.bindToRequest(request, ImmutableMap.of("rebuild", image));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<artifactId>deltacloud</artifactId>
|
<artifactId>deltacloud</artifactId>
|
||||||
<name>jclouds deltacloud core</name>
|
<name>jclouds deltacloud core</name>
|
||||||
<description>jclouds components to access deltacloud</description>
|
<description>jclouds components to access deltacloud</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<!-- bootstrapping: need to fetch the project POM -->
|
<!-- bootstrapping: need to fetch the project POM -->
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -141,4 +142,21 @@
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.deltacloud.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -25,6 +25,9 @@ import static org.easymock.classextension.EasyMock.verify;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpCommand;
|
import org.jclouds.http.HttpCommand;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
@ -32,7 +35,12 @@ import org.jclouds.rest.BaseRestClientTest.MockModule;
|
||||||
import org.jclouds.rest.config.RestModule;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.LinkedHashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code DeltacloudRedirectionRetry}
|
* Tests behavior of {@code DeltacloudRedirectionRetry}
|
||||||
|
@ -41,6 +49,19 @@ import com.google.inject.Guice;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit")
|
@Test(groups = "unit")
|
||||||
public class DeltacloudRedirectionRetryHandlerTest {
|
public class DeltacloudRedirectionRetryHandlerTest {
|
||||||
|
Injector injector = Guice.createInjector(new MockModule(), new RestModule(), new AbstractModule() {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("CONSTANTS")
|
||||||
|
protected Multimap<String, String> constants() {
|
||||||
|
return LinkedHashMultimap.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test302DoesNotRetryOnDelete() {
|
public void test302DoesNotRetryOnDelete() {
|
||||||
|
@ -53,7 +74,7 @@ public class DeltacloudRedirectionRetryHandlerTest {
|
||||||
|
|
||||||
replay(command);
|
replay(command);
|
||||||
|
|
||||||
DeltacloudRedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
DeltacloudRedirectionRetryHandler retry = injector.getInstance(
|
||||||
DeltacloudRedirectionRetryHandler.class);
|
DeltacloudRedirectionRetryHandler.class);
|
||||||
|
|
||||||
assert !retry.shouldRetryRequest(command, response);
|
assert !retry.shouldRetryRequest(command, response);
|
||||||
|
@ -74,7 +95,7 @@ public class DeltacloudRedirectionRetryHandlerTest {
|
||||||
|
|
||||||
replay(command);
|
replay(command);
|
||||||
|
|
||||||
DeltacloudRedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
DeltacloudRedirectionRetryHandler retry = injector.getInstance(
|
||||||
DeltacloudRedirectionRetryHandler.class);
|
DeltacloudRedirectionRetryHandler.class);
|
||||||
|
|
||||||
assert !retry.shouldRetryRequest(command, response);
|
assert !retry.shouldRetryRequest(command, response);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<artifactId>ec2</artifactId>
|
<artifactId>ec2</artifactId>
|
||||||
<name>jcloud ec2 api</name>
|
<name>jcloud ec2 api</name>
|
||||||
<description>jclouds components to access an implementation of EC2</description>
|
<description>jclouds components to access an implementation of EC2</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- when instances are hung, open a ticket and add here -->
|
<!-- when instances are hung, open a ticket and add here -->
|
||||||
|
@ -142,6 +143,21 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.ec2.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -25,20 +25,20 @@
|
||||||
(:use (clojure.contrib def core))
|
(:use (clojure.contrib def core))
|
||||||
(:import org.jclouds.aws.domain.Region
|
(:import org.jclouds.aws.domain.Region
|
||||||
org.jclouds.compute.domain.NodeMetadata
|
org.jclouds.compute.domain.NodeMetadata
|
||||||
(org.jclouds.aws.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZone)
|
(org.jclouds.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZoneInfo)
|
||||||
(org.jclouds.aws.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions)))
|
(org.jclouds.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions)))
|
||||||
|
|
||||||
(defn snapshot?
|
(defn snapshot?
|
||||||
"Returns true iff the argument is a org.jclouds.aws.ec2.domain.Snapshot."
|
"Returns true iff the argument is a org.jclouds.ec2.domain.Snapshot."
|
||||||
[s]
|
[s]
|
||||||
(instance? Snapshot s))
|
(instance? Snapshot s))
|
||||||
|
|
||||||
(defn volume?
|
(defn volume?
|
||||||
"Returns true iff the argument is a org.jclouds.aws.ec2.domain.Volume."
|
"Returns true iff the argument is a org.jclouds.ec2.domain.Volume."
|
||||||
[v]
|
[v]
|
||||||
(instance? Volume v))
|
(instance? Volume v))
|
||||||
|
|
||||||
(defn #^org.jclouds.aws.ec2.services.ElasticBlockStoreClient
|
(defn #^org.jclouds.ec2.services.ElasticBlockStoreClient
|
||||||
ebs-service
|
ebs-service
|
||||||
"Returns the synchronous ElasticBlockStoreClient associated with
|
"Returns the synchronous ElasticBlockStoreClient associated with
|
||||||
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
(str "Can't obtain volume id from argument of type " (class v))))))
|
(str "Can't obtain volume id from argument of type " (class v))))))
|
||||||
|
|
||||||
(defn volumes
|
(defn volumes
|
||||||
"Returns a set of org.jclouds.aws.ec2.domain.Volume instances corresponding to the
|
"Returns a set of org.jclouds.ec2.domain.Volume instances corresponding to the
|
||||||
volumes in the specified region (defaulting to your account's default region).
|
volumes in the specified region (defaulting to your account's default region).
|
||||||
|
|
||||||
e.g. (with-compute-service [compute] (volumes))
|
e.g. (with-compute-service [compute] (volumes))
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
(defn get-zone
|
(defn get-zone
|
||||||
[v]
|
[v]
|
||||||
(cond
|
(cond
|
||||||
(instance? AvailabilityZone v) v
|
(instance? AvailabilityZoneInfo v) (.getZone v)
|
||||||
(instance? NodeMetadata v) (compute/location #^NodeMetadata v)
|
(instance? NodeMetadata v) (compute/location #^NodeMetadata v)
|
||||||
(string? v) v
|
(string? v) v
|
||||||
(keyword? v) (name v)
|
(keyword? v) (name v)
|
||||||
|
@ -225,14 +225,14 @@
|
||||||
(defn create-volume
|
(defn create-volume
|
||||||
"Creates a new volume given a set of options:
|
"Creates a new volume given a set of options:
|
||||||
|
|
||||||
- one of :zone (keyword, string, or AvailabilityZone) or :node (NodeMetadata)
|
- one of :zone (keyword, string, or AvailabilityZoneInfo) or :node (NodeMetadata)
|
||||||
- one or both of :snapshot (keyword, string, or Snapshot instance) or :size
|
- one or both of :snapshot (keyword, string, or Snapshot instance) or :size
|
||||||
(string, keyword, or number)
|
(string, keyword, or number)
|
||||||
- :device (string or keyword) provided *only* when you want to attach the new volume to
|
- :device (string or keyword) provided *only* when you want to attach the new volume to
|
||||||
the :node you specified!
|
the :node you specified!
|
||||||
|
|
||||||
Returns a vector of [created org.jclouds.aws.ec2.domain.Volume,
|
Returns a vector of [created org.jclouds.ec2.domain.Volume,
|
||||||
optional org.jclouds.aws.ec2.domain.Attachment]
|
optional org.jclouds.ec2.domain.Attachment]
|
||||||
|
|
||||||
Note that specifying :node instead of :zone will only attach the created volume
|
Note that specifying :node instead of :zone will only attach the created volume
|
||||||
:device is also provided. Otherwise, the node is only used to obtain the desired
|
:device is also provided. Otherwise, the node is only used to obtain the desired
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
:doc "A clojure binding for the jclouds AWS elastic IP address interface."}
|
:doc "A clojure binding for the jclouds AWS elastic IP address interface."}
|
||||||
org.jclouds.ec2.elastic-ip
|
org.jclouds.ec2.elastic-ip
|
||||||
(:require (org.jclouds [compute :as compute])
|
(:require (org.jclouds [compute :as compute])
|
||||||
[org.jclouds.aws.ebs :as ebs])
|
[org.jclouds.ec2.ebs :as ebs])
|
||||||
(:use (clojure.contrib def core))
|
(:use (clojure.contrib def core))
|
||||||
(:import org.jclouds.compute.domain.NodeMetadata
|
(:import org.jclouds.compute.domain.NodeMetadata
|
||||||
(org.jclouds.aws.ec2.domain PublicIpInstanceIdPair)))
|
(org.jclouds.ec2.domain PublicIpInstanceIdPair)))
|
||||||
|
|
||||||
(defn #^org.jclouds.aws.ec2.services.ElasticIPAddressClient
|
(defn #^org.jclouds.ec2.services.ElasticIPAddressClient
|
||||||
eip-service
|
eip-service
|
||||||
"Returns the synchronous ElasticIPAddressClient associated with
|
"Returns the synchronous ElasticIPAddressClient associated with
|
||||||
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
||||||
|
|
|
@ -37,11 +37,13 @@ import org.jclouds.Constants;
|
||||||
import org.jclouds.aws.util.AWSUtils;
|
import org.jclouds.aws.util.AWSUtils;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.internal.BaseComputeService;
|
import org.jclouds.compute.internal.BaseComputeService;
|
||||||
|
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||||
|
@ -60,6 +62,7 @@ import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -89,13 +92,16 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
|
||||||
|
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||||
|
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
||||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
||||||
initScriptRunnerFactory, timeouts, executor);
|
initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts,
|
||||||
|
executor);
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.credentialsMap = credentialsMap;
|
this.credentialsMap = credentialsMap;
|
||||||
this.securityGroupMap = securityGroupMap;
|
this.securityGroupMap = securityGroupMap;
|
||||||
|
@ -125,7 +131,8 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
// when the keypair is unique per group
|
// when the keypair is unique per group
|
||||||
keyPair.getKeyName().equals("jclouds#" + group)
|
keyPair.getKeyName().equals("jclouds#" + group)
|
||||||
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s", group, "[0-9a-f]+"))
|
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s", group, "[0-9a-f]+"))
|
||||||
// old keypair pattern too verbose as it has an unnecessary region qualifier
|
// old keypair pattern too verbose as it has an unnecessary
|
||||||
|
// region qualifier
|
||||||
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) {
|
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) {
|
||||||
Set<String> instancesUsingKeyPair = extractIdsFromInstances(filter(concat(ec2Client.getInstanceServices()
|
Set<String> instancesUsingKeyPair = extractIdsFromInstances(filter(concat(ec2Client.getInstanceServices()
|
||||||
.describeInstancesInRegion(region)), usingKeyPairAndNotDead(keyPair)));
|
.describeInstancesInRegion(region)), usingKeyPairAndNotDead(keyPair)));
|
||||||
|
@ -170,8 +177,8 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* like {@link BaseComputeService#destroyNodesMatching} except that this will clean implicit
|
* like {@link BaseComputeService#destroyNodesMatching} except that this will
|
||||||
* keypairs and security groups.
|
* clean implicit keypairs and security groups.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class Volume implements Comparable<Volume> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Status {
|
public static enum Status {
|
||||||
CREATING, AVAILABLE, IN_USE, DELETING, UNRECOGNIZED;
|
CREATING, AVAILABLE, IN_USE, DELETING, ERROR, UNRECOGNIZED;
|
||||||
public String value() {
|
public String value() {
|
||||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
|
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<artifactId>elasticstack</artifactId>
|
<artifactId>elasticstack</artifactId>
|
||||||
<name>jclouds elasticstack core</name>
|
<name>jclouds elasticstack core</name>
|
||||||
<description>jclouds components to access elasticstack</description>
|
<description>jclouds components to access elasticstack</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<!-- bootstrapping: need to fetch the project POM -->
|
<!-- bootstrapping: need to fetch the project POM -->
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -147,4 +148,20 @@
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.elasticstack.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<artifactId>eucalyptus</artifactId>
|
<artifactId>eucalyptus</artifactId>
|
||||||
<name>jclouds Eucalyptus api</name>
|
<name>jclouds Eucalyptus api</name>
|
||||||
<description>EC2 implementation based on Eucalyptus</description>
|
<description>EC2 implementation based on Eucalyptus</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.eucalyptus.endpoint>http://ecc.eucalyptus.com:8773/services/Eucalyptus</test.eucalyptus.endpoint>
|
<test.eucalyptus.endpoint>http://ecc.eucalyptus.com:8773/services/Eucalyptus</test.eucalyptus.endpoint>
|
||||||
|
@ -136,6 +137,21 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.eucalyptus.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<artifactId>filesystem</artifactId>
|
<artifactId>filesystem</artifactId>
|
||||||
<name>jcloud filesystem core</name>
|
<name>jcloud filesystem core</name>
|
||||||
<description>jclouds components to access filesystem</description>
|
<description>jclouds components to access filesystem</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -72,5 +73,21 @@
|
||||||
<test.initializer>org.jclouds.filesystem.integration.FilesystemTestInitializer</test.initializer>
|
<test.initializer>org.jclouds.filesystem.integration.FilesystemTestInitializer</test.initializer>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.filesystem.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
|
||||||
====================================================================
|
====================================================================
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
<artifactId>nova</artifactId>
|
<artifactId>nova</artifactId>
|
||||||
<name>jcloud nova api</name>
|
<name>jcloud nova api</name>
|
||||||
<description>jclouds components to access an implementation of OpenStack Nova</description>
|
<description>jclouds components to access an implementation of OpenStack Nova</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
||||||
|
@ -96,22 +97,6 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>process-remote-resources</id>
|
|
||||||
<!-- plugin is tuned off due to incorrect work in Eclipse-->
|
|
||||||
<phase></phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>live</id>
|
<id>live</id>
|
||||||
|
@ -175,5 +160,20 @@
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.openstack.nova.*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jclouds.openstack.nova;
|
package org.jclouds.openstack.nova;
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import org.jclouds.PropertiesBuilder;
|
|
@ -1,3 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.openstack.nova.domain;
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
|
@ -1,3 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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.openstack.nova.domain;
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
|
@ -26,8 +26,11 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.Base64;
|
import org.jclouds.encryption.internal.Base64;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -39,7 +42,9 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateServerOptions extends BindToJsonPayload {
|
public class CreateServerOptions implements MapBinder {
|
||||||
|
@Inject
|
||||||
|
private BindToJsonPayload jsonBinder;
|
||||||
|
|
||||||
static class File {
|
static class File {
|
||||||
private final String path;
|
private final String path;
|
||||||
|
@ -49,11 +54,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
this.path = checkNotNull(path, "path");
|
this.path = checkNotNull(path, "path");
|
||||||
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
||||||
checkArgument(path.getBytes().length < 255, String.format(
|
checkArgument(path.getBytes().length < 255, String.format(
|
||||||
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
|
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path.getBytes().length));
|
||||||
.getBytes().length));
|
|
||||||
checkArgument(contents.length < 10 * 1024, String.format(
|
checkArgument(contents.length < 10 * 1024, String.format(
|
||||||
"maximum size of the file is 10KB. Contents specified is %d bytes",
|
"maximum size of the file is 10KB. Contents specified is %d bytes", contents.length));
|
||||||
contents.length));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContents() {
|
public String getContents() {
|
||||||
|
@ -87,10 +90,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
|
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"), "name parameter not present"),
|
||||||
"name parameter not present"), checkNotNull(postParams
|
checkNotNull(postParams.get("imageRef"), "imageRef parameter not present"), checkNotNull(postParams
|
||||||
.get("imageRef"), "imageRef parameter not present"), checkNotNull(
|
.get("flavorRef"), "flavorRef parameter not present"));
|
||||||
postParams.get("flavorRef"), "flavorRef parameter not present"));
|
|
||||||
if (metadata.size() > 0)
|
if (metadata.size() > 0)
|
||||||
server.metadata = metadata;
|
server.metadata = metadata;
|
||||||
if (files.size() > 0)
|
if (files.size() > 0)
|
||||||
|
@ -128,19 +130,15 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
*/
|
*/
|
||||||
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
||||||
checkNotNull(metadata, "metadata");
|
checkNotNull(metadata, "metadata");
|
||||||
checkArgument(metadata.size() <= 5,
|
checkArgument(metadata.size() <= 5, "you cannot have more then 5 metadata values. You specified: "
|
||||||
"you cannot have more then 5 metadata values. You specified: " + metadata.size());
|
+ metadata.size());
|
||||||
for (Entry<String, String> entry : metadata.entrySet()) {
|
for (Entry<String, String> entry : metadata.entrySet()) {
|
||||||
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
||||||
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes",
|
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes", entry.getKey(), entry
|
||||||
entry.getKey(), entry.getKey().getBytes().length));
|
.getKey().getBytes().length));
|
||||||
checkArgument(
|
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
||||||
entry.getKey().getBytes().length < 255,
|
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes", entry
|
||||||
String
|
.getKey(), entry.getValue(), entry.getValue().getBytes().length));
|
||||||
.format(
|
|
||||||
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes",
|
|
||||||
entry.getKey(), entry.getValue(),
|
|
||||||
entry.getValue().getBytes().length));
|
|
||||||
}
|
}
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
|
@ -164,4 +162,9 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
return options.withMetadata(metadata);
|
return options.withMetadata(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||||
|
return jsonBinder.bindToRequest(request, input);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,7 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -35,7 +38,9 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RebuildServerOptions extends BindToJsonPayload {
|
public class RebuildServerOptions implements MapBinder {
|
||||||
|
@Inject
|
||||||
|
private BindToJsonPayload jsonBinder;
|
||||||
String imageRef;
|
String imageRef;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,7 +48,7 @@ public class RebuildServerOptions extends BindToJsonPayload {
|
||||||
Map<String, String> image = Maps.newHashMap();
|
Map<String, String> image = Maps.newHashMap();
|
||||||
if (imageRef != null)
|
if (imageRef != null)
|
||||||
image.put("imageRef", imageRef);
|
image.put("imageRef", imageRef);
|
||||||
return super.bindToRequest(request, ImmutableMap.of("rebuild", image));
|
return jsonBinder.bindToRequest(request, ImmutableMap.of("rebuild", image));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +57,8 @@ public class RebuildServerOptions extends BindToJsonPayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ref - reference of the image to rebuild the server with.
|
* @param ref
|
||||||
|
* - reference of the image to rebuild the server with.
|
||||||
*/
|
*/
|
||||||
public RebuildServerOptions withImage(String ref) {
|
public RebuildServerOptions withImage(String ref) {
|
||||||
checkNotNull(ref, "image reference should not be null");
|
checkNotNull(ref, "image reference should not be null");
|
|
@ -66,7 +66,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||||
@Test(groups = "unit", testName = "NovaAsyncClientTest")
|
@Test(groups = "unit", singleThreaded = true, testName = "NovaAsyncClientTest")
|
||||||
public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
||||||
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[]{}.getClass();
|
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[]{}.getClass();
|
||||||
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[]{}
|
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[]{}
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jclouds.openstack.nova.domain;
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jclouds.openstack.nova.functions;
|
package org.jclouds.openstack.nova.functions;
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jclouds.openstack.nova.live.compute;
|
package org.jclouds.openstack.nova.live.compute;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue