mirror of https://github.com/apache/jclouds.git
JCLOUDS-756 - Adding tags/userMetadata to NodeMetadata transform
This commit is contained in:
parent
01dac6439d
commit
f6d3aa4817
|
@ -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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
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())//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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"} ] } }
|
||||
{ "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"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
} }
|
Loading…
Reference in New Issue