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.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.features.FirewallApi;
|
||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||
|
@ -125,36 +124,26 @@ public final class GoogleComputeEngineService extends BaseComputeService {
|
|||
protected synchronized void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
|
||||
Set<String> orphanedGroups = findOrphanedGroups.apply(deadNodes);
|
||||
for (String orphanedGroup : orphanedGroups) {
|
||||
cleanUpNetworksAndFirewallsForGroup(orphanedGroup);
|
||||
cleanUpFirewallsForGroup(orphanedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanUpNetworksAndFirewallsForGroup(final String groupName) {
|
||||
String resourceName = namingConvention.create().sharedNameForGroup(groupName);
|
||||
Network network = api.networks().get(resourceName);
|
||||
private void cleanUpFirewallsForGroup(final String groupName) {
|
||||
GroupNamingConvention namingScheme = namingConvention.create();
|
||||
FirewallApi firewallApi = api.firewalls();
|
||||
|
||||
for (Firewall firewall : concat(firewallApi.list())) {
|
||||
if (firewall == null || !firewall.network().equals(network.selfLink())) {
|
||||
continue;
|
||||
String foundGroup = namingScheme.groupInUniqueNameOrNull(firewall.name());
|
||||
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 org.jclouds.googlecloud.internal.ListPages.concat;
|
||||
import static org.jclouds.googlecomputeengine.config.GoogleComputeEngineProperties.IMAGE_PROJECTS;
|
||||
import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.simplifyPorts;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -111,26 +113,35 @@ public final class GoogleComputeEngineServiceAdapter
|
|||
@Override public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(String group, String name,
|
||||
Template template) {
|
||||
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.getImage().getUri(), "image URI is null");
|
||||
|
||||
List<AttachDisk> disks = Lists.newArrayList();
|
||||
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(
|
||||
name, // name
|
||||
template.getHardware().getUri(), // machineType
|
||||
options.network(), // network
|
||||
network, // network
|
||||
disks, // disks
|
||||
group // description
|
||||
);
|
||||
|
||||
// Add tags from template and for security groups
|
||||
// Add tags from template
|
||||
newInstance.tags().items().addAll(options.getTags());
|
||||
|
||||
// Add tags for firewalls
|
||||
FirewallTagNamingConvention naming = firewallTagNamingConvention.get(group);
|
||||
for (int port : options.getInboundPorts()) {
|
||||
newInstance.tags().items().add(naming.name(port));
|
||||
List<String> ports = simplifyPorts(options.getInboundPorts());
|
||||
if (ports != null){
|
||||
newInstance.tags().items().add(naming.name(ports));
|
||||
}
|
||||
|
||||
// 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.googlecomputeengine.compute.GoogleComputeEngineService;
|
||||
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.GoogleComputeEngineImageToImage;
|
||||
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.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||
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.Predicate;
|
||||
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.Maps;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -121,12 +114,6 @@ public final class GoogleComputeEngineServiceContextModule
|
|||
bind(new TypeLiteral<Predicate<String>>() {
|
||||
}).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);
|
||||
bindHttpApi(binder(), Resources.class);
|
||||
}
|
||||
|
@ -173,11 +160,6 @@ public final class GoogleComputeEngineServiceContextModule
|
|||
}, seconds, SECONDS);
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
LoadingCache<NetworkAndAddressRange, Network> networkMap(CacheLoader<NetworkAndAddressRange, Network> in) {
|
||||
return CacheBuilder.newBuilder().build(in);
|
||||
}
|
||||
|
||||
@Override protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
|
@ -46,10 +48,18 @@ public final class FirewallTagNamingConvention {
|
|||
this.sharedResourceName = sharedResourceName;
|
||||
}
|
||||
|
||||
public String name(int port) {
|
||||
return String.format("%s-port-%s", sharedResourceName, port);
|
||||
public String name(List<String> ports) {
|
||||
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() {
|
||||
return new Predicate<String>() {
|
||||
@Override
|
||||
|
|
|
@ -89,7 +89,6 @@ public final class InstanceToNodeMetadata implements Function<Instance, NodeMeta
|
|||
URI bootImage = diskToSourceImage.get(input.disks().get(0).source());
|
||||
|
||||
builder.id(input.selfLink().toString())
|
||||
.providerId(input.id())
|
||||
.name(input.name())
|
||||
.providerId(input.id())
|
||||
.hostname(input.name())
|
||||
|
|
|
@ -16,18 +16,15 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine.compute.options;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
||||
/** Instance options specific to Google Compute Engine. */
|
||||
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||
|
||||
private URI network = null;
|
||||
private boolean autoCreateKeyPair = true;
|
||||
|
||||
@Override
|
||||
|
@ -42,22 +39,10 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
|||
super.copyTo(to);
|
||||
if (to instanceof GoogleComputeEngineTemplateOptions) {
|
||||
GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
|
||||
eTo.network(network());
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -16,10 +16,13 @@
|
|||
*/
|
||||
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.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.Map;
|
||||
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.ListNodesStrategy;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
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.Strings;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
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.util.concurrent.Atomics;
|
||||
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 DEFAULT_INTERNAL_NETWORK_RANGE = "10.0.0.0/8";
|
||||
|
||||
public static final String DEFAULT_NETWORK_NAME = "default";
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final LoadingCache<NetworkAndAddressRange, Network> networkMap;
|
||||
private final Predicate<AtomicReference<Operation>> operationDone;
|
||||
private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
|
||||
private final SshKeyPairGenerator keyGenerator;
|
||||
|
@ -85,13 +87,11 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
|||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||
GoogleComputeEngineApi api, Predicate<AtomicReference<Operation>> operationDone,
|
||||
LoadingCache<NetworkAndAddressRange, Network> networkMap,
|
||||
FirewallTagNamingConvention.Factory firewallTagNamingConvention, SshKeyPairGenerator keyGenerator) {
|
||||
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
|
||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||
this.api = api;
|
||||
this.operationDone = operationDone;
|
||||
this.networkMap = networkMap;
|
||||
this.firewallTagNamingConvention = firewallTagNamingConvention;
|
||||
this.keyGenerator = keyGenerator;
|
||||
}
|
||||
|
@ -101,17 +101,16 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
|||
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
||||
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||
|
||||
String sharedResourceName = namingConvention.create().sharedNameForGroup(group);
|
||||
Template mutableTemplate = template.clone();
|
||||
Template mutableTemplate = template.clone();
|
||||
GoogleComputeEngineTemplateOptions templateOptions = GoogleComputeEngineTemplateOptions.class
|
||||
.cast(mutableTemplate.getOptions());
|
||||
assert template.getOptions().equals(templateOptions) : "options didn't clone properly";
|
||||
|
||||
// get or insert the network and insert a firewall with the users
|
||||
// configuration
|
||||
Network network = getOrCreateNetwork(templateOptions, sharedResourceName);
|
||||
// Get Network
|
||||
Network network = getNetwork(templateOptions.getNetworks());
|
||||
// Setup Firewall rules
|
||||
getOrCreateFirewalls(templateOptions, network, firewallTagNamingConvention.get(group));
|
||||
templateOptions.network(network.selfLink());
|
||||
templateOptions.networks(ImmutableSet.of(network.selfLink().toString()));
|
||||
templateOptions.userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, group);
|
||||
|
||||
// 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
|
||||
* defined.
|
||||
* Try and find a network previously created by the user.
|
||||
*/
|
||||
private Network getOrCreateNetwork(GoogleComputeEngineTemplateOptions templateOptions, String sharedResourceName) {
|
||||
String networkName = templateOptions.network() != null ? toName(templateOptions.network()) : sharedResourceName;
|
||||
return networkMap.getUnchecked(NetworkAndAddressRange.create(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
|
||||
private Network getNetwork(Set<String> networks) {
|
||||
String networkName;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,7 +156,7 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
|||
* {@link FirewallTagNamingConvention}, with a target tag also following the
|
||||
* {@link FirewallTagNamingConvention}, which opens the requested port for
|
||||
* all sources on both TCP and UDP protocols.
|
||||
*
|
||||
*
|
||||
* @see org.jclouds.googlecomputeengine.features.FirewallApi#patch(String,
|
||||
* org.jclouds.googlecomputeengine.options.FirewallOptions)
|
||||
*/
|
||||
|
@ -155,32 +164,70 @@ public final class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
|
|||
FirewallTagNamingConvention naming) {
|
||||
|
||||
FirewallApi firewallApi = api.firewalls();
|
||||
List<AtomicReference<Operation>> operations = Lists.newArrayList();
|
||||
|
||||
for (Integer port : templateOptions.getInboundPorts()) {
|
||||
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);
|
||||
}
|
||||
int[] inboundPorts = templateOptions.getInboundPorts();
|
||||
if ((inboundPorts == null) || inboundPorts.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
checkState(operation.get().httpErrorStatusCode() == null, "Could not insert firewall, operation failed %s",
|
||||
operation);
|
||||
}
|
||||
}
|
||||
|
||||
private static String toName(URI link) {
|
||||
String path = link.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
// Helper function for simplifying an array of ports to a list of ranges FirewallOptions expects.
|
||||
public static List<String> simplifyPorts(int[] ports){
|
||||
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 java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
@ -113,4 +114,12 @@ public class GoogleComputeEngineServiceLiveTest extends BaseComputeServiceLiveTe
|
|||
protected Module getSshModule() {
|
||||
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");
|
||||
}
|
||||
|
||||
public void networksAndFirewallDeletedWhenAllGroupNodesAreTerminated() throws IOException, InterruptedException {
|
||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", RUNNING));
|
||||
public void firewallDeletedWhenAllGroupNodesAreTerminated() throws IOException, InterruptedException {
|
||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-1", "default", RUNNING));
|
||||
server.enqueue(singleRegionSingleZoneResponse());
|
||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
||||
server.enqueue(jsonResponse("/operation.json"));
|
||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json")); // Why are we getting machineTypes to delete an instance?
|
||||
server.enqueue(jsonResponse("/operation.json")); // instance delete
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
|
||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
|
||||
server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/network_get.json"));
|
||||
server.enqueue(instanceWithNetworkAndStatus("test-delete-1", "default", TERMINATED));
|
||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-delete-1", "default", TERMINATED));
|
||||
server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/firewall_list.json"));
|
||||
server.enqueue(jsonResponse("/operation.json"));
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
server.enqueue(jsonResponse("/operation.json"));
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
|
||||
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/aggregated/machineTypes");
|
||||
assertSent(server, "DELETE", "/jclouds/zones/us-central1-a/instances/test-delete-networks");
|
||||
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-1"); // instance delete
|
||||
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/global/networks/jclouds-test-delete");
|
||||
assertSent(server, "GET", "/projects/party/global/firewalls");
|
||||
assertSent(server, "DELETE", "/projects/party/global/firewalls/jclouds-test-delete");
|
||||
assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
|
||||
assertSent(server, "DELETE", "/projects/party/global/networks/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");
|
||||
}
|
||||
|
||||
|
||||
public void listAssignableLocations() throws Exception {
|
||||
server.enqueue(singleRegionSingleZoneResponse());
|
||||
|
||||
|
@ -146,17 +141,13 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
|||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||
}
|
||||
|
||||
public void createNodeWhenNetworkNorFirewallExistDoesNotExist() throws Exception {
|
||||
public void createNodeWhenFirewallDoesNotExist() throws Exception {
|
||||
server.enqueue(singleRegionSingleZoneResponse());
|
||||
server.enqueue(jsonResponse("/image_list.json"));
|
||||
server.enqueue(jsonResponse("/image_list_debian.json")); // per IMAGE_PROJECTS = "debian-cloud"
|
||||
server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
|
||||
server.enqueue(new MockResponse().setResponseCode(404)); // Network
|
||||
server.enqueue(new MockResponse().setResponseCode(404)); // Network again?
|
||||
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("/network_get_default.json"));
|
||||
server.enqueue(new MockResponse().setResponseCode(404)); // Get Firewall
|
||||
server.enqueue(jsonResponse("/operation.json")); // Create Firewall
|
||||
server.enqueue(jsonResponse("/zone_operation.json"));
|
||||
server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
|
||||
|
@ -179,14 +170,9 @@ public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineA
|
|||
assertSent(server, "GET", "/projects/party/global/images");
|
||||
assertSent(server, "GET", "/projects/debian-cloud/global/images");
|
||||
assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
|
||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
|
||||
assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
|
||||
assertSent(server, "POST", "/projects/party/global/networks",
|
||||
"{\"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",
|
||||
assertSent(server, "GET", "/projects/party/global/networks/default");
|
||||
assertSent(server, "GET", "/projects/party/global/firewalls/jclouds-test-65f"); // Get Firewall
|
||||
assertSent(server, "POST", "/projects/party/global/firewalls", // Create Firewall
|
||||
stringFromResource("/firewall_insert_2.json"));
|
||||
|
||||
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
|
||||
parse("2012-10-24T20:13:19.967"), // creationTimestamp
|
||||
URI.create(baseUrl + "/party/networks/jclouds-test"), // selfLink
|
||||
"default", // name
|
||||
"Default network for the project", // description
|
||||
"jclouds-test", // name
|
||||
"A custom network for the project", // description
|
||||
"10.0.0.0/8", // rangeIPv4
|
||||
"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",
|
||||
"items": [
|
||||
{
|
||||
|
||||
"kind": "compute#firewall",
|
||||
"id": "12862241031274216284",
|
||||
"creationTimestamp": "2012-04-13T03:05:02.855",
|
||||
"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",
|
||||
"network": "https://www.googleapis.com/compute/v1/projects/party/global/networks/jclouds-test-delete",
|
||||
"sourceRanges": [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jclouds-test-port-22",
|
||||
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
||||
"name": "jclouds-test-65f",
|
||||
"network": "https://www.googleapis.com/compute/v1/projects/party/networks/default",
|
||||
"sourceRanges": [
|
||||
"10.0.0.0/8",
|
||||
"0.0.0.0/0"
|
||||
|
@ -9,7 +9,7 @@
|
|||
"aTag"
|
||||
],
|
||||
"targetTags": [
|
||||
"jclouds-test-port-22"
|
||||
"jclouds-test-65f"
|
||||
],
|
||||
"allowed": [
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "test-1",
|
||||
"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": [
|
||||
{
|
||||
"type": "ONE_TO_ONE_NAT"
|
||||
|
@ -25,7 +25,7 @@
|
|||
"tags": {
|
||||
"items": [
|
||||
"aTag",
|
||||
"jclouds-test-port-22"
|
||||
"jclouds-test-65f"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
"id": "13024414170909937976",
|
||||
"creationTimestamp": "2012-10-24T20:13:19.967",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
||||
"name": "default",
|
||||
"description": "Default network for the project",
|
||||
"name": "jclouds-test",
|
||||
"description": "A custom network for the project",
|
||||
"IPv4Range": "10.0.0.0/8",
|
||||
"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",
|
||||
"creationTimestamp": "2012-10-24T20:13:19.967",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1/projects/party/networks/jclouds-test",
|
||||
"name": "default",
|
||||
"description": "Default network for the project",
|
||||
"name": "jclouds-test",
|
||||
"description": "A custom network for the project",
|
||||
"IPv4Range": "10.0.0.0/8",
|
||||
"gatewayIPv4": "10.0.0.1"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue