mirror of https://github.com/apache/jclouds.git
added tags to nodemetadata, revised byon to be persistable to blobstore
This commit is contained in:
parent
ddc514d602
commit
08ee5d5c8d
|
@ -44,6 +44,7 @@ public class Node {
|
||||||
private String osFamily;
|
private String osFamily;
|
||||||
private String osDescription;
|
private String osDescription;
|
||||||
private String osVersion;
|
private String osVersion;
|
||||||
|
private boolean os64Bit;
|
||||||
private String group;
|
private String group;
|
||||||
private Set<String> tags = ImmutableSet.of();
|
private Set<String> tags = ImmutableSet.of();
|
||||||
private String username;
|
private String username;
|
||||||
|
@ -96,6 +97,11 @@ public class Node {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder os64Bit(boolean os64Bit) {
|
||||||
|
this.os64Bit = os64Bit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder group(String group) {
|
public Builder group(String group) {
|
||||||
this.group = group;
|
this.group = group;
|
||||||
return this;
|
return this;
|
||||||
|
@ -128,13 +134,13 @@ public class Node {
|
||||||
|
|
||||||
public Node build() {
|
public Node build() {
|
||||||
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
|
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
|
||||||
group, tags, username, credential, credentialUrl, sudoPassword);
|
os64Bit, group, tags, username, credential, credentialUrl, sudoPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node(String id, String name, String description, String hostname, String locationId, String osArch,
|
public Node(String id, String name, String description, String hostname, String locationId, String osArch,
|
||||||
String osFamily, String osDescription, String osVersion, String group, Iterable<String> tags,
|
String osFamily, String osDescription, String osVersion, boolean os64Bit, String group,
|
||||||
String username, String credential, URI credentialUrl, String sudoPassword) {
|
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;
|
||||||
|
@ -144,6 +150,7 @@ public class Node {
|
||||||
this.osFamily = osFamily;
|
this.osFamily = osFamily;
|
||||||
this.osDescription = osDescription;
|
this.osDescription = osDescription;
|
||||||
this.osVersion = osVersion;
|
this.osVersion = osVersion;
|
||||||
|
this.os64Bit = os64Bit;
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.tags = ImmutableSet.copyOf(tags);
|
this.tags = ImmutableSet.copyOf(tags);
|
||||||
this.username = username;
|
this.username = username;
|
||||||
|
@ -161,6 +168,7 @@ public class Node {
|
||||||
private final String osFamily;
|
private final String osFamily;
|
||||||
private final String osDescription;
|
private final String osDescription;
|
||||||
private final String osVersion;
|
private final String osVersion;
|
||||||
|
private final boolean os64Bit;
|
||||||
private final String group;
|
private final String group;
|
||||||
private final Set<String> tags;
|
private final Set<String> tags;
|
||||||
private final String username;
|
private final String username;
|
||||||
|
@ -208,6 +216,10 @@ public class Node {
|
||||||
return osVersion;
|
return osVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOs64Bit() {
|
||||||
|
return os64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
public Set<String> getTags() {
|
public Set<String> getTags() {
|
||||||
Set<String> tagSet = new HashSet<String>();
|
Set<String> tagSet = new HashSet<String>();
|
||||||
for (String tag : tags)
|
for (String tag : tags)
|
||||||
|
@ -227,15 +239,15 @@ public class Node {
|
||||||
return credentialUrl;
|
return credentialUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSudoPassword() {
|
||||||
|
return sudoPassword;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(id);
|
return Objects.hashCode(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSudoPassword() {
|
|
||||||
return sudoPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object that) {
|
public boolean equals(Object that) {
|
||||||
if (that == null)
|
if (that == null)
|
||||||
|
@ -247,9 +259,10 @@ public class Node {
|
||||||
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(
|
||||||
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
|
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
|
||||||
"osDescription", osDescription).add("osVersion", osVersion).add("group", group).add("tags", tags).add(
|
"osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit).add("group", group)
|
||||||
"username", username).add("hasCredential", credential != null || credentialUrl != null).add(
|
.add("tags", tags).add("username", username).add("hasCredential",
|
||||||
"hasSudoPassword", sudoPassword != 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;
|
||||||
|
@ -72,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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -81,7 +81,7 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
||||||
builder.name(from.getName());
|
builder.name(from.getName());
|
||||||
builder.location(findLocationWithId(from.getLocationId()));
|
builder.location(findLocationWithId(from.getLocationId()));
|
||||||
builder.group(from.getGroup());
|
builder.group(from.getGroup());
|
||||||
// TODO add tags!
|
builder.tags(from.getTags());
|
||||||
builder.operatingSystem(OperatingSystem.builder().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());
|
||||||
|
|
|
@ -21,13 +21,13 @@ package org.jclouds.byon.functions;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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;
|
||||||
|
@ -35,7 +35,6 @@ 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.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,38 +65,14 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @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<CrappyNode> nodes;
|
public List<YamlNode> nodes;
|
||||||
}
|
|
||||||
|
|
||||||
// crappy, as snakeyaml..
|
|
||||||
// 1. complains on illegalaccesserror for extends Constructor.ConstructMapping, so we can't use a
|
|
||||||
// real constructor
|
|
||||||
// 2. cannot set non-public fields, or fill non-public classes
|
|
||||||
// 3. doesn't support a SerializedName annotation, so your fields need to be named the same as
|
|
||||||
// the text
|
|
||||||
public static class CrappyNode {
|
|
||||||
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 String group;
|
|
||||||
public List<String> tags = Lists.newArrayList();
|
|
||||||
public String username;
|
|
||||||
public String credential;
|
|
||||||
public String credential_url;
|
|
||||||
public String sudo_password;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,12 +80,12 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
||||||
|
|
||||||
Constructor constructor = new Constructor(Config.class);
|
Constructor constructor = new Constructor(Config.class);
|
||||||
|
|
||||||
TypeDescription nodeDesc = new TypeDescription(CrappyNode.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", CrappyNode.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
|
// note that snakeyaml also throws nosuchmethod error when you use the non-deprecated
|
||||||
// constructor
|
// constructor
|
||||||
|
@ -119,19 +94,7 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
||||||
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(Iterables.transform(config.nodes, new Function<CrappyNode, Node>() {
|
return Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode), new Function<Node, String>() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node apply(CrappyNode arg0) {
|
|
||||||
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).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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}), new Function<Node, String>() {
|
|
||||||
public String apply(Node node) {
|
public String apply(Node node) {
|
||||||
return node.getId();
|
return node.getId();
|
||||||
}
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,22 +41,22 @@ 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", null, "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"),
|
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, "hadoop", ImmutableList.of("vanilla"),
|
||||||
"myUser", key, null, "happy bear");
|
"myUser", key, null, "happy bear");
|
||||||
|
|
||||||
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||||
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", "hadoop",
|
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, "hadoop",
|
||||||
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||||
|
|
||||||
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
|
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
|
||||||
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", "hadoop",
|
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, "hadoop",
|
||||||
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
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));
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class NodesFromYamlTest {
|
||||||
public void testNodesParseLocation() throws Exception {
|
public void testNodesParseLocation() throws Exception {
|
||||||
|
|
||||||
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
InputStream is = getClass().getResourceAsStream("/test_location.yaml");
|
||||||
NodesFromYaml parser = new NodesFromYaml();
|
NodesFromYamlStream parser = new NodesFromYamlStream();
|
||||||
|
|
||||||
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
||||||
}
|
}
|
||||||
|
@ -74,14 +74,14 @@ public class NodesFromYamlTest {
|
||||||
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();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[]{}
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.compute.domain;
|
package org.jclouds.compute.domain;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||||
import org.jclouds.domain.ResourceMetadata;
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
|
|
||||||
|
@ -30,24 +34,23 @@ import com.google.inject.ImplementedBy;
|
||||||
@ImplementedBy(ComputeMetadataImpl.class)
|
@ImplementedBy(ComputeMetadataImpl.class)
|
||||||
public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
|
public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
|
||||||
/**
|
/**
|
||||||
* Type of the resource, ex node, image, size
|
* @return Type of the resource, ex node, image, size
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ComputeType getType();
|
public ComputeType getType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* id of the server within the naming scope it was created. potentially generated by the service.
|
* @return id of the server within the naming scope it was created. potentially generated by the
|
||||||
*
|
* service.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getProviderId();
|
public String getProviderId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* user defined name of the server.
|
* @return user defined name of the server.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +59,12 @@ public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
|
||||||
* a node or image is region based, the id will likely include both the region and the
|
* a node or image is region based, the id will likely include both the region and the
|
||||||
* provider-supplied id encoded to avoid collisions.
|
* provider-supplied id encoded to avoid collisions.
|
||||||
*
|
*
|
||||||
|
* @return unique id within your account on the provider
|
||||||
*/
|
*/
|
||||||
public String getId();
|
public String getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return tags describing this resource, if supported
|
||||||
|
*/
|
||||||
|
public Set<String> getTags();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.ResourceMetadataBuilder;
|
import org.jclouds.domain.ResourceMetadataBuilder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -34,9 +37,9 @@ import org.jclouds.domain.ResourceMetadataBuilder;
|
||||||
public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType> {
|
public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType> {
|
||||||
protected String id;
|
protected String id;
|
||||||
protected ComputeType type;
|
protected ComputeType type;
|
||||||
|
protected Set<String> tags = ImmutableSet.<String>of();
|
||||||
|
|
||||||
public ComputeMetadataBuilder(ComputeType type) {
|
public ComputeMetadataBuilder(ComputeType type) {
|
||||||
super();
|
|
||||||
this.type = checkNotNull(type, "type");
|
this.type = checkNotNull(type, "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +48,11 @@ public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType>
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ComputeMetadataBuilder tags(Set<String> tags) {
|
||||||
|
this.tags = ImmutableSet.<String> copyOf(checkNotNull(tags, "tags"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set id and providerId to the same value;
|
* set id and providerId to the same value;
|
||||||
*/
|
*/
|
||||||
|
@ -79,11 +87,11 @@ public class ComputeMetadataBuilder extends ResourceMetadataBuilder<ComputeType>
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputeMetadata build() {
|
public ComputeMetadata build() {
|
||||||
return new ComputeMetadataImpl(type, providerId, name, id, location, uri, userMetadata);
|
return new ComputeMetadataImpl(type, providerId, name, id, location, uri, userMetadata, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ComputeMetadataBuilder fromComputeMetadata(ComputeMetadata in) {
|
public static ComputeMetadataBuilder fromComputeMetadata(ComputeMetadata in) {
|
||||||
return new ComputeMetadataBuilder(in.getType()).id(in.getId()).location(in.getLocation()).name(in.getName())
|
return new ComputeMetadataBuilder(in.getType()).id(in.getId()).location(in.getLocation()).name(in.getName())
|
||||||
.uri(in.getUri()).userMetadata(in.getUserMetadata());
|
.uri(in.getUri()).userMetadata(in.getUserMetadata()).tags(in.getTags());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@ import static org.jclouds.compute.predicates.ImagePredicates.any;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.internal.HardwareImpl;
|
import org.jclouds.compute.domain.internal.HardwareImpl;
|
||||||
import org.jclouds.compute.predicates.ImagePredicates;
|
import org.jclouds.compute.predicates.ImagePredicates;
|
||||||
|
@ -88,6 +89,11 @@ public class HardwareBuilder extends ComputeMetadataBuilder {
|
||||||
return HardwareBuilder.class.cast(super.id(id));
|
return HardwareBuilder.class.cast(super.id(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HardwareBuilder tags(Set<String> tags) {
|
||||||
|
return HardwareBuilder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HardwareBuilder ids(String id) {
|
public HardwareBuilder ids(String id) {
|
||||||
return HardwareBuilder.class.cast(super.ids(id));
|
return HardwareBuilder.class.cast(super.ids(id));
|
||||||
|
@ -120,14 +126,14 @@ public class HardwareBuilder extends ComputeMetadataBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Hardware build() {
|
public Hardware build() {
|
||||||
return new HardwareImpl(providerId, name, id, location, uri, userMetadata, processors, ram, volumes,
|
return new HardwareImpl(providerId, name, id, location, uri, userMetadata, tags, processors, ram, volumes,
|
||||||
supportsImage);
|
supportsImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static HardwareBuilder fromHardware(Hardware in) {
|
public static HardwareBuilder fromHardware(Hardware in) {
|
||||||
return new HardwareBuilder().id(in.getId()).providerId(in.getProviderId()).location(in.getLocation()).name(
|
return new HardwareBuilder().id(in.getId()).providerId(in.getProviderId()).location(in.getLocation()).name(
|
||||||
in.getName()).uri(in.getUri()).userMetadata(in.getUserMetadata()).processors(
|
in.getName()).uri(in.getUri()).userMetadata(in.getUserMetadata()).tags(in.getTags()).processors(
|
||||||
List.class.cast(in.getProcessors())).ram(in.getRam()).volumes(List.class.cast(in.getVolumes()))
|
List.class.cast(in.getProcessors())).ram(in.getRam()).volumes(List.class.cast(in.getVolumes()))
|
||||||
.supportsImage(in.supportsImage());
|
.supportsImage(in.supportsImage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -74,6 +75,10 @@ public class ImageBuilder extends ComputeMetadataBuilder {
|
||||||
return ImageBuilder.class.cast(super.id(id));
|
return ImageBuilder.class.cast(super.id(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImageBuilder tags(Set<String> tags) {
|
||||||
|
return ImageBuilder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageBuilder ids(String id) {
|
public ImageBuilder ids(String id) {
|
||||||
return ImageBuilder.class.cast(super.ids(id));
|
return ImageBuilder.class.cast(super.ids(id));
|
||||||
|
@ -106,13 +111,13 @@ public class ImageBuilder extends ComputeMetadataBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Image build() {
|
public Image build() {
|
||||||
return new ImageImpl(providerId, name, id, location, uri, userMetadata, operatingSystem, description, version,
|
return new ImageImpl(providerId, name, id, location, uri, userMetadata, tags, operatingSystem, description, version,
|
||||||
adminPassword, defaultCredentials);
|
adminPassword, defaultCredentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageBuilder fromImage(Image image) {
|
public static ImageBuilder fromImage(Image image) {
|
||||||
return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()).location(
|
return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()).location(
|
||||||
image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).version(
|
image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).tags(image.getTags()).version(
|
||||||
image.getVersion()).description(image.getDescription()).operatingSystem(image.getOperatingSystem())
|
image.getVersion()).description(image.getDescription()).operatingSystem(image.getOperatingSystem())
|
||||||
.adminPassword(image.getAdminPassword()).defaultCredentials(image.getDefaultCredentials());
|
.adminPassword(image.getAdminPassword()).defaultCredentials(image.getDefaultCredentials());
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
||||||
return NodeMetadataBuilder.class.cast(super.id(id));
|
return NodeMetadataBuilder.class.cast(super.id(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadataBuilder tags(Set<String> tags) {
|
||||||
|
return NodeMetadataBuilder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadataBuilder ids(String id) {
|
public NodeMetadataBuilder ids(String id) {
|
||||||
return NodeMetadataBuilder.class.cast(super.ids(id));
|
return NodeMetadataBuilder.class.cast(super.ids(id));
|
||||||
|
@ -145,17 +150,17 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata build() {
|
public NodeMetadata build() {
|
||||||
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, group, hardware, imageId, os, state,
|
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tags, group, hardware, imageId,
|
||||||
loginPort, publicAddresses, privateAddresses, adminPassword, credentials);
|
os, state, loginPort, publicAddresses, privateAddresses, adminPassword, credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) {
|
public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) {
|
||||||
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
|
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
|
||||||
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).group(node.getGroup()).hardware(
|
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tags(node.getTags()).group(
|
||||||
node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()).state(
|
node.getGroup()).hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem(
|
||||||
node.getState()).loginPort(node.getLoginPort()).publicAddresses(node.getPublicAddresses())
|
node.getOperatingSystem()).state(node.getState()).loginPort(node.getLoginPort()).publicAddresses(
|
||||||
.privateAddresses(node.getPrivateAddresses()).adminPassword(node.getAdminPassword()).credentials(
|
node.getPublicAddresses()).privateAddresses(node.getPrivateAddresses()).adminPassword(
|
||||||
node.getCredentials());
|
node.getAdminPassword()).credentials(node.getCredentials());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,12 +22,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.ComputeType;
|
import org.jclouds.compute.domain.ComputeType;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.internal.ResourceMetadataImpl;
|
import org.jclouds.domain.internal.ResourceMetadataImpl;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @author Ivan Meredith
|
* @author Ivan Meredith
|
||||||
|
@ -37,12 +40,14 @@ public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> imple
|
||||||
private static final long serialVersionUID = 7374704415964898694L;
|
private static final long serialVersionUID = 7374704415964898694L;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final ComputeType type;
|
private final ComputeType type;
|
||||||
|
protected final Set<String> tags;
|
||||||
|
|
||||||
public ComputeMetadataImpl(ComputeType type, String providerId, String name, String id, Location location, URI uri,
|
public ComputeMetadataImpl(ComputeType type, String providerId, String name, String id, Location location, URI uri,
|
||||||
Map<String, String> userMetadata) {
|
Map<String, String> userMetadata, Set<String> tags) {
|
||||||
super(providerId, name, location, uri, userMetadata);
|
super(providerId, name, location, uri, userMetadata);
|
||||||
this.id = checkNotNull(id, "id");
|
this.id = checkNotNull(id, "id");
|
||||||
this.type = checkNotNull(type, "type");
|
this.type = checkNotNull(type, "type");
|
||||||
|
this.tags = ImmutableSet.<String> copyOf(checkNotNull(tags, "tags"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,6 +66,14 @@ public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> imple
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getSpace;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -53,9 +54,9 @@ public class HardwareImpl extends ComputeMetadataImpl implements Hardware {
|
||||||
private final Predicate<Image> supportsImage;
|
private final Predicate<Image> supportsImage;
|
||||||
|
|
||||||
public HardwareImpl(String providerId, String name, String id, @Nullable Location location, URI uri,
|
public HardwareImpl(String providerId, String name, String id, @Nullable Location location, URI uri,
|
||||||
Map<String, String> userMetadata, Iterable<? extends Processor> processors, int ram,
|
Map<String, String> userMetadata, Set<String> tags, Iterable<? extends Processor> processors, int ram,
|
||||||
Iterable<? extends Volume> volumes, Predicate<Image> supportsImage) {
|
Iterable<? extends Volume> volumes, Predicate<Image> supportsImage) {
|
||||||
super(ComputeType.HARDWARE, providerId, name, id, location, uri, userMetadata);
|
super(ComputeType.HARDWARE, providerId, name, id, location, uri, userMetadata, tags);
|
||||||
this.processors = ImmutableList.copyOf(checkNotNull(processors, "processors"));
|
this.processors = ImmutableList.copyOf(checkNotNull(processors, "processors"));
|
||||||
this.ram = ram;
|
this.ram = ram;
|
||||||
this.volumes = ImmutableList.copyOf(checkNotNull(volumes, "volumes"));
|
this.volumes = ImmutableList.copyOf(checkNotNull(volumes, "volumes"));
|
||||||
|
@ -106,7 +107,7 @@ public class HardwareImpl extends ComputeMetadataImpl implements Hardware {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[id=" + getId() + ", providerId=" + getProviderId() + ", name=" + getName() + ", processors="
|
return "[id=" + getId() + ", providerId=" + getProviderId() + ", name=" + getName() + ", processors="
|
||||||
+ processors + ", ram=" + ram + ", volumes=" + volumes + ", supportsImage=" + supportsImage + "]";
|
+ processors + ", ram=" + ram + ", volumes=" + volumes + ", supportsImage=" + supportsImage + ", tags=" + tags + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -47,9 +48,9 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
private final Credentials defaultCredentials;
|
private final Credentials defaultCredentials;
|
||||||
|
|
||||||
public ImageImpl(String providerId, String name, String id, Location location, URI uri,
|
public ImageImpl(String providerId, String name, String id, Location location, URI uri,
|
||||||
Map<String, String> userMetadata, OperatingSystem operatingSystem, String description,
|
Map<String, String> userMetadata, Set<String> tags, OperatingSystem operatingSystem, String description,
|
||||||
@Nullable String version, @Nullable String adminPassword, @Nullable Credentials defaultCredentials) {
|
@Nullable String version, @Nullable String adminPassword, @Nullable Credentials defaultCredentials) {
|
||||||
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata);
|
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata, tags);
|
||||||
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
|
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.description = checkNotNull(description, "description");
|
this.description = checkNotNull(description, "description");
|
||||||
|
@ -102,7 +103,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description="
|
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description="
|
||||||
+ description + ", version=" + version + ", location=" + getLocation() + ", loginUser="
|
+ description + ", version=" + version + ", location=" + getLocation() + ", loginUser="
|
||||||
+ ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata="
|
+ ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata="
|
||||||
+ getUserMetadata() + "]";
|
+ getUserMetadata() + ", tags=" + tags + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -63,11 +63,11 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
private final OperatingSystem os;
|
private final OperatingSystem os;
|
||||||
|
|
||||||
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
|
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
|
||||||
Map<String, String> userMetadata, @Nullable String group, @Nullable Hardware hardware,
|
Map<String, String> userMetadata, Set<String> tags, @Nullable String group, @Nullable Hardware hardware,
|
||||||
@Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort,
|
@Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort,
|
||||||
Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable String adminPassword,
|
Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable String adminPassword,
|
||||||
@Nullable Credentials credentials) {
|
@Nullable Credentials credentials) {
|
||||||
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
|
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata, tags);
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.hardware = hardware;
|
this.hardware = hardware;
|
||||||
this.imageId = imageId;
|
this.imageId = imageId;
|
||||||
|
@ -175,7 +175,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
+ getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort()
|
+ getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort()
|
||||||
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware="
|
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware="
|
||||||
+ getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
|
+ getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
|
||||||
+ ", userMetadata=" + getUserMetadata() + "]";
|
+ ", userMetadata=" + getUserMetadata() + ", tags=" + tags + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
|
@ -31,6 +32,7 @@ import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
|
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
|
||||||
|
@ -70,6 +72,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
||||||
to.blockOnPort(this.getPort(), this.getSeconds());
|
to.blockOnPort(this.getPort(), this.getSeconds());
|
||||||
if (this.isIncludeMetadata())
|
if (this.isIncludeMetadata())
|
||||||
to.withMetadata();
|
to.withMetadata();
|
||||||
|
if (this.getTags().size() > 0)
|
||||||
|
to.tags(getTags());
|
||||||
if (!this.shouldBlockUntilRunning())
|
if (!this.shouldBlockUntilRunning())
|
||||||
to.blockUntilRunning(false);
|
to.blockUntilRunning(false);
|
||||||
if (!this.shouldBlockOnComplete())
|
if (!this.shouldBlockOnComplete())
|
||||||
|
@ -276,6 +280,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
||||||
|
|
||||||
protected Statement script;
|
protected Statement script;
|
||||||
|
|
||||||
|
protected Set<String> tags = ImmutableSet.of();
|
||||||
|
|
||||||
protected String privateKey;
|
protected String privateKey;
|
||||||
|
|
||||||
protected String publicKey;
|
protected String publicKey;
|
||||||
|
@ -292,6 +298,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
public String getPrivateKey() {
|
public String getPrivateKey() {
|
||||||
return privateKey;
|
return privateKey;
|
||||||
}
|
}
|
||||||
|
@ -403,6 +413,14 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* assigns tags to the created nodes
|
||||||
|
*/
|
||||||
|
public TemplateOptions tags(Iterable<String> tags) {
|
||||||
|
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the set of ports to public access.
|
* Opens the set of ports to public access.
|
||||||
*/
|
*/
|
||||||
|
@ -461,6 +479,14 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
||||||
return options.inboundPorts(ports);
|
return options.inboundPorts(ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TemplateOptions#tags
|
||||||
|
*/
|
||||||
|
public static TemplateOptions tags(Iterable<String> tags) {
|
||||||
|
TemplateOptions options = new TemplateOptions();
|
||||||
|
return options.tags(tags);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see TemplateOptions#blockUntilRunning
|
* @see TemplateOptions#blockUntilRunning
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,8 +45,9 @@ import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.ImmutableList.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -85,6 +86,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
String id = idProvider.get() + "";
|
String id = idProvider.get() + "";
|
||||||
builder.ids(id);
|
builder.ids(id);
|
||||||
builder.name(name);
|
builder.name(name);
|
||||||
|
builder.tags(template.getOptions().getTags());
|
||||||
builder.group(group);
|
builder.group(group);
|
||||||
builder.location(location.get());
|
builder.location(location.get());
|
||||||
builder.imageId(template.getImage().getId());
|
builder.imageId(template.getImage().getId());
|
||||||
|
@ -110,18 +112,19 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Image> listImages() {
|
public Iterable<Image> listImages() {
|
||||||
Credentials defaultCredentials = new Credentials("root", null);
|
Credentials defaultCredentials = new Credentials("root", null);
|
||||||
Set<Image> images = Sets.newLinkedHashSet();
|
// initializing as a List, as ImmutableSet does not allow you to put duplicates
|
||||||
|
Builder<Image> images = ImmutableList.<Image>builder();
|
||||||
int id = 1;
|
int id = 1;
|
||||||
for (boolean is64Bit : new boolean[] { true, false })
|
for (boolean is64Bit : new boolean[] { true, false })
|
||||||
for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) {
|
for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) {
|
||||||
for (String version : Sets.newLinkedHashSet(osVersions.getValue().values())) {
|
for (String version : ImmutableSet.copyOf(osVersions.getValue().values())) {
|
||||||
String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit);
|
String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit);
|
||||||
images.add(new ImageBuilder().ids(id++ + "").name(osVersions.getKey().name()).location(location.get())
|
images.add(new ImageBuilder().ids(id++ + "").name(osVersions.getKey().name()).location(location.get())
|
||||||
.operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit))
|
.operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit))
|
||||||
.description(desc).defaultCredentials(defaultCredentials).build());
|
.description(desc).defaultCredentials(defaultCredentials).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return images;
|
return images.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.io;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.collect.InputSupplierMap;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class CopyInputStreamInputSupplierMap extends InputSupplierMap<String, InputStream> {
|
||||||
|
@Inject
|
||||||
|
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap,
|
||||||
|
CopyInputStreamIntoSupplier putFunction) {
|
||||||
|
super(toMap, putFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap) {
|
||||||
|
super(toMap, new CopyInputStreamIntoSupplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.io;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.common.io.Closeables;
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class CopyInputStreamIntoSupplier implements Function<InputStream, InputSupplier<InputStream>> {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public InputSupplier<InputStream> apply(InputStream from) {
|
||||||
|
if (from == null)
|
||||||
|
return new InputSupplier<InputStream>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInput() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn(e, "ignoring problem retrieving credentials");
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
Closeables.closeQuietly(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ package org.jclouds.rest.config;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -29,9 +28,9 @@ import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.InputSupplierMap;
|
|
||||||
import org.jclouds.collect.TransformingMap;
|
import org.jclouds.collect.TransformingMap;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.ConfiguresCredentialStore;
|
import org.jclouds.rest.ConfiguresCredentialStore;
|
||||||
|
@ -39,8 +38,6 @@ import org.jclouds.util.Strings2;
|
||||||
|
|
||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.common.io.Closeables;
|
|
||||||
import com.google.common.io.InputSupplier;
|
import com.google.common.io.InputSupplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -97,48 +94,6 @@ public class CredentialStoreModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public static class CopyInputStreamInputSupplierMap extends InputSupplierMap<String, InputStream> {
|
|
||||||
@Singleton
|
|
||||||
public static class CopyInputStreamIntoSupplier implements Function<InputStream, InputSupplier<InputStream>> {
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public InputSupplier<InputStream> apply(InputStream from) {
|
|
||||||
if (from == null)
|
|
||||||
return new InputSupplier<InputStream>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInput() throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn(e, "ignoring problem retrieving credentials");
|
|
||||||
return null;
|
|
||||||
} finally {
|
|
||||||
Closeables.closeQuietly(from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap,
|
|
||||||
CopyInputStreamIntoSupplier putFunction) {
|
|
||||||
super(toMap, putFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyInputStreamInputSupplierMap(Map<String, InputSupplier<InputStream>> toMap) {
|
|
||||||
super(toMap, new CopyInputStreamIntoSupplier());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CredentialsFromJsonInputStream implements Function<InputStream, Credentials> {
|
public static class CredentialsFromJsonInputStream implements Function<InputStream, Credentials> {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -28,10 +28,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.jclouds.crypto.PemsTest;
|
import org.jclouds.crypto.PemsTest;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.rest.config.CredentialStoreModule;
|
import org.jclouds.rest.config.CredentialStoreModule;
|
||||||
import org.jclouds.rest.config.CredentialStoreModule.CopyInputStreamInputSupplierMap;
|
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -46,7 +46,7 @@ import com.google.inject.TypeLiteral;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", sequential = true)
|
@Test(groups = "unit", singleThreaded = true)
|
||||||
public class CredentialStoreModuleTest {
|
public class CredentialStoreModuleTest {
|
||||||
Json json = createInjector().getInstance(Json.class);
|
Json json = createInjector().getInstance(Json.class);
|
||||||
|
|
||||||
|
|
|
@ -125,11 +125,11 @@ public class AWSEC2ImageParserTest {
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new Gson().toJson(Iterables.get(result, 1)),
|
new Gson().toJson(Iterables.get(result, 1)),
|
||||||
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new Gson().toJson(Iterables.get(result, 2)),
|
new Gson().toJson(Iterables.get(result, 2)),
|
||||||
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseAmznImage() {
|
public void testParseAmznImage() {
|
||||||
|
|
Loading…
Reference in New Issue