mirror of https://github.com/apache/jclouds.git
JCLOUDS-906: Add ServiceAccounts to GoogleComputeEngineTemplateOptions
This commit is contained in:
parent
aa33619c92
commit
55348c0ddb
|
@ -138,15 +138,14 @@ public final class GoogleComputeEngineServiceAdapter
|
|||
tags.add(naming.name(ports));
|
||||
}
|
||||
|
||||
NewInstance newInstance = NewInstance.create(
|
||||
name, // name
|
||||
NewInstance newInstance = new NewInstance.Builder( name,
|
||||
template.getHardware().getUri(), // machineType
|
||||
network, // network
|
||||
disks, // disks
|
||||
group, // description
|
||||
Tags.create(null, ImmutableList.copyOf(tags)) // tags
|
||||
);
|
||||
|
||||
network,
|
||||
disks)
|
||||
.description(group)
|
||||
.tags(Tags.create(null, ImmutableList.copyOf(tags)))
|
||||
.serviceAccounts(options.serviceAccounts())
|
||||
.build();
|
||||
|
||||
// Add metadata from template and for ssh key and image id
|
||||
newInstance.metadata().putAll(options.getUserMetadata());
|
||||
|
@ -177,7 +176,7 @@ public final class GoogleComputeEngineServiceAdapter
|
|||
null, // networkInterfaces
|
||||
null, // disks
|
||||
newInstance.metadata(), // metadata
|
||||
null, // serviceAccounts
|
||||
newInstance.serviceAccounts(), // serviceAccounts
|
||||
Scheduling.create(OnHostMaintenance.MIGRATE, true) // scheduling
|
||||
));
|
||||
checkState(instanceVisible.apply(instance), "instance %s is not api visible!", instance.get());
|
||||
|
|
|
@ -16,16 +16,19 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine.compute.options;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
|
||||
|
||||
/** Instance options specific to Google Compute Engine. */
|
||||
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||
|
||||
private boolean autoCreateKeyPair = true;
|
||||
private List<ServiceAccount> serviceAccounts;
|
||||
|
||||
@Override
|
||||
public GoogleComputeEngineTemplateOptions clone() {
|
||||
|
@ -40,6 +43,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
if (to instanceof GoogleComputeEngineTemplateOptions) {
|
||||
GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
|
||||
eTo.autoCreateKeyPair(autoCreateKeyPair());
|
||||
eTo.serviceAccounts(serviceAccounts());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,12 +56,30 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets whether an SSH key pair should be created automatically.
|
||||
* Gets whether an SSH key pair should be created automatically.
|
||||
*/
|
||||
public boolean autoCreateKeyPair() {
|
||||
return autoCreateKeyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of service accounts, with their specified scopes, to authorize on created instance.
|
||||
* For example, to give a node the 'compute' scope you would add a service account with the email 'default'
|
||||
* and the scope 'https://www.googleapis.com/auth/compute'
|
||||
* These scopes will be given to all nodes created with these template options.
|
||||
*/
|
||||
public GoogleComputeEngineTemplateOptions serviceAccounts(List<ServiceAccount> serviceAccounts){
|
||||
this.serviceAccounts = serviceAccounts;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of service accounts, with their specified scopes, that will be authorize on created instances.
|
||||
*/
|
||||
public List<ServiceAccount> serviceAccounts(){
|
||||
return serviceAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.jclouds.googlecomputeengine.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
@ -80,7 +81,8 @@ public abstract class NewInstance {
|
|||
return create(name, machineType, network, Arrays.asList(AttachDisk.newBootDisk(sourceImage)), null, null);
|
||||
}
|
||||
|
||||
public static NewInstance create(String name, URI machineType, URI network, List<AttachDisk> disks, @Nullable String description, @Nullable Tags tags) {
|
||||
public static NewInstance create(String name, URI machineType, URI network, List<AttachDisk> disks,
|
||||
@Nullable String description, @Nullable Tags tags) {
|
||||
checkArgument(disks.get(0).boot(), "disk 0 must be a boot disk! %s", disks);
|
||||
boolean foundBoot = false;
|
||||
for (AttachDisk disk : disks) {
|
||||
|
@ -93,13 +95,86 @@ public abstract class NewInstance {
|
|||
description, tags != null ? tags : Tags.create(), Metadata.create(), null, null);
|
||||
}
|
||||
|
||||
@SerializedNames({ "name", "machineType", "canIpForward", "networkInterfaces", "disks", "description", "tags", "metadata",
|
||||
"serviceAccounts", "scheduling" })
|
||||
static NewInstance create(String name, URI machineType, Boolean canIpForward, List<NetworkInterface> networkInterfaces,
|
||||
List<AttachDisk> disks, String description, Tags tags, Metadata metadata, List<ServiceAccount> serviceAccounts, Scheduling scheduling) {
|
||||
return new AutoValue_NewInstance(name, machineType, canIpForward, networkInterfaces, disks, description, tags, metadata, serviceAccounts, scheduling);
|
||||
@SerializedNames({ "name", "machineType", "canIpForward", "networkInterfaces", "disks", "description",
|
||||
"tags", "metadata", "serviceAccounts", "scheduling" })
|
||||
static NewInstance create(String name, URI machineType, Boolean canIpForward,
|
||||
List<NetworkInterface> networkInterfaces, List<AttachDisk> disks, String description,
|
||||
Tags tags, Metadata metadata, List<ServiceAccount> serviceAccounts, Scheduling scheduling) {
|
||||
return new AutoValue_NewInstance(name, machineType, canIpForward, networkInterfaces, disks, description,
|
||||
tags, metadata, serviceAccounts, scheduling);
|
||||
}
|
||||
|
||||
NewInstance() {
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String name;
|
||||
private URI machineType;
|
||||
private Boolean canIpForward;
|
||||
private List<NetworkInterface> networkInterfaces;
|
||||
private List<AttachDisk> disks;
|
||||
private String description;
|
||||
private Tags tags;
|
||||
private Metadata metadata;
|
||||
private List<ServiceAccount> serviceAccounts;
|
||||
private Scheduling scheduling;
|
||||
|
||||
public Builder(String name, URI machineType, URI network, List<AttachDisk> disks) {
|
||||
checkNotNull(name, "NewInstance name cannot be null");
|
||||
this.name = name;
|
||||
this.machineType = machineType;
|
||||
this.networkInterfaces = ImmutableList.of(NetworkInterface.create(network));
|
||||
this.disks = disks;
|
||||
}
|
||||
|
||||
public Builder(String name, URI machineType, URI network, URI sourceImage) {
|
||||
checkNotNull(name, "NewInstance name cannot be null");
|
||||
this.name = name;
|
||||
this.machineType = machineType;
|
||||
this.networkInterfaces = ImmutableList.of(NetworkInterface.create(network));
|
||||
this.disks = Arrays.asList(AttachDisk.newBootDisk(sourceImage));
|
||||
}
|
||||
|
||||
public Builder canIpForward(Boolean canIpForward){
|
||||
this.canIpForward = canIpForward;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description){
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tags(Tags tags){
|
||||
this.tags = tags;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder metadata(Metadata metadata){
|
||||
this.metadata = metadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of service accounts, with their specified scopes, authorized for this instance.
|
||||
* Service accounts generate access tokens that can be accessed through the metadata server
|
||||
* and used to authenticate applications on the instance.
|
||||
* Note: to add scopes to the default service account on the VM you can use 'default' as
|
||||
* a keyword for email.
|
||||
*/
|
||||
public Builder serviceAccounts(List<ServiceAccount> serviceAccounts){
|
||||
this.serviceAccounts = serviceAccounts;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder scheduling(Scheduling scheduling){
|
||||
this.scheduling = scheduling;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NewInstance build() {
|
||||
return create(name, machineType, canIpForward, networkInterfaces, disks, description, tags != null ? tags : Tags.create(),
|
||||
metadata != null ? metadata : Metadata.create(), serviceAccounts, scheduling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,6 @@ public abstract class Tags implements Cloneable {
|
|||
return Tags.create(null, null);
|
||||
}
|
||||
|
||||
public static Tags create(String fingerprint) {
|
||||
return Tags.create(fingerprint, null);
|
||||
}
|
||||
|
||||
@SerializedNames({ "fingerprint", "items" })
|
||||
public static Tags create(String fingerprint, ImmutableList<String> items) { // Dictates the type when created from json!
|
||||
ImmutableList<String> empty = ImmutableList.of();
|
||||
|
|
|
@ -34,7 +34,9 @@ import org.jclouds.googlecomputeengine.domain.Instance;
|
|||
import org.jclouds.googlecomputeengine.domain.Instance.AttachedDisk;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling.OnHostMaintenance;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.SerialPortOutput;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig;
|
||||
import org.jclouds.googlecomputeengine.domain.Metadata;
|
||||
import org.jclouds.googlecomputeengine.domain.NewInstance;
|
||||
|
@ -99,11 +101,16 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
|||
);
|
||||
instance.metadata().put("mykey", "myvalue");
|
||||
|
||||
instance2 = NewInstance.create(
|
||||
INSTANCE_NAME2, // name
|
||||
instance2 = new NewInstance.Builder(INSTANCE_NAME2, // name
|
||||
getDefaultMachineTypeUrl(), // machineType
|
||||
getNetworkUrl(INSTANCE_NETWORK_NAME), // network
|
||||
imageUri); // sourceImage
|
||||
imageUri) // sourceImage
|
||||
.canIpForward(true)
|
||||
.description("description")
|
||||
.tags(Tags.create(null, ImmutableList.of("tag1")))
|
||||
.serviceAccounts(ImmutableList.of(ServiceAccount.create("default", ImmutableList.of("https://www.googleapis.com/auth/compute"))))
|
||||
.scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true))
|
||||
.build();
|
||||
|
||||
return api;
|
||||
}
|
||||
|
@ -116,6 +123,18 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
|||
return api.disksInZone(DEFAULT_ZONE_NAME);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testGetInstance2() {
|
||||
Instance instance = api().get(INSTANCE_NAME2);
|
||||
assertNotNull(instance);
|
||||
assertInstanceEquals(instance, this.instance2);
|
||||
assertTrue(instance.canIpForward());
|
||||
assertEquals(instance.description(), "description");
|
||||
assertEquals(instance.serviceAccounts().get(0).scopes(), ImmutableList.of("https://www.googleapis.com/auth/compute"));
|
||||
assertTrue(instance.scheduling().automaticRestart());
|
||||
assertEquals(instance.scheduling().onHostMaintenance(), OnHostMaintenance.MIGRATE);
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertInstance() {
|
||||
// need to insert the network first
|
||||
|
@ -294,7 +313,7 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
|||
assertOperationDoneSuccessfully(api().reset(INSTANCE_NAME));
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
@Test(groups = "live", dependsOnMethods = "testGetInstance2")
|
||||
public void testStopInstance() {
|
||||
Instance originalInstance = api().get(INSTANCE_NAME2);
|
||||
assertEquals(originalInstance.status(), Instance.Status.RUNNING);
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.jclouds.googlecomputeengine.domain.AttachDisk;
|
|||
import org.jclouds.googlecomputeengine.domain.AttachDisk.DiskInterface;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
|
||||
import org.jclouds.googlecomputeengine.domain.Metadata;
|
||||
import org.jclouds.googlecomputeengine.domain.NewInstance;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance.Scheduling.OnHostMaintenance;
|
||||
|
@ -250,6 +252,41 @@ public class InstanceApiMockTest extends BaseGoogleComputeEngineApiMockTest {
|
|||
assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances/test-1/stop");
|
||||
}
|
||||
|
||||
public void builderTest() throws Exception {
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
|
||||
NewInstance newInstance = new NewInstance.Builder("test-1", // name
|
||||
URI.create(url("/projects/party/zones/us-central1-a/machineTypes/n1-standard-1")), // machineType
|
||||
URI.create(url("/projects/party/global/networks/default")), // network
|
||||
URI.create(url("/projects/party/global/images/centos-6-2-v20120326"))).build(); // sourceImage)
|
||||
|
||||
assertEquals(instanceApi().create(newInstance), new ParseZoneOperationTest().expected(url("/projects")));
|
||||
assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances",
|
||||
stringFromResource("/instance_insert_simple.json"));
|
||||
}
|
||||
|
||||
public void insert_builder_allOptions() throws Exception {
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
|
||||
NewInstance newInstance = new NewInstance.Builder(
|
||||
"test-1", // name
|
||||
URI.create(url("/projects/party/zones/us-central1-a/machineTypes/n1-standard-1")), // machineType
|
||||
URI.create(url("/projects/party/global/networks/default")), // network
|
||||
Arrays.asList(AttachDisk.existingBootDisk(URI.create(url("/projects/party/zones/us-central1-a/disks/test")))))
|
||||
.canIpForward(true)
|
||||
.description("desc")
|
||||
.tags(null)
|
||||
.metadata(Metadata.create().put("aKey", "aValue"))
|
||||
.serviceAccounts(ImmutableList.of(ServiceAccount.create("default",
|
||||
ImmutableList.of("https://www.googleapis.com/auth/compute"))))
|
||||
.scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true))
|
||||
.build();
|
||||
|
||||
assertEquals(instanceApi().create(newInstance), new ParseZoneOperationTest().expected(url("/projects")));
|
||||
assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances",
|
||||
stringFromResource("/instance_insert_full.json"));
|
||||
}
|
||||
|
||||
InstanceApi instanceApi(){
|
||||
return api().instancesInZone("us-central1-a");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "test-1",
|
||||
"machineType": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/machineTypes/n1-standard-1",
|
||||
"canIpForward": true,
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/default",
|
||||
"accessConfigs": [
|
||||
{
|
||||
"type": "ONE_TO_ONE_NAT"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"disks": [
|
||||
{
|
||||
"type": "PERSISTENT",
|
||||
"source": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/disks/test",
|
||||
"boot": true,
|
||||
"autoDelete": false
|
||||
}
|
||||
],
|
||||
"description": "desc",
|
||||
"tags": {
|
||||
"items": []
|
||||
},
|
||||
"metadata": {
|
||||
"items": [
|
||||
{
|
||||
"key": "aKey",
|
||||
"value": "aValue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"serviceAccounts": [
|
||||
{
|
||||
"email": "default",
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/compute"
|
||||
]
|
||||
}
|
||||
],
|
||||
"scheduling": {
|
||||
"onHostMaintenance": "MIGRATE",
|
||||
"automaticRestart": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue