Get rid of pointless IpProtocol and SecurityGroupRule in favor of org.jclouds.net.domain classes, add check for validity of CIDR string, add SecurityGroupBuilder.
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/7cc21241 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/7cc21241 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/7cc21241 Branch: refs/heads/jclouds-101 Commit: 7cc21241296e6d3ca6fbdc290ad6eafdd3a8dbd8 Parents: 34c5c46 Author: Andrew Bayer <[email protected]> Authored: Tue Jun 11 13:24:30 2013 -0700 Committer: Andrew Bayer <[email protected]> Committed: Tue Jun 11 13:24:30 2013 -0700 ---------------------------------------------------------------------- .../org/jclouds/compute/domain/IpProtocol.java | 39 ------ .../jclouds/compute/domain/SecurityGroup.java | 19 ++- .../compute/domain/SecurityGroupBuilder.java | 110 ++++++++++++++++ .../compute/domain/SecurityGroupRule.java | 132 ------------------- .../extensions/SecurityGroupExtension.java | 32 ++--- .../org/jclouds/net/domain/IpPermission.java | 20 ++- .../org/jclouds/net/util/IpPermissionsTest.java | 14 ++ .../main/java/org/jclouds/util/Strings2.java | 9 ++ .../java/org/jclouds/util/Strings2Test.java | 8 ++ 9 files changed, 183 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/compute/src/main/java/org/jclouds/compute/domain/IpProtocol.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/domain/IpProtocol.java b/compute/src/main/java/org/jclouds/compute/domain/IpProtocol.java deleted file mode 100644 index 2ec6993..0000000 --- a/compute/src/main/java/org/jclouds/compute/domain/IpProtocol.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.compute.domain; - -import static com.google.common.base.Preconditions.checkNotNull; - -public enum IpProtocol { - TCP, UDP, ICMP, UNRECOGNIZED; - public String value() { - return name().toLowerCase(); - } - - @Override - public String toString() { - return value(); - } - - public static IpProtocol fromValue(String protocol) { - try { - return valueOf(checkNotNull(protocol, "protocol").toUpperCase()); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java index 8849e01..a7b6ccd 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java +++ b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java @@ -23,12 +23,11 @@ import java.util.Map; import java.util.Set; import org.jclouds.compute.domain.ComputeType; -import org.jclouds.compute.domain.SecurityGroup; -import org.jclouds.compute.domain.SecurityGroupRule; import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.domain.Location; import org.jclouds.domain.ResourceMetadata; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.net.domain.IpPermission; import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Predicate; @@ -42,29 +41,29 @@ import com.google.common.collect.ImmutableSet; */ public class SecurityGroup extends ComputeMetadataImpl { - private final Set<SecurityGroupRule> rules; + private final Set<IpPermission> ipPermissions; public SecurityGroup(String providerId, String name, String id, @Nullable Location location, URI uri, Map<String, String> userMetadata, Set<String> tags, - Iterable<SecurityGroupRule> rules) { + Iterable<IpPermission> ipPermissions) { super(ComputeType.SECURITYGROUP, providerId, name, id, location, uri, userMetadata, tags); - this.rules = ImmutableSet.copyOf(checkNotNull(rules, "rules")); + this.ipPermissions = ImmutableSet.copyOf(checkNotNull(ipPermissions, "ipPermissions")); } /** * - * @return The set of @{link SecurityGroupRule}s for this security group + * @return The set of @{link IpPermission}s for this security group */ - public Set<SecurityGroupRule> getRules() { - return rules; + public Set<IpPermission> getIpPermissions() { + return ipPermissions; } @Override protected ToStringHelper string() { ToStringHelper helper = computeToStringPrefix(); - if (rules.size() > 0) - helper.add("rules", rules); + if (ipPermissions.size() > 0) + helper.add("ipPermissions", ipPermissions); return addComputeToStringSuffix(helper); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/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 new file mode 100644 index 0000000..346b0f1 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java @@ -0,0 +1,110 @@ +/* + * 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.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.net.domain.IpPermission; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +/** + * @author Andrew Bayer + */ +public class SecurityGroupBuilder extends ComputeMetadataBuilder { + private ImmutableSet.Builder<IpPermission> ipPermissions = ImmutableSet.<IpPermission> builder(); + + public SecurityGroupBuilder() { + super(ComputeType.SECURITYGROUP); + } + + public SecurityGroupBuilder ipPermissions(Iterable<IpPermission> ipPermissions) { + this.ipPermissions.addAll(checkNotNull(ipPermissions, "ipPermissions")); + return this; + } + + public SecurityGroupBuilder ipPermission(IpPermission ipPermission) { + this.ipPermissions.add(checkNotNull(ipPermission, "ipPermission")); + return this; + } + + @Override + public SecurityGroupBuilder id(String id) { + return SecurityGroupBuilder.class.cast(super.id(id)); + } + + @Override + public SecurityGroupBuilder tags(Iterable<String> tags) { + return SecurityGroupBuilder.class.cast(super.tags(tags)); + } + + @Override + public SecurityGroupBuilder ids(String id) { + return SecurityGroupBuilder.class.cast(super.ids(id)); + } + + @Override + public SecurityGroupBuilder providerId(String providerId) { + return SecurityGroupBuilder.class.cast(super.providerId(providerId)); + } + + @Override + public SecurityGroupBuilder name(String name) { + return SecurityGroupBuilder.class.cast(super.name(name)); + } + + @Override + public SecurityGroupBuilder location(Location location) { + return SecurityGroupBuilder.class.cast(super.location(location)); + } + + @Override + public SecurityGroupBuilder uri(URI uri) { + return SecurityGroupBuilder.class.cast(super.uri(uri)); + } + + @Override + public SecurityGroupBuilder userMetadata(Map<String, String> userMetadata) { + return SecurityGroupBuilder.class.cast(super.userMetadata(userMetadata)); + } + + @Override + public SecurityGroup build() { + return new SecurityGroup(providerId, name, id, location, uri, userMetadata, tags, + ipPermissions.build()); + } + + public static SecurityGroupBuilder fromSecurityGroup(SecurityGroup group) { + return new SecurityGroupBuilder().providerId(group.getProviderId()) + .name(group.getName()) + .id(group.getId()) + .location(group.getLocation()) + .uri(group.getUri()) + .userMetadata(group.getUserMetadata()) + .tags(group.getTags()) + .ipPermissions(group.getIpPermissions()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupRule.java ---------------------------------------------------------------------- diff --git a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupRule.java b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupRule.java deleted file mode 100644 index 1dfe945..0000000 --- a/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupRule.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.compute.domain; - -import static com.google.common.base.Objects.equal; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Set; - -import org.jclouds.compute.domain.IpProtocol; -import org.jclouds.compute.domain.SecurityGroupRule; -import org.jclouds.javax.annotation.Nullable; - -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; -import com.google.common.collect.ImmutableSet; - -/** - * The port range, IP ranges, protocol and instance groups for a rule in a @{link SecurityGroup}. - * - * @author Andrew Bayer - */ -public class SecurityGroupRule { - - @Nullable - private final String id; - private final IpProtocol protocol; - private final int startPort; - private final int endPort; - private final Set<String> ipRanges; - private final Set<String> groupIds; - - public SecurityGroupRule(@Nullable String id, IpProtocol protocol, int startPort, int endPort, - Iterable<String> ipRanges, Iterable<String> groupIds) { - this.id = id; - this.protocol = checkNotNull(protocol, "protocol"); - this.startPort = startPort; - this.endPort = endPort; - this.ipRanges = ImmutableSet.copyOf(checkNotNull(ipRanges, "ipRanges")); - this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); - } - - /** - * @return Unique identifier. - * - */ - @Nullable - public String getId() { - return id; - } - - /** - * @return The IP protocol for the rule. - */ - public IpProtocol getProtocol() { - return protocol; - } - - /** - * - * @return the start port. - */ - public int getStartPort() { - return startPort; - } - - /** - * - * @return the end port. - */ - public int getEndPort() { - return endPort; - } - - /** - * - * @return The set of IP ranges for this rule. - */ - public Set<String> getIpRanges() { - return ipRanges; - } - - /** - * - * @return The set of @{link SecurityGroup} ids for this rule. - */ - public Set<String> getGroupIds() { - return groupIds; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - SecurityGroupRule that = SecurityGroupRule.class.cast(o); - return equal(this.id, that.id) && equal(this.getProtocol(), that.getProtocol()) && equal(this.startPort, that.startPort) - && equal(this.endPort, that.endPort) && equal(this.getIpRanges(), that.getIpRanges()) - && equal(this.getGroupIds(), that.getGroupIds()); - } - - @Override - public int hashCode() { - return Objects.hashCode(id, protocol, startPort, endPort, ipRanges, groupIds); - } - - @Override - public String toString() { - return string().toString(); - } - - protected ToStringHelper string() { - return Objects.toStringHelper("").omitNullValues().add("id", id).add("protocol", getProtocol()).add("startPort", startPort) - .add("endPort", endPort).add("ipRanges", getIpRanges()).add("groupIds", getGroupIds()); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/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 9c00aaf..bb7f856 100644 --- a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java +++ b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java @@ -16,10 +16,10 @@ */ package org.jclouds.compute.extensions; -import org.jclouds.compute.domain.IpProtocol; import org.jclouds.compute.domain.SecurityGroup; -import org.jclouds.compute.domain.SecurityGroupRule; import org.jclouds.domain.Location; +import org.jclouds.net.domain.IpPermission; +import org.jclouds.net.domain.IpProtocol; import com.google.common.util.concurrent.ListenableFuture; @@ -44,38 +44,38 @@ public interface SecurityGroupExtension { SecurityGroup createSecurityGroup(String name, Location location); /** - * Add a @{link SecurityGroupRule} to an existing @{link SecurityGroup}. Applies the rule to the + * Add a @{link IpPermission} to an existing @{link SecurityGroup}. Applies the permission to the * security group on the provider. * * @param rule - * The SecurityGroupRule to add. + * The IpPermission to add. * @param group - * The SecurityGroup to add the rule to. + * The SecurityGroup to add the permission to. * - * @return The SecurityGroup with the new rule added, after the rule has been applied on the provider. + * @return The SecurityGroup with the new permission added, after the permission has been applied on the provider. */ - SecurityGroup addRule(SecurityGroupRule rule, SecurityGroup group); + SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group); /** - * Add a @{link SecurityGroupRule} to an existing @{link SecurityGroup}, based on the parameters given. - * Applies the rule to the security group on the provider. + * Add a @{link IpPermission} to an existing @{link SecurityGroup}, based on the parameters given. + * Applies the permission to the security group on the provider. * * @param protocol - * The @{link IpProtocol} for the rule. + * 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 ipRanges - * An Iterable of Strings representing the IP range(s) the rule should allow. + * An Iterable of Strings representing the IP range(s) the permission should allow. * @param groupIds - * An Iterable of @{link SecurityGroup} IDs this rule should allow. + * An Iterable of @{link SecurityGroup} IDs this permission should allow. * @param group - * The SecurityGroup to add the rule to. + * The SecurityGroup to add the permission to. * - * @return The SecurityGroup with the new rule added, after the rule has been applied on the provider. + * @return The SecurityGroup with the new permission added, after the permission has been applied on the provider. */ - SecurityGroup addRule(IpProtocol protocol, int startPort, int endPort, Iterable<String> ipRanges, - Iterable<String> groupIds, SecurityGroup group); + SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort, Iterable<String> ipRanges, + Iterable<String> groupIds, SecurityGroup group); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/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 895d9d3..15bfe0c 100644 --- a/compute/src/main/java/org/jclouds/net/domain/IpPermission.java +++ b/compute/src/main/java/org/jclouds/net/domain/IpPermission.java @@ -17,11 +17,15 @@ package org.jclouds.net.domain; import static com.google.common.base.Objects.equal; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.transform; +import static org.jclouds.util.Strings2.isCidrFormat; import java.util.Set; import com.google.common.annotations.Beta; +import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.collect.ImmutableMultimap; @@ -100,6 +104,7 @@ public class IpPermission implements Comparable<IpPermission> { * @see IpPermission#getCidrBlocks() */ public Builder cidrBlock(String cidrBlock) { + checkArgument(isCidrFormat(cidrBlock), "cidrBlock %s is not a valid CIDR", cidrBlock); this.cidrBlocks.add(cidrBlock); return this; } @@ -108,7 +113,16 @@ public class IpPermission implements Comparable<IpPermission> { * @see IpPermission#getCidrBlocks() */ public Builder cidrBlocks(Iterable<String> cidrBlocks) { - Iterables.addAll(this.cidrBlocks, 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; + } + })); return this; } @@ -227,8 +241,8 @@ public class IpPermission implements Comparable<IpPermission> { protected ToStringHelper string() { return Objects.toStringHelper("").add("ipProtocol", ipProtocol).add("fromPort", fromPort).add("toPort", toPort) - .add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds).add("groupIds", - groupIds); + .add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds).add("cidrBlocks", + cidrBlocks); } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/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 2c278f6..30f5453 100644 --- a/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java +++ b/compute/src/test/java/org/jclouds/net/util/IpPermissionsTest.java @@ -37,6 +37,20 @@ public class IpPermissionsTest { .cidrBlock("0.0.0.0/0").build()); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void testAllProtocolInvalidCidr() { + IpPermissions authorization = IpPermissions.permitAnyProtocol(); + assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535) + .cidrBlock("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()); + } + 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) http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/core/src/main/java/org/jclouds/util/Strings2.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/util/Strings2.java b/core/src/main/java/org/jclouds/util/Strings2.java index 8b85b53..2a47286 100644 --- a/core/src/main/java/org/jclouds/util/Strings2.java +++ b/core/src/main/java/org/jclouds/util/Strings2.java @@ -87,7 +87,16 @@ public class Strings2 { } } }); + + private static final String IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"; + private static final String SLASH_FORMAT = IP_ADDRESS + "/(\\d{1,3})"; + private static final Pattern ADDRESS_PATTERN = Pattern.compile(IP_ADDRESS); + private static final Pattern CIDR_PATTERN = Pattern.compile(SLASH_FORMAT); + public static boolean isCidrFormat(String in) { + return CIDR_PATTERN.matcher(in).matches(); + } + private static final Pattern URL_ENCODED_PATTERN = Pattern.compile(".*%[a-fA-F0-9][a-fA-F0-9].*"); public static boolean isUrlEncoded(String in) { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/7cc21241/core/src/test/java/org/jclouds/util/Strings2Test.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/jclouds/util/Strings2Test.java b/core/src/test/java/org/jclouds/util/Strings2Test.java index d7e3cd5..5b1c9a0 100644 --- a/core/src/test/java/org/jclouds/util/Strings2Test.java +++ b/core/src/test/java/org/jclouds/util/Strings2Test.java @@ -53,4 +53,12 @@ public class Strings2Test { assertEquals(actual, urlDecode(urlEncode(actual))); } + public void testIsCidrFormat() { + assert Strings2.isCidrFormat("1.2.3.4/5"); + assert Strings2.isCidrFormat("0.0.0.0/0"); + assert !Strings2.isCidrFormat("banana"); + assert !Strings2.isCidrFormat("1.2.3.4"); + assert !Strings2.isCidrFormat("500.500.500.500/2423"); + } + }
