From 4329129c2510d634575e207e44d8ba5c6f66b6ff Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 14 Nov 2011 19:23:06 +0200 Subject: [PATCH] Issue 750:property to set the image id for the default template --- .../internal/BYONComputeServiceAdapter.java | 5 +- .../CloudSigmaComputeServiceAdapter.java | 9 +- .../functions/PreinstalledDiskToImage.java | 12 +- .../DeltacloudComputeServiceAdapter.java | 34 ++-- .../functions/CredentialsForInstance.java | 9 +- ...faultLoginCredentialsForImageStrategy.java | 16 +- .../compute/functions/EC2ImageParserTest.java | 2 +- .../ElasticStackComputeServiceAdapter.java | 8 +- ...oginCredentialsFromGuestConfiguration.java | 13 +- ...scriptionToGetDefaultLoginCredentials.java | 23 ++- .../TerremarkVCloudComputeClientTest.java | 2 +- ...ltLoginCredentialsForVAppTemplateTest.java | 10 +- .../compute/ComputeServiceAdapter.java | 93 ++++++--- .../JCloudsNativeComputeServiceAdapter.java | 16 +- .../BaseComputeServiceContextModule.java | 9 +- .../ComputeServiceAdapterContextModule.java | 44 ++++- ...ertiesAndStoreCredentialsOrReturnNull.java | 72 +++++++ ...tialsFromImageOrOverridingCredentials.java | 53 +++++ ...faultLoginCredentialsForImageStrategy.java | 4 +- .../PrioritizeCredentialsFromTemplate.java | 60 ++++++ .../AdaptingComputeServiceStrategies.java | 21 +- ...ava => ReturnCredentialsBoundToImage.java} | 14 +- .../config/StubComputeServiceAdapter.java | 43 ++--- .../compute/BaseTemplateBuilderLiveTest.java | 113 +++++++---- .../compute/BaseVersionedServiceLiveTest.java | 24 ++- ...esAndStoreCredentialsOrReturnNullTest.java | 179 +++++++++++++++++ ...sFromImageOrOverridingCredentialsTest.java | 140 ++++++++++++++ ...PrioritizeCredentialsFromTemplateTest.java | 182 ++++++++++++++++++ .../java/org/jclouds/domain/Credentials.java | 1 + .../strategy/AWSEC2ImageParserTest.java | 2 +- ...dSigmaLasVegasTemplateBuilderLiveTest.java | 9 +- ...oudSigmaZurichTemplateBuilderLiveTest.java | 1 + ...ptusPartnerCloudReviseParsedImageTest.java | 2 +- .../internal/GoGridResolveImagesModule.java | 15 +- .../strategy/VPDCComputeServiceAdapter.java | 20 +- .../softlayer/SoftLayerPropertiesBuilder.java | 2 +- .../compute/functions/ProductItemToImage.java | 22 ++- .../SoftLayerComputeServiceAdapter.java | 58 +++--- ...oftLayerComputeServiceAdapterLiveTest.java | 30 +-- .../SoftLayerTemplateBuilderLiveTest.java | 4 +- .../VirtualBoxComputeServiceAdapter.java | 6 +- ...rtualBoxComputeServiceAdapterLiveTest.java | 22 ++- .../ServerManagerComputeServiceAdapter.java | 9 +- 43 files changed, 1124 insertions(+), 289 deletions(-) create mode 100644 compute/src/main/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.java create mode 100644 compute/src/main/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentials.java create mode 100644 compute/src/main/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplate.java rename compute/src/main/java/org/jclouds/compute/strategy/impl/{ReturnNullCredentials.java => ReturnCredentialsBoundToImage.java} (74%) create mode 100644 compute/src/test/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest.java create mode 100644 compute/src/test/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentialsTest.java create mode 100644 compute/src/test/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplateTest.java diff --git a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java index 4f9190bab6..3793aa6482 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java +++ b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java @@ -20,7 +20,6 @@ package org.jclouds.byon.internal; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.Map; import java.util.Set; import javax.inject.Inject; @@ -33,7 +32,6 @@ import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; @@ -67,8 +65,7 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda } @Override - public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, - Template template, Map credentialStore) { + public NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) { throw new UnsupportedOperationException(); } diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index 05c2570160..01a63767eb 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -107,8 +106,7 @@ public class CloudSigmaComputeServiceAdapter implements } @Override - public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize); DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(), @@ -128,9 +126,8 @@ public class CloudSigmaComputeServiceAdapter implements logger.debug("<< created server(%s)", from.getUuid()); logger.debug(">> starting server(%s)", from.getUuid()); client.startServer(from.getUuid()); - // store the credentials so that later functions can use them - credentialStore.put("node#" + from.getUuid(), new Credentials("root", defaultVncPassword)); - return from; + return new NodeAndInitialCredentials(from, from.getUuid(), + new Credentials("root", defaultVncPassword)); } @Override diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/PreinstalledDiskToImage.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/PreinstalledDiskToImage.java index 066a87955c..ec6e66706b 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/PreinstalledDiskToImage.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/PreinstalledDiskToImage.java @@ -25,8 +25,8 @@ import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.OsFamilyVersion64Bit; import org.jclouds.compute.domain.OperatingSystem.Builder; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; @@ -44,7 +44,7 @@ public class PreinstalledDiskToImage implements Function { @Inject public PreinstalledDiskToImage(Supplier locationSupplier, - Function imageParser) { + Function imageParser) { this.locationSupplier = locationSupplier; this.imageParser = imageParser; } @@ -59,9 +59,9 @@ public class PreinstalledDiskToImage implements Function { builder.name(drive.getName()).description(description) .is64Bit(drive.getBits() != null ? drive.getBits() == 64 : parsed.is64Bit).version(parsed.version) .family(parsed.family); - return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma").userMetadata( - ImmutableMap. of("size", drive.getSize() / 1024 / 1024 / 1024 + "")).defaultCredentials( - new Credentials("cloudsigma", "cloudsigma")).location(locationSupplier.get()).name(drive.getName()) - .description(description).operatingSystem(builder.build()).version("").build(); + return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma") + .userMetadata(ImmutableMap. of("size", drive.getSize() / 1024 / 1024 / 1024 + "")) + .defaultCredentials(new Credentials("cloudsigma", null)).location(locationSupplier.get()) + .name(drive.getName()).description(description).operatingSystem(builder.build()).version("").build(); } } \ No newline at end of file diff --git a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java index 56d81cc481..809c59520e 100644 --- a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java +++ b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java @@ -21,7 +21,6 @@ package org.jclouds.deltacloud.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; import java.net.URI; -import java.util.Map; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @@ -36,11 +35,11 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.deltacloud.DeltacloudClient; import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.Instance; +import org.jclouds.deltacloud.domain.Instance.State; import org.jclouds.deltacloud.domain.PasswordAuthentication; import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.TransitionOnAction; -import org.jclouds.deltacloud.domain.Instance.State; import org.jclouds.deltacloud.options.CreateInstanceOptions; import org.jclouds.deltacloud.predicates.InstanceFinished; import org.jclouds.deltacloud.predicates.InstanceRunning; @@ -56,13 +55,13 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; /** - * defines the connection between the {@link DeltacloudClient} implementation and the jclouds - * {@link ComputeService} + * defines the connection between the {@link DeltacloudClient} implementation + * and the jclouds {@link ComputeService} * */ @Singleton public class DeltacloudComputeServiceAdapter implements - ComputeServiceAdapter { + ComputeServiceAdapter { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -75,24 +74,23 @@ public class DeltacloudComputeServiceAdapter implements this.client = checkNotNull(client, "client"); // TODO: parameterize stateChanges = ImmutableMap.> of(// - Instance.State.RUNNING, new RetryablePredicate(new InstanceRunning(client), 600, 1, - TimeUnit.SECONDS),// - Instance.State.FINISH, new RetryablePredicate(new InstanceFinished(client), 30, 1, - TimeUnit.SECONDS)// - ); + Instance.State.RUNNING, new RetryablePredicate(new InstanceRunning(client), 600, 1, + TimeUnit.SECONDS),// + Instance.State.FINISH, new RetryablePredicate(new InstanceFinished(client), 30, 1, + TimeUnit.SECONDS)// + ); } @Override - public Instance createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, + Template template) { Instance instance = client.createInstance(template.getImage().getProviderId(), CreateInstanceOptions.Builder - .named(name).hardwareProfile(template.getHardware().getId()).realm(template.getLocation().getId())); + .named(name).hardwareProfile(template.getHardware().getId()).realm(template.getLocation().getId())); + Credentials creds = null; if (instance.getAuthentication() != null && instance.getAuthentication() instanceof PasswordAuthentication) { - Credentials creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); - // store the credentials so that later functions can use them - credentialStore.put(instance.getHref().toASCIIString(), creds); + creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); } - return instance; + return new NodeAndInitialCredentials(instance, instance.getId(), creds); } @Override @@ -139,7 +137,7 @@ public class DeltacloudComputeServiceAdapter implements } Iterable findChainTo(Instance.State desired, Instance.State currentState, - Multimap states) { + Multimap states) { for (Transition transition : states.get(currentState)) { if (currentState.ordinal() >= transition.getTo().ordinal()) continue; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java index 00cf49b48e..951a38d4f9 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java @@ -27,7 +27,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.compute.domain.Image; -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.domain.Credentials; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.domain.KeyPair; @@ -45,14 +44,12 @@ import com.google.common.cache.CacheLoader; @Singleton public class CredentialsForInstance extends CacheLoader { private final ConcurrentMap credentialsMap; - private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider; private final Supplier> imageMap; @Inject CredentialsForInstance(ConcurrentMap credentialsMap, - PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, Supplier> imageMap) { + Supplier> imageMap) { this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap"); - this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider"); this.imageMap = imageMap; } @@ -73,8 +70,6 @@ public class CredentialsForInstance extends CacheLoader result = DescribeImagesResponseHandlerTest.parseImages(resource); - EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, + EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers .ofInstance(defaultLocation), new ReviseParsedImage.NoopReviseParsedImage()); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java index c14f191f84..0f0402d060 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java @@ -103,8 +103,7 @@ public class ElasticStackComputeServiceAdapter implements } @Override - public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); logger.debug(">> creating boot drive bytes(%d)", bootSize); @@ -127,10 +126,7 @@ public class ElasticStackComputeServiceAdapter implements ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); - // store the credentials so that later functions can use them - credentialStore.put("node#" + from.getUuid(), new Credentials( - template.getImage().getDefaultCredentials().identity, from.getVnc().getPassword())); - return from; + return new NodeAndInitialCredentials(from, from.getUuid(), new Credentials(null, defaultVncPassword)); } @Override diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/GetLoginCredentialsFromGuestConfiguration.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/GetLoginCredentialsFromGuestConfiguration.java index 8fe3b35eec..23fa1eedd5 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/GetLoginCredentialsFromGuestConfiguration.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/GetLoginCredentialsFromGuestConfiguration.java @@ -22,20 +22,29 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom; +import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; +import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage; import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.vcloud.domain.VAppTemplate; /** * @author Adrian Cole */ @Singleton -public class GetLoginCredentialsFromGuestConfiguration implements PopulateDefaultLoginCredentialsForImageStrategy { +public class GetLoginCredentialsFromGuestConfiguration extends ReturnCredentialsBoundToImage { + @Inject + public GetLoginCredentialsFromGuestConfiguration(@Nullable @Named("image") Credentials creds) { + super(creds); + } @Override public Credentials execute(Object resourceToAuthenticate) { + if (creds != null) + return creds; checkNotNull(resourceToAuthenticate); checkArgument(resourceToAuthenticate instanceof VAppTemplate, "Resource must be an VAppTemplate"); return getCredentialsFrom(VAppTemplate.class.cast(resourceToAuthenticate)); diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.java index 08d4376203..b172547c44 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.java @@ -25,12 +25,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Resource; +import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; +import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage; import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.logging.Logger; import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; @@ -38,21 +40,25 @@ import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; * @author Adrian Cole */ @Singleton -public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials implements - PopulateDefaultLoginCredentialsForImageStrategy { +public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials extends ReturnCredentialsBoundToImage { + @Inject + public ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(@Nullable @Named("image") Credentials creds) { + super(creds); + } @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; - + public static final Pattern USER_PASSWORD_PATTERN = Pattern - .compile(".*[Uu]sername: ([a-z]+) ?.*\n[Pp]assword: ([^ \n\r]+) ?\r?\n.*"); + .compile(".*[Uu]sername: ([a-z]+) ?.*\n[Pp]assword: ([^ \n\r]+) ?\r?\n.*"); @Override public Credentials execute(Object resourceToAuthenticate) { + if (creds != null) + return creds; checkNotNull(resourceToAuthenticate); - checkArgument(resourceToAuthenticate instanceof VAppTemplate, - "Resource must be an VAppTemplate (for Terremark)"); + checkArgument(resourceToAuthenticate instanceof VAppTemplate, "Resource must be an VAppTemplate (for Terremark)"); VAppTemplate template = (VAppTemplate) resourceToAuthenticate; String search = template.getDescription() != null ? template.getDescription() : template.getName(); if (search.indexOf("Windows") >= 0) { @@ -62,8 +68,7 @@ public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials implements if (matcher.find()) { return new Credentials(matcher.group(1), matcher.group(2)); } else { - logger.warn("could not parse username/password for image: " + template.getHref() + "\n" - + search); + logger.warn("could not parse username/password for image: " + template.getHref() + "\n" + search); return null; } } diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeClientTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeClientTest.java index faba196723..00a06cbe0b 100644 --- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeClientTest.java +++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeClientTest.java @@ -88,7 +88,7 @@ public class TerremarkVCloudComputeClientTest { Map vAppStatusToNodeState = createMock(Map.class); TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client, - new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(), new Provider() { + new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null), new Provider() { @Override public String get() { diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/PopulateDefaultLoginCredentialsForVAppTemplateTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/PopulateDefaultLoginCredentialsForVAppTemplateTest.java index 2b9e5ef246..b3c27d0e8d 100644 --- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/PopulateDefaultLoginCredentialsForVAppTemplateTest.java +++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/PopulateDefaultLoginCredentialsForVAppTemplateTest.java @@ -47,7 +47,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest { VAppTemplate template = createMock(VAppTemplate.class); expect(template.getDescription()).andReturn(description).atLeastOnce(); replay(template); - ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); + ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null); Credentials creds = converter.execute(template); assertEquals(creds.identity, "vcloud"); assertEquals(creds.credential, "$Ep455l0ud!2"); @@ -61,7 +61,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest { VAppTemplate template = createMock(VAppTemplate.class); expect(template.getDescription()).andReturn(description).atLeastOnce(); replay(template); - ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); + ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null); Credentials creds = converter.execute(template); assertEquals(creds.identity, "ecloud"); assertEquals(creds.credential, "$Ep455l0ud!2"); @@ -75,7 +75,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest { VAppTemplate template = createMock(VAppTemplate.class); expect(template.getDescription()).andReturn(description).atLeastOnce(); replay(template); - ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); + ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null); Credentials creds = converter.execute(template); assertEquals(creds.identity, "vpncubed"); assertEquals(creds.credential, "vpncubed"); @@ -89,7 +89,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest { VAppTemplate template = createMock(VAppTemplate.class); expect(template.getDescription()).andReturn(description).atLeastOnce(); replay(template); - ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); + ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null); Credentials creds = converter.execute(template); assertEquals(creds.identity, "ecloud"); assertEquals(creds.credential, "TmrkCl0ud1s#1!"); @@ -103,7 +103,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest { VAppTemplate template = createMock(VAppTemplate.class); expect(template.getDescription()).andReturn(description).atLeastOnce(); replay(template); - ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); + ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null); Credentials creds = converter.execute(template); assertEquals(creds.identity, "Administrator"); assertEquals(creds.credential, null); diff --git a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java index 0901a6ee16..38fa9f15b1 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java @@ -18,14 +18,16 @@ */ package org.jclouds.compute; -import java.util.Map; +import static com.google.common.base.Preconditions.checkNotNull; import org.jclouds.compute.domain.Template; import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; /** - * A means of specifying the interface between the {@link ComputeService ComputeServices} and a concrete compute - * cloud implementation, jclouds or otherwise. + * A means of specifying the interface between the {@link ComputeService + * ComputeServices} and a concrete compute cloud implementation, jclouds or + * otherwise. * * @author Adrian Cole * @@ -33,41 +35,79 @@ import org.jclouds.domain.Credentials; public interface ComputeServiceAdapter { /** - * {@link ComputeService#runNodesWithTag(String, int, Template)} generates the parameters passed - * into this method such that each node in the set has a unique name. + * {@link ComputeService#runNodesWithTag(String, int, Template)} generates + * the parameters passed into this method such that each node in the set has + * a unique name. * - *

note

It is intentional to return the library native node object, as generic type - * {@code N}. If you are not using library-native objects (such as libvirt {@code Domain}) use + *

note

It is intentional to return the library native node object, + * as generic type {@code N}. If you are not using library-native objects + * (such as libvirt {@code Domain}) use * {@link JCloudsNativeComputeServiceAdapter} instead. * - *

note

Your responsibility is to create a node with the underlying library and return - * after storing its credentials in the supplied map corresponding to - * {@link ComputeServiceContext#getCredentialStore credentialStore} + *

note

Your responsibility is to create a node with the underlying + * library and return after storing its credentials in the supplied map + * corresponding to {@link ComputeServiceContext#getCredentialStore + * credentialStore} * * @param tag * used to aggregate nodes with identical configuration * @param name - * unique supplied name for the node, which has the tag encoded into it. + * unique supplied name for the node, which has the tag encoded + * into it. * @param template - * includes {@code imageId}, {@code locationId}, and {@code hardwareId} used to resume - * the instance. - * @param credentialStore - * once the node is resumeed, its login user and password must be stored keyed on - * {@code node#id}. + * includes {@code imageId}, {@code locationId}, and + * {@code hardwareId} used to resume the instance. * @return library-native representation of a node. * * @see ComputeService#runNodesWithTag(String, int, Template) - * @see ComputeServiceContext#getCredentialStore */ - N createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore); + NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template); + + public static class NodeAndInitialCredentials { + private final N node; + private final String nodeId; + private final Credentials credentials; + + public NodeAndInitialCredentials(N node, String nodeId, @Nullable Credentials credentials) { + this.node = checkNotNull(node, "node"); + this.nodeId = checkNotNull(nodeId, "nodeId"); + this.credentials = credentials; + } + + /** + * + * @return cloud specific representation of the newly created node + */ + public N getNode() { + return node; + } + + /** + * + * @return Stringifed version of the new node's id. + */ + public String getNodeId() { + return nodeId; + } + + /** + * + * @return credentials given by the api for the node, or null if this + * information is not available + */ + @Nullable + public Credentials getCredentials() { + return credentials; + } + } /** - * Hardware profiles describe available cpu, memory, and disk configurations that can be used to - * run a node. + * Hardware profiles describe available cpu, memory, and disk configurations + * that can be used to run a node. *

- * To implement this method, return the library native hardware profiles available to the user. - * These will be used to launch nodes as a part of the template. + * To implement this method, return the library native hardware profiles + * available to the user. These will be used to launch nodes as a part of the + * template. * * @return a non-null iterable of available hardware profiles. * @see ComputeService#listHardwareProfiles() @@ -75,10 +115,11 @@ public interface ComputeServiceAdapter { Iterable listHardwareProfiles(); /** - * Images are the available configured operating systems that someone can run a node with. * + * Images are the available configured operating systems that someone can run + * a node with. * *

- * To implement this method, return the library native images available to the user. These will - * be used to launch nodes as a part of the template. + * To implement this method, return the library native images available to + * the user. These will be used to launch nodes as a part of the template. * * @return a non-null iterable of available images. * @see ComputeService#listImages() diff --git a/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java index a661cd093f..bae4d3f7cf 100644 --- a/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java @@ -18,17 +18,15 @@ */ package org.jclouds.compute; -import java.util.Map; - import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; /** - * A means of specifying the implementation of a service that uses jclouds types. + * A means of specifying the implementation of a service that uses jclouds + * types. * * @author Adrian Cole * @@ -39,8 +37,14 @@ public interface JCloudsNativeComputeServiceAdapter extends * {@inheritDoc} */ @Override - NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore); + NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template); + + public static class NodeWithInitialCredentials extends ComputeServiceAdapter.NodeAndInitialCredentials { + + public NodeWithInitialCredentials(NodeMetadata node) { + super(node, node.getId(), node.getCredentials()); + } + } /** * {@inheritDoc} diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java index a31cb9e5b4..56c759d738 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java @@ -41,8 +41,10 @@ import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode; +import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials; import org.jclouds.compute.functions.TemplateOptionsToStatement; import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.TemplateOptions; @@ -50,6 +52,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.config.ValueOfConfigurationKeyOrNull; +import org.jclouds.domain.Credentials; import org.jclouds.json.Json; import org.jclouds.location.Provider; import org.jclouds.location.config.LocationModule; @@ -84,7 +87,11 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { }).to(CreateSshClientOncePortIsListeningOnNode.class); bind(new TypeLiteral>() { }).to(TemplateOptionsToStatement.class); - + bind(Credentials.class).annotatedWith(Names.named("image")).toProvider( + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.class); + bind(new TypeLiteral>() { + }).to(DefaultCredentialsFromImageOrOverridingCredentials.class); + install(new FactoryModuleBuilder() .implement(RunScriptOnNodeUsingSsh.class, Names.named("direct"), RunScriptOnNodeUsingSsh.class) .implement(RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete.class, Names.named("blocking"), diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java index 97e19a8aa9..a1ce092806 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java @@ -20,6 +20,7 @@ package org.jclouds.compute.config; import java.util.Set; +import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.collect.TransformingSetSupplier; @@ -27,18 +28,22 @@ import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies; +import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import com.google.common.base.Function; +import com.google.common.base.Functions; import com.google.common.base.Supplier; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -59,20 +64,19 @@ public class ComputeServiceAdapterContextModule extends BaseCo this.asyncClientType = asyncClientType; } - @SuppressWarnings( { "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected void configure() { super.configure(); bind(new TypeLiteral() { - }).to( - (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, - syncClientType, asyncClientType))).in(Scopes.SINGLETON); + }).to((TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, syncClientType, + asyncClientType))).in(Scopes.SINGLETON); } @Provides @Singleton protected Supplier> provideLocations(final ComputeServiceAdapter adapter, - Function transformer) { + Function transformer) { return new TransformingSetSupplier(new Supplier>() { @Override @@ -86,7 +90,7 @@ public class ComputeServiceAdapterContextModule extends BaseCo @Provides @Singleton protected Supplier> provideHardware(final ComputeServiceAdapter adapter, - Function transformer) { + Function transformer) { return new TransformingSetSupplier(new Supplier>() { @Override @@ -100,7 +104,7 @@ public class ComputeServiceAdapterContextModule extends BaseCo @Provides @Singleton protected Supplier> provideImages(final ComputeServiceAdapter adapter, - Function transformer) { + Function transformer, AddDefaultCredentialsToImage addDefaultCredentialsToImage) { return new TransformingSetSupplier(new Supplier>() { @Override @@ -108,12 +112,34 @@ public class ComputeServiceAdapterContextModule extends BaseCo return adapter.listImages(); } - }, transformer); + }, Functions.compose(addDefaultCredentialsToImage, transformer)); + } + + @Singleton + public static class AddDefaultCredentialsToImage implements Function { + private final PopulateDefaultLoginCredentialsForImageStrategy credsForImage; + + @Inject + public AddDefaultCredentialsToImage(PopulateDefaultLoginCredentialsForImageStrategy credsForImage) { + this.credsForImage = credsForImage; + } + + @Override + public Image apply(Image arg0) { + Credentials credentials = credsForImage.execute(arg0); + return credentials != null ? ImageBuilder.fromImage(arg0).defaultCredentials(credentials).build() : arg0; + } + + @Override + public String toString() { + return "addDefaultCredentialsToImage()"; + } } @Provides @Singleton - protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy(AdaptingComputeServiceStrategies in) { + protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy( + AdaptingComputeServiceStrategies in) { return in; } diff --git a/compute/src/main/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.java b/compute/src/main/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.java new file mode 100644 index 0000000000..41600c6f91 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.java @@ -0,0 +1,72 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.config; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import javax.inject.Singleton; + +import org.jclouds.config.ValueOfConfigurationKeyOrNull; +import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Provider; + +import com.google.inject.Inject; + +/** + * @author Adrian Cole + */ +@Singleton +public class GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull implements + javax.inject.Provider { + private final ValueOfConfigurationKeyOrNull config; + private final String provider; + private final Map credentialStore; + + @Inject + public GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull(@Provider String provider, + ValueOfConfigurationKeyOrNull config, Map credentialStore) { + this.config = checkNotNull(config, "config"); + this.provider = checkNotNull(provider, "provider"); + this.credentialStore = checkNotNull(credentialStore, "credentialStore"); + } + + @Override + @Nullable + public Credentials get() { + if (credentialStore.containsKey("image")) + return credentialStore.get("image"); + Credentials creds = null; + String loginUser = config.apply(provider + ".login-user"); + if (loginUser == null) + loginUser = config.apply("jclouds.login-user"); + if (loginUser != null) { + int pos = loginUser.indexOf(':'); + if (pos != -1) { + creds = new Credentials(loginUser.substring(0, pos), loginUser.substring(pos + 1)); + } else + creds = new Credentials(loginUser, null); + credentialStore.put("image", creds); + } + return creds; + } + +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentials.java b/compute/src/main/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentials.java new file mode 100644 index 0000000000..2221ecb33d --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentials.java @@ -0,0 +1,53 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.functions; + +import static org.jclouds.domain.Credentials.NO_CREDENTIALS; + +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; + +import com.google.common.base.Function; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class DefaultCredentialsFromImageOrOverridingCredentials implements Function { + + @Override + public Credentials apply(Template template) { + TemplateOptions options = template.getOptions(); + Credentials creds = template.getImage().getDefaultCredentials(); + Credentials overridingCredentials = options.getOverridingCredentials(); + Credentials overrideCreds = (overridingCredentials != null) ? overridingCredentials : NO_CREDENTIALS; + if (creds == null) + creds = overrideCreds; + if (overrideCreds.identity != null) + creds = creds.toBuilder().identity(overrideCreds.identity).build(); + if (overrideCreds.credential != null) + creds = creds.toBuilder().credential(overrideCreds.credential).build(); + return creds.equals(NO_CREDENTIALS) ? null : creds; + } + +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java b/compute/src/main/java/org/jclouds/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java index 188cc2e030..b273dd8815 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java @@ -18,7 +18,7 @@ */ package org.jclouds.compute.strategy; -import org.jclouds.compute.strategy.impl.ReturnNullCredentials; +import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage; import org.jclouds.domain.Credentials; import com.google.inject.ImplementedBy; @@ -26,7 +26,7 @@ import com.google.inject.ImplementedBy; /** * @author Oleksiy Yarmula */ -@ImplementedBy(ReturnNullCredentials.class) +@ImplementedBy(ReturnCredentialsBoundToImage.class) public interface PopulateDefaultLoginCredentialsForImageStrategy { /** diff --git a/compute/src/main/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplate.java b/compute/src/main/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplate.java new file mode 100644 index 0000000000..3d5319414b --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplate.java @@ -0,0 +1,60 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.domain.Credentials.NO_CREDENTIALS; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Template; +import org.jclouds.domain.Credentials; + +import com.google.common.base.Function; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class PrioritizeCredentialsFromTemplate { + private final Function credentialsFromImageOrTemplateOptions; + + @Inject + public PrioritizeCredentialsFromTemplate(Function credentialsFromImageOrTemplateOptions) { + this.credentialsFromImageOrTemplateOptions = checkNotNull(credentialsFromImageOrTemplateOptions, + "credentialsFromImageOrTemplateOptions"); + } + + public Credentials apply(Template template, Credentials fromNode) { + Credentials creds = (fromNode != null) ? fromNode : NO_CREDENTIALS; + Credentials credsFromParameters = credentialsFromImageOrTemplateOptions.apply(template); + if (credsFromParameters != null) { + if (credsFromParameters.identity != null) + creds = creds.toBuilder().identity(credsFromParameters.identity).build(); + if (credsFromParameters.credential != null) + creds = creds.toBuilder().credential(credsFromParameters.credential).build(); + } + if (creds.equals(NO_CREDENTIALS)) + creds = null; + return creds; + } + +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java index b1944b0e61..a583ba96eb 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java @@ -29,6 +29,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeState; @@ -39,6 +40,7 @@ import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; @@ -54,20 +56,25 @@ import com.google.common.collect.Iterables; * */ @Singleton -public class AdaptingComputeServiceStrategies implements CreateNodeWithGroupEncodedIntoName, DestroyNodeStrategy, - GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy { +public class AdaptingComputeServiceStrategies implements CreateNodeWithGroupEncodedIntoName, + DestroyNodeStrategy, GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, + SuspendNodeStrategy { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; private final Map credentialStore; + private final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate; private final ComputeServiceAdapter client; private final Function nodeMetadataAdapter; @Inject public AdaptingComputeServiceStrategies(Map credentialStore, - ComputeServiceAdapter client, Function nodeMetadataAdapter) { + PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate, ComputeServiceAdapter client, + Function nodeMetadataAdapter) { this.credentialStore = checkNotNull(credentialStore, "credentialStore"); + this.prioritizeCredentialsFromTemplate = checkNotNull(prioritizeCredentialsFromTemplate, + "prioritizeCredentialsFromTemplate"); this.client = checkNotNull(client, "client"); this.nodeMetadataAdapter = checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter"); } @@ -133,8 +140,12 @@ public class AdaptingComputeServiceStrategies implements CreateNodeW checkState(name != null && name.indexOf(group) != -1, "name should have %s encoded into it", group); checkState(template != null, "template must be specified"); - N from = client.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); - NodeMetadata node = nodeMetadataAdapter.apply(from); + NodeAndInitialCredentials from = client.createNodeWithGroupEncodedIntoName(group, name, template); + Credentials fromNode = from.getCredentials(); + Credentials creds = prioritizeCredentialsFromTemplate.apply(template, fromNode); + if (creds != null) + credentialStore.put("node#" + from.getNodeId(), creds); + NodeMetadata node = nodeMetadataAdapter.apply(from.getNode()); return node; } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnNullCredentials.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java similarity index 74% rename from compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnNullCredentials.java rename to compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java index e41e1768ea..c3a6a63aff 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnNullCredentials.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java @@ -18,19 +18,29 @@ */ package org.jclouds.compute.strategy.impl; +import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; /** * @author Adrian Cole */ @Singleton -public class ReturnNullCredentials implements PopulateDefaultLoginCredentialsForImageStrategy { +public class ReturnCredentialsBoundToImage implements PopulateDefaultLoginCredentialsForImageStrategy { + + protected final Credentials creds; + + @Inject + public ReturnCredentialsBoundToImage(@Nullable @Named("image") Credentials creds) { + this.creds = creds; + } @Override public Credentials execute(Object resourceToAuthenticate) { - return null; + return creds; } } diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java index e9d7f4a1e5..4817d5072d 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java @@ -19,8 +19,8 @@ package org.jclouds.compute.stub.config; import java.util.Map; -import java.util.Set; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ConcurrentMap; import javax.inject.Inject; @@ -46,8 +46,8 @@ import org.jclouds.rest.ResourceNotFoundException; import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableList.Builder; +import com.google.common.collect.ImmutableSet; /** * @@ -67,10 +67,10 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda @Inject public StubComputeServiceAdapter(ConcurrentMap nodes, Supplier location, - @Named("NODE_ID") Provider idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix, - @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix, - JustProvider locationSupplier, Map> osToVersionMap, - Map credentialStore) { + @Named("NODE_ID") Provider idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix, + @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix, + JustProvider locationSupplier, Map> osToVersionMap, + Map credentialStore) { this.nodes = nodes; this.location = location; this.idProvider = idProvider; @@ -83,8 +83,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda } @Override - public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name, Template template, - Map credentialStore) { + public NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) { NodeMetadataBuilder builder = new NodeMetadataBuilder(); String id = idProvider.get() + ""; builder.ids(id); @@ -100,41 +99,35 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda builder.state(NodeState.PENDING); builder.publicAddresses(ImmutableSet. of(publicIpPrefix + id)); builder.privateAddresses(ImmutableSet. of(privateIpPrefix + id)); - Credentials creds = template.getOptions().getOverridingCredentials(); - if (creds == null) - creds = new Credentials(null, null); - if (creds.identity == null) - creds = creds.toBuilder().identity("root").build(); - if (creds.credential == null) - creds = creds.toBuilder().credential(passwordPrefix + id).build(); - builder.credentials(creds); + builder.credentials(new Credentials(null, passwordPrefix + id)); NodeMetadata node = builder.build(); credentialStore.put("node#" + node.getId(), node.getCredentials()); nodes.put(node.getId(), node); StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100); - return node; + return new NodeWithInitialCredentials(node); } @Override public Iterable listHardwareProfiles() { return ImmutableSet. of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160), - StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule - .stub("large", 8, 15360, 1690)); + StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), + StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690)); } @Override public Iterable listImages() { Credentials defaultCredentials = new Credentials("root", null); - // initializing as a List, as ImmutableSet does not allow you to put duplicates - Builder images = ImmutableList.builder(); + // initializing as a List, as ImmutableSet does not allow you to put + // duplicates + Builder images = ImmutableList. builder(); int id = 1; for (boolean is64Bit : new boolean[] { true, false }) for (Entry> osVersions : this.osToVersionMap.entrySet()) { for (String version : ImmutableSet.copyOf(osVersions.getValue().values())) { String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit); images.add(new ImageBuilder().ids(id++ + "").name(osVersions.getKey().name()).location(location.get()) - .operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit)) - .description(desc).defaultCredentials(defaultCredentials).build()); + .operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit)) + .description(desc).defaultCredentials(defaultCredentials).build()); } } return images.build(); @@ -154,8 +147,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda @Override public NodeMetadata getNode(String id) { NodeMetadata node = nodes.get(id); - return node == null ? null : NodeMetadataBuilder.fromNodeMetadata(node).credentials( - credentialStore.get("node#" + node.getId())).build(); + return node == null ? null : NodeMetadataBuilder.fromNodeMetadata(node) + .credentials(credentialStore.get("node#" + node.getId())).build(); } @Override diff --git a/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java index 8fe7c96f35..24d3d2d9f4 100644 --- a/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java @@ -37,6 +37,7 @@ import org.jclouds.compute.domain.OsFamilyVersion64Bit; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import org.jclouds.domain.LocationScope; import org.jclouds.json.Json; @@ -89,20 +90,20 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi public void testFromTemplate() { Template defaultTemplate = context.getComputeService().templateBuilder().build(); assertEquals(context.getComputeService().templateBuilder().fromTemplate(defaultTemplate).build().toString(), - defaultTemplate.toString()); + defaultTemplate.toString()); } @BeforeClass public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { setupCredentials(); - context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, ImmutableSet - . of(new Log4JLoggingModule()), setupProperties()); + context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), setupProperties()); } @DataProvider(name = "osSupported") public Object[][] osSupported() { - return convertToArray(Sets.filter(provideAllOperatingSystems(), Predicates - .not(defineUnsupportedOperatingSystems()))); + return convertToArray(Sets.filter(provideAllOperatingSystems(), + Predicates.not(defineUnsupportedOperatingSystems()))); } protected Object[][] convertToArray(Set supportedOperatingSystems) { @@ -125,7 +126,7 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi protected Set provideAllOperatingSystems() { Map> map = new BaseComputeServiceContextModule() { }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) - .getInstance(Json.class)); + .getInstance(Json.class)); Set supportedOperatingSystems = Sets.newHashSet(); for (Entry> osVersions : map.entrySet()) { @@ -139,8 +140,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi @Test(dataProvider = "osSupported") public void testTemplateBuilderCanFind(OsFamilyVersion64Bit matrix) throws InterruptedException { - TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( - matrix.is64Bit); + TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family) + .os64Bit(matrix.is64Bit); if (!matrix.version.equals("")) builder.osVersionMatches("^" + matrix.version + "$"); Template template = builder.build(); @@ -152,8 +153,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi @Test(dataProvider = "osNotSupported", expectedExceptions = NoSuchElementException.class) public void testTemplateBuilderCannotFind(OsFamilyVersion64Bit matrix) throws InterruptedException { - TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( - matrix.is64Bit); + TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family) + .os64Bit(matrix.is64Bit); if (!matrix.version.equals("")) builder.osVersionMatches("^" + matrix.version + "$"); builder.build(); @@ -164,7 +165,7 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi Template defaultTemplate = context.getComputeService().templateBuilder().build(); Template template = context.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId()) - .locationId(defaultTemplate.getLocation().getId()).build(); + .locationId(defaultTemplate.getLocation().getId()).build(); assertEquals(template.getImage(), defaultTemplate.getImage()); } @@ -172,7 +173,7 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi public void testDefaultTemplateBuilder() throws IOException { Template defaultTemplate = context.getComputeService().templateBuilder().build(); assert defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[012].[10][04]") : defaultTemplate - .getImage().getOperatingSystem().getVersion(); + .getImage().getOperatingSystem().getVersion(); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); @@ -189,38 +190,38 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi assert location != location.getParent() : location; assert location.getScope() != null : location; switch (location.getScope()) { - case PROVIDER: - assertProvider(location); - break; - case REGION: - assertProvider(location.getParent()); - assert location.getIso3166Codes().size() == 0 - || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location - + " ||" + location.getParent(); - break; - case ZONE: - Location provider = location.getParent().getParent(); - // zone can be a direct descendant of provider - if (provider == null) - provider = location.getParent(); - assertProvider(provider); - assert location.getIso3166Codes().size() == 0 - || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location - + " ||" + location.getParent(); - break; - case HOST: - Location provider2 = location.getParent().getParent().getParent(); - // zone can be a direct descendant of provider - if (provider2 == null) - provider2 = location.getParent().getParent(); - assertProvider(provider2); - break; + case PROVIDER: + assertProvider(location); + break; + case REGION: + assertProvider(location.getParent()); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||" + + location.getParent(); + break; + case ZONE: + Location provider = location.getParent().getParent(); + // zone can be a direct descendant of provider + if (provider == null) + provider = location.getParent(); + assertProvider(provider); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||" + + location.getParent(); + break; + case HOST: + Location provider2 = location.getParent().getParent().getParent(); + // zone can be a direct descendant of provider + if (provider2 == null) + provider2 = location.getParent().getParent(); + assertProvider(provider2); + break; } } } @Test - public void testTemplateBuilderWithImageIdsSpecified() throws IOException { + public void testTemplateBuilderWithImageIdSpecified() throws IOException { Template defaultTemplate = context.getComputeService().templateBuilder().build(); ComputeServiceContext context = null; @@ -252,6 +253,40 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi } } + @Test + public void testTemplateBuilderWithLoginUserSpecified() throws IOException { + + ComputeServiceContext context = null; + try { + Properties overrides = setupProperties(); + overrides.setProperty("jclouds.login-user", "foo:bar"); + + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides); + + assertEquals(context.getComputeService().templateBuilder().build().getImage().getDefaultCredentials(), + new Credentials("foo", "bar")); + } finally { + if (context != null) + context.close(); + } + + context = null; + try { + Properties overrides = setupProperties(); + overrides.setProperty(provider + ".login-user", "foo:bar"); + + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides); + + assertEquals(context.getComputeService().templateBuilder().build().getImage().getDefaultCredentials(), + new Credentials("foo", "bar")); + } finally { + if (context != null) + context.close(); + } + } + void assertProvider(Location provider) { assertEquals(provider.getScope(), LocationScope.PROVIDER); assertEquals(provider.getParent(), null); diff --git a/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java index 02016e18b3..0cc26be1b4 100644 --- a/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java @@ -18,15 +18,16 @@ */ package org.jclouds.compute; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Strings.emptyToNull; + +import java.util.Properties; +import java.util.logging.Logger; + import org.jclouds.Constants; import org.jclouds.rest.RestContextFactory; import org.testng.annotations.BeforeClass; -import java.util.Properties; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.emptyToNull; - /** * * @author Jason King @@ -39,15 +40,18 @@ public abstract class BaseVersionedServiceLiveTest { protected String endpoint; protected String apiversion; protected String imageId; + protected String loginUser; protected Properties setupRestProperties() { return RestContextFactory.getPropertiesFromResource("/rest.properties"); } - + protected Properties setupProperties() { - if (emptyToNull(provider) == null) throw new NullPointerException("provider must not be null or empty:"+provider); - if (emptyToNull(identity) == null) throw new NullPointerException("identity must not be null or empty:"+provider); + if (emptyToNull(provider) == null) + throw new NullPointerException("provider must not be null or empty:" + provider); + if (emptyToNull(identity) == null) + throw new NullPointerException("identity must not be null or empty:" + provider); Properties overrides = new Properties(); overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); @@ -63,6 +67,8 @@ public abstract class BaseVersionedServiceLiveTest { overrides.setProperty(provider + ".apiversion", apiversion); if (imageId != null) overrides.setProperty(provider + ".image-id", imageId); + if (loginUser != null) + overrides.setProperty(provider + ".login-user", loginUser); return overrides; } @@ -74,7 +80,7 @@ public abstract class BaseVersionedServiceLiveTest { endpoint = System.getProperty("test." + provider + ".endpoint"); apiversion = System.getProperty("test." + provider + ".apiversion"); imageId = System.getProperty("test." + provider + ".image-id"); + loginUser = System.getProperty("test." + provider + ".login-user"); } - } diff --git a/compute/src/test/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest.java b/compute/src/test/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest.java new file mode 100644 index 0000000000..4dd84be3e5 --- /dev/null +++ b/compute/src/test/java/org/jclouds/compute/config/GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest.java @@ -0,0 +1,179 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.config; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.util.Map; + +import org.jclouds.config.ValueOfConfigurationKeyOrNull; +import org.jclouds.domain.Credentials; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest") +public class GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNullTest { + + public void testWhenCredentialsNotPresentReturnsNull() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = null; + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(false); + expect(config.apply("provider.login-user")).andReturn(null); + expect(config.apply("jclouds.login-user")).andReturn(null); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + + public void testWhenCredentialsNotPresentAndProviderPropertyHasUser() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = new Credentials("ubuntu", null); + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(false); + expect(config.apply("provider.login-user")).andReturn("ubuntu"); + expect(credstore.put("image", expected)).andReturn(null); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + + public void testWhenCredentialsNotPresentAndJcloudsPropertyHasUser() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = new Credentials("ubuntu", null); + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(false); + expect(config.apply("provider.login-user")).andReturn(null); + expect(config.apply("jclouds.login-user")).andReturn("ubuntu"); + expect(credstore.put("image", expected)).andReturn(null); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + + public void testWhenCredentialsAlreadyPresentReturnsSame() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = new Credentials("root", null); + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(true); + expect(credstore.get("image")).andReturn(expected); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + + public void testWhenCredentialsNotPresentAndProviderPropertyHasUserAndPassword() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = new Credentials("ubuntu", "password"); + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(false); + expect(config.apply("provider.login-user")).andReturn("ubuntu:password"); + expect(credstore.put("image", expected)).andReturn(null); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + + public void testWhenCredentialsNotPresentAndJcloudsPropertyHasUserAndPassword() { + @SuppressWarnings("unchecked") + Map credstore = createMock(Map.class); + Credentials expected = new Credentials("ubuntu", "password"); + + ValueOfConfigurationKeyOrNull config = createMock(ValueOfConfigurationKeyOrNull.class); + + expect(credstore.containsKey("image")).andReturn(false); + expect(config.apply("provider.login-user")).andReturn(null); + expect(config.apply("jclouds.login-user")).andReturn("ubuntu:password"); + expect(credstore.put("image", expected)).andReturn(null); + + replay(config); + replay(credstore); + + GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull fn = new GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull( + "provider", config, credstore); + assertEquals(fn.get(), expected); + + verify(config); + verify(credstore); + + } + +} diff --git a/compute/src/test/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentialsTest.java b/compute/src/test/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentialsTest.java new file mode 100644 index 0000000000..820c8b14c1 --- /dev/null +++ b/compute/src/test/java/org/jclouds/compute/functions/DefaultCredentialsFromImageOrOverridingCredentialsTest.java @@ -0,0 +1,140 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.functions; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "DefaultCredentialsFromImageOrOverridingCredentialsTest") +public class DefaultCredentialsFromImageOrOverridingCredentialsTest { + private static final DefaultCredentialsFromImageOrOverridingCredentials fn = new DefaultCredentialsFromImageOrOverridingCredentials(); + + public void testWhenCredentialsNotPresentInImageOrTemplateOptionsReturnNull() { + Credentials expected = null; + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(new TemplateOptions()); + + replay(template); + replay(image); + + assertEquals(fn.apply(template), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInImageReturnsOneInTemplateOptions() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideCredentialsWith(expected)); + + replay(template); + replay(image); + + assertEquals(fn.apply(template), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInTemplateOptionsReturnsOneInImage() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(expected); + expect(template.getOptions()).andReturn(new TemplateOptions()); + + replay(template); + replay(image); + + assertEquals(fn.apply(template), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsPresentInImageOverridesIdentityFromCredentialsInTemplateOptions() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(new Credentials("user", "password")); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideLoginUserWith("ubuntu")); + + replay(template); + replay(image); + + assertEquals(fn.apply(template), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsPresentInImageOverridesCredentialFromCredentialsInTemplateOptions() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(new Credentials("ubuntu", "password2")); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideLoginCredentialWith("password")); + + replay(template); + replay(image); + + assertEquals(fn.apply(template), expected); + + verify(template); + verify(image); + + } +} diff --git a/compute/src/test/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplateTest.java b/compute/src/test/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplateTest.java new file mode 100644 index 0000000000..64dfb6e02d --- /dev/null +++ b/compute/src/test/java/org/jclouds/compute/strategy/PrioritizeCredentialsFromTemplateTest.java @@ -0,0 +1,182 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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.compute.strategy; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "PrioritizeCredentialsFromTemplateTest") +public class PrioritizeCredentialsFromTemplateTest { + private static final PrioritizeCredentialsFromTemplate fn = new PrioritizeCredentialsFromTemplate( + new DefaultCredentialsFromImageOrOverridingCredentials()); + + public void testWhenCredentialsNotPresentInImageTemplateOptionsOrParameterReturnNull() { + Credentials expected = null; + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(new TemplateOptions()); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, null), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInImageTemplateOptionsReturnsFromParameter() { + Credentials expected = new Credentials("foo", "bar"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(new TemplateOptions()); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, expected), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInImageReturnsOneInTemplateOptionsAndNotParameter() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideCredentialsWith(expected)); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, new Credentials("foo", "bar")), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInImageReturnsCredentialFromTemplateOptionsAndUserFromParameter() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(null); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideLoginUserWith("ubuntu")); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, new Credentials("foo", "password")), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsNotPresentInTemplateOptionsReturnsOneInImageAndNotParameter() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(expected); + expect(template.getOptions()).andReturn(new TemplateOptions()); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, new Credentials("foo", "bar")), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsPresentInImageOverridesIdentityFromCredentialsInTemplateOptionsAndNotParameter() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(new Credentials("user", "password")); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideLoginUserWith("ubuntu")); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, new Credentials("foo", "bar")), expected); + + verify(template); + verify(image); + + } + + public void testWhenCredentialsPresentInImageOverridesCredentialFromCredentialsInTemplateOptionsAndNotParameter() { + Credentials expected = new Credentials("ubuntu", "password"); + + Image image = createMock(Image.class); + Template template = createMock(Template.class); + + expect(template.getImage()).andReturn(image); + expect(image.getDefaultCredentials()).andReturn(new Credentials("ubuntu", "password2")); + expect(template.getOptions()).andReturn(TemplateOptions.Builder.overrideLoginCredentialWith("password")); + + replay(template); + replay(image); + + assertEquals(fn.apply(template, new Credentials("foo", "bar")), expected); + + verify(template); + verify(image); + + } +} diff --git a/core/src/main/java/org/jclouds/domain/Credentials.java b/core/src/main/java/org/jclouds/domain/Credentials.java index 56fe4f96c7..4096ddc20c 100644 --- a/core/src/main/java/org/jclouds/domain/Credentials.java +++ b/core/src/main/java/org/jclouds/domain/Credentials.java @@ -32,6 +32,7 @@ import com.google.common.collect.Lists; * @author Adrian Cole */ public class Credentials { + public static final Credentials NO_CREDENTIALS = new Credentials(null, null); public static class Builder { private String identity; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java index 782639c996..c2b4ee6d0f 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java @@ -162,7 +162,7 @@ public class AWSEC2ImageParserTest { .getInstance(Json.class)); Set result = DescribeImagesResponseHandlerTest.parseImages(resource); - EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, + EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers .ofInstance(defaultLocation), new AWSEC2ReviseParsedImage(map)); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); diff --git a/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaLasVegasTemplateBuilderLiveTest.java b/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaLasVegasTemplateBuilderLiveTest.java index 79639a6d5b..e9809526ae 100644 --- a/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaLasVegasTemplateBuilderLiveTest.java +++ b/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaLasVegasTemplateBuilderLiveTest.java @@ -55,12 +55,12 @@ public class CloudSigmaLasVegasTemplateBuilderLiveTest extends BaseTemplateBuild return (input.version.equals("11.04") && input.is64Bit) || (input.version.equals("10.04") && !input.is64Bit) || input.version.equals(""); case SOLARIS: - return false; + return input.version.equals("") && input.is64Bit; case DEBIAN: return false; case CENTOS: - return input.version.equals("") || (input.version.equals("6.0") && !input.is64Bit) - || (input.version.equals("5.5") && input.is64Bit); + return (input.version.equals("") || input.version.equals("6.0") || input.version.equals("5.7")) + && input.is64Bit; case WINDOWS: return ((input.version.equals("2008 R2") || input.version.equals("2003") || input.version.equals("")) && input.is64Bit); default: @@ -76,8 +76,9 @@ public class CloudSigmaLasVegasTemplateBuilderLiveTest extends BaseTemplateBuild Template defaultTemplate = context.getComputeService().templateBuilder().build(); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getId(), "af8bfee4-d249-4d91-b157-b01ee1ce1943"); + assertEquals(defaultTemplate.getImage().getId(), "6aab1938-71b3-4252-ac1c-a3cb17c284ab"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(defaultTemplate.getImage().getDefaultCredentials().identity, "cloudsigma"); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichTemplateBuilderLiveTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichTemplateBuilderLiveTest.java index 162f14631f..789b148d72 100644 --- a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichTemplateBuilderLiveTest.java +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichTemplateBuilderLiveTest.java @@ -80,6 +80,7 @@ public class CloudSigmaZurichTemplateBuilderLiveTest extends BaseTemplateBuilder assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getId(), "7fad4fe1-daf3-4cb8-a847-082aae4d8506"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(defaultTemplate.getImage().getDefaultCredentials().identity, "cloudsigma"); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java index 016a72da98..73ed76c365 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java @@ -99,7 +99,7 @@ public class EucalyptusPartnerCloudReviseParsedImageTest { .getInstance(Json.class)); Set result = DescribeImagesResponseHandlerTest.parseImages(resource); - EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, + EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers .ofInstance(defaultLocation), new EucalyptusPartnerCloudReviseParsedImage(map)); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/config/internal/GoGridResolveImagesModule.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/config/internal/GoGridResolveImagesModule.java index 6f9eb188bd..abe3a5c742 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/config/internal/GoGridResolveImagesModule.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/config/internal/GoGridResolveImagesModule.java @@ -18,11 +18,15 @@ */ package org.jclouds.gogrid.config.internal; +import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.config.ResolvesImages; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; +import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage; import org.jclouds.domain.Credentials; +import org.jclouds.javax.annotation.Nullable; import com.google.inject.AbstractModule; @@ -34,15 +38,20 @@ public class GoGridResolveImagesModule extends AbstractModule { @Override protected void configure() { bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to( - GoGridPopulateDefaultLoginCredentialsForImageStrategy.class); + GoGridPopulateDefaultLoginCredentialsForImageStrategy.class); } @Singleton - public static class GoGridPopulateDefaultLoginCredentialsForImageStrategy implements - PopulateDefaultLoginCredentialsForImageStrategy { + public static class GoGridPopulateDefaultLoginCredentialsForImageStrategy extends ReturnCredentialsBoundToImage { + @Inject + public GoGridPopulateDefaultLoginCredentialsForImageStrategy(@Nullable @Named("image") Credentials creds) { + super(creds); + } @Override public Credentials execute(Object resourceToAuthenticate) { + if (creds != null) + return creds; return new Credentials("root", null); } } diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java index 2d46e7373f..d75c622ad6 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java @@ -23,7 +23,6 @@ import static org.jclouds.savvis.vpdc.options.GetVMOptions.Builder.withPowerStat import static org.jclouds.savvis.vpdc.reference.VPDCConstants.PROPERTY_VPDC_VDC_EMAIL; import java.net.URI; -import java.util.Map; import java.util.concurrent.TimeUnit; import javax.inject.Named; @@ -34,7 +33,6 @@ import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.domain.CIMOperatingSystem; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Volume; -import org.jclouds.domain.Credentials; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.savvis.vpdc.VPDCClient; import org.jclouds.savvis.vpdc.domain.Network; @@ -49,15 +47,15 @@ import org.jclouds.savvis.vpdc.reference.VCloudMediaType; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Iterables; import com.google.inject.Inject; ; /** - * defines the connection between the {@link VPDCClient} implementation and the jclouds - * {@link ComputeService} + * defines the connection between the {@link VPDCClient} implementation and the + * jclouds {@link ComputeService} * */ @Singleton @@ -73,12 +71,11 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter(checkNotNull(taskSuccess, "taskSuccess"), 650, 10, - TimeUnit.SECONDS); + TimeUnit.SECONDS); } @Override - public VM createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { String networkTierName = template.getLocation().getId(); String vpdcId = template.getLocation().getParent().getId(); String billingSiteId = template.getLocation().getParent().getParent().getId(); @@ -104,7 +101,8 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter(returnVal, returnVal.getId(), null); } finally { // TODO: get the credentials relevant to the billingSiteId/Org // credentialStore.put(id, new Credentials(orgId, orgUser)); @@ -118,7 +116,7 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter listHardwareProfiles() { // TODO don't depend on OS return ImmutableSet.of(VMSpec.builder().operatingSystem(Iterables.get(listImages(), 0)).memoryInGig(2) - .addDataDrive("/data01", 25).build()); + .addDataDrive("/data01", 25).build()); } @Override @@ -142,7 +140,7 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter prices = ImmutableSet. builder(); prices.add("21"); // 1 IP Address prices.add("55"); // Host Ping: categoryCode: monitoring, notification diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java index e4d8bab868..a99fc65fd5 100644 --- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java +++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java @@ -18,24 +18,27 @@ */ package org.jclouds.softlayer.compute.functions; -import com.google.common.base.Function; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Credentials; import org.jclouds.logging.Logger; import org.jclouds.softlayer.domain.ProductItem; import org.jclouds.softlayer.domain.ProductItemPrice; -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; -import java.util.NoSuchElementException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Function; /** * @author Jason King @@ -73,6 +76,7 @@ public class ProductItemToImage implements Function { return new ImageBuilder() .ids(imageId().apply(productItem)) .description(productItem.getDescription()) + .defaultCredentials(new Credentials("root", null)) .operatingSystem(os) .build(); } diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java index f3ff8580a5..a9c3b4c1c8 100644 --- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java +++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java @@ -33,7 +33,6 @@ import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLA import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY; import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED; -import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -65,17 +64,17 @@ import com.google.common.base.Predicate; import com.google.common.base.Splitter; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Iterables; /** - * defines the connection between the {@link SoftLayerClient} implementation and the jclouds - * {@link ComputeService} + * defines the connection between the {@link SoftLayerClient} implementation and + * the jclouds {@link ComputeService} * */ @Singleton public class SoftLayerComputeServiceAdapter implements - ComputeServiceAdapter, ProductItem, Datacenter> { + ComputeServiceAdapter, ProductItem, Datacenter> { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -92,18 +91,18 @@ public class SoftLayerComputeServiceAdapter implements @Inject public SoftLayerComputeServiceAdapter(SoftLayerClient client, - VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent, - @Memoized Supplier productPackageSupplier, Iterable prices, - @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX) String cpuRegex, - @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE) String disk0Type, - @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED) float portSpeed, - @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) { + VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent, + @Memoized Supplier productPackageSupplier, Iterable prices, + @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX) String cpuRegex, + @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE) String disk0Type, + @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED) float portSpeed, + @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) { this.client = checkNotNull(client, "client"); this.guestLoginDelay = guestLoginDelay; this.productPackageSupplier = checkNotNull(productPackageSupplier, "productPackageSupplier"); checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500"); this.loginDetailsTester = new RetryablePredicate(virtualGuestHasLoginDetailsPresent, - guestLoginDelay); + guestLoginDelay); this.cpuPattern = Pattern.compile(checkNotNull(cpuRegex, "cpuRegex")); this.prices = checkNotNull(prices, "prices"); this.portSpeed = portSpeed; @@ -112,21 +111,21 @@ public class SoftLayerComputeServiceAdapter implements } @Override - public VirtualGuest createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name, - Template template, Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, + Template template) { checkNotNull(template, "template was null"); checkNotNull(template.getOptions(), "template options was null"); checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class), - "options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions() - .getClass()); + "options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions() + .getClass()); String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName(); VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build(); - ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId()).location( - template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template)) - .virtualGuest(newGuest).build(); + ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId()) + .location(template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template)) + .virtualGuest(newGuest).build(); logger.debug(">> ordering new virtualGuest domain(%s) hostname(%s)", domainName, name); ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order); @@ -137,14 +136,13 @@ public class SoftLayerComputeServiceAdapter implements boolean orderInSystem = loginDetailsTester.apply(result); logger.trace("<< virtualGuest(%s) complete(%s)", result.getId(), orderInSystem); - checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long - .toString(guestLoginDelay)); + checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, + Long.toString(guestLoginDelay)); result = client.getVirtualGuestClient().getVirtualGuest(result.getId()); Password pw = get(result.getOperatingSystem().getPasswords(), 0); - Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword()); - credentialStore.put("node#" + result.getId(), credentials); - return result; + return new NodeAndInitialCredentials(result, result.getId() + "", new Credentials(pw.getUsername(), + pw.getPassword())); } private Iterable getPrices(Template template) { @@ -158,8 +156,8 @@ public class SoftLayerComputeServiceAdapter implements int id = Integer.parseInt(hardwareId); result.add(ProductItemPrice.builder().id(id).build()); } - ProductItem uplinkItem = find(productPackageSupplier.get().getItems(), and(capacity(portSpeed), - categoryCode("port_speed"))); + ProductItem uplinkItem = find(productPackageSupplier.get().getItems(), + and(capacity(portSpeed), categoryCode("port_speed"))); result.add(get(uplinkItem.getPrices(), 0)); result.addAll(prices); return result.build(); @@ -187,7 +185,7 @@ public class SoftLayerComputeServiceAdapter implements @Override public Iterable listNodes() { - return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate(){ + return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate() { @Override public boolean apply(VirtualGuest arg0) { @@ -197,7 +195,7 @@ public class SoftLayerComputeServiceAdapter implements logger.trace("guest invalid, as it has no billing item %s", arg0); return false; } - + }); } @@ -220,7 +218,7 @@ public class SoftLayerComputeServiceAdapter implements if (guest.getBillingItemId() == -1) throw new IllegalStateException(String.format("no billing item for guest(%s) so we cannot cancel the order", - id)); + id)); logger.debug(">> canceling service for guest(%s) billingItem(%s)", id, guest.getBillingItemId()); client.getVirtualGuestClient().cancelService(guest.getBillingItemId()); @@ -257,7 +255,7 @@ public class SoftLayerComputeServiceAdapter implements boolean hasBackendIp = newGuest.getPrimaryBackendIpAddress() != null; boolean hasPrimaryIp = newGuest.getPrimaryIpAddress() != null; boolean hasPasswords = newGuest.getOperatingSystem() != null - && newGuest.getOperatingSystem().getPasswords().size() > 0; + && newGuest.getOperatingSystem().getPasswords().size() > 0; return hasBackendIp && hasPrimaryIp && hasPasswords; } diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java index ab3ca02df2..27a6c331f0 100644 --- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java +++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java @@ -21,11 +21,13 @@ package org.jclouds.softlayer.compute; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; -import java.util.Map; import java.util.Random; +import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials; import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials; +import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate; import org.jclouds.domain.Credentials; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.net.IPSocket; @@ -40,7 +42,6 @@ import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.common.net.InetAddresses; import com.google.inject.Guice; @@ -48,13 +49,13 @@ import com.google.inject.Guice; public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest { private SoftLayerComputeServiceAdapter adapter; - private VirtualGuest guest; + private NodeAndInitialCredentials guest; @BeforeGroups(groups = { "live" }) public void setupClient() { super.setupClient(); adapter = Guice.createInjector(module, new Log4JLoggingModule()) - .getInstance(SoftLayerComputeServiceAdapter.class); + .getInstance(SoftLayerComputeServiceAdapter.class); } @Test @@ -62,6 +63,9 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL assertFalse(Iterables.isEmpty(adapter.listLocations())); } + private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate( + new DefaultCredentialsFromImageOrOverridingCredentials()); + @Test public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() { String group = "foo"; @@ -71,15 +75,13 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL // test passing custom options template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org"); - Map credentialStore = Maps.newLinkedHashMap(); - guest = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); - assertEquals(guest.getHostname(), name); - assertEquals(guest.getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName()); - // check other things, like cpu correct, mem correct, image/os is correct - // (as possible) - assert credentialStore.containsKey("node#" + guest.getId()) : "credentials to log into guest not found " + guest; - assert InetAddresses.isInetAddress(guest.getPrimaryBackendIpAddress()) : guest; - doConnectViaSsh(guest, credentialStore.get("node#" + guest.getId())); + guest = adapter.createNodeWithGroupEncodedIntoName(group, name, template); + assertEquals(guest.getNode().getHostname(), name); + assertEquals(guest.getNodeId(), guest.getNode().getId()); + assertEquals(guest.getNode().getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class) + .getDomainName()); + assert InetAddresses.isInetAddress(guest.getNode().getPrimaryBackendIpAddress()) : guest; + doConnectViaSsh(guest.getNode(), prioritizeCredentialsFromTemplate.apply(template, guest.getCredentials())); } protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) { @@ -111,7 +113,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL @AfterGroups(groups = "live") protected void tearDown() { if (guest != null) - adapter.destroyNode(guest.getId() + ""); + adapter.destroyNode(guest.getNodeId() + ""); super.tearDown(); } } diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerTemplateBuilderLiveTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerTemplateBuilderLiveTest.java index 0168e634db..195a63a35a 100644 --- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerTemplateBuilderLiveTest.java +++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerTemplateBuilderLiveTest.java @@ -68,7 +68,7 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes case UBUNTU: return input.version.equals("") || input.version.equals("10.04") || input.version.equals("8"); case DEBIAN: - return input.version.equals("") || input.version.equals("5.0"); + return input.version.equals("") || input.version.matches("[56].0"); case FEDORA: return input.version.equals("") || input.version.equals("13") || input.version.equals("15"); case RHEL: @@ -219,6 +219,6 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes @Override protected Set getIso3166Codes() { - return ImmutableSet. of("SG", "US-CA", "US-TX", "US-VA", "US-WA", "US-TX"); + return ImmutableSet. of("SG", "NL", "US-CA", "US-TX", "US-VA", "US-WA", "US-TX"); } } \ No newline at end of file diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java index 7ba6c7ae95..3fb4ac2cf2 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java @@ -25,14 +25,12 @@ import static com.google.common.collect.Iterables.transform; import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; import java.util.Collections; -import java.util.Map; import javax.inject.Inject; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Template; -import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import org.jclouds.javax.annotation.Nullable; import org.jclouds.location.suppliers.JustProvider; @@ -71,8 +69,8 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, + Template template) { return null; } diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java index cb600efbd1..0bb1f6868b 100644 --- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java +++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java @@ -25,12 +25,15 @@ import static org.testng.Assert.assertFalse; import java.net.URI; import java.util.Map; +import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials; import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate; import org.jclouds.domain.Credentials; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; @@ -48,14 +51,13 @@ import org.virtualbox_4_1.VirtualBoxManager; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.inject.Guice; @Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest") public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest { private VirtualBoxComputeServiceAdapter adapter; - private IMachine machine; + private NodeAndInitialCredentials machine; private final Map> osVersionMap = new BaseComputeServiceContextModule() { }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) .getInstance(Json.class)); @@ -78,24 +80,26 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien assertFalse(Iterables.isEmpty(adapter.listLocations())); } + private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate( + new DefaultCredentialsFromImageOrOverridingCredentials()); + @Test public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() { String group = "foo"; String name = "foo-ef4"; Template template = context.getComputeService().templateBuilder().build(); - Map credentialStore = Maps.newLinkedHashMap(); - machine = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); - assertEquals(machine.getName(), name); + machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template); + assertEquals(machine.getNode().getName(), name); + assertEquals(machine.getNodeId(), machine.getNode().getId()); // is there a place for group? // check other things, like cpu correct, mem correct, image/os is correct // (as possible) - assert credentialStore.containsKey("node#" + machine.getId()) : "credentials to log into machine not found " - + machine; // TODO: what's the IP address? // assert // InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) : // machine; - doConnectViaSsh(machine, credentialStore.get("node#" + machine.getId())); + doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials())); + } protected void doConnectViaSsh(IMachine machine, Credentials creds) { @@ -132,7 +136,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien @AfterGroups(groups = "live") protected void tearDown() throws Exception { if (machine != null) - adapter.destroyNode(machine.getId() + ""); + adapter.destroyNode(machine.getNodeId() + ""); super.tearDown(); } } diff --git a/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java b/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java index 68be6c424e..4289750ef4 100644 --- a/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java +++ b/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java @@ -20,8 +20,6 @@ package org.jclouds.servermanager.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.Map; - import javax.inject.Inject; import javax.inject.Singleton; @@ -52,15 +50,12 @@ public class ServerManagerComputeServiceAdapter implements ComputeServiceAdapter } @Override - public Server createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { // create the backend object using parameters from the template. Server from = client.createServerInDC(template.getLocation().getId(), name, Integer.parseInt(template.getImage().getProviderId()), Integer.parseInt(template.getHardware().getProviderId())); - // store the credentials so that later functions can use them - credentialStore.put(from.id + "", new Credentials(from.loginUser, from.password)); - return from; + return new NodeAndInitialCredentials(from, from.id + "", new Credentials(from.loginUser, from.password)); } @Override