mirror of https://github.com/apache/jclouds.git
Merge pull request #1150 from dralves/gce-instances
gce - instances api
This commit is contained in:
commit
d074fe19f2
|
@ -22,6 +22,7 @@ import com.google.common.annotations.Beta;
|
|||
import org.jclouds.googlecompute.features.DiskApi;
|
||||
import org.jclouds.googlecompute.features.FirewallApi;
|
||||
import org.jclouds.googlecompute.features.ImageApi;
|
||||
import org.jclouds.googlecompute.features.InstanceApi;
|
||||
import org.jclouds.googlecompute.features.KernelApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeApi;
|
||||
import org.jclouds.googlecompute.features.NetworkApi;
|
||||
|
@ -33,6 +34,7 @@ import org.jclouds.rest.annotations.Delegate;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
|
||||
/**
|
||||
* Provides synchronous access to GoogleCompute.
|
||||
* <p/>
|
||||
|
@ -71,6 +73,15 @@ public interface GoogleComputeApi {
|
|||
@Path("/projects/{project}")
|
||||
ImageApi getImageApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Instance features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
InstanceApi getInstanceApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Kernel features
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.google.common.annotations.Beta;
|
|||
import org.jclouds.googlecompute.features.DiskAsyncApi;
|
||||
import org.jclouds.googlecompute.features.FirewallAsyncApi;
|
||||
import org.jclouds.googlecompute.features.ImageAsyncApi;
|
||||
import org.jclouds.googlecompute.features.InstanceAsyncApi;
|
||||
import org.jclouds.googlecompute.features.KernelAsyncApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeAsyncApi;
|
||||
import org.jclouds.googlecompute.features.NetworkAsyncApi;
|
||||
|
@ -71,6 +72,15 @@ public interface GoogleComputeAsyncApi {
|
|||
@Path("/projects/{project}")
|
||||
ImageAsyncApi getImageApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Instance features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
InstanceAsyncApi getInstanceApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Kernel features
|
||||
*
|
||||
|
|
|
@ -34,6 +34,8 @@ import com.google.gson.JsonSerializer;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.domain.Project;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
|
@ -71,6 +73,8 @@ public class GoogleComputeParserModule extends AbstractModule {
|
|||
.put(Header.class, new HeaderTypeAdapter())
|
||||
.put(ClaimSet.class, new ClaimSetTypeAdapter())
|
||||
.put(Project.class, new ProjectTypeAdapter())
|
||||
.put(Instance.class, new InstanceTypeAdapter())
|
||||
.put(InstanceTemplate.class, new InstanceTemplateTypeAdapter())
|
||||
.put(Rule.class, new RuleTypeAdapter())
|
||||
.build();
|
||||
}
|
||||
|
@ -118,6 +122,96 @@ public class GoogleComputeParserModule extends AbstractModule {
|
|||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class InstanceTemplateTypeAdapter implements JsonSerializer<InstanceTemplate> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(InstanceTemplate src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
InstanceTemplateInternal template = new InstanceTemplateInternal(src);
|
||||
JsonObject instance = (JsonObject) context.serialize(template, InstanceTemplateInternal.class);
|
||||
|
||||
// deal with network
|
||||
JsonArray networkInterfaces = new JsonArray();
|
||||
networkInterfaces.add(context.serialize(src.getNetwork(), InstanceTemplate.Network.class));
|
||||
instance.add("networkInterfaces", networkInterfaces);
|
||||
|
||||
// deal with persistent disks
|
||||
if (src.getDisks() != null && !src.getDisks().isEmpty()) {
|
||||
JsonArray disks = new JsonArray();
|
||||
for (InstanceTemplate.PersistentDisk persistentDisk : src.getDisks()) {
|
||||
JsonObject disk = (JsonObject) context.serialize(persistentDisk, InstanceTemplate.PersistentDisk.class);
|
||||
disk.addProperty("type", "PERSISTENT");
|
||||
disks.add(disk);
|
||||
}
|
||||
instance.add("disks", disks);
|
||||
}
|
||||
|
||||
// deal with metadata
|
||||
if (src.getMetadata() != null && !src.getMetadata().isEmpty()) {
|
||||
JsonObject metadata = (JsonObject) context.serialize(new Metadata(src.getMetadata()));
|
||||
instance.add("metadata", metadata);
|
||||
return instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static class InstanceTemplateInternal extends InstanceTemplate {
|
||||
private InstanceTemplateInternal(InstanceTemplate template) {
|
||||
super(template.getMachineType());
|
||||
name(template.getName());
|
||||
description(template.getDescription());
|
||||
zone(template.getZone());
|
||||
image(template.getImage());
|
||||
tags(template.getTags());
|
||||
serviceAccounts(template.getServiceAccounts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class InstanceTypeAdapter implements JsonDeserializer<Instance> {
|
||||
|
||||
@Override
|
||||
public Instance deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
Instance.Builder instanceBuilder = ((Instance) context.deserialize(json,
|
||||
InstanceInternal.class)).toBuilder();
|
||||
JsonObject object = (JsonObject) json;
|
||||
if (object.get("disks") != null) {
|
||||
JsonArray disks = (JsonArray) object.get("disks");
|
||||
for (JsonElement element : disks) {
|
||||
JsonObject disk = (JsonObject) element;
|
||||
if (disk.get("type").getAsString().equals("PERSISTENT")) {
|
||||
instanceBuilder.addDisk((Instance.PersistentAttachedDisk) context.deserialize(disk,
|
||||
Instance.PersistentAttachedDisk.class));
|
||||
} else {
|
||||
instanceBuilder.addDisk((Instance.AttachedDisk) context.deserialize(disk,
|
||||
Instance.AttachedDisk.class));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Instance.builder().fromInstance(instanceBuilder.build()).build();
|
||||
}
|
||||
|
||||
|
||||
private static class InstanceInternal extends Instance {
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "tags", "image", "machineType",
|
||||
"status", "statusMessage", "zone", "networkInterfaces", "metadata", "serviceAccounts"
|
||||
})
|
||||
private InstanceInternal(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Set<String> tags, URI image, URI machineType, Status status, String statusMessage,
|
||||
URI zone, Set<NetworkInterface> networkInterfaces, Metadata metadata,
|
||||
Set<ServiceAccount> serviceAccounts) {
|
||||
super(id, creationTimestamp, selfLink, name, description, tags, image, machineType,
|
||||
status, statusMessage, zone, networkInterfaces, null, metadata, serviceAccounts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser for Metadata.
|
||||
*/
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
package org.jclouds.googlecompute.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.GoogleComputeAsyncApi;
|
||||
|
@ -36,6 +36,8 @@ import org.jclouds.googlecompute.features.FirewallApi;
|
|||
import org.jclouds.googlecompute.features.FirewallAsyncApi;
|
||||
import org.jclouds.googlecompute.features.ImageApi;
|
||||
import org.jclouds.googlecompute.features.ImageAsyncApi;
|
||||
import org.jclouds.googlecompute.features.InstanceApi;
|
||||
import org.jclouds.googlecompute.features.InstanceAsyncApi;
|
||||
import org.jclouds.googlecompute.features.KernelApi;
|
||||
import org.jclouds.googlecompute.features.KernelAsyncApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeApi;
|
||||
|
@ -51,22 +53,24 @@ import org.jclouds.googlecompute.features.ZoneAsyncApi;
|
|||
import org.jclouds.googlecompute.handlers.GoogleComputeErrorHandler;
|
||||
import org.jclouds.googlecompute.predicates.OperationDonePredicate;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.Uris;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
|
||||
/**
|
||||
* Configures the GoogleCompute connection.
|
||||
|
@ -79,6 +83,7 @@ public class GoogleComputeRestClientModule extends RestClientModule<GoogleComput
|
|||
.put(DiskApi.class, DiskAsyncApi.class)
|
||||
.put(FirewallApi.class, FirewallAsyncApi.class)
|
||||
.put(ImageApi.class, ImageAsyncApi.class)
|
||||
.put(InstanceApi.class, InstanceAsyncApi.class)
|
||||
.put(KernelApi.class, KernelAsyncApi.class)
|
||||
.put(MachineTypeApi.class, MachineTypeAsyncApi.class)
|
||||
.put(NetworkApi.class, NetworkAsyncApi.class)
|
||||
|
@ -108,13 +113,55 @@ public class GoogleComputeRestClientModule extends RestClientModule<GoogleComput
|
|||
@Provides
|
||||
@Singleton
|
||||
@UserProject
|
||||
public Supplier<String> supplyProject(
|
||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||
public Supplier<String> supplyProject(@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||
return compose(new Function<Credentials, String>() {
|
||||
public String apply(Credentials in) {
|
||||
checkState(in.identity.indexOf("@") != 1, "identity should be in project_id@developer.gserviceaccount.com format");
|
||||
checkState(in.identity.indexOf("@") != 1, "identity should be in project_id@developer.gserviceaccount.com" +
|
||||
" format");
|
||||
return Iterables.get(Splitter.on("@").split(in.identity), 0);
|
||||
}
|
||||
}, creds);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("machineTypes")
|
||||
public Function<String, URI> provideMachineTypeNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/machineTypes/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("networks")
|
||||
public Function<String, URI> provideNetworkNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/networks/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("zones")
|
||||
public Function<String, URI> provideZoneNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/zones/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Optional information for creating an instance.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceTemplate {
|
||||
|
||||
protected String name;
|
||||
protected String description;
|
||||
protected URI machineType;
|
||||
protected URI zone;
|
||||
protected URI image;
|
||||
protected Set<String> tags = Sets.newLinkedHashSet();
|
||||
protected Set<Instance.ServiceAccount> serviceAccounts = Sets.newLinkedHashSet();
|
||||
|
||||
protected transient Set<PersistentDisk> disks = Sets.newLinkedHashSet();
|
||||
protected transient Network network;
|
||||
protected transient String networkName;
|
||||
protected transient Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||
protected transient String machineTypeName;
|
||||
protected transient String zoneName;
|
||||
|
||||
|
||||
protected InstanceTemplate(URI machineType) {
|
||||
this.machineType = checkNotNull(machineType, "machineType");
|
||||
}
|
||||
|
||||
protected InstanceTemplate(String machineTypeName) {
|
||||
this.machineTypeName = checkNotNull(machineTypeName, "machineTypeName");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getName()
|
||||
*/
|
||||
public InstanceTemplate name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDescription()
|
||||
*/
|
||||
public InstanceTemplate description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getImage()
|
||||
*/
|
||||
public InstanceTemplate image(URI image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMachineType()
|
||||
*/
|
||||
public InstanceTemplate machineType(URI machineType) {
|
||||
this.machineType = machineType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMachineType()
|
||||
*/
|
||||
public InstanceTemplate machineType(String machineTypeName) {
|
||||
this.machineTypeName = machineTypeName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getZone()
|
||||
*/
|
||||
public InstanceTemplate zone(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getZone()
|
||||
*/
|
||||
public InstanceTemplate zone(URI zone) {
|
||||
this.zone = zone;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getTags()
|
||||
*/
|
||||
public InstanceTemplate addTag(String tag) {
|
||||
this.tags.add(checkNotNull(tag, "tag"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getTags()
|
||||
*/
|
||||
public InstanceTemplate tags(Set<String> tags) {
|
||||
this.tags = Sets.newLinkedHashSet();
|
||||
this.tags.addAll(checkNotNull(tags, "tags"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate addDisk(PersistentDisk.Mode mode, URI source) {
|
||||
this.disks.add(new PersistentDisk(mode, source, null, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate addDisk(PersistentDisk.Mode mode, URI source, String deviceName, Boolean deleteOnTerminate) {
|
||||
this.disks.add(new PersistentDisk(mode, source, deviceName, deleteOnTerminate));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate disks(Set<PersistentDisk> disks) {
|
||||
this.disks = Sets.newLinkedHashSet();
|
||||
this.disks.addAll(checkNotNull(disks, "disks"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public InstanceTemplate network(URI network) {
|
||||
// by default use the provided network and set to obtain an external IP address and not to specify an internal IP
|
||||
// this behavior can be overriden by using network(Network network)
|
||||
this.network = new Network(checkNotNull(network, "network"), null,
|
||||
ImmutableSet.of(Instance.NetworkInterface.AccessConfig.builder()
|
||||
.name("external")
|
||||
.type(Instance.NetworkInterface.AccessConfig.Type.ONE_TO_ONE_NAT)
|
||||
.build()));
|
||||
return this;
|
||||
}
|
||||
|
||||
private InstanceTemplate network(Network network) {
|
||||
this.network = network;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstanceTemplate networkName(String networkName) {
|
||||
this.networkName = networkName;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMetadata()
|
||||
*/
|
||||
public InstanceTemplate addMetadata(String key, String value) {
|
||||
this.metadata.put(checkNotNull(key, "key"), checkNotNull(value, "value of %", key));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMetadata()
|
||||
*/
|
||||
public InstanceTemplate metadata(Map<String, String> metadata) {
|
||||
this.metadata = Maps.newLinkedHashMap();
|
||||
this.metadata.putAll(checkNotNull(metadata, "metadata"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public InstanceTemplate addServiceAccount(Instance.ServiceAccount serviceAccount) {
|
||||
this.serviceAccounts.add(checkNotNull(serviceAccount, "serviceAccount"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public InstanceTemplate serviceAccounts(Set<Instance.ServiceAccount> serviceAccounts) {
|
||||
this.serviceAccounts = Sets.newLinkedHashSet();
|
||||
this.serviceAccounts.addAll(checkNotNull(serviceAccounts, "serviceAccounts"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDescription()
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getDisks()
|
||||
*/
|
||||
public Set<PersistentDisk> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getImage()
|
||||
*/
|
||||
public URI getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMachineType()
|
||||
*/
|
||||
public URI getMachineType() {
|
||||
return machineType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMachineType()
|
||||
*/
|
||||
public String getMachineTypeName() {
|
||||
return machineTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getMetadata()
|
||||
*/
|
||||
public Map<String, String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public Network getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public String getNetworkName() {
|
||||
return networkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public Set<Instance.ServiceAccount> getServiceAccounts() {
|
||||
return serviceAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getTags()
|
||||
*/
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getZone()
|
||||
*/
|
||||
public URI getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Instance#getZone()
|
||||
*/
|
||||
public String getZoneName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static InstanceTemplate fromInstance(Instance instance) {
|
||||
return Builder.fromInstance(instance);
|
||||
}
|
||||
|
||||
public static InstanceTemplate fromInstanceTemplate(InstanceTemplate instanceTemplate) {
|
||||
return Builder.fromInstanceTemplate(instanceTemplate);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public InstanceTemplate forMachineTypeAndNetwork(URI machineType, URI network) {
|
||||
return new InstanceTemplate(machineType).network(network);
|
||||
}
|
||||
|
||||
public InstanceTemplate forMachineTypeAndNetwork(URI machineType, Network network) {
|
||||
return new InstanceTemplate(machineType).network(network);
|
||||
}
|
||||
|
||||
public InstanceTemplate forMachineTypeAndNetwork(String machineTypeName, String networkName) {
|
||||
return new InstanceTemplate(machineTypeName).networkName(networkName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance options based on another instance.
|
||||
* All properties are the same as the original instance's except:
|
||||
* - disks (persistent disks are only attached to an instance)
|
||||
* - networkInterfaces (these are instance specific)
|
||||
*/
|
||||
public static InstanceTemplate fromInstance(Instance instance) {
|
||||
return InstanceTemplate.builder()
|
||||
.forMachineTypeAndNetwork(instance.getMachineType(),
|
||||
instance.getNetworkInterfaces().iterator().next().getNetwork())
|
||||
.description(instance.getDescription().orNull())
|
||||
.tags(instance.getTags())
|
||||
.image(instance.getImage())
|
||||
.metadata(instance.getMetadata())
|
||||
.zone(instance.getZone())
|
||||
.serviceAccounts(instance.getServiceAccounts());
|
||||
}
|
||||
|
||||
public static InstanceTemplate fromInstanceTemplate(InstanceTemplate instanceTemplate) {
|
||||
return InstanceTemplate.builder()
|
||||
.forMachineTypeAndNetwork(instanceTemplate.getMachineType(), instanceTemplate.getNetwork())
|
||||
.name(instanceTemplate.getName())
|
||||
.description(instanceTemplate.getDescription())
|
||||
.zone(instanceTemplate.getZone())
|
||||
.image(instanceTemplate.getImage())
|
||||
.tags(instanceTemplate.getTags())
|
||||
.disks(instanceTemplate.getDisks())
|
||||
.metadata(instanceTemplate.getMetadata())
|
||||
.serviceAccounts(instanceTemplate.getServiceAccounts());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class PersistentDisk {
|
||||
|
||||
public enum Mode {
|
||||
READ_WRITE,
|
||||
READ_ONLY
|
||||
}
|
||||
|
||||
public PersistentDisk(Mode mode, URI source, String deviceName, Boolean deleteOnTerminate) {
|
||||
this.mode = checkNotNull(mode, "mode");
|
||||
this.source = checkNotNull(source, "source");
|
||||
this.deviceName = deviceName;
|
||||
this.deleteOnTerminate = deleteOnTerminate;
|
||||
}
|
||||
|
||||
private final Mode mode;
|
||||
private final URI source;
|
||||
private final Boolean deleteOnTerminate;
|
||||
private final String deviceName;
|
||||
|
||||
/**
|
||||
* @return the mode in which to attach this disk, either READ_WRITE or READ_ONLY.
|
||||
*/
|
||||
public Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the URL of the persistent disk resource.
|
||||
*/
|
||||
public URI getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Must be unique within the instance when specified. This represents a unique
|
||||
* device name that is reflected into the /dev/ tree of a Linux operating system running within the
|
||||
* instance. If not specified, a default will be chosen by the system.
|
||||
*/
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return If true, delete the disk and all its data when the associated instance is deleted.
|
||||
*/
|
||||
public boolean isDeleteOnTerminate() {
|
||||
return deleteOnTerminate;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Network {
|
||||
|
||||
private final URI network;
|
||||
private final String networkIP;
|
||||
private final Set<Instance.NetworkInterface.AccessConfig> accessConfigs;
|
||||
|
||||
public Network(URI network, String networkIP, Set<Instance.NetworkInterface.AccessConfig>
|
||||
accessConfigs) {
|
||||
this.networkIP = networkIP;
|
||||
this.network = checkNotNull(network, "network");
|
||||
this.accessConfigs = accessConfigs;
|
||||
}
|
||||
|
||||
public Set<Instance.NetworkInterface.AccessConfig> getAccessConfigs() {
|
||||
return accessConfigs;
|
||||
}
|
||||
|
||||
public URI getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public String getNetworkIP() {
|
||||
return networkIP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof InstanceTemplate) {
|
||||
final InstanceTemplate other = InstanceTemplate.class.cast(object);
|
||||
return equal(description, other.description)
|
||||
&& equal(tags, other.tags)
|
||||
&& equal(image, other.image)
|
||||
&& equal(disks, other.disks)
|
||||
&& equal(network, other.network)
|
||||
&& equal(metadata, other.metadata)
|
||||
&& equal(serviceAccounts, other.serviceAccounts);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(description, tags, image, disks, network, metadata, serviceAccounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
Objects.ToStringHelper toString = Objects.toStringHelper("")
|
||||
.omitNullValues();
|
||||
toString.add("description", description);
|
||||
if (tags.size() > 0)
|
||||
toString.add("tags", tags);
|
||||
if (disks.size() > 0)
|
||||
toString.add("disks", disks);
|
||||
if (metadata.size() > 0)
|
||||
toString.add("metadata", metadata);
|
||||
if (serviceAccounts.size() > 0)
|
||||
toString.add("serviceAccounts", serviceAccounts);
|
||||
toString.add("image", image);
|
||||
toString.add("networkInterfaces", network);
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
}
|
|
@ -48,13 +48,14 @@ public interface DiskApi {
|
|||
/**
|
||||
* Creates a persistent disk resource in the specified project specifying the size of the disk.
|
||||
*
|
||||
*
|
||||
* @param diskName the name of disk.
|
||||
* @param zone the URi of the zone where the disk is to be created.
|
||||
* @param sizeGb the size of the disk
|
||||
* @param zone the URi of the zone where the disk is to be created.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field.
|
||||
*/
|
||||
Operation insert(String diskName, URI zone, int sizeGb);
|
||||
Operation createInZone(String diskName, int sizeGb, URI zone);
|
||||
|
||||
/**
|
||||
* Deletes the specified persistent disk resource.
|
||||
|
|
|
@ -76,7 +76,7 @@ public interface DiskAsyncApi {
|
|||
ListenableFuture<Disk> get(@PathParam("disk") String diskName);
|
||||
|
||||
/**
|
||||
* @see DiskApi#insert(String, java.net.URI, int)
|
||||
* @see DiskApi#createInZone(String, int, java.net.URI)
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
|
@ -84,9 +84,9 @@ public interface DiskAsyncApi {
|
|||
@Path("/disks")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ListenableFuture<Operation> insert(@PayloadParam("name") String diskName,
|
||||
@PayloadParam("zone") URI zone,
|
||||
@PayloadParam("sizeGb") int sizeGb);
|
||||
ListenableFuture<Operation> createInZone(@PayloadParam("name") String diskName,
|
||||
@PayloadParam("sizeGb") int sizeGb,
|
||||
@PayloadParam("zone") URI zone);
|
||||
|
||||
/**
|
||||
* @see DiskApi#delete(String)
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Instances via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @author David Alves
|
||||
* @see InstanceAsyncApi
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/instances/get"/>
|
||||
*/
|
||||
public interface InstanceApi {
|
||||
|
||||
/**
|
||||
* Returns the specified instance resource.
|
||||
*
|
||||
* @param instanceName name of the instance resource to return.
|
||||
* @return an Instance resource
|
||||
*/
|
||||
public Instance get(String instanceName);
|
||||
|
||||
/**
|
||||
* Creates a instance resource in the specified project using the data included in the request.
|
||||
*
|
||||
* @param instanceName this name of the instance to be created
|
||||
* @param template the instance template
|
||||
* @param zone the name of the zone where the instance will be created
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field.
|
||||
*/
|
||||
public Operation createInZone(String instanceName, InstanceTemplate template, String zone);
|
||||
|
||||
/**
|
||||
* Deletes the specified instance resource.
|
||||
*
|
||||
* @param instanceName name of the instance resource to delete.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field. If the instance did not exist the result is null.
|
||||
*/
|
||||
public Operation delete(String instanceName);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
public ListPage<Instance> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
public ListPage<Instance> listAtMarker(@Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of instance resources available to the specified project.
|
||||
* By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
|
||||
* been set.
|
||||
*
|
||||
* @param marker marks the beginning of the next list page
|
||||
* @param listOptions listing options
|
||||
* @return a page of the list
|
||||
* @see ListOptions
|
||||
* @see org.jclouds.googlecompute.domain.ListPage
|
||||
*/
|
||||
public ListPage<Instance> listAtMarker(@Nullable String marker, @Nullable ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#list(org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
public PagedIterable<Instance> list();
|
||||
|
||||
/**
|
||||
* A paged version of InstanceApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
public PagedIterable<Instance> list(@Nullable ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* Adds an access config to an instance's network interface.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @param accessConfig the AccessConfig to add.
|
||||
* @param networkInterfaceName network interface name.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field. If the instance did not exist the result is null.
|
||||
*/
|
||||
public Operation addAccessConfigToNic(String instanceName, Instance.NetworkInterface.AccessConfig accessConfig,
|
||||
String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* Deletes an access config from an instance's network interface.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @param accessConfigName the name of the access config to delete
|
||||
* @param networkInterfaceName network interface name.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field. If the instance did not exist the result is null.
|
||||
*/
|
||||
public Operation deleteAccessConfigFromNic(String instanceName, String accessConfigName,
|
||||
String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* Returns the specified instance's serial port output.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @return if successful, this method returns a SerialPortOutput containing the instance's serial output.
|
||||
*/
|
||||
public Instance.SerialPortOutput getSerialPortOutput(String instanceName);
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.functions.internal.ParseInstances;
|
||||
import org.jclouds.googlecompute.handlers.InstanceBinder;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.oauth.v2.config.OAuthScopes;
|
||||
import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import static org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import static org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Instances via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see InstanceApi
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface InstanceAsyncApi {
|
||||
|
||||
/**
|
||||
* @see InstanceApi#get(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Instance> get(@PathParam("instance") String instanceName);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#createInZone(String, org.jclouds.googlecompute.domain.InstanceTemplate, String)
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(InstanceBinder.class)
|
||||
ListenableFuture<Operation> createInZone(@PayloadParam("name") String instanceName,
|
||||
@PayloadParam("template") InstanceTemplate template,
|
||||
@PayloadParam("zone") String zone);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#delete(String)
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Operation> delete(@PathParam("instance") String instanceName);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listFirstPage()
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Instance>> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listAtMarker(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Instance>> listAtMarker(@Nullable String marker);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Instance>> listAtMarker(@Nullable String marker, ListOptions options);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#list()
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Transform(ParseInstances.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<Instance>> list();
|
||||
|
||||
/**
|
||||
* @see InstanceApi#list(org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Transform(ParseInstances.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<Instance>> list(ListOptions options);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#addAccessConfigToNic(String, Instance.NetworkInterface.AccessConfig, String)
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/addAccessConfig")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
ListenableFuture<Operation> addAccessConfigToNic(@PathParam("instance") String instanceName,
|
||||
@BinderParam(BindToJsonPayload.class)
|
||||
Instance.NetworkInterface.AccessConfig accessConfig,
|
||||
@QueryParam("network_interface") String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#deleteAccessConfigFromNic(String, String, String)
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/deleteAccessConfig")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Operation> deleteAccessConfigFromNic(@PathParam("instance") String instanceName,
|
||||
@QueryParam("access_config") String accessConfigName,
|
||||
@QueryParam("network_interface") String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#getSerialPortOutput(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/serialPort")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Instance.SerialPortOutput> getSerialPortOutput(@PathParam("instance") String instanceName);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ParseInstances extends ParseJson<ListPage<Instance>> {
|
||||
|
||||
@Inject
|
||||
public ParseInstances(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Instance>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Instance, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Instance>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Instance>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Instance> apply(Object input) {
|
||||
return api.getInstanceApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.handlers;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.MapBinder;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceBinder implements MapBinder {
|
||||
|
||||
@Inject
|
||||
private BindToJsonPayload jsonBinder;
|
||||
|
||||
@Inject
|
||||
@Named("machineTypes")
|
||||
Function<String, URI> machineTypesToURI;
|
||||
|
||||
@Inject
|
||||
@Named("networks")
|
||||
Function<String, URI> networksToURI;
|
||||
|
||||
@Inject
|
||||
@Named("zones")
|
||||
Function<String, URI> zonesToURI;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
|
||||
InstanceTemplate template = (InstanceTemplate) checkNotNull(postParams.get("template"), "template");
|
||||
template.name(checkNotNull(postParams.get("name"), "name").toString());
|
||||
template.zone(zonesToURI.apply((String) checkNotNull(postParams.get("zone"), "zone")));
|
||||
if (template.getNetworkName() != null) {
|
||||
template.network(networksToURI.apply(template.getNetworkName()));
|
||||
}
|
||||
|
||||
if (template.getMachineTypeName() != null) {
|
||||
template.machineType(machineTypesToURI.apply(template.getMachineTypeName()));
|
||||
}
|
||||
template.zone((String) null);
|
||||
template.machineType((String) null);
|
||||
return bindToRequest(request, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
return jsonBinder.bindToRequest(request, input);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.googlecompute.parse.ParseDiskListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseDiskTest;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationTest;
|
||||
|
@ -94,8 +93,8 @@ public class DiskApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
|||
TOKEN_RESPONSE, insert,
|
||||
insertDiskResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertEquals(api.insert("testimage1", URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/zones/us-central1-a"), 1)
|
||||
assertEquals(api.createInZone("testimage1", 1, URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/zones/us-central1-a"))
|
||||
, new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public class DiskApiLiveTest extends BaseGoogleComputeApiLiveTest {
|
|||
public void testInsertDisk() {
|
||||
Project project = context.getApi().getProjectApi().get(getUserProject());
|
||||
zoneUrl = getDefaultZoneUrl(project.getName());
|
||||
assertOperationDoneSucessfully(api().insert(DISK_NAME, zoneUrl, sizeGb), TIME_WAIT);
|
||||
assertOperationDoneSucessfully(api().createInZone(DISK_NAME, sizeGb, zoneUrl), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseInstanceListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseInstanceSerialOutputTest;
|
||||
import org.jclouds.googlecompute.parse.ParseInstanceTest;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.AssertJUnit.assertNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class InstanceApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public void testGetInstanceResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/instance_get.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("test-instance"),
|
||||
new ParseInstanceTest().expected());
|
||||
}
|
||||
|
||||
public void testGetInstanceResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertNull(api.get("test-instance"));
|
||||
}
|
||||
|
||||
public void testGetInstanceSerialPortOutput() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance/serialPort")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/instance_serial_port.json")).build();
|
||||
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.getSerialPortOutput("test-instance"), new ParseInstanceSerialOutputTest().expected());
|
||||
}
|
||||
|
||||
public void testInsertInstanceResponseIs2xxNoOptions() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/instance_insert_simple.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertInstanceResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert,
|
||||
insertInstanceResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.createInZone("test-instance",
|
||||
InstanceTemplate.builder()
|
||||
.forMachineTypeAndNetwork("n1-standard-1", "default"),
|
||||
"us-central1-a"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testInsertInstanceResponseIs2xxAllOptions() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/instance_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertInstanceResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert, insertInstanceResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
Instance instance = new ParseInstanceTest().expected();
|
||||
InstanceTemplate options = new InstanceTemplate.Builder()
|
||||
.fromInstance(instance)
|
||||
.network(instance.getNetworkInterfaces().iterator().next().getNetwork())
|
||||
.addDisk(InstanceTemplate.PersistentDisk.Mode.READ_WRITE,
|
||||
URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/test"));
|
||||
|
||||
assertEquals(api.createInZone(instance.getName(), options, "us-central1-a"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteInstanceResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.delete("test-instance"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteInstanceResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertNull(api.delete("test-instance"));
|
||||
}
|
||||
|
||||
public void testListInstancesResponseIs2xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/instance_list.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseInstanceListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListInstancesResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiLiveTest;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceApiLiveTest extends BaseGoogleComputeApiLiveTest {
|
||||
|
||||
private static final String INSTANCE_NAME = "instance-api-live-test-instance";
|
||||
private static final String DISK_NAME = "instance-live-test-disk";
|
||||
private static final int TIME_WAIT = 600;
|
||||
|
||||
private InstanceTemplate instance;
|
||||
|
||||
@BeforeClass(groups = {"integration", "live"})
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
instance = InstanceTemplate.builder()
|
||||
.forMachineTypeAndNetwork(getDefaultMachineTypekUrl(getUserProject()),
|
||||
getDefaultNetworkUrl(getUserProject()))
|
||||
.addMetadata("mykey", "myvalue")
|
||||
.addTag("atag")
|
||||
.description("a description")
|
||||
.addDisk(InstanceTemplate.PersistentDisk.Mode.READ_WRITE, getDiskUrl(getUserProject(), DISK_NAME))
|
||||
.zone(getDefaultZoneUrl(getUserProject()));
|
||||
}
|
||||
|
||||
private InstanceApi api() {
|
||||
return context.getApi().getInstanceApiForProject(getUserProject());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertInstance() {
|
||||
|
||||
assertOperationDoneSucessfully(context.getApi().getDiskApiForProject(getUserProject()).createInZone
|
||||
("instance-live-test-disk", 1, getDefaultZoneUrl(getUserProject())), TIME_WAIT);
|
||||
|
||||
assertOperationDoneSucessfully(api().createInZone(INSTANCE_NAME, instance, DEFAULT_ZONE_NAME), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testInsertInstanceCopy() {
|
||||
Instance instance = api().get(INSTANCE_NAME);
|
||||
InstanceTemplate copy = InstanceTemplate.fromInstance(instance);
|
||||
copy.network(instance.getNetworkInterfaces().iterator().next().getNetwork());
|
||||
|
||||
assertOperationDoneSucessfully(api().createInZone(INSTANCE_NAME + "-2", copy, DEFAULT_ZONE_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testGetInstance() {
|
||||
|
||||
Instance instance = api().get(INSTANCE_NAME);
|
||||
assertNotNull(instance);
|
||||
assertInstanceEquals(instance, this.instance);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testListInstance() {
|
||||
|
||||
PagedIterable<Instance> instances = api().list(new ListOptions.Builder()
|
||||
.filter("name eq " + INSTANCE_NAME));
|
||||
|
||||
List<Instance> instancesAsList = Lists.newArrayList(instances.concat());
|
||||
|
||||
assertEquals(instancesAsList.size(), 1);
|
||||
|
||||
assertInstanceEquals(Iterables.getOnlyElement(instancesAsList), instance);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = {"testListInstance", "testInsertInstanceCopy"})
|
||||
public void testDeleteInstance() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(INSTANCE_NAME), TIME_WAIT);
|
||||
assertOperationDoneSucessfully(api().delete(INSTANCE_NAME + "-2"), TIME_WAIT);
|
||||
assertOperationDoneSucessfully(context.getApi().getDiskApiForProject(getUserProject()).delete(DISK_NAME),
|
||||
TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertInstanceEquals(Instance result, InstanceTemplate expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
assertEquals(result.getTags(), expected.getTags());
|
||||
assertEquals(result.getMetadata(), expected.getMetadata());
|
||||
}
|
||||
}
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeExpectTest;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseKernelListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseKernelTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -36,7 +35,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class KernelApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
public class KernelApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public void testGetKernelResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeExpectTest;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseMachineTypeListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseMachineTypeTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -36,7 +35,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class MachineTypeApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
public class MachineTypeApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public void testGetMachineTypeResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeExpectTest;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationTest;
|
||||
|
@ -38,7 +37,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class OperationApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
public class OperationApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
private static final String OPERATIONS_URL_PREFIX = "https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/operations";
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.GoogleComputeConstants;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeExpectTest;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseMetadataTest;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationTest;
|
||||
import org.jclouds.googlecompute.parse.ParseProjectTest;
|
||||
|
@ -39,7 +38,7 @@ import static org.testng.Assert.assertNull;
|
|||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ProjectApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
public class ProjectApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public static final String PROJECTS_URL_PREFIX = "https://www.googleapis.com/compute/v1beta13/projects";
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
package org.jclouds.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeExpectTest;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseZoneListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseZoneTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -36,7 +35,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ZoneApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
public class ZoneApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public static final String ZONES_URL_PREFIX = "https://www.googleapis.com/compute/v1beta13/projects/google/zones";
|
||||
|
||||
|
|
|
@ -20,9 +20,17 @@ package org.jclouds.googlecompute.internal;
|
|||
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseGoogleComputeApiExpectTest extends BaseGoogleComputeExpectTest<GoogleComputeApi> {
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
properties.put("google-compute.identity", "myproject");
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.googlecompute.internal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.apis.BaseContextLiveTest;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.GoogleComputeApiMetadata;
|
||||
|
@ -36,11 +32,14 @@ import org.jclouds.googlecompute.domain.Operation;
|
|||
import org.jclouds.oauth.v2.OAuthTestUtils;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -123,6 +122,10 @@ public class BaseGoogleComputeApiLiveTest extends BaseContextLiveTest<RestContex
|
|||
return URI.create(API_URL_PREFIX + project + MACHINE_TYPE_API_URL_SUFFIX + machineType);
|
||||
}
|
||||
|
||||
protected URI getDiskUrl(String project, String diskName) {
|
||||
return URI.create(API_URL_PREFIX + project + "/disks/" + diskName);
|
||||
}
|
||||
|
||||
protected static Operation waitOperationDone(Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
Operation operation, long maxWaitSeconds) {
|
||||
AtomicReference<Operation> operationReference = new AtomicReference<Operation>(operation);
|
||||
|
|
|
@ -47,7 +47,7 @@ public class BaseGoogleComputeExpectTest<T> extends BaseRestApiExpectTest<T> {
|
|||
private static final String header = "{\"alg\":\"none\",\"typ\":\"JWT\"}";
|
||||
|
||||
private static final String CLAIMS_TEMPLATE = "{" +
|
||||
"\"iss\":\"identity\"," +
|
||||
"\"iss\":\"myproject\"," +
|
||||
"\"scope\":\"%s\"," +
|
||||
"\"aud\":\"https://accounts.google.com/o/oauth2/token\"," +
|
||||
"\"exp\":3600," +
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.parse;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Resource;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ParseInstanceListTest extends BaseGoogleComputeParseTest<ListPage<Instance>> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/instance_list.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public ListPage<Instance> expected() {
|
||||
return ListPage.<Instance>builder()
|
||||
.kind(Resource.Kind.INSTANCE_LIST)
|
||||
.id("projects/myproject/instances")
|
||||
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances"))
|
||||
.items(ImmutableSet.of(new ParseInstanceTest().expected()))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.parse;
|
||||
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ParseInstanceSerialOutputTest extends BaseGoogleComputeParseTest<Instance.SerialPortOutput> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/instance_serial_port.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Instance.SerialPortOutput expected() {
|
||||
return Instance.SerialPortOutput.builder()
|
||||
.contents("console output").build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.googlecompute.parse;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.googlecompute.domain.Instance;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ParseInstanceTest extends BaseGoogleComputeParseTest<Instance> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/instance_get.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Instance expected() {
|
||||
return Instance.builder()
|
||||
.id("13051190678907570425")
|
||||
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-11-25T23:48:20.758"))
|
||||
.selfLink(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-instance"))
|
||||
.description("desc")
|
||||
.name("test-instance")
|
||||
.image(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/images/ubuntu-12-04-v20120912"))
|
||||
.machineType(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes/n1" +
|
||||
"-standard-1"))
|
||||
.status(Instance.Status.RUNNING)
|
||||
.zone(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a"))
|
||||
.addNetworkInterface(
|
||||
Instance.NetworkInterface.builder()
|
||||
.name("nic0")
|
||||
.networkIP("10.240.121.115")
|
||||
.network(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.build()
|
||||
)
|
||||
.addDisk(
|
||||
Instance.PersistentAttachedDisk.builder()
|
||||
.index(0)
|
||||
.mode(Instance.PersistentAttachedDisk.Mode.READ_WRITE)
|
||||
.deviceName("test")
|
||||
.source(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks/test"))
|
||||
.build()
|
||||
)
|
||||
.addTag("aTag")
|
||||
.metadata(ImmutableMap.of("aKey", "aValue"))
|
||||
.addServiceAccount(Instance.ServiceAccount.builder().email("default").addScopes("myscope").build())
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
{"name":"testimage1","zone":"https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a","sizeGb":1}
|
||||
{"name":"testimage1","sizeGb":1,"zone":"https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a"}
|
|
@ -0,0 +1,11 @@
|
|||
POST https://www.googleapis.com/compute/v1beta13/projects/jclouds-gce/instances/test-instance/addAccessConfig?network_interface=nic0&key={YOUR_API_KEY}
|
||||
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer ya29.AHES6ZRyNKVHwnMPUvZitAuA8mR8b0lcWh1bMI5UQ5bgsJ4j
|
||||
X-JavaScript-User-Agent: Google APIs Explorer
|
||||
|
||||
{
|
||||
"name": "config1",
|
||||
"natIP": "10.0.1.1",
|
||||
"type": "ONE_TO_ONE_NAT"
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"kind": "compute#instance",
|
||||
"id": "13051190678907570425",
|
||||
"description": "desc",
|
||||
"creationTimestamp": "2012-11-25T23:48:20.758",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/instances/test-instance",
|
||||
"name": "test-instance",
|
||||
"image": "https://www.googleapis.com/compute/v1beta13/projects/google/images/ubuntu-12-04-v20120912",
|
||||
"machineType": "https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1",
|
||||
"status": "RUNNING",
|
||||
"zone": "https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a",
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"kind": "compute#instanceNetworkInterface",
|
||||
"name": "nic0",
|
||||
"networkIP": "10.240.121.115",
|
||||
"network": "https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default"
|
||||
}
|
||||
],
|
||||
"disks": [
|
||||
{
|
||||
"kind": "compute#instanceDisk",
|
||||
"type": "PERSISTENT",
|
||||
"mode": "READ_WRITE",
|
||||
"deviceName": "test",
|
||||
"source": "https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/test",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"serviceAccounts": [
|
||||
{
|
||||
"kind": "compute#serviceAccount",
|
||||
"email": "default",
|
||||
"scopes": [
|
||||
"myscope"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"items": [
|
||||
{
|
||||
"key": "aKey",
|
||||
"value": "aValue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tags": [
|
||||
"aTag"
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"name":"test-instance","description":"desc","machineType":"https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1","zone":"https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a","image":"https://www.googleapis.com/compute/v1beta13/projects/google/images/ubuntu-12-04-v20120912","tags":["aTag"],"serviceAccounts":[{"email":"default","scopes":["myscope"]}],"networkInterfaces":[{"network":"https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default","accessConfigs":[{"name":"external","type":"ONE_TO_ONE_NAT"}]}],"disks":[{"mode":"READ_WRITE","source":"https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/test","type":"PERSISTENT"}],"metadata":{"kind":"compute#metadata","items":[{"key":"aKey","value":"aValue"}]}}
|
|
@ -0,0 +1 @@
|
|||
{"name":"test-instance","machineType":"https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1","zone":"https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a","tags":[],"serviceAccounts":[],"networkInterfaces":[{"network":"https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default","accessConfigs":[{"name":"external","type":"ONE_TO_ONE_NAT"}]}]}
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"kind": "compute#instanceList",
|
||||
"id": "projects/myproject/instances",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/instances",
|
||||
"items": [
|
||||
{
|
||||
"kind": "compute#instance",
|
||||
"id": "13051190678907570425",
|
||||
"description": "desc",
|
||||
"creationTimestamp": "2012-11-25T23:48:20.758",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/instances/test-instance",
|
||||
"name": "test-instance",
|
||||
"image": "https://www.googleapis.com/compute/v1beta13/projects/google/images/ubuntu-12-04-v20120912",
|
||||
"machineType": "https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1",
|
||||
"status": "RUNNING",
|
||||
"zone": "https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a",
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"kind": "compute#instanceNetworkInterface",
|
||||
"name": "nic0",
|
||||
"networkIP": "10.240.121.115",
|
||||
"network": "https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default"
|
||||
}
|
||||
],
|
||||
"disks": [
|
||||
{
|
||||
"kind": "compute#instanceDisk",
|
||||
"type": "PERSISTENT",
|
||||
"mode": "READ_WRITE",
|
||||
"deviceName": "test",
|
||||
"source": "https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/test",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"serviceAccounts": [
|
||||
{
|
||||
"kind": "compute#serviceAccount",
|
||||
"email": "default",
|
||||
"scopes": [
|
||||
"myscope"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"items": [
|
||||
{
|
||||
"key": "aKey",
|
||||
"value": "aValue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tags": [
|
||||
"aTag"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"kind": "compute#serialPortOutput",
|
||||
"contents": "console output"
|
||||
}
|
Loading…
Reference in New Issue