From bedfee376a63b6c275ac9c639c860116feeca70f Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 7 Sep 2011 11:50:31 +0200 Subject: [PATCH] Issue 659:Specify non-default key pair for boot script in EC2 --- ...rityGroupsAsNeededAndReturnRunOptions.java | 26 ++- .../compute/EC2ComputeServiceLiveTest.java | 12 +- ...GroupsAsNeededAndReturnRunOptionsTest.java | 171 ++++++++++++++---- .../compute/AWSEC2ComputeServiceLiveTest.java | 12 +- ...GroupsAsNeededAndReturnRunOptionsTest.java | 89 ++++++++- 5 files changed, 264 insertions(+), 46 deletions(-) diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java index 320b203412..4fdaceb6a2 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -109,15 +109,31 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { 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(); } + if (keyPairName == null && shouldAutomaticallyCreateKeyPair) { keyPairName = createOrImportKeyPair(region, group, options); + } else if (keyPairName != null) { + if (options.getOverridingCredentials() != null && options.getOverridingCredentials().credential != null) { + KeyPair keyPair = KeyPair.builder().region(region).keyName(keyPairName).keyFingerprint("//TODO") + .keyMaterial(options.getOverridingCredentials().credential).build(); + putKeyPairIntoCredentialMap(keyPair); + } } + + if (options.getRunScript() != null) { + RegionAndName regionAndName = new RegionAndName(region, keyPairName); + checkState(credentialsMap.containsKey(regionAndName), + "no private key configured for: %s; please use options.overrideLoginCredentialWith(rsa_private_text)", + regionAndName); + } + return keyPairName; } @@ -127,18 +143,20 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { } protected String createUniqueKeyPairAndPutIntoMap(String region, String group) { - String keyPairName; RegionAndName regionAndName = new RegionAndName(region, group); KeyPair keyPair = createUniqueKeyPair.apply(regionAndName); - keyPairName = keyPair.getKeyName(); + putKeyPairIntoCredentialMap(keyPair); + return keyPair.getKeyName(); + } + + protected void putKeyPairIntoCredentialMap(KeyPair keyPair) { // 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; + credentialsMap.put(new RegionAndName(keyPair.getRegion(), keyPair.getKeyName()), keyPair); } @VisibleForTesting diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java index 379e6263ef..1422e84d11 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java @@ -47,6 +47,7 @@ import org.jclouds.ec2.services.ElasticBlockStoreClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairClient; import org.jclouds.ec2.services.SecurityGroupClient; +import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.sshj.config.SshjSshClientModule; import org.testng.annotations.Test; @@ -97,7 +98,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { TemplateOptions options = client.templateOptions(); options.as(EC2TemplateOptions.class).securityGroups(group); - options.as(EC2TemplateOptions.class).keyPair(group); String startedId = null; try { @@ -110,7 +110,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { // create a keypair to pass in as well KeyPair result = keyPairClient.createKeyPairInRegion(null, group); - + options.as(EC2TemplateOptions.class).keyPair(result.getKeyName()); + + // pass in the private key, so that we can run a script with it + assert result.getKeyMaterial() != null : result; + options.overrideLoginCredentialWith(result.getKeyMaterial()); + + // an arbitrary command to run + options.runScript(Statements.exec("find /usr")); + Set nodes = client.createNodesInGroup(group, 1, options); NodeMetadata first = Iterables.get(nodes, 0); assert first.getCredentials() != null : first; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index 146be89383..c3550d9240 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -34,6 +34,7 @@ import org.jclouds.aws.domain.Region; 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.domain.EC2HardwareBuilder; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; @@ -44,6 +45,7 @@ import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.encryption.internal.Base64; +import org.jclouds.scriptbuilder.domain.Statements; import org.testng.annotations.Test; import com.google.common.base.Function; @@ -76,15 +78,15 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // create mocks CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getOptionsProvider"), - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, - TemplateOptions.class) }); + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, + new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); EC2TemplateOptions options = createMock(EC2TemplateOptions.class); Template template = createMock(Template.class); @@ -95,7 +97,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getUserData()).andReturn(null); @@ -107,9 +109,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", - size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName) - .entries()); + assertEquals( + customize.buildFormParameters().entries(), + ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", + generatedGroup, "KeyName", systemGeneratedKeyPairName).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -131,15 +134,15 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // create mocks CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getOptionsProvider"), - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, - TemplateOptions.class) }); + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, + new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); EC2TemplateOptions options = createMock(EC2TemplateOptions.class); Template template = createMock(Template.class); @@ -150,7 +153,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getUserData()).andReturn("hello".getBytes()); @@ -162,9 +165,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", - size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData", - Base64.encodeBytes("hello".getBytes())).entries()); + assertEquals( + customize.buildFormParameters().entries(), + ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group", + "KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -188,6 +192,106 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // setup expectations expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(null); + expect(options.getRunScript()).andReturn(null); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptButNoCredentials() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(false); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsAlreadyInMap() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsSpecified() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(new Credentials(null, "MyRsa")).atLeastOnce(); + expect( + strategy.credentialsMap.put(new RegionAndName(region, userSuppliedKeyPair), KeyPair.builder() + .region(region).keyName(userSuppliedKeyPair).keyFingerprint("//TODO").keyMaterial("MyRsa").build())) + .andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); // replay mocks replay(options); @@ -220,9 +324,11 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair); + expect(keyPair.getRegion()).andReturn(region).atLeastOnce(); expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( - null); + null); + expect(options.getRunScript()).andReturn(null); // replay mocks replay(options); @@ -231,7 +337,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // run assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); // verify mocks verify(options); @@ -254,6 +360,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // setup expectations expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getRunScript()).andReturn(null); expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); // replay mocks @@ -289,7 +396,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(options.getGroups()).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); @@ -325,7 +432,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(options.getGroups()).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); @@ -361,7 +468,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(options.getGroups()).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 @@ -394,7 +501,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { // setup expectations expect(options.getGroups()).andReturn(groupIds).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); // note + ports, shouldAuthorizeSelf); // note // this // works // since diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java index 17d3989277..c716920316 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java @@ -38,6 +38,7 @@ import org.jclouds.ec2.domain.SecurityGroup; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairClient; import org.jclouds.ec2.util.IpPermissions; +import org.jclouds.scriptbuilder.domain.Statements; import org.testng.annotations.Test; import com.google.common.collect.ImmutableSortedSet; @@ -74,7 +75,6 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest { // Date before = new Date(); - options.as(AWSEC2TemplateOptions.class).keyPair(group); options.as(AWSEC2TemplateOptions.class).enableMonitoring(); options.as(AWSEC2TemplateOptions.class).spotPrice(0.3f); @@ -93,7 +93,15 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest { // create a keypair to pass in as well KeyPair result = keyPairClient.createKeyPairInRegion(null, group); - + options.as(AWSEC2TemplateOptions.class).keyPair(result.getKeyName()); + + // pass in the private key, so that we can run a script with it + assert result.getKeyMaterial() != null : result; + options.overrideLoginCredentialWith(result.getKeyMaterial()); + + // an arbitrary command to run + options.runScript(Statements.exec("find /usr")); + Set nodes = client.createNodesInGroup(group, 1, options); NodeMetadata first = Iterables.get(nodes, 0); assert first.getCredentials() != null : first; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index b8a15e0a45..20a1a17e5d 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -44,11 +44,13 @@ 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.options.EC2TemplateOptions; import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.encryption.internal.Base64; +import org.jclouds.scriptbuilder.domain.Statements; import org.testng.annotations.Test; import com.google.common.base.Function; @@ -382,19 +384,24 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT verify(strategy); } - public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() { + + @Test(expectedExceptions = IllegalStateException.class) + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptButNoCredentials() { // setup constants String region = Region.AP_SOUTHEAST_1; - String group = "group"; + String tag = "tag"; String userSuppliedKeyPair = "myKeyPair"; // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(false); // replay mocks replay(options); @@ -402,7 +409,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT replayStrategy(strategy); // run - assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options), userSuppliedKeyPair); + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); // verify mocks verify(options); @@ -410,6 +417,72 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT verifyStrategy(strategy); } + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsAlreadyInMap() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldToWithRunScriptAndCredentialsSpecified() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getOverridingCredentials()).andReturn(new Credentials(null, "MyRsa")).atLeastOnce(); + expect( + strategy.credentialsMap.put(new RegionAndName(region, userSuppliedKeyPair), KeyPair.builder() + .region(region).keyName(userSuppliedKeyPair).keyFingerprint("//TODO").keyMaterial("MyRsa").build())) + .andReturn(null); + expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); + expect(strategy.credentialsMap.containsKey(new RegionAndName(region, userSuppliedKeyPair))).andReturn(true); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_importsKeyPairAndUnsetsTemplateInstructionWhenPublicKeySuppliedAndAddsCredentialToMapWhenOverridingCredsAreSet() { // setup constants String region = Region.AP_SOUTHEAST_1; @@ -431,7 +504,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT .andReturn(keyPair); expect(options.dontAuthorizePublicKey()).andReturn(options); expect(options.getOverridingCredentials()).andReturn(new Credentials("foo", "bar")).times(3); - expect(options.getRunScript()).andReturn(null); + expect(options.getRunScript()).andReturn(null).times(2); expect(options.getPrivateKey()).andReturn(null); expect( strategy.credentialsMap.put(new RegionAndName(region, "jclouds#" + group), @@ -470,7 +543,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT .andReturn(keyPair); expect(options.dontAuthorizePublicKey()).andReturn(options); expect(options.getOverridingCredentials()).andReturn(null); - expect(options.getRunScript()).andReturn(null); + expect(options.getRunScript()).andReturn(null).times(2); expect(options.getPrivateKey()).andReturn(null); expect(strategy.credentialsMap.put(new RegionAndName(region, "jclouds#" + group), keyPair)).andReturn(null); @@ -505,7 +578,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT 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.getRegion()).andReturn(region).atLeastOnce(); expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); + expect(options.getRunScript()).andReturn(null); expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( null); @@ -539,6 +614,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // setup expectations expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getRunScript()).andReturn(null); expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); expect(strategy.credentialsMap.get(new RegionAndName(region, "jclouds#" + group))).andReturn(keyPair); expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); @@ -572,6 +648,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // setup expectations expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.getRunScript()).andReturn(null); expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); // replay mocks