simplified terremark credential handling

This commit is contained in:
Adrian Cole 2011-12-21 02:16:14 -08:00
parent 298e6fa3e4
commit 95753e5695
12 changed files with 144 additions and 228 deletions

View File

@ -25,9 +25,9 @@ import static org.jclouds.trmk.vcloud_0_8.options.AddInternetServiceOptions.Buil
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Map.Entry;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -35,9 +35,9 @@ import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.javax.annotation.Nullable;
@ -70,23 +70,18 @@ public class TerremarkVCloudComputeClient {
protected Logger logger = Logger.NULL;
protected final TerremarkVCloudClient client;
protected final PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider;
protected final Provider<String> passwordGenerator;
protected final Map<String, Credentials> credentialStore;
protected final InternetServiceAndPublicIpAddressSupplier internetServiceAndPublicIpAddressSupplier;
protected final Map<Status, NodeState> vAppStatusToNodeState;
protected final Predicate<URI> taskTester;
@Inject
protected TerremarkVCloudComputeClient(TerremarkVCloudClient client,
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
@Named("PASSWORD") Provider<String> passwordGenerator, Predicate<URI> successTester,
Map<Status, NodeState> vAppStatusToNodeState, Map<String, Credentials> credentialStore,
InternetServiceAndPublicIpAddressSupplier internetServiceAndPublicIpAddressSupplier) {
this.client = client;
this.credentialsProvider = credentialsProvider;
this.passwordGenerator = passwordGenerator;
this.credentialStore = credentialStore;
this.internetServiceAndPublicIpAddressSupplier = internetServiceAndPublicIpAddressSupplier;
this.vAppStatusToNodeState = vAppStatusToNodeState;
this.taskTester = successTester;
@ -95,7 +90,48 @@ public class TerremarkVCloudComputeClient {
protected Status getStatus(VApp vApp) {
return vApp.getStatus();
}
public ComputeServiceAdapter.NodeAndInitialCredentials<VApp> startAndReturnCredentials(@Nullable URI VDC, URI templateId, String name, InstantiateVAppTemplateOptions options,
int... portsToOpen) {
// we only get IP addresses after "deploy"
if (portsToOpen.length > 0 && !options.shouldBlock())
throw new IllegalArgumentException("We cannot open ports on terremark unless we can deploy the vapp");
String password = null;
VAppTemplate template = client.getVAppTemplate(templateId);
if (template.getDescription().indexOf("Windows") != -1) {
password = passwordGenerator.get();
options.getProperties().put("password", password);
}
checkNotNull(options, "options");
logger.debug(">> instantiating vApp vDC(%s) template(%s) name(%s) options(%s) ", VDC, templateId, name, options);
VApp vAppResponse = client.instantiateVAppTemplateInVDC(VDC, templateId, name, options);
logger.debug("<< instantiated VApp(%s)", vAppResponse.getName());
if (options.shouldDeploy()) {
logger.debug(">> deploying vApp(%s)", vAppResponse.getName());
Task task = client.deployVApp(vAppResponse.getHref());
if (options.shouldBlock()) {
if (!taskTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy", vAppResponse.getName(), task));
}
logger.debug("<< deployed vApp(%s)", vAppResponse.getName());
if (options.shouldPowerOn()) {
logger.debug(">> powering vApp(%s)", vAppResponse.getName());
task = client.powerOnVApp(vAppResponse.getHref());
if (!taskTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "powerOn", vAppResponse.getName(),
task));
}
logger.debug("<< on vApp(%s)", vAppResponse.getName());
}
}
}
if (portsToOpen.length > 0)
createPublicAddressMappedToPorts(vAppResponse.getHref(), portsToOpen);
return new ComputeServiceAdapter.NodeAndInitialCredentials<VApp>(vAppResponse, vAppResponse.getHref().toASCIIString(), password!= null?LoginCredentials.builder().password(password).build():null);
}
/**
* Runs through all commands necessary to startup a vApp, opening at least
* one ip address to the public network. These are the steps:
@ -125,49 +161,8 @@ public class TerremarkVCloudComputeClient {
* </ol>
*/
public VApp start(@Nullable URI VDC, URI templateId, String name, InstantiateVAppTemplateOptions options,
int... portsToOpen) {
// we only get IP addresses after "deploy"
if (portsToOpen.length > 0 && !options.shouldBlock())
throw new IllegalArgumentException("We cannot open ports on terremark unless we can deploy the vapp");
String password = null;
VAppTemplate template = client.getVAppTemplate(templateId);
if (template.getDescription().indexOf("Windows") != -1) {
password = passwordGenerator.get();
options.getProperties().put("password", password);
}
LoginCredentials defaultCredentials = credentialsProvider.apply(template);
checkNotNull(options, "options");
logger.debug(">> instantiating vApp vDC(%s) template(%s) name(%s) options(%s) ", VDC, templateId, name, options);
VApp vAppResponse = client.instantiateVAppTemplateInVDC(VDC, templateId, name, options);
logger.debug("<< instantiated VApp(%s)", vAppResponse.getName());
if (options.shouldDeploy()) {
logger.debug(">> deploying vApp(%s)", vAppResponse.getName());
Task task = client.deployVApp(vAppResponse.getHref());
if (options.shouldBlock()) {
if (!taskTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy", vAppResponse.getName(), task));
}
logger.debug("<< deployed vApp(%s)", vAppResponse.getName());
if (options.shouldPowerOn()) {
logger.debug(">> powering vApp(%s)", vAppResponse.getName());
task = client.powerOnVApp(vAppResponse.getHref());
if (!taskTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "powerOn", vAppResponse.getName(),
task));
}
logger.debug("<< on vApp(%s)", vAppResponse.getName());
}
}
}
if (password != null) {
credentialStore.put("node#" + vAppResponse.getHref().toASCIIString(), new Credentials(
defaultCredentials.identity, password));
}
if (portsToOpen.length > 0)
createPublicAddressMappedToPorts(vAppResponse.getHref(), portsToOpen);
return vAppResponse;
int... portsToOpen) {
return startAndReturnCredentials(VDC, templateId, name, options, portsToOpen).getNode();
}
public String createPublicAddressMappedToPorts(URI vAppId, int... ports) {

View File

@ -20,8 +20,6 @@ package org.jclouds.trmk.vcloud_0_8.compute.config;
import java.security.SecureRandom;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.inject.Named;
import javax.inject.Singleton;
@ -41,7 +39,6 @@ import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudAsyncClient;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.jclouds.trmk.vcloud_0_8.compute.TerremarkVCloudComputeService;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.compute.functions.ImagesInVCloudExpressOrg;
import org.jclouds.trmk.vcloud_0_8.compute.functions.NodeMetadataToOrgAndName;
@ -126,12 +123,6 @@ public class TerremarkVCloudComputeServiceContextModule extends BaseComputeServi
}
@Provides
@Singleton
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap() {
return new ConcurrentHashMap<OrgAndName, KeyPairCredentials>();
}
@Named("PASSWORD")
@Provides
String providePassword(SecureRandom random) {

View File

@ -1,64 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.vcloud_0_8.compute.domain;
import org.jclouds.domain.Credentials;
import org.jclouds.trmk.vcloud_0_8.domain.KeyPair;
/**
* @author Adrian Cole
*/
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;
}
private final KeyPair keyPair;
public KeyPairCredentials(String identity, KeyPair keyPair) {
super(identity, keyPair.getPrivateKey());
this.keyPair = keyPair;
}
public Builder<? extends KeyPairCredentials> toBuilder() {
return new Builder<KeyPairCredentials>().identity(identity).keyPair(keyPair);
}
}

View File

@ -21,10 +21,8 @@ package org.jclouds.trmk.vcloud_0_8.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -42,8 +40,6 @@ import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.TerremarkVCloudComputeClient;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.domain.Status;
import org.jclouds.trmk.vcloud_0_8.domain.VApp;
@ -62,20 +58,17 @@ public class VAppToNodeMetadata implements Function<VApp, NodeMetadata> {
protected final FindLocationForResource findLocationForResourceInVDC;
protected final HardwareForVCloudExpressVApp hardwareForVCloudExpressVApp;
protected final Map<Status, NodeState> vAppStatusToNodeState;
protected final ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap;
@Inject
protected VAppToNodeMetadata(TerremarkVCloudComputeClient computeClient, Map<String, Credentials> credentialStore,
Map<Status, NodeState> vAppStatusToNodeState, HardwareForVCloudExpressVApp hardwareForVCloudExpressVApp,
FindLocationForResource findLocationForResourceInVDC, @Memoized Supplier<Set<? extends Image>> images,
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap) {
FindLocationForResource findLocationForResourceInVDC, @Memoized Supplier<Set<? extends Image>> images) {
this.images = checkNotNull(images, "images");
this.hardwareForVCloudExpressVApp = checkNotNull(hardwareForVCloudExpressVApp, "hardwareForVCloudExpressVApp");
this.findLocationForResourceInVDC = checkNotNull(findLocationForResourceInVDC, "findLocationForResourceInVDC");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.computeClient = checkNotNull(computeClient, "computeClient");
this.vAppStatusToNodeState = checkNotNull(vAppStatusToNodeState, "vAppStatusToNodeState");
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
}
@Override
@ -106,18 +99,8 @@ public class VAppToNodeMetadata implements Function<VApp, NodeMetadata> {
builder.privateAddresses(computeClient.getPrivateAddresses(from.getHref()));
String group = parseGroupFromName(from.getName());
builder.group(group);
// node-specific credentials override those from cache based on group
if (group != null && !credentialStore.containsKey("node#" + from.getHref().toASCIIString())) {
OrgAndName orgAndName = new OrgAndName(URI.create(vdcLocation.getParent().getId()), group);
if (credentialsMap.containsKey(orgAndName)) {
builder.credentials(LoginCredentials.builder(credentialsMap.get(orgAndName)).build());
}
} else {
builder.credentials(LoginCredentials.builder(credentialStore.get("node#" + from.getHref().toASCIIString()))
.build());
}
builder.credentials(LoginCredentials.fromCredentials(credentialStore
.get("node#" + from.getHref().toASCIIString())));
return builder.build();
}
}

View File

@ -69,8 +69,9 @@ public class CleanupOrphanKeys {
Iterable<? extends NodeMetadata> nodesInOrg = listNodes.listDetailsOnNodesMatching(parentLocationId(orgGroup
.getOrg().toASCIIString()));
Iterable<? extends NodeMetadata> nodesInGroup = filter(nodesInOrg, inGroup(orgGroup.getName()));
if (size(nodesInGroup) == 0 || all(nodesInGroup, TERMINATED))
if (size(nodesInGroup) == 0 || all(nodesInGroup, TERMINATED)){
deleteKeyPair.execute(orgGroup);
}
}
}

View File

@ -18,13 +18,17 @@
*/
package org.jclouds.trmk.vcloud_0_8.compute.strategy;
import static com.google.common.base.Preconditions.checkState;
import java.net.URI;
import java.util.concurrent.ConcurrentMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.crypto.SshKeys;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.compute.functions.CreateUniqueKeyPair;
import org.jclouds.trmk.vcloud_0_8.compute.options.TerremarkVCloudTemplateOptions;
@ -39,30 +43,41 @@ import com.google.common.annotations.VisibleForTesting;
*/
@Singleton
public class CreateNewKeyPairUnlessUserSpecifiedOtherwise {
final ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap;
final Map<String, Credentials> credentialStore;
@VisibleForTesting
final CreateUniqueKeyPair createUniqueKeyPair;
@Inject
CreateNewKeyPairUnlessUserSpecifiedOtherwise(ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap,
CreateUniqueKeyPair createUniqueKeyPair) {
this.credentialsMap = credentialsMap;
CreateNewKeyPairUnlessUserSpecifiedOtherwise(Map<String, Credentials> credentialStore,
CreateUniqueKeyPair createUniqueKeyPair) {
this.credentialStore = credentialStore;
this.createUniqueKeyPair = createUniqueKeyPair;
}
@VisibleForTesting
public void execute(URI org, String tag, String identity, TerremarkVCloudTemplateOptions options) {
public void execute(URI org, String group, String identity, TerremarkVCloudTemplateOptions options) {
String sshKeyFingerprint = options.getSshKeyFingerprint();
boolean shouldAutomaticallyCreateKeyPair = options.shouldAutomaticallyCreateKeyPair();
if (sshKeyFingerprint == null && shouldAutomaticallyCreateKeyPair) {
OrgAndName orgAndName = new OrgAndName(org, tag);
if (credentialsMap.containsKey(orgAndName)) {
options.sshKeyFingerprint(credentialsMap.get(orgAndName).getKeyPair().getFingerPrint());
} else {
KeyPair keyPair = createUniqueKeyPair.apply(orgAndName);
credentialsMap.put(orgAndName, new KeyPairCredentials(identity, keyPair));
options.sshKeyFingerprint(keyPair.getFingerPrint());
// make sure that we don't request multiple keys simultaneously
synchronized (credentialStore) {
// if there is already a keypair for the group specified, use it
if (credentialStore.containsKey("group#" + group)) {
LoginCredentials creds = LoginCredentials.fromCredentials(credentialStore.get("group#" + group));
checkState(creds.getOptionalPrivateKey().isPresent(),
"incorrect state: should have private key for: %s", creds);
options.sshKeyFingerprint(SshKeys.fingerprintPrivateKey(creds.getPrivateKey()));
} else {
// otherwise create a new keypair and key it under the group
KeyPair keyPair = createUniqueKeyPair.apply(new OrgAndName(org, group));
credentialStore.put("group#" + group, LoginCredentials.builder().user(identity).privateKey(
keyPair.getPrivateKey()).build());
options.sshKeyFingerprint(keyPair.getFingerPrint());
}
}
}
}
}
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.trmk.vcloud_0_8.compute.strategy;
import java.util.concurrent.ConcurrentMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -26,9 +26,9 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.domain.KeyPair;
@ -44,12 +44,12 @@ public class DeleteKeyPair {
protected Logger logger = Logger.NULL;
final TerremarkVCloudClient terremarkClient;
final ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap;
final Map<String, Credentials> credentialStore;
@Inject
DeleteKeyPair(TerremarkVCloudClient terremarkClient, ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap) {
DeleteKeyPair(TerremarkVCloudClient terremarkClient, Map<String, Credentials> credentialStore) {
this.terremarkClient = terremarkClient;
this.credentialsMap = credentialsMap;
this.credentialStore = credentialStore;
}
public void execute(OrgAndName orgTag) {
@ -57,9 +57,8 @@ public class DeleteKeyPair {
if (keyPair.getName().matches("jclouds_" + orgTag.getName().replaceAll("-", "_") + "_[0-9a-f]+")) {
logger.debug(">> deleting keyPair(%s)", keyPair.getName());
terremarkClient.deleteKeyPair(keyPair.getId());
// TODO: test this clear happens
credentialsMap.remove(orgTag);
logger.debug("<< deleted keyPair(%s)", keyPair.getName());
credentialStore.remove("group#" + orgTag.getName());
}
}
}

View File

@ -26,11 +26,13 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.TerremarkVCloudComputeClient;
import org.jclouds.trmk.vcloud_0_8.compute.functions.TemplateToInstantiateOptions;
import org.jclouds.trmk.vcloud_0_8.domain.VApp;
@ -46,28 +48,34 @@ public class StartVAppWithGroupEncodedIntoName implements CreateNodeWithGroupEnc
protected final TerremarkVCloudComputeClient computeClient;
protected final TemplateToInstantiateOptions getOptions;
protected final Function<VApp, NodeMetadata> vAppToNodeMetadata;
private final Map<String, Credentials> credentialStore;
protected final Map<String, Credentials> credentialStore;
protected final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate;
@Inject
protected StartVAppWithGroupEncodedIntoName(TerremarkVCloudComputeClient computeClient,
Function<VApp, NodeMetadata> vAppToNodeMetadata, TemplateToInstantiateOptions getOptions,
Map<String, Credentials> credentialStore) {
Map<String, Credentials> credentialStore, PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate) {
this.computeClient = computeClient;
this.vAppToNodeMetadata = vAppToNodeMetadata;
this.getOptions = checkNotNull(getOptions, "getOptions");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.prioritizeCredentialsFromTemplate = checkNotNull(prioritizeCredentialsFromTemplate, "prioritizeCredentialsFromTemplate");
}
@Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
InstantiateVAppTemplateOptions options = getOptions.apply(template);
VApp vApp = computeClient.start(URI.create(template.getLocation().getId()), URI.create(template
NodeAndInitialCredentials<VApp> from = computeClient.startAndReturnCredentials(URI.create(template.getLocation().getId()), URI.create(template
.getImage().getId()), name, options, template.getOptions().getInboundPorts());
NodeMetadata node = vAppToNodeMetadata.apply(vApp);
NodeMetadataBuilder builder = NodeMetadataBuilder.fromNodeMetadata(node);
if (template.getImage().getDefaultCredentials() != null)
credentialStore.put("node#" + node.getId(), template.getImage().getDefaultCredentials());
return builder.build();
LoginCredentials fromNode = from.getCredentials();
if (credentialStore.containsKey("group#" + group)) {
fromNode = fromNode == null ? LoginCredentials.fromCredentials(credentialStore.get("group#" + group))
: fromNode.toBuilder().privateKey(credentialStore.get("group#" + group).credential).build();
}
LoginCredentials creds = prioritizeCredentialsFromTemplate.apply(template, fromNode);
if (creds != null)
credentialStore.put("node#" + from.getNodeId(), creds);
return vAppToNodeMetadata.apply(from.getNode());
}
}

View File

@ -31,10 +31,11 @@ import java.util.Map;
import javax.inject.Provider;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.jclouds.trmk.vcloud_0_8.compute.strategy.ParseVAppTemplateDescriptionToGetDefaultLoginCredentials;
import org.jclouds.trmk.vcloud_0_8.domain.Status;
import org.jclouds.trmk.vcloud_0_8.domain.Task;
import org.jclouds.trmk.vcloud_0_8.domain.VApp;
@ -88,7 +89,7 @@ public class TerremarkVCloudComputeClientTest {
Map<Status, NodeState> vAppStatusToNodeState = createMock(Map.class);
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client,
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(null), new Provider<String>() {
new Provider<String>() {
@Override
public String get() {
@ -106,10 +107,11 @@ public class TerremarkVCloudComputeClientTest {
replay(notFoundTester);
replay(vAppStatusToNodeState);
VApp response = computeClient.start(vdcURI, templateURI, "name", new InstantiateVAppTemplateOptions());
NodeAndInitialCredentials<VApp> response = computeClient.startAndReturnCredentials(vdcURI, templateURI, "name", new InstantiateVAppTemplateOptions());
assertEquals(response.getHref().toASCIIString(), "vapp");
assertEquals(credentialStore.get("node#vapp"), new Credentials("Administrator", "password"));
assertEquals(response.getNodeId(), "vapp");
assertEquals(response.getNode(),vApp);
assertEquals(response.getCredentials(), LoginCredentials.builder().password("password").build());
verify(vdc);
verify(template);

View File

@ -140,9 +140,8 @@ public class CleanupOrphanKeysTest {
}
private void expectCleanupCredentialStore(CleanupOrphanKeys strategy, NodeMetadata nodeMetadata) {
expect("node#" + nodeMetadata.getId()).andReturn("1").times(2);
expect("node#" + nodeMetadata.getId()).andReturn("1");
expect(strategy.credentialStore.remove("node#1")).andReturn(null);
expect(strategy.credentialStore.remove("node#1#adminPassword")).andReturn(null);
}
public void testWhenNoneLeftWithTag() {

View File

@ -27,14 +27,16 @@ import static org.jclouds.trmk.vcloud_0_8.compute.options.TerremarkVCloudTemplat
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.compute.functions.CreateUniqueKeyPair;
import org.jclouds.trmk.vcloud_0_8.compute.options.TerremarkVCloudTemplateOptions;
import org.jclouds.trmk.vcloud_0_8.compute.strategy.CreateNewKeyPairUnlessUserSpecifiedOtherwise;
import org.jclouds.trmk.vcloud_0_8.domain.KeyPair;
import org.jclouds.trmk.vcloud_0_8.xml.KeyPairHandlerTest;
import org.testng.annotations.Test;
/**
@ -47,34 +49,25 @@ public class CreateNewKeyPairUnlessUserSpecifiedOtherwiseTest {
// setup constants
URI org = URI.create("org1");
String identity = "identity";
String tag = "tag";
OrgAndName orgAndName = new OrgAndName(org, "tag");
String systemGeneratedFingerprint = "systemGeneratedKeyPairfinger";
String group = "group";
TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions();
// create mocks
CreateNewKeyPairUnlessUserSpecifiedOtherwise strategy = setupStrategy();
KeyPairCredentials keyPairCredentials = createMock(KeyPairCredentials.class);
KeyPair keyPair = createMock(KeyPair.class);
LoginCredentials keyPairCredentials = LoginCredentials.builder().privateKey(KeyPairHandlerTest.keyPair.getPrivateKey()).build();
// setup expectations
expect(strategy.credentialsMap.containsKey(orgAndName)).andReturn(true);
expect(strategy.credentialsMap.get(orgAndName)).andReturn(keyPairCredentials);
expect(keyPairCredentials.getKeyPair()).andReturn(keyPair);
expect(keyPair.getFingerPrint()).andReturn(systemGeneratedFingerprint).atLeastOnce();
expect(strategy.credentialStore.containsKey("group#group")).andReturn(true);
expect(strategy.credentialStore.get("group#group")).andReturn(keyPairCredentials);
// replay mocks
replay(keyPair);
replay(keyPairCredentials);
replayStrategy(strategy);
// run
strategy.execute(org, tag, identity, options);
assertEquals(options.getSshKeyFingerprint(), "systemGeneratedKeyPairfinger");
strategy.execute(org, group, identity, options);
assertEquals(options.getSshKeyFingerprint(), KeyPairHandlerTest.keyPair.getFingerPrint());
// verify mocks
verify(keyPair);
verify(keyPairCredentials);
verifyStrategy(strategy);
}
@ -82,7 +75,7 @@ public class CreateNewKeyPairUnlessUserSpecifiedOtherwiseTest {
// setup constants
URI org = URI.create("org1");
String identity = "identity";
String tag = "tag";
String group = "group";
TerremarkVCloudTemplateOptions options = sshKeyFingerprint("fingerprintFromUser");
// create mocks
@ -94,7 +87,7 @@ public class CreateNewKeyPairUnlessUserSpecifiedOtherwiseTest {
replayStrategy(strategy);
// run
strategy.execute(org, tag, identity, options);
strategy.execute(org, group, identity, options);
assertEquals(options.getSshKeyFingerprint(), "fingerprintFromUser");
// verify mocks
@ -108,30 +101,27 @@ public class CreateNewKeyPairUnlessUserSpecifiedOtherwiseTest {
// setup constants
URI org = URI.create("org1");
String identity = "identity";
String tag = "tag";
String group = "group";
String systemGeneratedFingerprint = "systemGeneratedKeyPairfinger";
String privateKey = "privateKey";
TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions();
OrgAndName orgAndName = new OrgAndName(org, "tag");
// create mocks
CreateNewKeyPairUnlessUserSpecifiedOtherwise strategy = setupStrategy();
KeyPairCredentials keyPairCredentials = createMock(KeyPairCredentials.class);
LoginCredentials keyPairCredentials = LoginCredentials.builder().privateKey(KeyPairHandlerTest.keyPair.getPrivateKey()).build();
KeyPair keyPair = createMock(KeyPair.class);
// setup expectations
expect(strategy.credentialsMap.containsKey(orgAndName)).andReturn(false);
expect(strategy.createUniqueKeyPair.apply(orgAndName)).andReturn(keyPair);
expect(keyPair.getFingerPrint()).andReturn(systemGeneratedFingerprint).atLeastOnce();
expect(keyPair.getPrivateKey()).andReturn(privateKey).atLeastOnce();
expect(strategy.credentialsMap.put(orgAndName, keyPairCredentials)).andReturn(null);
expect(strategy.credentialStore.containsKey("group#group")).andReturn(false);
expect(strategy.createUniqueKeyPair.apply(new OrgAndName(org, "group"))).andReturn(keyPair);
expect(keyPair.getFingerPrint()).andReturn(KeyPairHandlerTest.keyPair.getFingerPrint()).atLeastOnce();
expect(strategy.credentialStore.put("group#group", keyPairCredentials)).andReturn(null);
// replay mocks
replay(keyPair);
replayStrategy(strategy);
// run
strategy.execute(org, tag, identity, options);
strategy.execute(org, group, identity, options);
assertEquals(options.getSshKeyFingerprint(), systemGeneratedFingerprint);
// verify mocks
@ -143,43 +133,40 @@ public class CreateNewKeyPairUnlessUserSpecifiedOtherwiseTest {
// setup constants
URI org = URI.create("org1");
String identity = "identity";
String tag = "tag";
String group = "group";
TerremarkVCloudTemplateOptions options = noKeyPair();
// create mocks
CreateNewKeyPairUnlessUserSpecifiedOtherwise strategy = setupStrategy();
KeyPair keyPair = createMock(KeyPair.class);
// setup expectations
// replay mocks
replay(keyPair);
replayStrategy(strategy);
// run
strategy.execute(org, tag, identity, options);
strategy.execute(org, group, identity, options);
assertEquals(options.getSshKeyFingerprint(), null);
// verify mocks
verify(keyPair);
verifyStrategy(strategy);
}
private void verifyStrategy(CreateNewKeyPairUnlessUserSpecifiedOtherwise strategy) {
verify(strategy.credentialsMap);
verify(strategy.credentialStore);
verify(strategy.createUniqueKeyPair);
}
@SuppressWarnings("unchecked")
private CreateNewKeyPairUnlessUserSpecifiedOtherwise setupStrategy() {
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap = createMock(ConcurrentMap.class);
Map<String, Credentials> credentialStore = createMock(ConcurrentMap.class);
CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class);
return new CreateNewKeyPairUnlessUserSpecifiedOtherwise(credentialsMap, createUniqueKeyPair);
return new CreateNewKeyPairUnlessUserSpecifiedOtherwise(credentialStore, createUniqueKeyPair);
}
private void replayStrategy(CreateNewKeyPairUnlessUserSpecifiedOtherwise strategy) {
replay(strategy.credentialsMap);
replay(strategy.credentialStore);
replay(strategy.createUniqueKeyPair);
}

View File

@ -24,12 +24,12 @@ import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import org.jclouds.domain.Credentials;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.jclouds.trmk.vcloud_0_8.compute.domain.KeyPairCredentials;
import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName;
import org.jclouds.trmk.vcloud_0_8.compute.strategy.DeleteKeyPair;
import org.jclouds.trmk.vcloud_0_8.domain.KeyPair;
import org.testng.annotations.Test;
@ -78,7 +78,7 @@ public class DeleteKeyPairTest {
expect(keyPair.getName()).andReturn("jclouds_" + orgTag.getName() + "_123").atLeastOnce();
expect(keyPair.getId()).andReturn(URI.create("1245"));
strategy.terremarkClient.deleteKeyPair(URI.create("1245"));
expect(strategy.credentialsMap.remove(orgTag)).andReturn(null);
expect(strategy.credentialStore.remove("group#tag")).andReturn(null);
// replay mocks
replay(keyPair);
@ -119,20 +119,20 @@ public class DeleteKeyPairTest {
}
private void verifyStrategy(DeleteKeyPair strategy) {
verify(strategy.credentialsMap);
verify(strategy.credentialStore);
verify(strategy.terremarkClient);
}
@SuppressWarnings("unchecked")
private DeleteKeyPair setupStrategy() {
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap = createMock(ConcurrentMap.class);
Map<String, Credentials> credentialStore = createMock(ConcurrentMap.class);
TerremarkVCloudClient terremarkClient = createMock(TerremarkVCloudClient.class);
return new DeleteKeyPair(terremarkClient, credentialsMap);
return new DeleteKeyPair(terremarkClient, credentialStore);
}
private void replayStrategy(DeleteKeyPair strategy) {
replay(strategy.credentialsMap);
replay(strategy.credentialStore);
replay(strategy.terremarkClient);
}