JCLOUDS-1122: Support subnetworks definitions in Google Compute.

This commit is contained in:
Nelson Araujo 2016-08-06 23:33:29 -07:00 committed by Ignasi Barrera
parent db2f86bcec
commit 2ec28df21b
18 changed files with 701 additions and 10 deletions

View File

@ -17,11 +17,13 @@
package org.jclouds.googlecomputeengine;
import java.io.Closeable;
import java.net.URI;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.googlecloud.config.CurrentProject;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.googlecomputeengine.features.AddressApi;
import org.jclouds.googlecomputeengine.features.AggregatedListApi;
import org.jclouds.googlecomputeengine.features.BackendServiceApi;
@ -40,6 +42,8 @@ import org.jclouds.googlecomputeengine.features.ProjectApi;
import org.jclouds.googlecomputeengine.features.RegionApi;
import org.jclouds.googlecomputeengine.features.RouteApi;
import org.jclouds.googlecomputeengine.features.SnapshotApi;
import org.jclouds.googlecomputeengine.features.SubnetworkApi;
import org.jclouds.googlecomputeengine.features.TargetHttpProxyApi;
import org.jclouds.googlecomputeengine.features.TargetInstanceApi;
import org.jclouds.googlecomputeengine.features.TargetPoolApi;
import org.jclouds.googlecomputeengine.features.TargetHttpProxyApi;
@ -47,6 +51,7 @@ import org.jclouds.googlecomputeengine.features.UrlMapApi;
import org.jclouds.googlecomputeengine.features.ZoneApi;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam;
public interface GoogleComputeEngineApi extends Closeable {
@ -116,6 +121,11 @@ public interface GoogleComputeEngineApi extends Closeable {
@Path("/global")
NetworkApi networks();
@Delegate
@Endpoint(CurrentProject.class)
@Path("/regions/{region}")
SubnetworkApi subnetworksInRegion(@PathParam("region") String region);
@Delegate
OperationApi operations();
@ -159,5 +169,4 @@ public interface GoogleComputeEngineApi extends Closeable {
@Endpoint(CurrentProject.class)
@Path("/global/urlMaps")
UrlMapApi urlMaps();
}

View File

@ -136,11 +136,17 @@ public final class GoogleComputeEngineServiceAdapter
URI network = URI.create(networks.next());
assert !networks.hasNext() : "Error: Options should specify only one network";
Iterator<String> subnetworks = options.getSubnetworks().iterator();
URI subnetwork = subnetworks.hasNext() ? URI.create(subnetworks.next()) : null;
assert !subnetworks.hasNext() : "Error: Options should specify only one subnetwork";
Scheduling scheduling = getScheduling(options);
NewInstance newInstance = new NewInstance.Builder( name,
NewInstance newInstance = new NewInstance.Builder(name,
template.getHardware().getUri(), // machineType
network,
subnetwork,
disks)
.description(group)
.tags(Tags.create(null, ImmutableList.copyOf(options.getTags())))

View File

@ -32,6 +32,7 @@ import org.jclouds.googlecomputeengine.domain.Image;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.oauth.v2.filters.OAuthFilter;
import org.jclouds.rest.annotations.EndpointParam;
@ -82,6 +83,10 @@ public interface Resources {
@Path("/stop")
Operation stopInstance(@EndpointParam URI selfLink);
@Named("Subnetworks:get")
@GET
@Fallback(NullOnNotFoundOr404.class) @Nullable Subnetwork subnetwork(@EndpointParam URI selfLink);
/** Returns a disk by self-link or null if not found. */
@Named("Disks:get")
@GET

View File

@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.compute.loaders;
import java.net.URI;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.googlecomputeengine.compute.functions.Resources;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.logging.Logger;
import com.google.common.cache.CacheLoader;
@Singleton
public class SubnetworkLoader extends CacheLoader<URI, Subnetwork> {
@Resource
protected Logger logger = Logger.NULL;
private final Resources resources;
@Inject
SubnetworkLoader(Resources resources) {
this.resources = resources;
}
@Override
public Subnetwork load(URI key) throws ExecutionException {
try {
return resources.subnetwork(key);
} catch (Exception e) {
throw new ExecutionException(message(key, e), e);
}
}
public static String message(URI key, Exception e) {
return String.format("could not find image for disk %s: %s", key.toString(), e.getMessage());
}
}

View File

@ -18,12 +18,15 @@ package org.jclouds.googlecomputeengine.compute.options;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.collect.ImmutableSet;
/** Instance options specific to Google Compute Engine. */
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
@ -32,6 +35,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
private List<ServiceAccount> serviceAccounts;
private String bootDiskType;
private boolean preemptible = false;
private Set<String> subnetworks;
@Override
public GoogleComputeEngineTemplateOptions clone() {
@ -134,6 +138,11 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
return serviceAccounts;
}
public Set<String> getSubnetworks() {
return subnetworks;
}
/**
* {@inheritDoc}
*/
@ -286,6 +295,22 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
return GoogleComputeEngineTemplateOptions.class.cast(super.networks(networks));
}
/**
* Assigns subnetworks to the machine.
*/
public GoogleComputeEngineTemplateOptions subnetworks(Iterable<String> networks) {
this.subnetworks = ImmutableSet.copyOf(networks);
return this;
}
/**
* Assigns subnetworks to the machine.
*/
public GoogleComputeEngineTemplateOptions subnetworks(String... networks) {
this.subnetworks = ImmutableSet.copyOf(networks);
return this;
}
/**
* {@inheritDoc}
*/

View File

@ -18,11 +18,13 @@ package org.jclouds.googlecomputeengine.domain;
import java.net.URI;
import java.util.Date;
import java.util.List;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
/**
* Represents a network used to enable instance communication.
@ -30,6 +32,12 @@ import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Network {
public enum NetworkType {
LegacyNetwork,
AutoSubnetwork,
CustomNetwork,
}
public abstract String id();
public abstract Date creationTimestamp();
@ -38,6 +46,8 @@ public abstract class Network {
public abstract String name();
public abstract NetworkType type();
@Nullable public abstract String description();
/**
@ -52,10 +62,23 @@ public abstract class Network {
*/
@Nullable public abstract String gatewayIPv4();
@SerializedNames({ "id", "creationTimestamp", "selfLink", "name", "description", "IPv4Range", "gatewayIPv4" })
@Nullable public abstract List<URI> subnetworks();
public static Network create(String id, Date creationTimestamp, URI selfLink, String name, String description, String rangeIPv4,
String gatewayIPv4) {
return new AutoValue_Network(id, creationTimestamp, selfLink, name, description, rangeIPv4, gatewayIPv4);
String gatewayIPv4) {
return new AutoValue_Network(id, creationTimestamp, selfLink, name, NetworkType.LegacyNetwork, description,
rangeIPv4, gatewayIPv4, null);
}
@SerializedNames({ "id", "creationTimestamp", "selfLink", "name", "description", "IPv4Range", "gatewayIPv4", "autoCreateSubnetworks", "subnetworks" })
public static Network create(String id, Date creationTimestamp, URI selfLink, String name, String description, String rangeIPv4,
String gatewayIPv4, String autoCreateSubnetworks, List<URI> subnetworks) {
NetworkType type;
type = !Strings.isNullOrEmpty(rangeIPv4) ? NetworkType.LegacyNetwork
: (autoCreateSubnetworks.equals("true") ? NetworkType.AutoSubnetwork
: NetworkType.CustomNetwork);
return new AutoValue_Network(id, creationTimestamp, selfLink, name, type, description, rangeIPv4, gatewayIPv4,
subnetworks);
}
Network() {

View File

@ -39,6 +39,7 @@ public abstract class NewInstance {
@AutoValue
abstract static class NetworkInterface {
abstract URI network();
@Nullable abstract URI subnetwork();
abstract List<AccessConfig> accessConfigs();
@ -46,9 +47,19 @@ public abstract class NewInstance {
return create(network, Arrays.asList(AccessConfig.create(null, Type.ONE_TO_ONE_NAT, null)));
}
static NetworkInterface create(URI network, URI subnetwork) {
return create(network, subnetwork,
Arrays.asList(AccessConfig.create(null, Type.ONE_TO_ONE_NAT, null)));
}
@SerializedNames({ "network", "accessConfigs" })
static NetworkInterface create(URI network, List<AccessConfig> accessConfigs) {
return new AutoValue_NewInstance_NetworkInterface(network, accessConfigs);
return new AutoValue_NewInstance_NetworkInterface(network, null, accessConfigs);
}
@SerializedNames({ "network", "subnetwork", "accessConfigs" })
static NetworkInterface create(URI network, URI subnetwork, List<AccessConfig> accessConfigs) {
return new AutoValue_NewInstance_NetworkInterface(network, subnetwork, accessConfigs);
}
NetworkInterface() {
@ -81,8 +92,18 @@ 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, URI subnetwork, URI sourceImage) {
return create(name, machineType, network, subnetwork, 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) {
return create(name, machineType, network, null, disks, description, tags);
}
public static NewInstance create(String name, URI machineType, URI network, @Nullable URI subnetwork,
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) {
@ -127,6 +148,14 @@ public abstract class NewInstance {
this.disks = disks;
}
public Builder(String name, URI machineType, URI network, URI subnetwork, List<AttachDisk> disks) {
checkNotNull(name, "NewInstance name cannot be null");
this.name = name;
this.machineType = machineType;
this.networkInterfaces = ImmutableList.of(NetworkInterface.create(network, subnetwork));
this.disks = disks;
}
public Builder(String name, URI machineType, URI network, URI sourceImage) {
checkNotNull(name, "NewInstance name cannot be null");
this.name = name;
@ -135,6 +164,14 @@ public abstract class NewInstance {
this.disks = Arrays.asList(AttachDisk.newBootDisk(sourceImage));
}
public Builder(String name, URI machineType, URI network, URI subnetwork, URI sourceImage) {
checkNotNull(name, "NewInstance name cannot be null");
this.name = name;
this.machineType = machineType;
this.networkInterfaces = ImmutableList.of(NetworkInterface.create(network, subnetwork));
this.disks = Arrays.asList(AttachDisk.newBootDisk(sourceImage));
}
public Builder canIpForward(Boolean canIpForward){
this.canIpForward = canIpForward;
return this;

View File

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.domain;
import java.net.URI;
import java.util.Date;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
/**
* Represents a network used to enable instance communication.
*/
@AutoValue
public abstract class Subnetwork {
public abstract String id();
public abstract Date creationTimestamp();
public abstract URI selfLink();
public abstract String name();
@Nullable public abstract String description();
public abstract String gatewayAddress();
public abstract URI network();
public abstract String ipCidrRange();
public abstract URI region();
@SerializedNames({ "id", "creationTimestamp", "selfLink", "name",
"description", "gatewayAddress", "network", "ipCidrRange", "region" })
public static Subnetwork create(String id, Date creationTimestamp, URI selfLink, String name,
String description, String gatewayAddress, URI network,
String ipCidrRange, URI region) {
return new AutoValue_Subnetwork(id, creationTimestamp, selfLink, name, description,
gatewayAddress, network, ipCidrRange, region);
}
Subnetwork() {
}
}

View File

@ -36,6 +36,7 @@ import org.jclouds.googlecomputeengine.domain.ForwardingRule;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.MachineType;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.googlecomputeengine.domain.TargetInstance;
import org.jclouds.googlecomputeengine.domain.TargetPool;
import org.jclouds.googlecomputeengine.internal.BaseToIteratorOfListPage;
@ -498,4 +499,53 @@ public interface AggregatedListApi {
};
}
}
/**
* 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 pageToken
* marks the beginning of the next list page
* @param listOptions
* listing options
* @return a page of the list
*/
@Named("Subnetworks:aggregatedList")
@GET
@Path("/subnetworks")
ListPage<Subnetwork> pageOfSubnetworks(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions);
/** @see #pageOfSubnetworks(String, ListOptions) */
@Named("Subnetworks:aggregatedList")
@GET
@Path("/subnetworks")
@Transform(SubnetworksPages.class)
Iterator<ListPage<Subnetwork>> subnetworks();
/** @see #pageOfSubnetworks(String, ListOptions) */
@Named("Subnetworks:aggregatedList")
@GET
@Path("/subnetworks")
@Transform(SubnetworksPages.class)
Iterator<ListPage<Subnetwork>> subnetworks(ListOptions options);
static final class SubnetworksPages extends BaseToIteratorOfListPage<Subnetwork, SubnetworksPages> {
private final GoogleComputeEngineApi api;
@Inject
SubnetworksPages(GoogleComputeEngineApi api) {
this.api = api;
}
@Override
protected Function<String, ListPage<Subnetwork>> fetchNextPage(final ListOptions options) {
return new Function<String, ListPage<Subnetwork>>() {
@Override
public ListPage<Subnetwork> apply(String pageToken) {
return api.aggregatedList().pageOfSubnetworks(pageToken, options);
}
};
}
}
}

View File

@ -83,9 +83,7 @@ public interface NetworkApi {
/**
* Creates a persistent network resource in the specified project with the specified range and specified gateway.
*
* @param networkName the network name
* @param IPv4Range the range of the network to be inserted.
* @param gatewayIPv4 the range of the network to be inserted.
* @param options the options to create the network.
* @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.
*/
@ -126,7 +124,7 @@ public interface NetworkApi {
@Transform(NetworkPages.class)
Iterator<ListPage<Network>> list(ListOptions options);
static final class NetworkPages extends BaseToIteratorOfListPage<Network, NetworkPages> {
final class NetworkPages extends BaseToIteratorOfListPage<Network, NetworkPages> {
private final GoogleComputeEngineApi api;

View File

@ -0,0 +1,127 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.features;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.net.URI;
import java.util.Iterator;
import javax.inject.Inject;
import javax.inject.Named;
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 org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.googlecomputeengine.internal.BaseCallerArg0ToIteratorOfListPage;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.googlecomputeengine.options.SubnetworkCreationOptions;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.oauth.v2.filters.OAuthFilter;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
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.SkipEncoding;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.base.Function;
@SkipEncoding({'/', '='})
@RequestFilters(OAuthFilter.class)
@Path("/subnetworks")
@Consumes(APPLICATION_JSON)
public interface SubnetworkApi {
/**
* Returns a network by name or null if not found.
*/
@Named("Subnetworks:get")
@GET
@Path("/{subnetwork}")
@Fallback(NullOnNotFoundOr404.class)
Subnetwork get(@PathParam("subnetwork") String subnetworkName);
/**
* Creates a persistent network resource in the specified project with the specified range and specified gateway.
*
* @param newSubnetwork definition of the subnetwork.
* @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.
*/
@Named("Subnetworks:insert")
@POST
@Produces(APPLICATION_JSON)
Operation createInNetwork(@BinderParam(BindToJsonPayload.class) SubnetworkCreationOptions newSubnetwork);
/** Deletes a network by name and returns the operation in progress, or null if not found. */
@Named("Subnetworks:delete")
@DELETE
@Path("/{subnetwork}")
@Fallback(NullOnNotFoundOr404.class)
Operation delete(@PathParam("subnetwork") String subnetworkName);
/**
* Retrieves the list of network 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 pageToken marks the beginning of the next list page
* @param listOptions listing options
* @return a page of the list
*/
@Named("Subnetworks:list")
@GET
ListPage<Subnetwork> listPage(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions);
/** @see #listPage(String, ListOptions) */
@Named("Subnetworks:list")
@GET
@Transform(SubnetworkPages.class)
Iterator<ListPage<Subnetwork>> list();
static final class SubnetworkPages extends BaseCallerArg0ToIteratorOfListPage<Subnetwork, SubnetworkPages> {
private final GoogleComputeEngineApi api;
@Inject SubnetworkPages(GoogleComputeEngineApi api) {
this.api = api;
}
@Override protected Function<String, ListPage<Subnetwork>> fetchNextPage(final String region, final ListOptions options) {
return new Function<String, ListPage<Subnetwork>>() {
@Override public ListPage<Subnetwork> apply(String pageToken) {
return api.subnetworksInRegion(region).listPage(pageToken, options);
}
};
}
}
}

View File

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
/**
* Represents a subnetwork used to enable instance communication.
*/
@AutoValue
public abstract class SubnetworkCreationOptions {
public abstract String name();
@Nullable public abstract String description();
public abstract URI network();
public abstract String ipCidrRange();
public abstract URI region();
@SerializedNames({ "name", "description", "network", "ipCidrRange", "region" })
public static SubnetworkCreationOptions create(String name, String description, URI network,
String ipCidrRange, URI region) {
return new AutoValue_SubnetworkCreationOptions(name, description, network, ipCidrRange, region);
}
SubnetworkCreationOptions() {
}
}

View File

@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import java.net.URI;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiMockTest;
import org.jclouds.googlecomputeengine.options.SubnetworkCreationOptions;
import org.jclouds.googlecomputeengine.parse.ParseSubnetworkListTest;
import org.jclouds.googlecomputeengine.parse.ParseSubnetworkTest;
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "SubnetworkApiMockTest", singleThreaded = true)
public class SubnetworkApiMockTest extends BaseGoogleComputeEngineApiMockTest {
public void get() throws Exception {
server.enqueue(jsonResponse("/subnetwork_get.json"));
assertEquals(subnetworkApi().get("jclouds-test"),
new ParseSubnetworkTest().expected(url("/projects")));
assertSent(server, "GET", "/projects/party/regions/someregion/subnetworks/jclouds-test");
}
public void get_4xx() throws Exception {
server.enqueue(response404());
assertNull(subnetworkApi().get("jclouds-test"));
assertSent(server, "GET", "/projects/party/regions/someregion/subnetworks/jclouds-test");
}
public void insert() throws Exception {
server.enqueue(jsonResponse("/operation.json"));
assertEquals(subnetworkApi().createInNetwork(SubnetworkCreationOptions.create(
"jclouds-test",
"my subnetwork",
URI.create(url("/projects/party/global/networks/mynetwork")),
"10.0.0.0/24",
URI.create(url("/projects/party/regions/someregion")))), new ParseOperationTest().expected(url("/projects")));
assertSent(server, "POST", "/projects/party/regions/someregion/subnetworks",
stringFromResource("/subnetwork_insert.json"));
}
public void delete() throws Exception {
server.enqueue(jsonResponse("/operation.json"));
assertEquals(subnetworkApi().delete("jclouds-test"),
new ParseOperationTest().expected(url("/projects")));
assertSent(server, "DELETE", "/projects/party/regions/someregion/subnetworks/jclouds-test");
}
public void delete_4xx() throws Exception {
server.enqueue(response404());
assertNull(subnetworkApi().delete("jclouds-test"));
assertSent(server, "DELETE", "/projects/party/regions/someregion/subnetworks/jclouds-test");
}
public void list() throws Exception {
server.enqueue(jsonResponse("/subnetwork_list.json"));
assertEquals(subnetworkApi().list().next(), new ParseSubnetworkListTest().expected(url("/projects")));
assertSent(server, "GET", "/projects/party/regions/someregion/subnetworks");
}
public void list_empty() throws Exception {
server.enqueue(jsonResponse("/list_empty.json"));
assertFalse(subnetworkApi().list().hasNext());
assertSent(server, "GET", "/projects/party/regions/someregion/subnetworks");
}
SubnetworkApi subnetworkApi() {
return api().subnetworksInRegion("someregion");
}
}

View File

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.parse;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import javax.ws.rs.Consumes;
import org.jclouds.googlecloud.domain.ForwardingListPage;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@Test(groups = "unit", testName = "ParseSubnetworkListTest")
public class ParseSubnetworkListTest extends BaseGoogleComputeEngineParseTest<ListPage<Subnetwork>> {
@Override
public String resource() {
return "/network_list.json";
}
@Override @Consumes(APPLICATION_JSON)
public ListPage<Subnetwork> expected() {
return expected(BASE_URL);
}
@Consumes(APPLICATION_JSON)
public ListPage<Subnetwork> expected(String baseUrl) {
return ForwardingListPage.create( //
ImmutableList.of(new ParseSubnetworkTest().expected(baseUrl)), // items
null // nextPageToken
);
}
}

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.googlecomputeengine.parse;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.net.URI;
import javax.ws.rs.Consumes;
import org.jclouds.googlecomputeengine.domain.Subnetwork;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "ParseSubnetworkTest")
public class ParseSubnetworkTest extends BaseGoogleComputeEngineParseTest<Subnetwork> {
@Override
public String resource() {
return "/network_get.json";
}
@Override @Consumes(APPLICATION_JSON)
public Subnetwork expected() {
return expected(BASE_URL);
}
@Consumes(APPLICATION_JSON)
public Subnetwork expected(String baseUrl) {
return Subnetwork.create( //
"5850679262666457680", // id
parse("2016-06-07T14:29:35.476-07:00"), // creationTimestamp
URI.create(baseUrl + "/party/regions/someregion/subnetworks/jclouds-test"), // selfLink
"jclouds-subnetwork-test", // name
"A custom subnetwork for the project", // description
"10.128.0.1",
URI.create(baseUrl + "/party/global/networks/mynetwork"), // network
"10.128.0.0/20", // rangeIPv4
URI.create(baseUrl + "/party/regions/someregion") // region
);
}
}

View File

@ -0,0 +1,12 @@
{
"kind": "compute#subnetwork",
"id": "5850679262666457680",
"creationTimestamp": "2016-06-07T14:29:35.476-07:00",
"gatewayAddress": "10.128.0.1",
"name": "jclouds-subnetwork-test",
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/mynetwork",
"ipCidrRange": "10.128.0.0/20",
"region": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion",
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion/subnetworks/jclouds-test",
"description": "A custom subnetwork for the project"
}

View File

@ -0,0 +1,7 @@
{
"name": "jclouds-test",
"description": "my subnetwork",
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/mynetwork",
"ipCidrRange": "10.0.0.0/24",
"region": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion"
}

View File

@ -0,0 +1,19 @@
{
"kind": "compute#networkList",
"id": "projects/party/networks",
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion/subnetworks",
"items": [
{
"kind": "compute#subnetwork",
"id": "5850679262666457680",
"creationTimestamp": "2016-06-07T14:29:35.476-07:00",
"gatewayAddress": "10.128.0.1",
"name": "jclouds-subnetwork-test",
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/mynetwork",
"ipCidrRange": "10.128.0.0/20",
"region": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion",
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/regions/someregion/subnetworks/jclouds-test",
"description": "A custom subnetwork for the project"
}
]
}