JCLOUDS-312. Add SecurityGroupExtension for GCE.

Note - there is no GoogleComputEngineSecurityGroupExtensionExpectTest,
due to it being more or less redundant given that we're not making any
new API calls.
This commit is contained in:
Andrew Bayer 2013-09-30 11:54:47 -07:00
parent d4abfec8aa
commit 6b0680fc8c
24 changed files with 1641 additions and 74 deletions

View File

@ -114,6 +114,9 @@
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/GoogleComputeEngineSecurityGroupExtensionLiveTest.java</include>
</includes>
<systemPropertyVariables>
<test.google-compute-engine.identity>${test.google-compute-engine.identity}
</test.google-compute-engine.identity>

View File

@ -35,32 +35,43 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Location;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
import org.jclouds.googlecomputeengine.compute.extensions.GoogleComputeEngineSecurityGroupExtension;
import org.jclouds.googlecomputeengine.compute.functions.BuildInstanceMetadata;
import org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermission;
import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
import org.jclouds.googlecomputeengine.compute.functions.InstanceInZoneToNodeMetadata;
import org.jclouds.googlecomputeengine.compute.functions.MachineTypeInZoneToHardware;
import org.jclouds.googlecomputeengine.compute.functions.NetworkToSecurityGroup;
import org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
import org.jclouds.googlecomputeengine.compute.functions.RegionToLocation;
import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
import org.jclouds.googlecomputeengine.compute.loaders.FindNetworkOrCreate;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
import org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.googlecomputeengine.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Image;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.InstanceInZone;
import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Region;
import org.jclouds.googlecomputeengine.domain.Zone;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.functions.CreateNetworkIfNeeded;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
@ -69,6 +80,9 @@ import com.google.common.base.Function;
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.inject.Injector;
import com.google.inject.Provides;
@ -105,6 +119,12 @@ public class GoogleComputeEngineServiceContextModule
bind(new TypeLiteral<Function<Zone, Location>>() {})
.to(ZoneToLocation.class);
bind(new TypeLiteral<Function<Firewall, Iterable<IpPermission>>>() {})
.to(FirewallToIpPermission.class);
bind(new TypeLiteral<Function<Network, SecurityGroup>>() {})
.to(NetworkToSecurityGroup.class);
bind(new TypeLiteral<Function<TemplateOptions, ImmutableMap.Builder<String, String>>>() {})
.to(BuildInstanceMetadata.class);
@ -121,6 +141,15 @@ public 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(new TypeLiteral<SecurityGroupExtension>() {})
.to(GoogleComputeEngineSecurityGroupExtension.class);
bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
install(new LocationsFromComputeServiceAdapterModule<InstanceInZone, MachineTypeInZone, Image, Zone>() {});
@ -131,7 +160,7 @@ public class GoogleComputeEngineServiceContextModule
@Singleton
@Memoized
public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> provideImagesMap(
AtomicReference<AuthorizationException> authException,
AtomicReference <AuthorizationException> authException,
final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images,
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
@ -219,11 +248,23 @@ public class GoogleComputeEngineServiceContextModule
seconds, TimeUnit.SECONDS);
}
@Provides
@Singleton
protected LoadingCache<NetworkAndAddressRange, Network> networkMap(
CacheLoader<NetworkAndAddressRange, Network> in) {
return CacheBuilder.newBuilder().build(in);
}
@Override
protected Optional<ImageExtension> provideImageExtension(Injector i) {
return Optional.absent();
}
@Override
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
return Optional.of(i.getInstance(SecurityGroupExtension.class));
}
@VisibleForTesting
public static final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus =
ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()

View File

@ -0,0 +1,340 @@
/*
* 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.extensions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.DEFAULT_INTERNAL_NETWORK_RANGE;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.equalsIpPermission;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.providesIpPermission;
import static org.jclouds.util.Predicates2.retry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.domain.Location;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.googlecomputeengine.options.ListOptions.Builder;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
/**
* An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
* is optional by providers.
*
* @author Andrew Bayer
*/
public class GoogleComputeEngineSecurityGroupExtension implements SecurityGroupExtension {
protected final Supplier<String> userProject;
protected final GroupNamingConvention.Factory namingConvention;
protected final LoadingCache<NetworkAndAddressRange, Network> networkCreator;
protected final Function<Network, SecurityGroup> groupConverter;
protected final GoogleComputeEngineApi api;
protected final Predicate<AtomicReference<Operation>> operationDonePredicate;
protected final long operationCompleteCheckInterval;
protected final long operationCompleteCheckTimeout;
@Inject
public GoogleComputeEngineSecurityGroupExtension(GoogleComputeEngineApi api,
@UserProject Supplier<String> userProject,
GroupNamingConvention.Factory namingConvention,
LoadingCache<NetworkAndAddressRange, Network> networkCreator,
Function<Network, SecurityGroup> groupConverter,
@Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
this.api = checkNotNull(api, "api");
this.userProject = checkNotNull(userProject, "userProject");
this.namingConvention = checkNotNull(namingConvention, "namingConvention");
this.networkCreator = checkNotNull(networkCreator, "networkCreator");
this.groupConverter = checkNotNull(groupConverter, "groupConverter");
this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
"operation completed check interval");
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
"operation completed check timeout");
this.operationDonePredicate = operationDonePredicate;
}
@Override
public Set<SecurityGroup> listSecurityGroups() {
return api.getNetworkApiForProject(userProject.get()).list().concat().transform(groupConverter).toSet();
}
@Override
public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
return listSecurityGroups();
}
@Override
public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(id);
Instance instance = api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
slashEncodedIds.getSecondId());
if (instance == null) {
return ImmutableSet.of();
}
ImmutableSet.Builder builder = ImmutableSet.builder();
for (NetworkInterface nwInterface : instance.getNetworkInterfaces()) {
String networkUrl = nwInterface.getNetwork().getPath();
Network nw = api.getNetworkApiForProject(userProject.get()).get(networkUrl.substring(networkUrl.lastIndexOf('/') + 1));
SecurityGroup grp = groupForTagsInNetwork(nw, instance.getTags().getItems());
if (grp != null) {
builder.add(grp);
}
}
return builder.build();
}
@Override
public SecurityGroup getSecurityGroupById(String id) {
checkNotNull(id, "id");
Network network = api.getNetworkApiForProject(userProject.get()).get(id);
if (network == null) {
return null;
}
return groupConverter.apply(network);
}
@Override
public SecurityGroup createSecurityGroup(String name, Location location) {
return createSecurityGroup(name);
}
public SecurityGroup createSecurityGroup(String name) {
checkNotNull(name, "name");
NetworkAndAddressRange nAr = new NetworkAndAddressRange(name, DEFAULT_INTERNAL_NETWORK_RANGE, null);
Network nw = networkCreator.apply(nAr);
return groupConverter.apply(nw);
}
@Override
public boolean removeSecurityGroup(String id) {
checkNotNull(id, "id");
if (api.getNetworkApiForProject(userProject.get()).get(id) == null) {
return false;
}
ListOptions options = new ListOptions.Builder().filter("network eq .*/" + id);
FluentIterable<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(options).concat();
for (Firewall fw : fws) {
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject.get())
.delete(fw.getName()));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not delete firewall, operation failed" + operation);
}
AtomicReference<Operation> operation = new AtomicReference<Operation>(
api.getNetworkApiForProject(userProject.get()).delete(id));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
return true;
}
@Override
public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
if (api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null) {
// Network corresponding to security group does not exist.
return null;
}
ListOptions options = new ListOptions.Builder().filter("network eq .*/" + group.getName());
if (api.getFirewallApiForProject(userProject.get()).list(options).concat().anyMatch(providesIpPermission(ipPermission))) {
// Permission already exists.
return group;
}
FirewallOptions fwOptions = new FirewallOptions();
String uniqueFwName = namingConvention.createWithoutPrefix().uniqueNameForGroup(group.getName());
fwOptions.name(uniqueFwName);
fwOptions.network(group.getUri());
if (ipPermission.getGroupIds().size() > 0) {
fwOptions.sourceTags(ipPermission.getGroupIds());
}
if (ipPermission.getCidrBlocks().size() > 0) {
fwOptions.sourceRanges(ipPermission.getCidrBlocks());
}
Firewall.Rule.Builder ruleBuilder = Firewall.Rule.builder();
ruleBuilder.IpProtocol(ipPermission.getIpProtocol());
if (ipPermission.getToPort() > 0) {
ruleBuilder.addPortRange(ipPermission.getFromPort(), ipPermission.getToPort());
}
fwOptions.addAllowedRule(ruleBuilder.build());
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject
.get()).createInNetwork(
uniqueFwName,
group.getUri(),
fwOptions));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not create firewall, operation failed" + operation);
return getSecurityGroupById(group.getId());
}
@Override
public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
Multimap<String,String> tenantIdGroupNamePairs, Iterable<String> ipRanges,
Iterable<String> groupIds, SecurityGroup group) {
IpPermission.Builder permBuilder = IpPermission.builder();
permBuilder.ipProtocol(protocol);
permBuilder.fromPort(startPort);
permBuilder.toPort(endPort);
permBuilder.groupIds(groupIds);
permBuilder.cidrBlocks(ipRanges);
return addIpPermission(permBuilder.build(), group);
}
@Override
public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
if (api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null) {
// Network corresponding to security group does not exist.
return null;
}
ListOptions options = new ListOptions.Builder().filter("network eq .*/" + group.getName());
FluentIterable<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(options).concat();
for (Firewall fw : fws) {
if (equalsIpPermission(ipPermission).apply(fw)) {
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject.get())
.delete(fw.getName()));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not delete firewall, operation failed" + operation);
}
}
return getSecurityGroupById(group.getId());
}
@Override
public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
Multimap<String,String> tenantIdGroupNamePairs, Iterable<String> ipRanges,
Iterable<String> groupIds, SecurityGroup group) {
IpPermission.Builder permBuilder = IpPermission.builder();
permBuilder.ipProtocol(protocol);
permBuilder.fromPort(startPort);
permBuilder.toPort(endPort);
permBuilder.groupIds(groupIds);
permBuilder.cidrBlocks(ipRanges);
return removeIpPermission(permBuilder.build(), group);
}
@Override
public boolean supportsTenantIdGroupNamePairs() {
return false;
}
@Override
public boolean supportsTenantIdGroupIdPairs() {
return false;
}
@Override
public boolean supportsGroupIds() {
return true;
}
@Override
public boolean supportsPortRangesForGroups() {
return true;
}
private SecurityGroup groupForTagsInNetwork(Network nw, final Set <String> tags) {
ListOptions opts = new Builder().filter("network eq .*/" + nw.getName());
Set<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(opts).concat()
.filter(new Predicate<Firewall>() {
@Override
public boolean apply(final Firewall input) {
// If any of the targetTags on the firewall apply or the firewall has no target tags...
return Iterables.any(input.getTargetTags(), Predicates.in(tags))
|| Predicates.equalTo(0).apply(input.getTargetTags().size());
}
}).toSet();
if (fws.size() > 0) {
return groupConverter.apply(nw);
}
return null;
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.annotation.Resource;
import javax.inject.Named;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
import org.jclouds.logging.Logger;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
/**
* A function for transforming a GCE-specific Firewall into a generic
* IpPermission object.
*
* @author Andrew Bayer
*/
public class FirewallToIpPermission implements Function<Firewall, Iterable<IpPermission>> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
public FirewallToIpPermission() {
}
@Override
public Iterable<IpPermission> apply(Firewall fw) {
ImmutableSet.Builder setBuilder = ImmutableSet.builder();
for (Rule rule: fw.getAllowed()) {
if (!rule.getPorts().isEmpty()) {
for (Range<Integer> r : rule.getPorts().asRanges()) {
IpPermission.Builder builder = populateBuilder(fw, rule.getIpProtocol());
builder.fromPort(r.lowerEndpoint());
builder.toPort(r.upperEndpoint());
setBuilder.add(builder.build());
}
} else {
setBuilder.add(populateBuilder(fw, rule.getIpProtocol()).build());
}
}
return setBuilder.build();
}
/**
* Convenience method for populating common parts of the IpPermission.
* @param fw
* @param protocol
* @return a pre-populated builder.
*/
private IpPermission.Builder populateBuilder(Firewall fw, IpProtocol protocol) {
IpPermission.Builder builder = IpPermission.builder();
builder.ipProtocol(protocol);
if (!fw.getSourceRanges().isEmpty()) {
builder.cidrBlocks(fw.getSourceRanges());
}
if (!fw.getSourceTags().isEmpty()) {
builder.groupIds(fw.getSourceTags());
}
return builder;
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.domain.SecurityGroupBuilder;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.domain.IpPermission;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
/**
* A function for transforming a GCE-specific Network into a generic
* SecurityGroup object.
*
* @author Andrew Bayer
*/
public class NetworkToSecurityGroup implements Function<Network, SecurityGroup> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Function<Firewall, Iterable<IpPermission>> firewallToPerms;
private final GoogleComputeEngineApi api;
private final Supplier<String> project;
@Inject
public NetworkToSecurityGroup(Function<Firewall, Iterable<IpPermission>> firewallToPerms,
GoogleComputeEngineApi api,
@UserProject Supplier<String> project) {
this.firewallToPerms = firewallToPerms;
this.api = api;
this.project = project;
}
@Override
public SecurityGroup apply(Network network) {
SecurityGroupBuilder builder = new SecurityGroupBuilder();
builder.id(network.getName());
builder.providerId(network.getId());
builder.name(network.getName());
builder.uri(network.getSelfLink());
ImmutableSet.Builder permBuilder = ImmutableSet.builder();
ListOptions options = new ListOptions.Builder().filter("network eq .*/" + network.getName());
for (Firewall fw : api.getFirewallApiForProject(project.get()).list(options).concat()) {
permBuilder.addAll(firewallToPerms.apply(fw));
}
builder.ipPermissions(permBuilder.build());
return builder.build();
}
}

View File

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecomputeengine.compute.loaders;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheLoader;
/**
* @author Andrew Bayer
*/
public class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
protected final GoogleComputeEngineApi api;
protected final Function<NetworkAndAddressRange, Network> networkCreator;
protected final Supplier<String> userProject;
@Inject
public FindNetworkOrCreate(GoogleComputeEngineApi api,
Function<NetworkAndAddressRange, Network> networkCreator,
@UserProject Supplier<String> userProject) {
this.api = checkNotNull(api, "api");
this.networkCreator = checkNotNull(networkCreator, "networkCreator");
this.userProject = checkNotNull(userProject, "userProject");
}
@Override
public Network load(NetworkAndAddressRange in) {
Network network = api.getNetworkApiForProject(userProject.get()).get(in.getName());
if (network != null) {
return network;
} else {
return networkCreator.apply(in);
}
}
}

View File

@ -45,10 +45,13 @@ import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
@ -65,6 +68,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
private final GoogleComputeEngineApi api;
private final Supplier<String> userProject;
private final LoadingCache<NetworkAndAddressRange, Network> networkMap;
private final Predicate<AtomicReference<Operation>> operationDonePredicate;
private final long operationCompleteCheckInterval;
private final long operationCompleteCheckTimeout;
@ -82,7 +86,8 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
@UserProject Supplier<String> userProject,
@Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout,
LoadingCache<NetworkAndAddressRange, Network> networkMap) {
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
@ -93,6 +98,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
"operation completed check timeout");
this.operationDonePredicate = operationDonePredicate;
this.networkMap = checkNotNull(networkMap, "networkMap");
}
@Override
@ -123,31 +129,13 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
String networkName = templateOptions.getNetworkName().or(sharedResourceName);
// check if the network was previously created (cache???)
Network network = api.getNetworkApiForProject(userProject.get()).get(networkName);
if (network != null) {
return network;
} else if (templateOptions.getNetwork().isPresent()) {
throw new IllegalArgumentException("requested network " + networkName + " does not exist");
}
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
.get()).createInIPv4Range(sharedResourceName, DEFAULT_INTERNAL_NETWORK_RANGE));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
return checkNotNull(api.getNetworkApiForProject(userProject.get()).get(sharedResourceName),
"no network with name %s was found", sharedResourceName);
return networkMap.apply(new NetworkAndAddressRange(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
}
/**
* Tries to find if a firewall already exists for this group, if not it creates one.
*
* @see org.jclouds.googlecomputeengine.features.FirewallAsyncApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
* @see org.jclouds.googlecomputeengine.features.FirewallApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
*/
private void getOrCreateFirewall(GoogleComputeEngineTemplateOptions templateOptions, Network network,
String sharedResourceName) {
@ -161,9 +149,9 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
ImmutableSet.Builder<Firewall.Rule> rules = ImmutableSet.builder();
Firewall.Rule.Builder tcpRule = Firewall.Rule.builder();
tcpRule.IPProtocol(Firewall.Rule.IPProtocol.TCP);
tcpRule.IpProtocol(IpProtocol.TCP);
Firewall.Rule.Builder udpRule = Firewall.Rule.builder();
udpRule.IPProtocol(Firewall.Rule.IPProtocol.UDP);
udpRule.IpProtocol(IpProtocol.UDP);
for (Integer port : templateOptions.getInboundPorts()) {
tcpRule.addPort(port);
udpRule.addPort(port);

View File

@ -36,6 +36,7 @@ import org.jclouds.googlecomputeengine.domain.Project;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.googlecomputeengine.options.RouteOptions;
import org.jclouds.json.config.GsonModule;
import org.jclouds.net.domain.IpProtocol;
import org.jclouds.oauth.v2.domain.ClaimSet;
import org.jclouds.oauth.v2.domain.Header;
import org.jclouds.oauth.v2.json.ClaimSetTypeAdapter;
@ -380,7 +381,7 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
JsonParseException {
JsonObject rule = json.getAsJsonObject();
Rule.Builder builder = Rule.builder();
builder.IPProtocol(Rule.IPProtocol.fromValue(rule.get("IPProtocol").getAsString()));
builder.IpProtocol(IpProtocol.fromValue(rule.get("IPProtocol").getAsString()));
if (rule.get("ports") != null) {
JsonArray ports = (JsonArray) rule.get("ports");
for (JsonElement port : ports) {
@ -399,7 +400,7 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
@Override
public JsonElement serialize(Firewall.Rule src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject ruleObject = new JsonObject();
ruleObject.addProperty("IPProtocol", src.getIPProtocol().value());
ruleObject.addProperty("IPProtocol", src.getIpProtocol().value());
if (src.getPorts() != null && !src.getPorts().isEmpty()) {
JsonArray ports = new JsonArray();
for (Range<Integer> range : src.getPorts().asRanges()) {

View File

@ -28,6 +28,8 @@ import java.net.URI;
import java.util.Date;
import java.util.Set;
import org.jclouds.net.domain.IpProtocol;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
@ -245,32 +247,14 @@ public final class Firewall extends Resource {
*/
public static final class Rule {
public enum IPProtocol {
TCP, UDP, ICMP, UNKNOWN;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static IPProtocol fromValue(String protocol) {
return valueOf(protocol.toUpperCase());
}
}
private final IPProtocol ipProtocol;
private final IpProtocol ipProtocol;
private final RangeSet<Integer> ports;
@ConstructorProperties({
"IPProtocol", "ports"
"IpProtocol", "ports"
})
private Rule(IPProtocol IPProtocol, RangeSet<Integer> ports) {
this.ipProtocol = checkNotNull(IPProtocol);
private Rule(IpProtocol IpProtocol, RangeSet<Integer> ports) {
this.ipProtocol = checkNotNull(IpProtocol);
this.ports = ports == null ? TreeRangeSet.<Integer>create() : ports;
}
@ -279,7 +263,7 @@ public final class Firewall extends Resource {
*
* @return this is the IP protocol that is allowed for this rule.
*/
public IPProtocol getIPProtocol() {
public IpProtocol getIpProtocol() {
return ipProtocol;
}
@ -320,7 +304,7 @@ public final class Firewall extends Resource {
*/
public Objects.ToStringHelper string() {
return toStringHelper(this)
.add("IPProtocol", ipProtocol).add("ports", ports);
.add("IpProtocol", ipProtocol).add("ports", ports);
}
/**
@ -341,14 +325,14 @@ public final class Firewall extends Resource {
public static final class Builder {
private IPProtocol ipProtocol;
private IpProtocol ipProtocol;
private RangeSet<Integer> ports = TreeRangeSet.create();
/**
* @see org.jclouds.googlecomputeengine.domain.Firewall.Rule#getIPProtocol()
* @see org.jclouds.googlecomputeengine.domain.Firewall.Rule#getIpProtocol()
*/
public Builder IPProtocol(IPProtocol IPProtocol) {
this.ipProtocol = IPProtocol;
public Builder IpProtocol(IpProtocol IpProtocol) {
this.ipProtocol = IpProtocol;
return this;
}
@ -384,7 +368,7 @@ public final class Firewall extends Resource {
}
public Builder fromFirewallRule(Rule firewallRule) {
return new Builder().IPProtocol(firewallRule.getIPProtocol()).ports(firewallRule.getPorts());
return new Builder().IpProtocol(firewallRule.getIpProtocol()).ports(firewallRule.getPorts());
}
}

View File

@ -178,7 +178,7 @@ public class Project extends Resource {
"metric", "usage", "limit"
})
protected Quota(String metric, Double usage, Double limit) {
this.metric = checkNotNull(metric, "metric");
this.metric = metric != null ? metric : "undefined";
this.usage = checkNotNull(usage, "usage");
this.limit = checkNotNull(limit, "limit");
}

View File

@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecomputeengine.domain.internal;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/**
* Container for network, IPv4 range and optional gateway, for creation caching
*/
public class NetworkAndAddressRange {
protected final String name;
protected final String ipV4Range;
protected final Optional<String> gateway;
@ConstructorProperties({
"name", "ipV4Range", "gateway"
})
public NetworkAndAddressRange(String name, String ipV4Range, @Nullable String gateway) {
this.name = checkNotNull(name, "name");
this.ipV4Range = checkNotNull(ipV4Range, "ipV4Range");
this.gateway = fromNullable(gateway);
}
public String getName() {
return name;
}
public String getIpV4Range() {
return ipV4Range;
}
@Nullable
public Optional<String> getGateway() {
return gateway;
}
@Override
public int hashCode() {
// We only do hashcode/equals on name.
// the ip v4 range and gateway are included for creation rather than caching.
return Objects.hashCode(name);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
NetworkAndAddressRange that = NetworkAndAddressRange.class.cast(obj);
return equal(this.name, that.name);
}
protected ToStringHelper string() {
return toStringHelper(this)
.omitNullValues()
.add("name", name)
.add("ipV4Range", ipV4Range)
.add("gateway", gateway.orNull());
}
@Override
public String toString() {
return string().toString();
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.util.Predicates2.retry;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
/**
* @author Andrew Bayer
*/
@Singleton
public class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
protected final GoogleComputeEngineApi api;
protected final Supplier<String> userProject;
private final Predicate<AtomicReference<Operation>> operationDonePredicate;
private final long operationCompleteCheckInterval;
private final long operationCompleteCheckTimeout;
@Inject
public CreateNetworkIfNeeded(GoogleComputeEngineApi api,
@UserProject Supplier<String> userProject,
@Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
this.api = checkNotNull(api, "api");
this.userProject = checkNotNull(userProject, "userProject");
this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
"operation completed check interval");
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
"operation completed check timeout");
this.operationDonePredicate = operationDonePredicate;
}
@Override
public Network apply(NetworkAndAddressRange input) {
checkNotNull(input, "input");
try {
if (input.getGateway().isPresent()) {
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
.get()).createInIPv4RangeWithGateway(input.getName(), input.getIpV4Range(), input.getGateway().get()));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
} else {
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
.get()).createInIPv4Range(input.getName(), input.getIpV4Range()));
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
MILLISECONDS).apply(operation);
checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
}
return checkNotNull(api.getNetworkApiForProject(userProject.get()).get(input.getName()),
"no network with name %s was found", input.getName());
} catch (IllegalStateException e) {
return api.getNetworkApiForProject(userProject.get()).get(input.getName());
}
}
}

View File

@ -39,7 +39,7 @@ public class GlobalOperationDonePredicate implements Predicate<AtomicReference<O
private final Supplier<String> project;
@Inject
GlobalOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
public GlobalOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
this.api = api;
this.project = project;
}

View File

@ -0,0 +1,123 @@
/*
* 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.predicates;
import static com.google.common.collect.Collections2.transform;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
public class NetworkFirewallPredicates {
public static Predicate<Firewall> hasProtocol(final IpProtocol protocol) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall fw) {
return Predicates.in(transform(fw.getAllowed(), new Function<Rule, IpProtocol>() {
@Override
public IpProtocol apply(Rule input) {
return input.getIpProtocol();
}
})).apply(protocol);
}
};
}
public static Predicate<Firewall> hasPortRange(final Range<Integer> portRange) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall fw) {
return Iterables.any(fw.getAllowed(), new Predicate<Rule>() {
@Override
public boolean apply(Rule input) {
return input.getPorts().encloses(portRange);
}
});
}
};
}
public static Predicate<Firewall> hasSourceTag(final String sourceTag) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall input) {
return input.getSourceTags() != null && input.getSourceTags().contains(sourceTag);
}
};
}
public static Predicate<Firewall> hasSourceRange(final String sourceRange) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall input) {
return input.getSourceRanges() != null && input.getSourceRanges().contains(sourceRange);
}
};
}
public static Predicate<Firewall> equalsIpPermission(final IpPermission permission) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall input) {
return Iterables.elementsEqual(permission.getGroupIds(), input.getSourceTags())
&& Iterables.elementsEqual(permission.getCidrBlocks(), input.getSourceRanges())
&& (input.getAllowed().size() == 1
&& ruleEqualsIpPermission(permission).apply(Iterables.getOnlyElement(input.getAllowed())));
}
};
}
public static Predicate<Firewall> providesIpPermission(final IpPermission permission) {
return new Predicate<Firewall>() {
@Override
public boolean apply(Firewall input) {
return ((permission.getGroupIds().size() == 0 && input.getSourceTags().size() == 0)
|| Sets.intersection(permission.getGroupIds(), input.getSourceTags()).size() > 0)
&& ((permission.getCidrBlocks().size() == 0 && input.getSourceRanges().size() == 0)
|| Sets.intersection(permission.getCidrBlocks(), input.getSourceRanges()).size() > 0)
&& hasProtocol(permission.getIpProtocol()).apply(input)
&& ((permission.getFromPort() == 0 && permission.getToPort() == 0)
|| hasPortRange(Range.closed(permission.getFromPort(), permission.getToPort())).apply(input));
}
};
}
private static Predicate<Firewall.Rule> ruleEqualsIpPermission(final IpPermission permission) {
return new Predicate<Rule>() {
@Override
public boolean apply(Firewall.Rule input) {
return permission.getIpProtocol().equals(input.getIpProtocol())
&& ((input.getPorts().isEmpty() && permission.getFromPort() == 0 && permission.getToPort() == 0)
|| (input.getPorts().asRanges().size() == 1
&& permission.getFromPort() == Iterables.getOnlyElement(input.getPorts().asRanges()).lowerEndpoint()
&& permission.getToPort() == Iterables.getOnlyElement(input.getPorts().asRanges()).upperEndpoint()));
}
};
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.extensions;
import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
import org.testng.annotations.Test;
/**
* @author Andrew Bayer
*/
@Test(groups = "live", singleThreaded = true, testName = "GoogleComputeEngineSecurityGroupExtensionLiveTest")
public class GoogleComputeEngineSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
public GoogleComputeEngineSecurityGroupExtensionLiveTest() {
provider = "google-compute-engine";
}
}

View File

@ -0,0 +1,93 @@
/*
* 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.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
public class FirewallToIpPermissionTest {
@Test
public void testApply() {
Firewall fw = fwForTest();
FirewallToIpPermission converter = new FirewallToIpPermission();
Iterable<IpPermission> perms = converter.apply(fw);
assertEquals(Iterables.size(perms), 3, "There should be three IpPermissions but there is only " + Iterables.size(perms));
assertTrue(Iterables.any(perms, Predicates.and(hasProtocol(IpProtocol.TCP),
hasStartAndEndPort(1, 10))), "No permission found for TCP, ports 1-10");
assertTrue(Iterables.any(perms, Predicates.and(hasProtocol(IpProtocol.TCP),
hasStartAndEndPort(33, 33))), "No permission found for TCP, port 33");
assertTrue(Iterables.any(perms, hasProtocol(IpProtocol.ICMP)),
"No permission found for ICMP");
}
public static Firewall fwForTest() {
Firewall.Builder builder = Firewall.builder();
builder.addSourceRange("0.0.0.0/0");
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
.addPortRange(1, 10).build());
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
.addPort(33).build());
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.ICMP).build());
builder.id("abcd");
builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
builder.creationTimestamp(new Date());
builder.name("jclouds-test");
return builder.build();
}
public static Predicate<IpPermission> hasProtocol(final IpProtocol protocol) {
return new Predicate<IpPermission>() {
@Override
public boolean apply(IpPermission perm) {
return protocol.equals(perm.getIpProtocol());
}
};
}
public static Predicate<IpPermission> hasStartAndEndPort(final int startPort, final int endPort) {
return new Predicate<IpPermission>() {
@Override
public boolean apply(IpPermission perm) {
return startPort == perm.getFromPort() && endPort == perm.getToPort();
}
};
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.hasProtocol;
import static org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.hasStartAndEndPort;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import org.jclouds.collect.IterableWithMarkers;
import org.jclouds.collect.PagedIterables;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.features.FirewallApi;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.googlecomputeengine.options.ListOptions.Builder;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
public class NetworkToSecurityGroupTest {
@Test
public void testApply() {
Supplier<String> projectSupplier = new Supplier<String>() {
@Override
public String get() {
return "myproject";
}
};
FirewallToIpPermission fwToPerm = new FirewallToIpPermission();
GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
FirewallApi fwApi = createMock(FirewallApi.class);
ListOptions options = new Builder().filter("network eq .*/jclouds-test");
expect(api.getFirewallApiForProject(projectSupplier.get()))
.andReturn(fwApi);
expect(fwApi.list(options)).andReturn(PagedIterables.of(IterableWithMarkers.from(ImmutableSet.of(FirewallToIpPermissionTest.fwForTest()))));
replay(api, fwApi);
Network.Builder builder = Network.builder();
builder.id("abcd");
builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
builder.creationTimestamp(new Date());
builder.description("some description");
builder.gatewayIPv4("1.2.3.4");
builder.IPv4Range("0.0.0.0/0");
builder.name("jclouds-test");
Network network = builder.build();
NetworkToSecurityGroup netToSg = new NetworkToSecurityGroup(fwToPerm, api, projectSupplier);
SecurityGroup group = netToSg.apply(network);
assertEquals(group.getId(), "jclouds-test");
assertEquals(group.getUri(), URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
assertEquals(group.getIpPermissions().size(), 3);
assertTrue(Iterables.any(group.getIpPermissions(), Predicates.and(hasProtocol(IpProtocol.TCP),
hasStartAndEndPort(1, 10))), "No permission found for TCP, ports 1-10");
assertTrue(Iterables.any(group.getIpPermissions(), Predicates.and(hasProtocol(IpProtocol.TCP),
hasStartAndEndPort(33, 33))), "No permission found for TCP, port 33");
assertTrue(Iterables.any(group.getIpPermissions(), hasProtocol(IpProtocol.ICMP)),
"No permission found for ICMP");
}
}

View File

@ -0,0 +1,144 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecomputeengine.compute.loaders;
import static com.google.common.base.Optional.fromNullable;
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.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
import org.jclouds.googlecomputeengine.features.NetworkApi;
import org.jclouds.googlecomputeengine.functions.CreateNetworkIfNeeded;
import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
/**
* @author Andrew Bayer
*/
public class FindNetworkOrCreateTest {
@Test
public void testLoadExisting() {
final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
final NetworkApi nwApi = createMock(NetworkApi.class);
Network network = Network.builder().IPv4Range("0.0.0.0/0")
.id("abcd").name("this-network")
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
.build();
final Supplier<String> userProject = new Supplier<String>() {
@Override
public String get() {
return "myproject";
}
};
expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
expect(nwApi.get("this-network")).andReturn(network);
replay(api, nwApi);
NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
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);
}
@Test
public void testLoadNew() {
final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
final NetworkApi nwApi = createMock(NetworkApi.class);
final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
Network network = Network.builder().IPv4Range("0.0.0.0/0")
.id("abcd").name("this-network")
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
.build();
Operation createOp = createMock(Operation.class);
final Supplier<String> userProject = new Supplier<String>() {
@Override
public String get() {
return "myproject";
}
};
expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0"))
.andReturn(createOp);
expect(globalApi.get("create-op")).andReturn(createOp);
// pre-creation
expect(nwApi.get("this-network")).andReturn(null);
// post-creation
expect(nwApi.get("this-network")).andReturn(network);
expect(createOp.getName()).andReturn("create-op");
expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
replay(api, nwApi, createOp, globalApi);
NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
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, globalApi, createOp);
}
}

View File

@ -21,7 +21,6 @@ import static com.google.common.collect.Iterables.transform;
import static java.lang.String.format;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
import static org.jclouds.io.Payloads.newStringPayload;
import static org.jclouds.util.Strings2.toStringAndClose;
import static org.testng.Assert.assertEquals;
@ -43,6 +42,7 @@ import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payload;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Function;
@ -147,7 +147,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
".com/compute/v1beta15/projects/myproject/global/networks/default"),
new FirewallOptions()
.addAllowedRule(Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")
@ -185,7 +185,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
.network(URI.create("https://www.googleapis" +
".com/compute/v1beta15/projects/myproject/global/networks/default"))
.addAllowedRule(Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")
@ -222,7 +222,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
.network(URI.create("https://www.googleapis" +
".com/compute/v1beta15/projects/myproject/global/networks/default"))
.addAllowedRule(Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")

View File

@ -17,7 +17,6 @@
package org.jclouds.googlecomputeengine.features;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@ -28,6 +27,7 @@ import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.googlecomputeengine.options.ListOptions;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -57,7 +57,7 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
FirewallOptions firewall = new FirewallOptions()
.addAllowedRule(
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22).build())
.addSourceRange("10.0.0.0/8")
.addSourceTag("tag1")
@ -79,7 +79,7 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.addTargetTag("tag2")
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()));
@ -96,11 +96,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22)
.build(),
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()))
.addSourceRange("10.0.0.0/8")
@ -119,11 +119,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22)
.build(),
Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()))
.addSourceRange("10.0.0.0/8")

View File

@ -0,0 +1,133 @@
/*
* 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.functions;
import static com.google.common.base.Optional.fromNullable;
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.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
import org.jclouds.googlecomputeengine.features.NetworkApi;
import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
/**
* @author Andrew Bayer
*/
public class CreateNetworkIfNeededTest {
@Test
public void testApply() {
final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
final NetworkApi nwApi = createMock(NetworkApi.class);
final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
Network network = Network.builder().IPv4Range("0.0.0.0/0")
.id("abcd").name("this-network")
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
.build();
Operation createOp = createMock(Operation.class);
final Supplier<String> userProject = new Supplier<String>() {
@Override
public String get() {
return "myproject";
}
};
expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0"))
.andReturn(createOp);
expect(globalApi.get("create-op")).andReturn(createOp);
expect(nwApi.get("this-network")).andReturn(network);
expect(createOp.getName()).andReturn("create-op");
expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
replay(api, nwApi, createOp, globalApi);
NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
assertEquals(creator.apply(input), network);
verify(api, nwApi, globalApi, createOp);
}
@Test
public void testApplyWithGateway() {
final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
final NetworkApi nwApi = createMock(NetworkApi.class);
final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
Network network = Network.builder().IPv4Range("0.0.0.0/0")
.id("abcd").name("this-network").gatewayIPv4("1.2.3.4")
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
.build();
Operation createOp = createMock(Operation.class);
final Supplier<String> userProject = new Supplier<String>() {
@Override
public String get() {
return "myproject";
}
};
expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
expect(nwApi.createInIPv4RangeWithGateway("this-network", "0.0.0.0/0", "1.2.3.4"))
.andReturn(createOp);
expect(globalApi.get("create-op")).andReturn(createOp);
expect(nwApi.get("this-network")).andReturn(network);
expect(createOp.getName()).andReturn("create-op");
expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
replay(api, nwApi, createOp, globalApi);
NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", "1.2.3.4");
GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
assertEquals(creator.apply(input), network);
verify(api, nwApi, globalApi, createOp);
}
}

View File

@ -26,6 +26,7 @@ import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.ListPage;
import org.jclouds.googlecomputeengine.domain.Resource;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -61,7 +62,7 @@ public class ParseFirewallListTest extends BaseGoogleComputeEngineParseTest<List
".com/compute/v1beta15/projects/google/global/networks/default"))
.addSourceRange("0.0.0.0/0")
.addAllowed(Firewall.Rule.builder()
.IPProtocol(Firewall.Rule.IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPort(22).build())
.build()
))

View File

@ -16,8 +16,6 @@
*/
package org.jclouds.googlecomputeengine.parse;
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
import java.net.URI;
import javax.ws.rs.Consumes;
@ -26,6 +24,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
/**
@ -51,13 +50,13 @@ public class ParseFirewallTest extends BaseGoogleComputeEngineParseTest<Firewall
.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"))
.addSourceRange("10.0.0.0/8")
.addAllowed(Firewall.Rule.builder()
.IPProtocol(IPProtocol.TCP)
.IpProtocol(IpProtocol.TCP)
.addPortRange(1, 65535).build())
.addAllowed(Firewall.Rule.builder()
.IPProtocol(IPProtocol.UDP)
.IpProtocol(IpProtocol.UDP)
.addPortRange(1, 65535).build())
.addAllowed(Firewall.Rule.builder()
.IPProtocol(IPProtocol.ICMP).build())
.IpProtocol(IpProtocol.ICMP).build())
.build();
}

View File

@ -0,0 +1,162 @@
/*
* 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.predicates;
import static org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.fwForTest;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.equalsIpPermission;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasPortRange;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasProtocol;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasSourceRange;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasSourceTag;
import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.providesIpPermission;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Date;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.Range;
@Test(groups = "unit")
public class NetworkFirewallPredicatesTest {
public static Firewall getFwForTestSourceTags() {
Firewall.Builder builder = Firewall.builder();
builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
builder.addSourceTag("tag-1");
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
.addPortRange(1, 10).build());
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
.addPort(33).build());
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.ICMP).build());
builder.id("abcd");
builder.creationTimestamp(new Date());
builder.name("jclouds-test");
return builder.build();
}
public static Firewall getFwForTestSourceTagsExact() {
Firewall.Builder builder = Firewall.builder();
builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
builder.addSourceTag("tag-1");
builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
.addPortRange(1, 10).build());
builder.id("abcd");
builder.creationTimestamp(new Date());
builder.name("jclouds-test");
return builder.build();
}
@Test
public void testHasProtocol() {
assertTrue(hasProtocol(IpProtocol.TCP).apply(fwForTest()),
"Firewall " + fwForTest() + " should contain a TCP rule.");
}
@Test
public void testHasProtocolFails() {
assertFalse(hasProtocol(IpProtocol.UDP).apply(fwForTest()),
"Firewall " + fwForTest() + " should NOT contain a UDP rule.");
}
@Test
public void testHasPortRange() {
assertTrue(hasPortRange(Range.closed(2, 9)).apply(fwForTest()),
"Firewall " + fwForTest() + " should contain the port range 2-9.");
}
@Test
public void testHasPortRangeFails() {
assertFalse(hasPortRange(Range.closed(11, 15)).apply(fwForTest()),
"Firewall " + fwForTest() + " should NOT contain the port range 11-15.");
}
@Test
public void testHasSourceTag() {
assertTrue(hasSourceTag("tag-1").apply(getFwForTestSourceTags()),
"Firewall " + getFwForTestSourceTags() + " should contain the source tag 'tag-1'.");
}
@Test
public void testHasSourceTagFails() {
assertFalse(hasSourceTag("tag-1").apply(fwForTest()),
"Firewall " + fwForTest() + " should NOT contain the source tag 'tag-1'.");
}
@Test
public void testHasSourceRange() {
assertTrue(hasSourceRange("0.0.0.0/0").apply(fwForTest()),
"Firewall " + fwForTest() + " should contain the source range '0.0.0.0/0'.");
}
@Test
public void testHasSourceRangeFails() {
assertFalse(hasSourceRange("0.0.0.0/0").apply(getFwForTestSourceTags()),
"Firewall " + getFwForTestSourceTags() + " should NOT contain the source range '0.0.0.0/0'.");
}
@Test
public void testEqualsIpPermission() {
IpPermission perm = IpPermission.builder().groupId("tag-1")
.fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
assertTrue(equalsIpPermission(perm).apply(getFwForTestSourceTagsExact()),
"Firewall " + getFwForTestSourceTagsExact() + " should match IpPermission " + perm + " but does not.");
}
@Test
public void testEqualsIpPermissionFails() {
IpPermission perm = IpPermission.builder().groupId("tag-1")
.fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
assertFalse(equalsIpPermission(perm).apply(getFwForTestSourceTags()),
"Firewall " + getFwForTestSourceTags() + " should not match IpPermission " + perm + " but does.");
}
@Test
public void testProvidesIpPermission() {
IpPermission perm = IpPermission.builder().groupId("tag-1")
.fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
assertTrue(providesIpPermission(perm).apply(getFwForTestSourceTagsExact()),
"Firewall " + getFwForTestSourceTagsExact() + " should provide IpPermission " + perm + " but does not.");
assertTrue(providesIpPermission(perm).apply(getFwForTestSourceTags()),
"Firewall " + getFwForTestSourceTags() + " should inexactly provide IpPermission " + perm + " but does not.");
}
@Test
public void testProvidesIpPermissionFails() {
IpPermission perm = IpPermission.builder().groupId("tag-1")
.fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
assertFalse(providesIpPermission(perm).apply(fwForTest()),
"Firewall " + fwForTest() + " should not provide IpPermission " + perm + " but does.");
}
}