mirror of https://github.com/apache/jclouds.git
Issue 499:add and use import key support to aws-ec2
This commit is contained in:
parent
d7814821a3
commit
ebd4d1e432
|
@ -19,9 +19,14 @@
|
|||
|
||||
package org.jclouds.ec2.compute;
|
||||
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.util.Preconditions2.checkNotEmpty;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -40,13 +45,13 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
|||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -55,12 +60,15 @@ import org.jclouds.ec2.compute.domain.RegionAndName;
|
|||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -73,31 +81,30 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
|
||||
@Inject
|
||||
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
nodeSuspended, initScriptRunnerFactory, timeouts, executor);
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
||||
initScriptRunnerFactory, timeouts, executor);
|
||||
this.ec2Client = ec2Client;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deleteSecurityGroup(String region, String group) {
|
||||
Preconditions2.checkNotEmpty(group, "group");
|
||||
checkNotEmpty(group, "group");
|
||||
String groupName = String.format("jclouds#%s#%s", group, region);
|
||||
if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupName).size() > 0) {
|
||||
logger.debug(">> deleting securityGroup(%s)", groupName);
|
||||
|
@ -115,16 +122,54 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@VisibleForTesting
|
||||
void deleteKeyPair(String region, String group) {
|
||||
for (KeyPair keyPair : ec2Client.getKeyPairServices().describeKeyPairsInRegion(region)) {
|
||||
if (keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) {
|
||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||
// TODO: test this clear happens
|
||||
credentialsMap.remove(new RegionAndName(region, keyPair.getKeyName()));
|
||||
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
||||
if (
|
||||
// when the keypair is unique per group
|
||||
keyPair.getKeyName().equals("jclouds#" + group)
|
||||
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s", group, "[0-9a-f]+"))
|
||||
// old keypair pattern too verbose as it has an unnecessary region qualifier
|
||||
|| keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) {
|
||||
Set<String> instancesUsingKeyPair = extractIdsFromInstances(filter(concat(ec2Client.getInstanceServices()
|
||||
.describeInstancesInRegion(region)), usingKeyPairAndNotDead(keyPair)));
|
||||
if (instancesUsingKeyPair.size() > 0) {
|
||||
logger.debug("<< inUse keyPair(%s), by (%s)", keyPair.getKeyName(), instancesUsingKeyPair);
|
||||
} else {
|
||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||
// TODO: test this clear happens
|
||||
credentialsMap.remove(new RegionAndName(region, keyPair.getKeyName()));
|
||||
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ImmutableSet<String> extractIdsFromInstances(Iterable<? extends RunningInstance> deadOnes) {
|
||||
return ImmutableSet.copyOf(transform(deadOnes, new Function<RunningInstance, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(RunningInstance input) {
|
||||
return input.getId();
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
protected Predicate<RunningInstance> usingKeyPairAndNotDead(final KeyPair keyPair) {
|
||||
return new Predicate<RunningInstance>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(RunningInstance input) {
|
||||
switch (input.getInstanceState()) {
|
||||
case TERMINATED:
|
||||
case SHUTTING_DOWN:
|
||||
return false;
|
||||
}
|
||||
return keyPair.getKeyName().equals(input.getKeyName());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* like {@link BaseComputeService#destroyNodesMatching} except that this will clean implicit
|
||||
* keypairs and security groups.
|
||||
|
@ -132,20 +177,20 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@Override
|
||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
|
||||
Map<String, String> regionTags = Maps.newHashMap();
|
||||
Builder<String, String> regionGroups = ImmutableMap.<String, String> builder();
|
||||
for (NodeMetadata nodeMetadata : deadOnes) {
|
||||
if (nodeMetadata.getGroup() != null)
|
||||
regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup());
|
||||
regionGroups.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup());
|
||||
}
|
||||
for (Entry<String, String> regionTag : regionTags.entrySet()) {
|
||||
cleanUpIncidentalResources(regionTag);
|
||||
for (Entry<String, String> regionGroup : regionGroups.build().entrySet()) {
|
||||
cleanUpIncidentalResources(regionGroup);
|
||||
}
|
||||
return deadOnes;
|
||||
}
|
||||
|
||||
protected void cleanUpIncidentalResources(Entry<String, String> regionTag) {
|
||||
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
|
||||
deleteSecurityGroup(regionTag.getKey(), regionTag.getValue());
|
||||
protected void cleanUpIncidentalResources(Entry<String, String> regionGroup) {
|
||||
deleteKeyPair(regionGroup.getKey(), regionGroup.getValue());
|
||||
deleteSecurityGroup(regionGroup.getKey(), regionGroup.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.jclouds.ec2.EC2AsyncClient;
|
|||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
|
@ -76,11 +77,11 @@ import com.google.inject.TypeLiteral;
|
|||
public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
||||
|
||||
public static final Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
|
||||
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING).put(
|
||||
InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, NodeState.PENDING).put(
|
||||
InstanceState.TERMINATED, NodeState.TERMINATED).put(InstanceState.STOPPING, NodeState.PENDING)
|
||||
.put(InstanceState.STOPPED, NodeState.SUSPENDED).put(InstanceState.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
||||
.build();
|
||||
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
|
||||
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, NodeState.PENDING)
|
||||
.put(InstanceState.TERMINATED, NodeState.TERMINATED).put(InstanceState.STOPPING, NodeState.PENDING)
|
||||
.put(InstanceState.STOPPED, NodeState.SUSPENDED).put(InstanceState.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
||||
.build();
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
|
@ -104,6 +105,12 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
}).to(RunningInstanceToNodeMetadata.class);
|
||||
bind(new TypeLiteral<Function<RunningInstance, Credentials>>() {
|
||||
}).to(CredentialsForInstance.class);
|
||||
bind(new TypeLiteral<Function<RegionNameAndIngressRules, String>>() {
|
||||
}).to(CreateSecurityGroupIfNeeded.class);
|
||||
bind(new TypeLiteral<Function<RegionAndName, KeyPair>>() {
|
||||
}).to(CreateUniqueKeyPair.class);
|
||||
bind(new TypeLiteral<Function<RegionAndName, Image>>() {
|
||||
}).to(RegionAndIdToImage.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
|
@ -128,7 +135,7 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected final Map<RegionAndName, KeyPair> credentialsMap(CreateUniqueKeyPair in) {
|
||||
protected final Map<RegionAndName, KeyPair> credentialsMap(Function<RegionAndName, KeyPair> in) {
|
||||
// doesn't seem to clear when someone issues remove(key)
|
||||
// return new MapMaker().makeComputingMap(in);
|
||||
return newLinkedHashMap();
|
||||
|
@ -137,13 +144,12 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
@Named("SECURITY")
|
||||
protected final Map<RegionAndName, String> securityGroupMap(CreateSecurityGroupIfNeeded in) {
|
||||
protected final Map<RegionAndName, String> securityGroupMap(Function<RegionNameAndIngressRules, String> in) {
|
||||
// doesn't seem to clear when someone issues remove(key)
|
||||
// return new MapMaker().makeComputingMap(in);
|
||||
return newLinkedHashMap();
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named(PROPERTY_EC2_AMI_OWNERS)
|
||||
|
@ -153,10 +159,9 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
return toArray(Splitter.on(',').split(amiOwners), String.class);
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<RegionAndName, Image> provideImageMap(RegionAndIdToImage regionAndIdToImage) {
|
||||
protected Map<RegionAndName, Image> provideImageMap(Function<RegionAndName, Image> regionAndIdToImage) {
|
||||
return new MapMaker().makeComputingMap(regionAndIdToImage);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ public class RegionAndName {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RegionTag [region=" + region + ", name=" + name + "]";
|
||||
return "[region=" + region + ", name=" + name + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -46,7 +46,7 @@ public class CreateUniqueKeyPair implements Function<RegionAndName, KeyPair> {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final EC2Client ec2Client;
|
||||
protected Supplier<String> randomSuffix;
|
||||
protected final Supplier<String> randomSuffix;
|
||||
|
||||
@Inject
|
||||
public CreateUniqueKeyPair(EC2Client ec2Client, Supplier<String> randomSuffix) {
|
||||
|
@ -60,14 +60,14 @@ public class CreateUniqueKeyPair implements Function<RegionAndName, KeyPair> {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
KeyPair createNewKeyPairInRegion(String region, String tag) {
|
||||
KeyPair createNewKeyPairInRegion(String region, String group) {
|
||||
checkNotNull(region, "region");
|
||||
checkNotNull(tag, "tag");
|
||||
logger.debug(">> creating keyPair region(%s) tag(%s)", region, tag);
|
||||
checkNotNull(group, "group");
|
||||
logger.debug(">> creating keyPair region(%s) group(%s)", region, group);
|
||||
KeyPair keyPair = null;
|
||||
while (keyPair == null) {
|
||||
try {
|
||||
keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(region, getNextName(region, tag));
|
||||
keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(region, getNextName(region, group));
|
||||
logger.debug("<< created keyPair(%s)", keyPair.getKeyName());
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class CreateUniqueKeyPair implements Function<RegionAndName, KeyPair> {
|
|||
return keyPair;
|
||||
}
|
||||
|
||||
private String getNextName(String region, String tag) {
|
||||
return String.format("jclouds#%s#%s#%s", tag, region, randomSuffix.get());
|
||||
private String getNextName(String region, String group) {
|
||||
return String.format("jclouds#%s#%s#%s", group, region, randomSuffix.get());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ public class EC2ImageParser implements Function<org.jclouds.ec2.domain.Image, Im
|
|||
@Override
|
||||
public Image apply(final org.jclouds.ec2.domain.Image from) {
|
||||
if (from.getImageType() != ImageType.MACHINE) {
|
||||
logger.trace("skipping as not a machine image(%s)", from.getId());
|
||||
return null;
|
||||
}
|
||||
ImageBuilder builder = new ImageBuilder();
|
||||
|
|
|
@ -27,21 +27,22 @@ import java.util.Set;
|
|||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -55,16 +56,16 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
|||
@VisibleForTesting
|
||||
public final Map<RegionAndName, String> securityGroupMap;
|
||||
@VisibleForTesting
|
||||
public final CreateUniqueKeyPair createUniqueKeyPair;
|
||||
public final Function<RegionAndName, KeyPair> createUniqueKeyPair;
|
||||
@VisibleForTesting
|
||||
public final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded;
|
||||
private final javax.inject.Provider<RunInstancesOptions> optionsProvider;
|
||||
public final Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded;
|
||||
protected final Provider<RunInstancesOptions> optionsProvider;
|
||||
|
||||
@Inject
|
||||
public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map<RegionAndName, KeyPair> credentialsMap,
|
||||
@Named("SECURITY") Map<RegionAndName, String> securityGroupMap, CreateUniqueKeyPair createUniqueKeyPair,
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded,
|
||||
javax.inject.Provider<RunInstancesOptions> optionsProvider) {
|
||||
@Named("SECURITY") Map<RegionAndName, String> securityGroupMap, Function<RegionAndName, KeyPair> createUniqueKeyPair,
|
||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded,
|
||||
Provider<RunInstancesOptions> optionsProvider) {
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
this.createUniqueKeyPair = createUniqueKeyPair;
|
||||
|
@ -72,13 +73,13 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
|||
this.optionsProvider = optionsProvider;
|
||||
}
|
||||
|
||||
public RunInstancesOptions execute(String region, String tag, Template template) {
|
||||
public RunInstancesOptions execute(String region, String group, Template template) {
|
||||
|
||||
RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId());
|
||||
|
||||
String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions());
|
||||
String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, template.getOptions());
|
||||
|
||||
addSecurityGroups(region, tag, template, instanceOptions);
|
||||
addSecurityGroups(region, group, template, instanceOptions);
|
||||
if (template.getOptions() instanceof EC2TemplateOptions) {
|
||||
|
||||
if (keyPairName != null)
|
||||
|
@ -90,72 +91,83 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
|||
instanceOptions.withUserData(userData);
|
||||
|
||||
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
|
||||
.getBlockDeviceMappings();
|
||||
.getBlockDeviceMappings();
|
||||
if (blockDeviceMappings.size() > 0) {
|
||||
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
|
||||
"BlockDeviceMapping only available on ebs boot");
|
||||
"BlockDeviceMapping only available on ebs boot");
|
||||
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
}
|
||||
return instanceOptions;
|
||||
}
|
||||
|
||||
protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) {
|
||||
Set<String> groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions());
|
||||
protected void addSecurityGroups(String region, String group, Template template, RunInstancesOptions instanceOptions) {
|
||||
Set<String> groups = getSecurityGroupsForTagAndOptions(region, group, template.getOptions());
|
||||
instanceOptions.withSecurityGroups(groups);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) {
|
||||
public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
|
||||
String keyPairName = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
if (options instanceof EC2TemplateOptions) {
|
||||
keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
|
||||
if (keyPairName == null)
|
||||
shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
|
||||
.shouldAutomaticallyCreateKeyPair();
|
||||
.shouldAutomaticallyCreateKeyPair();
|
||||
}
|
||||
if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
|
||||
RegionAndName regionAndName = new RegionAndName(region, tag);
|
||||
KeyPair keyPair = createUniqueKeyPair.apply(regionAndName);
|
||||
// get or create incidental resources
|
||||
// TODO race condition. we were using MapMaker, but it doesn't seem to
|
||||
// refresh properly
|
||||
// when
|
||||
// another thread
|
||||
// deletes a key
|
||||
credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair);
|
||||
keyPairName = keyPair.getKeyName();
|
||||
keyPairName = createOrImportKeyPair(region, group, options);
|
||||
}
|
||||
return keyPairName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) {
|
||||
Set<String> groups = Sets.newLinkedHashSet();
|
||||
// base EC2 driver currently does not support key import
|
||||
protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
|
||||
return createUniqueKeyPairAndPutIntoMap(region, group);
|
||||
}
|
||||
|
||||
if (tag != null) {
|
||||
String markerGroup = String.format("jclouds#%s#%s", tag, region);
|
||||
protected String createUniqueKeyPairAndPutIntoMap(String region, String group) {
|
||||
String keyPairName;
|
||||
RegionAndName regionAndName = new RegionAndName(region, group);
|
||||
KeyPair keyPair = createUniqueKeyPair.apply(regionAndName);
|
||||
keyPairName = keyPair.getKeyName();
|
||||
// get or create incidental resources
|
||||
// TODO race condition. we were using MapMaker, but it doesn't seem to
|
||||
// refresh properly
|
||||
// when
|
||||
// another thread
|
||||
// deletes a key
|
||||
credentialsMap.put(new RegionAndName(regionAndName.getRegion(), keyPairName), keyPair);
|
||||
return keyPairName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String group, TemplateOptions options) {
|
||||
Builder<String> groups = ImmutableSet.<String> builder();
|
||||
|
||||
if (group != null) {
|
||||
String markerGroup = String.format("jclouds#%s#%s", group, region);
|
||||
groups.add(markerGroup);
|
||||
|
||||
RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup;
|
||||
|
||||
if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
|
||||
false);
|
||||
false);
|
||||
groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds());
|
||||
|
||||
} else {
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options
|
||||
.getInboundPorts(), true);
|
||||
regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup,
|
||||
options.getInboundPorts(), true);
|
||||
}
|
||||
|
||||
if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) {
|
||||
securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, createSecurityGroupIfNeeded
|
||||
.apply(regionNameAndIngessRulesForMarkerGroup));
|
||||
securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup,
|
||||
createSecurityGroupIfNeeded.apply(regionNameAndIngessRulesForMarkerGroup));
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
return groups.build();
|
||||
}
|
||||
|
||||
// allows us to mock this method
|
||||
|
|
|
@ -31,12 +31,14 @@ import java.util.concurrent.Future;
|
|||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.compute.config.CustomizationResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
|
@ -77,16 +79,19 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
|||
final Predicate<RunningInstance> instancePresent;
|
||||
final Function<RunningInstance, Credentials> instanceToCredentials;
|
||||
final Map<String, Credentials> credentialStore;
|
||||
final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
|
||||
@Inject
|
||||
EC2CreateNodesInGroupThenAddToSet(
|
||||
EC2Client client,
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||
ComputeUtils utils) {
|
||||
EC2Client client,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||
ComputeUtils utils) {
|
||||
this.client = client;
|
||||
this.templateBuilderProvider = templateBuilderProvider;
|
||||
this.instancePresent = instancePresent;
|
||||
this.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
|
@ -97,10 +102,11 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
|||
|
||||
@Override
|
||||
public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||
|
||||
Iterable<? extends RunningInstance> started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group, count,
|
||||
template);
|
||||
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||
// ensure we don't mutate the input template
|
||||
template = templateBuilderProvider.get().fromTemplate(template).build();
|
||||
Iterable<? extends RunningInstance> started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group,
|
||||
count, template);
|
||||
Iterable<String> ids = transform(started, instanceToId);
|
||||
|
||||
String idsString = Joiner.on(',').join(ids);
|
||||
|
@ -111,8 +117,8 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
|||
populateCredentials(started);
|
||||
}
|
||||
|
||||
return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(started,
|
||||
runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
|
||||
return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(),
|
||||
transform(started, runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
|
||||
}
|
||||
|
||||
protected void populateCredentials(Iterable<? extends RunningInstance> started) {
|
||||
|
@ -131,12 +137,12 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
|||
// TODO write test for this
|
||||
@VisibleForTesting
|
||||
Iterable<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String group, int count,
|
||||
Template template) {
|
||||
Template template) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
|
||||
String zone = getZoneFromLocationOrNull(template.getLocation());
|
||||
|
||||
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region,
|
||||
group, template);
|
||||
group, template);
|
||||
|
||||
int countStarted = 0;
|
||||
int tries = 0;
|
||||
|
@ -145,10 +151,12 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen
|
|||
while (countStarted < count && tries++ < count) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region,
|
||||
zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters());
|
||||
zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters());
|
||||
|
||||
started = Iterables.concat(started, client.getInstanceServices().runInstancesInRegion(region, zone,
|
||||
template.getImage().getProviderId(), 1, count - countStarted, instanceOptions));
|
||||
started = Iterables.concat(
|
||||
started,
|
||||
client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1,
|
||||
count - countStarted, instanceOptions));
|
||||
|
||||
countStarted = Iterables.size(started);
|
||||
if (countStarted < count)
|
||||
|
|
|
@ -31,6 +31,52 @@ import javax.annotation.Nullable;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class KeyPair implements Comparable<KeyPair> {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[region=" + region + ", keyName=" + keyName + ", keyFingerprint=" + keyFingerprint + ", keyMaterial?="
|
||||
+ (keyMaterial != null) + "]";
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String region;
|
||||
private String keyName;
|
||||
private String keyFingerprint;
|
||||
private String keyMaterial;
|
||||
|
||||
public Builder region(String region) {
|
||||
this.region = region;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keyName(String keyName) {
|
||||
this.keyName = keyName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keyFingerprint(String keyFingerprint) {
|
||||
this.keyFingerprint = keyFingerprint;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keyMaterial(String keyMaterial) {
|
||||
this.keyMaterial = keyMaterial;
|
||||
return this;
|
||||
}
|
||||
|
||||
public KeyPair build() {
|
||||
return new KeyPair(region, keyName, keyFingerprint, keyMaterial);
|
||||
}
|
||||
|
||||
public static Builder fromKeyPair(KeyPair in) {
|
||||
return new Builder().region(in.getRegion()).keyName(in.getKeyName()).keyFingerprint(in.getKeyFingerprint())
|
||||
.keyMaterial(in.getKeyMaterial());
|
||||
}
|
||||
}
|
||||
|
||||
private final String region;
|
||||
private final String keyName;
|
||||
private final String keyFingerprint;
|
||||
|
@ -122,4 +168,7 @@ public class KeyPair implements Comparable<KeyPair> {
|
|||
return true;
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return Builder.fromKeyPair(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.jclouds.ec2.compute;
|
||||
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
|
@ -28,7 +27,6 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
|
@ -83,19 +81,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
assertEquals(byId.getImage(), defaultTemplate.getImage());
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testImagesResolveCorrectly")
|
||||
public void testDefaultTemplateBuilder() {
|
||||
assertDefaultWorks();
|
||||
}
|
||||
|
||||
protected void assertDefaultWorks() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "2010.11.1-beta");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||
public void testExtendedOptionsAndLogin() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.jclouds.ec2.options.RunInstancesOptions;
|
|||
import org.jclouds.encryption.internal.Base64;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
@ -426,10 +427,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
|||
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
|
||||
Map<RegionAndName, String> securityGroupMap = createMock(Map.class);
|
||||
CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class);
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class);
|
||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class);
|
||||
|
||||
return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap,
|
||||
createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER);
|
||||
createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER);
|
||||
}
|
||||
|
||||
private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.jclouds.compute.domain.Hardware;
|
|||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -54,6 +55,7 @@ import com.google.common.base.Predicate;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.util.Providers;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -97,25 +99,29 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
String imageId = "ami1";
|
||||
String instanceCreatedId = "instance1";
|
||||
// setup mocks
|
||||
EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy();
|
||||
TemplateBuilder templateBuilder = createMock(TemplateBuilder.class);
|
||||
EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(templateBuilder);
|
||||
InputParams input = new InputParams(location);
|
||||
InstanceClient instanceClient = createMock(InstanceClient.class);
|
||||
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
||||
RunningInstance instance = createMock(RunningInstance.class);
|
||||
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region, ImmutableSet
|
||||
.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId", "reservationId");
|
||||
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region,
|
||||
ImmutableSet.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId",
|
||||
"reservationId");
|
||||
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
||||
|
||||
// setup expectations
|
||||
expect(templateBuilder.fromTemplate(input.template)).andReturn(templateBuilder);
|
||||
expect(templateBuilder.build()).andReturn(input.template);
|
||||
expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
|
||||
expect(
|
||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region, input.tag,
|
||||
input.template)).andReturn(ec2Options);
|
||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize
|
||||
.execute(region, input.tag, input.template)).andReturn(ec2Options);
|
||||
expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
|
||||
expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
|
||||
expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce();
|
||||
expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn(
|
||||
(Reservation) reservation);
|
||||
(Reservation) reservation);
|
||||
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
|
||||
// simulate a lazy credentials fetch
|
||||
Credentials creds = new Credentials("foo", "bar");
|
||||
|
@ -128,11 +134,12 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
|
||||
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata);
|
||||
expect(
|
||||
strategy.utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(eq(input.options),
|
||||
containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes),
|
||||
eq(input.customization))).andReturn(null);
|
||||
strategy.utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(eq(input.options),
|
||||
containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes), eq(input.customization)))
|
||||
.andReturn(null);
|
||||
|
||||
// replay mocks
|
||||
replay(templateBuilder);
|
||||
replay(instanceClient);
|
||||
replay(ec2Options);
|
||||
replay(instance);
|
||||
|
@ -144,6 +151,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes, input.customization);
|
||||
|
||||
// verify mocks
|
||||
verify(templateBuilder);
|
||||
verify(instanceClient);
|
||||
verify(ec2Options);
|
||||
verify(instance);
|
||||
|
@ -152,12 +160,12 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
private static final Location REGION_AP_SOUTHEAST_1 = new LocationBuilder().scope(LocationScope.REGION).id(
|
||||
"ap-southeast-1").description("ap-southeast-1").parent(
|
||||
new LocationBuilder().scope(LocationScope.PROVIDER).id("aws-ec2").description("aws-ec2").build()).build();
|
||||
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationBuilder().scope(LocationScope.ZONE).id(
|
||||
"ap-southeast-1a").description("ap-southeast-1a").parent(
|
||||
REGION_AP_SOUTHEAST_1).build();
|
||||
private static final Location REGION_AP_SOUTHEAST_1 = new LocationBuilder().scope(LocationScope.REGION)
|
||||
.id("ap-southeast-1").description("ap-southeast-1")
|
||||
.parent(new LocationBuilder().scope(LocationScope.PROVIDER).id("aws-ec2").description("aws-ec2").build())
|
||||
.build();
|
||||
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationBuilder().scope(LocationScope.ZONE)
|
||||
.id("ap-southeast-1a").description("ap-southeast-1a").parent(REGION_AP_SOUTHEAST_1).build();
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -209,7 +217,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private EC2CreateNodesInGroupThenAddToSet setupStrategy() {
|
||||
private EC2CreateNodesInGroupThenAddToSet setupStrategy(TemplateBuilder template) {
|
||||
EC2Client client = createMock(EC2Client.class);
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class);
|
||||
Predicate<RunningInstance> instanceStateRunning = createMock(Predicate.class);
|
||||
|
@ -217,8 +225,9 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
Function<RunningInstance, Credentials> instanceToCredentials = createMock(Function.class);
|
||||
Map<String, Credentials> credentialStore = createMock(Map.class);
|
||||
ComputeUtils utils = createMock(ComputeUtils.class);
|
||||
return new EC2CreateNodesInGroupThenAddToSet(client, createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils);
|
||||
return new EC2CreateNodesInGroupThenAddToSet(client, Providers.<TemplateBuilder> of(template),
|
||||
createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, instanceStateRunning,
|
||||
runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils);
|
||||
}
|
||||
|
||||
private void replayStrategy(EC2CreateNodesInGroupThenAddToSet strategy) {
|
||||
|
|
|
@ -19,11 +19,6 @@
|
|||
|
||||
package org.jclouds.eucalyptus.compute;
|
||||
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,14 +36,6 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
|
|||
group = "eu";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertDefaultWorks() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||
public void testSuspendResume() throws Exception {
|
||||
|
|
|
@ -26,6 +26,26 @@ import org.jclouds.vcloud.terremark.domain.KeyPair;
|
|||
*/
|
||||
public class KeyPairCredentials extends Credentials {
|
||||
|
||||
public static class Builder<T extends KeyPairCredentials> extends Credentials.Builder<T> {
|
||||
private String identity;
|
||||
private KeyPair keyPair;
|
||||
|
||||
public Builder<T> identity(String identity) {
|
||||
this.identity = identity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> keyPair(KeyPair keyPair) {
|
||||
this.keyPair = keyPair;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T build() {
|
||||
return (T) new KeyPairCredentials(identity, keyPair);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
return keyPair;
|
||||
}
|
||||
|
@ -37,4 +57,8 @@ public class KeyPairCredentials extends Credentials {
|
|||
this.keyPair = keyPair;
|
||||
}
|
||||
|
||||
public Builder<? extends KeyPairCredentials> toBuilder() {
|
||||
return new Builder<KeyPairCredentials>().identity(identity).keyPair(keyPair);
|
||||
}
|
||||
|
||||
}
|
|
@ -70,16 +70,17 @@ import org.jclouds.compute.options.RunScriptOptions;
|
|||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Credentials.Builder;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -132,18 +133,17 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
@Inject
|
||||
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images,
|
||||
@Memoized Supplier<Set<? extends Hardware>> hardwareProfiles,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwareProfiles,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
this.images = checkNotNull(images, "images");
|
||||
|
@ -179,7 +179,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String group, int count, Template template)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, template);
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String group, int count, TemplateOptions templateOptions)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build());
|
||||
}
|
||||
|
||||
|
@ -202,20 +202,20 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
checkNotNull(group, "group cannot be null");
|
||||
checkNotNull(template.getLocation(), "location");
|
||||
logger.debug(">> running %d node%s group(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
||||
count > 1 ? "s" : "", group, template.getLocation().getId(), template.getImage().getId(), template
|
||||
.getHardware().getId(), template.getOptions());
|
||||
count > 1 ? "s" : "", group, template.getLocation().getId(), template.getImage().getId(), template
|
||||
.getHardware().getId(), template.getOptions());
|
||||
Set<NodeMetadata> goodNodes = newLinkedHashSet();
|
||||
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
||||
Multimap<NodeMetadata, CustomizationResponse> customizationResponses = LinkedHashMultimap.create();
|
||||
|
||||
Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(group, count, template, goodNodes, badNodes,
|
||||
customizationResponses);
|
||||
customizationResponses);
|
||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "runNodesWithTag("
|
||||
+ group + ")");
|
||||
+ group + ")");
|
||||
for (NodeMetadata node : concat(goodNodes, badNodes.keySet()))
|
||||
if (node.getCredentials() != null)
|
||||
credentialStore.put("node#" + node.getId(), node.getCredentials());
|
||||
|
@ -227,7 +227,7 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build());
|
||||
|
||||
}
|
||||
|
@ -274,23 +274,23 @@ public class BaseComputeService implements ComputeService {
|
|||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> destroying nodes matching(%s)", filter);
|
||||
Set<NodeMetadata> set = newLinkedHashSet(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
|
||||
new Function<NodeMetadata, Future<NodeMetadata>>() {
|
||||
new Function<NodeMetadata, Future<NodeMetadata>>() {
|
||||
|
||||
// TODO make an async interface instead of re-wrapping
|
||||
@Override
|
||||
public Future<NodeMetadata> apply(final NodeMetadata from) {
|
||||
return executor.submit(new Callable<NodeMetadata>() {
|
||||
// TODO make an async interface instead of re-wrapping
|
||||
@Override
|
||||
public Future<NodeMetadata> apply(final NodeMetadata from) {
|
||||
return executor.submit(new Callable<NodeMetadata>() {
|
||||
|
||||
@Override
|
||||
public NodeMetadata call() throws Exception {
|
||||
destroyNode(from.getId());
|
||||
return from;
|
||||
}
|
||||
@Override
|
||||
public NodeMetadata call() throws Exception {
|
||||
destroyNode(from.getId());
|
||||
return from;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, executor, null, logger, "destroyNodesMatching(" + filter + ")"));
|
||||
}, executor, null, logger, "destroyNodesMatching(" + filter + ")"));
|
||||
logger.debug("<< destroyed(%d)", set.size());
|
||||
return set;
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ public class BaseComputeService implements ComputeService {
|
|||
* if none found
|
||||
*/
|
||||
Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(
|
||||
Predicate<NodeMetadata> filter) {
|
||||
Predicate<NodeMetadata> filter) {
|
||||
Iterable<? extends NodeMetadata> nodes = nodesMatchingFilterAndNotTerminated(filter);
|
||||
if (Iterables.size(nodes) == 0)
|
||||
throw new NoSuchElementException("no nodes matched filter: " + filter);
|
||||
|
@ -394,15 +394,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void rebootNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> rebooting nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
rebootNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
rebootNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "rebootNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "rebootNodesMatching(" + filter + ")");
|
||||
logger.debug("<< rebooted");
|
||||
}
|
||||
|
||||
|
@ -425,15 +425,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void resumeNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> resuming nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
resumeNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
resumeNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "resumeNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "resumeNodesMatching(" + filter + ")");
|
||||
logger.debug("<< resumed");
|
||||
}
|
||||
|
||||
|
@ -456,15 +456,15 @@ public class BaseComputeService implements ComputeService {
|
|||
public void suspendNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> suspending nodes matching(%s)", filter);
|
||||
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter),
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
suspendNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
new Function<NodeMetadata, Future<Void>>() {
|
||||
// TODO use native async
|
||||
@Override
|
||||
public Future<Void> apply(NodeMetadata from) {
|
||||
suspendNode(from.getId());
|
||||
return immediateFuture(null);
|
||||
}
|
||||
|
||||
}, executor, null, logger, "suspendNodesMatching(" + filter + ")");
|
||||
}, executor, null, logger, "suspendNodesMatching(" + filter + ")");
|
||||
logger.debug("<< suspended");
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
|
@ -482,10 +482,10 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript,
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
try {
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(Strings2.toStringAndClose(checkNotNull(runScript,
|
||||
"runScript").getInput())), options);
|
||||
return runScriptOnNodesMatching(filter,
|
||||
Statements.exec(Strings2.toStringAndClose(checkNotNull(runScript, "runScript").getInput())), options);
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
|
@ -497,7 +497,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")));
|
||||
}
|
||||
|
||||
|
@ -506,15 +506,15 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||
String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")),
|
||||
RunScriptOptions.NONE);
|
||||
RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -522,7 +522,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript,
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
RunScriptOptions options) throws RunScriptOnNodesException {
|
||||
|
||||
checkNotNull(filter, "filter");
|
||||
checkNotNull(runScript, "runScript");
|
||||
|
@ -534,11 +534,11 @@ public class BaseComputeService implements ComputeService {
|
|||
Map<?, Exception> exceptions = ImmutableMap.<Object, Exception> of();
|
||||
|
||||
Iterable<? extends RunScriptOnNode> scriptRunners = transformNodesIntoInitializedScriptRunners(
|
||||
nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), runScript, options, badNodes);
|
||||
nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), runScript, options, badNodes);
|
||||
if (Iterables.size(scriptRunners) > 0) {
|
||||
for (RunScriptOnNode runner : scriptRunners) {
|
||||
responses.put(runner.getNode(), executor.submit(new RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||
runner, goodNodes, badNodes)));
|
||||
runner, goodNodes, badNodes)));
|
||||
}
|
||||
exceptions = awaitCompletion(responses, executor, null, logger, "runScriptOnNodesMatching(" + filter + ")");
|
||||
}
|
||||
|
@ -550,10 +550,11 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
private Iterable<? extends RunScriptOnNode> transformNodesIntoInitializedScriptRunners(
|
||||
Iterable<? extends NodeMetadata> nodes, Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
return filter(transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes),
|
||||
executor, null, logger, "initialize script runners"), notNull());
|
||||
Iterable<? extends NodeMetadata> nodes, Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
return filter(
|
||||
transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes),
|
||||
executor, null, logger, "initialize script runners"), notNull());
|
||||
}
|
||||
|
||||
private Set<? extends NodeMetadata> detailsOnAllNodes() {
|
||||
|
@ -566,13 +567,13 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
private final class TransformNodesIntoInitializedScriptRunners implements
|
||||
Function<NodeMetadata, Future<RunScriptOnNode>> {
|
||||
Function<NodeMetadata, Future<RunScriptOnNode>> {
|
||||
private final Map<NodeMetadata, Exception> badNodes;
|
||||
private final Statement script;
|
||||
private final RunScriptOptions options;
|
||||
|
||||
private TransformNodesIntoInitializedScriptRunners(Statement script, RunScriptOptions options,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
this.badNodes = checkNotNull(badNodes, "badNodes");
|
||||
this.script = checkNotNull(script, "script");
|
||||
this.options = checkNotNull(options, "options");
|
||||
|
@ -581,8 +582,14 @@ public class BaseComputeService implements ComputeService {
|
|||
@Override
|
||||
public Future<RunScriptOnNode> apply(NodeMetadata node) {
|
||||
checkNotNull(node, "node");
|
||||
if (options.getOverrideCredentials() != null) {
|
||||
node = NodeMetadataBuilder.fromNodeMetadata(node).credentials(options.getOverrideCredentials()).build();
|
||||
if (options.getOverridingCredentials() != null) {
|
||||
Builder<? extends Credentials> builder = node.getCredentials() != null ? node.getCredentials().toBuilder()
|
||||
: new Credentials.Builder<Credentials>();
|
||||
if (options.getOverridingCredentials().identity != null)
|
||||
builder.identity(options.getOverridingCredentials().identity);
|
||||
if (options.getOverridingCredentials().credential != null)
|
||||
builder.credential(options.getOverridingCredentials().credential);
|
||||
node = NodeMetadataBuilder.fromNodeMetadata(node).credentials(builder.build()).build();
|
||||
}
|
||||
return executor.submit(initScriptRunnerFactory.create(node, script, options, badNodes));
|
||||
}
|
||||
|
|
|
@ -34,6 +34,26 @@ import com.google.common.collect.Lists;
|
|||
*/
|
||||
public class Credentials {
|
||||
|
||||
public static class Builder<T extends Credentials> {
|
||||
private String identity;
|
||||
private String credential;
|
||||
|
||||
public Builder<T> identity(String identity) {
|
||||
this.identity = identity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> credential(String credential) {
|
||||
this.credential = credential;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T build() {
|
||||
return (T) new Credentials(identity, credential);
|
||||
}
|
||||
}
|
||||
|
||||
public final String identity;
|
||||
public final String credential;
|
||||
|
||||
|
@ -45,7 +65,7 @@ public class Credentials {
|
|||
public static Credentials parse(URI uri) {
|
||||
checkNotNull(uri, "uri");
|
||||
List<String> userInfo = Lists.newArrayList(Splitter.on(':').split(
|
||||
checkNotNull(uri.getUserInfo(), "no userInfo in " + uri)));
|
||||
checkNotNull(uri.getUserInfo(), "no userInfo in " + uri)));
|
||||
String identity = checkNotNull(userInfo.get(0), "no username in " + uri.getUserInfo());
|
||||
if (Strings2.isUrlEncoded(identity)) {
|
||||
identity = Strings2.urlDecode(identity);
|
||||
|
@ -57,6 +77,10 @@ public class Credentials {
|
|||
return new Credentials(identity, credential);
|
||||
}
|
||||
|
||||
public Builder<? extends Credentials> toBuilder() {
|
||||
return new Builder<Credentials>().identity(identity).credential(credential);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
|
|
@ -22,8 +22,8 @@ package org.jclouds.aws.ec2.compute;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -43,13 +43,13 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -75,44 +75,47 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
|
||||
@Inject
|
||||
protected AWSEC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
nodeSuspended, initScriptRunnerFactory, timeouts, executor, ec2Client, credentialsMap, securityGroupMap);
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended,
|
||||
initScriptRunnerFactory, timeouts, executor, ec2Client, credentialsMap, securityGroupMap);
|
||||
this.ec2Client = ec2Client;
|
||||
this.placementGroupMap = placementGroupMap;
|
||||
this.placementGroupDeleted = placementGroupDeleted;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deletePlacementGroup(String region, String tag) {
|
||||
Preconditions2.checkNotEmpty(tag, "tag");
|
||||
String group = String.format("jclouds#%s#%s", tag, region);
|
||||
void deletePlacementGroup(String region, String group) {
|
||||
Preconditions2.checkNotEmpty(group, "group");
|
||||
// placementGroupName must be unique within an account per
|
||||
// http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?using_cluster_computing.html
|
||||
String placementGroup = String.format("jclouds#%s#%s", group, region);
|
||||
try {
|
||||
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) {
|
||||
logger.debug(">> deleting placementGroup(%s)", group);
|
||||
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, placementGroup).size() > 0) {
|
||||
logger.debug(">> deleting placementGroup(%s)", placementGroup);
|
||||
try {
|
||||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)),
|
||||
String.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||
placementGroupMap.remove(new RegionAndName(region, group));
|
||||
logger.debug("<< deleted placementGroup(%s)", group);
|
||||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, placementGroup);
|
||||
checkState(
|
||||
placementGroupDeleted.apply(new PlacementGroup(region, placementGroup, "cluster", State.PENDING)),
|
||||
String.format("placementGroup region(%s) name(%s) failed to delete", region, placementGroup));
|
||||
placementGroupMap.remove(new RegionAndName(region, placementGroup));
|
||||
logger.debug("<< deleted placementGroup(%s)", placementGroup);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("<< inUse placementGroup(%s)", group);
|
||||
logger.debug("<< inUse placementGroup(%s)", placementGroup);
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException e) {
|
||||
|
@ -120,6 +123,7 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanUpIncidentalResources(Entry<String, String> regionTag) {
|
||||
super.cleanUpIncidentalResources(regionTag);
|
||||
deletePlacementGroup(regionTag.getKey(), regionTag.getValue());
|
||||
|
|
|
@ -34,10 +34,13 @@ import org.jclouds.aws.ec2.AWSEC2Client;
|
|||
import org.jclouds.aws.ec2.compute.AWSEC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial;
|
||||
import org.jclouds.aws.ec2.functions.ImportOrReturnExistingKeypair;
|
||||
import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
|
||||
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
|
@ -45,10 +48,14 @@ import org.jclouds.compute.options.TemplateOptions;
|
|||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.RegionAndIdToImage;
|
||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
@ -75,6 +82,14 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep
|
|||
}).to(RunningInstanceToNodeMetadata.class);
|
||||
bind(new TypeLiteral<Function<RunningInstance, Credentials>>() {
|
||||
}).to(CredentialsForInstance.class);
|
||||
bind(new TypeLiteral<Function<RegionNameAndIngressRules, String>>() {
|
||||
}).to(CreateSecurityGroupIfNeeded.class);
|
||||
bind(new TypeLiteral<Function<RegionAndName, KeyPair>>() {
|
||||
}).to(CreateUniqueKeyPair.class);
|
||||
bind(new TypeLiteral<Function<RegionNameAndPublicKeyMaterial, KeyPair>>() {
|
||||
}).to(ImportOrReturnExistingKeypair.class);
|
||||
bind(new TypeLiteral<Function<RegionAndName, Image>>() {
|
||||
}).to(RegionAndIdToImage.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
}).to(new TypeLiteral<ComputeServiceContextImpl<AWSEC2Client, AWSEC2AsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
|
|
|
@ -100,7 +100,7 @@ public class AWSEC2ReviseParsedImage implements ReviseParsedImage {
|
|||
} catch (IllegalArgumentException e) {
|
||||
logger.debug("<< didn't match os(%s)", from.getImageLocation());
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.debug("<< didn't match at all(%s)", from.getImageLocation());
|
||||
logger.trace("<< didn't match at all(%s)", from.getImageLocation());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,26 +19,35 @@
|
|||
|
||||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Predicates.and;
|
||||
import static com.google.common.base.Predicates.or;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial;
|
||||
import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded;
|
||||
import org.jclouds.aws.ec2.options.AWSRunInstancesOptions;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,31 +55,37 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
*/
|
||||
@Singleton
|
||||
public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions extends
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@VisibleForTesting
|
||||
final Map<RegionAndName, String> placementGroupMap;
|
||||
@VisibleForTesting
|
||||
final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded;
|
||||
@VisibleForTesting
|
||||
final Function<RegionNameAndPublicKeyMaterial, KeyPair> importExistingKeyPair;
|
||||
|
||||
@Inject
|
||||
public CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair,
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded,
|
||||
javax.inject.Provider<RunInstancesOptions> optionsProvider,
|
||||
CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) {
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||
Function<RegionAndName, KeyPair> createUniqueKeyPair,
|
||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded,
|
||||
Provider<RunInstancesOptions> optionsProvider, CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded,
|
||||
Function<RegionNameAndPublicKeyMaterial, KeyPair> importExistingKeyPair) {
|
||||
super(credentialsMap, securityGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, optionsProvider);
|
||||
this.placementGroupMap = placementGroupMap;
|
||||
this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded;
|
||||
this.importExistingKeyPair = importExistingKeyPair;
|
||||
}
|
||||
|
||||
public AWSRunInstancesOptions execute(String region, String tag, Template template) {
|
||||
AWSRunInstancesOptions instanceOptions = AWSRunInstancesOptions.class.cast(super.execute(region, tag, template));
|
||||
public AWSRunInstancesOptions execute(String region, String group, Template template) {
|
||||
AWSRunInstancesOptions instanceOptions = AWSRunInstancesOptions.class
|
||||
.cast(super.execute(region, group, template));
|
||||
|
||||
String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise(
|
||||
region, tag, template.getOptions())
|
||||
: null;
|
||||
region, group, template.getOptions()) : null;
|
||||
|
||||
if (placementGroupName != null)
|
||||
instanceOptions.inPlacementGroup(placementGroupName);
|
||||
|
@ -82,17 +97,19 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) {
|
||||
String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
|
||||
String placementGroupName = null;
|
||||
boolean shouldAutomaticallyCreatePlacementGroup = true;
|
||||
if (options instanceof EC2TemplateOptions) {
|
||||
placementGroupName = AWSEC2TemplateOptions.class.cast(options).getPlacementGroup();
|
||||
if (placementGroupName == null)
|
||||
shouldAutomaticallyCreatePlacementGroup = AWSEC2TemplateOptions.class.cast(options)
|
||||
.shouldAutomaticallyCreatePlacementGroup();
|
||||
.shouldAutomaticallyCreatePlacementGroup();
|
||||
}
|
||||
if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) {
|
||||
placementGroupName = String.format("jclouds#%s#%s", tag, region);
|
||||
// placementGroupName must be unique within an account per
|
||||
// http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?using_cluster_computing.html
|
||||
placementGroupName = String.format("jclouds#%s#%s", group, region);
|
||||
RegionAndName regionAndName = new RegionAndName(region, placementGroupName);
|
||||
if (!placementGroupMap.containsKey(regionAndName)) {
|
||||
placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName));
|
||||
|
@ -102,12 +119,60 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) {
|
||||
protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
|
||||
RegionAndName key = new RegionAndName(region, "jclouds#" + group);
|
||||
KeyPair pair = credentialsMap.get(key);
|
||||
if (pair != null)
|
||||
return pair.getKeyName();
|
||||
if (and(hasPublicKeyMaterial, or(doesntNeedSshAfterImportingPublicKey, hasLoginCredential)).apply(options)) {
|
||||
pair = importExistingKeyPair.apply(new RegionNameAndPublicKeyMaterial(region, group, options.getPublicKey()));
|
||||
options.dontAuthorizePublicKey();
|
||||
if (hasLoginCredential.apply(options))
|
||||
pair = pair.toBuilder().keyMaterial(options.getOverridingCredentials().credential).build();
|
||||
credentialsMap.put(key, pair);
|
||||
} else {
|
||||
if (hasPublicKeyMaterial.apply(options)) {
|
||||
logger.warn("to avoid creating extra keys in aws-ec2, use templateOption overrideLoginCredentialWith(id_rsa)");
|
||||
}
|
||||
return createUniqueKeyPairAndPutIntoMap(region, group);
|
||||
}
|
||||
return pair.getKeyName();
|
||||
}
|
||||
|
||||
public static final Predicate<TemplateOptions> hasPublicKeyMaterial = new Predicate<TemplateOptions>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(TemplateOptions options) {
|
||||
return options.getPublicKey() != null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final Predicate<TemplateOptions> doesntNeedSshAfterImportingPublicKey = new Predicate<TemplateOptions>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(TemplateOptions options) {
|
||||
return (options.getRunScript() == null && options.getPrivateKey() == null);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final Predicate<TemplateOptions> hasLoginCredential = new Predicate<TemplateOptions>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(TemplateOptions options) {
|
||||
return options.getOverridingCredentials() != null && options.getOverridingCredentials().credential != null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void addSecurityGroups(String region, String group, Template template, RunInstancesOptions instanceOptions) {
|
||||
String subnetId = AWSEC2TemplateOptions.class.cast(template.getOptions()).getSubnetId();
|
||||
if (subnetId != null) {
|
||||
AWSRunInstancesOptions.class.cast(instanceOptions).withSubnetId(subnetId);
|
||||
} else {
|
||||
super.addSecurityGroups(region, tag, template, instanceOptions);
|
||||
super.addSecurityGroups(region, group, template, instanceOptions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.ec2.domain;
|
||||
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RegionNameAndPublicKeyMaterial extends RegionAndName {
|
||||
private final String publicKeyMaterial;
|
||||
|
||||
public RegionNameAndPublicKeyMaterial(String region, String tag, String publicKeyMaterial) {
|
||||
super(region, tag);
|
||||
this.publicKeyMaterial = publicKeyMaterial;
|
||||
}
|
||||
|
||||
// intentionally not overriding equals or hash-code so that we can search only by region/tag in a
|
||||
// map
|
||||
|
||||
public String getPublicKeyMaterial() {
|
||||
return publicKeyMaterial;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.ec2.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ImportOrReturnExistingKeypair implements Function<RegionNameAndPublicKeyMaterial, KeyPair> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final AWSEC2Client ec2Client;
|
||||
|
||||
@Inject
|
||||
public ImportOrReturnExistingKeypair(AWSEC2Client ec2Client) {
|
||||
this.ec2Client = ec2Client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair apply(RegionNameAndPublicKeyMaterial from) {
|
||||
return importOrReturnExistingKeypair(from.getRegion(), from.getName(), from.getPublicKeyMaterial());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
KeyPair importOrReturnExistingKeypair(String region, String group, String publicKeyMaterial) {
|
||||
checkNotNull(region, "region");
|
||||
checkNotNull(group, "group");
|
||||
checkNotNull(publicKeyMaterial, "publicKeyMaterial");
|
||||
logger.debug(">> importing keyPair region(%s) group(%s)", region, group);
|
||||
KeyPair keyPair = null;
|
||||
// loop for eventual consistency or race condition.
|
||||
// as this command is idempotent, it should be ok
|
||||
while (keyPair == null)
|
||||
try {
|
||||
keyPair = ec2Client.getKeyPairServices().importKeyPairInRegion(region, "jclouds#" + group,
|
||||
publicKeyMaterial);
|
||||
logger.debug("<< imported keyPair(%s)", keyPair.getKeyName());
|
||||
} catch (IllegalStateException e) {
|
||||
keyPair = Iterables.getFirst(
|
||||
ec2Client.getKeyPairServices().describeKeyPairsInRegion(region, "jclouds#" + group), null);
|
||||
if (keyPair != null)
|
||||
logger.debug("<< retrieved existing keyPair(%s)", keyPair.getKeyName());
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
}
|
|
@ -59,13 +59,13 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||
public void testExtendedOptionsAndLogin() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
.getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
.getInstanceServices();
|
||||
|
||||
String group = this.group + "o";
|
||||
|
||||
|
@ -117,17 +117,17 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
// }
|
||||
|
||||
// make sure we made our dummy group and also let in the user's group
|
||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet.<String> of("jclouds#" + group + "#"
|
||||
+ instance.getRegion(), group));
|
||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()),
|
||||
ImmutableSortedSet.<String> of("jclouds#" + group + "#" + instance.getRegion(), group));
|
||||
|
||||
// make sure our dummy group has no rules
|
||||
SecurityGroup secgroup = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
||||
"jclouds#" +group + "#" + instance.getRegion()));
|
||||
"jclouds#" + group + "#" + instance.getRegion()));
|
||||
assert secgroup.getIpPermissions().size() == 0 : secgroup;
|
||||
|
||||
// try to run a script with the original keyPair
|
||||
runScriptWithCreds(group, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result
|
||||
.getKeyMaterial()));
|
||||
runScriptWithCreds(group, first.getOperatingSystem(),
|
||||
new Credentials(first.getCredentials().identity, result.getKeyMaterial()));
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.inGroup(group));
|
||||
|
@ -138,21 +138,17 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, group);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||
public void testExtendedOptionsWithSubnetId() throws Exception {
|
||||
public void testSubnetId() throws Exception {
|
||||
|
||||
String subnetId = System.getProperty("test.subnetId");
|
||||
if (subnetId == null) {
|
||||
// Skip test and return
|
||||
return;
|
||||
}
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
@ -161,20 +157,11 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
// options.as(AWSEC2TemplateOptions.class).securityGroups(group);
|
||||
options.as(AWSEC2TemplateOptions.class).keyPair(group);
|
||||
options.as(AWSEC2TemplateOptions.class).subnetId(subnetId);
|
||||
|
||||
String startedId = null;
|
||||
String nodeId = null;
|
||||
try {
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, group);
|
||||
|
||||
// create the security group
|
||||
// securityGroupClient.createSecurityGroupInRegion(null, group, group);
|
||||
|
||||
// create a keypair to pass in as well
|
||||
keyPairClient.createKeyPairInRegion(null, group);
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
||||
|
||||
|
@ -192,11 +179,6 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
} finally {
|
||||
if (nodeId != null)
|
||||
client.destroyNode(nodeId);
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(keyPairClient.describeKeyPairsInRegion(null, group).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, group);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,17 +34,17 @@ import javax.inject.Provider;
|
|||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial;
|
||||
import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded;
|
||||
import org.jclouds.aws.ec2.options.AWSRunInstancesOptions;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.compute.EC2TemplateBuilderTest;
|
||||
import org.jclouds.ec2.compute.domain.EC2HardwareBuilder;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
|
@ -52,6 +52,7 @@ import org.jclouds.ec2.options.RunInstancesOptions;
|
|||
import org.jclouds.encryption.internal.Base64;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
@ -72,7 +73,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
Hardware size = EC2HardwareBuilder.m1_small().build();
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
|
@ -80,18 +81,18 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
||||
TemplateOptions.class) });
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||
new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
Template template = createMock(Template.class);
|
||||
|
@ -101,9 +102,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(template.getHardware()).andReturn(size).atLeastOnce();
|
||||
expect(template.getOptions()).andReturn(options).atLeastOnce();
|
||||
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups);
|
||||
expect(options.getSubnetId()).andReturn(null);
|
||||
expect(options.getUserData()).andReturn(null);
|
||||
expect(options.isMonitoringEnabled()).andReturn(false);
|
||||
|
@ -114,11 +115,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy);
|
||||
|
||||
// run
|
||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||
RunInstancesOptions customize = strategy.execute(region, group, template);
|
||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
||||
size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName)
|
||||
.entries());
|
||||
assertEquals(
|
||||
customize.buildFormParameters().entries(),
|
||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||
generatedGroup, "KeyName", systemGeneratedKeyPairName).entries());
|
||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildStringPayload(), null);
|
||||
|
@ -132,7 +134,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testExecuteForCCAutomatic() throws SecurityException, NoSuchMethodException {
|
||||
// setup constants
|
||||
String region = Region.US_EAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
Hardware size = EC2TemplateBuilderTest.CC1_4XLARGE;
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
|
@ -140,18 +142,18 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
||||
TemplateOptions.class) });
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||
new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
Template template = createMock(Template.class);
|
||||
|
@ -161,11 +163,11 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(template.getHardware()).andReturn(size).atLeastOnce();
|
||||
expect(template.getOptions()).andReturn(options).atLeastOnce();
|
||||
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
generatedGroup);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
generatedGroup);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups);
|
||||
expect(options.getSubnetId()).andReturn(null);
|
||||
expect(options.getUserData()).andReturn(null);
|
||||
expect(options.isMonitoringEnabled()).andReturn(false);
|
||||
|
@ -176,11 +178,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy);
|
||||
|
||||
// run
|
||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||
RunInstancesOptions customize = strategy.execute(region, group, template);
|
||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
||||
size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName,
|
||||
"Placement.GroupName", generatedGroup).entries());
|
||||
assertEquals(
|
||||
customize.buildFormParameters().entries(),
|
||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
||||
.entries());
|
||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildStringPayload(), null);
|
||||
|
@ -194,7 +198,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testExecuteForCCUserSpecified() throws SecurityException, NoSuchMethodException {
|
||||
// setup constants
|
||||
String region = Region.US_EAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
Hardware size = EC2TemplateBuilderTest.CC1_4XLARGE;
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
|
@ -202,18 +206,18 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
||||
TemplateOptions.class) });
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||
new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
Template template = createMock(Template.class);
|
||||
|
@ -223,11 +227,11 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(template.getHardware()).andReturn(size).atLeastOnce();
|
||||
expect(template.getOptions()).andReturn(options).atLeastOnce();
|
||||
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
generatedGroup);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
generatedGroup);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups);
|
||||
expect(options.getSubnetId()).andReturn(null);
|
||||
expect(options.getUserData()).andReturn(null);
|
||||
expect(options.isMonitoringEnabled()).andReturn(false);
|
||||
|
@ -238,11 +242,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy);
|
||||
|
||||
// run
|
||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||
RunInstancesOptions customize = strategy.execute(region, group, template);
|
||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
||||
size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName,
|
||||
"Placement.GroupName", generatedGroup).entries());
|
||||
assertEquals(
|
||||
customize.buildFormParameters().entries(),
|
||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
||||
.entries());
|
||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildStringPayload(), null);
|
||||
|
@ -256,24 +262,24 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testExecuteWithSubnet() throws SecurityException, NoSuchMethodException {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
Hardware size = EC2HardwareBuilder.m1_small().build();
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
||||
TemplateOptions.class) });
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||
new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
Template template = createMock(Template.class);
|
||||
|
@ -283,8 +289,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(template.getHardware()).andReturn(size).atLeastOnce();
|
||||
expect(template.getOptions()).andReturn(options).atLeastOnce();
|
||||
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(options.getSubnetId()).andReturn("1");
|
||||
expect(options.getUserData()).andReturn(null);
|
||||
expect(options.isMonitoringEnabled()).andReturn(false);
|
||||
|
@ -295,10 +301,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy);
|
||||
|
||||
// run
|
||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||
RunInstancesOptions customize = strategy.execute(region, group, template);
|
||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
||||
size.getProviderId(), "SubnetId", "1", "KeyName", systemGeneratedKeyPairName).entries());
|
||||
assertEquals(
|
||||
customize.buildFormParameters().entries(),
|
||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SubnetId", "1", "KeyName",
|
||||
systemGeneratedKeyPairName).entries());
|
||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildStringPayload(), null);
|
||||
|
@ -312,7 +320,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testExecuteWithUserData() throws SecurityException, NoSuchMethodException {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
Hardware size = EC2HardwareBuilder.m1_small().build();
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
|
@ -320,18 +328,18 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock(
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class,
|
||||
TemplateOptions.class) });
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class,
|
||||
new Method[] {
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class
|
||||
.getDeclaredMethod("getOptionsProvider"),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class,
|
||||
TemplateOptions.class),
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod(
|
||||
"getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) });
|
||||
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
Template template = createMock(Template.class);
|
||||
|
@ -341,9 +349,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(template.getHardware()).andReturn(size).atLeastOnce();
|
||||
expect(template.getOptions()).andReturn(options).atLeastOnce();
|
||||
expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet.<BlockDeviceMapping> of()).atLeastOnce();
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups);
|
||||
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options)).andReturn(
|
||||
systemGeneratedKeyPairName);
|
||||
expect(strategy.getSecurityGroupsForTagAndOptions(region, group, options)).andReturn(generatedGroups);
|
||||
expect(options.getSubnetId()).andReturn(null);
|
||||
expect(options.getUserData()).andReturn("hello".getBytes());
|
||||
expect(options.isMonitoringEnabled()).andReturn(false);
|
||||
|
@ -354,11 +362,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy);
|
||||
|
||||
// run
|
||||
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||
RunInstancesOptions customize = strategy.execute(region, group, template);
|
||||
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap.<String, String> of("InstanceType",
|
||||
size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData",
|
||||
Base64.encodeBytes("hello".getBytes())).entries());
|
||||
assertEquals(
|
||||
customize.buildFormParameters().entries(),
|
||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group",
|
||||
"KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries());
|
||||
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||
assertEquals(customize.buildStringPayload(), null);
|
||||
|
@ -372,7 +381,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = "myKeyPair";
|
||||
|
||||
// create mocks
|
||||
|
@ -389,7 +398,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair);
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -397,10 +406,86 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault() {
|
||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_importsKeyPairAndUnsetsTemplateInstructionWhenPublicKeySuppliedAndAddsCredentialToMapWhenOverridingCredsAreSet() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
KeyPair keyPair = new KeyPair(region, "jclouds#" + group, "fingerprint", null);
|
||||
|
||||
// setup expectations
|
||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||
expect(strategy.credentialsMap.get(new RegionAndName(region, "jclouds#" + group))).andReturn(null);
|
||||
expect(options.getPublicKey()).andReturn("ssh-rsa").times(2);
|
||||
expect(strategy.importExistingKeyPair.apply(new RegionNameAndPublicKeyMaterial(region, group, "ssh-rsa")))
|
||||
.andReturn(keyPair);
|
||||
expect(options.dontAuthorizePublicKey()).andReturn(options);
|
||||
expect(options.getOverridingCredentials()).andReturn(new Credentials("foo", "bar")).times(3);
|
||||
expect(options.getRunScript()).andReturn(null);
|
||||
expect(options.getPrivateKey()).andReturn(null);
|
||||
expect(
|
||||
strategy.credentialsMap.put(new RegionAndName(region, "jclouds#" + group),
|
||||
keyPair.toBuilder().keyMaterial("bar").build())).andReturn(null);
|
||||
|
||||
// replay mocks
|
||||
replay(options);
|
||||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), "jclouds#" + group);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_importsKeyPairAndUnsetsTemplateInstructionWhenPublicKeySupplied() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
KeyPair keyPair = new KeyPair(region, "jclouds#" + group, "fingerprint", null);
|
||||
|
||||
// setup expectations
|
||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||
expect(strategy.credentialsMap.get(new RegionAndName(region, "jclouds#" + group))).andReturn(null);
|
||||
expect(options.getPublicKey()).andReturn("ssh-rsa").times(2);
|
||||
expect(strategy.importExistingKeyPair.apply(new RegionNameAndPublicKeyMaterial(region, group, "ssh-rsa")))
|
||||
.andReturn(keyPair);
|
||||
expect(options.dontAuthorizePublicKey()).andReturn(options);
|
||||
expect(options.getOverridingCredentials()).andReturn(null);
|
||||
expect(options.getRunScript()).andReturn(null);
|
||||
expect(options.getPrivateKey()).andReturn(null);
|
||||
expect(strategy.credentialsMap.put(new RegionAndName(region, "jclouds#" + group), keyPair)).andReturn(null);
|
||||
|
||||
// replay mocks
|
||||
replay(options);
|
||||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), "jclouds#" + group);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameWhenNoPublicKeySupplied() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
|
@ -413,10 +498,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
// setup expectations
|
||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||
expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair);
|
||||
expect(strategy.credentialsMap.get(new RegionAndName(region, "jclouds#" + group))).andReturn(null);
|
||||
expect(options.getPublicKey()).andReturn(null).times(2);
|
||||
expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, group))).andReturn(keyPair);
|
||||
expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce();
|
||||
expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn(
|
||||
null);
|
||||
null);
|
||||
|
||||
// replay mocks
|
||||
replay(options);
|
||||
|
@ -424,8 +511,41 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options),
|
||||
systemGeneratedKeyPairName);
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options),
|
||||
systemGeneratedKeyPairName);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
verify(keyPair);
|
||||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_returnsExistingKeyIfAlreadyPresent() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = true;
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||
AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class);
|
||||
KeyPair keyPair = createMock(KeyPair.class);
|
||||
|
||||
// setup expectations
|
||||
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
|
||||
expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair);
|
||||
expect(strategy.credentialsMap.get(new RegionAndName(region, "jclouds#" + group))).andReturn(keyPair);
|
||||
expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce();
|
||||
// replay mocks
|
||||
replay(options);
|
||||
replay(keyPair);
|
||||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options),
|
||||
systemGeneratedKeyPairName);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -436,7 +556,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_doesntCreateAKeyPairAndReturnsNullWhenToldNotTo() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedKeyPair = null;
|
||||
boolean shouldAutomaticallyCreateKeyPair = false; // here's the important
|
||||
// part!
|
||||
|
@ -456,7 +576,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), null);
|
||||
assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), null);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -467,8 +587,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String generatedMarkerGroup = "jclouds#group#" + Region.AP_SOUTHEAST_1;
|
||||
Set<String> groupIds = ImmutableSet.<String> of();
|
||||
int[] ports = new int[] {};
|
||||
boolean shouldAuthorizeSelf = true;
|
||||
|
@ -483,7 +603,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce();
|
||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||
ports, shouldAuthorizeSelf);
|
||||
ports, shouldAuthorizeSelf);
|
||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
||||
expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
||||
expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null);
|
||||
|
@ -493,7 +613,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal);
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -503,8 +623,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String generatedMarkerGroup = "jclouds#group#" + Region.AP_SOUTHEAST_1;
|
||||
Set<String> groupIds = ImmutableSet.<String> of();
|
||||
int[] ports = new int[] { 22, 80 };
|
||||
boolean shouldAuthorizeSelf = true;
|
||||
|
@ -519,7 +639,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce();
|
||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||
ports, shouldAuthorizeSelf);
|
||||
ports, shouldAuthorizeSelf);
|
||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
||||
expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup);
|
||||
expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null);
|
||||
|
@ -529,7 +649,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal);
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -539,8 +659,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String generatedMarkerGroup = "jclouds#group#" + Region.AP_SOUTHEAST_1;
|
||||
Set<String> groupIds = ImmutableSet.<String> of();
|
||||
int[] ports = new int[] {};
|
||||
boolean shouldAuthorizeSelf = true;
|
||||
|
@ -555,7 +675,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce();
|
||||
expect(options.getInboundPorts()).andReturn(ports).atLeastOnce();
|
||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||
ports, shouldAuthorizeSelf);
|
||||
ports, shouldAuthorizeSelf);
|
||||
expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted);
|
||||
|
||||
// replay mocks
|
||||
|
@ -563,7 +683,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal);
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -573,8 +693,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExistAndAcceptsUserSuppliedGroups() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1;
|
||||
String group = "group";
|
||||
String generatedMarkerGroup = "jclouds#group#" + Region.AP_SOUTHEAST_1;
|
||||
Set<String> groupIds = ImmutableSet.<String> of("group1", "group2");
|
||||
int[] ports = new int[] {};
|
||||
boolean shouldAuthorizeSelf = true;
|
||||
|
@ -588,7 +708,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
// setup expectations
|
||||
expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce();
|
||||
RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup,
|
||||
ports, shouldAuthorizeSelf); // note
|
||||
ports, shouldAuthorizeSelf); // note
|
||||
// this
|
||||
// works
|
||||
// since
|
||||
|
@ -601,7 +721,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal);
|
||||
assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, group, options), returnVal);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -611,7 +731,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testCreateNewPlacementGroupUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedPlacementGroup = "myPlacementGroup";
|
||||
|
||||
// create mocks
|
||||
|
@ -628,8 +748,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options),
|
||||
userSuppliedPlacementGroup);
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, group, options),
|
||||
userSuppliedPlacementGroup);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -640,10 +760,10 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testCreateNewPlacementGroupUnlessUserSpecifiedOtherwise_createsNewPlacementGroupAndReturnsItsNameByDefault() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedPlacementGroup = null;
|
||||
boolean shouldAutomaticallyCreatePlacementGroup = true;
|
||||
String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1;
|
||||
String generatedMarkerGroup = "jclouds#group#" + Region.AP_SOUTHEAST_1;
|
||||
|
||||
// create mocks
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy();
|
||||
|
@ -654,17 +774,17 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
expect(options.shouldAutomaticallyCreatePlacementGroup()).andReturn(shouldAutomaticallyCreatePlacementGroup);
|
||||
expect(strategy.placementGroupMap.containsKey(new RegionAndName(region, generatedMarkerGroup))).andReturn(false);
|
||||
expect(strategy.createPlacementGroupIfNeeded.apply(new RegionAndName(region, generatedMarkerGroup))).andReturn(
|
||||
generatedMarkerGroup);
|
||||
generatedMarkerGroup);
|
||||
expect(strategy.placementGroupMap.put(new RegionAndName(region, generatedMarkerGroup), generatedMarkerGroup))
|
||||
.andReturn(null);
|
||||
.andReturn(null);
|
||||
|
||||
// replay mocks
|
||||
replay(options);
|
||||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options),
|
||||
generatedMarkerGroup);
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, group, options),
|
||||
generatedMarkerGroup);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -674,7 +794,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
public void testCreateNewPlacementGroupUnlessUserSpecifiedOtherwise_doesntCreateAPlacementGroupAndReturnsNullWhenToldNotTo() {
|
||||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
String group = "group";
|
||||
String userSuppliedPlacementGroup = null;
|
||||
boolean shouldAutomaticallyCreatePlacementGroup = false; // here's the important
|
||||
// part!
|
||||
|
@ -694,7 +814,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replayStrategy(strategy);
|
||||
|
||||
// run
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options), null);
|
||||
assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, group, options), null);
|
||||
|
||||
// verify mocks
|
||||
verify(options);
|
||||
|
@ -707,6 +827,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
verify(strategy.securityGroupMap);
|
||||
verify(strategy.placementGroupMap);
|
||||
verify(strategy.createUniqueKeyPair);
|
||||
verify(strategy.importExistingKeyPair);
|
||||
verify(strategy.createSecurityGroupIfNeeded);
|
||||
verify(strategy.createPlacementGroupIfNeeded);
|
||||
}
|
||||
|
@ -716,13 +837,14 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
|
||||
Map<RegionAndName, String> securityGroupMap = createMock(Map.class);
|
||||
Map<RegionAndName, String> placementGroupMap = createMock(Map.class);
|
||||
CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class);
|
||||
CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class);
|
||||
Function<RegionAndName, KeyPair> createOrGetKeyPair = createMock(Function.class);
|
||||
Function<RegionNameAndIngressRules, String> createSecurityGroupIfNeeded = createMock(Function.class);
|
||||
Function<RegionNameAndPublicKeyMaterial, KeyPair> importExistingKeyPair = createMock(Function.class);
|
||||
CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded = createMock(CreatePlacementGroupIfNeeded.class);
|
||||
|
||||
return new CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap,
|
||||
placementGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER,
|
||||
createPlacementGroupIfNeeded);
|
||||
placementGroupMap, createOrGetKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER,
|
||||
createPlacementGroupIfNeeded, importExistingKeyPair);
|
||||
}
|
||||
|
||||
private void replayStrategy(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy) {
|
||||
|
@ -730,6 +852,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
|||
replay(strategy.securityGroupMap);
|
||||
replay(strategy.placementGroupMap);
|
||||
replay(strategy.createUniqueKeyPair);
|
||||
replay(strategy.importExistingKeyPair);
|
||||
replay(strategy.createSecurityGroupIfNeeded);
|
||||
replay(strategy.createPlacementGroupIfNeeded);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.ec2.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 java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.ec2.services.AWSKeyPairClient;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ImportOrReturnExistingKeypairTest {
|
||||
@Test
|
||||
public void testApply() throws UnknownHostException {
|
||||
AWSEC2Client client = createMock(AWSEC2Client.class);
|
||||
AWSKeyPairClient keyClient = createMock(AWSKeyPairClient.class);
|
||||
|
||||
KeyPair pair = createMock(KeyPair.class);
|
||||
|
||||
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||
|
||||
expect(keyClient.importKeyPairInRegion("region", "jclouds#group", "ssh-rsa")).andReturn(pair);
|
||||
|
||||
replay(client);
|
||||
replay(keyClient);
|
||||
|
||||
ImportOrReturnExistingKeypair parser = new ImportOrReturnExistingKeypair(client);
|
||||
|
||||
assertEquals(parser.importOrReturnExistingKeypair("region", "group", "ssh-rsa"), pair);
|
||||
|
||||
verify(client);
|
||||
verify(keyClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyWithIllegalStateExceptionReturnsExistingKey() throws UnknownHostException {
|
||||
AWSEC2Client client = createMock(AWSEC2Client.class);
|
||||
AWSKeyPairClient keyClient = createMock(AWSKeyPairClient.class);
|
||||
|
||||
KeyPair pair = createMock(KeyPair.class);
|
||||
|
||||
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||
|
||||
expect(keyClient.importKeyPairInRegion("region", "jclouds#group", "ssh-rsa")).andThrow(
|
||||
new IllegalStateException());
|
||||
expect(keyClient.describeKeyPairsInRegion("region", "jclouds#group")).andReturn(ImmutableSet.of(pair));
|
||||
|
||||
replay(client);
|
||||
replay(keyClient);
|
||||
|
||||
ImportOrReturnExistingKeypair parser = new ImportOrReturnExistingKeypair(client);
|
||||
|
||||
assertEquals(parser.importOrReturnExistingKeypair("region", "group", "ssh-rsa"), pair);
|
||||
|
||||
verify(client);
|
||||
verify(keyClient);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyWithIllegalStateExceptionRetriesWhenExistingKeyNotFound() throws UnknownHostException {
|
||||
AWSEC2Client client = createMock(AWSEC2Client.class);
|
||||
AWSKeyPairClient keyClient = createMock(AWSKeyPairClient.class);
|
||||
|
||||
KeyPair pair = createMock(KeyPair.class);
|
||||
|
||||
expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
|
||||
|
||||
expect(keyClient.importKeyPairInRegion("region", "jclouds#group", "ssh-rsa")).andThrow(
|
||||
new IllegalStateException());
|
||||
expect(keyClient.describeKeyPairsInRegion("region", "jclouds#group")).andReturn(ImmutableSet.<KeyPair> of());
|
||||
expect(keyClient.importKeyPairInRegion("region", "jclouds#group", "ssh-rsa")).andThrow(
|
||||
new IllegalStateException());
|
||||
expect(keyClient.describeKeyPairsInRegion("region", "jclouds#group")).andReturn(ImmutableSet.<KeyPair> of(pair));
|
||||
|
||||
replay(client);
|
||||
replay(keyClient);
|
||||
|
||||
ImportOrReturnExistingKeypair parser = new ImportOrReturnExistingKeypair(client);
|
||||
|
||||
assertEquals(parser.importOrReturnExistingKeypair("region", "group", "ssh-rsa"), pair);
|
||||
|
||||
verify(client);
|
||||
verify(keyClient);
|
||||
|
||||
}
|
||||
}
|
|
@ -20,6 +20,13 @@
|
|||
package org.jclouds.aws.ec2.services;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.collect.Sets.newTreeSet;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.overrideCredentialsWith;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.runningInGroup;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
|
@ -34,17 +41,26 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
|
||||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.ComputeTestUtils;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.services.InstanceClient;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
|
@ -63,6 +79,7 @@ public class AWSKeyPairClientLiveTest {
|
|||
protected String credential;
|
||||
protected String endpoint;
|
||||
protected String apiversion;
|
||||
private ComputeServiceContext computeContext;
|
||||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
|
@ -89,20 +106,67 @@ public class AWSKeyPairClientLiveTest {
|
|||
public void setupClient() {
|
||||
setupCredentials();
|
||||
Properties overrides = setupProperties();
|
||||
context = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
|
||||
computeContext = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides);
|
||||
context = computeContext.getProviderSpecificContext();
|
||||
client = context.getApi().getKeyPairServices();
|
||||
}
|
||||
|
||||
public void testNoSsh() throws Exception {
|
||||
|
||||
Map<String, String> keyPair = ComputeTestUtils.setupKeyPair();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getApi()).getInstanceServices();
|
||||
|
||||
String group = PREFIX + "unssh";
|
||||
computeContext.getComputeService().destroyNodesMatching(inGroup(group));
|
||||
|
||||
TemplateOptions options = computeContext.getComputeService().templateOptions();
|
||||
|
||||
options.authorizePublicKey(keyPair.get("public"));
|
||||
|
||||
ComputeServiceContext noSshContext = null;
|
||||
try {
|
||||
noSshContext = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), setupProperties());
|
||||
|
||||
Set<? extends NodeMetadata> nodes = noSshContext.getComputeService().createNodesInGroup(group, 1, options);
|
||||
|
||||
NodeMetadata first = get(nodes, 0);
|
||||
assert first.getCredentials() != null : first;
|
||||
assert first.getCredentials().identity != null : first;
|
||||
|
||||
AWSRunningInstance instance = AWSRunningInstance.class
|
||||
.cast(getInstance(instanceClient, first.getProviderId()));
|
||||
|
||||
assertEquals(instance.getKeyName(), "jclouds#" + group);
|
||||
assertEquals(first.getCredentials().credential, null);
|
||||
|
||||
Map<? extends NodeMetadata, ExecResponse> responses = computeContext.getComputeService()
|
||||
.runScriptOnNodesMatching(
|
||||
runningInGroup(group),
|
||||
exec("echo hello"),
|
||||
overrideCredentialsWith(new Credentials(first.getCredentials().identity, keyPair.get("private")))
|
||||
.wrapInInitScript(false).runAsRoot(false));
|
||||
|
||||
ExecResponse hello = getOnlyElement(responses.values());
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
|
||||
} finally {
|
||||
noSshContext.close();
|
||||
computeContext.getComputeService().destroyNodesMatching(inGroup(group));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDescribeAWSKeyPairs() {
|
||||
for (String region : Region.DEFAULT_REGIONS) {
|
||||
|
||||
SortedSet<KeyPair> allResults = Sets.newTreeSet(client.describeKeyPairsInRegion(region));
|
||||
SortedSet<KeyPair> allResults = newTreeSet(client.describeKeyPairsInRegion(region));
|
||||
assertNotNull(allResults);
|
||||
if (allResults.size() >= 1) {
|
||||
KeyPair pair = allResults.last();
|
||||
SortedSet<KeyPair> result = Sets.newTreeSet(client.describeKeyPairsInRegion(region, pair.getKeyName()));
|
||||
SortedSet<KeyPair> result = newTreeSet(client.describeKeyPairsInRegion(region, pair.getKeyName()));
|
||||
assertNotNull(result);
|
||||
KeyPair compare = result.last();
|
||||
assertEquals(compare, pair);
|
||||
|
@ -163,7 +227,7 @@ public class AWSKeyPairClientLiveTest {
|
|||
assertNotNull(keyPair.getKeyFingerprint());
|
||||
assertEquals(keyPair.getKeyName(), keyName);
|
||||
|
||||
Set<KeyPair> twoResults = Sets.newLinkedHashSet(client.describeKeyPairsInRegion(null, keyName));
|
||||
Set<KeyPair> twoResults = client.describeKeyPairsInRegion(null, keyName);
|
||||
assertNotNull(twoResults);
|
||||
assertEquals(twoResults.size(), 1);
|
||||
KeyPair listPair = twoResults.iterator().next();
|
||||
|
@ -171,6 +235,11 @@ public class AWSKeyPairClientLiveTest {
|
|||
assertEquals(listPair.getKeyFingerprint(), keyPair.getKeyFingerprint());
|
||||
}
|
||||
|
||||
protected RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||
RunningInstance instance = getOnlyElement(getOnlyElement(instanceClient.describeInstancesInRegion(null, id)));
|
||||
return instance;
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void shutdown() {
|
||||
context.close();
|
||||
|
|
|
@ -197,8 +197,8 @@ public class PlacementGroupClientLiveTest {
|
|||
assertEquals(template.getHardware().getProviderId(), InstanceType.CC1_4XLARGE);
|
||||
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
|
||||
|
||||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
||||
.runScript(buildScript(template.getImage().getOperatingSystem()));
|
||||
template.getOptions().overrideLoginCredentialWith(keyPair.get("private"))
|
||||
.authorizePublicKey(keyPair.get("public")).runScript(buildScript(template.getImage().getOperatingSystem()));
|
||||
|
||||
String group = PREFIX + "cccluster";
|
||||
context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group));
|
||||
|
|
Loading…
Reference in New Issue