Adding StubSecurityGroupExtension and some changes to the builder
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/7caa60ec Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/7caa60ec Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/7caa60ec Branch: refs/heads/jclouds-101 Commit: 7caa60ec71c950e35deb2c3dc47760cc13d1212a Parents: 7cc2124 Author: Andrew Bayer <[email protected]> Authored: Tue Jun 11 15:56:01 2013 -0700 Committer: Andrew Bayer <[email protected]> Committed: Tue Jun 11 15:56:01 2013 -0700 ---------------------------------------------------------------------- .../compute/domain/SecurityGroupBuilder.java | 5 + .../extensions/SecurityGroupExtension.java | 54 ++++- .../config/StubComputeServiceContextModule.java | 10 + .../StubComputeServiceDependenciesModule.java | 39 ++++ .../extensions/StubSecurityGroupExtension.java | 210 +++++++++++++++++++ 5 files changed, 317 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7caa60ec/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java index 346b0f1..f0c7b6a 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java +++ b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java @@ -40,6 +40,11 @@ public class SecurityGroupBuilder extends ComputeMetadataBuilder { super(ComputeType.SECURITYGROUP); } + public SecurityGroupBuilder ipPermissions() { + this.ipPermissions = ImmutableSet.<IpPermission> builder(); + return this; + } + public SecurityGroupBuilder ipPermissions(Iterable<IpPermission> ipPermissions) { this.ipPermissions.addAll(checkNotNull(ipPermissions, "ipPermissions")); return this; http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7caa60ec/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java index bb7f856..5abfcaa 100644 --- a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java +++ b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java @@ -21,6 +21,7 @@ import org.jclouds.domain.Location; import org.jclouds.net.domain.IpPermission; import org.jclouds.net.domain.IpProtocol; +import com.google.common.collect.Multimap; import com.google.common.util.concurrent.ListenableFuture; /** @@ -44,6 +45,14 @@ public interface SecurityGroupExtension { SecurityGroup createSecurityGroup(String name, Location location); /** + * Remove an existing @{link SecurityGroup}, and its permissions. + * + * @param id + * The id of the SecurityGroup to delete. + */ + void removeSecurityGroup(String id); + + /** * Add a @{link IpPermission} to an existing @{link SecurityGroup}. Applies the permission to the * security group on the provider. * @@ -57,6 +66,19 @@ public interface SecurityGroupExtension { SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group); /** + * Remove a @{link IpPermission} from an existing @{link SecurityGroup}. Removes the permission from the + * security group on the provider. + * + * @param rule + * The IpPermission to remove. + * @param group + * The SecurityGroup to remove the permission from. + * + * @return The SecurityGroup with the permission removed, after the permission has been removed on the provider. + */ + SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group); + + /** * Add a @{link IpPermission} to an existing @{link SecurityGroup}, based on the parameters given. * Applies the permission to the security group on the provider. * @@ -66,6 +88,8 @@ public interface SecurityGroupExtension { * The first port in the range to be opened, or -1 for ICMP. * @param endPort * The last port in the range to be opened, or -1 for ICMP. + * @param tenantIdGroupNamePairs + * source of traffic allowed is on basis of another group in a tenant, as opposed to by cidr * @param ipRanges * An Iterable of Strings representing the IP range(s) the permission should allow. * @param groupIds @@ -75,7 +99,35 @@ public interface SecurityGroupExtension { * * @return The SecurityGroup with the new permission added, after the permission has been applied on the provider. */ - SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort, Iterable<String> ipRanges, + SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort, + Multimap<String, String> tenantIdGroupNamePairs, + Iterable<String> ipRanges, Iterable<String> groupIds, SecurityGroup group); + + /** + * Remove a @{link IpPermission} from an existing @{link SecurityGroup}, based on the parameters given. + * Removes the permission from the security group on the provider. + * + * @param protocol + * The @{link IpProtocol} for the permission. + * @param startPort + * The first port in the range to be opened, or -1 for ICMP. + * @param endPort + * The last port in the range to be opened, or -1 for ICMP. + * @param tenantIdGroupNamePairs + * source of traffic allowed is on basis of another group in a tenant, as opposed to by cidr + * @param ipRanges + * An Iterable of Strings representing the IP range(s) the permission should allow. + * @param groupIds + * An Iterable of @{link SecurityGroup} IDs this permission should allow. + * @param group + * The SecurityGroup to remove the permission from. + * + * @return The SecurityGroup with the permission removed, after the permission has been removed from the provider. + */ + SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort, + Multimap<String, String> tenantIdGroupNamePairs, + Iterable<String> ipRanges, + Iterable<String> groupIds, SecurityGroup group); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7caa60ec/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java index 91e858a..ab381b3 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java @@ -17,8 +17,12 @@ package org.jclouds.compute.stub.config; import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule; +import org.jclouds.compute.extensions.SecurityGroupExtension; import org.jclouds.concurrent.SingleThreaded; +import com.google.common.base.Optional; +import com.google.inject.Injector; + /** * * @author Adrian Cole @@ -35,4 +39,10 @@ public class StubComputeServiceContextModule extends JCloudsNativeComputeService install(new StubComputeServiceDependenciesModule()); super.configure(); } + + @Override + protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) { + return Optional.of(i.getInstance(SecurityGroupExtension.class)); + } + } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7caa60ec/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java index de28ee1..b6f22cb 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java @@ -29,8 +29,11 @@ import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata.Status; import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.SecurityGroup; import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.internal.VolumeImpl; +import org.jclouds.compute.extensions.SecurityGroupExtension; +import org.jclouds.compute.stub.extensions.StubSecurityGroupExtension; import org.jclouds.domain.Credentials; import org.jclouds.location.Provider; import org.jclouds.predicates.SocketOpen; @@ -43,6 +46,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.net.HostAndPort; import com.google.inject.AbstractModule; import com.google.inject.Provides; +import com.google.inject.TypeLiteral; /** * @@ -52,6 +56,8 @@ public class StubComputeServiceDependenciesModule extends AbstractModule { @Override protected void configure() { + bind(new TypeLiteral<SecurityGroupExtension>() { + }).to(StubSecurityGroupExtension.class); } @@ -73,6 +79,23 @@ public class StubComputeServiceDependenciesModule extends AbstractModule { return backing.get(creds.get().identity); } + protected static final LoadingCache<String, ConcurrentMap<String, SecurityGroup>> groupBacking = CacheBuilder.newBuilder() + .build(new CacheLoader<String, ConcurrentMap<String, SecurityGroup>>() { + + @Override + public ConcurrentMap<String, SecurityGroup> load(String arg0) throws Exception { + return new ConcurrentHashMap<String, SecurityGroup>(); + } + + }); + + @Provides + @Singleton + protected ConcurrentMap<String, SecurityGroup> provideGroups(@Provider Supplier<Credentials> creds) + throws ExecutionException { + return groupBacking.get(creds.get().identity); + } + protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build( new CacheLoader<String, AtomicInteger>() { @@ -89,6 +112,22 @@ public class StubComputeServiceDependenciesModule extends AbstractModule { return nodeIds.get(creds.get().identity).incrementAndGet(); } + protected static final LoadingCache<String, AtomicInteger> groupIds = CacheBuilder.newBuilder().build( + new CacheLoader<String, AtomicInteger>() { + + @Override + public AtomicInteger load(String arg0) throws Exception { + return new AtomicInteger(0); + } + + }); + + @Provides + @Named("GROUP_ID") + protected Integer provideGroupIdForIdentity(@Provider Supplier<Credentials> creds) throws ExecutionException { + return groupIds.get(creds.get().identity).incrementAndGet(); + } + @Singleton @Provides @Named("PUBLIC_IP_PREFIX") http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7caa60ec/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java new file mode 100644 index 0000000..797dbd5 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java @@ -0,0 +1,210 @@ +/* + * 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.compute.stub.extensions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.Iterables.filter; + +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +import org.jclouds.Constants; +import org.jclouds.compute.domain.SecurityGroup; +import org.jclouds.compute.domain.SecurityGroupBuilder; +import org.jclouds.compute.extensions.SecurityGroupExtension; +import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.all.JustProvider; +import org.jclouds.net.domain.IpPermission; +import org.jclouds.net.domain.IpProtocol; + +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; + +/** + * An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation + * is optional by providers. + * + * @author Andrew Bayer + */ +public class StubSecurityGroupExtension implements SecurityGroupExtension { + + private final Supplier<Location> location; + private final Provider<Integer> idProvider; + private final Supplier<Set<? extends Location>> locationSupplier; + private final ListeningExecutorService ioExecutor; + private final ConcurrentMap<String, SecurityGroup> groups; + + @Inject + public StubSecurityGroupExtension(ConcurrentMap<String, SecurityGroup> groups, + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, + Supplier<Location> location, + @Named("GROUP_ID") Provider<Integer> idProvider, + JustProvider locationSupplier) { + this.groups = groups; + this.ioExecutor = ioExecutor; + this.location = location; + this.idProvider = idProvider; + this.locationSupplier = locationSupplier; + } + + @Override + public SecurityGroup createSecurityGroup(String name, Location location) { + SecurityGroupBuilder builder = new SecurityGroupBuilder(); + + String id = idProvider.get() + ""; + builder.ids(id); + builder.name(name); + builder.location(location); + + SecurityGroup group = builder.build(); + + groups.put(group.getId(), group); + + return group; + } + + @Override + public void removeSecurityGroup(String id) { + if (groups.containsKey(id)) { + groups.remove(id); + } + } + + @Override + public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) { + SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group")); + + builder.ipPermission(checkNotNull(ipPermission, "ipPermission")); + + SecurityGroup newGroup = builder.build(); + + if (groups.containsKey(newGroup.getId())) { + groups.remove(newGroup.getId()); + } + + groups.put(newGroup.getId(), newGroup); + + return newGroup; + } + + @Override + public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort, + Multimap<String, String> tenantIdGroupNamePairs, + Iterable<String> ipRanges, + Iterable<String> groupIds, SecurityGroup group) { + IpPermission.Builder ipBuilder = IpPermission.builder(); + + ipBuilder.ipProtocol(protocol); + ipBuilder.fromPort(startPort); + ipBuilder.toPort(endPort); + if (tenantIdGroupNamePairs.size() > 0) { + ipBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs); + } + if (Iterables.size(ipRanges) > 0) { + ipBuilder.cidrBlocks(ipRanges); + } + if (Iterables.size(groupIds) > 0) { + ipBuilder.groupIds(groupIds); + } + + IpPermission perm = ipBuilder.build(); + + SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group")); + + builder.ipPermission(perm); + + SecurityGroup newGroup = builder.build(); + + if (groups.containsKey(newGroup.getId())) { + groups.remove(newGroup.getId()); + } + + groups.put(newGroup.getId(), newGroup); + + return newGroup; + } + + @Override + public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) { + SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group")); + + builder.ipPermissions(); + + builder.ipPermissions(filter(group.getIpPermissions(), not(equalTo(ipPermission)))); + + SecurityGroup newGroup = builder.build(); + + if (groups.containsKey(newGroup.getId())) { + groups.remove(newGroup.getId()); + } + + groups.put(newGroup.getId(), newGroup); + + return newGroup; + } + + + @Override + public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort, + Multimap<String, String> tenantIdGroupNamePairs, + Iterable<String> ipRanges, + Iterable<String> groupIds, SecurityGroup group) { + IpPermission.Builder ipBuilder = IpPermission.builder(); + + ipBuilder.ipProtocol(protocol); + ipBuilder.fromPort(startPort); + ipBuilder.toPort(endPort); + if (tenantIdGroupNamePairs.size() > 0) { + ipBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs); + } + if (Iterables.size(ipRanges) > 0) { + ipBuilder.cidrBlocks(ipRanges); + } + if (Iterables.size(groupIds) > 0) { + ipBuilder.groupIds(groupIds); + } + + IpPermission perm = ipBuilder.build(); + + SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group")); + + builder.ipPermissions(); + + builder.ipPermissions(filter(group.getIpPermissions(), not(equalTo(perm)))); + + SecurityGroup newGroup = builder.build(); + + if (groups.containsKey(newGroup.getId())) { + groups.remove(newGroup.getId()); + } + + groups.put(newGroup.getId(), newGroup); + + return newGroup; + } +}
