You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/06/26 23:59:07 UTC
[1/4] JCLOUDS-101 - Add SecurityGroupExtension for compute
Updated Branches:
refs/heads/master a906f9f4e -> 5f524ee6c
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtension.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtension.java
new file mode 100644
index 0000000..c0e21f0
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtension.java
@@ -0,0 +1,177 @@
+/*
+ * 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.aws.ec2.compute.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.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.toArray;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.NoSuchElementException;
+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.aws.ec2.AWSEC2Client;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.functions.GroupNamingConvention.Factory;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
+import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.location.Region;
+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.Supplier;
+import com.google.common.cache.LoadingCache;
+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;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public class AWSEC2SecurityGroupExtension extends EC2SecurityGroupExtension {
+ protected final AWSEC2Client client;
+
+ @Inject
+ public AWSEC2SecurityGroupExtension(AWSEC2Client client,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ @Region Supplier<Set<String>> regions,
+ Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter,
+ @Memoized Supplier<Set<? extends Location>> locations,
+ @Named("SECURITY") LoadingCache<RegionAndName, String> groupCreator,
+ GroupNamingConvention.Factory namingConvention) {
+ super(client, userExecutor, regions, groupConverter, locations, groupCreator, namingConvention);
+ this.client = checkNotNull(client, "client");
+ }
+
+
+ @Override
+ public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
+
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, ipPermission);
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(protocol);
+ builder.fromPort(startPort);
+ builder.toPort(endPort);
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ builder.cidrBlock(cidr);
+ }
+ }
+
+ if (tenantIdGroupNamePairs.size() > 0) {
+ for (String userId : tenantIdGroupNamePairs.keySet()) {
+ for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+ builder.tenantIdGroupNamePair(userId, groupName);
+ }
+ }
+ }
+
+ client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, builder.build());
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ client.getSecurityGroupServices().revokeSecurityGroupIngressInRegion(region, name, ipPermission);
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(protocol);
+ builder.fromPort(startPort);
+ builder.toPort(endPort);
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ builder.cidrBlock(cidr);
+ }
+ }
+
+ if (tenantIdGroupNamePairs.size() > 0) {
+ for (String userId : tenantIdGroupNamePairs.keySet()) {
+ for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+ builder.tenantIdGroupNamePair(userId, groupName);
+ }
+ }
+ }
+
+ client.getSecurityGroupServices().revokeSecurityGroupIngressInRegion(region, name, builder.build());
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeeded.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeeded.java
index ad14efe..6676ef6 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeeded.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeeded.java
@@ -32,10 +32,10 @@ import org.jclouds.aws.ec2.services.AWSSecurityGroupClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheLoader;
@@ -95,7 +95,7 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader<RegionAndName
.fromPort(range.getKey())
.toPort(range.getValue())
.ipProtocol(IpProtocol.TCP)
- .ipRange("0.0.0.0/0")
+ .cidrBlock("0.0.0.0/0")
.build());
}
@@ -104,13 +104,13 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader<RegionAndName
.fromPort(0)
.toPort(65535)
.ipProtocol(IpProtocol.TCP)
- .userIdGroupPair(myOwnerId, name)
+ .tenantIdGroupNamePair(myOwnerId, name)
.build());
permissions.add(IpPermission.builder()
.fromPort(0)
.toPort(65535)
.ipProtocol(IpProtocol.UDP)
- .userIdGroupPair(myOwnerId, name)
+ .tenantIdGroupNamePair(myOwnerId, name)
.build());
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClient.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClient.java
index 75a6f9b..25acb03 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClient.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClient.java
@@ -33,12 +33,12 @@ import org.jclouds.aws.filters.FormSigner;
import org.jclouds.ec2.binders.BindGroupIdsToIndexedFormParams;
import org.jclouds.ec2.binders.BindIpPermissionToIndexedFormParams;
import org.jclouds.ec2.binders.BindIpPermissionsToIndexedFormParams;
-import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.services.SecurityGroupAsyncClient;
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.Fallback;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClient.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClient.java
index 383b0fd..ac3b301 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClient.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClient.java
@@ -18,10 +18,10 @@ package org.jclouds.aws.ec2.services;
import java.util.Set;
import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions;
-import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.services.SecurityGroupClient;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.net.domain.IpPermission;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java
index 7ee0e9d..ae39523 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java
@@ -48,11 +48,11 @@ import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairClient;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.scriptbuilder.domain.Statements;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionExpectTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionExpectTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionExpectTest.java
new file mode 100644
index 0000000..4bae7c3
--- /dev/null
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionExpectTest.java
@@ -0,0 +1,367 @@
+/*
+ * 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.aws.ec2.compute.extensions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.aws.ec2.compute.internal.BaseAWSEC2ComputeServiceExpectTest;
+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.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+
+/**
+ *
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "AWSEC2SecurityGroupExtensionExpectTest")
+public class AWSEC2SecurityGroupExtensionExpectTest extends BaseAWSEC2ComputeServiceExpectTest {
+
+ public void testAddIpPermissionCidrFromIpPermission() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestRange =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("GroupId", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.FromPort", "22")
+ .addFormParam("IpPermissions.0.IpProtocol", "tcp")
+ .addFormParam("IpPermissions.0.IpRanges.0.CidrIp", "0.0.0.0/0")
+ .addFormParam("IpPermissions.0.ToPort", "40")
+ .build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(40);
+ builder.cidrBlock("0.0.0.0/0");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(1, newPerm.getCidrBlocks().size());
+ assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
+ }
+
+ public void testAddIpPermissionCidrFromParams() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestRange =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("GroupId", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.FromPort", "22")
+ .addFormParam("IpPermissions.0.IpProtocol", "tcp")
+ .addFormParam("IpPermissions.0.IpRanges.0.CidrIp", "0.0.0.0/0")
+ .addFormParam("IpPermissions.0.ToPort", "40")
+ .build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 40,
+ emptyMultimap(),
+ ImmutableSet.of("0.0.0.0/0"),
+ emptyStringSet(),
+ origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(1, newPerm.getCidrBlocks().size());
+ assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
+ }
+
+ public void testAddIpPermissionGroupFromIpPermission() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("GroupId", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.FromPort", "22")
+ .addFormParam("IpPermissions.0.Groups.0.GroupName", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.Groups.0.UserId", "993194456877")
+ .addFormParam("IpPermissions.0.IpProtocol", "tcp")
+ .addFormParam("IpPermissions.0.ToPort", "40")
+ .build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(40);
+ builder.tenantIdGroupNamePair("993194456877", "jclouds#some-group");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+ groupBuilder.ownerId("993194456877");
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(0, newPerm.getCidrBlocks().size());
+ assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
+ assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
+ assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
+ }
+
+
+ public void testAddIpPermissionGroupFromParams() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("GroupId", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.FromPort", "22")
+ .addFormParam("IpPermissions.0.Groups.0.GroupName", "jclouds#some-group")
+ .addFormParam("IpPermissions.0.Groups.0.UserId", "993194456877")
+ .addFormParam("IpPermissions.0.IpProtocol", "tcp")
+ .addFormParam("IpPermissions.0.ToPort", "40")
+ .build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.ownerId("993194456877");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ ImmutableMultimap.Builder<String, String> permBuilder = ImmutableMultimap.builder();
+ permBuilder.put(origGroup.getOwnerId(), origGroup.getName());
+
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 40,
+ permBuilder.build(),
+ emptyStringSet(),
+ emptyStringSet(),
+ origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(0, newPerm.getCidrBlocks().size());
+ assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
+ assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
+ assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
+ }
+
+ private Multimap<String, String> emptyMultimap() {
+ return LinkedHashMultimap.create();
+ }
+
+ private Set<String> emptyStringSet() {
+ return Sets.newLinkedHashSet();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionLiveTest.java
new file mode 100644
index 0000000..9de4f24
--- /dev/null
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.aws.ec2.compute.extensions;
+
+import static com.google.common.collect.Iterables.transform;
+
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
+import org.testng.annotations.Test;
+
+import com.google.inject.Module;
+
+/**
+ * Live test for aws-ec2 {@link SecurityGroupExtension} implementation
+ *
+ * @author Andrew Bayer
+ *
+ */
+@Test(groups = "live", singleThreaded = true, testName = "AWSEC2SecurityGroupExtensionLiveTest")
+public class AWSEC2SecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
+
+ public AWSEC2SecurityGroupExtensionLiveTest() {
+ provider = "aws-ec2";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeededTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeededTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeededTest.java
index db3093c..269a8f0 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeededTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/loaders/AWSEC2CreateSecurityGroupIfNeededTest.java
@@ -30,10 +30,10 @@ import java.util.concurrent.ExecutionException;
import org.jclouds.aws.ec2.services.AWSSecurityGroupClient;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@@ -63,20 +63,20 @@ public class AWSEC2CreateSecurityGroupIfNeededTest {
.fromPort(22)
.toPort(22)
.ipProtocol(IpProtocol.TCP)
- .ipRange("0.0.0.0/0")
+ .cidrBlock("0.0.0.0/0")
.build());
permissions.add(IpPermission.builder()
.fromPort(0)
.toPort(65535)
.ipProtocol(IpProtocol.TCP)
- .userIdGroupPair("ownerId", "group")
+ .tenantIdGroupNamePair("ownerId", "group")
.build());
permissions.add(IpPermission.builder()
.fromPort(0)
.toPort(65535)
.ipProtocol(IpProtocol.UDP)
- .userIdGroupPair("ownerId", "group")
+ .tenantIdGroupNamePair("ownerId", "group")
.build());
client.createSecurityGroupInRegion("region", "group", "group");
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/parse/DescribeSecurityGroupsResponseTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/parse/DescribeSecurityGroupsResponseTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/parse/DescribeSecurityGroupsResponseTest.java
index 40e49dd..8f948f5 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/parse/DescribeSecurityGroupsResponseTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/parse/DescribeSecurityGroupsResponseTest.java
@@ -25,12 +25,12 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.xml.BaseEC2HandlerTest;
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.http.functions.ParseSax;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.reflect.Invocation;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
@@ -69,7 +69,7 @@ public class DescribeSecurityGroupsResponseTest extends BaseEC2HandlerTest {
// .vpcId("vpc-99999999")
.ipPermission(IpPermission.builder()
.ipProtocol(IpProtocol.ALL)
- .userIdGroupPair("123123123123","sg-11111111").build())
+ .tenantIdGroupNamePair("123123123123","sg-11111111").build())
// .ipPermissionEgress(IpPermission.builder()
// .ipProtocol(IpProtocol.ALL)
// .ipRange("0.0.0.0/0").build())
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClientTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClientTest.java
index 2ad3467..9ebead5 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClientTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupAsyncClientTest.java
@@ -22,13 +22,13 @@ import java.io.IOException;
import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.util.IpPermissions;
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClientLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClientLiveTest.java
index 0ec81dd..76c7e91 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSSecurityGroupClientLiveTest.java
@@ -21,11 +21,11 @@ import static org.testng.Assert.assertNotNull;
import java.util.Set;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.services.SecurityGroupClientLiveTest;
import org.jclouds.ec2.util.IpPermissions;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@@ -69,7 +69,7 @@ public class AWSSecurityGroupClientLiveTest extends SecurityGroupClientLiveTest
assertEventually(new GroupHasPermission(client, group2Name, new Predicate<IpPermission>() {
@Override
public boolean apply(IpPermission arg0) {
- return arg0.getUserIdGroupPairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name))
+ return arg0.getTenantIdGroupNamePairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name))
&& arg0.getFromPort() == 80 && arg0.getToPort() == 80 && arg0.getIpProtocol() == IpProtocol.TCP;
}
}));
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
----------------------------------------------------------------------
diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
index 3f5935c..8e34a5e 100644
--- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
+++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
@@ -37,6 +37,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.PersistNodeCredentials;
import org.jclouds.compute.options.TemplateOptions;
@@ -81,12 +82,12 @@ public class GoGridComputeService extends BaseComputeService {
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
- Optional<ImageExtension> imageExtension) {
+ Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
- persistNodeCredentials, timeouts, userExecutor, imageExtension);
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
}
/**
[2/4] JCLOUDS-101 - Add SecurityGroupExtension for compute
Posted by ab...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseComputeServiceTypicalSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseComputeServiceTypicalSecurityGroupTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseComputeServiceTypicalSecurityGroupTest.java
index 5da793f..9b056b9 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseComputeServiceTypicalSecurityGroupTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseComputeServiceTypicalSecurityGroupTest.java
@@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupListTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupListTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupListTest.java
index 9f477ee..4e46ede 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupListTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupListTest.java
@@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.rest.annotations.SelectJson;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupTest.java
index a5c83f4..784a0bd 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseSecurityGroupTest.java
@@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeService.java
----------------------------------------------------------------------
diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeService.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeService.java
index 1431d54..b37e85e 100644
--- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeService.java
+++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/TerremarkVCloudComputeService.java
@@ -37,6 +37,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.PersistNodeCredentials;
import org.jclouds.compute.options.TemplateOptions;
@@ -84,12 +85,12 @@ public class TerremarkVCloudComputeService extends BaseComputeService {
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, CleanupOrphanKeys cleanupOrphanKeys,
- Optional<ImageExtension> imageExtension) {
+ Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
- persistNodeCredentials, timeouts, userExecutor, imageExtension);
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
this.cleanupOrphanKeys = cleanupOrphanKeys;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/ComputeService.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/ComputeService.java b/compute/src/main/java/org/jclouds/compute/ComputeService.java
index 610090a..a7c2519 100644
--- a/compute/src/main/java/org/jclouds/compute/ComputeService.java
+++ b/compute/src/main/java/org/jclouds/compute/ComputeService.java
@@ -27,6 +27,7 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.options.TemplateOptions;
@@ -383,5 +384,13 @@ public interface ComputeService {
@Beta
Optional<ImageExtension> getImageExtension();
+ /**
+ * Returns the {@link SecurityGroupExtension} for this provider if it implements it.
+ *
+ * @return an optional of the {@link SecurityGroupExtension} or {@link Optional#absent()} if not
+ * implemented
+ */
+ @Beta
+ Optional<SecurityGroupExtension> getSecurityGroupExtension();
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
index 7581e86..7307196 100644
--- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
+++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
@@ -44,6 +44,7 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
import org.jclouds.compute.functions.TemplateOptionsToStatement;
@@ -306,5 +307,11 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
return Optional.absent();
}
+ @Provides
+ @Singleton
+ protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i){
+ return Optional.absent();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/domain/ComputeType.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/domain/ComputeType.java b/compute/src/main/java/org/jclouds/compute/domain/ComputeType.java
index 26df759..8e2c75c 100644
--- a/compute/src/main/java/org/jclouds/compute/domain/ComputeType.java
+++ b/compute/src/main/java/org/jclouds/compute/domain/ComputeType.java
@@ -22,6 +22,6 @@ package org.jclouds.compute.domain;
*/
public enum ComputeType {
- NODE, IMAGE, HARDWARE;
+ NODE, IMAGE, HARDWARE, SECURITYGROUP;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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
new file mode 100644
index 0000000..fecba5a
--- /dev/null
+++ b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroup.java
@@ -0,0 +1,80 @@
+/*
+ * 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.compute.domain.ComputeType;
+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;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Describes a security group containing a set of @{link IpPermission}s
+ *
+ * @author Andrew Bayer
+ */
+public class SecurityGroup extends ComputeMetadataImpl {
+
+ private final Set<IpPermission> ipPermissions;
+ private final String ownerId;
+
+ public SecurityGroup(String providerId, String name, String id, @Nullable Location location, URI uri,
+ Map<String, String> userMetadata, Set<String> tags,
+ Iterable<IpPermission> ipPermissions,
+ @Nullable String ownerId) {
+ super(ComputeType.SECURITYGROUP, providerId, name, id, location, uri, userMetadata, tags);
+ this.ipPermissions = ImmutableSet.copyOf(checkNotNull(ipPermissions, "ipPermissions"));
+ this.ownerId = ownerId;
+ }
+
+ /**
+ *
+ * @return The set of @{link IpPermission}s for this security group
+ */
+ public Set<IpPermission> getIpPermissions() {
+ return ipPermissions;
+ }
+
+ /**
+ *
+ * @return the owner ID. Can be null.
+ */
+ public String getOwnerId() {
+ return ownerId;
+ }
+
+ @Override
+ protected ToStringHelper string() {
+ ToStringHelper helper = computeToStringPrefix();
+ if (ipPermissions.size() > 0)
+ helper.add("ipPermissions", ipPermissions);
+ return addComputeToStringSuffix(helper);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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..002116f
--- /dev/null
+++ b/compute/src/main/java/org/jclouds/compute/domain/SecurityGroupBuilder.java
@@ -0,0 +1,122 @@
+/*
+ * 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();
+ private String ownerId;
+
+ public SecurityGroupBuilder() {
+ 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;
+ }
+
+ public SecurityGroupBuilder ipPermission(IpPermission ipPermission) {
+ this.ipPermissions.add(checkNotNull(ipPermission, "ipPermission"));
+ return this;
+ }
+
+ public SecurityGroupBuilder ownerId(String ownerId) {
+ this.ownerId = ownerId;
+ 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(), ownerId);
+ }
+
+ 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())
+ .ownerId(group.getOwnerId());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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
new file mode 100644
index 0000000..f07e72d
--- /dev/null
+++ b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
@@ -0,0 +1,180 @@
+/*
+ * 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.extensions;
+
+import java.util.Set;
+
+import org.jclouds.compute.domain.SecurityGroup;
+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;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public interface SecurityGroupExtension {
+
+ /**
+ * List security groups.
+ *
+ * @return The set of @{link SecurityGroup}s we have access to.
+ */
+ Set<SecurityGroup> listSecurityGroups();
+
+ /**
+ * List security groups in a given @{link Location}.
+ *
+ * @return The set of @{link SecurityGroup}s we have access to in the given location.
+ */
+ Set<SecurityGroup> listSecurityGroupsInLocation(Location location);
+
+ /**
+ * List security groups for a given instance given the instance's ID.
+ *
+ * @return The set of @{link SecurityGroup}s for the given instance..
+ */
+ Set<SecurityGroup> listSecurityGroupsForNode(String id);
+
+ /**
+ * Get a security group by id.
+ *
+ * @return The @{link SecurityGroup}, if it exists.
+ */
+ SecurityGroup getSecurityGroupById(String id);
+
+ /**
+ * Create a new @{link SecurityGroup} from the parameters given.
+ *
+ * @param name
+ * The name of the security group
+ * @param location
+ * The @{link Location} of the security group
+ *
+ * @return The SecurityGroup that has been created.
+ */
+ SecurityGroup createSecurityGroup(String name, Location location);
+
+ /**
+ * Remove an existing @{link SecurityGroup}, and its permissions.
+ *
+ * @param id
+ * The id of the SecurityGroup to delete.
+ *
+ * @return true if we were able to remove the group, false otherwise.
+ */
+ boolean removeSecurityGroup(String id);
+
+ /**
+ * Add a @{link IpPermission} to an existing @{link SecurityGroup}. Applies the permission to the
+ * security group on the provider.
+ *
+ * @param rule
+ * The IpPermission to add.
+ * @param group
+ * The SecurityGroup to add the permission to.
+ *
+ * @return The SecurityGroup with the new permission added, after the permission has been applied on the provider.
+ */
+ 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.
+ *
+ * @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 add the permission to.
+ *
+ * @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,
+ 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);
+
+ /**
+ * Returns true if this SecurityGroupExtension supports tenant ID + group name pairs.
+ */
+ boolean supportsTenantIdGroupNamePairs();
+
+ /**
+ * Returns true if this SecurityGroupExtension supports group IDs.
+ */
+ boolean supportsGroupIds();
+
+ /**
+ * Returns true if this SecurityGroupExtension supports port ranges for group authorization.
+ */
+ boolean supportsPortRangesForGroups();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
index fd177ac..75ea787 100644
--- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
+++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
@@ -66,6 +66,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
@@ -141,6 +142,7 @@ public class BaseComputeService implements ComputeService {
private final RunScriptOnNode.Factory runScriptOnNodeFactory;
private final ListeningExecutorService userExecutor;
private final Optional<ImageExtension> imageExtension;
+ private final Optional<SecurityGroupExtension> securityGroupExtension;
@Inject
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
@@ -158,7 +160,7 @@ public class BaseComputeService implements ComputeService {
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
- Optional<ImageExtension> imageExtension) {
+ Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
this.context = checkNotNull(context, "context");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.images = checkNotNull(images, "images");
@@ -184,6 +186,7 @@ public class BaseComputeService implements ComputeService {
this.persistNodeCredentials = checkNotNull(persistNodeCredentials, "persistNodeCredentials");
this.userExecutor = checkNotNull(userExecutor, "userExecutor");
this.imageExtension = checkNotNull(imageExtension, "imageExtension");
+ this.securityGroupExtension = checkNotNull(securityGroupExtension, "securityGroupExtension");
}
/**
@@ -714,4 +717,11 @@ public class BaseComputeService implements ComputeService {
return imageExtension;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<SecurityGroupExtension> getSecurityGroupExtension() {
+ return securityGroupExtension;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
index 270633a..d17a6cd 100644
--- a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
+++ b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
@@ -70,6 +70,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
to.inboundPorts(this.getInboundPorts());
if (this.getRunScript() != null)
to.runScript(this.getRunScript());
+ if (this.getGroups().size() > 0)
+ to.securityGroups(this.getGroups());
if (this.getPrivateKey() != null)
to.installPrivateKey(this.getPrivateKey());
if (this.getPublicKey() != null)
@@ -295,6 +297,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
@Override
+ public Set<String> getGroups() {
+ return delegate.getGroups();
+ }
+
+ @Override
+ public TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ throw new IllegalArgumentException("tags are immutable");
+ }
+
+ @Override
+ public TemplateOptions securityGroups(String... securityGroups) {
+ throw new IllegalArgumentException("tags are immutable");
+ }
+
+ @Override
public TemplateOptions userMetadata(Map<String, String> userMetadata) {
throw new IllegalArgumentException("userMetadata is immutable");
}
@@ -321,6 +338,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
protected Set<String> tags = ImmutableSet.of();
+ protected Set<String> securityGroups = ImmutableSet.of();
+
protected String privateKey;
protected String publicKey;
@@ -339,13 +358,13 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return super.equals(that) && equal(this.inboundPorts, that.inboundPorts) && equal(this.script, that.script)
&& equal(this.publicKey, that.publicKey) && equal(this.privateKey, that.privateKey)
&& equal(this.blockUntilRunning, that.blockUntilRunning) && equal(this.tags, that.tags)
- && equal(this.userMetadata, that.userMetadata);
+ && equal(this.securityGroups, that.securityGroups) && equal(this.userMetadata, that.userMetadata);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), inboundPorts, script, publicKey, privateKey, blockUntilRunning, tags,
- userMetadata);
+ securityGroups, userMetadata);
}
@Override
@@ -363,6 +382,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
toString.add("blockUntilRunning", blockUntilRunning);
if (tags.size() != 0)
toString.add("tags", tags);
+ if (securityGroups.size() != 0)
+ toString.add("securityGroups", securityGroups);
if (userMetadata.size() != 0)
toString.add("userMetadata", userMetadata);
return toString;
@@ -380,6 +401,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return tags;
}
+ public Set<String> getGroups() {
+ return securityGroups;
+ }
+
public String getPrivateKey() {
return privateKey;
}
@@ -451,6 +476,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
/**
+ * assigns the created nodes to these security groups
+ */
+ public TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ this.securityGroups = ImmutableSet.copyOf(checkNotNull(securityGroups, "securityGroups"));
+ return this;
+ }
+
+ /**
+ * @see TemplateOptions#securityGroups(Iterable<String>)
+ */
+ public TemplateOptions securityGroups(String... securityGroups) {
+ return securityGroups(ImmutableSet.copyOf(securityGroups));
+ }
+
+ /**
* Opens the set of ports to public access.
*/
public TemplateOptions inboundPorts(int... ports) {
@@ -522,6 +562,22 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
/**
+ * @see TemplateOptions#securityGroups
+ */
+ public static TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ TemplateOptions options = new TemplateOptions();
+ return options.securityGroups(securityGroups);
+ }
+
+ /**
+ * @see TemplateOptions#securityGroups
+ */
+ public static TemplateOptions securityGroups(String... securityGroups) {
+ TemplateOptions options = new TemplateOptions();
+ return options.securityGroups(securityGroups);
+ }
+
+ /**
* @see TemplateOptions#blockUntilRunning(boolean)
*/
public static TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
index 925dc1a..22e7dcf 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
@@ -41,13 +41,18 @@ import org.jclouds.compute.domain.NodeMetadata.Status;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.location.suppliers.all.JustProvider;
import org.jclouds.rest.ResourceNotFoundException;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
@@ -55,6 +60,7 @@ import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListeningExecutorService;
@@ -66,20 +72,25 @@ import com.google.common.util.concurrent.ListeningExecutorService;
public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
private final Supplier<Location> location;
private final ConcurrentMap<String, NodeMetadata> nodes;
+ private final Multimap<String, SecurityGroup> groupsForNodes;
private final ListeningExecutorService ioExecutor;
private final Provider<Integer> idProvider;
+ private final Provider<Integer> groupIdProvider;
private final String publicIpPrefix;
private final String privateIpPrefix;
private final String passwordPrefix;
private final Supplier<Set<? extends Location>> locationSupplier;
private final Map<OsFamily, Map<String, String>> osToVersionMap;
+ private final Optional<SecurityGroupExtension> securityGroupExtension;
@Inject
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, Supplier<Location> location,
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
- JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap) {
+ JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap,
+ Multimap<String, SecurityGroup> groupsForNodes, @Named("GROUP_ID") Provider<Integer> groupIdProvider,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
this.nodes = nodes;
this.ioExecutor = ioExecutor;
this.location = location;
@@ -89,6 +100,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
this.passwordPrefix = passwordPrefix;
this.locationSupplier = locationSupplier;
this.osToVersionMap = osToVersionMap;
+ this.groupsForNodes = groupsForNodes;
+ this.groupIdProvider = groupIdProvider;
+ this.securityGroupExtension = securityGroupExtension;
}
protected void setStateOnNode(Status status, NodeMetadata node) {
@@ -133,6 +147,22 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
builder.credentials(LoginCredentials.builder().user("root").password(passwordPrefix + id).build());
NodeMetadata node = builder.build();
nodes.put(node.getId(), node);
+
+ if (template.getOptions().getGroups().size() > 0) {
+ final String groupId = Iterables.getFirst(template.getOptions().getGroups(), "0");
+ Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroups(),
+ new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ return input.getId().equals(groupId);
+ }
+ });
+
+ if (secGroup.isPresent()) {
+ groupsForNodes.put(node.getId(), secGroup.get());
+ }
+ }
+
setStateOnNodeAfterDelay(Status.RUNNING, node, 100);
return new NodeWithInitialCredentials(node);
}
@@ -195,6 +225,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
return;
setStateOnNodeAfterDelay(Status.PENDING, node, 0);
setStateOnNodeAfterDelay(Status.TERMINATED, node, 50);
+ groupsForNodes.removeAll(id);
+
ioExecutor.execute(new Runnable() {
@Override
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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/5f524ee6/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..0d07bbe 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;
@@ -40,9 +43,12 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
import com.google.common.net.HostAndPort;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
/**
*
@@ -52,6 +58,8 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
@Override
protected void configure() {
+ bind(new TypeLiteral<SecurityGroupExtension>() {
+ }).to(StubSecurityGroupExtension.class);
}
@@ -73,6 +81,40 @@ 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, Multimap<String, SecurityGroup>> groupsForNodeBacking = CacheBuilder.newBuilder()
+ .build(new CacheLoader<String, Multimap<String, SecurityGroup>>() {
+
+ @Override
+ public Multimap<String, SecurityGroup> load(String arg0) throws Exception {
+ return LinkedHashMultimap.create();
+ }
+
+ });
+
+ @Provides
+ @Singleton
+ protected Multimap<String, SecurityGroup> provideGroupsForNode(@Provider Supplier<Credentials> creds)
+ throws ExecutionException {
+ return groupsForNodeBacking.get(creds.get().identity);
+ }
+
protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build(
new CacheLoader<String, AtomicInteger>() {
@@ -89,6 +131,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/5f524ee6/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..5e8fdd9
--- /dev/null
+++ b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
@@ -0,0 +1,256 @@
+/*
+ * 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.Predicate;
+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> groupIdProvider;
+ private final Supplier<Set<? extends Location>> locationSupplier;
+ private final ListeningExecutorService ioExecutor;
+ private final ConcurrentMap<String, SecurityGroup> groups;
+ private final Multimap<String, SecurityGroup> groupsForNodes;
+
+ @Inject
+ public StubSecurityGroupExtension(ConcurrentMap<String, SecurityGroup> groups,
+ @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
+ Supplier<Location> location,
+ @Named("GROUP_ID") Provider<Integer> groupIdProvider,
+ JustProvider locationSupplier,
+ Multimap<String, SecurityGroup> groupsForNodes) {
+ this.groups = groups;
+ this.ioExecutor = ioExecutor;
+ this.location = location;
+ this.groupIdProvider = groupIdProvider;
+ this.locationSupplier = locationSupplier;
+ this.groupsForNodes = groupsForNodes;
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroups() {
+ return ImmutableSet.copyOf(groups.values());
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
+ return ImmutableSet.copyOf(filter(groups.values(), new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup group) {
+ return group.getLocation().equals(location);
+ }
+ }));
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String nodeId) {
+ return ImmutableSet.copyOf(groupsForNodes.get(nodeId));
+ }
+
+ @Override
+ public SecurityGroup getSecurityGroupById(String id) {
+ return groups.get(id);
+ }
+
+ @Override
+ public SecurityGroup createSecurityGroup(String name, Location location) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+ String id = groupIdProvider.get() + "";
+ builder.ids(id);
+ builder.name(name);
+ builder.location(location);
+
+ SecurityGroup group = builder.build();
+
+ groups.put(group.getId(), group);
+
+ return group;
+ }
+
+ @Override
+ public boolean removeSecurityGroup(String id) {
+ if (groups.containsKey(id)) {
+ groups.remove(id);
+ return true;
+ }
+ return false;
+ }
+
+ @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;
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupNamePairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupIds() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsPortRangesForGroups() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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..d04af0c 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;
}
@@ -140,7 +154,7 @@ public class IpPermission implements Comparable<IpPermission> {
private final IpProtocol ipProtocol;
private final Set<String> cidrBlocks;
- protected IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
+ public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks) {
this.fromPort = fromPort;
this.toPort = toPort;
@@ -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/5f524ee6/compute/src/main/java/org/jclouds/net/domain/IpProtocol.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/net/domain/IpProtocol.java b/compute/src/main/java/org/jclouds/net/domain/IpProtocol.java
index 50d4422..203f0f9 100644
--- a/compute/src/main/java/org/jclouds/net/domain/IpProtocol.java
+++ b/compute/src/main/java/org/jclouds/net/domain/IpProtocol.java
@@ -29,12 +29,22 @@ public enum IpProtocol {
TCP, UDP, ICMP, ALL, UNRECOGNIZED;
+ public String value() {
+ return this == ALL ? "-1" : name().toLowerCase();
+ }
+
+ @Override
+ public String toString() {
+ return value();
+ }
+
public static IpProtocol fromValue(String protocol) {
try {
+ if (protocol.equalsIgnoreCase("-1"))
+ return ALL;
return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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
new file mode 100644
index 0000000..1a5c646
--- /dev/null
+++ b/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
@@ -0,0 +1,348 @@
+/*
+ * 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.extensions.internal;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+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 static org.jclouds.compute.predicates.NodePredicates.inGroup;
+import static org.jclouds.util.Predicates2.retry;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.ssh.SshClient;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+
+/**
+ * Base test for {@link SecurityGroupExtension} implementations.
+ *
+ * @author David Alves
+ *
+ */
+public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServiceContextLiveTest {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected String groupId;
+
+ /**
+ * Returns the template for the base node, override to test different templates.
+ *
+ * @return
+ */
+ public Template getNodeTemplate() {
+ return view.getComputeService().templateBuilder().build();
+ }
+
+
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true)
+ public void testCreateSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
+
+ ComputeService computeService = view.getComputeService();
+
+ Location location = getNodeTemplate().getLocation();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+
+ assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
+
+ SecurityGroup group = securityGroupExtension.get().createSecurityGroup("test-create-security-group", location);
+
+ logger.info("Group created: %s", group);
+
+ assertTrue(group.getName().contains("test-create-security-group"));
+
+ groupId = group.getId();
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testCreateSecurityGroup")
+ public void testGetSecurityGroupById() throws RunNodesException, InterruptedException, ExecutionException {
+
+ ComputeService computeService = view.getComputeService();
+
+ Location location = getNodeTemplate().getLocation();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+
+ assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
+
+ SecurityGroup group = securityGroupExtension.get().getSecurityGroupById(groupId);
+
+ logger.info("Group found: %s", group);
+
+ assertTrue(group.getName().contains("test-create-security-group"));
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testGetSecurityGroupById")
+ public void testAddIpPermission() {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+
+ assertTrue(optGroup.isPresent());
+
+ SecurityGroup group = optGroup.get();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(10);
+ builder.toPort(20);
+ builder.cidrBlock("0.0.0.0/0");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroup newGroup = securityGroupExtension.get().addIpPermission(perm, group);
+
+ assertEquals(perm, Iterables.getOnlyElement(newGroup.getIpPermissions()));
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermission")
+ public void testRemoveIpPermission() {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+
+ assertTrue(optGroup.isPresent());
+
+ SecurityGroup group = optGroup.get();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(10);
+ builder.toPort(20);
+ builder.cidrBlock("0.0.0.0/0");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroup newGroup = securityGroupExtension.get().removeIpPermission(perm, group);
+
+ assertEquals(0, Iterables.size(newGroup.getIpPermissions()));
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testRemoveIpPermission")
+ public void testAddIpPermissionsFromSpec() {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+
+ assertTrue(optGroup.isPresent());
+
+ SecurityGroup group = optGroup.get();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(50);
+ builder.toPort(60);
+ builder.cidrBlock("0.0.0.0/0");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroup newGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
+ 50,
+ 60,
+ emptyMultimap(),
+ ImmutableSet.of("0.0.0.0/0"),
+ emptyStringSet(),
+ group);
+
+ assertTrue(newGroup.getIpPermissions().contains(perm));
+
+ if (securityGroupExtension.get().supportsGroupIds()) {
+ IpPermission.Builder secondBuilder = IpPermission.builder();
+
+ int fromPort;
+ int toPort;
+
+ if (securityGroupExtension.get().supportsPortRangesForGroups()) {
+ fromPort = 70;
+ toPort = 80;
+ } else {
+ fromPort = 1;
+ toPort = 65535;
+ }
+ secondBuilder.ipProtocol(IpProtocol.TCP);
+ secondBuilder.fromPort(fromPort);
+ secondBuilder.toPort(toPort);
+ secondBuilder.groupId(group.getId());
+
+ IpPermission secondPerm = secondBuilder.build();
+
+ SecurityGroup secondNewGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
+ fromPort,
+ toPort,
+ emptyMultimap(),
+ emptyStringSet(),
+ ImmutableSet.of(group.getId()),
+ newGroup);
+
+ assertTrue(secondNewGroup.getIpPermissions().contains(secondPerm));
+ }
+
+ if (securityGroupExtension.get().supportsTenantIdGroupNamePairs()) {
+ IpPermission.Builder thirdBuilder = IpPermission.builder();
+
+ int fromPort;
+ int toPort;
+
+ if (securityGroupExtension.get().supportsPortRangesForGroups()) {
+ fromPort = 90;
+ toPort = 100;
+ } else {
+ fromPort = 1;
+ toPort = 65535;
+ }
+ thirdBuilder.ipProtocol(IpProtocol.TCP);
+ thirdBuilder.fromPort(fromPort);
+ thirdBuilder.toPort(toPort);
+ thirdBuilder.tenantIdGroupNamePair(group.getOwnerId(), group.getId());
+
+ IpPermission thirdPerm = thirdBuilder.build();
+
+ SecurityGroup thirdNewGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
+ fromPort,
+ toPort,
+ thirdPerm.getTenantIdGroupNamePairs(),
+ emptyStringSet(),
+ emptyStringSet(),
+ newGroup);
+
+ assertTrue(thirdNewGroup.getIpPermissions().contains(thirdPerm));
+ }
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionsFromSpec")
+ public void testCreateNodeWithSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Template template = view.getComputeService().templateBuilder()
+ .options(TemplateOptions.Builder.securityGroups(groupId))
+ .build();
+
+ NodeMetadata node = Iterables.getOnlyElement(computeService.createNodesInGroup("test-create-node-with-group", 1, template));
+
+ Set<SecurityGroup> groups = securityGroupExtension.get().listSecurityGroupsForNode(node.getId());
+
+ assertTrue(groups.size() > 0, "node has no groups");
+
+ Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroupsForNode(node.getId()),
+ new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ return input.getId().equals(groupId);
+ }
+ });
+
+ assertTrue(secGroup.isPresent());
+
+ computeService.destroyNodesMatching(inGroup(node.getGroup()));
+
+
+ }
+
+ // 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 = "testCreateNodeWithSecurityGroup")
+ public void testDeleteSecurityGroup() {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
+
+ assertTrue(optGroup.isPresent());
+
+ SecurityGroup group = optGroup.get();
+
+ assertTrue(securityGroupExtension.get().removeSecurityGroup(group.getId()));
+ }
+ */
+
+ private Multimap<String, String> emptyMultimap() {
+ return LinkedHashMultimap.create();
+ }
+
+ private Set<String> emptyStringSet() {
+ return Sets.newLinkedHashSet();
+ }
+
+ private Optional<SecurityGroup> getGroup(SecurityGroupExtension ext) {
+ return Iterables.tryFind(ext.listSecurityGroups(), new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ return input.getId().equals(groupId);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
----------------------------------------------------------------------
diff --git a/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
new file mode 100644
index 0000000..8c2b31c
--- /dev/null
+++ b/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.extensions.internal;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.util.Predicates2.retry;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.ssh.SshClient;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+
+/**
+ * Base test for {@link SecurityGroupExtension} implementations.
+ *
+ * @author Andrew Bayer
+ *
+ */
+@Test(groups = { "integration", "live" }, singleThreaded = true, testName="StubSecurityGroupExtensionIntegrationTest")
+public class StubSecurityGroupExtensionIntegrationTest extends BaseSecurityGroupExtensionLiveTest {
+
+ public StubSecurityGroupExtensionIntegrationTest() {
+ provider = "stub";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties overrides = super.setupProperties();
+ // This is a hack to make sure we get a different set of node IDs, nodes, groups, etc from StubComputeServiceIntegrationTest.
+ overrides.setProperty(provider + ".identity", "sec-stub");
+
+ return overrides;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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/5f524ee6/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/5f524ee6/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");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
index d9a15f3..8bcc4d5 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
@@ -46,6 +46,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.internal.PersistNodeCredentials;
import org.jclouds.compute.options.TemplateOptions;
@@ -104,13 +105,14 @@ public class AWSEC2ComputeService extends EC2ComputeService {
@Named("PLACEMENT") LoadingCache<RegionAndName, String> placementGroupMap,
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted, Optional<ImageExtension> imageExtension,
GroupNamingConvention.Factory namingConvention,
- @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames) {
+ @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, runScriptOnNodeFactory, initAdminAccess,
persistNodeCredentials, timeouts, userExecutor, client, credentialsMap, securityGroupMap, imageExtension,
- namingConvention, generateInstanceNames);
+ namingConvention, generateInstanceNames, securityGroupExtension);
this.client = client;
this.placementGroupMap = placementGroupMap;
this.placementGroupDeleted = placementGroupDeleted;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java
index 7d18968..5341d57 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java
@@ -39,6 +39,7 @@ import org.jclouds.aws.ec2.compute.suppliers.AWSEC2HardwareSupplier;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.ec2.compute.config.EC2BindComputeStrategiesByClass;
import org.jclouds.ec2.compute.domain.RegionAndName;
@@ -173,4 +174,9 @@ public class AWSEC2ComputeServiceContextModule extends BaseComputeServiceContext
protected Optional<ImageExtension> provideImageExtension(Injector i) {
return Optional.of(i.getInstance(ImageExtension.class));
}
+
+ @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/5f524ee6/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java
index f82216f..8102cb6 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java
@@ -31,6 +31,7 @@ import javax.inject.Singleton;
import org.jclouds.aws.ec2.compute.AWSEC2ComputeService;
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.aws.ec2.compute.extensions.AWSEC2SecurityGroupExtension;
import org.jclouds.aws.ec2.compute.loaders.AWSEC2CreateSecurityGroupIfNeeded;
import org.jclouds.aws.ec2.compute.suppliers.CallForImages;
import org.jclouds.aws.ec2.domain.PlacementGroup;
@@ -41,8 +42,10 @@ import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.domain.LoginCredentials;
@@ -50,9 +53,11 @@ import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule;
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.extensions.EC2ImageExtension;
+import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
import org.jclouds.ec2.compute.functions.EC2ImageParser;
+import org.jclouds.ec2.compute.functions.EC2SecurityGroupToSecurityGroup;
import org.jclouds.ec2.compute.functions.PasswordCredentialsFromWindowsInstance;
import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
@@ -105,8 +110,12 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep
install(new FactoryModuleBuilder().build(CallForImages.Factory.class));
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.Image, Image>>() {
}).to(EC2ImageParser.class);
+ bind(new TypeLiteral<Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup>>() {
+ }).to(EC2SecurityGroupToSecurityGroup.class);
bind(new TypeLiteral<ImageExtension>() {
}).to(EC2ImageExtension.class);
+ bind(new TypeLiteral<SecurityGroupExtension>() {
+ }).to(AWSEC2SecurityGroupExtension.class);
}
@Provides
[3/4] JCLOUDS-101 - Add SecurityGroupExtension for compute
Posted by ab...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionExpectTest.java
new file mode 100644
index 0000000..89e54f2
--- /dev/null
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionExpectTest.java
@@ -0,0 +1,585 @@
+/*
+ * 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.ec2.compute.extensions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+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.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.internal.BaseEC2ComputeServiceExpectTest;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "EC2SecurityGroupExtensionExpectTest")
+public class EC2SecurityGroupExtensionExpectTest extends BaseEC2ComputeServiceExpectTest {
+
+ public void testListSecurityGroups() {
+ HttpRequest describeSecurityGroupsAllRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups").build());
+
+ HttpResponse describeSecurityGroupsAllResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_new.xml", MediaType.APPLICATION_XML)).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsAllRequest, describeSecurityGroupsAllResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(describeInstanceRequest, describeInstanceResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroups();
+ assertEquals(2, groups.size());
+ }
+
+ public void testListSecurityGroupsInLocation() {
+ HttpRequest describeSecurityGroupsAllRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups").build());
+
+ HttpResponse describeSecurityGroupsAllResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_new.xml", MediaType.APPLICATION_XML)).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsAllRequest, describeSecurityGroupsAllResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(describeInstanceRequest, describeInstanceResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroupsInLocation(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+ assertEquals(2, groups.size());
+ }
+
+
+ public void testListSecurityGroupsForNode() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "sg-3c6ef654").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
+
+ HttpResponse describeInstanceWithSGResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_instances_running_securitygroups.xml", MediaType.APPLICATION_XML)).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(describeInstanceRequest, describeInstanceWithSGResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroupsForNode(new RegionAndName(region, "i-2baa5550").slashEncode());
+ assertEquals(1, groups.size());
+ }
+
+ public void testGetSecurityGroupById() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
+
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroup group = extension.getSecurityGroupById(new RegionAndName(region, "jclouds#some-group").slashEncode());
+ assertEquals("sg-3c6ef654", group.getProviderId());
+ assertEquals("jclouds#some-group", group.getId());
+ }
+
+ public void testCreateSecurityGroup() {
+ HttpRequest createSecurityGroupExtRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "CreateSecurityGroup")
+ .addFormParam("GroupDescription", "jclouds#some-group")
+ .addFormParam("GroupName", "jclouds#some-group").build());
+
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
+
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupExtRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroup group = extension.createSecurityGroup("some-group", new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ assertEquals("sg-3c6ef654", group.getProviderId());
+ assertEquals("jclouds#some-group", group.getId());
+ }
+
+ public void testRemoveSecurityGroup() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
+
+ HttpRequest deleteSecurityGroupRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DeleteSecurityGroup")
+ .addFormParam("GroupName", "jclouds#some-group").build());
+
+ HttpResponse deleteSecurityGroupResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/delete_securitygroup.xml", MediaType.APPLICATION_XML)).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(deleteSecurityGroupRequest, deleteSecurityGroupResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
+
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ assertTrue(extension.removeSecurityGroup(new RegionAndName(region, "jclouds#some-group").slashEncode()));
+ }
+
+ public void testAddIpPermissionCidrFromIpPermission() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestRange =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("CidrIp", "0.0.0.0/0")
+ .addFormParam("FromPort", "22")
+ .addFormParam("ToPort", "40")
+ .addFormParam("GroupName", "jclouds#some-group")
+ .addFormParam("IpProtocol", "tcp").build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(40);
+ builder.cidrBlock("0.0.0.0/0");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(1, newPerm.getCidrBlocks().size());
+ assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
+ }
+
+ public void testAddIpPermissionCidrFromParams() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestRange =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("CidrIp", "0.0.0.0/0")
+ .addFormParam("FromPort", "22")
+ .addFormParam("ToPort", "40")
+ .addFormParam("GroupName", "jclouds#some-group")
+ .addFormParam("IpProtocol", "tcp").build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 40,
+ emptyMultimap(),
+ ImmutableSet.of("0.0.0.0/0"),
+ emptyStringSet(),
+ origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(1, newPerm.getCidrBlocks().size());
+ assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
+ }
+
+
+ public void testAddIpPermissionGroupFromIpPermission() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("SourceSecurityGroupName", "jclouds#some-group")
+ .addFormParam("SourceSecurityGroupOwnerId", "993194456877")
+ .addFormParam("GroupName", "jclouds#some-group").build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(40);
+ builder.tenantIdGroupNamePair("993194456877", "jclouds#some-group");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+ groupBuilder.ownerId("993194456877");
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(0, newPerm.getCidrBlocks().size());
+ assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
+ assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
+ assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
+ }
+
+ public void testAddIpPermissionGroupFromParams() {
+ HttpRequest describeSecurityGroupsSingleRequest =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "DescribeSecurityGroups")
+ .addFormParam("GroupName.1", "jclouds#some-group").build());
+
+ HttpResponse describeSecurityGroupsSingleResponse =
+ HttpResponse.builder().statusCode(200)
+ .payload(payloadFromResourceWithContentType(
+ "/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
+
+
+ HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
+ formSigner.filter(HttpRequest.builder()
+ .method("POST")
+ .endpoint("https://ec2." + region + ".amazonaws.com/")
+ .addHeader("Host", "ec2." + region + ".amazonaws.com")
+ .addFormParam("Action", "AuthorizeSecurityGroupIngress")
+ .addFormParam("SourceSecurityGroupName", "jclouds#some-group")
+ .addFormParam("SourceSecurityGroupOwnerId", "993194456877")
+ .addFormParam("GroupName", "jclouds#some-group").build());
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
+ requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
+ requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
+ requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
+ requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
+
+ requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
+ groupBuilder.id("jclouds#some-group");
+ groupBuilder.providerId("sg-3c6ef654");
+ groupBuilder.name("jclouds#some-group");
+ groupBuilder.ownerId("993194456877");
+ groupBuilder.location(new LocationBuilder()
+ .scope(LocationScope.REGION)
+ .id(region)
+ .description("region")
+ .build());
+
+ SecurityGroup origGroup = groupBuilder.build();
+
+ ImmutableMultimap.Builder<String, String> permBuilder = ImmutableMultimap.builder();
+ permBuilder.put(origGroup.getOwnerId(), origGroup.getName());
+
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 40,
+ permBuilder.build(),
+ emptyStringSet(),
+ emptyStringSet(),
+ origGroup);
+
+ assertEquals(1, newGroup.getIpPermissions().size());
+
+ IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
+
+ assertNotNull(newPerm);
+ assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
+ assertEquals(22, newPerm.getFromPort());
+ assertEquals(40, newPerm.getToPort());
+ assertEquals(0, newPerm.getCidrBlocks().size());
+ assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
+ assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
+ assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
+ }
+
+ private Multimap<String, String> emptyMultimap() {
+ return LinkedHashMultimap.create();
+ }
+
+ private Set<String> emptyStringSet() {
+ return Sets.newLinkedHashSet();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionLiveTest.java
new file mode 100644
index 0000000..128e1a3
--- /dev/null
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtensionLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ec2.compute.extensions;
+
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+import com.google.inject.Module;
+
+/**
+ * Live test for ec2 {@link SecurityGroupExtension} implementation
+ *
+ * @author Andrew Bayer
+ *
+ */
+@Test(groups = "live", singleThreaded = true, testName = "EC2SecurityGroupExtensionLiveTest")
+public class EC2SecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
+
+ public EC2SecurityGroupExtensionLiveTest() {
+ provider = "ec2";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroupTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroupTest.java
new file mode 100644
index 0000000..9c7d3b1
--- /dev/null
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroupTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.ec2.compute.functions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.ec2.util.IpPermissions;
+import org.jclouds.net.domain.IpPermission;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "EC2SecurityGroupToSecurityGroupTest")
+public class EC2SecurityGroupToSecurityGroupTest {
+
+ static Location provider = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1")
+ .description("us-east-1").build();
+
+ @Test
+ public void testApply() {
+ IpPermissions authorization = IpPermissions.permitAnyProtocol();
+
+ org.jclouds.ec2.domain.SecurityGroup origGroup = org.jclouds.ec2.domain.SecurityGroup.builder()
+ .region("us-east-1")
+ .id("some-id")
+ .name("some-group")
+ .ownerId("some-owner")
+ .description("some-description")
+ .ipPermission(authorization)
+ .build();
+
+ EC2SecurityGroupToSecurityGroup parser = createGroupParser(ImmutableSet.of(provider));
+
+ SecurityGroup group = parser.apply(origGroup);
+
+ assertEquals(group.getLocation(), provider);
+ assertEquals(group.getId(), origGroup.getName());
+ assertEquals(group.getProviderId(), origGroup.getId());
+ assertEquals(group.getName(), origGroup.getName());
+ assertEquals(group.getIpPermissions(), (Set<IpPermission>)origGroup);
+ assertEquals(group.getOwnerId(), origGroup.getOwnerId());
+ }
+
+ private EC2SecurityGroupToSecurityGroup createGroupParser(final ImmutableSet<Location> locations) {
+ Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() {
+
+ @Override
+ public Set<? extends Location> get() {
+ return locations;
+ }
+
+ };
+
+ EC2SecurityGroupToSecurityGroup parser = new EC2SecurityGroupToSecurityGroup(locationSupplier);
+
+ return parser;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
index 85358b3..9597e1a 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
@@ -29,10 +29,10 @@ import java.util.concurrent.ExecutionException;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.ec2.services.SecurityGroupClient;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupAsyncClientTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupAsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupAsyncClientTest.java
index 24360d7..c22a279 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupAsyncClientTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupAsyncClientTest.java
@@ -22,12 +22,12 @@ import java.io.IOException;
import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
index 0f25935..c6d02d2 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
@@ -30,10 +30,10 @@ import java.util.Set;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.ec2.EC2ApiMetadata;
import org.jclouds.ec2.EC2Client;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -174,7 +174,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
assertEventually(new GroupHasPermission(client, group2Name, new Predicate<IpPermission>() {
@Override
public boolean apply(IpPermission arg0) {
- return arg0.getUserIdGroupPairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name));
+ return arg0.getTenantIdGroupNamePairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name));
}
}));
@@ -191,7 +191,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
@Override
public boolean apply(IpPermission arg0) {
return arg0.getIpProtocol() == IpProtocol.TCP && arg0.getFromPort() == 80 && arg0.getToPort() == 80
- && arg0.getIpRanges().equals(ImmutableSet.of("0.0.0.0/0"));
+ && arg0.getCidrBlocks().equals(ImmutableSet.of("0.0.0.0/0"));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/util/IpPermissionsTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/util/IpPermissionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/util/IpPermissionsTest.java
index 6d466b7..03a2549 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/util/IpPermissionsTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/util/IpPermissionsTest.java
@@ -18,7 +18,7 @@ package org.jclouds.ec2.util;
import static org.testng.Assert.assertEquals;
-import org.jclouds.ec2.domain.IpProtocol;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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 8032aaa..caabd1a 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
@@ -21,10 +21,10 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.http.functions.ParseSax;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
@@ -46,10 +46,10 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
InputStream is = getClass().getResourceAsStream("/describe_securitygroups.xml");
Set<SecurityGroup> expected = ImmutableSet.of(
- new SecurityGroup(defaultRegion, null, "WebServers", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers",
+ 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")))),
- new SecurityGroup(defaultRegion, null, "RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Group A",
+ 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()))));
@@ -69,7 +69,7 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
userIdGroupPairs.put("UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "jclouds#cluster#world");
Set<SecurityGroup> expected = ImmutableSet.of(
- new SecurityGroup(defaultRegion, null, "jclouds#cluster#world", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Cluster",
+ 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")),
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/delete_securitygroup.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/delete_securitygroup.xml b/apis/ec2/src/test/resources/delete_securitygroup.xml
new file mode 100644
index 0000000..9545778
--- /dev/null
+++ b/apis/ec2/src/test/resources/delete_securitygroup.xml
@@ -0,0 +1,4 @@
+<DeleteSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/2013-02-01/">
+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
+ <return>true</return>
+</DeleteSecurityGroupResponse>
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_instances_running_securitygroups.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_instances_running_securitygroups.xml b/apis/ec2/src/test/resources/describe_instances_running_securitygroups.xml
new file mode 100644
index 0000000..4c07ed2
--- /dev/null
+++ b/apis/ec2/src/test/resources/describe_instances_running_securitygroups.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2011-05-15/">
+ <requestId>f6d3252e-35e5-4ef5-b2c5-62da95dd829b</requestId>
+ <reservationSet>
+ <item>
+ <reservationId>r-205ad944</reservationId>
+ <ownerId>993194456877</ownerId>
+ <groupSet>
+ <item>
+ <groupId>sg-3c6ef654</groupId>
+ <groupName>jclouds#some-group</groupName>
+ </item>
+ </groupSet>
+ <instancesSet>
+ <item>
+ <instanceId>i-2baa5550</instanceId>
+ <imageId>ami-aecd60c7</imageId>
+ <instanceState>
+ <code>16</code>
+ <name>running</name>
+ </instanceState>
+ <privateDnsName>ip-10-28-89-195.ec2.internal</privateDnsName>
+ <dnsName>ec2-50-16-1-166.compute-1.amazonaws.com</dnsName>
+ <reason/>
+ <keyName>jclouds#mygroup2#81</keyName>
+ <amiLaunchIndex>0</amiLaunchIndex>
+ <productCodes/>
+ <instanceType>t1.micro</instanceType>
+ <launchTime>2012-08-02T04:28:30.000Z</launchTime>
+ <placement>
+ <availabilityZone>us-east-1e</availabilityZone>
+ <groupName/>
+ <tenancy>default</tenancy>
+ </placement>
+ <kernelId>aki-88aa75e1</kernelId>
+ <monitoring>
+ <state>disabled</state>
+ </monitoring>
+ <privateIpAddress>10.28.89.195</privateIpAddress>
+ <ipAddress>50.16.1.166</ipAddress>
+ <groupSet>
+ <item>
+ <groupId>sg-3c6ef654</groupId>
+ <groupName>jclouds#some-group</groupName>
+ </item>
+ </groupSet>
+ <architecture>x86_64</architecture>
+ <rootDeviceType>ebs</rootDeviceType>
+ <rootDeviceName>/dev/sda1</rootDeviceName>
+ <blockDeviceMapping>
+ <item>
+ <deviceName>/dev/sda1</deviceName>
+ <ebs>
+ <volumeId>vol-f2d7c993</volumeId>
+ <status>attached</status>
+ <attachTime>2012-08-02T04:28:56.000Z</attachTime>
+ <deleteOnTermination>true</deleteOnTermination>
+ </ebs>
+ </item>
+ </blockDeviceMapping>
+ <virtualizationType>paravirtual</virtualizationType>
+ <clientToken/>
+ <tagSet>
+ <item>
+ <key>Name</key>
+ <value>mygroup2-2baa5550</value>
+ </item>
+ </tagSet>
+ <hypervisor>xen</hypervisor>
+ </item>
+ </instancesSet>
+ </item>
+ </reservationSet>
+</DescribeInstancesResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups.xml b/apis/ec2/src/test/resources/describe_securitygroups.xml
index 3a6c9b8..b703afa 100644
--- a/apis/ec2/src/test/resources/describe_securitygroups.xml
+++ b/apis/ec2/src/test/resources/describe_securitygroups.xml
@@ -3,6 +3,7 @@
<securityGroupInfo>
<item>
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
+ <groupId>sg-3c6ef654</groupId>
<groupName>WebServers</groupName>
<groupDescription>Web Servers</groupDescription>
<ipPermissions>
@@ -21,7 +22,8 @@
</item>
<item>
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
- <groupName>RangedPortsBySource</groupName>
+ <groupId>sg-867309ab</groupId>
+ <groupName>RangedPortsBySource</groupName>
<groupDescription>Group A</groupDescription>
<ipPermissions>
<item>
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups_empty.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups_empty.xml b/apis/ec2/src/test/resources/describe_securitygroups_empty.xml
index 0079ee6..ca89f4e 100644
--- a/apis/ec2/src/test/resources/describe_securitygroups_empty.xml
+++ b/apis/ec2/src/test/resources/describe_securitygroups_empty.xml
@@ -23,6 +23,7 @@
<ipRanges />
<groups>
<item>
+ <groupId>sg-3c6ef654</groupId>
<groupName>jclouds#cluster#world</groupName>
<userId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</userId>
</item>
@@ -31,6 +32,7 @@
</item>
</ipPermissions>
<groupName>jclouds#cluster#world</groupName>
+ <groupId>sg-3c6ef654</groupId>
<groupDescription>Cluster</groupDescription>
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
</item>
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups_extension_cidr.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups_extension_cidr.xml b/apis/ec2/src/test/resources/describe_securitygroups_extension_cidr.xml
new file mode 100644
index 0000000..f6a6f9e
--- /dev/null
+++ b/apis/ec2/src/test/resources/describe_securitygroups_extension_cidr.xml
@@ -0,0 +1,24 @@
+<DescribeSecurityGroupsResponse
+ xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
+ <securityGroupInfo>
+ <item>
+ <ownerId>993194456877</ownerId>
+ <groupId>sg-3c6ef654</groupId>
+ <groupName>jclouds#some-group</groupName>
+ <groupDescription>jclouds#some-group</groupDescription>
+ <ipPermissions>
+ <item>
+ <ipProtocol>tcp</ipProtocol>
+ <fromPort>22</fromPort>
+ <toPort>40</toPort>
+ <groups />
+ <ipRanges>
+ <item>
+ <cidrIp>0.0.0.0/0</cidrIp>
+ </item>
+ </ipRanges>
+ </item>
+ </ipPermissions>
+ </item>
+ </securityGroupInfo>
+</DescribeSecurityGroupsResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups_extension_group.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups_extension_group.xml b/apis/ec2/src/test/resources/describe_securitygroups_extension_group.xml
new file mode 100644
index 0000000..126d45c
--- /dev/null
+++ b/apis/ec2/src/test/resources/describe_securitygroups_extension_group.xml
@@ -0,0 +1,26 @@
+<DescribeSecurityGroupsResponse
+ xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
+ <securityGroupInfo>
+ <item>
+ <ownerId>993194456877</ownerId>
+ <groupName>jclouds#some-group</groupName>
+ <groupDescription>jclouds#some-group</groupDescription>
+ <groupId>sg-3c6ef654</groupId>
+ <ipPermissions>
+ <item>
+ <ipProtocol>tcp</ipProtocol>
+ <fromPort>22</fromPort>
+ <toPort>40</toPort>
+ <groups>
+ <item>
+ <userId>993194456877</userId>
+ <groupId>sg-3c6ef654</groupId>
+ <groupName>jclouds#some-group</groupName>
+ </item>
+ </groups>
+ <ipRanges/>
+ </item>
+ </ipPermissions>
+ </item>
+ </securityGroupInfo>
+</DescribeSecurityGroupsResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups_extension_new.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups_extension_new.xml b/apis/ec2/src/test/resources/describe_securitygroups_extension_new.xml
new file mode 100644
index 0000000..7d2c211
--- /dev/null
+++ b/apis/ec2/src/test/resources/describe_securitygroups_extension_new.xml
@@ -0,0 +1,27 @@
+<DescribeSecurityGroupsResponse
+ xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
+ <securityGroupInfo>
+ <item>
+ <ownerId>993194456877</ownerId>
+ <groupName>jclouds#some-group</groupName>
+ <groupDescription>jclouds#some-group</groupDescription>
+ <groupId>sg-3c6ef654</groupId>
+ <ipPermissions/>
+ </item>
+ <item>
+ <ownerId>993194456877</ownerId>
+ <groupId>sg-3a2b3c4d</groupId>
+ <groupName>group-a</groupName>
+ <groupDescription>Group A</groupDescription>
+ <ipPermissions>
+ <item>
+ <ipProtocol>tcp</ipProtocol>
+ <fromPort>6000</fromPort>
+ <toPort>7000</toPort>
+ <groups />
+ <ipRanges />
+ </item>
+ </ipPermissions>
+ </item>
+ </securityGroupInfo>
+</DescribeSecurityGroupsResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/resources/describe_securitygroups_extension_single.xml
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/resources/describe_securitygroups_extension_single.xml b/apis/ec2/src/test/resources/describe_securitygroups_extension_single.xml
new file mode 100644
index 0000000..f66e4c6
--- /dev/null
+++ b/apis/ec2/src/test/resources/describe_securitygroups_extension_single.xml
@@ -0,0 +1,12 @@
+<DescribeSecurityGroupsResponse
+ xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
+ <securityGroupInfo>
+ <item>
+ <ownerId>993194456877</ownerId>
+ <groupName>jclouds#some-group</groupName>
+ <groupDescription>jclouds#some-group</groupDescription>
+ <groupId>sg-3c6ef654</groupId>
+ <ipPermissions/>
+ </item>
+ </securityGroupInfo>
+</DescribeSecurityGroupsResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
index 28c26e1..7a10942 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
@@ -40,6 +40,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.PersistNodeCredentials;
@@ -107,12 +108,13 @@ public class NovaComputeService extends BaseComputeService {
LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap,
LoadingCache<ZoneAndName, KeyPair> keyPairCache,
Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId,
- GroupNamingConvention.Factory namingConvention, Optional<ImageExtension> imageExtension) {
+ GroupNamingConvention.Factory namingConvention, Optional<ImageExtension> imageExtension,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
- persistNodeCredentials, timeouts, userExecutor, imageExtension);
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
this.novaApi = checkNotNull(novaApi, "novaApi");
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache");
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
index 92a19b3..57a341d 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
@@ -38,12 +38,14 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.functions.IdentityFunction;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeService;
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeServiceAdapter;
import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
@@ -51,7 +53,9 @@ import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNe
import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInZoneToHardware;
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInZoneToImage;
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
+import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByZoneId;
+import org.jclouds.openstack.nova.v2_0.compute.functions.SecurityGroupRuleToIpPermission;
import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInZoneToNodeMetadata;
import org.jclouds.openstack.nova.v2_0.compute.loaders.CreateUniqueKeyPair;
import org.jclouds.openstack.nova.v2_0.compute.loaders.FindSecurityGroupOrCreate;
@@ -60,6 +64,7 @@ import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
import org.jclouds.openstack.nova.v2_0.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.domain.Server;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
@@ -108,6 +113,12 @@ public class NovaComputeServiceContextModule extends
bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
}).to(ServerInZoneToNodeMetadata.class);
+ bind(new TypeLiteral<Function<SecurityGroupRule, IpPermission>>() {
+ }).to(SecurityGroupRuleToIpPermission.class);
+
+ bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup>>() {
+ }).to(NovaSecurityGroupToSecurityGroup.class);
+
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
}).to(OrphanedGroupsByZoneId.class);
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
index 04f992e..6b5d519 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
@@ -28,9 +28,9 @@ import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
new file mode 100644
index 0000000..3e8b8a6
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
@@ -0,0 +1,74 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming a Nova-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class NovaSecurityGroupToSecurityGroup implements Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected Function<SecurityGroupRule,IpPermission> ruleToPermission;
+
+ @Inject
+ public NovaSecurityGroupToSecurityGroup(Function<SecurityGroupRule,IpPermission> ruleToPermission) {
+ this.ruleToPermission = ruleToPermission;
+ }
+
+ @Override
+ public SecurityGroup apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+ builder.id(group.getId());
+ builder.providerId(group.getId());
+ builder.ownerId(group.getTenantId());
+ builder.name(group.getName());
+ builder.ipPermissions(transform(group.getRules(), ruleToPermission));
+
+ return builder.build();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
new file mode 100644
index 0000000..c2e5e64
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
@@ -0,0 +1,57 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+
+import com.google.common.base.Function;
+
+
+/**
+ * A function for transforming a nova-specific SecurityGroupRule into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class SecurityGroupRuleToIpPermission implements Function<SecurityGroupRule, IpPermission> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ public SecurityGroupRuleToIpPermission() {
+ }
+
+ @Override
+ public IpPermission apply(SecurityGroupRule rule) {
+ IpPermission.Builder builder = IpPermission.builder();
+ builder.ipProtocol(rule.getIpProtocol());
+ builder.fromPort(rule.getFromPort());
+ builder.toPort(rule.getToPort());
+ if (rule.getGroup() != null)
+ builder.tenantIdGroupNamePair(rule.getGroup().getTenantId(), rule.getGroup().getName());
+ if (rule.getIpRange() != null)
+ builder.cidrBlock(rule.getIpRange());
+
+ return builder.build();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Ingress.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Ingress.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Ingress.java
index d687e83..3a9322d 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Ingress.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Ingress.java
@@ -21,6 +21,7 @@ import java.beans.ConstructorProperties;
import javax.inject.Named;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.net.domain.IpProtocol;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/IpProtocol.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/IpProtocol.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/IpProtocol.java
deleted file mode 100644
index ac13977..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/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.openstack.nova.v2_0.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/5f524ee6/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/SecurityGroupRule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/SecurityGroupRule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/SecurityGroupRule.java
index 3da080d..92d58f7 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/SecurityGroupRule.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/SecurityGroupRule.java
@@ -23,6 +23,7 @@ import java.beans.ConstructorProperties;
import javax.inject.Named;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
new file mode 100644
index 0000000..8db1e15
--- /dev/null
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.collect.Iterables.transform;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "NovaSecurityGroupToSecurityGroupTest")
+public class NovaSecurityGroupToSecurityGroupTest {
+
+ private static final SecurityGroupRuleToIpPermission ruleConverter = new SecurityGroupRuleToIpPermission();
+
+ @Test
+ public void testApplyWithGroup() {
+ TenantIdAndName group = TenantIdAndName.builder().tenantId("tenant").name("name").build();
+
+ SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .group(group)
+ .parentGroupId("some-other-id")
+ .build();
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
+ .tenantId("tenant")
+ .id("some-id")
+ .name("some-group")
+ .description("some-description")
+ .rules(ruleToConvert)
+ .build();
+
+ NovaSecurityGroupToSecurityGroup parser = createGroupParser();
+
+ SecurityGroup newGroup = parser.apply(origGroup);
+
+ assertEquals(newGroup.getId(), origGroup.getId());
+ assertEquals(newGroup.getProviderId(), origGroup.getId());
+ assertEquals(newGroup.getName(), origGroup.getName());
+ assertEquals(newGroup.getOwnerId(), origGroup.getTenantId());
+ assertEquals(newGroup.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getRules(), ruleConverter)));
+ }
+
+ @Test
+ public void testApplyWithCidr() {
+ SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .ipRange("0.0.0.0/0")
+ .parentGroupId("some-other-id")
+ .build();
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
+ .tenantId("tenant")
+ .id("some-id")
+ .name("some-group")
+ .description("some-description")
+ .rules(ruleToConvert)
+ .build();
+
+ NovaSecurityGroupToSecurityGroup parser = createGroupParser();
+
+ SecurityGroup group = parser.apply(origGroup);
+
+ assertEquals(group.getId(), origGroup.getId());
+ assertEquals(group.getProviderId(), origGroup.getId());
+ assertEquals(group.getName(), origGroup.getName());
+ assertEquals(group.getOwnerId(), origGroup.getTenantId());
+ assertEquals(group.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getRules(), ruleConverter)));
+ }
+
+ private NovaSecurityGroupToSecurityGroup createGroupParser() {
+ NovaSecurityGroupToSecurityGroup parser = new NovaSecurityGroupToSecurityGroup(ruleConverter);
+
+ return parser;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermissionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermissionTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermissionTest.java
new file mode 100644
index 0000000..1702a13
--- /dev/null
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermissionTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+
+/**
+ * Tests for the function for transforming a nova specific SecurityGroupRule into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class SecurityGroupRuleToIpPermissionTest {
+
+ @Test
+ public void testApplyWithGroup() {
+
+ TenantIdAndName group = TenantIdAndName.builder().tenantId("tenant").name("name").build();
+
+ SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .group(group)
+ .parentGroupId("some-other-id")
+ .build();
+
+ SecurityGroupRuleToIpPermission converter = new SecurityGroupRuleToIpPermission();
+
+ IpPermission convertedPerm = converter.apply(ruleToConvert);
+
+ assertEquals(convertedPerm.getIpProtocol(), ruleToConvert.getIpProtocol());
+ assertEquals(convertedPerm.getFromPort(), ruleToConvert.getFromPort());
+ assertEquals(convertedPerm.getToPort(), ruleToConvert.getToPort());
+ assertTrue(convertedPerm.getTenantIdGroupNamePairs().containsKey(group.getTenantId()));
+ assertTrue(convertedPerm.getTenantIdGroupNamePairs().containsValue(group.getName()));
+ assertTrue(convertedPerm.getCidrBlocks().size() == 0);
+ }
+
+ @Test
+ public void testApplyWithCidr() {
+ SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .ipRange("0.0.0.0/0")
+ .parentGroupId("some-other-id")
+ .build();
+
+ SecurityGroupRuleToIpPermission converter = new SecurityGroupRuleToIpPermission();
+
+ IpPermission convertedPerm = converter.apply(ruleToConvert);
+
+ assertEquals(convertedPerm.getIpProtocol(), ruleToConvert.getIpProtocol());
+ assertEquals(convertedPerm.getFromPort(), ruleToConvert.getFromPort());
+ assertEquals(convertedPerm.getToPort(), ruleToConvert.getToPort());
+ assertEquals(convertedPerm.getCidrBlocks(), ImmutableSet.of("0.0.0.0/0"));
+ assertTrue(convertedPerm.getTenantIdGroupNamePairs().size() == 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiExpectTest.java
index 1a9f4fd..1fa8416 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiExpectTest.java
@@ -24,9 +24,9 @@ import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiLiveTest.java
index 665bb4e..c0fb2df 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiLiveTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApiLiveTest.java
@@ -20,8 +20,8 @@ import static org.testng.Assert.assertNotNull;
import java.util.Set;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
-import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
[4/4] git commit: JCLOUDS-101 - Add SecurityGroupExtension for compute
Posted by ab...@apache.org.
JCLOUDS-101 - Add SecurityGroupExtension for compute
- Adds the SecurityGroupExtension to compute, with tests and stub
support.
- Gets everything else to actually build against this.
- Unifies on compute's IpPermission/IpProtocol, eliminating EC2's.
- Converters from EC2/Nova/CloudStack SecurityGroup (and rules, for
the latter two) to the compute SecurityGroup (and rules, etc).
- EC2SecurityGroupExtension and tests.
- AWSEC2SecurityGroupExtension and tests - depends on JCLOUDS-99.
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/5f524ee6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/5f524ee6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/5f524ee6
Branch: refs/heads/master
Commit: 5f524ee6c91916bfbda15d484a47315c1f0ece6e
Parents: a906f9f
Author: Andrew Bayer <an...@gmail.com>
Authored: Wed Jun 26 13:48:17 2013 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Wed Jun 26 14:59:01 2013 -0700
----------------------------------------------------------------------
.../compute/CloudStackComputeService.java | 6 +-
.../CloudStackComputeServiceContextModule.java | 8 +
.../CloudStackSecurityGroupToSecurityGroup.java | 74 +++
.../functions/IngressRuleToIpPermission.java | 55 ++
...udStackSecurityGroupToSecurityGroupTest.java | 80 +++
.../IngressRuleToIpPermissionTest.java | 61 ++
.../clojure/org/jclouds/ec2/security_group2.clj | 6 +-
.../BindIpPermissionToIndexedFormParams.java | 2 +-
.../BindIpPermissionsToIndexedFormParams.java | 2 +-
.../jclouds/ec2/compute/EC2ComputeService.java | 6 +-
.../config/EC2ComputeServiceContextModule.java | 5 +
.../EC2ComputeServiceDependenciesModule.java | 8 +
.../extensions/EC2SecurityGroupExtension.java | 384 ++++++++++++
.../EC2SecurityGroupToSecurityGroup.java | 95 +++
.../loaders/CreateSecurityGroupIfNeeded.java | 2 +-
.../org/jclouds/ec2/domain/IpPermission.java | 189 ------
.../java/org/jclouds/ec2/domain/IpProtocol.java | 48 --
.../org/jclouds/ec2/domain/SecurityGroup.java | 1 +
.../ec2/services/SecurityGroupAsyncClient.java | 2 +-
.../ec2/services/SecurityGroupClient.java | 2 +-
.../org/jclouds/ec2/util/IpPermissions.java | 22 +-
.../jclouds/ec2/xml/IpPermissionHandler.java | 8 +-
...plicationArchitecturesEC2ClientLiveTest.java | 2 +-
.../jclouds/ec2/EBSBootEC2ClientLiveTest.java | 2 +-
.../ec2/compute/EC2ComputeServiceLiveTest.java | 2 +-
.../EC2SecurityGroupExtensionExpectTest.java | 585 +++++++++++++++++++
.../EC2SecurityGroupExtensionLiveTest.java | 39 ++
.../EC2SecurityGroupToSecurityGroupTest.java | 85 +++
.../CreateSecurityGroupIfNeededTest.java | 2 +-
.../services/SecurityGroupAsyncClientTest.java | 2 +-
.../services/SecurityGroupClientLiveTest.java | 8 +-
.../org/jclouds/ec2/util/IpPermissionsTest.java | 2 +-
...scribeSecurityGroupsResponseHandlerTest.java | 10 +-
.../src/test/resources/delete_securitygroup.xml | 4 +
...escribe_instances_running_securitygroups.xml | 74 +++
.../test/resources/describe_securitygroups.xml | 4 +-
.../resources/describe_securitygroups_empty.xml | 2 +
.../describe_securitygroups_extension_cidr.xml | 24 +
.../describe_securitygroups_extension_group.xml | 26 +
.../describe_securitygroups_extension_new.xml | 27 +
...describe_securitygroups_extension_single.xml | 12 +
.../nova/v2_0/compute/NovaComputeService.java | 6 +-
.../config/NovaComputeServiceContextModule.java | 11 +
.../functions/CreateSecurityGroupIfNeeded.java | 2 +-
.../NovaSecurityGroupToSecurityGroup.java | 74 +++
.../SecurityGroupRuleToIpPermission.java | 57 ++
.../openstack/nova/v2_0/domain/Ingress.java | 1 +
.../openstack/nova/v2_0/domain/IpProtocol.java | 39 --
.../nova/v2_0/domain/SecurityGroupRule.java | 1 +
.../NovaSecurityGroupToSecurityGroupTest.java | 112 ++++
.../SecurityGroupRuleToIpPermissionTest.java | 86 +++
.../extensions/SecurityGroupApiExpectTest.java | 2 +-
.../extensions/SecurityGroupApiLiveTest.java | 2 +-
...eComputeServiceTypicalSecurityGroupTest.java | 2 +-
.../v2_0/parse/ParseSecurityGroupListTest.java | 2 +-
.../nova/v2_0/parse/ParseSecurityGroupTest.java | 2 +-
.../compute/TerremarkVCloudComputeService.java | 5 +-
.../org/jclouds/compute/ComputeService.java | 9 +
.../config/BaseComputeServiceContextModule.java | 7 +
.../org/jclouds/compute/domain/ComputeType.java | 2 +-
.../jclouds/compute/domain/SecurityGroup.java | 80 +++
.../compute/domain/SecurityGroupBuilder.java | 122 ++++
.../extensions/SecurityGroupExtension.java | 180 ++++++
.../compute/internal/BaseComputeService.java | 12 +-
.../compute/options/TemplateOptions.java | 60 +-
.../stub/config/StubComputeServiceAdapter.java | 34 +-
.../config/StubComputeServiceContextModule.java | 10 +
.../StubComputeServiceDependenciesModule.java | 58 ++
.../extensions/StubSecurityGroupExtension.java | 256 ++++++++
.../org/jclouds/net/domain/IpPermission.java | 22 +-
.../java/org/jclouds/net/domain/IpProtocol.java | 12 +-
.../BaseSecurityGroupExtensionLiveTest.java | 348 +++++++++++
...ubSecurityGroupExtensionIntegrationTest.java | 70 +++
.../org/jclouds/net/util/IpPermissionsTest.java | 14 +
.../main/java/org/jclouds/util/Strings2.java | 9 +
.../java/org/jclouds/util/Strings2Test.java | 8 +
.../aws/ec2/compute/AWSEC2ComputeService.java | 6 +-
.../AWSEC2ComputeServiceContextModule.java | 6 +
.../AWSEC2ComputeServiceDependenciesModule.java | 9 +
.../AWSEC2SecurityGroupExtension.java | 177 ++++++
.../AWSEC2CreateSecurityGroupIfNeeded.java | 10 +-
.../services/AWSSecurityGroupAsyncClient.java | 2 +-
.../ec2/services/AWSSecurityGroupClient.java | 2 +-
.../compute/AWSEC2ComputeServiceLiveTest.java | 2 +-
.../AWSEC2SecurityGroupExtensionExpectTest.java | 367 ++++++++++++
.../AWSEC2SecurityGroupExtensionLiveTest.java | 39 ++
.../AWSEC2CreateSecurityGroupIfNeededTest.java | 10 +-
.../DescribeSecurityGroupsResponseTest.java | 6 +-
.../AWSSecurityGroupAsyncClientTest.java | 4 +-
.../AWSSecurityGroupClientLiveTest.java | 6 +-
.../gogrid/compute/GoGridComputeService.java | 5 +-
91 files changed, 3982 insertions(+), 364 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/CloudStackComputeService.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/CloudStackComputeService.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/CloudStackComputeService.java
index 32d4d59..fe25a68 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/CloudStackComputeService.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/CloudStackComputeService.java
@@ -43,6 +43,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.PersistNodeCredentials;
@@ -113,12 +114,13 @@ public class CloudStackComputeService extends BaseComputeService {
Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId,
GroupNamingConvention.Factory namingConvention,
Supplier<LoadingCache<String, Zone>> zoneIdToZone,
- Optional<ImageExtension> imageExtension) {
+ Optional<ImageExtension> imageExtension,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
- persistNodeCredentials, timeouts, userExecutor, imageExtension);
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
this.zoneIdToZone = checkNotNull(zoneIdToZone, "zoneIdToZone");
this.client = checkNotNull(client, "client");
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
index 92e0b6c..fa4c214 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
@@ -32,6 +32,8 @@ import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.compute.CloudStackComputeService;
import org.jclouds.cloudstack.compute.extensions.CloudStackImageExtension;
+import org.jclouds.cloudstack.compute.functions.CloudStackSecurityGroupToSecurityGroup;
+import org.jclouds.cloudstack.compute.functions.IngressRuleToIpPermission;
import org.jclouds.cloudstack.compute.functions.OrphanedGroupsByZoneId;
import org.jclouds.cloudstack.compute.functions.ServiceOfferingToHardware;
import org.jclouds.cloudstack.compute.functions.TemplateToImage;
@@ -46,6 +48,7 @@ import org.jclouds.cloudstack.compute.strategy.BasicNetworkOptionsConverter;
import org.jclouds.cloudstack.compute.strategy.CloudStackComputeServiceAdapter;
import org.jclouds.cloudstack.compute.strategy.OptionsConverter;
import org.jclouds.cloudstack.domain.FirewallRule;
+import org.jclouds.cloudstack.domain.IngressRule;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkType;
@@ -77,6 +80,7 @@ import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
@@ -112,6 +116,10 @@ public class CloudStackComputeServiceContextModule extends
}).to(CloudStackComputeServiceAdapter.class);
bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
}).to(VirtualMachineToNodeMetadata.class);
+ bind(new TypeLiteral<Function<SecurityGroup, org.jclouds.compute.domain.SecurityGroup>>() {
+ }).to(CloudStackSecurityGroupToSecurityGroup.class);
+ bind(new TypeLiteral<Function<IngressRule, IpPermission>>() {
+ }).to(IngressRuleToIpPermission.class);
bind(new TypeLiteral<Function<Template, org.jclouds.compute.domain.Image>>() {
}).to(TemplateToImage.class);
bind(new TypeLiteral<Function<ServiceOffering, org.jclouds.compute.domain.Hardware>>() {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroup.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroup.java
new file mode 100644
index 0000000..10a3e31
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroup.java
@@ -0,0 +1,74 @@
+/*
+ * 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.cloudstack.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.cloudstack.domain.IngressRule;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming a CloudStack-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class CloudStackSecurityGroupToSecurityGroup implements Function<org.jclouds.cloudstack.domain.SecurityGroup, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final Function<IngressRule,IpPermission> ruleToPermission;
+
+ @Inject
+ public CloudStackSecurityGroupToSecurityGroup(Function<IngressRule,IpPermission> ruleToPermission) {
+ this.ruleToPermission = ruleToPermission;
+ }
+
+ @Override
+ public SecurityGroup apply(org.jclouds.cloudstack.domain.SecurityGroup group) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+ builder.id(group.getId());
+ builder.providerId(group.getId());
+ builder.name(group.getName());
+ builder.ownerId(group.getAccount());
+ builder.ipPermissions(transform(group.getIngressRules(), ruleToPermission));
+
+ return builder.build();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermission.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermission.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermission.java
new file mode 100644
index 0000000..ed04568
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermission.java
@@ -0,0 +1,55 @@
+/*
+ * 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.cloudstack.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+
+
+/**
+ * A function for transforming a CloudStack-specific IngressRule into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class IngressRuleToIpPermission implements Function<IngressRule, IpPermission> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ public IngressRuleToIpPermission() {
+ }
+
+ @Override
+ public IpPermission apply(IngressRule rule) {
+ IpPermission.Builder builder = IpPermission.builder();
+ builder.ipProtocol(IpProtocol.fromValue(rule.getProtocol()));
+ builder.fromPort(rule.getStartPort());
+ builder.toPort(rule.getEndPort());
+ builder.cidrBlock(rule.getCIDR());
+
+ return builder.build();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroupTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroupTest.java
new file mode 100644
index 0000000..22420de
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/CloudStackSecurityGroupToSecurityGroupTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cloudstack.compute.functions;
+
+import static com.google.common.collect.Iterables.transform;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "CloudStackSecurityGroupToSecurityGroupTest")
+public class CloudStackSecurityGroupToSecurityGroupTest {
+
+ private static final IngressRuleToIpPermission ruleConverter = new IngressRuleToIpPermission();
+
+ @Test
+ public void testApply() {
+ IngressRule ruleToConvert = IngressRule.builder()
+ .id("some-id")
+ .account("some-account")
+ .securityGroupName("some-group-name")
+ .protocol(IpProtocol.TCP.toString())
+ .startPort(10)
+ .endPort(20)
+ .CIDR("0.0.0.0/0")
+ .build();
+
+ org.jclouds.cloudstack.domain.SecurityGroup origGroup = org.jclouds.cloudstack.domain.SecurityGroup.builder()
+ .id("some-id")
+ .name("some-group")
+ .description("some-description")
+ .account("some-account")
+ .ingressRules(ImmutableSet.of(ruleToConvert))
+ .build();
+
+ CloudStackSecurityGroupToSecurityGroup parser = createGroupParser();
+
+ SecurityGroup group = parser.apply(origGroup);
+
+ assertEquals(group.getId(), origGroup.getId());
+ assertEquals(group.getProviderId(), origGroup.getId());
+ assertEquals(group.getName(), origGroup.getName());
+ assertEquals(group.getOwnerId(), origGroup.getAccount());
+ assertEquals(group.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getIngressRules(), ruleConverter)));
+ }
+
+ private CloudStackSecurityGroupToSecurityGroup createGroupParser() {
+ CloudStackSecurityGroupToSecurityGroup parser = new CloudStackSecurityGroupToSecurityGroup(ruleConverter);
+
+ return parser;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermissionTest.java
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermissionTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermissionTest.java
new file mode 100644
index 0000000..0f5babb
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/functions/IngressRuleToIpPermissionTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.cloudstack.compute.functions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+
+/**
+ * Tests for the function for transforming a cloudstack specific IngressRule into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class IngressRuleToIpPermissionTest {
+
+ @Test
+ public void testApplyWithTCP() {
+ IngressRule ruleToConvert = IngressRule.builder()
+ .id("some-id")
+ .account("some-account")
+ .securityGroupName("some-group-name")
+ .protocol(IpProtocol.TCP.toString())
+ .startPort(10)
+ .endPort(20)
+ .CIDR("0.0.0.0/0")
+ .build();
+
+ IngressRuleToIpPermission converter = new IngressRuleToIpPermission();
+
+ IpPermission convertedPerm = converter.apply(ruleToConvert);
+
+ assertEquals(convertedPerm.getIpProtocol(), IpProtocol.fromValue(ruleToConvert.getProtocol()));
+ assertEquals(convertedPerm.getFromPort(), ruleToConvert.getStartPort());
+ assertEquals(convertedPerm.getToPort(), ruleToConvert.getEndPort());
+ assertEquals(convertedPerm.getCidrBlocks(), ImmutableSet.of("0.0.0.0/0"));
+ assertTrue(convertedPerm.getTenantIdGroupNamePairs().size() == 0);
+ assertTrue(convertedPerm.getGroupIds().size() == 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/clojure/org/jclouds/ec2/security_group2.clj
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/clojure/org/jclouds/ec2/security_group2.clj b/apis/ec2/src/main/clojure/org/jclouds/ec2/security_group2.clj
index bc000a2..a6bc49c 100644
--- a/apis/ec2/src/main/clojure/org/jclouds/ec2/security_group2.clj
+++ b/apis/ec2/src/main/clojure/org/jclouds/ec2/security_group2.clj
@@ -21,9 +21,9 @@
org.jclouds.ec2.security-group2
(:require (org.jclouds [compute2 :as compute])
[org.jclouds.ec2.ebs2 :as ebs])
- (:import org.jclouds.ec2.domain.IpProtocol
- org.jclouds.ec2.domain.SecurityGroup
- org.jclouds.ec2.services.SecurityGroupClient))
+ (:import org.jclouds.ec2.domain.SecurityGroup
+ org.jclouds.ec2.services.SecurityGroupClient
+ org.jclouds.net.domain.IpProtocol))
(defn #^SecurityGroupClient
sg-service
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java
index f90e938..403f592 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java
@@ -19,9 +19,9 @@ package org.jclouds.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.util.IpPermissions;
import org.jclouds.http.HttpRequest;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.Binder;
/**
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java
index d9260f9..4bead83 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java
@@ -19,9 +19,9 @@ package org.jclouds.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.util.IpPermissions;
import org.jclouds.http.HttpRequest;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMultimap;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java
index 9e6949c..c62a259 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java
@@ -55,6 +55,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.functions.GroupNamingConvention.Factory;
import org.jclouds.compute.internal.BaseComputeService;
@@ -128,12 +129,13 @@ public class EC2ComputeService extends BaseComputeService {
ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
@Named("SECURITY") LoadingCache<RegionAndName, String> securityGroupMap,
Optional<ImageExtension> imageExtension, GroupNamingConvention.Factory namingConvention,
- @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames) {
+ @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
- persistNodeCredentials, timeouts, userExecutor, imageExtension);
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
this.client = client;
this.credentialsMap = credentialsMap;
this.securityGroupMap = securityGroupMap;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java
index 5e209c9..2a1b495 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java
@@ -31,6 +31,7 @@ import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.ec2.compute.EC2ComputeService;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.loaders.RegionAndIdToImage;
@@ -137,5 +138,9 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
return Optional.of(i.getInstance(ImageExtension.class));
}
+ @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/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
index 06b524f..c93baee 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
@@ -29,18 +29,22 @@ import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.compute.EC2ComputeService;
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.extensions.EC2ImageExtension;
+import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
import org.jclouds.ec2.compute.functions.AddElasticIpsToNodemetadata;
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
import org.jclouds.ec2.compute.functions.EC2ImageParser;
+import org.jclouds.ec2.compute.functions.EC2SecurityGroupToSecurityGroup;
import org.jclouds.ec2.compute.functions.PasswordCredentialsFromWindowsInstance;
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
@@ -129,8 +133,12 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
}).to(PasswordCredentialsFromWindowsInstance.class);
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.Image, Image>>() {
}).to(EC2ImageParser.class);
+ bind(new TypeLiteral<Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup>>() {
+ }).to(EC2SecurityGroupToSecurityGroup.class);
bind(new TypeLiteral<ImageExtension>() {
}).to(EC2ImageExtension.class);
+ bind(new TypeLiteral<SecurityGroupExtension>() {
+ }).to(EC2SecurityGroupExtension.class);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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
new file mode 100644
index 0000000..4b09d56
--- /dev/null
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
@@ -0,0 +1,384 @@
+/*
+ * 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.ec2.compute.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.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.toArray;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.NoSuchElementException;
+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.aws.util.AWSUtils;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.functions.GroupNamingConvention.Factory;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.location.Region;
+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.Supplier;
+import com.google.common.cache.LoadingCache;
+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;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public class EC2SecurityGroupExtension implements SecurityGroupExtension {
+
+ protected final EC2Client client;
+ protected final ListeningExecutorService userExecutor;
+ protected final Supplier<Set<String>> regions;
+ protected final Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter;
+ protected final Supplier<Set<? extends Location>> locations;
+ protected final LoadingCache<RegionAndName, String> groupCreator;
+ protected final Factory namingConvention;
+
+ @Inject
+ public EC2SecurityGroupExtension(EC2Client client,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ @Region Supplier<Set<String>> regions,
+ Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter,
+ @Memoized Supplier<Set<? extends Location>> locations,
+ @Named("SECURITY") LoadingCache<RegionAndName, String> groupCreator,
+ GroupNamingConvention.Factory namingConvention) {
+
+ this.client = checkNotNull(client, "client");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ this.regions = checkNotNull(regions, "regions");
+ this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+ this.locations = checkNotNull(locations, "locations");
+ this.groupCreator = checkNotNull(groupCreator, "groupCreator");
+ this.namingConvention = checkNotNull(namingConvention, "namingConvention");
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroups() {
+ Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = pollSecurityGroups();
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
+ String region = AWSUtils.getRegionFromLocationOrNull(location);
+ if (region == null) {
+ return ImmutableSet.of();
+ }
+ return listSecurityGroupsInLocation(region);
+ }
+
+ public Set<SecurityGroup> listSecurityGroupsInLocation(String region) {
+ Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = pollSecurityGroupsByRegion(region);
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+ checkNotNull(id, "id");
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+
+ RunningInstance instance = getOnlyElement(Iterables.concat(client.getInstanceServices().describeInstancesInRegion(region, instanceId)));
+
+ if (instance == null) {
+ return ImmutableSet.of();
+ }
+
+ Set<String> groupNames = instance.getGroupNames();
+ Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
+ client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, Iterables.toArray(groupNames, String.class));
+
+ return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
+ }
+
+ @Override
+ public SecurityGroup getSecurityGroupById(String id) {
+ checkNotNull(id, "id");
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String groupId = parts[1];
+
+ Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
+ client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupId);
+
+ return getOnlyElement(transform(filter(rawGroups, notNull()), groupConverter));
+ }
+
+ @Override
+ public SecurityGroup createSecurityGroup(String name, Location location) {
+ String region = AWSUtils.getRegionFromLocationOrNull(location);
+ if (region != null) {
+ return createSecurityGroup(name, region);
+ } else {
+ return null;
+ }
+ }
+
+ public SecurityGroup createSecurityGroup(String name, String region) {
+ String markerGroup = namingConvention.create().sharedNameForGroup(name);
+ RegionNameAndIngressRules regionAndName = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
+ false);
+
+ groupCreator.getUnchecked(regionAndName);
+
+ return getSecurityGroupById(regionAndName.slashEncode());
+ }
+
+ @Override
+ public boolean removeSecurityGroup(String id) {
+ checkNotNull(id, "id");
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String groupName = parts[1];
+
+ if (client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupName).size() > 0) {
+ client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName);
+ // TODO: test this clear happens
+ groupCreator.invalidate(new RegionNameAndIngressRules(region, groupName, null, false));
+ return true;
+ }
+
+ return false;
+ }
+
+
+ @Override
+ public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ client.getSecurityGroupServices().
+ authorizeSecurityGroupIngressInRegion(region,
+ name,
+ ipPermission.getIpProtocol(),
+ ipPermission.getFromPort(),
+ ipPermission.getToPort(),
+ cidr);
+ }
+ }
+
+ if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
+ for (String userId : ipPermission.getTenantIdGroupNamePairs().keySet()) {
+ for (String groupName : ipPermission.getTenantIdGroupNamePairs().get(userId)) {
+ client.getSecurityGroupServices().
+ authorizeSecurityGroupIngressInRegion(region,
+ name,
+ new UserIdGroupPair(userId, groupName));
+ }
+ }
+ }
+ System.out.println("group: " + group);
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ client.getSecurityGroupServices().
+ authorizeSecurityGroupIngressInRegion(region,
+ name,
+ protocol,
+ startPort,
+ endPort,
+ cidr);
+ }
+ }
+
+ if (tenantIdGroupNamePairs.size() > 0) {
+ for (String userId : tenantIdGroupNamePairs.keySet()) {
+ for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+ client.getSecurityGroupServices().
+ authorizeSecurityGroupIngressInRegion(region,
+ name,
+ new UserIdGroupPair(userId, groupName));
+ }
+ }
+ }
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ client.getSecurityGroupServices().
+ revokeSecurityGroupIngressInRegion(region,
+ name,
+ ipPermission.getIpProtocol(),
+ ipPermission.getFromPort(),
+ ipPermission.getToPort(),
+ cidr);
+ }
+ }
+
+ if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
+ for (String userId : ipPermission.getTenantIdGroupNamePairs().keySet()) {
+ for (String groupName : ipPermission.getTenantIdGroupNamePairs().get(userId)) {
+ client.getSecurityGroupServices().
+ revokeSecurityGroupIngressInRegion(region,
+ name,
+ new UserIdGroupPair(userId, groupName));
+ }
+ }
+ }
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+ String name = group.getName();
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ client.getSecurityGroupServices().
+ revokeSecurityGroupIngressInRegion(region,
+ name,
+ protocol,
+ startPort,
+ endPort,
+ cidr);
+ }
+ }
+
+ if (tenantIdGroupNamePairs.size() > 0) {
+ for (String userId : tenantIdGroupNamePairs.keySet()) {
+ for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+ client.getSecurityGroupServices().
+ revokeSecurityGroupIngressInRegion(region,
+ name,
+ new UserIdGroupPair(userId, groupName));
+ }
+ }
+ }
+
+ return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupNamePairs() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsGroupIds() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsPortRangesForGroups() {
+ 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());
+
+ return concat(groups);
+ }
+
+
+ protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> pollSecurityGroupsByRegion(String region) {
+ return allSecurityGroupsInRegion().apply(region);
+ }
+
+ protected Function<String, Set<? extends org.jclouds.ec2.domain.SecurityGroup>> allSecurityGroupsInRegion() {
+ return new Function<String, Set<? extends org.jclouds.ec2.domain.SecurityGroup>>() {
+
+ @Override
+ public Set<? extends org.jclouds.ec2.domain.SecurityGroup> apply(String from) {
+ return client.getSecurityGroupServices().describeSecurityGroupsInRegion(from);
+ }
+
+ };
+ }
+
+ protected Location findLocationWithId(final String locationId) {
+ if (locationId == null)
+ return null;
+ try {
+ Location location = Iterables.find(locations.get(), new Predicate<Location>() {
+
+ @Override
+ public boolean apply(Location input) {
+ return input.getId().equals(locationId);
+ }
+
+ });
+ return location;
+
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
new file mode 100644
index 0000000..7e0ff66
--- /dev/null
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
@@ -0,0 +1,95 @@
+/*
+ * 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.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming an EC2-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class EC2SecurityGroupToSecurityGroup implements Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final Supplier<Set<? extends Location>> locations;
+
+ @Inject
+ public EC2SecurityGroupToSecurityGroup(@Memoized Supplier<Set<? extends Location>> locations) {
+ this.locations = checkNotNull(locations, "locations");
+ }
+
+ @Override
+ public SecurityGroup apply(org.jclouds.ec2.domain.SecurityGroup group) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+ Location location = findLocationWithId(group.getRegion());
+ builder.location(location);
+ builder.id(group.getName());
+ builder.providerId(group.getId());
+ builder.name(group.getName());
+ builder.ipPermissions(group);
+ builder.ownerId(group.getOwnerId());
+
+ return builder.build();
+ }
+
+ private Location findLocationWithId(final String locationId) {
+ if (locationId == null)
+ return null;
+ try {
+ Location location = Iterables.find(locations.get(), new Predicate<Location>() {
+
+ @Override
+ public boolean apply(Location input) {
+ return input.getId().equals(locationId);
+ }
+
+ });
+ return location;
+
+ } catch (NoSuchElementException e) {
+ logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
+ return null;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeeded.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeeded.java
index 0d54164..de3b906 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeeded.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeeded.java
@@ -27,10 +27,10 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.ec2.services.SecurityGroupClient;
import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheLoader;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
deleted file mode 100644
index 91c75e7..0000000
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
+++ /dev/null
@@ -1,189 +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.ec2.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Set;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-/**
- *
- * @see <a href=
- * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-IpPermissionType.html"
- * />
- * @author Adrian Cole
- */
-public class IpPermission {
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private int fromPort;
- private int toPort;
- private IpProtocol ipProtocol;
- private Multimap<String, String> userIdGroupPairs = LinkedHashMultimap.create();
- private Set<String> groupIds = Sets.newLinkedHashSet();
- private Set<String> ipRanges = Sets.newLinkedHashSet();
-
- public Builder fromPort(int fromPort) {
- this.fromPort = fromPort;
- return this;
- }
-
- public Builder toPort(int toPort) {
- this.toPort = toPort;
- return this;
- }
-
- public Builder ipProtocol(IpProtocol ipProtocol) {
- this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
- return this;
- }
-
- public Builder userIdGroupPair(String userId, String groupNameOrId) {
- this.userIdGroupPairs.put(checkNotNull(userId, "userId"), checkNotNull(groupNameOrId, "groupNameOrId of %s", userId));
- return this;
- }
-
- public Builder userIdGroupPairs(Multimap<String, String> userIdGroupPairs) {
- this.userIdGroupPairs.putAll(checkNotNull(userIdGroupPairs, "userIdGroupPairs"));
- return this;
- }
-
- public Builder ipRange(String ipRange) {
- this.ipRanges.add(ipRange);
- return this;
- }
-
- public Builder ipRanges(Iterable<String> ipRanges) {
- Iterables.addAll(this.ipRanges, checkNotNull(ipRanges, "ipRanges"));
- return this;
- }
-
- public Builder groupId(String groupId) {
- this.groupIds.add(checkNotNull(groupId, "groupId"));
- return this;
- }
-
- public Builder groupIds(Iterable<String> groupIds) {
- Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
- return this;
- }
-
- public IpPermission build() {
- return new IpPermission(ipProtocol, fromPort, toPort, userIdGroupPairs, groupIds, ipRanges);
- }
- }
-
- private final int fromPort;
- private final int toPort;
- private final Multimap<String, String> userIdGroupPairs;
- private final Set<String> groupIds;
- private final IpProtocol ipProtocol;
- private final Set<String> ipRanges;
-
- public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort, Multimap<String, String> userIdGroupPairs,
- Iterable<String> groupIds, Iterable<String> ipRanges) {
- this.fromPort = fromPort;
- this.toPort = toPort;
- this.userIdGroupPairs = ImmutableMultimap.copyOf(checkNotNull(userIdGroupPairs, "userIdGroupPairs"));
- this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
- this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds"));
- this.ipRanges = ImmutableSet.copyOf(checkNotNull(ipRanges, "ipRanges"));
- }
-
- /**
- * Start of port range for the TCP and UDP protocols, or an ICMP type number.
- * An ICMP type number of -1 indicates a wildcard (i.e., any ICMP type
- * number).
- */
- public int getFromPort() {
- return fromPort;
- }
-
- /**
- * End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP
- * code of -1 indicates a wildcard (i.e., any ICMP code).
- */
- public int getToPort() {
- return toPort;
- }
-
- /**
- * List of security group and user ID pairs.
- */
- public Multimap<String, String> getUserIdGroupPairs() {
- return userIdGroupPairs;
- }
-
- /**
- * List of security group Ids
- */
- public Set<String> getGroupIds() {
- return groupIds;
- }
-
- /**
- * IP protocol
- */
- public IpProtocol getIpProtocol() {
- return ipProtocol;
- }
-
- /**
- * IP ranges.
- */
- public Set<String> getIpRanges() {
- return ipRanges;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(fromPort, toPort, groupIds, ipProtocol, ipRanges, userIdGroupPairs);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null || getClass() != obj.getClass())
- return false;
- IpPermission that = IpPermission.class.cast(obj);
- return Objects.equal(this.fromPort, that.fromPort) && Objects.equal(this.toPort, that.toPort)
- && Objects.equal(this.groupIds, that.groupIds) && Objects.equal(this.ipProtocol, that.ipProtocol)
- && Objects.equal(this.ipRanges, that.ipRanges)
- && Objects.equal(this.userIdGroupPairs, that.userIdGroupPairs);
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this).omitNullValues().add("fromPort", fromPort == -1 ? null : fromPort)
- .add("toPort", toPort == -1 ? null : toPort).add("groupIds", groupIds.size() == 0 ? null : groupIds)
- .add("ipProtocol", ipProtocol).add("ipRanges", ipRanges.size() == 0 ? null : ipRanges)
- .add("userIdGroupPairs", userIdGroupPairs.size() == 0 ? null : userIdGroupPairs).toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpProtocol.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpProtocol.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpProtocol.java
deleted file mode 100644
index 41e771c..0000000
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpProtocol.java
+++ /dev/null
@@ -1,48 +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.ec2.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * @author Adrian Cole
- *
- */
-public enum IpProtocol {
-
- TCP, UDP, ICMP, ALL, UNRECOGNIZED;
-
- public String value() {
- return this == ALL ? "-1" : name().toLowerCase();
- }
-
- @Override
- public String toString() {
- return value();
- }
-
- public static IpProtocol fromValue(String protocol) {
- try {
- if (protocol.equalsIgnoreCase("-1"))
- return ALL;
- return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
- } catch (IllegalArgumentException e) {
- return UNRECOGNIZED;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/domain/SecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/SecurityGroup.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/SecurityGroup.java
index ca5cdbb..caccebc 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/SecurityGroup.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/SecurityGroup.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.net.domain.IpPermission;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupAsyncClient.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupAsyncClient.java
index 4d074ee..0de10f9 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupAsyncClient.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupAsyncClient.java
@@ -30,12 +30,12 @@ import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
import org.jclouds.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.Fallback;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupClient.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupClient.java
index 3874bfb..23c8272 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupClient.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/SecurityGroupClient.java
@@ -17,10 +17,10 @@
package org.jclouds.ec2.services;
import java.util.Set;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.net.domain.IpProtocol;
/**
* Provides access to EC2 via their REST API.
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/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 ac32cda..9c938f0 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
@@ -21,8 +21,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Map.Entry;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.util.Maps2;
import com.google.common.annotations.Beta;
@@ -58,7 +58,7 @@ public class IpPermissions extends IpPermission {
headers.put("IpPermissions.%d.ToPort", permission.getToPort() + "");
String prefix = "IpPermissions.%d.IpRanges.";
int i = 0;
- for (String cidrIp : checkNotNull(permission.getIpRanges(), "cidrIps")) {
+ for (String cidrIp : checkNotNull(permission.getCidrBlocks(), "cidrIps")) {
headers.put(prefix + i++ + ".CidrIp", cidrIp);
}
prefix = "IpPermissions.%d.Groups.";
@@ -68,15 +68,15 @@ public class IpPermissions extends IpPermission {
}
prefix = "IpPermissions.%d.Groups.";
i = 0;
- for (Entry<String, String> userIdGroupNamePair : checkNotNull(permission.getUserIdGroupPairs(),
- "userIdGroupNamePairs").entries()) {
- headers.put(prefix + i + ".UserId", userIdGroupNamePair.getKey());
- headers.put(prefix + i + ".GroupName", userIdGroupNamePair.getValue());
+ for (Entry<String, String> tenantIdGroupNamePair : checkNotNull(permission.getTenantIdGroupNamePairs(),
+ "tenantIdGroupNamePairs").entries()) {
+ headers.put(prefix + i + ".UserId", tenantIdGroupNamePair.getKey());
+ headers.put(prefix + i + ".GroupName", tenantIdGroupNamePair.getValue());
i++;
}
prefix = "IpPermissions.%d.IpRanges.";
i = 0;
- for (String cidrIp : checkNotNull(permission.getIpRanges(), "cidrIps")) {
+ for (String cidrIp : checkNotNull(permission.getCidrBlocks(), "cidrIps")) {
headers.put(prefix + i++ + ".CidrIp", cidrIp);
}
return Multimaps.forMap(Maps2.transformKeys(headers, new Function<String, String>() {
@@ -165,7 +165,7 @@ public class IpPermissions extends IpPermission {
}
public IpPermissions toVPCSecurityGroups(Iterable<String> groupIds) {
- return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), getUserIdGroupPairs(), groupIds,
+ return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), getTenantIdGroupNamePairs(), groupIds,
ImmutableSet.<String> of());
}
}
@@ -189,8 +189,8 @@ public class IpPermissions extends IpPermission {
checkNotNull(groupName, "groupName")));
}
- public IpPermissions toEC2SecurityGroups(Multimap<String, String> userIdGroupNamePairs) {
- return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), userIdGroupNamePairs, getGroupIds(),
+ public IpPermissions toEC2SecurityGroups(Multimap<String, String> tenantIdGroupNamePairs) {
+ return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), tenantIdGroupNamePairs, getGroupIds(),
ImmutableSet.<String> of());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/main/java/org/jclouds/ec2/xml/IpPermissionHandler.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/IpPermissionHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/IpPermissionHandler.java
index 5b4dc6d..980ef35 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/IpPermissionHandler.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/IpPermissionHandler.java
@@ -19,9 +19,9 @@ package org.jclouds.ec2.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
-import org.jclouds.ec2.domain.IpPermission;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.http.functions.ParseSax;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
import org.xml.sax.SAXException;
/**
@@ -66,14 +66,14 @@ public class IpPermissionHandler extends ParseSax.HandlerForGeneratedRequestWith
// EC2)
builder.toPort(Integer.parseInt(currentOrNegative(currentText)));
} else if (equalsOrSuffix(qName, "cidrIp")) {
- builder.ipRange(currentOrNull(currentText));
+ builder.cidrBlock(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "userId")) {
this.userId = currentOrNull(currentText);
} else if (equalsOrSuffix(qName, "groupName") || equalsOrSuffix(qName, "groupId")) {
this.groupId = currentOrNull(currentText);
} else if (equalsOrSuffix(qName, "item")) {
if (userId != null && groupId != null)
- builder.userIdGroupPair(userId, groupId);
+ builder.tenantIdGroupNamePair(userId, groupId);
userId = groupId = null;
}
currentText = new StringBuilder();
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
index 584e6d9..1fc8de9 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
@@ -40,7 +40,6 @@ import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.ec2.domain.Reservation;
@@ -49,6 +48,7 @@ import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.predicates.InstanceHasIpAddress;
import org.jclouds.ec2.predicates.InstanceStateRunning;
import org.jclouds.http.HttpResponseException;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
index 67af652..3b8bd75 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
@@ -42,7 +42,6 @@ import org.jclouds.ec2.domain.Image.Architecture;
import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType;
@@ -58,6 +57,7 @@ import org.jclouds.ec2.predicates.VolumeAttached;
import org.jclouds.ec2.predicates.VolumeAvailable;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payloads;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.scriptbuilder.InitScript;
import org.jclouds.scriptbuilder.domain.OsFamily;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f524ee6/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
index 67db38b..6334c9a 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
@@ -39,7 +39,6 @@ import org.jclouds.ec2.EC2ApiMetadata;
import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDevice;
-import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.ec2.domain.RunningInstance;
@@ -51,6 +50,7 @@ import org.jclouds.ec2.services.ElasticBlockStoreClient;
import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.services.SecurityGroupClient;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.util.InetAddresses2;