You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/10/11 14:04:32 UTC

git commit: Allow to configure CIDR exclusion blocks

Repository: jclouds
Updated Branches:
  refs/heads/master 2caf6ea86 -> e5fb0b607


Allow to configure CIDR exclusion blocks


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/e5fb0b60
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/e5fb0b60
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/e5fb0b60

Branch: refs/heads/master
Commit: e5fb0b607d763530647a1f97848f95158cb88ffb
Parents: 2caf6ea
Author: Ignasi Barrera <na...@apache.org>
Authored: Fri Oct 10 00:47:53 2014 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Sat Oct 11 14:04:00 2014 +0200

----------------------------------------------------------------------
 .../CloudStackSecurityGroupExtension.java       |  5 ++
 .../extensions/EC2SecurityGroupExtension.java   |  5 ++
 .../org/jclouds/ec2/util/IpPermissions.java     |  2 +-
 ...scribeSecurityGroupsResponseHandlerTest.java |  8 +--
 .../extensions/NovaSecurityGroupExtension.java  |  6 ++
 .../extensions/SecurityGroupExtension.java      |  7 ++
 .../extensions/StubSecurityGroupExtension.java  |  5 ++
 .../org/jclouds/net/domain/IpPermission.java    | 76 +++++++++++++++-----
 .../org/jclouds/net/util/IpPermissions.java     | 25 +++++--
 .../BaseSecurityGroupExtensionLiveTest.java     | 64 ++++++++++++++++-
 .../org/jclouds/net/util/IpPermissionsTest.java | 39 ++++++++++
 11 files changed, 209 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/extensions/CloudStackSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/extensions/CloudStackSecurityGroupExtension.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/extensions/CloudStackSecurityGroupExtension.java
index 70f7728..da1ab84 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/extensions/CloudStackSecurityGroupExtension.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/extensions/CloudStackSecurityGroupExtension.java
@@ -279,4 +279,9 @@ public class CloudStackSecurityGroupExtension implements SecurityGroupExtension
       return false;
    }
 
+    @Override
+    public boolean supportsExclusionCidrBlocks() {
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
index 612b529..6160fe6 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
@@ -333,6 +333,11 @@ public class EC2SecurityGroupExtension implements SecurityGroupExtension {
       return false;
    }
 
+   @Override
+   public boolean supportsExclusionCidrBlocks() {
+      return false;
+   }
+
    protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> pollSecurityGroups() {
       Iterable<? extends Set<? extends org.jclouds.ec2.domain.SecurityGroup>> groups
          = transform(regions.get(), allSecurityGroupsInRegion());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/apis/ec2/src/main/java/org/jclouds/ec2/util/IpPermissions.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/util/IpPermissions.java b/apis/ec2/src/main/java/org/jclouds/ec2/util/IpPermissions.java
index 5b26f48..36fe18e 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/util/IpPermissions.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/util/IpPermissions.java
@@ -42,7 +42,7 @@ public class IpPermissions extends IpPermission {
    protected IpPermissions(IpProtocol ipProtocol, int fromPort, int toPort,
          Multimap<String, String> userIdGroupPairs, Iterable<String> groupIds, Iterable<String> ipRanges) {
       super(ipProtocol, fromPort, toPort, userIdGroupPairs, groupIds, userIdGroupPairs.isEmpty() ? ipRanges
-            : ImmutableSet.<String> of());
+            : ImmutableSet.<String> of(), ImmutableSet.<String> of());
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeSecurityGroupsResponseHandlerTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeSecurityGroupsResponseHandlerTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeSecurityGroupsResponseHandlerTest.java
index d534b01..6e81bd1 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeSecurityGroupsResponseHandlerTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeSecurityGroupsResponseHandlerTest.java
@@ -46,10 +46,10 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
       Set<SecurityGroup> expected = ImmutableSet.of(
             new SecurityGroup(defaultRegion, "sg-3c6ef654", "WebServers", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers",
                   ImmutableSet.of(new IpPermission(IpProtocol.TCP, 80, 80, ImmutableMultimap.<String, String> of(),
-                        ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0")))),
+                        ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0"), ImmutableSet.<String> of()))),
             new SecurityGroup(defaultRegion, "sg-867309ab", "RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Group A",
                   ImmutableSet.of(new IpPermission(IpProtocol.TCP, 6000, 7000, ImmutableMultimap
-                        .<String, String> of(), ImmutableSet.<String> of(), ImmutableSet.<String> of()))));
+                        .<String, String> of(), ImmutableSet.<String> of(), ImmutableSet.<String> of(), ImmutableSet.<String> of()))));
 
       DescribeSecurityGroupsResponseHandler handler = injector.getInstance(DescribeSecurityGroupsResponseHandler.class);
       addDefaultRegionToHandler(handler);
@@ -70,9 +70,9 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
             new SecurityGroup(defaultRegion, "sg-3c6ef654", "jclouds#cluster#world", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Cluster",
                   ImmutableSet.of(
                         new IpPermission(IpProtocol.TCP, 22, 22, ImmutableMultimap.<String, String> of(),
-                              ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0")),
+                              ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0"), ImmutableSet.<String> of()),
                         new IpPermission(IpProtocol.ALL, -1, -1, userIdGroupPairs,
-                              ImmutableSet.<String> of(), ImmutableSet.<String> of()))));
+                              ImmutableSet.<String> of(), ImmutableSet.<String> of(), ImmutableSet.<String> of()))));
 
       DescribeSecurityGroupsResponseHandler handler = injector.getInstance(DescribeSecurityGroupsResponseHandler.class);
       addDefaultRegionToHandler(handler);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
index c6f78b4..1a5c4fe 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
@@ -330,6 +330,11 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
       return false;
    }
 
+   @Override
+   public boolean supportsExclusionCidrBlocks() {
+       return false;
+   }
+
    protected Iterable<? extends SecurityGroupInRegion> pollSecurityGroups() {
       Iterable<? extends Set<? extends SecurityGroupInRegion>> groups
               = transform(regionIds.get(), allSecurityGroupsInRegion());
@@ -368,4 +373,5 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
          }
       };
    }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/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 d165dec..26a3a67 100644
--- a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
+++ b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
@@ -23,6 +23,7 @@ import org.jclouds.domain.Location;
 import org.jclouds.net.domain.IpPermission;
 import org.jclouds.net.domain.IpProtocol;
 
+import com.google.common.annotations.Beta;
 import com.google.common.collect.Multimap;
 
 /**
@@ -180,4 +181,10 @@ public interface SecurityGroupExtension {
     */
    boolean supportsPortRangesForGroups();
    
+   /**
+    * Returns true if this SecurityGroupExtension supports exclusion CIDR groups.
+    */
+   @Beta
+   boolean supportsExclusionCidrBlocks();
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/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
index 4a57d73..f0f219f 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
@@ -245,4 +245,9 @@ public class StubSecurityGroupExtension implements SecurityGroupExtension {
    public boolean supportsPortRangesForGroups() {
       return true;
    }
+
+   @Override
+   public boolean supportsExclusionCidrBlocks() {
+      return true;
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/net/domain/IpPermission.java b/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
index 6ae7209..522acd8 100644
--- a/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
+++ b/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
@@ -56,6 +56,7 @@ public class IpPermission implements Comparable<IpPermission> {
       private Multimap<String, String> tenantIdGroupNamePairs = LinkedHashMultimap.create();
       private Set<String> groupIds = Sets.newLinkedHashSet();
       private Set<String> cidrBlocks = Sets.newLinkedHashSet();
+      private Set<String> exclusionCidrBlocks = Sets.newLinkedHashSet();
 
       /**
        * 
@@ -113,16 +114,39 @@ public class IpPermission implements Comparable<IpPermission> {
        * @see IpPermission#getCidrBlocks()
        */
       public Builder cidrBlocks(Iterable<String> cidrBlocks) {
-         Iterables.addAll(this.cidrBlocks, transform(cidrBlocks,
-                                                     new Function<String, String>() {
-                                                        @Override
-                                                        public String apply(String input) {
-                                                           checkArgument(isCidrFormat(input),
-                                                                         "input %s is not a valid CIDR",
-                                                                         input);
-                                                           return input;
-                                                        }
-                                                     }));
+         Iterables.addAll(this.cidrBlocks, transform(cidrBlocks, new Function<String, String>() {
+            @Override
+            public String apply(String input) {
+               checkArgument(isCidrFormat(input), "input %s is not a valid CIDR", input);
+               return input;
+            }
+         }));
+         return this;
+      }
+
+      /**
+       * @see IpPermission#getExclusionCidrBlocks()
+       */
+      @Beta
+      public Builder exclusionCidrBlock(String exclusionCidrBlock) {
+         checkArgument(isCidrFormat(exclusionCidrBlock), "exclusionCidrBlock %s is not a valid CIDR",
+               exclusionCidrBlock);
+         this.exclusionCidrBlocks.add(exclusionCidrBlock);
+         return this;
+      }
+
+      /**
+       * @see IpPermission#getExclusionCidrBlocks()
+       */
+      @Beta
+      public Builder exclusionCidrBlocks(Iterable<String> exclusionCidrBlocks) {
+         Iterables.addAll(this.exclusionCidrBlocks, transform(exclusionCidrBlocks, new Function<String, String>() {
+            @Override
+            public String apply(String input) {
+               checkArgument(isCidrFormat(input), "input %s is not a valid CIDR", input);
+               return input;
+            }
+         }));
          return this;
       }
 
@@ -143,7 +167,8 @@ public class IpPermission implements Comparable<IpPermission> {
       }
 
       public IpPermission build() {
-         return new IpPermission(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks);
+         return new IpPermission(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks,
+               exclusionCidrBlocks);
       }
    }
 
@@ -153,16 +178,19 @@ public class IpPermission implements Comparable<IpPermission> {
    private final Set<String> groupIds;
    private final IpProtocol ipProtocol;
    private final Set<String> cidrBlocks;
+   private final Set<String> exclusionCidrBlocks;
 
    public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
-            Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks) {
+         Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks,
+         Iterable<String> exclusionCidrBlocks) {
       this.fromPort = fromPort;
       this.toPort = toPort;
       this.tenantIdGroupNamePairs = ImmutableMultimap.copyOf(checkNotNull(tenantIdGroupNamePairs,
-               "tenantIdGroupNamePairs"));
+            "tenantIdGroupNamePairs"));
       this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
       this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds"));
       this.cidrBlocks = ImmutableSet.copyOf(checkNotNull(cidrBlocks, "cidrBlocks"));
+      this.exclusionCidrBlocks = ImmutableSet.copyOf(checkNotNull(exclusionCidrBlocks, "exclusionCidrBlocks"));
    }
 
    /**
@@ -217,6 +245,14 @@ public class IpPermission implements Comparable<IpPermission> {
       return cidrBlocks;
    }
 
+   /**
+    * source of traffic is a all but this exclusionCidrBlocks
+    */
+   @Beta
+   public Set<String> getExclusionCidrBlocks() {
+      return exclusionCidrBlocks;
+   }
+
    @Override
    public boolean equals(Object o) {
       if (this == o)
@@ -226,13 +262,15 @@ public class IpPermission implements Comparable<IpPermission> {
          return false;
       IpPermission that = IpPermission.class.cast(o);
       return equal(this.ipProtocol, that.ipProtocol) && equal(this.fromPort, that.fromPort)
-               && equal(this.toPort, that.toPort) && equal(this.tenantIdGroupNamePairs, that.tenantIdGroupNamePairs)
-               && equal(this.groupIds, that.groupIds) && equal(this.cidrBlocks, that.cidrBlocks);
+            && equal(this.toPort, that.toPort) && equal(this.tenantIdGroupNamePairs, that.tenantIdGroupNamePairs)
+            && equal(this.groupIds, that.groupIds) && equal(this.cidrBlocks, that.cidrBlocks)
+            && equal(this.exclusionCidrBlocks, that.exclusionCidrBlocks);
    }
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks);
+      return Objects.hashCode(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks,
+            exclusionCidrBlocks);
    }
 
    @Override
@@ -241,9 +279,9 @@ public class IpPermission implements Comparable<IpPermission> {
    }
 
    protected ToStringHelper string() {
-      return MoreObjects.toStringHelper("").add("ipProtocol", ipProtocol).add("fromPort", fromPort).add("toPort", toPort)
-               .add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds).add("cidrBlocks",
-                        cidrBlocks);
+      return MoreObjects.toStringHelper("").add("ipProtocol", ipProtocol).add("fromPort", fromPort)
+            .add("toPort", toPort).add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds)
+            .add("cidrBlocks", cidrBlocks).add("exclusionCidrBlocks", exclusionCidrBlocks);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/compute/src/main/java/org/jclouds/net/util/IpPermissions.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/net/util/IpPermissions.java b/compute/src/main/java/org/jclouds/net/util/IpPermissions.java
index ff3602a..cc92291 100644
--- a/compute/src/main/java/org/jclouds/net/util/IpPermissions.java
+++ b/compute/src/main/java/org/jclouds/net/util/IpPermissions.java
@@ -32,9 +32,11 @@ import com.google.common.collect.Multimap;
 public class IpPermissions extends IpPermission {
 
    protected IpPermissions(IpProtocol ipProtocol, int fromPort, int toPort,
-         Multimap<String, String> tenantIdGroupPairs, Iterable<String> groupIds, Iterable<String> cidrBlocks) {
+         Multimap<String, String> tenantIdGroupPairs, Iterable<String> groupIds, Iterable<String> cidrBlocks,
+         Iterable<String> exclusionCidrBlocks) {
       super(ipProtocol, fromPort, toPort, tenantIdGroupPairs, groupIds, tenantIdGroupPairs.size() == 0 ? cidrBlocks
-            : ImmutableSet.<String> of());
+            : ImmutableSet.<String> of(), tenantIdGroupPairs.size() == 0 ? exclusionCidrBlocks : ImmutableSet
+            .<String> of());
    }
 
    public static ICMPTypeSelection permitICMP() {
@@ -105,7 +107,7 @@ public class IpPermissions extends IpPermission {
 
       protected ToGroupSourceSelection(IpProtocol ipProtocol, int fromPort, int toPort) {
          super(ipProtocol, fromPort, toPort, ImmutableMultimap.<String, String> of(), ImmutableSet.<String> of(),
-               ImmutableSet.of("0.0.0.0/0"));
+               ImmutableSet.of("0.0.0.0/0"), ImmutableSet.<String> of());
       }
 
       public IpPermissions originatingFromSecurityGroupId(String groupId) {
@@ -114,7 +116,7 @@ public class IpPermissions extends IpPermission {
 
       public IpPermissions originatingFromSecurityGroupIds(Iterable<String> groupIds) {
          return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), getTenantIdGroupNamePairs(), groupIds,
-               ImmutableSet.<String> of());
+               ImmutableSet.<String> of(), ImmutableSet.<String> of());
       }
    }
 
@@ -128,8 +130,17 @@ public class IpPermissions extends IpPermission {
       }
 
       public IpPermissions originatingFromCidrBlocks(Iterable<String> cidrIps) {
-         return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(),
-               ImmutableMultimap.<String, String> of(), ImmutableSet.<String> of(), cidrIps);
+         return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), ImmutableMultimap.<String, String> of(),
+               ImmutableSet.<String> of(), cidrIps, ImmutableSet.<String> of());
+      }
+
+      public IpPermissions exceptOriginatingFromCidrBlock(String excludedCidrIp) {
+         return exceptOriginatingFromCidrBlocks(ImmutableSet.of(checkNotNull(excludedCidrIp, "excludedCidrIp")));
+      }
+
+      public IpPermissions exceptOriginatingFromCidrBlocks(Iterable<String> excludedCidrIps) {
+         return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), ImmutableMultimap.<String, String> of(),
+               ImmutableSet.<String> of(), ImmutableSet.<String> of(), excludedCidrIps);
       }
 
       public IpPermissions originatingFromTenantAndSecurityGroup(String tenantId, String groupName) {
@@ -139,7 +150,7 @@ public class IpPermissions extends IpPermission {
 
       public IpPermissions toTenantsGroupsNamed(Multimap<String, String> tenantIdGroupNamePairs) {
          return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), tenantIdGroupNamePairs, getGroupIds(),
-               ImmutableSet.<String> of());
+               ImmutableSet.<String> of(), ImmutableSet.<String> of());
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java b/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
index 258b8cb..06bd18b 100644
--- a/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
+++ b/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
@@ -17,6 +17,7 @@
 package org.jclouds.compute.extensions.internal;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Set;
@@ -311,9 +312,57 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
       
    }
 */
+
+   @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionsFromSpec")
+   public void testAddIpPermissionWithCidrExclusionGroup() {
+      skipIfSecurityGroupsNotSupported();
+
+      ComputeService computeService = view.getComputeService();
+
+      Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+      assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+      if (!securityGroupExtension.get().supportsExclusionCidrBlocks()) {
+         throw new SkipException("Test cannot run without CIDR exclusion groups available.");
+      }
+
+      Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+      assertTrue(optGroup.isPresent());
+      SecurityGroup group = optGroup.get();
+
+      IpPermission cidrExclusionPermission = createCidrExclusionPermission();
+      Set<IpPermission> expectedPermissions = ImmutableSet.of(cidrExclusionPermission);
+
+      SecurityGroup securityGriupWithExclusion = securityGroupExtension.get().addIpPermission(cidrExclusionPermission, group);
+
+      assertTrue(securityGriupWithExclusion.getIpPermissions().containsAll(expectedPermissions));
+   }
+
+   @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionWithCidrExclusionGroup")
+   public void testRemoveIpPermissionWithCidrExclusionGroup() {
+      skipIfSecurityGroupsNotSupported();
+
+      ComputeService computeService = view.getComputeService();
+
+      Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+      assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+      if (!securityGroupExtension.get().supportsExclusionCidrBlocks()) {
+         throw new SkipException("Test cannot run without CIDR exclusion groups available.");
+      }
+
+      Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+      assertTrue(optGroup.isPresent());
+      SecurityGroup group = optGroup.get();
+
+      IpPermission cidrExclusionPermission = createCidrExclusionPermission();
+
+      SecurityGroup emptyGroup = securityGroupExtension.get().removeIpPermission(cidrExclusionPermission, group);
+
+      assertFalse(emptyGroup.getIpPermissions().contains(cidrExclusionPermission));
+   }
+
    // testDeleteSecurityGroup currently disabled until I can find a way to get it to delete the security group while a terminated
    // instance is still floating around in EC2. - abayer, 6/14/13
-   @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionsFromSpec")
+   @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testRemoveIpPermissionWithCidrExclusionGroup", alwaysRun = true)
    public void testDeleteSecurityGroup() {
       skipIfSecurityGroupsNotSupported();
 
@@ -329,7 +378,7 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
       SecurityGroup group = optGroup.get();
       assertTrue(securityGroupExtension.get().removeSecurityGroup(group.getId()));
    }
-   
+
    private Multimap<String, String> emptyMultimap() {
       return LinkedHashMultimap.create();
    }
@@ -358,6 +407,17 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
       return builder.build();
    }
 
+   private IpPermission createCidrExclusionPermission() {
+      IpPermission.Builder builder = IpPermission.builder();
+
+      builder.ipProtocol(IpProtocol.TCP);
+      builder.fromPort(10);
+      builder.toPort(20);
+      builder.exclusionCidrBlock("10.0.0.0/8");
+
+      return builder.build();
+   }
+
    private IpPermission createSinglePortPermission() {
       IpPermission.Builder builder = IpPermission.builder();
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/e5fb0b60/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java
----------------------------------------------------------------------
diff --git a/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java b/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java
index 5d05a28..4c6ad3d 100644
--- a/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java
+++ b/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java
@@ -43,30 +43,62 @@ public class IpPermissionsTest {
    }
 
    @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testAllProtocolInvalidExclusionCidr() {
+      IpPermissions authorization = IpPermissions.permitAnyProtocol();
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
+               .exclusionCidrBlock("a.0.0.0/0").build());
+   }
+
+   @Test(expectedExceptions = IllegalArgumentException.class)
    public void testAllProtocolInvalidCidrMultiple() {
       IpPermissions authorization = IpPermissions.permitAnyProtocol();
       assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
                    .cidrBlocks(ImmutableSet.of("a.0.0.0/0", "0.0.0.0/0")).build());
    }
 
+   @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testAllProtocolInvalidExclusionCidrMultiple() {
+      IpPermissions authorization = IpPermissions.permitAnyProtocol();
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
+                   .exclusionCidrBlocks(ImmutableSet.of("a.0.0.0/0", "0.0.0.0/0")).build());
+   }
+
    public void testAllProtocolCidrBound() {
       IpPermissions authorization = IpPermissions.permit(IpProtocol.ALL).originatingFromCidrBlock("1.1.1.1/32");
       assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
                .cidrBlock("1.1.1.1/32").build());
    }
 
+   public void testAllProtocolExclusionCidrBound() {
+      IpPermissions authorization = IpPermissions.permit(IpProtocol.ALL).exceptOriginatingFromCidrBlock("1.1.1.1/32");
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
+               .exclusionCidrBlock("1.1.1.1/32").build());
+   }
+
    public void testJustProtocolAndCidr() {
       IpPermissions authorization = IpPermissions.permit(IpProtocol.TCP).originatingFromCidrBlock("1.1.1.1/32");
       assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.TCP).fromPort(1).toPort(65535)
                .cidrBlock("1.1.1.1/32").build());
    }
 
+   public void testJustProtocolAndExcludedCidr() {
+      IpPermissions authorization = IpPermissions.permit(IpProtocol.TCP).exceptOriginatingFromCidrBlock("1.1.1.1/32");
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.TCP).fromPort(1).toPort(65535)
+               .exclusionCidrBlock("1.1.1.1/32").build());
+   }
+
    public void testAnyProtocol() {
       IpPermissions authorization = IpPermissions.permitAnyProtocol().originatingFromCidrBlock("1.1.1.1/32");
       assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
                .cidrBlock("1.1.1.1/32").build());
    }
 
+   public void testAnyProtocolWithExcludedCidr() {
+      IpPermissions authorization = IpPermissions.permitAnyProtocol().exceptOriginatingFromCidrBlock("1.1.1.1/32");
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
+               .exclusionCidrBlock("1.1.1.1/32").build());
+   }
+
    public void testMultipleCidrs() {
       IpPermissions authorization = IpPermissions.permit(IpProtocol.TCP).originatingFromCidrBlocks(
                ImmutableSet.of("1.1.1.1/32", "1.1.1.2/32"));
@@ -74,6 +106,13 @@ public class IpPermissionsTest {
                .cidrBlocks(ImmutableSet.of("1.1.1.1/32", "1.1.1.2/32")).build());
    }
 
+   public void testMultipleCidrsExclusions() {
+      IpPermissions authorization = IpPermissions.permit(IpProtocol.TCP).exceptOriginatingFromCidrBlocks(
+               ImmutableSet.of("1.1.1.1/32", "1.1.1.2/32"));
+      assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.TCP).fromPort(1).toPort(65535)
+               .exclusionCidrBlocks(ImmutableSet.of("1.1.1.1/32", "1.1.1.2/32")).build());
+   }
+
    public void testProtocolFromAndToPortAndGroupIds() {
       IpPermissions authorization = IpPermissions.permit(IpProtocol.UDP).fromPort(11).to(53)
                .originatingFromSecurityGroupId("groupId");