mirror of https://github.com/apache/jclouds.git
Issue 561:add location_id to byon provider
This commit is contained in:
parent
99d4e3472c
commit
533045edd7
|
@ -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
|
||||||
|
|
|
@ -20,60 +20,162 @@ 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 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 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,
|
||||||
|
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, 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.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 String group;
|
||||||
public List<String> tags;
|
private final Set<String> tags;
|
||||||
public String username;
|
private final String username;
|
||||||
public String credential;
|
private final String credential;
|
||||||
public String credential_url;
|
private final URI credentialUrl;
|
||||||
public String sudo_password;
|
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 +193,19 @@ 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 Set<String> getTags() {
|
public Set<String> getTags() {
|
||||||
|
@ -122,7 +224,7 @@ public class Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getCredentialUrl() {
|
public URI getCredentialUrl() {
|
||||||
return credential_url != null ? URI.create(credential_url) : null;
|
return credentialUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,7 +233,7 @@ public class Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSudoPassword() {
|
public String getSudoPassword() {
|
||||||
return sudo_password;
|
return sudoPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,10 +246,10 @@ 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("group", group).add("tags", tags).add(
|
||||||
username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword",
|
"username", username).add("hasCredential", credential != null || credentialUrl != null).add(
|
||||||
sudo_password != null).toString();
|
"hasSudoPassword", sudoPassword != null).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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!
|
// TODO add tags!
|
||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ 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;
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ 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.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +47,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,6 +63,7 @@ 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 NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
||||||
|
@ -68,27 +73,65 @@ public class NodesFromYaml implements Function<InputStream, Map<String, Node>> {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static class Config {
|
public static class Config {
|
||||||
public List<Node> nodes;
|
public List<CrappyNode> 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
|
||||||
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(CrappyNode.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", CrappyNode.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, new Function<CrappyNode, Node>() {
|
||||||
|
|
||||||
|
@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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(
|
|
||||||
|
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();
|
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,8 +41,16 @@ 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", "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", "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", "hadoop",
|
||||||
|
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParse() throws Exception {
|
public void testNodesParse() throws Exception {
|
||||||
|
@ -53,6 +61,15 @@ public class NodesFromYamlTest {
|
||||||
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");
|
||||||
|
NodesFromYaml parser = new NodesFromYaml();
|
||||||
|
|
||||||
|
assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesParseWhenCredentialInUrl() throws Exception {
|
public void testNodesParseWhenCredentialInUrl() throws Exception {
|
||||||
|
|
||||||
|
@ -66,4 +83,5 @@ public class NodesFromYamlTest {
|
||||||
public void testMustParseSomething() throws Exception {
|
public void testMustParseSomething() throws Exception {
|
||||||
new NodesFromYaml().apply(Strings2.toInputStream(""));
|
new NodesFromYaml().apply(Strings2.toInputStream(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue