mirror of https://github.com/apache/jclouds.git
fix issue #1277 some nova installs do not generate passwords
This commit is contained in:
parent
9961f09c2e
commit
737e2d3a20
|
@ -131,8 +131,8 @@ public class NovaComputeServiceAdapter implements
|
||||||
logger.trace("<< server(%s)", server.getId());
|
logger.trace("<< server(%s)", server.getId());
|
||||||
|
|
||||||
ServerInZone serverInZone = new ServerInZone(server, zoneId);
|
ServerInZone serverInZone = new ServerInZone(server, zoneId);
|
||||||
if (!privateKey.isPresent())
|
if (!privateKey.isPresent() && lightweightServer.getAdminPass().isPresent())
|
||||||
credentialsBuilder.password(lightweightServer.getAdminPass());
|
credentialsBuilder.password(lightweightServer.getAdminPass().get());
|
||||||
return new NodeAndInitialCredentials<ServerInZone>(serverInZone, serverInZone.slashEncode(), credentialsBuilder
|
return new NodeAndInitialCredentials<ServerInZone>(serverInZone, serverInZone.slashEncode(), credentialsBuilder
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v2_0.domain;
|
package org.jclouds.openstack.nova.v2_0.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.beans.ConstructorProperties;
|
import java.beans.ConstructorProperties;
|
||||||
import java.util.Set;
|
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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Resource with administrative password returned by ServerApi#CreateServer calls
|
* 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 class ServerCreated extends Resource {
|
||||||
|
|
||||||
public static Builder<?> builder() {
|
public static Builder builder() {
|
||||||
return new ConcreteBuilder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<?> toBuilder() {
|
public Builder toBuilder() {
|
||||||
return new ConcreteBuilder().fromServerCreated(this);
|
return builder().fromServerCreated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class Builder<T extends Builder<T>> extends Resource.Builder<T> {
|
public final static class Builder extends Resource.Builder<Builder> {
|
||||||
protected String adminPass;
|
protected String adminPass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ServerCreated#getAdminPass()
|
* @see ServerCreated#getAdminPass()
|
||||||
*/
|
*/
|
||||||
public T adminPass(String adminPass) {
|
public Builder adminPass(String adminPass) {
|
||||||
this.adminPass = adminPass;
|
this.adminPass = adminPass;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
@ -63,33 +62,30 @@ public class ServerCreated extends Resource {
|
||||||
return new ServerCreated(id, name, links, adminPass);
|
return new ServerCreated(id, name, links, adminPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T fromServerCreated(ServerCreated in) {
|
public Builder fromServerCreated(ServerCreated in) {
|
||||||
return super.fromResource(in)
|
return super.fromResource(in).adminPass(in.getAdminPass().orNull());
|
||||||
.adminPass(in.getAdminPass());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
|
||||||
@Override
|
@Override
|
||||||
protected ConcreteBuilder self() {
|
protected Builder self() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String adminPass;
|
private final Optional<String> adminPass;
|
||||||
|
|
||||||
@ConstructorProperties({
|
@ConstructorProperties({
|
||||||
"id", "name", "links", "adminPass"
|
"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);
|
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;
|
return this.adminPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,10 +101,9 @@ public class ServerCreated extends Resource {
|
||||||
ServerCreated that = ServerCreated.class.cast(obj);
|
ServerCreated that = ServerCreated.class.cast(obj);
|
||||||
return super.equals(that) && Objects.equal(this.adminPass, that.adminPass);
|
return super.equals(that) && Objects.equal(this.adminPass, that.adminPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return super.string()
|
return super.string().add("adminPass", adminPass.orNull());
|
||||||
.add("adminPass", adminPass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.v2_0.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.assertNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -51,6 +52,15 @@ import com.google.inject.TypeLiteral;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "NovaComputeServiceAdapterExpectTest")
|
@Test(groups = "unit", testName = "NovaComputeServiceAdapterExpectTest")
|
||||||
public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceContextExpectTest<Injector> {
|
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 {
|
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")
|
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||||
.payload(payloadFromResourceWithContentType("/new_server.json","application/json; charset=UTF-8")).build();
|
.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()
|
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||||
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
|
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
|
||||||
|
@ -117,17 +117,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||||
|
|
||||||
|
|
||||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||||
.payload(payloadFromResourceWithContentType("/new_server.json","application/json; charset=UTF-8")).build();
|
.payload(payloadFromResourceWithContentType("/new_server_no_adminpass.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()
|
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||||
|
@ -156,6 +146,47 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||||
assertNotNull(server);
|
assertNotNull(server);
|
||||||
assertEquals(server.getCredentials(), LoginCredentials.builder().privateKey("privateKey").build());
|
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
|
@Override
|
||||||
public Injector apply(ComputeServiceContext input) {
|
public Injector apply(ComputeServiceContext input) {
|
||||||
|
|
|
@ -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": {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue