fix issue #1277 some nova installs do not generate passwords

This commit is contained in:
adriancole 2013-01-31 13:56:39 -08:00
parent bdc2fb3a1e
commit e85b7b7cc8
4 changed files with 112 additions and 46 deletions

View File

@ -130,8 +130,8 @@ public class NovaComputeServiceAdapter implements
logger.trace("<< server(%s)", server.getId());
ServerInZone serverInZone = new ServerInZone(server, zoneId);
if (!privateKey.isPresent())
credentialsBuilder.password(lightweightServer.getAdminPass());
if (!privateKey.isPresent() && lightweightServer.getAdminPass().isPresent())
credentialsBuilder.password(lightweightServer.getAdminPass().get());
return new NodeAndInitialCredentials<ServerInZone>(serverInZone, serverInZone.slashEncode(), credentialsBuilder
.build());
}

View File

@ -18,8 +18,6 @@
*/
package org.jclouds.openstack.nova.v2_0.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Set;
@ -29,6 +27,7 @@ import org.jclouds.openstack.v2_0.domain.Resource;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* Server Resource with administrative password returned by ServerApi#CreateServer calls
@ -40,21 +39,21 @@ import com.google.common.base.Objects.ToStringHelper;
*/
public class ServerCreated extends Resource {
public static Builder<?> builder() {
return new ConcreteBuilder();
public static Builder builder() {
return new Builder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromServerCreated(this);
public Builder toBuilder() {
return builder().fromServerCreated(this);
}
public abstract static class Builder<T extends Builder<T>> extends Resource.Builder<T> {
public final static class Builder extends Resource.Builder<Builder> {
protected String adminPass;
/**
* @see ServerCreated#getAdminPass()
*/
public T adminPass(String adminPass) {
public Builder adminPass(String adminPass) {
this.adminPass = adminPass;
return self();
}
@ -63,33 +62,30 @@ public class ServerCreated extends Resource {
return new ServerCreated(id, name, links, adminPass);
}
public T fromServerCreated(ServerCreated in) {
return super.fromResource(in)
.adminPass(in.getAdminPass());
}
public Builder fromServerCreated(ServerCreated in) {
return super.fromResource(in).adminPass(in.getAdminPass().orNull());
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
protected Builder self() {
return this;
}
}
private final String adminPass;
private final Optional<String> adminPass;
@ConstructorProperties({
"id", "name", "links", "adminPass"
})
protected ServerCreated(String id, @Nullable String name, Set<Link> links, String adminPass) {
protected ServerCreated(String id, @Nullable String name, Set<Link> links, @Nullable String adminPass) {
super(id, name, links);
this.adminPass = checkNotNull(adminPass, "adminPass");
this.adminPass = Optional.fromNullable(adminPass);
}
/**
* @return the administrative password for this server. Note: this is not available in Server responses.
* present unless the nova install was configured with the option {@code enable_instance_password=false}
*/
public String getAdminPass() {
public Optional<String> getAdminPass() {
return this.adminPass;
}
@ -106,9 +102,8 @@ public class ServerCreated extends Resource {
return super.equals(that) && Objects.equal(this.adminPass, that.adminPass);
}
@Override
protected ToStringHelper string() {
return super.string()
.add("adminPass", adminPass);
return super.string().add("adminPass", adminPass.orNull());
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.v2_0.compute;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import java.util.Map;
import java.util.Properties;
@ -51,6 +52,15 @@ import com.google.inject.TypeLiteral;
*/
@Test(groups = "unit", testName = "NovaComputeServiceAdapterExpectTest")
public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceContextExpectTest<Injector> {
HttpRequest serverDetail = HttpRequest
.builder()
.method("GET")
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/71752")
.addHeader("Accept", "application/json")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse serverDetailResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/server_details.json")).build();
public void testCreateNodeWithGroupEncodedIntoNameWhenSecurityGroupsArePresent() throws Exception {
@ -67,16 +77,6 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
.payload(payloadFromResourceWithContentType("/new_server.json","application/json; charset=UTF-8")).build();
HttpRequest serverDetail = HttpRequest
.builder()
.method("GET")
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/71752")
.addHeader("Accept", "application/json")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse serverDetailResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/server_details.json")).build();
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
@ -117,17 +117,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
.payload(payloadFromResourceWithContentType("/new_server.json","application/json; charset=UTF-8")).build();
HttpRequest serverDetail = HttpRequest
.builder()
.method("GET")
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/71752")
.addHeader("Accept", "application/json")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse serverDetailResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/server_details.json")).build();
.payload(payloadFromResourceWithContentType("/new_server_no_adminpass.json","application/json; charset=UTF-8")).build();
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
@ -157,6 +147,47 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
assertEquals(server.getCredentials(), LoginCredentials.builder().privateKey("privateKey").build());
}
/**
* When enable_instance_password is false, then no admin pass is generated.
* However in this case if you don't specify the name of the SSH keypair to
* inject, then you simply cannot log in to the server.
*/
public void testNoKeyPairOrAdminPass() throws Exception {
HttpRequest createServer = HttpRequest
.builder()
.method("POST")
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers")
.addHeader("Accept", "application/json")
.addHeader("X-Auth-Token", authToken)
.payload(payloadFromStringWithContentType(
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\"}}","application/json"))
.build();
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
.payload(payloadFromResourceWithContentType("/new_server_no_adminpass.json","application/json; charset=UTF-8")).build();
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
.put(listDetail, listDetailResponse)
.put(listFlavorsDetail, listFlavorsDetailResponse)
.put(createServer, createServerResponse)
.put(serverDetail, serverDetailResponse).build();
Injector forSecurityGroups = requestsSendResponses(requestResponseMap);
Template template = forSecurityGroups.getInstance(TemplateBuilder.class).build();
NovaComputeServiceAdapter adapter = forSecurityGroups.getInstance(NovaComputeServiceAdapter.class);
NodeAndInitialCredentials<ServerInZone> server = adapter.createNodeWithGroupEncodedIntoName("test", "test-e92",
template);
assertNotNull(server);
assertNull(server.getCredentials());
}
@Override
public Injector apply(ComputeServiceContext input) {
return input.utils().injector();

View File

@ -0,0 +1,40 @@
{
"server": {
"status": "BUILD(scheduling)",
"updated": "2012-03-19T06:21:13Z",
"hostId": "",
"user_id": "54297837463082",
"name": "test-e92",
"links": [{
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers/71752",
"rel": "self"
}, {
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/servers/71752",
"rel": "bookmark"
}],
"addresses": {},
"tenant_id": "37936628937291",
"image": {
"id": "1241",
"links": [{
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1241",
"rel": "bookmark"
}]
},
"created": "2012-03-19T06:21:13Z",
"uuid": "47491020-6a78-4f63-9475-23195ac4515c",
"accessIPv4": "",
"accessIPv6": "",
"key_name": null,
"flavor": {
"id": "100",
"links": [{
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/flavors/100",
"rel": "bookmark"
}]
},
"config_drive": "",
"id": 71752,
"metadata": {}
}
}