mirror of https://github.com/apache/jclouds.git
Removing network management, use default network, use fewer firewalls.
This commit is contained in:
parent
9d3b2d70e1
commit
5adfce8d48
|
@ -58,7 +58,6 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||||
import org.jclouds.googlecomputeengine.features.FirewallApi;
|
import org.jclouds.googlecomputeengine.features.FirewallApi;
|
||||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||||
|
@ -125,36 +124,26 @@ public final class GoogleComputeEngineService extends BaseComputeService {
|
||||||
protected synchronized void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
|
protected synchronized void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
|
||||||
Set<String> orphanedGroups = findOrphanedGroups.apply(deadNodes);
|
Set<String> orphanedGroups = findOrphanedGroups.apply(deadNodes);
|
||||||
for (String orphanedGroup : orphanedGroups) {
|
for (String orphanedGroup : orphanedGroups) {
|
||||||
cleanUpNetworksAndFirewallsForGroup(orphanedGroup);
|
cleanUpFirewallsForGroup(orphanedGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUpNetworksAndFirewallsForGroup(final String groupName) {
|
private void cleanUpFirewallsForGroup(final String groupName) {
|
||||||
String resourceName = namingConvention.create().sharedNameForGroup(groupName);
|
GroupNamingConvention namingScheme = namingConvention.create();
|
||||||
Network network = api.networks().get(resourceName);
|
|
||||||
FirewallApi firewallApi = api.firewalls();
|
FirewallApi firewallApi = api.firewalls();
|
||||||
|
|
||||||
for (Firewall firewall : concat(firewallApi.list())) {
|
for (Firewall firewall : concat(firewallApi.list())) {
|
||||||
if (firewall == null || !firewall.network().equals(network.selfLink())) {
|
String foundGroup = namingScheme.groupInUniqueNameOrNull(firewall.name());
|
||||||
continue;
|
if ((foundGroup != null) && foundGroup.equals(groupName)){
|
||||||
|
AtomicReference<Operation> operation = Atomics.newReference(firewallApi.delete(firewall.name()));
|
||||||
|
operationDone.apply(operation);
|
||||||
|
|
||||||
|
if (operation.get().httpErrorStatusCode() != null) {
|
||||||
|
logger.warn("delete orphaned firewall %s failed. Http Error Code: %d HttpError: %s",
|
||||||
|
operation.get().targetId(), operation.get().httpErrorStatusCode(),
|
||||||
|
operation.get().httpErrorMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AtomicReference<Operation> operation = Atomics.newReference(firewallApi.delete(firewall.name()));
|
|
||||||
operationDone.apply(operation);
|
|
||||||
|
|
||||||
if (operation.get().httpErrorStatusCode() != null) {
|
|
||||||
logger.warn("delete orphaned firewall %s failed. Http Error Code: %d HttpError: %s",
|
|
||||||
operation.get().targetId(), operation.get().httpErrorStatusCode(),
|
|
||||||
operation.get().httpErrorMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicReference<Operation> operation = Atomics.newReference(api.networks().delete(resourceName));
|
|
||||||
|
|
||||||
operationDone.apply(operation);
|
|
||||||
|
|
||||||
if (operation.get().httpErrorStatusCode() != null) {
|
|
||||||
logger.warn("delete orphaned network failed. Http Error Code: " + operation.get().httpErrorStatusCode() +
|
|
||||||
" HttpError: " + operation.get().httpErrorMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,10 @@ import static com.google.common.collect.Lists.newArrayList;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static org.jclouds.googlecloud.internal.ListPages.concat;
|
import static org.jclouds.googlecloud.internal.ListPages.concat;
|
||||||
import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.IMAGE_PROJECTS;
|
import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.IMAGE_PROJECTS;
|
||||||
|
import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.simplifyPorts;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
@ -111,26 +113,35 @@ public final class GoogleComputeEngineServiceAdapter
|
||||||
@Override public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(String group, String name,
|
@Override public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(String group, String name,
|
||||||
Template template) {
|
Template template) {
|
||||||
GoogleComputeEngineTemplateOptions options = GoogleComputeEngineTemplateOptions.class.cast(template.getOptions());
|
GoogleComputeEngineTemplateOptions options = GoogleComputeEngineTemplateOptions.class.cast(template.getOptions());
|
||||||
checkNotNull(options.network(), "template options must specify a network");
|
|
||||||
|
checkNotNull(options.getNetworks(), "template options must specify a network");
|
||||||
checkNotNull(template.getHardware().getUri(), "hardware must have a URI");
|
checkNotNull(template.getHardware().getUri(), "hardware must have a URI");
|
||||||
checkNotNull(template.getImage().getUri(), "image URI is null");
|
checkNotNull(template.getImage().getUri(), "image URI is null");
|
||||||
|
|
||||||
List<AttachDisk> disks = Lists.newArrayList();
|
List<AttachDisk> disks = Lists.newArrayList();
|
||||||
disks.add(AttachDisk.newBootDisk(template.getImage().getUri()));
|
disks.add(AttachDisk.newBootDisk(template.getImage().getUri()));
|
||||||
|
|
||||||
|
Iterator<String> networks = options.getNetworks().iterator();
|
||||||
|
|
||||||
|
URI network = URI.create(networks.next());
|
||||||
|
assert !networks.hasNext() : "Error: Options should specify only one network";
|
||||||
|
|
||||||
NewInstance newInstance = NewInstance.create(
|
NewInstance newInstance = NewInstance.create(
|
||||||
name, // name
|
name, // name
|
||||||
template.getHardware().getUri(), // machineType
|
template.getHardware().getUri(), // machineType
|
||||||
options.network(), // network
|
network, // network
|
||||||
disks, // disks
|
disks, // disks
|
||||||
group // description
|
group // description
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add tags from template and for security groups
|
// Add tags from template
|
||||||
newInstance.tags().items().addAll(options.getTags());
|
newInstance.tags().items().addAll(options.getTags());
|
||||||
|
|
||||||
|
// Add tags for firewalls
|
||||||
FirewallTagNamingConvention naming = firewallTagNamingConvention.get(group);
|
FirewallTagNamingConvention naming = firewallTagNamingConvention.get(group);
|
||||||
for (int port : options.getInboundPorts()) {
|
List<String> ports = simplifyPorts(options.getInboundPorts());
|
||||||
newInstance.tags().items().add(naming.name(port));
|
if (ports != null){
|
||||||
|
newInstance.tags().items().add(naming.name(ports));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add metadata from template and for ssh key and image id
|
// Add metadata from template and for ssh key and image id
|
||||||
|
|
|
@ -45,9 +45,6 @@ import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
|
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
|
||||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
|
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.CreateNetworkIfNeeded;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.FindNetworkOrCreate;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
|
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
|
import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.InstanceToNodeMetadata;
|
import org.jclouds.googlecomputeengine.compute.functions.InstanceToNodeMetadata;
|
||||||
|
@ -62,7 +59,6 @@ import org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEnco
|
||||||
import org.jclouds.googlecomputeengine.domain.Image;
|
import org.jclouds.googlecomputeengine.domain.Image;
|
||||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
import org.jclouds.location.suppliers.implicit.FirstZone;
|
import org.jclouds.location.suppliers.implicit.FirstZone;
|
||||||
|
@ -72,9 +68,6 @@ import com.google.common.base.Functions;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -121,12 +114,6 @@ public final class GoogleComputeEngineServiceContextModule
|
||||||
bind(new TypeLiteral<Predicate<String>>() {
|
bind(new TypeLiteral<Predicate<String>>() {
|
||||||
}).to(AllNodesInGroupTerminated.class);
|
}).to(AllNodesInGroupTerminated.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<Function<NetworkAndAddressRange, Network>>() {
|
|
||||||
}).to(CreateNetworkIfNeeded.class);
|
|
||||||
|
|
||||||
bind(new TypeLiteral<CacheLoader<NetworkAndAddressRange, Network>>() {
|
|
||||||
}).to(FindNetworkOrCreate.class);
|
|
||||||
|
|
||||||
bind(FirewallTagNamingConvention.Factory.class).in(Scopes.SINGLETON);
|
bind(FirewallTagNamingConvention.Factory.class).in(Scopes.SINGLETON);
|
||||||
bindHttpApi(binder(), Resources.class);
|
bindHttpApi(binder(), Resources.class);
|
||||||
}
|
}
|
||||||
|
@ -173,11 +160,6 @@ public final class GoogleComputeEngineServiceContextModule
|
||||||
}, seconds, SECONDS);
|
}, seconds, SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Singleton
|
|
||||||
LoadingCache<NetworkAndAddressRange, Network> networkMap(CacheLoader<NetworkAndAddressRange, Network> in) {
|
|
||||||
return CacheBuilder.newBuilder().build(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
@Override protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.domain;
|
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.json.SerializedNames;
|
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
|
||||||
|
|
||||||
/** Container for network, IPv4 range and optional gateway, for creation caching */
|
|
||||||
@AutoValue
|
|
||||||
public abstract class NetworkAndAddressRange {
|
|
||||||
|
|
||||||
public abstract String name();
|
|
||||||
|
|
||||||
public abstract String rangeIPv4();
|
|
||||||
|
|
||||||
@Nullable public abstract String gateway();
|
|
||||||
|
|
||||||
@SerializedNames({ "name", "ipV4Range", "gateway" })
|
|
||||||
public static NetworkAndAddressRange create(String name, String rangeIPv4, @Nullable String gateway) {
|
|
||||||
return new AutoValue_NetworkAndAddressRange(name, rangeIPv4, gateway);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkAndAddressRange() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.functions;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
|
||||||
import org.jclouds.googlecomputeengine.options.NetworkCreationOptions;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.util.concurrent.Atomics;
|
|
||||||
|
|
||||||
public final class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
|
|
||||||
private final GoogleComputeEngineApi api;
|
|
||||||
private final Predicate<AtomicReference<Operation>> operationDone;
|
|
||||||
|
|
||||||
@Inject CreateNetworkIfNeeded(GoogleComputeEngineApi api, Predicate<AtomicReference<Operation>> operationDone) {
|
|
||||||
this.api = api;
|
|
||||||
this.operationDone = operationDone;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Network apply(NetworkAndAddressRange input) {
|
|
||||||
checkNotNull(input, "input");
|
|
||||||
|
|
||||||
Network nw = api.networks().get(input.name());
|
|
||||||
if (nw != null) {
|
|
||||||
return nw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.gateway() != null) {
|
|
||||||
NetworkCreationOptions options = new NetworkCreationOptions.Builder(input.name(), input.rangeIPv4())
|
|
||||||
.gatewayIPv4(input.gateway()).build();
|
|
||||||
AtomicReference<Operation> operation = Atomics.newReference(api.networks()
|
|
||||||
.createInIPv4Range(options));
|
|
||||||
operationDone.apply(operation);
|
|
||||||
|
|
||||||
checkState(operation.get().httpErrorStatusCode() == null,
|
|
||||||
"Could not insert network, operation failed" + operation);
|
|
||||||
} else {
|
|
||||||
AtomicReference<Operation> operation = Atomics
|
|
||||||
.newReference(api.networks().createInIPv4Range(input.name(), input.rangeIPv4()));
|
|
||||||
operationDone.apply(operation);
|
|
||||||
|
|
||||||
checkState(operation.get().httpErrorStatusCode() == null,
|
|
||||||
"Could not insert network, operation failed" + operation);
|
|
||||||
}
|
|
||||||
return checkNotNull(api.networks().get(input.name()), "no network with name %s was found",
|
|
||||||
input.name());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.functions;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
|
|
||||||
public final class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
|
|
||||||
private final GoogleComputeEngineApi api;
|
|
||||||
private final Function<NetworkAndAddressRange, Network> networkCreator;
|
|
||||||
|
|
||||||
@Inject FindNetworkOrCreate(GoogleComputeEngineApi api, Function<NetworkAndAddressRange, Network> networkCreator) {
|
|
||||||
this.api = api;
|
|
||||||
this.networkCreator = networkCreator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Network load(NetworkAndAddressRange in) {
|
|
||||||
Network network = api.networks().get(in.name());
|
|
||||||
if (network != null) {
|
|
||||||
return network;
|
|
||||||
} else {
|
|
||||||
return networkCreator.apply(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.googlecomputeengine.compute.functions;
|
package org.jclouds.googlecomputeengine.compute.functions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||||
|
@ -46,10 +48,18 @@ public final class FirewallTagNamingConvention {
|
||||||
this.sharedResourceName = sharedResourceName;
|
this.sharedResourceName = sharedResourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String name(int port) {
|
public String name(List<String> ports) {
|
||||||
return String.format("%s-port-%s", sharedResourceName, port);
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
for (String s : ports){
|
||||||
|
result = result * prime + s.hashCode();
|
||||||
|
// TODO(broudy): this may break between java versions! Consider a different implementation.
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format("%s-%s", sharedResourceName, Integer.toHexString(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Predicate<String> isFirewallTag() {
|
public Predicate<String> isFirewallTag() {
|
||||||
return new Predicate<String>() {
|
return new Predicate<String>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -89,7 +89,6 @@ public final class InstanceToNodeMetadata implements Function<Instance, NodeMeta
|
||||||
URI bootImage = diskToSourceImage.get(input.disks().get(0).source());
|
URI bootImage = diskToSourceImage.get(input.disks().get(0).source());
|
||||||
|
|
||||||
builder.id(input.selfLink().toString())
|
builder.id(input.selfLink().toString())
|
||||||
.providerId(input.id())
|
|
||||||
.name(input.name())
|
.name(input.name())
|
||||||
.providerId(input.id())
|
.providerId(input.id())
|
||||||
.hostname(input.name())
|
.hostname(input.name())
|
||||||
|
|
|
@ -16,18 +16,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.googlecomputeengine.compute.options;
|
package org.jclouds.googlecomputeengine.compute.options;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
/** Instance options specific to Google Compute Engine. */
|
/** Instance options specific to Google Compute Engine. */
|
||||||
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||||
|
|
||||||
private URI network = null;
|
|
||||||
private boolean autoCreateKeyPair = true;
|
private boolean autoCreateKeyPair = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,22 +39,10 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||||
super.copyTo(to);
|
super.copyTo(to);
|
||||||
if (to instanceof GoogleComputeEngineTemplateOptions) {
|
if (to instanceof GoogleComputeEngineTemplateOptions) {
|
||||||
GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
|
GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
|
||||||
eTo.network(network());
|
|
||||||
eTo.autoCreateKeyPair(autoCreateKeyPair());
|
eTo.autoCreateKeyPair(autoCreateKeyPair());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see #network() */
|
|
||||||
public GoogleComputeEngineTemplateOptions network(URI network) {
|
|
||||||
this.network = network;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The network instances will attach to. When absent, a new network will be created for the project. */
|
|
||||||
@Nullable public URI network() {
|
|
||||||
return network;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether an SSH key pair should be created automatically.
|
* Sets whether an SSH key pair should be created automatically.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.googlecomputeengine.compute.strategy;
|
package org.jclouds.googlecomputeengine.compute.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static com.google.common.collect.ImmutableList.of;
|
import static com.google.common.collect.ImmutableList.of;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -39,7 +42,6 @@ import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
|
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
|
||||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||||
|
@ -53,9 +55,8 @@ import org.jclouds.ssh.SshKeyPairGenerator;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.util.concurrent.Atomics;
|
import com.google.common.util.concurrent.Atomics;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
@ -67,8 +68,9 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
||||||
public static final String EXTERIOR_RANGE = "0.0.0.0/0";
|
public static final String EXTERIOR_RANGE = "0.0.0.0/0";
|
||||||
public static final String DEFAULT_INTERNAL_NETWORK_RANGE = "10.0.0.0/8";
|
public static final String DEFAULT_INTERNAL_NETWORK_RANGE = "10.0.0.0/8";
|
||||||
|
|
||||||
|
public static final String DEFAULT_NETWORK_NAME = "default";
|
||||||
|
|
||||||
private final GoogleComputeEngineApi api;
|
private final GoogleComputeEngineApi api;
|
||||||
private final LoadingCache<NetworkAndAddressRange, Network> networkMap;
|
|
||||||
private final Predicate<AtomicReference<Operation>> operationDone;
|
private final Predicate<AtomicReference<Operation>> operationDone;
|
||||||
private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
|
private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
|
||||||
private final SshKeyPairGenerator keyGenerator;
|
private final SshKeyPairGenerator keyGenerator;
|
||||||
|
@ -85,13 +87,11 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||||
GoogleComputeEngineApi api, Predicate<AtomicReference<Operation>> operationDone,
|
GoogleComputeEngineApi api, Predicate<AtomicReference<Operation>> operationDone,
|
||||||
LoadingCache<NetworkAndAddressRange, Network> networkMap,
|
|
||||||
FirewallTagNamingConvention.Factory firewallTagNamingConvention, SshKeyPairGenerator keyGenerator) {
|
FirewallTagNamingConvention.Factory firewallTagNamingConvention, SshKeyPairGenerator keyGenerator) {
|
||||||
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
|
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
|
||||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.operationDone = operationDone;
|
this.operationDone = operationDone;
|
||||||
this.networkMap = networkMap;
|
|
||||||
this.firewallTagNamingConvention = firewallTagNamingConvention;
|
this.firewallTagNamingConvention = firewallTagNamingConvention;
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
}
|
}
|
||||||
|
@ -101,17 +101,16 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
||||||
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
||||||
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
|
|
||||||
String sharedResourceName = namingConvention.create().sharedNameForGroup(group);
|
Template mutableTemplate = template.clone();
|
||||||
Template mutableTemplate = template.clone();
|
|
||||||
GoogleComputeEngineTemplateOptions templateOptions = GoogleComputeEngineTemplateOptions.class
|
GoogleComputeEngineTemplateOptions templateOptions = GoogleComputeEngineTemplateOptions.class
|
||||||
.cast(mutableTemplate.getOptions());
|
.cast(mutableTemplate.getOptions());
|
||||||
assert template.getOptions().equals(templateOptions) : "options didn't clone properly";
|
assert template.getOptions().equals(templateOptions) : "options didn't clone properly";
|
||||||
|
|
||||||
// get or insert the network and insert a firewall with the users
|
// Get Network
|
||||||
// configuration
|
Network network = getNetwork(templateOptions.getNetworks());
|
||||||
Network network = getOrCreateNetwork(templateOptions, sharedResourceName);
|
// Setup Firewall rules
|
||||||
getOrCreateFirewalls(templateOptions, network, firewallTagNamingConvention.get(group));
|
getOrCreateFirewalls(templateOptions, network, firewallTagNamingConvention.get(group));
|
||||||
templateOptions.network(network.selfLink());
|
templateOptions.networks(ImmutableSet.of(network.selfLink().toString()));
|
||||||
templateOptions.userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, group);
|
templateOptions.userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, group);
|
||||||
|
|
||||||
// Configure the default credentials, if needed
|
// Configure the default credentials, if needed
|
||||||
|
@ -131,12 +130,22 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try and find a network either previously created by jclouds or user
|
* Try and find a network previously created by the user.
|
||||||
* defined.
|
|
||||||
*/
|
*/
|
||||||
private Network getOrCreateNetwork(GoogleComputeEngineTemplateOptions templateOptions, String sharedResourceName) {
|
private Network getNetwork(Set<String> networks) {
|
||||||
String networkName = templateOptions.network() != null ? toName(templateOptions.network()) : sharedResourceName;
|
String networkName;
|
||||||
return networkMap.getUnchecked(NetworkAndAddressRange.create(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
|
if (networks == null || networks.isEmpty()){
|
||||||
|
networkName = DEFAULT_NETWORK_NAME;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Iterator<String> iterator = networks.iterator();
|
||||||
|
networkName = nameFromNetworkString(iterator.next());
|
||||||
|
checkArgument(!iterator.hasNext(), "Error: Please specify only one network in TemplateOptions when using GCE.");
|
||||||
|
|
||||||
|
}
|
||||||
|
Network network = api.networks().get(networkName);
|
||||||
|
checkArgument(network != null, "Error: no network with name %s was found", networkName);
|
||||||
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,32 +164,70 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
||||||
FirewallTagNamingConvention naming) {
|
FirewallTagNamingConvention naming) {
|
||||||
|
|
||||||
FirewallApi firewallApi = api.firewalls();
|
FirewallApi firewallApi = api.firewalls();
|
||||||
List<AtomicReference<Operation>> operations = Lists.newArrayList();
|
int[] inboundPorts = templateOptions.getInboundPorts();
|
||||||
|
if ((inboundPorts == null) || inboundPorts.length == 0){
|
||||||
for (Integer port : templateOptions.getInboundPorts()) {
|
return;
|
||||||
String name = naming.name(port);
|
|
||||||
Firewall firewall = firewallApi.get(name);
|
|
||||||
if (firewall == null) {
|
|
||||||
List<String> ports = ImmutableList.of(String.valueOf(port));
|
|
||||||
List<Rule> rules = ImmutableList.of(Rule.create("tcp", ports), Rule.create("udp", ports));
|
|
||||||
FirewallOptions firewallOptions = new FirewallOptions().name(name).network(network.selfLink())
|
|
||||||
.allowedRules(rules).sourceTags(templateOptions.getTags())
|
|
||||||
.sourceRanges(of(DEFAULT_INTERNAL_NETWORK_RANGE, EXTERIOR_RANGE)).targetTags(ImmutableList.of(name));
|
|
||||||
AtomicReference<Operation> operation = Atomics.newReference(firewallApi.createInNetwork(
|
|
||||||
firewallOptions.name(), network.selfLink(), firewallOptions));
|
|
||||||
operations.add(operation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AtomicReference<Operation> operation : operations) {
|
List<String> ports = simplifyPorts(inboundPorts);
|
||||||
|
String name = naming.name(ports);
|
||||||
|
Firewall firewall = firewallApi.get(name);
|
||||||
|
AtomicReference<Operation> operation = null;
|
||||||
|
if (firewall == null) {
|
||||||
|
List<Rule> rules = ImmutableList.of(Rule.create("tcp", ports), Rule.create("udp", ports));
|
||||||
|
FirewallOptions firewallOptions = new FirewallOptions().name(name).network(network.selfLink())
|
||||||
|
.allowedRules(rules).sourceTags(templateOptions.getTags())
|
||||||
|
.sourceRanges(of(DEFAULT_INTERNAL_NETWORK_RANGE, EXTERIOR_RANGE))
|
||||||
|
.targetTags(ImmutableList.of(name));
|
||||||
|
|
||||||
|
operation = Atomics.newReference(firewallApi
|
||||||
|
.createInNetwork(firewallOptions.name(), network.selfLink(), firewallOptions));
|
||||||
|
|
||||||
operationDone.apply(operation);
|
operationDone.apply(operation);
|
||||||
checkState(operation.get().httpErrorStatusCode() == null, "Could not insert firewall, operation failed %s",
|
checkState(operation.get().httpErrorStatusCode() == null, "Could not insert firewall, operation failed %s",
|
||||||
operation);
|
operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toName(URI link) {
|
// Helper function for simplifying an array of ports to a list of ranges FirewallOptions expects.
|
||||||
String path = link.getPath();
|
public static List<String> simplifyPorts(int[] ports){
|
||||||
return path.substring(path.lastIndexOf('/') + 1);
|
if ((ports == null) || (ports.length == 0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ArrayList<String> output = new ArrayList<String>();
|
||||||
|
Arrays.sort(ports);
|
||||||
|
|
||||||
|
int range_start = ports[0];
|
||||||
|
int range_end = ports[0];
|
||||||
|
for (int i = 1; i < ports.length; i++) {
|
||||||
|
if ((ports[i - 1] == ports[i] - 1) || (ports[i - 1] == ports[i])){
|
||||||
|
// Range continues.
|
||||||
|
range_end = ports[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Range ends.
|
||||||
|
output.add(formatRange(range_start, range_end));
|
||||||
|
range_start = ports[i];
|
||||||
|
range_end = ports[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make sure we get the last range.
|
||||||
|
output.add(formatRange(range_start, range_end));
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for simplifyPorts. Formats port range strings.
|
||||||
|
private static String formatRange(int start, int finish){
|
||||||
|
if (start == finish){
|
||||||
|
return Integer.toString(start);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return String.format("%s-%s", Integer.toString(start), Integer.toString(finish));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for getting the network name from the full URI.
|
||||||
|
public static String nameFromNetworkString(String networkString) {
|
||||||
|
return networkString.substring(networkString.lastIndexOf('/') + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -113,4 +114,12 @@ public class GoogleComputeEngineServiceLiveTest extends BaseComputeServiceLiveTe
|
||||||
protected Module getSshModule() {
|
protected Module getSshModule() {
|
||||||
return new SshjSshClientModule();
|
return new SshjSshClientModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet<String> tags) {
|
||||||
|
Set<String> nodeTags = node.getTags();
|
||||||
|
for (String tag : tags){
|
||||||
|
assert nodeTags.contains(tag) : String.format("node tags did not match %s %s node:", tags, nodeTags, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,39 +73,34 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
||||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void networksAndFirewallDeletedWhenAllGroupNodesAreTerminated() throws IOException, InterruptedException {
|
public void firewallDeletedWhenAllGroupNodesAreTerminated() throws IOException, InterruptedException {
|
||||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", RUNNING));
|
server.enqueue(instanceWithNetworkAndStatus("test-delete-1", "default", RUNNING));
|
||||||
server.enqueue(singleRegionSingleZoneResponse());
|
server.enqueue(singleRegionSingleZoneResponse());
|
||||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
server.enqueue(jsonResponse("/aggregated_machinetype_list.json")); // Why are we getting machineTypes to delete an instance?
|
||||||
server.enqueue(jsonResponse("/operation.json"));
|
server.enqueue(jsonResponse("/operation.json")); // instance delete
|
||||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
|
server.enqueue(instanceWithNetworkAndStatus("test-delete-1", "default", TERMINATED));
|
||||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
|
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-delete-1", "default", TERMINATED));
|
||||||
server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/network_get.json"));
|
|
||||||
server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/firewall_list.json"));
|
server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/firewall_list.json"));
|
||||||
server.enqueue(jsonResponse("/operation.json"));
|
server.enqueue(jsonResponse("/operation.json"));
|
||||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||||
server.enqueue(jsonResponse("/operation.json"));
|
|
||||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
|
||||||
|
|
||||||
ComputeService computeService = computeService();
|
ComputeService computeService = computeService();
|
||||||
computeService.destroyNode(url("/jclouds/zones/us-central1-a/instances/test-delete-networks"));
|
computeService.destroyNode(url("/jclouds/zones/us-central1-a/instances/test-delete-1"));
|
||||||
|
|
||||||
assertSent(server, "GET", "/jclouds/zones/us-central1-a/instances/test-delete-networks");
|
assertSent(server, "GET", "/jclouds/zones/us-central1-a/instances/test-delete-1");
|
||||||
assertSent(server, "GET", "/projects/party/regions");
|
assertSent(server, "GET", "/projects/party/regions");
|
||||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
assertSent(server, "GET", "/projects/party/aggregated/machineTypes"); // Why are we getting machineTypes to delete an instance?
|
||||||
assertSent(server, "DELETE", "/jclouds/zones/us-central1-a/instances/test-delete-networks");
|
assertSent(server, "DELETE", "/jclouds/zones/us-central1-a/instances/test-delete-1"); // instance delete
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-delete-networks");
|
assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-delete-1"); // get instance
|
||||||
assertSent(server, "GET", "/projects/party/aggregated/instances");
|
assertSent(server, "GET", "/projects/party/aggregated/instances");
|
||||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test-delete");
|
|
||||||
assertSent(server, "GET", "/projects/party/global/firewalls");
|
assertSent(server, "GET", "/projects/party/global/firewalls");
|
||||||
assertSent(server, "DELETE", "/projects/party/global/firewalls/jclouds-test-delete");
|
assertSent(server, "DELETE", "/projects/party/global/firewalls/jclouds-test-delete-34sf");
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
|
||||||
assertSent(server, "DELETE", "/projects/party/global/networks/jclouds-test-delete");
|
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void listAssignableLocations() throws Exception {
|
public void listAssignableLocations() throws Exception {
|
||||||
server.enqueue(singleRegionSingleZoneResponse());
|
server.enqueue(singleRegionSingleZoneResponse());
|
||||||
|
|
||||||
|
@ -146,17 +141,13 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
||||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createNodeWhenNetworkNorFirewallExistDoesNotExist() throws Exception {
|
public void createNodeWhenFirewallDoesNotExist() throws Exception {
|
||||||
server.enqueue(singleRegionSingleZoneResponse());
|
server.enqueue(singleRegionSingleZoneResponse());
|
||||||
server.enqueue(jsonResponse("/image_list.json"));
|
server.enqueue(jsonResponse("/image_list.json"));
|
||||||
server.enqueue(jsonResponse("/image_list_debian.json")); // per IMAGE_PROJECTS = "debian-cloud"
|
server.enqueue(jsonResponse("/image_list_debian.json")); // per IMAGE_PROJECTS = "debian-cloud"
|
||||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
||||||
server.enqueue(new MockResponse().setResponseCode(404)); // Network
|
server.enqueue(jsonResponse("/network_get_default.json"));
|
||||||
server.enqueue(new MockResponse().setResponseCode(404)); // Network again?
|
server.enqueue(new MockResponse().setResponseCode(404)); // Get Firewall
|
||||||
server.enqueue(jsonResponse("/operation.json")); // Create Network
|
|
||||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
|
||||||
server.enqueue(jsonResponse("/network_get.json"));
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404)); // Firewall
|
|
||||||
server.enqueue(jsonResponse("/operation.json")); // Create Firewall
|
server.enqueue(jsonResponse("/operation.json")); // Create Firewall
|
||||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
|
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
|
||||||
|
@ -179,14 +170,9 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
||||||
assertSent(server, "GET", "/projects/party/global/images");
|
assertSent(server, "GET", "/projects/party/global/images");
|
||||||
assertSent(server, "GET", "/projects/debian-cloud/global/images");
|
assertSent(server, "GET", "/projects/debian-cloud/global/images");
|
||||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
|
assertSent(server, "GET", "/projects/party/global/networks/default");
|
||||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
|
assertSent(server, "GET", "/projects/party/global/firewalls/jclouds-test-65f"); // Get Firewall
|
||||||
assertSent(server, "POST", "/projects/party/global/networks",
|
assertSent(server, "POST", "/projects/party/global/firewalls", // Create Firewall
|
||||||
"{\"name\":\"jclouds-test\",\"IPv4Range\":\"10.0.0.0/8\"}");
|
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
|
||||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
|
|
||||||
assertSent(server, "GET", "/projects/party/global/firewalls/jclouds-test-port-22");
|
|
||||||
assertSent(server, "POST", "/projects/party/global/firewalls",
|
|
||||||
stringFromResource("/firewall_insert_2.json"));
|
stringFromResource("/firewall_insert_2.json"));
|
||||||
|
|
||||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.functions;
|
|
||||||
|
|
||||||
import static org.easymock.EasyMock.createMock;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.EasyMock.replay;
|
|
||||||
import static org.easymock.EasyMock.verify;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.predicates.AtomicOperationDone;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
|
||||||
import org.jclouds.googlecomputeengine.features.NetworkApi;
|
|
||||||
import org.jclouds.googlecomputeengine.options.NetworkCreationOptions;
|
|
||||||
import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationTest;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public class CreateNetworkIfNeededTest {
|
|
||||||
|
|
||||||
private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects";
|
|
||||||
|
|
||||||
public void testApply() {
|
|
||||||
GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
|
|
||||||
NetworkApi nwApi = createMock(NetworkApi.class);
|
|
||||||
Resources resources = createMock(Resources.class);
|
|
||||||
|
|
||||||
Network network = Network.create( //
|
|
||||||
"abcd", // id
|
|
||||||
new SimpleDateFormatDateService().iso8601DateParse("2014-07-18T09:47:30.826-07:00"), // creationTimestamp
|
|
||||||
URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
|
|
||||||
"this-network", // name
|
|
||||||
null, // description
|
|
||||||
"0.0.0.0/0", // rangeIPv4
|
|
||||||
null // gatewayIPv4
|
|
||||||
);
|
|
||||||
|
|
||||||
Operation createOp = new ParseGlobalOperationTest().expected();
|
|
||||||
|
|
||||||
expect(api.networks()).andReturn(nwApi).atLeastOnce();
|
|
||||||
|
|
||||||
expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0")) .andReturn(createOp);
|
|
||||||
expect(resources.operation(createOp.selfLink())).andReturn(createOp);
|
|
||||||
expect(nwApi.get("this-network")).andReturn(null);
|
|
||||||
expect(nwApi.get("this-network")).andReturn(network);
|
|
||||||
|
|
||||||
replay(api, nwApi, resources);
|
|
||||||
|
|
||||||
NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
|
|
||||||
|
|
||||||
AtomicOperationDone pred = atomicOperationDone(api, resources);
|
|
||||||
|
|
||||||
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, pred);
|
|
||||||
|
|
||||||
assertEquals(creator.apply(input), network);
|
|
||||||
|
|
||||||
verify(api, nwApi, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testApplyWithGateway() {
|
|
||||||
GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
|
|
||||||
NetworkApi nwApi = createMock(NetworkApi.class);
|
|
||||||
Resources resources = createMock(Resources.class);
|
|
||||||
|
|
||||||
Network network = Network.create( //
|
|
||||||
"abcd", // id
|
|
||||||
new SimpleDateFormatDateService().iso8601DateParse("2014-07-18T09:47:30.826-07:00"), // creationTimestamp
|
|
||||||
URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
|
|
||||||
"this-network", // name
|
|
||||||
null, // description
|
|
||||||
"0.0.0.0/0", // rangeIPv4
|
|
||||||
"1.2.3.4" // gatewayIPv4
|
|
||||||
);
|
|
||||||
|
|
||||||
Operation createOp = new ParseGlobalOperationTest().expected();
|
|
||||||
|
|
||||||
expect(api.networks()).andReturn(nwApi).atLeastOnce();
|
|
||||||
|
|
||||||
expect(nwApi.createInIPv4Range(new NetworkCreationOptions.Builder("this-network", "0.0.0.0/0")
|
|
||||||
.gatewayIPv4("1.2.3.4").build())).andReturn(createOp);
|
|
||||||
expect(resources.operation(createOp.selfLink())).andReturn(createOp);
|
|
||||||
expect(nwApi.get("this-network")).andReturn(null);
|
|
||||||
expect(nwApi.get("this-network")).andReturn(network);
|
|
||||||
|
|
||||||
replay(api, nwApi, resources);
|
|
||||||
|
|
||||||
NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", "1.2.3.4");
|
|
||||||
|
|
||||||
AtomicOperationDone pred = atomicOperationDone(api, resources);
|
|
||||||
|
|
||||||
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, pred);
|
|
||||||
|
|
||||||
assertEquals(creator.apply(input), network);
|
|
||||||
|
|
||||||
verify(api, nwApi, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AtomicOperationDone atomicOperationDone(final GoogleComputeEngineApi api,
|
|
||||||
final Resources resources) {
|
|
||||||
return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
|
|
||||||
@Override protected void configure() {
|
|
||||||
bind(GoogleComputeEngineApi.class).toInstance(api);
|
|
||||||
bind(Resources.class).toInstance(resources);
|
|
||||||
}
|
|
||||||
}).getInstance(AtomicOperationDone.class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.functions;
|
|
||||||
|
|
||||||
import static org.easymock.EasyMock.createMock;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.EasyMock.replay;
|
|
||||||
import static org.easymock.EasyMock.verify;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|
||||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
|
||||||
import org.jclouds.googlecomputeengine.compute.predicates.AtomicOperationDone;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Network;
|
|
||||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
|
||||||
import org.jclouds.googlecomputeengine.features.NetworkApi;
|
|
||||||
import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationTest;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public class FindNetworkOrCreateTest {
|
|
||||||
private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects";
|
|
||||||
private static final Network NETWORK = Network.create( //
|
|
||||||
"abcd", // id
|
|
||||||
new SimpleDateFormatDateService().iso8601DateParse("2014-07-18T09:47:30.826-07:00"), // creationTimestamp
|
|
||||||
URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
|
|
||||||
"this-network", // name
|
|
||||||
null, // description
|
|
||||||
"0.0.0.0/0", // rangeIPv4
|
|
||||||
null // gatewayIPv4
|
|
||||||
);
|
|
||||||
|
|
||||||
public void testLoadExisting() {
|
|
||||||
GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
|
|
||||||
NetworkApi nwApi = createMock(NetworkApi.class);
|
|
||||||
|
|
||||||
expect(api.networks()).andReturn(nwApi).atLeastOnce();
|
|
||||||
|
|
||||||
expect(nwApi.get("this-network")).andReturn(NETWORK);
|
|
||||||
|
|
||||||
replay(api, nwApi);
|
|
||||||
|
|
||||||
NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
|
|
||||||
|
|
||||||
Predicate<AtomicReference<Operation>> operationDone = Predicates.alwaysFalse(); // No op should be created!
|
|
||||||
|
|
||||||
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, operationDone);
|
|
||||||
|
|
||||||
FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator);
|
|
||||||
|
|
||||||
LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
|
|
||||||
|
|
||||||
assertEquals(cache.getUnchecked(input), NETWORK);
|
|
||||||
|
|
||||||
// Second call is to ensure we only need to make the API calls once.
|
|
||||||
assertEquals(cache.getUnchecked(input), NETWORK);
|
|
||||||
|
|
||||||
verify(api, nwApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLoadNew() {
|
|
||||||
GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
|
|
||||||
NetworkApi nwApi = createMock(NetworkApi.class);
|
|
||||||
Resources resources = createMock(Resources.class);
|
|
||||||
|
|
||||||
Operation createOp = new ParseGlobalOperationTest().expected();
|
|
||||||
|
|
||||||
expect(api.networks()).andReturn(nwApi).atLeastOnce();
|
|
||||||
|
|
||||||
expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0")).andReturn(createOp);
|
|
||||||
expect(resources.operation(createOp.selfLink())).andReturn(createOp);
|
|
||||||
// pre-creation
|
|
||||||
expect(nwApi.get("this-network")).andReturn(null).times(2);
|
|
||||||
// post-creation
|
|
||||||
expect(nwApi.get("this-network")).andReturn(NETWORK);
|
|
||||||
|
|
||||||
replay(api, nwApi, resources);
|
|
||||||
|
|
||||||
NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
|
|
||||||
|
|
||||||
AtomicOperationDone pred = atomicOperationDone(resources);
|
|
||||||
|
|
||||||
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, pred);
|
|
||||||
|
|
||||||
FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator);
|
|
||||||
|
|
||||||
LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
|
|
||||||
|
|
||||||
assertEquals(cache.getUnchecked(input), NETWORK);
|
|
||||||
|
|
||||||
// Second call is to ensure we only need to make the API calls once.
|
|
||||||
assertEquals(cache.getUnchecked(input), NETWORK);
|
|
||||||
|
|
||||||
verify(api, nwApi, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AtomicOperationDone atomicOperationDone(final Resources resources) {
|
|
||||||
return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
|
|
||||||
@Override protected void configure() {
|
|
||||||
bind(Resources.class).toInstance(resources);
|
|
||||||
}
|
|
||||||
}).getInstance(AtomicOperationDone.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,8 +45,8 @@ public class ParseNetworkTest extends BaseGoogleComputeEngineParseTest<Network>
|
||||||
"13024414170909937976", // id
|
"13024414170909937976", // id
|
||||||
parse("2012-10-24T20:13:19.967"), // creationTimestamp
|
parse("2012-10-24T20:13:19.967"), // creationTimestamp
|
||||||
URI.create(baseUrl + "/party/networks/jclouds-test"), // selfLink
|
URI.create(baseUrl + "/party/networks/jclouds-test"), // selfLink
|
||||||
"default", // name
|
"jclouds-test", // name
|
||||||
"Default network for the project", // description
|
"A custom network for the project", // description
|
||||||
"10.0.0.0/8", // rangeIPv4
|
"10.0.0.0/8", // rangeIPv4
|
||||||
"10.0.0.1" // gatewayIPv4
|
"10.0.0.1" // gatewayIPv4
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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 org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.simplifyPorts;
|
||||||
|
import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.nameFromNetworkString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "SimpleParsingTests", singleThreaded = true)
|
||||||
|
public class SimpleParsingTests {
|
||||||
|
|
||||||
|
public void testOnePort(){
|
||||||
|
int[] ports = {22};
|
||||||
|
List<String> output = simplifyPorts(ports);
|
||||||
|
|
||||||
|
assertEquals(ImmutableList.of("22"), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasic(){
|
||||||
|
int[] ports = {1, 2, 3, 4};
|
||||||
|
List<String> output = simplifyPorts(ports);
|
||||||
|
|
||||||
|
assertEquals(ImmutableList.of("1-4"), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testComplex(){
|
||||||
|
int[] ports = {3, 1, 5, 2, 1002, 17, 1001, 22, 80, 1000};
|
||||||
|
List<String> output = simplifyPorts(ports);
|
||||||
|
|
||||||
|
assertEquals(ImmutableList.of("1-3", "5", "17", "22", "80", "1000-1002"), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEmpty(){
|
||||||
|
int[] ports = {};
|
||||||
|
List<String> output = simplifyPorts(ports);
|
||||||
|
|
||||||
|
assertEquals(null, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEndSingle(){
|
||||||
|
int[] ports = {1, 2, 3, 4, 7};
|
||||||
|
List<String> output = simplifyPorts(ports);
|
||||||
|
|
||||||
|
assertEquals(ImmutableList.of("1-4", "7"), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNetworkFromString(){
|
||||||
|
String network = "https://www.googleapis.com/compute/v1/projects/project/global/networks/network";
|
||||||
|
assertEquals("network", nameFromNetworkString(network));
|
||||||
|
|
||||||
|
network = "projects/project/global/networks/network";
|
||||||
|
assertEquals("network", nameFromNetworkString(network));
|
||||||
|
|
||||||
|
network = "global/networks/default";
|
||||||
|
assertEquals("default", nameFromNetworkString(network));
|
||||||
|
|
||||||
|
network = "default";
|
||||||
|
assertEquals("default", nameFromNetworkString(network));
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,12 +4,11 @@
|
||||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/google/global/firewalls",
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/google/global/firewalls",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
|
|
||||||
"kind": "compute#firewall",
|
"kind": "compute#firewall",
|
||||||
"id": "12862241031274216284",
|
"id": "12862241031274216284",
|
||||||
"creationTimestamp": "2012-04-13T03:05:02.855",
|
"creationTimestamp": "2012-04-13T03:05:02.855",
|
||||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/global/firewalls/jclouds-test-delete",
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/global/firewalls/jclouds-test-delete",
|
||||||
"name": "jclouds-test-delete",
|
"name": "jclouds-test-delete-34sf",
|
||||||
"description": "Internal traffic from default allowed",
|
"description": "Internal traffic from default allowed",
|
||||||
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/jclouds-test-delete",
|
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/jclouds-test-delete",
|
||||||
"sourceRanges": [
|
"sourceRanges": [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "jclouds-test-port-22",
|
"name": "jclouds-test-65f",
|
||||||
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/default",
|
||||||
"sourceRanges": [
|
"sourceRanges": [
|
||||||
"10.0.0.0/8",
|
"10.0.0.0/8",
|
||||||
"0.0.0.0/0"
|
"0.0.0.0/0"
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
"aTag"
|
"aTag"
|
||||||
],
|
],
|
||||||
"targetTags": [
|
"targetTags": [
|
||||||
"jclouds-test-port-22"
|
"jclouds-test-65f"
|
||||||
],
|
],
|
||||||
"allowed": [
|
"allowed": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"name": "test-1",
|
"name": "test-1",
|
||||||
"networkInterfaces": [
|
"networkInterfaces": [
|
||||||
{
|
{
|
||||||
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/default",
|
||||||
"accessConfigs": [
|
"accessConfigs": [
|
||||||
{
|
{
|
||||||
"type": "ONE_TO_ONE_NAT"
|
"type": "ONE_TO_ONE_NAT"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
"tags": {
|
"tags": {
|
||||||
"items": [
|
"items": [
|
||||||
"aTag",
|
"aTag",
|
||||||
"jclouds-test-port-22"
|
"jclouds-test-65f"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"id": "13024414170909937976",
|
"id": "13024414170909937976",
|
||||||
"creationTimestamp": "2012-10-24T20:13:19.967",
|
"creationTimestamp": "2012-10-24T20:13:19.967",
|
||||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
||||||
"name": "default",
|
"name": "jclouds-test",
|
||||||
"description": "Default network for the project",
|
"description": "A custom network for the project",
|
||||||
"IPv4Range": "10.0.0.0/8",
|
"IPv4Range": "10.0.0.0/8",
|
||||||
"gatewayIPv4": "10.0.0.1"
|
"gatewayIPv4": "10.0.0.1"
|
||||||
}
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"kind": "compute#network",
|
||||||
|
"id": "13024414170909937976",
|
||||||
|
"creationTimestamp": "2012-10-24T20:13:19.967",
|
||||||
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/default",
|
||||||
|
"name": "default",
|
||||||
|
"description": "Default network for the project",
|
||||||
|
"IPv4Range": "10.0.0.0/8",
|
||||||
|
"gatewayIPv4": "10.0.0.1"
|
||||||
|
}
|
|
@ -9,8 +9,8 @@
|
||||||
"id": "13024414170909937976",
|
"id": "13024414170909937976",
|
||||||
"creationTimestamp": "2012-10-24T20:13:19.967",
|
"creationTimestamp": "2012-10-24T20:13:19.967",
|
||||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
||||||
"name": "default",
|
"name": "jclouds-test",
|
||||||
"description": "Default network for the project",
|
"description": "A custom network for the project",
|
||||||
"IPv4Range": "10.0.0.0/8",
|
"IPv4Range": "10.0.0.0/8",
|
||||||
"gatewayIPv4": "10.0.0.1"
|
"gatewayIPv4": "10.0.0.1"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue