JCLOUDS-1025: Add support for metadata and tags in the ComputeService

This commit is contained in:
Ignasi Barrera 2015-10-23 00:18:45 +02:00
parent 200e0e12ba
commit 4596471bb2
5 changed files with 55 additions and 6 deletions

View File

@ -27,7 +27,10 @@ import static com.google.common.collect.Sets.newHashSet;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -48,6 +51,7 @@ import org.jclouds.digitalocean2.domain.Region;
import org.jclouds.digitalocean2.domain.Size; import org.jclouds.digitalocean2.domain.Size;
import org.jclouds.digitalocean2.domain.options.CreateDropletOptions; import org.jclouds.digitalocean2.domain.options.CreateDropletOptions;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -67,15 +71,18 @@ public class DigitalOcean2ComputeServiceAdapter implements ComputeServiceAdapter
private final Predicate<Integer> nodeRunningPredicate; private final Predicate<Integer> nodeRunningPredicate;
private final Predicate<Integer> nodeStoppedPredicate; private final Predicate<Integer> nodeStoppedPredicate;
private final Predicate<Integer> nodeTerminatedPredicate; private final Predicate<Integer> nodeTerminatedPredicate;
private final Json json;
@Inject DigitalOcean2ComputeServiceAdapter(DigitalOcean2Api api, @Inject DigitalOcean2ComputeServiceAdapter(DigitalOcean2Api api,
@Named(TIMEOUT_NODE_RUNNING) Predicate<Integer> nodeRunningPredicate, @Named(TIMEOUT_NODE_RUNNING) Predicate<Integer> nodeRunningPredicate,
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<Integer> nodeStoppedPredicate, @Named(TIMEOUT_NODE_SUSPENDED) Predicate<Integer> nodeStoppedPredicate,
@Named(TIMEOUT_NODE_TERMINATED) Predicate<Integer> nodeTerminatedPredicate) { @Named(TIMEOUT_NODE_TERMINATED) Predicate<Integer> nodeTerminatedPredicate,
Json json) {
this.api = api; this.api = api;
this.nodeRunningPredicate = nodeRunningPredicate; this.nodeRunningPredicate = nodeRunningPredicate;
this.nodeStoppedPredicate = nodeStoppedPredicate; this.nodeStoppedPredicate = nodeStoppedPredicate;
this.nodeTerminatedPredicate = nodeTerminatedPredicate; this.nodeTerminatedPredicate = nodeTerminatedPredicate;
this.json = json;
} }
@Override @Override
@ -91,6 +98,18 @@ public class DigitalOcean2ComputeServiceAdapter implements ComputeServiceAdapter
options.addSshKeyIds(templateOptions.getSshKeyIds()); options.addSshKeyIds(templateOptions.getSshKeyIds());
} }
Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(templateOptions);
if (!metadataAndTags.isEmpty()) {
@SuppressWarnings("unchecked")
List<String> regionFeatures = (List<String>) template.getLocation().getMetadata().get("features");
if (regionFeatures.contains("metadata")) {
options.userData(json.toJson(metadataAndTags));
} else {
logger.debug(">> region %s does not support metadata, ignoring provided user data", template.getLocation()
.getId());
}
}
DropletCreate dropletCreated = api.dropletApi().create(name, DropletCreate dropletCreated = api.dropletApi().create(name,
template.getLocation().getId(), template.getLocation().getId(),
template.getHardware().getProviderId(), template.getHardware().getProviderId(),

View File

@ -29,6 +29,7 @@ import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.all.JustProvider; import org.jclouds.location.suppliers.all.JustProvider;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -52,6 +53,7 @@ public class RegionToLocation implements Function<Region, Location> {
builder.scope(LocationScope.REGION); builder.scope(LocationScope.REGION);
builder.parent(getOnlyElement(justProvider.get())); builder.parent(getOnlyElement(justProvider.get()));
builder.iso3166Codes(ImmutableSet.<String> of()); builder.iso3166Codes(ImmutableSet.<String> of());
builder.metadata(ImmutableMap.<String, Object> of("available", input.available(), "features", input.features()));
return builder.build(); return builder.build();
} }
} }

View File

@ -104,6 +104,14 @@ public class CreateDropletOptions implements MapBinder {
return backupsEnabled; return backupsEnabled;
} }
public boolean isIpv6Enabled() {
return ipv6Enabled;
}
public String getUserData() {
return userData;
}
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
@ -148,6 +156,22 @@ public class CreateDropletOptions implements MapBinder {
return this; return this;
} }
/**
* Sets the user data for the droplet.
*/
public Builder userData(String userData) {
this.userData = userData;
return this;
}
/**
* Enables/disables IPv6 for the droplet.
*/
public Builder ipv6Enabled(boolean ipv6Enabled) {
this.ipv6Enabled = ipv6Enabled;
return this;
}
public CreateDropletOptions build() { public CreateDropletOptions build() {
return new CreateDropletOptions(sshKeyIds.build(), backupsEnabled, ipv6Enabled, privateNetworking, userData); return new CreateDropletOptions(sshKeyIds.build(), backupsEnabled, ipv6Enabled, privateNetworking, userData);
} }

View File

@ -47,12 +47,12 @@ public class DigitalOcean2ComputeServiceLiveTest extends BaseComputeServiceLiveT
@Override @Override
protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet<String> tags) { protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet<String> tags) {
// DigitalOcean does not support tags // We encode the tags in the user data but the DigitalOcean API does not return it
} }
@Override @Override
protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) { protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
// DigitalOcean does not support user metadata // The DigitalOcean API does not return the user data
} }
} }

View File

@ -42,11 +42,15 @@ public class RegionToLocationTest {
JustProvider locationsSupplier = new JustProvider(metadata.getId(), Suppliers.<URI> ofInstance(URI JustProvider locationsSupplier = new JustProvider(metadata.getId(), Suppliers.<URI> ofInstance(URI
.create(metadata.getEndpoint())), ImmutableSet.<String> of()); .create(metadata.getEndpoint())), ImmutableSet.<String> of());
Region region = Region.create("reg1", "Region1", ImmutableList.<String> of(), true, ImmutableList.<String> of()); Region region = Region.create("reg1", "Region1", ImmutableList.<String> of(), true,
ImmutableList.<String> of("virtio", "metadata"));
Location expected = new LocationBuilder().id("reg1").description("reg1/Region 1") Location expected = new LocationBuilder().id("reg1").description("reg1/Region 1")
.parent(getOnlyElement(locationsSupplier.get())).scope(LocationScope.REGION).build(); .parent(getOnlyElement(locationsSupplier.get())).scope(LocationScope.REGION).build();
RegionToLocation function = new RegionToLocation(locationsSupplier); Location location = new RegionToLocation(locationsSupplier).apply(region);
assertEquals(function.apply(region), expected);
assertEquals(location, expected);
assertEquals(location.getMetadata().get("available"), true);
assertEquals(location.getMetadata().get("features"), ImmutableList.of("virtio", "metadata"));
} }
} }