Test to demonstrate getting the Windows Administrator password

This commit is contained in:
Richard Downer 2012-02-01 17:40:06 +00:00 committed by Andrei Savu
parent c665eb6a6b
commit 27aaafe139
2 changed files with 104 additions and 6 deletions

View File

@ -83,6 +83,12 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-bouncycastle</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>

View File

@ -18,19 +18,52 @@
*/ */
package org.jclouds.ec2.services; package org.jclouds.ec2.services;
import java.util.Properties; import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Module;
import org.jclouds.compute.BaseVersionedServiceLiveTest; import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
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.domain.LoginCredentials;
import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.EC2ContextBuilder;
import org.jclouds.ec2.EC2PropertiesBuilder;
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.PasswordData;
import org.jclouds.ec2.reference.EC2Constants;
import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
import org.jclouds.logging.Logger;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import javax.annotation.Nullable;
import com.google.inject.Module; import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/** /**
* Tests behavior of {@code WindowsClient} * Tests behavior of {@code WindowsClient}
@ -43,19 +76,30 @@ public class WindowsClientLiveTest extends BaseVersionedServiceLiveTest {
provider = "ec2"; provider = "ec2";
} }
private ComputeService computeService;
private WindowsClient client; private WindowsClient client;
private static final String DEFAULT_INSTANCE = "i-TODO"; private static final String DEFAULT_INSTANCE = "i-TODO";
private static final String DEFAULT_BUCKET = "TODO"; private static final String DEFAULT_BUCKET = "TODO";
private RestContext<EC2Client, EC2AsyncClient> context; private RestContext<EC2Client, EC2AsyncClient> context;
@Override
public Properties setupRestProperties() {
Properties rest = super.setupRestProperties();
rest.put("ec2.contextbuilder", EC2ContextBuilder.class.getName());
rest.put("ec2.propertiesbuilder", EC2PropertiesBuilder.class.getName());
return rest;
}
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider, overrides.put(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "206029621532");
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); ComputeServiceContext serviceContext = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider,
ImmutableSet.<Module>of(new Log4JLoggingModule(), new BouncyCastleCryptoModule()), overrides);
computeService = serviceContext.getComputeService();
context = serviceContext.getProviderSpecificContext();
client = context.getApi().getWindowsServices(); client = context.getApi().getWindowsServices();
} }
@ -82,4 +126,52 @@ public class WindowsClientLiveTest extends BaseVersionedServiceLiveTest {
public void testDescribeBundleTasksInRegion() { public void testDescribeBundleTasksInRegion() {
} }
@Test
public void testGetPasswordData() throws Exception {
// Spin up a new node. Make sure to open the RDP port 3389
Template template = computeService.templateBuilder()
.osFamily(OsFamily.WINDOWS)
.os64Bit(true)
.imageNameMatches("Windows-2008R2-SP1-English-Base-")
.hardwareId(InstanceType.M1_LARGE)
.options(TemplateOptions.Builder.inboundPorts(3389))
.build();
Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup("test", 1, template);
NodeMetadata node = Iterables.getOnlyElement(nodes);
boolean shutdown = true;
try {
// The Administrator password will take some time before it is ready - Amazon says sometimes 15 minutes.
// So we create a predicate that tests if the password is ready, and wrap it in a retryable predicate.
Predicate<String> passwordReady = new Predicate<String>() {
@Override
public boolean apply(@Nullable String s) {
if (Strings.isNullOrEmpty(s)) return false;
PasswordData data = client.getPasswordData(null, s);
if (data == null) return false;
return !Strings.isNullOrEmpty(data.getPasswordData());
}
};
RetryablePredicate<String> passwordReadyRetryable = new RetryablePredicate<String>(passwordReady, 600, 10, TimeUnit.SECONDS);
assertTrue(passwordReadyRetryable.apply(node.getProviderId()));
// Now pull together Amazon's encrypted password blob, and the private key that jclouds generated
PasswordDataAndPrivateKey dataAndKey = new PasswordDataAndPrivateKey(
client.getPasswordData(null, node.getProviderId()),
node.getCredentials().getPrivateKey());
// And apply it to the decryption function
WindowsLoginCredentialsFromEncryptedData f = context.getUtils().getInjector().getInstance(WindowsLoginCredentialsFromEncryptedData.class);
LoginCredentials credentials = f.apply(dataAndKey);
assertEquals(credentials.getUser(), "Administrator");
assertFalse(Strings.isNullOrEmpty(credentials.getPassword()));
} finally {
computeService.destroyNode(node.getId());
}
}
} }