JCLOUDS-549: Fix NPE in LoginCredentials.toString

- also deprecates LoginCredentails.get(Password|PrivateKey)
- use getOptionalPassword and getOptionalPrivateKey instead
This commit is contained in:
Aled Sage 2014-05-17 21:59:17 +01:00
parent fb60d76704
commit 1fb286809e
25 changed files with 117 additions and 71 deletions

View File

@ -18,6 +18,7 @@ package org.jclouds.cloudstack.compute;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -179,7 +180,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertEquals(server.getCredentials().getPrivateKey(), privKey); assertEquals(server.getCredentials().getOptionalPrivateKey().get(), privKey);
} }
public void testCreateNodeWithGroupEncodedIntoNameWithGenerateKeyPair() throws IOException { public void testCreateNodeWithGroupEncodedIntoNameWithGenerateKeyPair() throws IOException {
@ -226,7 +227,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertNotNull(server.getCredentials().getPrivateKey()); assertTrue(server.getCredentials().getOptionalPrivateKey().isPresent());
} }
public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairDefaultSecurityGroup() throws IOException { public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairDefaultSecurityGroup() throws IOException {
@ -277,7 +278,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertEquals(server.getCredentials().getPrivateKey(), privKey); assertEquals(server.getCredentials().getOptionalPrivateKey().get(), privKey);
} }
public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairDefaultSecurityGroupAndDisk() throws IOException { public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairDefaultSecurityGroupAndDisk() throws IOException {
@ -333,7 +334,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertEquals(server.getCredentials().getPrivateKey(), privKey); assertEquals(server.getCredentials().getOptionalPrivateKey().get(), privKey);
} }
public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairGenerateSecurityGroup() throws IOException { public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairGenerateSecurityGroup() throws IOException {
@ -391,7 +392,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertEquals(server.getCredentials().getPrivateKey(), privKey); assertEquals(server.getCredentials().getOptionalPrivateKey().get(), privKey);
} }
public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairAssignedToAccountAndDomain() throws IOException { public void testCreateNodeWithGroupEncodedIntoNameWithKeyPairAssignedToAccountAndDomain() throws IOException {
@ -444,7 +445,7 @@ public class CloudStackComputeServiceAdapterExpectTest extends BaseCloudStackCom
NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92", NodeAndInitialCredentials<VirtualMachine> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template); template);
assertNotNull(server); assertNotNull(server);
assertEquals(server.getCredentials().getPrivateKey(), privKey); assertEquals(server.getCredentials().getOptionalPrivateKey().get(), privKey);
} }
@Override @Override

View File

@ -77,7 +77,7 @@ public class FirewallApiLiveTest extends BaseCloudStackApiLiveTest {
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
client, jobComplete, virtualMachineRunning); client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && loginCredentials.getOptionalPassword() == null) if (vm.getPassword() != null && !loginCredentials.getOptionalPassword().isPresent())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {

View File

@ -89,7 +89,7 @@ public class LoadBalancerApiLiveTest extends BaseCloudStackApiLiveTest {
vm = VirtualMachineApiLiveTest.createVirtualMachineInNetwork(network, vm = VirtualMachineApiLiveTest.createVirtualMachineInNetwork(network,
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
client, jobComplete, virtualMachineRunning); client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && loginCredentials.getOptionalPassword() == null) if (vm.getPassword() != null && !loginCredentials.getOptionalPassword().isPresent())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} }

View File

@ -177,7 +177,7 @@ public class SecurityGroupApiLiveTest extends BaseCloudStackApiLiveTest {
vm = VirtualMachineApiLiveTest.createVirtualMachineWithSecurityGroupInZone(zone.getId(), vm = VirtualMachineApiLiveTest.createVirtualMachineWithSecurityGroupInZone(zone.getId(),
defaultTemplateOrPreferredInZone(defaultTemplate, client, zone.getId()), group.getId(), client, defaultTemplateOrPreferredInZone(defaultTemplate, client, zone.getId()), group.getId(), client,
jobComplete, virtualMachineRunning); jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && loginCredentials.getOptionalPassword() == null) if (vm.getPassword() != null && !loginCredentials.getOptionalPassword().isPresent())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
// ingress port 22 // ingress port 22
checkSSH(HostAndPort.fromParts(vm.getIPAddress(), 22)); checkSSH(HostAndPort.fromParts(vm.getIPAddress(), 22));

View File

@ -74,7 +74,7 @@ public class VirtualMachineApiExpectTest extends BaseCloudStackExpectTest<Virtua
WindowsLoginCredentialsFromEncryptedData passwordDecrypt = new WindowsLoginCredentialsFromEncryptedData(new JCECrypto()); WindowsLoginCredentialsFromEncryptedData passwordDecrypt = new WindowsLoginCredentialsFromEncryptedData(new JCECrypto());
assertEquals(passwordDecrypt.apply( assertEquals(passwordDecrypt.apply(
EncryptedPasswordAndPrivateKey.builder().encryptedPassword(actual).privateKey(privateKey).build()).getPassword(), "bX7vvptvw"); EncryptedPasswordAndPrivateKey.builder().encryptedPassword(actual).privateKey(privateKey).build()).getOptionalPassword().get(), "bX7vvptvw");
} }
HttpRequest deployVirtualMachineInZone = HttpRequest.builder().method("GET") HttpRequest deployVirtualMachineInZone = HttpRequest.builder().method("GET")

View File

@ -279,7 +279,7 @@ public class VirtualMachineApiLiveTest extends BaseCloudStackApiLiveTest {
} }
private void conditionallyCheckSSH() { private void conditionallyCheckSSH() {
if (vm.getPassword() != null && loginCredentials.getOptionalPassword() == null) if (vm.getPassword() != null && !loginCredentials.getOptionalPassword().isPresent())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
assert HostSpecifier.isValid(vm.getIPAddress()); assert HostSpecifier.isValid(vm.getIPAddress());
if (!InetAddresses2.isPrivateIPAddress(vm.getIPAddress())) { if (!InetAddresses2.isPrivateIPAddress(vm.getIPAddress())) {

View File

@ -62,7 +62,7 @@ public class StaticNATVirtualMachineInNetworkLiveTest extends NATApiLiveTest {
vm = VirtualMachineApiLiveTest.createVirtualMachineInNetwork(network, vm = VirtualMachineApiLiveTest.createVirtualMachineInNetwork(network,
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete, defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete,
virtualMachineRunning); virtualMachineRunning);
if (vm.getPassword() != null && loginCredentials.getOptionalPassword() == null) if (vm.getPassword() != null && !loginCredentials.getOptionalPassword().isPresent())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
networksDisabled = true; networksDisabled = true;

View File

@ -62,7 +62,7 @@ public class WindowsLoginCredentialsFromEncryptedDataTest {
LoginCredentials credentials = f.apply(new EncryptedPasswordAndPrivateKey(ENCRYPTED_PASSWORD, PRIVATE_KEY)); LoginCredentials credentials = f.apply(new EncryptedPasswordAndPrivateKey(ENCRYPTED_PASSWORD, PRIVATE_KEY));
assertEquals(credentials.getUser(), "Administrator"); assertEquals(credentials.getUser(), "Administrator");
assertEquals(credentials.getPassword(), "u4.y9mb;nR."); assertEquals(credentials.getOptionalPassword().get(), "u4.y9mb;nR.");
assertFalse(credentials.getOptionalPrivateKey().isPresent()); assertFalse(credentials.getOptionalPrivateKey().isPresent());
} }
} }

View File

@ -20,6 +20,7 @@ import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.blockUn
import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.maxCount; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.maxCount;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.util.Set; import java.util.Set;
@ -132,7 +133,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest
blockUntilRunning(false).overrideLoginUser("ec2-user"))); blockUntilRunning(false).overrideLoginUser("ec2-user")));
assertEquals(node.getCredentials().getUser(), "ec2-user"); assertEquals(node.getCredentials().getUser(), "ec2-user");
System.out.println(node.getImageId()); System.out.println(node.getImageId());
assertNotNull(node.getCredentials().getPrivateKey()); assertTrue(node.getCredentials().getOptionalPrivateKey().isPresent());
} }
public void testCreateThreeNodesWithMaxCountThree() throws Exception { public void testCreateThreeNodesWithMaxCountThree() throws Exception {
@ -312,7 +313,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest
apiThatCreatesNode.createNodesInGroup("test", 1, apiThatCreatesNode.createNodesInGroup("test", 1,
apiThatCreatesNode.templateBuilder().from("osDescriptionMatches=.*fedora.*,loginUser=ec2-user").build())); apiThatCreatesNode.templateBuilder().from("osDescriptionMatches=.*fedora.*,loginUser=ec2-user").build()));
assertEquals(node.getCredentials().getUser(), "ec2-user"); assertEquals(node.getCredentials().getUser(), "ec2-user");
assertNotNull(node.getCredentials().getPrivateKey()); assertTrue(node.getCredentials().getOptionalPrivateKey().isPresent());
} }
} }

View File

@ -68,7 +68,7 @@ public class WindowsLoginCredentialsFromEncryptedDataTest {
LoginCredentials credentials = f.apply(new PasswordDataAndPrivateKey(passwordData, PRIVATE_KEY)); LoginCredentials credentials = f.apply(new PasswordDataAndPrivateKey(passwordData, PRIVATE_KEY));
assertEquals(credentials.getUser(), "Administrator"); assertEquals(credentials.getUser(), "Administrator");
assertEquals(credentials.getPassword(), "u4.y9mb;nR."); assertEquals(credentials.getOptionalPassword().get(), "u4.y9mb;nR.");
assertFalse(credentials.getOptionalPrivateKey().isPresent()); assertFalse(credentials.getOptionalPrivateKey().isPresent());
} }
} }

View File

@ -317,7 +317,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
// setup expectations // setup expectations
expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); expect(options.getKeyPair()).andReturn(userSuppliedKeyPair);
expect(options.getLoginPrivateKey()).andReturn(CREDENTIALS.getPrivateKey()).atLeastOnce(); expect(options.getLoginPrivateKey()).andReturn(CREDENTIALS.getOptionalPrivateKey().get()).atLeastOnce();
// Notice that the fingerprint and sha1 generated // Notice that the fingerprint and sha1 generated
expect(strategy.credentialsMap.put(new RegionAndName(region, userSuppliedKeyPair), KEYPAIR)).andReturn(null); expect(strategy.credentialsMap.put(new RegionAndName(region, userSuppliedKeyPair), KEYPAIR)).andReturn(null);

View File

@ -20,6 +20,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions.Builder.blockUntilRunning; import static org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions.Builder.blockUntilRunning;
import static org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions.Builder.keyPairName; import static org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions.Builder.keyPairName;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -267,7 +268,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1, NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1,
blockUntilRunning(false).generateKeyPair(true))); blockUntilRunning(false).generateKeyPair(true)));
assertNotNull(node.getCredentials().getPrivateKey()); assertTrue(node.getCredentials().getOptionalPrivateKey().isPresent());
} }
@Test @Test
@ -323,7 +324,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1, NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1,
keyPairName("fooPair").blockUntilRunning(false))); keyPairName("fooPair").blockUntilRunning(false)));
// we don't have access to this private key // we don't have access to this private key
assertEquals(node.getCredentials().getPrivateKey(), null); assertFalse(node.getCredentials().getOptionalPrivateKey().isPresent());
} }
@ -374,7 +375,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1, NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1,
keyPairName("fooPair").securityGroupNames("mygroup").blockUntilRunning(false))); keyPairName("fooPair").securityGroupNames("mygroup").blockUntilRunning(false)));
// we don't have access to this private key // we don't have access to this private key
assertEquals(node.getCredentials().getPrivateKey(), null); assertFalse(node.getCredentials().getOptionalPrivateKey().isPresent());
} }
} }

View File

@ -102,8 +102,8 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
protected ExecResponse runCommand(String command) { protected ExecResponse runCommand(String command) {
ExecResponse returnVal; ExecResponse returnVal;
logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().getPassword() != null ? node logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().getOptionalPassword().isPresent() ? node
.getCredentials().getPassword() : "XXXXX", "XXXXX"), ssh.getUsername(), ssh.getHostAddress()); .getCredentials().getOptionalPassword().get() : "XXXXX", "XXXXX"), ssh.getUsername(), ssh.getHostAddress());
returnVal = ssh.exec(command); returnVal = ssh.exec(command);
return returnVal; return returnVal;
} }
@ -112,7 +112,7 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
public String execAsRoot(String command) { public String execAsRoot(String command) {
if (node.getCredentials().identity.equals("root")) { if (node.getCredentials().identity.equals("root")) {
} else if (node.getCredentials().shouldAuthenticateSudo()) { } else if (node.getCredentials().shouldAuthenticateSudo()) {
command = String.format("sudo -S sh <<'%s'\n%s\n%s%s\n", MARKER, node.getCredentials().getPassword(), command, MARKER); command = String.format("sudo -S sh <<'%s'\n%s\n%s%s\n", MARKER, node.getCredentials().getOptionalPassword().get(), command, MARKER);
} else { } else {
command = String.format("sudo sh <<'%s'\n%s%s\n", MARKER, command, MARKER); command = String.format("sudo sh <<'%s'\n%s%s\n", MARKER, command, MARKER);
} }

View File

@ -95,7 +95,7 @@ public class SudoAwareInitManager {
ExecResponse runCommand(String command) { ExecResponse runCommand(String command) {
String statement = String.format("[%s] as %s@%s", command.replace( String statement = String.format("[%s] as %s@%s", command.replace(
node.getCredentials().getPassword() != null ? node.getCredentials().getPassword() : "XXXXX", "XXXXX"), ssh node.getCredentials().getOptionalPassword().isPresent() ? node.getCredentials().getOptionalPassword().get() : "XXXXX", "XXXXX"), ssh
.getUsername(), ssh.getHostAddress()); .getUsername(), ssh.getHostAddress());
if (command.endsWith("status") || command.endsWith("stdout") || command.endsWith("stderr")) if (command.endsWith("status") || command.endsWith("stdout") || command.endsWith("stderr"))
logger.trace(">> running %s", statement); logger.trace(">> running %s", statement);
@ -113,7 +113,7 @@ public class SudoAwareInitManager {
if (node.getCredentials().identity.equals("root")) { if (node.getCredentials().identity.equals("root")) {
command = initFile + " " + action; command = initFile + " " + action;
} else if (node.getCredentials().shouldAuthenticateSudo()) { } else if (node.getCredentials().shouldAuthenticateSudo()) {
command = String.format("echo '%s'|sudo -S %s %s", node.getCredentials().getPassword(), command = String.format("echo '%s'|sudo -S %s %s", node.getCredentials().getOptionalPassword().get(),
initFile, action); initFile, action);
} else { } else {
command = "sudo " + initFile + " " + action; command = "sudo " + initFile + " " + action;

View File

@ -44,10 +44,10 @@ public class PrioritizeCredentialsFromTemplate {
Builder builder = LoginCredentials.builder(creds); Builder builder = LoginCredentials.builder(creds);
if (credsFromParameters.getUser() != null) if (credsFromParameters.getUser() != null)
builder.user(credsFromParameters.getUser()); builder.user(credsFromParameters.getUser());
if (credsFromParameters.getPassword() != null) if (credsFromParameters.getOptionalPassword().isPresent())
builder.password(credsFromParameters.getPassword()); builder.password(credsFromParameters.getOptionalPassword().get());
if (credsFromParameters.getPrivateKey() != null) if (credsFromParameters.getOptionalPrivateKey().isPresent())
builder.privateKey(credsFromParameters.getPrivateKey()); builder.privateKey(credsFromParameters.getOptionalPrivateKey().get());
if (credsFromParameters.shouldAuthenticateSudo()) if (credsFromParameters.shouldAuthenticateSudo())
builder.authenticateSudo(true); builder.authenticateSudo(true);
creds = builder.build(); creds = builder.build();

View File

@ -16,6 +16,7 @@
*/ */
package org.jclouds.domain; package org.jclouds.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.crypto.Pems.PRIVATE_PKCS1_MARKER; import static org.jclouds.crypto.Pems.PRIVATE_PKCS1_MARKER;
import static org.jclouds.crypto.Pems.PRIVATE_PKCS8_MARKER; import static org.jclouds.crypto.Pems.PRIVATE_PKCS8_MARKER;
@ -54,8 +55,8 @@ public class LoginCredentials extends Credentials {
public static class Builder extends Credentials.Builder<LoginCredentials> { public static class Builder extends Credentials.Builder<LoginCredentials> {
private boolean authenticateSudo; private boolean authenticateSudo;
private Optional<String> password; private Optional<String> password = Optional.absent();
private Optional<String> privateKey; private Optional<String> privateKey = Optional.absent();
public Builder identity(String identity) { public Builder identity(String identity) {
return Builder.class.cast(super.identity(identity)); return Builder.class.cast(super.identity(identity));
@ -67,8 +68,6 @@ public class LoginCredentials extends Credentials {
public Builder password(String password) { public Builder password(String password) {
this.password = Optional.fromNullable(password); this.password = Optional.fromNullable(password);
if (privateKey == null)
noPrivateKey();
return this; return this;
} }
@ -79,8 +78,6 @@ public class LoginCredentials extends Credentials {
public Builder privateKey(String privateKey) { public Builder privateKey(String privateKey) {
this.privateKey = Optional.fromNullable(privateKey); this.privateKey = Optional.fromNullable(privateKey);
if (password == null)
noPassword();
return this; return this;
} }
@ -103,7 +100,7 @@ public class LoginCredentials extends Credentials {
} }
public LoginCredentials build() { public LoginCredentials build() {
if (identity == null && password == null && privateKey == null && !authenticateSudo) if (identity == null && !password.isPresent() && !privateKey.isPresent() && !authenticateSudo)
return null; return null;
return new LoginCredentials(identity, password, privateKey, authenticateSudo); return new LoginCredentials(identity, password, privateKey, authenticateSudo);
} }
@ -113,13 +110,13 @@ public class LoginCredentials extends Credentials {
private final Optional<String> password; private final Optional<String> password;
private final Optional<String> privateKey; private final Optional<String> privateKey;
private LoginCredentials(String username, @Nullable Optional<String> password, @Nullable Optional<String> privateKey, boolean authenticateSudo) { private LoginCredentials(String username, Optional<String> password, Optional<String> privateKey, boolean authenticateSudo) {
super(username, privateKey != null && privateKey.isPresent() && isPrivateKeyCredential(privateKey.get()) super(username, privateKey.isPresent() && isPrivateKeyCredential(privateKey.get())
? privateKey.get() ? privateKey.get()
: (password != null && password.isPresent() ? password.get() : null)); : password.orNull());
this.authenticateSudo = authenticateSudo; this.authenticateSudo = authenticateSudo;
this.password = password; this.password = checkNotNull(password, "password");
this.privateKey = privateKey; this.privateKey = checkNotNull(privateKey, "privateKey");
} }
/** /**
@ -131,41 +128,45 @@ public class LoginCredentials extends Credentials {
/** /**
* @return the password of the login user or null * @return the password of the login user or null
*
* @deprecated since 1.8; instead use {@link #getOptionalPassword()}
*/ */
@Nullable @Nullable
@Deprecated
public String getPassword() { public String getPassword() {
return (password != null) ? password.orNull() : null; return password.orNull();
} }
/** /**
* @return the optional password of the user or null * @return the optional password of the user (Optional.absent if none supplied).
*/ */
@Nullable
public Optional<String> getOptionalPassword() { public Optional<String> getOptionalPassword() {
return password; return password;
} }
/** /**
* @return the private ssh key of the user or null * @return the private ssh key of the user or null
*
* @deprecated since 1.8; instead use {@link #getOptionalPrivateKey()}
*/ */
@Nullable @Nullable
@Deprecated
public String getPrivateKey() { public String getPrivateKey() {
return (privateKey != null) ? privateKey.orNull() : null; return privateKey.orNull();
} }
/** /**
* @return true if there is a private key attached that is not encrypted * @return true if there is a private key attached that is not encrypted
*/ */
public boolean hasUnencryptedPrivateKey() { public boolean hasUnencryptedPrivateKey() {
return getPrivateKey() != null return getOptionalPrivateKey().isPresent()
&& !getPrivateKey().isEmpty() && !getOptionalPrivateKey().get().isEmpty()
&& !getPrivateKey().contains(Pems.PROC_TYPE_ENCRYPTED); && !getOptionalPrivateKey().get().contains(Pems.PROC_TYPE_ENCRYPTED);
} }
/** /**
* @return the optional private ssh key of the user or null * @return the optional private ssh key of the user (Optional.absent if none supplied).
*/ */
@Nullable
public Optional<String> getOptionalPrivateKey() { public Optional<String> getOptionalPrivateKey() {
return privateKey; return privateKey;
} }

View File

@ -85,8 +85,8 @@ public class CredentialStoreModule extends AbstractModule {
LoginCredentials login = LoginCredentials.class.cast(from); LoginCredentials login = LoginCredentials.class.cast(from);
JsonLoginCredentials val = new JsonLoginCredentials(); JsonLoginCredentials val = new JsonLoginCredentials();
val.user = login.getUser(); val.user = login.getUser();
val.password = login.getPassword(); val.password = login.getOptionalPassword().orNull();
val.privateKey = login.getPrivateKey(); val.privateKey = login.getOptionalPrivateKey().orNull();
if (login.shouldAuthenticateSudo()) if (login.shouldAuthenticateSudo())
val.authenticateSudo = login.shouldAuthenticateSudo(); val.authenticateSudo = login.shouldAuthenticateSudo();
return ByteSource.wrap(json.toJson(val).getBytes(Charsets.UTF_8)); return ByteSource.wrap(json.toJson(val).getBytes(Charsets.UTF_8));

View File

@ -17,6 +17,7 @@
package org.jclouds.domain; package org.jclouds.domain;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -48,4 +49,15 @@ public class LoginCredentialsTest {
assertEquals(toTest.getOptionalPassword(), Optional.of("password")); assertEquals(toTest.getOptionalPassword(), Optional.of("password"));
assertEquals(toTest.getOptionalPrivateKey(), Optional.of("key")); assertEquals(toTest.getOptionalPrivateKey(), Optional.of("key"));
} }
public void testToStringWhenNullPasswordAndKey() {
LoginCredentials toTest = LoginCredentials.builder().user("myuser").build();
assertNotNull(toTest.toString());
}
public void testToString() {
LoginCredentials toTest = LoginCredentials.builder().user("myuser").password("password").privateKey("key").build();
assertNotNull(toTest.toString());
}
} }

View File

@ -34,6 +34,7 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.io.ByteSource; import com.google.common.io.ByteSource;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -124,6 +125,25 @@ public class CredentialStoreModuleTest {
remove(map, getStore(createInjector()), "test"); remove(map, getStore(createInjector()), "test");
} }
public void testCredentialsToByteSourceConversion() throws Exception {
Function<Credentials, ByteSource> toBytesFunc = getCredentialsToByteStoreFunction(createInjector());
Function<ByteSource, Credentials> fromBytesFunc = getByteStoreToCredentialsFunction(createInjector());
LoginCredentials creds = LoginCredentials.builder().user("myuser").password("mypass").authenticateSudo(true).build();
ByteSource bytes = toBytesFunc.apply(creds);
LoginCredentials deserializedCreds = (LoginCredentials) fromBytesFunc.apply(bytes);
String json = bytes.asCharSource(Charsets.UTF_8).read();
assertEquals(json, "{\"user\":\"myuser\",\"password\":\"mypass\",\"authenticateSudo\":true}");
assertEquals(deserializedCreds.identity, creds.identity);
assertEquals(deserializedCreds.credential, creds.credential);
assertEquals(deserializedCreds.getUser(), creds.getUser());
assertEquals(deserializedCreds.getOptionalPassword(), creds.getOptionalPassword());
assertEquals(deserializedCreds.getOptionalPrivateKey(), creds.getOptionalPrivateKey());
assertEquals(deserializedCreds.shouldAuthenticateSudo(), creds.shouldAuthenticateSudo());
}
protected Map<String, Credentials> getStore(Injector injector) { protected Map<String, Credentials> getStore(Injector injector) {
return injector.getInstance(Key.get(new TypeLiteral<Map<String, Credentials>>() { return injector.getInstance(Key.get(new TypeLiteral<Map<String, Credentials>>() {
})); }));
@ -134,6 +154,16 @@ public class CredentialStoreModuleTest {
})); }));
} }
protected Function<ByteSource, Credentials> getByteStoreToCredentialsFunction(Injector injector) {
return injector.getInstance(Key.get(new TypeLiteral<Function<ByteSource, Credentials>>() {
}));
}
protected Function<Credentials, ByteSource> getCredentialsToByteStoreFunction(Injector injector) {
return injector.getInstance(Key.get(new TypeLiteral<Function<Credentials, ByteSource>>() {
}));
}
protected Injector createInjectorWithProvidedMap(Map<String, ByteSource> map) { protected Injector createInjectorWithProvidedMap(Map<String, ByteSource> map) {
return Guice.createInjector(new CredentialStoreModule(map), new GsonModule()); return Guice.createInjector(new CredentialStoreModule(map), new GsonModule());
} }

View File

@ -128,16 +128,16 @@ public class JschSshClient implements SshClient {
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser(); this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
this.host = checkNotNull(socket, "socket").getHostText(); this.host = checkNotNull(socket, "socket").getHostText();
checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort()); checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort());
checkArgument(loginCredentials.getPassword() != null || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(), checkArgument(loginCredentials.getOptionalPassword().isPresent() || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(),
"you must specify a password, a key or an SSH agent needs to be available"); "you must specify a password, a key or an SSH agent needs to be available");
this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler"); this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler");
if (loginCredentials.getPassword() != null) { if (loginCredentials.getOptionalPassword().isPresent()) {
this.toString = String.format("%s:pw[%s]@%s:%d", loginCredentials.getUser(), this.toString = String.format("%s:pw[%s]@%s:%d", loginCredentials.getUser(),
base16().lowerCase().encode(md5().hashString(loginCredentials.getPassword(), UTF_8).asBytes()), host, base16().lowerCase().encode(md5().hashString(loginCredentials.getOptionalPassword().get(), UTF_8).asBytes()), host,
socket.getPort()); socket.getPort());
} else if (loginCredentials.hasUnencryptedPrivateKey()) { } else if (loginCredentials.hasUnencryptedPrivateKey()) {
String fingerPrint = fingerprintPrivateKey(loginCredentials.getPrivateKey()); String fingerPrint = fingerprintPrivateKey(loginCredentials.getOptionalPrivateKey().get());
String sha1 = sha1PrivateKey(loginCredentials.getPrivateKey()); String sha1 = sha1PrivateKey(loginCredentials.getOptionalPrivateKey().get());
this.toString = String.format("%s:rsa[fingerprint(%s),sha1(%s)]@%s:%d", loginCredentials.getUser(), this.toString = String.format("%s:rsa[fingerprint(%s),sha1(%s)]@%s:%d", loginCredentials.getUser(),
fingerPrint, sha1, host, socket.getPort()); fingerPrint, sha1, host, socket.getPort());
} else { } else {

View File

@ -169,10 +169,10 @@ public final class SessionConnection implements Connection<Session> {
.getSession(loginCredentials.getUser(), hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22)); .getSession(loginCredentials.getUser(), hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22));
if (sessionTimeout != 0) if (sessionTimeout != 0)
session.setTimeout(sessionTimeout); session.setTimeout(sessionTimeout);
if (loginCredentials.getPrivateKey() == null) { if (!loginCredentials.getOptionalPrivateKey().isPresent()) {
session.setPassword(loginCredentials.getPassword()); session.setPassword(loginCredentials.getOptionalPassword().orNull());
} else if (loginCredentials.hasUnencryptedPrivateKey()) { } else if (loginCredentials.hasUnencryptedPrivateKey()) {
byte[] privateKey = loginCredentials.getPrivateKey().getBytes(); byte[] privateKey = loginCredentials.getOptionalPrivateKey().get().getBytes();
jsch.addIdentity(loginCredentials.getUser(), privateKey, null, emptyPassPhrase); jsch.addIdentity(loginCredentials.getUser(), privateKey, null, emptyPassPhrase);
} else if (agentConnector.isPresent()) { } else if (agentConnector.isPresent()) {
JSch.setConfig("PreferredAuthentications", "publickey"); JSch.setConfig("PreferredAuthentications", "publickey");

View File

@ -157,11 +157,11 @@ public class SSHClientConnection implements Connection<SSHClient> {
ssh.setTimeout(sessionTimeout); ssh.setTimeout(sessionTimeout);
} }
ssh.connect(hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22)); ssh.connect(hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22));
if (loginCredentials.getPassword() != null) { if (loginCredentials.getOptionalPassword().isPresent()) {
ssh.authPassword(loginCredentials.getUser(), loginCredentials.getPassword()); ssh.authPassword(loginCredentials.getUser(), loginCredentials.getOptionalPassword().get());
} else if (loginCredentials.hasUnencryptedPrivateKey()) { } else if (loginCredentials.hasUnencryptedPrivateKey()) {
OpenSSHKeyFile key = new OpenSSHKeyFile(); OpenSSHKeyFile key = new OpenSSHKeyFile();
key.init(loginCredentials.getPrivateKey(), null); key.init(loginCredentials.getOptionalPrivateKey().get(), null);
ssh.authPublickey(loginCredentials.getUser(), key); ssh.authPublickey(loginCredentials.getUser(), key);
} else if (agentConnector.isPresent()) { } else if (agentConnector.isPresent()) {
AgentProxy proxy = new AgentProxy(agentConnector.get()); AgentProxy proxy = new AgentProxy(agentConnector.get());

View File

@ -145,16 +145,16 @@ public class SshjSshClient implements SshClient {
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser(); this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
this.host = checkNotNull(socket, "socket").getHostText(); this.host = checkNotNull(socket, "socket").getHostText();
checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort()); checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort());
checkArgument(loginCredentials.getPassword() != null || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(), checkArgument(loginCredentials.getOptionalPassword().isPresent() || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(),
"you must specify a password, a key or an SSH agent needs to be available"); "you must specify a password, a key or an SSH agent needs to be available");
this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler"); this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler");
if (loginCredentials.getPassword() != null) { if (loginCredentials.getOptionalPassword().isPresent()) {
this.toString = String.format("%s:pw[%s]@%s:%d", loginCredentials.getUser(), this.toString = String.format("%s:pw[%s]@%s:%d", loginCredentials.getUser(),
base16().lowerCase().encode(md5().hashString(loginCredentials.getPassword(), UTF_8).asBytes()), host, base16().lowerCase().encode(md5().hashString(loginCredentials.getOptionalPassword().get(), UTF_8).asBytes()), host,
socket.getPort()); socket.getPort());
} else if (loginCredentials.hasUnencryptedPrivateKey()) { } else if (loginCredentials.hasUnencryptedPrivateKey()) {
String fingerPrint = fingerprintPrivateKey(loginCredentials.getPrivateKey()); String fingerPrint = fingerprintPrivateKey(loginCredentials.getOptionalPrivateKey().get());
String sha1 = sha1PrivateKey(loginCredentials.getPrivateKey()); String sha1 = sha1PrivateKey(loginCredentials.getOptionalPrivateKey().get());
this.toString = String.format("%s:rsa[fingerprint(%s),sha1(%s)]@%s:%d", loginCredentials.getUser(), this.toString = String.format("%s:rsa[fingerprint(%s),sha1(%s)]@%s:%d", loginCredentials.getUser(),
fingerPrint, sha1, host, socket.getPort()); fingerPrint, sha1, host, socket.getPort());
} else { } else {

View File

@ -170,11 +170,11 @@ public class AWSEC2ImageParserTest {
assertEquals( assertEquals(
new Gson().toJson(Iterables.get(result, 1)), new Gson().toJson(Iterables.get(result, 1)),
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"status\":\"AVAILABLE\",\"backendStatus\":\"available\",\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"authenticateSudo\":false,\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-c19db6b5\",\"name\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\",\"virtualizationType\":\"paravirtual\",\"hypervisor\":\"xen\"}}"); "{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"status\":\"AVAILABLE\",\"backendStatus\":\"available\",\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"authenticateSudo\":false,\"password\":{},\"privateKey\":{},\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-c19db6b5\",\"name\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\",\"virtualizationType\":\"paravirtual\",\"hypervisor\":\"xen\"}}");
assertEquals( assertEquals(
new Gson().toJson(Iterables.get(result, 2)), new Gson().toJson(Iterables.get(result, 2)),
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"status\":\"AVAILABLE\",\"backendStatus\":\"available\",\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"authenticateSudo\":false,\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-710c2605\",\"name\":\"RightImage Windows_2003_i386_v5.4.3\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\",\"virtualizationType\":\"hvm\",\"hypervisor\":\"xen\"}}"); "{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"status\":\"AVAILABLE\",\"backendStatus\":\"available\",\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"authenticateSudo\":false,\"password\":{},\"privateKey\":{},\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-710c2605\",\"name\":\"RightImage Windows_2003_i386_v5.4.3\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\",\"virtualizationType\":\"hvm\",\"hypervisor\":\"xen\"}}");
} }
public void testParseAmznImage() { public void testParseAmznImage() {

View File

@ -463,7 +463,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// we specify we have a public key we want to use for authentication // we specify we have a public key we want to use for authentication
expect(options.getPublicKey()).andReturn("ssh-rsa").times(2); expect(options.getPublicKey()).andReturn("ssh-rsa").times(2);
expect(options.getLoginPrivateKey()).andReturn(CREDENTIALS.getPrivateKey()).atLeastOnce(); expect(options.getLoginPrivateKey()).andReturn(CREDENTIALS.getOptionalPrivateKey().get()).atLeastOnce();
// Here, we import the keypair and place it into the cache // Here, we import the keypair and place it into the cache
expect(strategy.importExistingKeyPair.apply(new RegionNameAndPublicKeyMaterial(region, group, "ssh-rsa"))) expect(strategy.importExistingKeyPair.apply(new RegionNameAndPublicKeyMaterial(region, group, "ssh-rsa")))