mirror of https://github.com/apache/jclouds.git
JCLOUDS-1355: Enable VM creation without external IP address.
This commit is contained in:
parent
73c3b6024c
commit
5d82a3df97
|
@ -19,7 +19,6 @@ package org.jclouds.googlecomputeengine.compute;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static java.lang.String.format;
|
||||
import static org.jclouds.googlecloud.internal.ListPages.concat;
|
||||
import static org.jclouds.googlecomputeengine.compute.domain.internal.RegionAndName.fromRegionAndName;
|
||||
|
@ -52,10 +51,12 @@ import org.jclouds.googlecomputeengine.domain.AttachDisk;
|
|||
import org.jclouds.googlecomputeengine.domain.DiskType;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling.OnHostMaintenance;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.domain.NewInstance;
|
||||
import org.jclouds.googlecomputeengine.domain.NewInstance.NetworkInterface;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Region;
|
||||
import org.jclouds.googlecomputeengine.domain.Subnetwork;
|
||||
|
@ -148,16 +149,24 @@ public final class GoogleComputeEngineServiceAdapter
|
|||
|
||||
Scheduling scheduling = getScheduling(options);
|
||||
|
||||
NewInstance newInstance = new NewInstance.Builder(name,
|
||||
List<NetworkInterface> networks = Lists.newArrayList();
|
||||
if (options.assignExternalIp()) {
|
||||
networks.add(NetworkInterface.create(network, subnetwork));
|
||||
} else {
|
||||
// Do not assign an externally facing IP address to the machine.
|
||||
networks.add(NetworkInterface.create(network, subnetwork, ImmutableList.<AccessConfig>of()));
|
||||
}
|
||||
|
||||
NewInstance.Builder newInstanceBuilder = new NewInstance.Builder(name,
|
||||
template.getHardware().getUri(), // machineType
|
||||
network,
|
||||
subnetwork,
|
||||
networks,
|
||||
disks)
|
||||
.description(group)
|
||||
.tags(Tags.create(null, ImmutableList.copyOf(options.getTags())))
|
||||
.serviceAccounts(options.serviceAccounts())
|
||||
.scheduling(scheduling)
|
||||
.build();
|
||||
.scheduling(scheduling);
|
||||
|
||||
NewInstance newInstance = newInstanceBuilder.build();
|
||||
|
||||
// Add metadata from template and for ssh key and image id
|
||||
newInstance.metadata().putAll(options.getUserMetadata());
|
||||
|
@ -216,7 +225,7 @@ public final class GoogleComputeEngineServiceAdapter
|
|||
}
|
||||
|
||||
@Override public Iterable<Image> listImages() {
|
||||
List<Iterable<Image>> images = newArrayList();
|
||||
List<Iterable<Image>> images = Lists.newArrayList();
|
||||
|
||||
images.add(concat(api.images().list()));
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.jclouds.scriptbuilder.domain.Statement;
|
|||
/** Instance options specific to Google Compute Engine. */
|
||||
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||
|
||||
private boolean assignExternalIp = true;
|
||||
private boolean autoCreateKeyPair = true;
|
||||
private boolean autoCreateWindowsPassword;
|
||||
private List<ServiceAccount> serviceAccounts;
|
||||
|
@ -46,6 +47,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
super.copyTo(to);
|
||||
if (to instanceof GoogleComputeEngineTemplateOptions) {
|
||||
GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
|
||||
eTo.assignExternalIp(assignExternalIp());
|
||||
eTo.autoCreateKeyPair(autoCreateKeyPair());
|
||||
eTo.serviceAccounts(serviceAccounts());
|
||||
eTo.autoCreateWindowsPassword(autoCreateWindowsPassword());
|
||||
|
@ -69,6 +71,21 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
return bootDiskType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether an external IP address should be assigned to the machine.
|
||||
*/
|
||||
public GoogleComputeEngineTemplateOptions assignExternalIp(boolean assignExternalIp) {
|
||||
this.assignExternalIp = assignExternalIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether an external IP address should be assigned to the machine.
|
||||
*/
|
||||
public boolean assignExternalIp() {
|
||||
return assignExternalIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether an SSH key pair should be created automatically.
|
||||
*/
|
||||
|
@ -115,7 +132,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
* the password if and only if the image is for a Windows VM.
|
||||
*/
|
||||
public Boolean autoCreateWindowsPassword() {
|
||||
return autoCreateWindowsPassword;
|
||||
return autoCreateWindowsPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,19 +37,19 @@ import com.google.common.collect.ImmutableList;
|
|||
@AutoValue
|
||||
public abstract class NewInstance {
|
||||
@AutoValue
|
||||
abstract static class NetworkInterface {
|
||||
public abstract static class NetworkInterface {
|
||||
abstract URI network();
|
||||
@Nullable abstract URI subnetwork();
|
||||
|
||||
abstract List<AccessConfig> accessConfigs();
|
||||
|
||||
static NetworkInterface create(URI network, URI subnetwork) {
|
||||
public static NetworkInterface create(URI network, URI subnetwork) {
|
||||
return create(network, subnetwork,
|
||||
Arrays.asList(AccessConfig.create(null, Type.ONE_TO_ONE_NAT, null)));
|
||||
}
|
||||
|
||||
@SerializedNames({ "network", "subnetwork", "accessConfigs" })
|
||||
static NetworkInterface create(URI network, URI subnetwork, List<AccessConfig> accessConfigs) {
|
||||
public static NetworkInterface create(URI network, URI subnetwork, List<AccessConfig> accessConfigs) {
|
||||
return new AutoValue_NewInstance_NetworkInterface(network, subnetwork, accessConfigs);
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,14 @@ public abstract class NewInstance {
|
|||
this.disks = disks;
|
||||
}
|
||||
|
||||
public Builder(String name, URI machineType, List<NetworkInterface> networks, List<AttachDisk> disks) {
|
||||
checkNotNull(name, "NewInstance name cannot be null");
|
||||
this.name = name;
|
||||
this.machineType = machineType;
|
||||
this.networkInterfaces = ImmutableList.copyOf(networks);
|
||||
this.disks = disks;
|
||||
}
|
||||
|
||||
public Builder(String name, URI machineType, URI network, URI subnetwork, URI sourceImage) {
|
||||
checkNotNull(name, "NewInstance name cannot be null");
|
||||
this.name = name;
|
||||
|
|
|
@ -319,6 +319,58 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
|||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-1");
|
||||
}
|
||||
|
||||
public void createNodeWithoutExternalIp() throws Exception {
|
||||
server.enqueue(singleRegionSingleZoneResponse());
|
||||
server.enqueue(jsonResponse("/image_list.json"));
|
||||
server.enqueue(jsonResponse("/image_list_debian.json")); // per IMAGE_PROJECTS = "debian-cloud"
|
||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
||||
server.enqueue(jsonResponse("/subnetwork_get.json"));
|
||||
server.enqueue(jsonResponse("/network_get.json"));
|
||||
server.enqueue(new MockResponse().setResponseCode(404)); // Get Firewall
|
||||
server.enqueue(jsonResponse("/operation.json")); // Create Firewall
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
|
||||
server.enqueue(jsonResponse("/disk_get_with_source_image.json"));
|
||||
server.enqueue(jsonResponse("/image_get_for_source_image.json"));
|
||||
server.enqueue(jsonResponse("/disktype_ssd.json"));
|
||||
server.enqueue(jsonResponse("/operation.json")); // Create Instance
|
||||
server.enqueue(instanceWithNetworkAndStatusAndSsd("test-1", "test-network", RUNNING));
|
||||
|
||||
ComputeService computeService = computeService();
|
||||
|
||||
GoogleComputeEngineTemplateOptions options = computeService.templateOptions()
|
||||
.as(GoogleComputeEngineTemplateOptions.class).autoCreateKeyPair(false)
|
||||
.tags(ImmutableSet.of("aTag")).blockUntilRunning(false)
|
||||
.bootDiskType("pd-ssd").networks("jclouds-test").assignExternalIp(false);
|
||||
|
||||
Template template = computeService.templateBuilder().options(options).build();
|
||||
NodeMetadata node = getOnlyElement(computeService.createNodesInGroup("test", 1, template));
|
||||
|
||||
// prove our caching works.
|
||||
assertEquals(node.getImageId(), template.getImage().getId());
|
||||
assertEquals(node.getLocation().getId(), template.getLocation().getId());
|
||||
|
||||
assertSent(server, "GET", "/projects/party/regions");
|
||||
assertSent(server, "GET", "/projects/party/global/images");
|
||||
assertSent(server, "GET", "/projects/debian-cloud/global/images");
|
||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||
assertSent(server, "GET", "/projects/party/regions/us-central1/subnetworks/jclouds-test");
|
||||
assertSent(server, "GET", "/projects/party/global/networks/mynetwork");
|
||||
assertSent(server, "GET", "/projects/party/global/firewalls/jclouds-test-65f"); // Get Firewall
|
||||
assertSent(server, "POST", "/projects/party/global/firewalls", // Create Firewall
|
||||
stringFromResource("/firewall_insert_3.json"));
|
||||
|
||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
||||
assertSent(server, "GET", "/projects/party/aggregated/instances");
|
||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/disks/test");
|
||||
assertSent(server, "GET", "/projects/debian-cloud/global/images/debian-7-wheezy-v20140718");
|
||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/diskTypes/pd-ssd");
|
||||
assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances",
|
||||
String.format(stringFromResource("/instance_insert_no_ip.json"), template.getHardware().getId(), template.getImage().getId()));
|
||||
|
||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-1");
|
||||
}
|
||||
|
||||
private MockResponse instanceWithNetworkAndStatus(String instanceName, String networkName, Instance.Status status) {
|
||||
return new MockResponse().setBody(
|
||||
stringFromResource("/instance_get.json").replace("test-0", instanceName).replace("default", networkName)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"machineType": "%s",
|
||||
"name": "test-1",
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/mynetwork",
|
||||
"subnetwork": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion/subnetworks/jclouds-test",
|
||||
"accessConfigs": []
|
||||
}
|
||||
],
|
||||
"disks": [
|
||||
{
|
||||
"type": "PERSISTENT",
|
||||
"initializeParams": {
|
||||
"sourceImage": "%s",
|
||||
"diskType": "https://content.googleapis.com/compute/v1/projects/party/zones/us-central1-a/diskTypes/pd-ssd"
|
||||
},
|
||||
"boot": true,
|
||||
"autoDelete": true
|
||||
}
|
||||
],
|
||||
"description": "test",
|
||||
"tags": {
|
||||
"items": [
|
||||
"aTag",
|
||||
"jclouds-test-65f"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"items": [
|
||||
{
|
||||
"key": "jclouds-group",
|
||||
"value": "test"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scheduling": {
|
||||
"onHostMaintenance": "MIGRATE",
|
||||
"automaticRestart": true,
|
||||
"preemptible": false
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue