Issue 750:property to set the image id for the default template

This commit is contained in:
Adrian Cole 2011-11-14 19:23:06 +02:00
parent 69467b04e3
commit 4329129c25
43 changed files with 1124 additions and 289 deletions

View File

@ -20,7 +20,6 @@ package org.jclouds.byon.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; 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.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
@ -67,8 +65,7 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda
} }
@Override @Override
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, public NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
Template template, Map<String, Credentials> credentialStore) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.filter;
import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -107,8 +106,7 @@ public class CloudSigmaComputeServiceAdapter implements
} }
@Override @Override
public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
Map<String, Credentials> credentialStore) {
long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); 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); logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize);
DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(), 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("<< created server(%s)", from.getUuid());
logger.debug(">> starting server(%s)", from.getUuid()); logger.debug(">> starting server(%s)", from.getUuid());
client.startServer(from.getUuid()); client.startServer(from.getUuid());
// store the credentials so that later functions can use them return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(),
credentialStore.put("node#" + from.getUuid(), new Credentials("root", defaultVncPassword)); new Credentials("root", defaultVncPassword));
return from;
} }
@Override @Override

View File

@ -25,8 +25,8 @@ import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
import org.jclouds.compute.domain.OperatingSystem.Builder; import org.jclouds.compute.domain.OperatingSystem.Builder;
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
@ -59,9 +59,9 @@ public class PreinstalledDiskToImage implements Function<DriveInfo, Image> {
builder.name(drive.getName()).description(description) builder.name(drive.getName()).description(description)
.is64Bit(drive.getBits() != null ? drive.getBits() == 64 : parsed.is64Bit).version(parsed.version) .is64Bit(drive.getBits() != null ? drive.getBits() == 64 : parsed.is64Bit).version(parsed.version)
.family(parsed.family); .family(parsed.family);
return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma").userMetadata( return new ImageBuilder().ids(drive.getUuid()).adminPassword("cloudsigma")
ImmutableMap.<String, String> of("size", drive.getSize() / 1024 / 1024 / 1024 + "")).defaultCredentials( .userMetadata(ImmutableMap.<String, String> of("size", drive.getSize() / 1024 / 1024 / 1024 + ""))
new Credentials("cloudsigma", "cloudsigma")).location(locationSupplier.get()).name(drive.getName()) .defaultCredentials(new Credentials("cloudsigma", null)).location(locationSupplier.get())
.description(description).operatingSystem(builder.build()).version("").build(); .name(drive.getName()).description(description).operatingSystem(builder.build()).version("").build();
} }
} }

View File

@ -21,7 +21,6 @@ package org.jclouds.deltacloud.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -36,11 +35,11 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.deltacloud.DeltacloudClient; import org.jclouds.deltacloud.DeltacloudClient;
import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.domain.PasswordAuthentication; import org.jclouds.deltacloud.domain.PasswordAuthentication;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.TransitionOnAction; import org.jclouds.deltacloud.domain.TransitionOnAction;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.options.CreateInstanceOptions; import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.deltacloud.predicates.InstanceFinished; import org.jclouds.deltacloud.predicates.InstanceFinished;
import org.jclouds.deltacloud.predicates.InstanceRunning; import org.jclouds.deltacloud.predicates.InstanceRunning;
@ -56,8 +55,8 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
/** /**
* defines the connection between the {@link DeltacloudClient} implementation and the jclouds * defines the connection between the {@link DeltacloudClient} implementation
* {@link ComputeService} * and the jclouds {@link ComputeService}
* *
*/ */
@Singleton @Singleton
@ -83,16 +82,15 @@ public class DeltacloudComputeServiceAdapter implements
} }
@Override @Override
public Instance createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(String tag, String name,
Map<String, Credentials> credentialStore) { Template template) {
Instance instance = client.createInstance(template.getImage().getProviderId(), CreateInstanceOptions.Builder 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) { if (instance.getAuthentication() != null && instance.getAuthentication() instanceof PasswordAuthentication) {
Credentials creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials();
// store the credentials so that later functions can use them
credentialStore.put(instance.getHref().toASCIIString(), creds);
} }
return instance; return new NodeAndInitialCredentials<Instance>(instance, instance.getId(), creds);
} }
@Override @Override

View File

@ -27,7 +27,6 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.KeyPair;
@ -45,14 +44,12 @@ import com.google.common.cache.CacheLoader;
@Singleton @Singleton
public class CredentialsForInstance extends CacheLoader<RunningInstance, Credentials> { public class CredentialsForInstance extends CacheLoader<RunningInstance, Credentials> {
private final ConcurrentMap<RegionAndName, KeyPair> credentialsMap; private final ConcurrentMap<RegionAndName, KeyPair> credentialsMap;
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
private final Supplier<Cache<RegionAndName, ? extends Image>> imageMap; private final Supplier<Cache<RegionAndName, ? extends Image>> imageMap;
@Inject @Inject
CredentialsForInstance(ConcurrentMap<RegionAndName, KeyPair> credentialsMap, CredentialsForInstance(ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, Supplier<Cache<RegionAndName, ? extends Image>> imageMap) { Supplier<Cache<RegionAndName, ? extends Image>> imageMap) {
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap"); this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
this.imageMap = imageMap; this.imageMap = imageMap;
} }
@ -73,8 +70,6 @@ public class CredentialsForInstance extends CacheLoader<RunningInstance, Credent
@VisibleForTesting @VisibleForTesting
String getLoginAccountFor(RunningInstance from) throws ExecutionException { String getLoginAccountFor(RunningInstance from) throws ExecutionException {
return checkNotNull( return imageMap.get().get(new RegionAndName(from.getRegion(), from.getImageId())).getDefaultCredentials().identity;
credentialProvider.execute(imageMap.get().get(new RegionAndName(from.getRegion(), from.getImageId()))),
"login from image: " + from.getImageId()).identity;
} }
} }

View File

@ -20,21 +20,29 @@ package org.jclouds.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.ec2.domain.Image; import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.ec2.domain.Image;
import org.jclouds.javax.annotation.Nullable;
/** /**
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
@Singleton @Singleton
public class EC2PopulateDefaultLoginCredentialsForImageStrategy implements public class EC2PopulateDefaultLoginCredentialsForImageStrategy extends ReturnCredentialsBoundToImage {
PopulateDefaultLoginCredentialsForImageStrategy { @Inject
public EC2PopulateDefaultLoginCredentialsForImageStrategy(@Nullable @Named("image") Credentials creds) {
super(creds);
}
@Override @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
if (creds != null)
return creds;
Credentials credentials = new Credentials("root", null); Credentials credentials = new Credentials("root", null);
if (resourceToAuthenticate != null) { if (resourceToAuthenticate != null) {
String owner = null; String owner = null;

View File

@ -83,7 +83,7 @@ public class EC2ImageParserTest {
.getInstance(Json.class)); .getInstance(Json.class));
Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource); Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource);
EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map,
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation), new ReviseParsedImage.NoopReviseParsedImage()); .ofInstance(defaultLocation), new ReviseParsedImage.NoopReviseParsedImage());
return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull()));

View File

@ -103,8 +103,7 @@ public class ElasticStackComputeServiceAdapter implements
} }
@Override @Override
public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
Map<String, Credentials> credentialStore) {
long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l);
logger.debug(">> creating boot drive bytes(%d)", bootSize); logger.debug(">> creating boot drive bytes(%d)", bootSize);
@ -127,10 +126,7 @@ public class ElasticStackComputeServiceAdapter implements
ServerInfo from = client.createServer(toCreate); ServerInfo from = client.createServer(toCreate);
client.startServer(from.getUuid()); client.startServer(from.getUuid());
from = client.getServerInfo(from.getUuid()); from = client.getServerInfo(from.getUuid());
// store the credentials so that later functions can use them return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), new Credentials(null, defaultVncPassword));
credentialStore.put("node#" + from.getUuid(), new Credentials(
template.getImage().getDefaultCredentials().identity, from.getVnc().getPassword()));
return from;
} }
@Override @Override

View File

@ -22,20 +22,29 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; 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.domain.Credentials;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.vcloud.domain.VAppTemplate; import org.jclouds.vcloud.domain.VAppTemplate;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class GetLoginCredentialsFromGuestConfiguration implements PopulateDefaultLoginCredentialsForImageStrategy { public class GetLoginCredentialsFromGuestConfiguration extends ReturnCredentialsBoundToImage {
@Inject
public GetLoginCredentialsFromGuestConfiguration(@Nullable @Named("image") Credentials creds) {
super(creds);
}
@Override @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
if (creds != null)
return creds;
checkNotNull(resourceToAuthenticate); checkNotNull(resourceToAuthenticate);
checkArgument(resourceToAuthenticate instanceof VAppTemplate, "Resource must be an VAppTemplate"); checkArgument(resourceToAuthenticate instanceof VAppTemplate, "Resource must be an VAppTemplate");
return getCredentialsFrom(VAppTemplate.class.cast(resourceToAuthenticate)); return getCredentialsFrom(VAppTemplate.class.cast(resourceToAuthenticate));

View File

@ -25,12 +25,14 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants; 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.domain.Credentials;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate;
@ -38,8 +40,11 @@ import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials implements public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials extends ReturnCredentialsBoundToImage {
PopulateDefaultLoginCredentialsForImageStrategy { @Inject
public ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(@Nullable @Named("image") Credentials creds) {
super(creds);
}
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
@ -50,9 +55,10 @@ public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials implements
@Override @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
if (creds != null)
return creds;
checkNotNull(resourceToAuthenticate); checkNotNull(resourceToAuthenticate);
checkArgument(resourceToAuthenticate instanceof VAppTemplate, checkArgument(resourceToAuthenticate instanceof VAppTemplate, "Resource must be an VAppTemplate (for Terremark)");
"Resource must be an VAppTemplate (for Terremark)");
VAppTemplate template = (VAppTemplate) resourceToAuthenticate; VAppTemplate template = (VAppTemplate) resourceToAuthenticate;
String search = template.getDescription() != null ? template.getDescription() : template.getName(); String search = template.getDescription() != null ? template.getDescription() : template.getName();
if (search.indexOf("Windows") >= 0) { if (search.indexOf("Windows") >= 0) {
@ -62,8 +68,7 @@ public class ParseVAppTemplateDescriptionToGetDefaultLoginCredentials implements
if (matcher.find()) { if (matcher.find()) {
return new Credentials(matcher.group(1), matcher.group(2)); return new Credentials(matcher.group(1), matcher.group(2));
} else { } else {
logger.warn("could not parse username/password for image: " + template.getHref() + "\n" logger.warn("could not parse username/password for image: " + template.getHref() + "\n" + search);
+ search);
return null; return null;
} }
} }

View File

@ -88,7 +88,7 @@ public class TerremarkVCloudComputeClientTest {
Map<Status, NodeState> vAppStatusToNodeState = createMock(Map.class); Map<Status, NodeState> vAppStatusToNodeState = createMock(Map.class);
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client, TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client,
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(), new Provider<String>() { new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null), new Provider<String>() {
@Override @Override
public String get() { public String get() {

View File

@ -47,7 +47,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest {
VAppTemplate template = createMock(VAppTemplate.class); VAppTemplate template = createMock(VAppTemplate.class);
expect(template.getDescription()).andReturn(description).atLeastOnce(); expect(template.getDescription()).andReturn(description).atLeastOnce();
replay(template); replay(template);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null);
Credentials creds = converter.execute(template); Credentials creds = converter.execute(template);
assertEquals(creds.identity, "vcloud"); assertEquals(creds.identity, "vcloud");
assertEquals(creds.credential, "$Ep455l0ud!2"); assertEquals(creds.credential, "$Ep455l0ud!2");
@ -61,7 +61,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest {
VAppTemplate template = createMock(VAppTemplate.class); VAppTemplate template = createMock(VAppTemplate.class);
expect(template.getDescription()).andReturn(description).atLeastOnce(); expect(template.getDescription()).andReturn(description).atLeastOnce();
replay(template); replay(template);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null);
Credentials creds = converter.execute(template); Credentials creds = converter.execute(template);
assertEquals(creds.identity, "ecloud"); assertEquals(creds.identity, "ecloud");
assertEquals(creds.credential, "$Ep455l0ud!2"); assertEquals(creds.credential, "$Ep455l0ud!2");
@ -75,7 +75,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest {
VAppTemplate template = createMock(VAppTemplate.class); VAppTemplate template = createMock(VAppTemplate.class);
expect(template.getDescription()).andReturn(description).atLeastOnce(); expect(template.getDescription()).andReturn(description).atLeastOnce();
replay(template); replay(template);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null);
Credentials creds = converter.execute(template); Credentials creds = converter.execute(template);
assertEquals(creds.identity, "vpncubed"); assertEquals(creds.identity, "vpncubed");
assertEquals(creds.credential, "vpncubed"); assertEquals(creds.credential, "vpncubed");
@ -89,7 +89,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest {
VAppTemplate template = createMock(VAppTemplate.class); VAppTemplate template = createMock(VAppTemplate.class);
expect(template.getDescription()).andReturn(description).atLeastOnce(); expect(template.getDescription()).andReturn(description).atLeastOnce();
replay(template); replay(template);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null);
Credentials creds = converter.execute(template); Credentials creds = converter.execute(template);
assertEquals(creds.identity, "ecloud"); assertEquals(creds.identity, "ecloud");
assertEquals(creds.credential, "TmrkCl0ud1s#1!"); assertEquals(creds.credential, "TmrkCl0ud1s#1!");
@ -103,7 +103,7 @@ public class PopulateDefaultLoginCredentialsForVAppTemplateTest {
VAppTemplate template = createMock(VAppTemplate.class); VAppTemplate template = createMock(VAppTemplate.class);
expect(template.getDescription()).andReturn(description).atLeastOnce(); expect(template.getDescription()).andReturn(description).atLeastOnce();
replay(template); replay(template);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(); ParseVAppTemplateDescriptionToGetDefaultLoginCredentials converter = new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null);
Credentials creds = converter.execute(template); Credentials creds = converter.execute(template);
assertEquals(creds.identity, "Administrator"); assertEquals(creds.identity, "Administrator");
assertEquals(creds.credential, null); assertEquals(creds.credential, null);

View File

@ -18,14 +18,16 @@
*/ */
package org.jclouds.compute; 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.compute.domain.Template;
import org.jclouds.domain.Credentials; 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 * A means of specifying the interface between the {@link ComputeService
* cloud implementation, jclouds or otherwise. * ComputeServices} and a concrete compute cloud implementation, jclouds or
* otherwise.
* *
* @author Adrian Cole * @author Adrian Cole
* *
@ -33,41 +35,79 @@ import org.jclouds.domain.Credentials;
public interface ComputeServiceAdapter<N, H, I, L> { public interface ComputeServiceAdapter<N, H, I, L> {
/** /**
* {@link ComputeService#runNodesWithTag(String, int, Template)} generates the parameters passed * {@link ComputeService#runNodesWithTag(String, int, Template)} generates
* into this method such that each node in the set has a unique name. * the parameters passed into this method such that each node in the set has
* a unique name.
* *
* <h4>note</h4> It is intentional to return the library native node object, as generic type * <h4>note</h4> It is intentional to return the library native node object,
* {@code N}. If you are not using library-native objects (such as libvirt {@code Domain}) use * as generic type {@code N}. If you are not using library-native objects
* (such as libvirt {@code Domain}) use
* {@link JCloudsNativeComputeServiceAdapter} instead. * {@link JCloudsNativeComputeServiceAdapter} instead.
* *
* <h4>note</h4> Your responsibility is to create a node with the underlying library and return * <h4>note</h4> Your responsibility is to create a node with the underlying
* after storing its credentials in the supplied map corresponding to * library and return after storing its credentials in the supplied map
* {@link ComputeServiceContext#getCredentialStore credentialStore} * corresponding to {@link ComputeServiceContext#getCredentialStore
* credentialStore}
* *
* @param tag * @param tag
* used to aggregate nodes with identical configuration * used to aggregate nodes with identical configuration
* @param name * @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 * @param template
* includes {@code imageId}, {@code locationId}, and {@code hardwareId} used to resume * includes {@code imageId}, {@code locationId}, and
* the instance. * {@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}.
* @return library-native representation of a node. * @return library-native representation of a node.
* *
* @see ComputeService#runNodesWithTag(String, int, Template) * @see ComputeService#runNodesWithTag(String, int, Template)
* @see ComputeServiceContext#getCredentialStore
*/ */
N createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, NodeAndInitialCredentials<N> createNodeWithGroupEncodedIntoName(String tag, String name, Template template);
Map<String, Credentials> credentialStore);
public static class NodeAndInitialCredentials<N> {
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;
}
/** /**
* Hardware profiles describe available cpu, memory, and disk configurations that can be used to *
* run a node. * @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.
* <p/> * <p/>
* To implement this method, return the library native hardware profiles available to the user. * To implement this method, return the library native hardware profiles
* These will be used to launch nodes as a part of the template. * 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. * @return a non-null iterable of available hardware profiles.
* @see ComputeService#listHardwareProfiles() * @see ComputeService#listHardwareProfiles()
@ -75,10 +115,11 @@ public interface ComputeServiceAdapter<N, H, I, L> {
Iterable<H> listHardwareProfiles(); Iterable<H> 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. *
* <p/> * <p/>
* To implement this method, return the library native images available to the user. These will * To implement this method, return the library native images available to
* be used to launch nodes as a part of the template. * the user. These will be used to launch nodes as a part of the template.
* *
* @return a non-null iterable of available images. * @return a non-null iterable of available images.
* @see ComputeService#listImages() * @see ComputeService#listImages()

View File

@ -18,17 +18,15 @@
*/ */
package org.jclouds.compute; package org.jclouds.compute;
import java.util.Map;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; 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 * @author Adrian Cole
* *
@ -39,8 +37,14 @@ public interface JCloudsNativeComputeServiceAdapter extends
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template);
Map<String, Credentials> credentialStore);
public static class NodeWithInitialCredentials extends ComputeServiceAdapter.NodeAndInitialCredentials<NodeMetadata> {
public NodeWithInitialCredentials(NodeMetadata node) {
super(node, node.getId(), node.getCredentials());
}
}
/** /**
* {@inheritDoc} * {@inheritDoc}

View File

@ -41,8 +41,10 @@ import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode; import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
import org.jclouds.compute.functions.TemplateOptionsToStatement; import org.jclouds.compute.functions.TemplateOptionsToStatement;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.options.TemplateOptions; 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.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.domain.Credentials;
import org.jclouds.json.Json; import org.jclouds.json.Json;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
import org.jclouds.location.config.LocationModule; import org.jclouds.location.config.LocationModule;
@ -84,6 +87,10 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
}).to(CreateSshClientOncePortIsListeningOnNode.class); }).to(CreateSshClientOncePortIsListeningOnNode.class);
bind(new TypeLiteral<Function<TemplateOptions, Statement>>() { bind(new TypeLiteral<Function<TemplateOptions, Statement>>() {
}).to(TemplateOptionsToStatement.class); }).to(TemplateOptionsToStatement.class);
bind(Credentials.class).annotatedWith(Names.named("image")).toProvider(
GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull.class);
bind(new TypeLiteral<Function<Template, Credentials>>() {
}).to(DefaultCredentialsFromImageOrOverridingCredentials.class);
install(new FactoryModuleBuilder() install(new FactoryModuleBuilder()
.implement(RunScriptOnNodeUsingSsh.class, Names.named("direct"), RunScriptOnNodeUsingSsh.class) .implement(RunScriptOnNodeUsingSsh.class, Names.named("direct"), RunScriptOnNodeUsingSsh.class)

View File

@ -20,6 +20,7 @@ package org.jclouds.compute.config;
import java.util.Set; import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.collect.TransformingSetSupplier; import org.jclouds.collect.TransformingSetSupplier;
@ -27,18 +28,22 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies; import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Scopes; import com.google.inject.Scopes;
@ -59,14 +64,13 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
this.asyncClientType = asyncClientType; this.asyncClientType = asyncClientType;
} }
@SuppressWarnings( { "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
bind(new TypeLiteral<ComputeServiceContext>() { bind(new TypeLiteral<ComputeServiceContext>() {
}).to( }).to((TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, syncClientType,
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, asyncClientType))).in(Scopes.SINGLETON);
syncClientType, asyncClientType))).in(Scopes.SINGLETON);
} }
@Provides @Provides
@ -100,7 +104,7 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
@Provides @Provides
@Singleton @Singleton
protected Supplier<Set<? extends Image>> provideImages(final ComputeServiceAdapter<N, H, I, L> adapter, protected Supplier<Set<? extends Image>> provideImages(final ComputeServiceAdapter<N, H, I, L> adapter,
Function<I, Image> transformer) { Function<I, Image> transformer, AddDefaultCredentialsToImage addDefaultCredentialsToImage) {
return new TransformingSetSupplier<I, Image>(new Supplier<Iterable<I>>() { return new TransformingSetSupplier<I, Image>(new Supplier<Iterable<I>>() {
@Override @Override
@ -108,12 +112,34 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
return adapter.listImages(); return adapter.listImages();
} }
}, transformer); }, Functions.compose(addDefaultCredentialsToImage, transformer));
}
@Singleton
public static class AddDefaultCredentialsToImage implements Function<Image, Image> {
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 @Provides
@Singleton @Singleton
protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy(AdaptingComputeServiceStrategies<N, H, I, L> in) { protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy(
AdaptingComputeServiceStrategies<N, H, I, L> in) {
return in; return in;
} }

View File

@ -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<Credentials> {
private final ValueOfConfigurationKeyOrNull config;
private final String provider;
private final Map<String, Credentials> credentialStore;
@Inject
public GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull(@Provider String provider,
ValueOfConfigurationKeyOrNull config, Map<String, Credentials> 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;
}
}

View File

@ -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<Template, Credentials> {
@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;
}
}

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.compute.strategy; 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 org.jclouds.domain.Credentials;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
@ -26,7 +26,7 @@ import com.google.inject.ImplementedBy;
/** /**
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
@ImplementedBy(ReturnNullCredentials.class) @ImplementedBy(ReturnCredentialsBoundToImage.class)
public interface PopulateDefaultLoginCredentialsForImageStrategy { public interface PopulateDefaultLoginCredentialsForImageStrategy {
/** /**

View File

@ -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<Template, Credentials> credentialsFromImageOrTemplateOptions;
@Inject
public PrioritizeCredentialsFromTemplate(Function<Template, Credentials> 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;
}
}

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; 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.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy;
@ -54,20 +56,25 @@ import com.google.common.collect.Iterables;
* *
*/ */
@Singleton @Singleton
public class AdaptingComputeServiceStrategies<N, H, I, L> implements CreateNodeWithGroupEncodedIntoName, DestroyNodeStrategy, public class AdaptingComputeServiceStrategies<N, H, I, L> implements CreateNodeWithGroupEncodedIntoName,
GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy { DestroyNodeStrategy, GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy,
SuspendNodeStrategy {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Map<String, Credentials> credentialStore; private final Map<String, Credentials> credentialStore;
private final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate;
private final ComputeServiceAdapter<N, H, I, L> client; private final ComputeServiceAdapter<N, H, I, L> client;
private final Function<N, NodeMetadata> nodeMetadataAdapter; private final Function<N, NodeMetadata> nodeMetadataAdapter;
@Inject @Inject
public AdaptingComputeServiceStrategies(Map<String, Credentials> credentialStore, public AdaptingComputeServiceStrategies(Map<String, Credentials> credentialStore,
ComputeServiceAdapter<N, H, I, L> client, Function<N, NodeMetadata> nodeMetadataAdapter) { PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate, ComputeServiceAdapter<N, H, I, L> client,
Function<N, NodeMetadata> nodeMetadataAdapter) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.prioritizeCredentialsFromTemplate = checkNotNull(prioritizeCredentialsFromTemplate,
"prioritizeCredentialsFromTemplate");
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.nodeMetadataAdapter = checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter"); this.nodeMetadataAdapter = checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter");
} }
@ -133,8 +140,12 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements CreateNodeW
checkState(name != null && name.indexOf(group) != -1, "name should have %s encoded into it", group); checkState(name != null && name.indexOf(group) != -1, "name should have %s encoded into it", group);
checkState(template != null, "template must be specified"); checkState(template != null, "template must be specified");
N from = client.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); NodeAndInitialCredentials<N> from = client.createNodeWithGroupEncodedIntoName(group, name, template);
NodeMetadata node = nodeMetadataAdapter.apply(from); 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; return node;
} }

View File

@ -18,19 +18,29 @@
*/ */
package org.jclouds.compute.strategy.impl; package org.jclouds.compute.strategy.impl;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.javax.annotation.Nullable;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @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 @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
return null; return creds;
} }
} }

View File

@ -19,8 +19,8 @@
package org.jclouds.compute.stub.config; package org.jclouds.compute.stub.config;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import javax.inject.Inject; import javax.inject.Inject;
@ -46,8 +46,8 @@ import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
/** /**
* *
@ -83,8 +83,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
} }
@Override @Override
public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name, Template template, public NodeWithInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
Map<String, Credentials> credentialStore) {
NodeMetadataBuilder builder = new NodeMetadataBuilder(); NodeMetadataBuilder builder = new NodeMetadataBuilder();
String id = idProvider.get() + ""; String id = idProvider.get() + "";
builder.ids(id); builder.ids(id);
@ -100,33 +99,27 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
builder.state(NodeState.PENDING); builder.state(NodeState.PENDING);
builder.publicAddresses(ImmutableSet.<String> of(publicIpPrefix + id)); builder.publicAddresses(ImmutableSet.<String> of(publicIpPrefix + id));
builder.privateAddresses(ImmutableSet.<String> of(privateIpPrefix + id)); builder.privateAddresses(ImmutableSet.<String> of(privateIpPrefix + id));
Credentials creds = template.getOptions().getOverridingCredentials(); builder.credentials(new Credentials(null, passwordPrefix + id));
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);
NodeMetadata node = builder.build(); NodeMetadata node = builder.build();
credentialStore.put("node#" + node.getId(), node.getCredentials()); credentialStore.put("node#" + node.getId(), node.getCredentials());
nodes.put(node.getId(), node); nodes.put(node.getId(), node);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100); StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100);
return node; return new NodeWithInitialCredentials(node);
} }
@Override @Override
public Iterable<Hardware> listHardwareProfiles() { public Iterable<Hardware> listHardwareProfiles() {
return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160), return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160),
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850),
.stub("large", 8, 15360, 1690)); StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690));
} }
@Override @Override
public Iterable<Image> listImages() { public Iterable<Image> listImages() {
Credentials defaultCredentials = new Credentials("root", null); Credentials defaultCredentials = new Credentials("root", null);
// initializing as a List, as ImmutableSet does not allow you to put duplicates // initializing as a List, as ImmutableSet does not allow you to put
Builder<Image> images = ImmutableList.<Image>builder(); // duplicates
Builder<Image> images = ImmutableList.<Image> builder();
int id = 1; int id = 1;
for (boolean is64Bit : new boolean[] { true, false }) for (boolean is64Bit : new boolean[] { true, false })
for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) { for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) {
@ -154,8 +147,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
@Override @Override
public NodeMetadata getNode(String id) { public NodeMetadata getNode(String id) {
NodeMetadata node = nodes.get(id); NodeMetadata node = nodes.get(id);
return node == null ? null : NodeMetadataBuilder.fromNodeMetadata(node).credentials( return node == null ? null : NodeMetadataBuilder.fromNodeMetadata(node)
credentialStore.get("node#" + node.getId())).build(); .credentials(credentialStore.get("node#" + node.getId())).build();
} }
@Override @Override

View File

@ -37,6 +37,7 @@ import org.jclouds.compute.domain.OsFamilyVersion64Bit;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
import org.jclouds.json.Json; import org.jclouds.json.Json;
@ -95,14 +96,14 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
@BeforeClass @BeforeClass
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException {
setupCredentials(); setupCredentials();
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, ImmutableSet context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider,
.<Module> of(new Log4JLoggingModule()), setupProperties()); ImmutableSet.<Module> of(new Log4JLoggingModule()), setupProperties());
} }
@DataProvider(name = "osSupported") @DataProvider(name = "osSupported")
public Object[][] osSupported() { public Object[][] osSupported() {
return convertToArray(Sets.filter(provideAllOperatingSystems(), Predicates return convertToArray(Sets.filter(provideAllOperatingSystems(),
.not(defineUnsupportedOperatingSystems()))); Predicates.not(defineUnsupportedOperatingSystems())));
} }
protected Object[][] convertToArray(Set<OsFamilyVersion64Bit> supportedOperatingSystems) { protected Object[][] convertToArray(Set<OsFamilyVersion64Bit> supportedOperatingSystems) {
@ -139,8 +140,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
@Test(dataProvider = "osSupported") @Test(dataProvider = "osSupported")
public void testTemplateBuilderCanFind(OsFamilyVersion64Bit matrix) throws InterruptedException { public void testTemplateBuilderCanFind(OsFamilyVersion64Bit matrix) throws InterruptedException {
TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family)
matrix.is64Bit); .os64Bit(matrix.is64Bit);
if (!matrix.version.equals("")) if (!matrix.version.equals(""))
builder.osVersionMatches("^" + matrix.version + "$"); builder.osVersionMatches("^" + matrix.version + "$");
Template template = builder.build(); Template template = builder.build();
@ -152,8 +153,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
@Test(dataProvider = "osNotSupported", expectedExceptions = NoSuchElementException.class) @Test(dataProvider = "osNotSupported", expectedExceptions = NoSuchElementException.class)
public void testTemplateBuilderCannotFind(OsFamilyVersion64Bit matrix) throws InterruptedException { public void testTemplateBuilderCannotFind(OsFamilyVersion64Bit matrix) throws InterruptedException {
TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family)
matrix.is64Bit); .os64Bit(matrix.is64Bit);
if (!matrix.version.equals("")) if (!matrix.version.equals(""))
builder.osVersionMatches("^" + matrix.version + "$"); builder.osVersionMatches("^" + matrix.version + "$");
builder.build(); builder.build();
@ -195,8 +196,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
case REGION: case REGION:
assertProvider(location.getParent()); assertProvider(location.getParent());
assert location.getIso3166Codes().size() == 0 assert location.getIso3166Codes().size() == 0
|| location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||"
+ " ||" + location.getParent(); + location.getParent();
break; break;
case ZONE: case ZONE:
Location provider = location.getParent().getParent(); Location provider = location.getParent().getParent();
@ -205,8 +206,8 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
provider = location.getParent(); provider = location.getParent();
assertProvider(provider); assertProvider(provider);
assert location.getIso3166Codes().size() == 0 assert location.getIso3166Codes().size() == 0
|| location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||"
+ " ||" + location.getParent(); + location.getParent();
break; break;
case HOST: case HOST:
Location provider2 = location.getParent().getParent().getParent(); Location provider2 = location.getParent().getParent().getParent();
@ -220,7 +221,7 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseVersionedServiceLi
} }
@Test @Test
public void testTemplateBuilderWithImageIdsSpecified() throws IOException { public void testTemplateBuilderWithImageIdSpecified() throws IOException {
Template defaultTemplate = context.getComputeService().templateBuilder().build(); Template defaultTemplate = context.getComputeService().templateBuilder().build();
ComputeServiceContext context = null; 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.<Module> 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.<Module> 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) { void assertProvider(Location provider) {
assertEquals(provider.getScope(), LocationScope.PROVIDER); assertEquals(provider.getScope(), LocationScope.PROVIDER);
assertEquals(provider.getParent(), null); assertEquals(provider.getParent(), null);

View File

@ -18,15 +18,16 @@
*/ */
package org.jclouds.compute; 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.Constants;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.BeforeClass; 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 * @author Jason King
@ -39,6 +40,7 @@ public abstract class BaseVersionedServiceLiveTest {
protected String endpoint; protected String endpoint;
protected String apiversion; protected String apiversion;
protected String imageId; protected String imageId;
protected String loginUser;
protected Properties setupRestProperties() { protected Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties"); return RestContextFactory.getPropertiesFromResource("/rest.properties");
@ -46,8 +48,10 @@ public abstract class BaseVersionedServiceLiveTest {
protected Properties setupProperties() { protected Properties setupProperties() {
if (emptyToNull(provider) == null) throw new NullPointerException("provider must not be null or empty:"+provider); if (emptyToNull(provider) == null)
if (emptyToNull(identity) == null) throw new NullPointerException("identity must not be null or empty:"+provider); 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(); Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
@ -63,6 +67,8 @@ public abstract class BaseVersionedServiceLiveTest {
overrides.setProperty(provider + ".apiversion", apiversion); overrides.setProperty(provider + ".apiversion", apiversion);
if (imageId != null) if (imageId != null)
overrides.setProperty(provider + ".image-id", imageId); overrides.setProperty(provider + ".image-id", imageId);
if (loginUser != null)
overrides.setProperty(provider + ".login-user", loginUser);
return overrides; return overrides;
} }
@ -74,7 +80,7 @@ public abstract class BaseVersionedServiceLiveTest {
endpoint = System.getProperty("test." + provider + ".endpoint"); endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion"); apiversion = System.getProperty("test." + provider + ".apiversion");
imageId = System.getProperty("test." + provider + ".image-id"); imageId = System.getProperty("test." + provider + ".image-id");
loginUser = System.getProperty("test." + provider + ".login-user");
} }
} }

View File

@ -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<String, Credentials> 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<String, Credentials> 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<String, Credentials> 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<String, Credentials> 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<String, Credentials> 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<String, Credentials> 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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -32,6 +32,7 @@ import com.google.common.collect.Lists;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Credentials { public class Credentials {
public static final Credentials NO_CREDENTIALS = new Credentials(null, null);
public static class Builder<T extends Credentials> { public static class Builder<T extends Credentials> {
private String identity; private String identity;

View File

@ -162,7 +162,7 @@ public class AWSEC2ImageParserTest {
.getInstance(Json.class)); .getInstance(Json.class));
Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource); Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource);
EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map,
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation), new AWSEC2ReviseParsedImage(map)); .ofInstance(defaultLocation), new AWSEC2ReviseParsedImage(map));
return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull()));

View File

@ -55,12 +55,12 @@ public class CloudSigmaLasVegasTemplateBuilderLiveTest extends BaseTemplateBuild
return (input.version.equals("11.04") && input.is64Bit) return (input.version.equals("11.04") && input.is64Bit)
|| (input.version.equals("10.04") && !input.is64Bit) || input.version.equals(""); || (input.version.equals("10.04") && !input.is64Bit) || input.version.equals("");
case SOLARIS: case SOLARIS:
return false; return input.version.equals("") && input.is64Bit;
case DEBIAN: case DEBIAN:
return false; return false;
case CENTOS: case CENTOS:
return input.version.equals("") || (input.version.equals("6.0") && !input.is64Bit) return (input.version.equals("") || input.version.equals("6.0") || input.version.equals("5.7"))
|| (input.version.equals("5.5") && input.is64Bit); && input.is64Bit;
case WINDOWS: case WINDOWS:
return ((input.version.equals("2008 R2") || input.version.equals("2003") || input.version.equals("")) && input.is64Bit); return ((input.version.equals("2008 R2") || input.version.equals("2003") || input.version.equals("")) && input.is64Bit);
default: default:
@ -76,8 +76,9 @@ public class CloudSigmaLasVegasTemplateBuilderLiveTest extends BaseTemplateBuild
Template defaultTemplate = context.getComputeService().templateBuilder().build(); Template defaultTemplate = context.getComputeService().templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); 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().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getImage().getDefaultCredentials().identity, "cloudsigma");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
} }

View File

@ -80,6 +80,7 @@ public class CloudSigmaZurichTemplateBuilderLiveTest extends BaseTemplateBuilder
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getId(), "7fad4fe1-daf3-4cb8-a847-082aae4d8506"); assertEquals(defaultTemplate.getImage().getId(), "7fad4fe1-daf3-4cb8-a847-082aae4d8506");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getImage().getDefaultCredentials().identity, "cloudsigma");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
} }

View File

@ -99,7 +99,7 @@ public class EucalyptusPartnerCloudReviseParsedImageTest {
.getInstance(Json.class)); .getInstance(Json.class));
Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource); Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource);
EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(null), map,
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation), new EucalyptusPartnerCloudReviseParsedImage(map)); .ofInstance(defaultLocation), new EucalyptusPartnerCloudReviseParsedImage(map));
return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull()));

View File

@ -18,11 +18,15 @@
*/ */
package org.jclouds.gogrid.config.internal; package org.jclouds.gogrid.config.internal;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.config.ResolvesImages; import org.jclouds.compute.config.ResolvesImages;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.javax.annotation.Nullable;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -38,11 +42,16 @@ public class GoGridResolveImagesModule extends AbstractModule {
} }
@Singleton @Singleton
public static class GoGridPopulateDefaultLoginCredentialsForImageStrategy implements public static class GoGridPopulateDefaultLoginCredentialsForImageStrategy extends ReturnCredentialsBoundToImage {
PopulateDefaultLoginCredentialsForImageStrategy { @Inject
public GoGridPopulateDefaultLoginCredentialsForImageStrategy(@Nullable @Named("image") Credentials creds) {
super(creds);
}
@Override @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
if (creds != null)
return creds;
return new Credentials("root", null); return new Credentials("root", null);
} }
} }

View File

@ -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 static org.jclouds.savvis.vpdc.reference.VPDCConstants.PROPERTY_VPDC_VDC_EMAIL;
import java.net.URI; import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Named; import javax.inject.Named;
@ -34,7 +33,6 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.CIMOperatingSystem; import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.Volume;
import org.jclouds.domain.Credentials;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.savvis.vpdc.VPDCClient; import org.jclouds.savvis.vpdc.VPDCClient;
import org.jclouds.savvis.vpdc.domain.Network; 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.base.Predicate;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.inject.Inject; import com.google.inject.Inject;
; ;
/** /**
* defines the connection between the {@link VPDCClient} implementation and the jclouds * defines the connection between the {@link VPDCClient} implementation and the
* {@link ComputeService} * jclouds {@link ComputeService}
* *
*/ */
@Singleton @Singleton
@ -77,8 +75,7 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter<VM, VMSp
} }
@Override @Override
public VM createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<VM> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
Map<String, Credentials> credentialStore) {
String networkTierName = template.getLocation().getId(); String networkTierName = template.getLocation().getId();
String vpdcId = template.getLocation().getParent().getId(); String vpdcId = template.getLocation().getParent().getId();
String billingSiteId = template.getLocation().getParent().getParent().getId(); String billingSiteId = template.getLocation().getParent().getParent().getId();
@ -104,7 +101,8 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter<VM, VMSp
if (taskTester.apply(task.getId())) { if (taskTester.apply(task.getId())) {
try { try {
return this.getNode(task.getResult().getHref().toASCIIString()); VM returnVal = this.getNode(task.getResult().getHref().toASCIIString());
return new NodeAndInitialCredentials<VM>(returnVal, returnVal.getId(), null);
} finally { } finally {
// TODO: get the credentials relevant to the billingSiteId/Org // TODO: get the credentials relevant to the billingSiteId/Org
// credentialStore.put(id, new Credentials(orgId, orgUser)); // credentialStore.put(id, new Credentials(orgId, orgUser));

View File

@ -56,7 +56,7 @@ public class SoftLayerPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "LOCAL"); properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "LOCAL");
// 10, 100, 1000 // 10, 100, 1000
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "10"); properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "10");
properties.setProperty(PROPERTY_ISO3166_CODES, "SG,US-CA,US-TX,US-VA,US-WA,US-TX"); properties.setProperty(PROPERTY_ISO3166_CODES, "SG,NL,US-CA,US-TX,US-VA,US-WA,US-TX");
Builder<String> prices = ImmutableSet.<String> builder(); Builder<String> prices = ImmutableSet.<String> builder();
prices.add("21"); // 1 IP Address prices.add("21"); // 1 IP Address
prices.add("55"); // Host Ping: categoryCode: monitoring, notification prices.add("55"); // Host Ping: categoryCode: monitoring, notification

View File

@ -18,24 +18,27 @@
*/ */
package org.jclouds.softlayer.compute.functions; 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.Image;
import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.softlayer.domain.ProductItem; import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductItemPrice; import org.jclouds.softlayer.domain.ProductItemPrice;
import javax.annotation.Resource; import com.google.common.base.Function;
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;
/** /**
* @author Jason King * @author Jason King
@ -73,6 +76,7 @@ public class ProductItemToImage implements Function<ProductItem, Image> {
return new ImageBuilder() return new ImageBuilder()
.ids(imageId().apply(productItem)) .ids(imageId().apply(productItem))
.description(productItem.getDescription()) .description(productItem.getDescription())
.defaultCredentials(new Credentials("root", null))
.operatingSystem(os) .operatingSystem(os)
.build(); .build();
} }

View File

@ -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_LOGIN_DETAILS_DELAY;
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED; import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -65,12 +64,12 @@ import com.google.common.base.Predicate;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
/** /**
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds * defines the connection between the {@link SoftLayerClient} implementation and
* {@link ComputeService} * the jclouds {@link ComputeService}
* *
*/ */
@Singleton @Singleton
@ -112,8 +111,8 @@ public class SoftLayerComputeServiceAdapter implements
} }
@Override @Override
public VirtualGuest createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name, public NodeAndInitialCredentials<VirtualGuest> createNodeWithGroupEncodedIntoName(String group, String name,
Template template, Map<String, Credentials> credentialStore) { Template template) {
checkNotNull(template, "template was null"); checkNotNull(template, "template was null");
checkNotNull(template.getOptions(), "template options was null"); checkNotNull(template.getOptions(), "template options was null");
checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class), checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
@ -124,8 +123,8 @@ public class SoftLayerComputeServiceAdapter implements
VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build(); VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId()).location( ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId())
template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template)) .location(template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
.virtualGuest(newGuest).build(); .virtualGuest(newGuest).build();
logger.debug(">> ordering new virtualGuest domain(%s) hostname(%s)", domainName, name); logger.debug(">> ordering new virtualGuest domain(%s) hostname(%s)", domainName, name);
@ -137,14 +136,13 @@ public class SoftLayerComputeServiceAdapter implements
boolean orderInSystem = loginDetailsTester.apply(result); boolean orderInSystem = loginDetailsTester.apply(result);
logger.trace("<< virtualGuest(%s) complete(%s)", result.getId(), orderInSystem); logger.trace("<< virtualGuest(%s) complete(%s)", result.getId(), orderInSystem);
checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result,
.toString(guestLoginDelay)); Long.toString(guestLoginDelay));
result = client.getVirtualGuestClient().getVirtualGuest(result.getId()); result = client.getVirtualGuestClient().getVirtualGuest(result.getId());
Password pw = get(result.getOperatingSystem().getPasswords(), 0); Password pw = get(result.getOperatingSystem().getPasswords(), 0);
Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword()); return new NodeAndInitialCredentials<VirtualGuest>(result, result.getId() + "", new Credentials(pw.getUsername(),
credentialStore.put("node#" + result.getId(), credentials); pw.getPassword()));
return result;
} }
private Iterable<ProductItemPrice> getPrices(Template template) { private Iterable<ProductItemPrice> getPrices(Template template) {
@ -158,8 +156,8 @@ public class SoftLayerComputeServiceAdapter implements
int id = Integer.parseInt(hardwareId); int id = Integer.parseInt(hardwareId);
result.add(ProductItemPrice.builder().id(id).build()); result.add(ProductItemPrice.builder().id(id).build());
} }
ProductItem uplinkItem = find(productPackageSupplier.get().getItems(), and(capacity(portSpeed), ProductItem uplinkItem = find(productPackageSupplier.get().getItems(),
categoryCode("port_speed"))); and(capacity(portSpeed), categoryCode("port_speed")));
result.add(get(uplinkItem.getPrices(), 0)); result.add(get(uplinkItem.getPrices(), 0));
result.addAll(prices); result.addAll(prices);
return result.build(); return result.build();
@ -187,7 +185,7 @@ public class SoftLayerComputeServiceAdapter implements
@Override @Override
public Iterable<VirtualGuest> listNodes() { public Iterable<VirtualGuest> listNodes() {
return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate<VirtualGuest>(){ return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate<VirtualGuest>() {
@Override @Override
public boolean apply(VirtualGuest arg0) { public boolean apply(VirtualGuest arg0) {

View File

@ -21,11 +21,13 @@ package org.jclouds.softlayer.compute;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertFalse;
import java.util.Map;
import java.util.Random; import java.util.Random;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Template; 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.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
@ -40,7 +42,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.inject.Guice; import com.google.inject.Guice;
@ -48,7 +49,7 @@ import com.google.inject.Guice;
public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest { public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest {
private SoftLayerComputeServiceAdapter adapter; private SoftLayerComputeServiceAdapter adapter;
private VirtualGuest guest; private NodeAndInitialCredentials<VirtualGuest> guest;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() { public void setupClient() {
@ -62,6 +63,9 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
assertFalse(Iterables.isEmpty(adapter.listLocations())); assertFalse(Iterables.isEmpty(adapter.listLocations()));
} }
private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
new DefaultCredentialsFromImageOrOverridingCredentials());
@Test @Test
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() { public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
String group = "foo"; String group = "foo";
@ -71,15 +75,13 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
// test passing custom options // test passing custom options
template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org"); template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org");
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap(); guest = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
guest = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); assertEquals(guest.getNode().getHostname(), name);
assertEquals(guest.getHostname(), name); assertEquals(guest.getNodeId(), guest.getNode().getId());
assertEquals(guest.getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName()); assertEquals(guest.getNode().getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class)
// check other things, like cpu correct, mem correct, image/os is correct .getDomainName());
// (as possible) assert InetAddresses.isInetAddress(guest.getNode().getPrimaryBackendIpAddress()) : guest;
assert credentialStore.containsKey("node#" + guest.getId()) : "credentials to log into guest not found " + guest; doConnectViaSsh(guest.getNode(), prioritizeCredentialsFromTemplate.apply(template, guest.getCredentials()));
assert InetAddresses.isInetAddress(guest.getPrimaryBackendIpAddress()) : guest;
doConnectViaSsh(guest, credentialStore.get("node#" + guest.getId()));
} }
protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) { protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) {
@ -111,7 +113,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
@AfterGroups(groups = "live") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {
if (guest != null) if (guest != null)
adapter.destroyNode(guest.getId() + ""); adapter.destroyNode(guest.getNodeId() + "");
super.tearDown(); super.tearDown();
} }
} }

View File

@ -68,7 +68,7 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
case UBUNTU: case UBUNTU:
return input.version.equals("") || input.version.equals("10.04") || input.version.equals("8"); return input.version.equals("") || input.version.equals("10.04") || input.version.equals("8");
case DEBIAN: case DEBIAN:
return input.version.equals("") || input.version.equals("5.0"); return input.version.equals("") || input.version.matches("[56].0");
case FEDORA: case FEDORA:
return input.version.equals("") || input.version.equals("13") || input.version.equals("15"); return input.version.equals("") || input.version.equals("13") || input.version.equals("15");
case RHEL: case RHEL:
@ -219,6 +219,6 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
@Override @Override
protected Set<String> getIso3166Codes() { protected Set<String> getIso3166Codes() {
return ImmutableSet.<String> of("SG", "US-CA", "US-TX", "US-VA", "US-WA", "US-TX"); return ImmutableSet.<String> of("SG", "NL", "US-CA", "US-TX", "US-VA", "US-WA", "US-TX");
} }
} }

View File

@ -25,14 +25,12 @@ import static com.google.common.collect.Iterables.transform;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.suppliers.JustProvider; import org.jclouds.location.suppliers.JustProvider;
@ -71,8 +69,8 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
} }
@Override @Override
public IMachine createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<IMachine> createNodeWithGroupEncodedIntoName(String tag, String name,
Map<String, Credentials> credentialStore) { Template template) {
return null; return null;
} }

View File

@ -25,12 +25,15 @@ import static org.testng.Assert.assertFalse;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.json.Json; import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule; 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.base.Function;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Guice; import com.google.inject.Guice;
@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest") @Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest")
public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest { public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest {
private VirtualBoxComputeServiceAdapter adapter; private VirtualBoxComputeServiceAdapter adapter;
private IMachine machine; private NodeAndInitialCredentials<IMachine> machine;
private final Map<OsFamily, Map<String, String>> osVersionMap = new BaseComputeServiceContextModule() { private final Map<OsFamily, Map<String, String>> osVersionMap = new BaseComputeServiceContextModule() {
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.getInstance(Json.class)); .getInstance(Json.class));
@ -78,24 +80,26 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
assertFalse(Iterables.isEmpty(adapter.listLocations())); assertFalse(Iterables.isEmpty(adapter.listLocations()));
} }
private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
new DefaultCredentialsFromImageOrOverridingCredentials());
@Test @Test
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() { public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
String group = "foo"; String group = "foo";
String name = "foo-ef4"; String name = "foo-ef4";
Template template = context.getComputeService().templateBuilder().build(); Template template = context.getComputeService().templateBuilder().build();
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap(); machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
machine = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); assertEquals(machine.getNode().getName(), name);
assertEquals(machine.getName(), name); assertEquals(machine.getNodeId(), machine.getNode().getId());
// is there a place for group? // is there a place for group?
// check other things, like cpu correct, mem correct, image/os is correct // check other things, like cpu correct, mem correct, image/os is correct
// (as possible) // (as possible)
assert credentialStore.containsKey("node#" + machine.getId()) : "credentials to log into machine not found "
+ machine;
// TODO: what's the IP address? // TODO: what's the IP address?
// assert // assert
// InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) : // InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) :
// machine; // machine;
doConnectViaSsh(machine, credentialStore.get("node#" + machine.getId())); doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials()));
} }
protected void doConnectViaSsh(IMachine machine, Credentials creds) { protected void doConnectViaSsh(IMachine machine, Credentials creds) {
@ -132,7 +136,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
@AfterGroups(groups = "live") @AfterGroups(groups = "live")
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
if (machine != null) if (machine != null)
adapter.destroyNode(machine.getId() + ""); adapter.destroyNode(machine.getNodeId() + "");
super.tearDown(); super.tearDown();
} }
} }

View File

@ -20,8 +20,6 @@ package org.jclouds.servermanager.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -52,15 +50,12 @@ public class ServerManagerComputeServiceAdapter implements ComputeServiceAdapter
} }
@Override @Override
public Server createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, public NodeAndInitialCredentials<Server> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
Map<String, Credentials> credentialStore) {
// create the backend object using parameters from the template. // create the backend object using parameters from the template.
Server from = client.createServerInDC(template.getLocation().getId(), name, Server from = client.createServerInDC(template.getLocation().getId(), name,
Integer.parseInt(template.getImage().getProviderId()), Integer.parseInt(template.getImage().getProviderId()),
Integer.parseInt(template.getHardware().getProviderId())); Integer.parseInt(template.getHardware().getProviderId()));
// store the credentials so that later functions can use them return new NodeAndInitialCredentials<Server>(from, from.id + "", new Credentials(from.loginUser, from.password));
credentialStore.put(from.id + "", new Credentials(from.loginUser, from.password));
return from;
} }
@Override @Override