You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2014/10/22 21:40:11 UTC
[5/5] git commit: JCLOUDS-756 - Adding tags/userMetadata to
NodeMetadata transform
JCLOUDS-756 - Adding tags/userMetadata to NodeMetadata transform
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/c8545350
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/c8545350
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/c8545350
Branch: refs/heads/master
Commit: c85453503ec8cb6704a6f047559f90c638e993b4
Parents: 43bb86f
Author: Andrew Bayer <an...@gmail.com>
Authored: Wed Oct 22 10:09:09 2014 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Wed Oct 22 10:09:09 2014 -0700
----------------------------------------------------------------------
.../functions/VirtualMachineToNodeMetadata.java | 43 +++++++-----
.../CloudStackComputeServiceAdapter.java | 69 +++++++++++++-------
.../CloudStackComputeServiceLiveTest.java | 12 +---
.../VirtualMachineToNodeMetadataTest.java | 12 +++-
.../parse/ListVirtualMachinesResponseTest.java | 22 ++++++-
.../resources/listvirtualmachinesresponse.json | 67 ++++++++++++++++++-
6 files changed, 173 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadata.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadata.java
index cb78ece..c234f9c 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadata.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadata.java
@@ -17,20 +17,33 @@
package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.equalTo;
+import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Maps.filterValues;
import static com.google.common.collect.Sets.newHashSet;
import static org.jclouds.location.predicates.LocationPredicates.idEquals;
import static org.jclouds.util.InetAddresses2.isPrivateIPAddress;
-import java.util.Map;
-import java.util.Set;
-
import javax.inject.Inject;
import javax.inject.Singleton;
+import java.util.Map;
+import java.util.Set;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.NIC;
+import org.jclouds.cloudstack.domain.Tag;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.HardwareBuilder;
@@ -44,17 +57,6 @@ import org.jclouds.domain.Location;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Throwables2;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Throwables;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-
@Singleton
public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> {
@@ -119,10 +121,21 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
builder.operatingSystem(image.getOperatingSystem());
}
+ if (!from.getTags().isEmpty()) {
+ ImmutableMap.Builder<String, String> tagsBuilder = ImmutableMap.<String, String>builder();
+
+ for (Tag tag : from.getTags()) {
+ tagsBuilder.put(tag.getKey(), tag.getValue());
+ }
+
+ Map<String, String> tagMap = tagsBuilder.build();
+ builder.tags(filterValues(tagMap, equalTo("jclouds-empty-tag-placeholder")).keySet())
+ .userMetadata(filterValues(tagMap, not(equalTo("jclouds-empty-tag-placeholder"))));
+ }
+
builder.hardware(new HardwareBuilder()
.ids(from.getServiceOfferingId() + "")
.name(from.getServiceOfferingName() + "")
- // .tags() TODO
.processors(ImmutableList.of(new Processor(from.getCpuCount(), from.getCpuSpeed())))
.ram((int)from.getMemory())//
.hypervisor(from.getHypervisor())//
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
index 29f5c85..e723f7f 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
@@ -28,15 +28,22 @@ import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady;
import static org.jclouds.cloudstack.predicates.ZonePredicates.supportsSecurityGroups;
import static org.jclouds.ssh.SshKeys.fingerprintPrivateKey;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.Sets;
+import com.google.common.primitives.Ints;
import org.jclouds.cloudstack.CloudStackApi;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
@@ -50,6 +57,7 @@ import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.SshKeyPair;
+import org.jclouds.cloudstack.domain.Tag;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone;
@@ -60,26 +68,20 @@ import org.jclouds.cloudstack.functions.CreateFirewallRulesForIP;
import org.jclouds.cloudstack.functions.CreatePortForwardingRulesForIP;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork.Factory;
+import org.jclouds.cloudstack.options.CreateTagsOptions;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.config.GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-import com.google.common.collect.Sets;
-import com.google.common.primitives.Ints;
-
/**
* defines the connection between the {@link CloudStackApi} implementation
* and the jclouds {@link ComputeService}
@@ -107,6 +109,7 @@ public class CloudStackComputeServiceAdapter implements
private final LoadingCache<ZoneAndName, SecurityGroup> securityGroupCache;
private final LoadingCache<String, SshKeyPair> keyPairCache;
private final GroupNamingConvention.Factory namingConvention;
+ private final GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull credentialsProvider;
@Inject
public CloudStackComputeServiceAdapter(CloudStackApi client, Predicate<String> jobComplete,
@@ -122,7 +125,8 @@ public class CloudStackComputeServiceAdapter implements
Supplier<LoadingCache<String, Zone>> zoneIdToZone,
LoadingCache<ZoneAndName, SecurityGroup> securityGroupCache,
LoadingCache<String, SshKeyPair> keyPairCache,
- GroupNamingConvention.Factory namingConvention) {
+ GroupNamingConvention.Factory namingConvention,
+ GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull credentialsProvider) {
this.client = checkNotNull(client, "client");
this.jobComplete = checkNotNull(jobComplete, "jobComplete");
this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier");
@@ -139,6 +143,7 @@ public class CloudStackComputeServiceAdapter implements
this.optionsConverters = optionsConverters;
this.zoneIdToZone = zoneIdToZone;
this.namingConvention = namingConvention;
+ this.credentialsProvider = credentialsProvider;
}
@Override
@@ -233,17 +238,37 @@ public class CloudStackComputeServiceAdapter implements
templateId, options);
VirtualMachine vm = blockUntilJobCompletesAndReturnResult.<VirtualMachine>apply(job);
logger.debug("--- virtualmachine: %s", vm);
- LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder();
- if (templateOptions.getKeyPair() != null) {
- SshKeyPair keyPair = keyPairCache.getUnchecked(templateOptions.getKeyPair());
- credentialsBuilder.privateKey(keyPair.getPrivateKey());
- } else if (vm.isPasswordEnabled()) {
- assert vm.getPassword() != null : vm;
- credentialsBuilder.password(vm.getPassword());
+ LoginCredentials credentials = credentialsProvider.get();
+ if (credentials == null || credentials.getUser() == null) {
+ LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder();
+ if (templateOptions.getKeyPair() != null) {
+ SshKeyPair keyPair = keyPairCache.getUnchecked(templateOptions.getKeyPair());
+ credentialsBuilder.privateKey(keyPair.getPrivateKey());
+ } else if (vm.isPasswordEnabled()) {
+ assert vm.getPassword() != null : vm;
+ credentialsBuilder.password(vm.getPassword());
+ }
+ credentials = credentialsBuilder.build();
}
try {
- if (templateOptions.shouldSetupStaticNat()) {
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+ builder.putAll(template.getOptions().getUserMetadata());
+ for (String tag : template.getOptions().getTags())
+ builder.put(tag, "jclouds-empty-tag-placeholder");
+ Map<String, String> common = builder.build();
+
+ if (!common.isEmpty()) {
+ logger.debug(">> adding tags %s to virtualmachine(%s)", common, vm.getId());
+ CreateTagsOptions tagOptions = CreateTagsOptions.Builder.resourceIds(vm.getId())
+ .resourceType(Tag.ResourceType.USER_VM)
+ .tags(common);
+ AsyncCreateResponse tagJob = client.getTagApi().createTags(tagOptions);
+ awaitCompletion(tagJob.getJobId());
+ logger.debug("<< tags added");
+ vm = client.getVirtualMachineApi().getVirtualMachine(vm.getId());
+ }
+ if (templateOptions.shouldSetupStaticNat()) {
Capabilities capabilities = client.getConfigurationApi().listCapabilities();
// TODO: possibly not all network ids, do we want to do this
for (String networkId : options.getNetworkIds()) {
@@ -272,7 +297,7 @@ public class CloudStackComputeServiceAdapter implements
}
throw re;
}
- return new NodeAndInitialCredentials<VirtualMachine>(vm, vm.getId() + "", credentialsBuilder.build());
+ return new NodeAndInitialCredentials<VirtualMachine>(vm, vm.getId() + "", credentials);
}
@Override
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceLiveTest.java
index 7cc6d40..7543965 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceLiveTest.java
@@ -16,14 +16,11 @@
*/
package org.jclouds.cloudstack.compute;
-import org.jclouds.compute.domain.NodeMetadata;
+import com.google.inject.Module;
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Module;
-
/**
*
* Generally disabled, as it incurs higher fees.
@@ -39,13 +36,6 @@ public class CloudStackComputeServiceLiveTest extends BaseComputeServiceLiveTest
return new SshjSshClientModule();
}
- // cloudstack does not support metadata
- @Override
- protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
- assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
- "node userMetadata did not match %s %s", userMetadata, node);
- }
-
@Override
public void testOptionToNotBlock() {
// start call blocks until we static nat, which is long enough to reach
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadataTest.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadataTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadataTest.java
index 6c055f7..01bf3b3 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadataTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/VirtualMachineToNodeMetadataTest.java
@@ -21,6 +21,7 @@ import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import java.util.Set;
+import com.google.common.collect.ImmutableMap;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.NIC;
@@ -81,7 +82,11 @@ public class VirtualMachineToNodeMetadataTest {
.privateAddresses(ImmutableSet.of("10.1.1.18")).publicAddresses(ImmutableSet.of("1.1.1.1"))
.hardware(addHypervisor(ServiceOfferingToHardwareTest.one, "XenServer"))
.imageId(TemplateToImageTest.one.getId())
- .operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
+ .operatingSystem(TemplateToImageTest.one.getOperatingSystem())
+ .tags(ImmutableSet.of("another-tag"))
+ .userMetadata(ImmutableMap.of("some-tag", "some-value"))
+ .build().toString()
+ );
}
@@ -177,7 +182,10 @@ public class VirtualMachineToNodeMetadataTest {
.privateAddresses(ImmutableSet.of("10.1.1.18"))
.hardware(addHypervisor(ServiceOfferingToHardwareTest.one, "XenServer"))
.imageId(TemplateToImageTest.one.getId())
- .operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
+ .operatingSystem(TemplateToImageTest.one.getOperatingSystem())
+ .tags(ImmutableSet.of("another-tag"))
+ .userMetadata(ImmutableMap.of("some-tag", "some-value"))
+ .build().toString());
}
protected Hardware addHypervisor(Hardware in, String hypervisor) {
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListVirtualMachinesResponseTest.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListVirtualMachinesResponseTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListVirtualMachinesResponseTest.java
index d6b737b..8d2d8e6 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListVirtualMachinesResponseTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListVirtualMachinesResponseTest.java
@@ -20,6 +20,7 @@ import java.util.Set;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.NIC;
+import org.jclouds.cloudstack.domain.Tag;
import org.jclouds.cloudstack.domain.TrafficType;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.date.internal.SimpleDateFormatDateService;
@@ -69,7 +70,26 @@ public class ListVirtualMachinesResponseTest extends BaseSetParserTest<VirtualMa
.jobStatus(0)
.nics(ImmutableSet.of(NIC.builder().id("72").networkId("204").netmask("255.255.255.0").gateway("10.1.1.1")
.IPAddress("10.1.1.18").trafficType(TrafficType.GUEST).guestIPType(GuestIPType.VIRTUAL)
- .isDefault(true).build())).hypervisor("XenServer").build());
+ .isDefault(true).build()))
+ .hypervisor("XenServer")
+ .tags(ImmutableSet.of(
+ Tag.builder().account("adrian")
+ .resourceId("54")
+ .resourceType(Tag.ResourceType.USER_VM)
+ .key("some-tag")
+ .value("some-value")
+ .domain("ROOT")
+ .domainId("1")
+ .build(),
+ Tag.builder().account("adrian")
+ .resourceId("54")
+ .resourceType(Tag.ResourceType.USER_VM)
+ .key("another-tag")
+ .value("jclouds-empty-tag-placeholder")
+ .domain("ROOT")
+ .domainId("1")
+ .build()))
+ .build());
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/c8545350/apis/cloudstack/src/test/resources/listvirtualmachinesresponse.json
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/resources/listvirtualmachinesresponse.json b/apis/cloudstack/src/test/resources/listvirtualmachinesresponse.json
index 0d27100..a623589 100644
--- a/apis/cloudstack/src/test/resources/listvirtualmachinesresponse.json
+++ b/apis/cloudstack/src/test/resources/listvirtualmachinesresponse.json
@@ -1 +1,66 @@
-{ "listvirtualmachinesresponse" : { "virtualmachine" : [ {"id":54,"name":"i-3-54-VM","displayname":"i-3-54-VM","account":"adrian","domainid":1,"domain":"ROOT","created":"2011-02-16T14:28:37-0800","state":"Starting","haenable":false,"zoneid":1,"zonename":"San Jose 1","templateid":2,"templatename":"CentOS 5.3(64-bit) no GUI (XenServer)","templatedisplaytext":"CentOS 5.3(64-bit) no GUI (XenServer)","passwordenabled":false,"serviceofferingid":1,"serviceofferingname":"Small Instance","cpunumber":1,"cpuspeed":500,"memory":512,"guestosid":11,"rootdeviceid":0,"rootdevicetype":"NetworkFilesystem","securitygroup":[],"jobid":63,"jobstatus":0,"nic":[{"id":72,"networkid":204,"netmask":"255.255.255.0","gateway":"10.1.1.1","ipaddress":"10.1.1.18","traffictype":"Guest","type":"Virtual","isdefault":true}],"hypervisor":"XenServer"} ] } }
\ No newline at end of file
+{ "listvirtualmachinesresponse": {
+ "virtualmachine": [
+ {
+ "id": 54,
+ "name": "i-3-54-VM",
+ "displayname": "i-3-54-VM",
+ "account": "adrian",
+ "domainid": 1,
+ "domain": "ROOT",
+ "created": "2011-02-16T14:28:37-0800",
+ "state": "Starting",
+ "haenable": false,
+ "zoneid": 1,
+ "zonename": "San Jose 1",
+ "templateid": 2,
+ "templatename": "CentOS 5.3(64-bit) no GUI (XenServer)",
+ "templatedisplaytext": "CentOS 5.3(64-bit) no GUI (XenServer)",
+ "passwordenabled": false,
+ "serviceofferingid": 1,
+ "serviceofferingname": "Small Instance",
+ "cpunumber": 1,
+ "cpuspeed": 500,
+ "memory": 512,
+ "guestosid": 11,
+ "rootdeviceid": 0,
+ "rootdevicetype": "NetworkFilesystem",
+ "securitygroup": [],
+ "jobid": 63,
+ "jobstatus": 0,
+ "nic": [
+ {
+ "id": 72,
+ "networkid": 204,
+ "netmask": "255.255.255.0",
+ "gateway": "10.1.1.1",
+ "ipaddress": "10.1.1.18",
+ "traffictype": "Guest",
+ "type": "Virtual",
+ "isdefault": true
+ }
+ ],
+ "hypervisor": "XenServer",
+ "tags": [
+ {
+ "account": "adrian",
+ "domain": "ROOT",
+ "domainid": "1",
+ "key": "some-tag",
+ "resourceid": "54",
+ "resourcetype": "UserVm",
+ "value": "some-value"
+ },
+ {
+ "account": "adrian",
+ "domain": "ROOT",
+ "domainid": "1",
+ "key": "another-tag",
+ "resourceid": "54",
+ "resourcetype": "UserVm",
+ "value": "jclouds-empty-tag-placeholder"
+ }
+
+ ]
+ }
+ ]
+} }
\ No newline at end of file