diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindSubnetIdsToIndexedFormParams.java b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindSubnetIdsToIndexedFormParams.java new file mode 100644 index 0000000000..f71d8d0053 --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindSubnetIdsToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to query parameters named with SubnetId.index + */ +@Singleton +public class BindSubnetIdsToIndexedFormParams implements Binder { + @Override + public R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "SubnetId", input); + } + +} 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 e84b65ea59..37d7553a53 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 @@ -32,9 +32,6 @@ import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_GENERATE_INSTA import static org.jclouds.ec2.util.Tags.resourceToTagsAsMap; import static org.jclouds.util.Predicates2.retry; -import javax.inject.Named; -import javax.inject.Provider; -import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -42,21 +39,10 @@ import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReference; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableMultimap.Builder; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + import org.jclouds.Constants; import org.jclouds.aws.util.AWSUtils; import org.jclouds.collect.Memoized; @@ -95,10 +81,27 @@ import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.domain.SecurityGroup; import org.jclouds.ec2.domain.Tag; import org.jclouds.ec2.util.TagFilterBuilder; import org.jclouds.scriptbuilder.functions.InitAdminAccess; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; + @Singleton public class EC2ComputeService extends BaseComputeService { private final EC2Api client; @@ -220,10 +223,16 @@ public class EC2ComputeService extends BaseComputeService { checkNotNull(emptyToNull(group), "group must be defined"); String groupName = namingConvention.create().sharedNameForGroup(group); - if (!client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, groupName).isEmpty()) { + Multimap securityGroupFilterByName = ImmutableMultimap.of("group-name", groupName); + Set securityGroupsToDelete = client.getSecurityGroupApi().get() + .describeSecurityGroupsInRegionWithFilter(region, securityGroupFilterByName); + if (securityGroupsToDelete.size() > 1) { + logger.warn("When trying to delete security group %s found more than one matching the name. Will delete all - %s.", + group, securityGroupsToDelete); + } + for (SecurityGroup securityGroup : securityGroupsToDelete) { logger.debug(">> deleting securityGroup(%s)", groupName); - client.getSecurityGroupApi().get().deleteSecurityGroupInRegion(region, groupName); - // TODO: test this clear happens + client.getSecurityGroupApi().get().deleteSecurityGroupInRegionById(region, securityGroup.getId()); securityGroupMap.invalidate(new RegionNameAndIngressRules(region, groupName, null, false, null)); logger.debug("<< deleted securityGroup(%s)", groupName); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java index 640a9671fa..56a7f80964 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java @@ -17,6 +17,7 @@ package org.jclouds.ec2.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableMultimap.of; import javax.inject.Inject; import javax.inject.Singleton; @@ -42,7 +43,7 @@ public class EC2SecurityGroupIdFromName implements Function { String[] parts = AWSUtils.parseHandle(input); String region = parts[0]; String name = parts[1]; - - return Iterables.getOnlyElement(api.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, name), null).getId(); + return Iterables.getOnlyElement(api.getSecurityGroupApi().get() + .describeSecurityGroupsInRegionWithFilter(region, of("group-name", name))).getId(); } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/predicates/SecurityGroupPresent.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/predicates/SecurityGroupPresent.java index 7899478d35..788ce018f3 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/predicates/SecurityGroupPresent.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/predicates/SecurityGroupPresent.java @@ -30,6 +30,7 @@ import org.jclouds.logging.Logger; import org.jclouds.rest.ResourceNotFoundException; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Iterables; import com.google.inject.Inject; @@ -57,8 +58,8 @@ public class SecurityGroupPresent implements Predicate { } } - protected SecurityGroup refresh(RegionAndName securityGroup) { - return Iterables.getOnlyElement(client.getSecurityGroupApi().get().describeSecurityGroupsInRegion( - securityGroup.getRegion(), securityGroup.getName())); + protected SecurityGroup refresh(final RegionAndName securityGroup) { + return Iterables.getOnlyElement(client.getSecurityGroupApi().get().describeSecurityGroupsInRegionWithFilter(securityGroup.getRegion(), + ImmutableMultimap.of("group-name", securityGroup.getName()))); } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java index 28fd4972d5..b44290f02d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java @@ -86,6 +86,39 @@ public interface SecurityGroupApi { @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("GroupName") String name, @FormParam("GroupDescription") String description); + + // Supported by + // * AWS + // * Openstack - https://github.com/openstack/ec2-api/blob/61daf6a80fd6cc9ab800e6b6a2cd3d1d827e2527/ec2api/api/security_group.py#L130 + // * Eucalyptus - https://docs.eucalyptus.com/eucalyptus/4.4.0/#euca2ools-guide/euca-delete-group.html + // https://github.com/eucalyptus/euca2ools/blob/096d97ef2729da976759657d6d6f645a6e959e05/euca2ools/commands/ec2/deletesecuritygroup.py#L37 + /** + * Deletes a security group by ID. + * + * @param region + * Security groups are not copied across Regions. Instances within the Region cannot + * communicate with instances outside the Region using group-based firewall rules. + * Traffic from instances in another Region is seen as WAN bandwidth. + * @param id + * ID of the security group to delete. + * + * @see #describeSecurityGroups + * @see #authorizeSecurityGroupIngress + * @see #revokeSecurityGroupIngress + * @see #createSecurityGroup + * + * @see + */ + @Named("DeleteSecurityGroup") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteSecurityGroup") + @Fallback(VoidOnNotFoundOr404.class) + void deleteSecurityGroupInRegionById( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("GroupId") String id); + /** * Deletes a security group that you own. * @@ -114,6 +147,7 @@ public interface SecurityGroupApi { /** * Returns information about security groups that you own. + *

NOTE Works with groups in default VPC only

* * @param region * Security groups are not copied across Regions. Instances within the Region cannot diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeSubnetsResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeSubnetsResponseHandler.java index 1f25d4b9a7..dbcc968530 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeSubnetsResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeSubnetsResponseHandler.java @@ -37,6 +37,7 @@ public class DescribeSubnetsResponseHandler extends private StringBuilder currentText = new StringBuilder(); private boolean inSubnetSet; private boolean inTagSet; + private boolean inIpv6CidrBlockAssociationSet; private Builder subnets = ImmutableSet. builder(); @Inject @@ -56,6 +57,8 @@ public class DescribeSubnetsResponseHandler extends } else if (inSubnetSet) { if (equalsOrSuffix(qName, "tagSet")) { inTagSet = true; + } else if (equalsOrSuffix(qName, "ipv6CidrBlockAssociationSet")) { + inIpv6CidrBlockAssociationSet = true; } subnetHandler.startElement(url, name, qName, attributes); } @@ -68,7 +71,10 @@ public class DescribeSubnetsResponseHandler extends } else if (equalsOrSuffix(qName, "tagSet")) { inTagSet = false; subnetHandler.endElement(uri, name, qName); - } else if (equalsOrSuffix(qName, "item") && !inTagSet) { + } else if (equalsOrSuffix(qName, "ipv6CidrBlockAssociationSet")) { + inIpv6CidrBlockAssociationSet = false; + subnetHandler.endElement(uri, name, qName); + } else if (equalsOrSuffix(qName, "item") && !inTagSet && !inIpv6CidrBlockAssociationSet) { subnets.add(subnetHandler.getResult()); } else if (inSubnetSet) { subnetHandler.endElement(uri, name, qName); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/SubnetHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/SubnetHandler.java index e0554251a7..1dd21e188b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/SubnetHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/SubnetHandler.java @@ -33,6 +33,7 @@ public class SubnetHandler extends ParseSax.HandlerForGeneratedRequestWithResult private Subnet.Builder builder = Subnet.builder(); private final TagSetHandler tagSetHandler; private boolean inTagSet; + private boolean inIpv6CidrBlockAssociationSet; @Inject public SubnetHandler(TagSetHandler tagSetHandler) { @@ -52,6 +53,8 @@ public class SubnetHandler extends ParseSax.HandlerForGeneratedRequestWithResult public void startElement(String uri, String name, String qName, Attributes attrs) { if (equalsOrSuffix(qName, "tagSet")) { inTagSet = true; + } else if (equalsOrSuffix(qName, "ipv6CidrBlockAssociationSet")) { + inIpv6CidrBlockAssociationSet = true; } if (inTagSet) { tagSetHandler.startElement(uri, name, qName, attrs); @@ -60,6 +63,13 @@ public class SubnetHandler extends ParseSax.HandlerForGeneratedRequestWithResult @Override public void endElement(String uri, String name, String qName) { + if (equalsOrSuffix(qName, "ipv6CidrBlockAssociationSet")) { + inIpv6CidrBlockAssociationSet = false; + } + if (inIpv6CidrBlockAssociationSet) { + return; // ignore contents (otherwise "item" and "state" will confuse us! + } + if (equalsOrSuffix(qName, "tagSet")) { inTagSet = false; builder.tags(tagSetHandler.getResult()); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java index 4ffad1f1b1..6de7d27bba 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java @@ -118,6 +118,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeImagesRequest, describeImagesResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupFilteredRequest, describeSecurityGroupFilteredResponse); requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); @@ -144,6 +145,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeImagesRequest, describeImagesResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupFilteredRequest, describeSecurityGroupFilteredResponse); requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); @@ -171,6 +173,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeImagesRequest, describeImagesResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupFilteredRequest, describeSecurityGroupFilteredResponse); requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); @@ -263,6 +266,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeImagesRequest, describeImagesResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupFilteredRequest, describeSecurityGroupFilteredResponse); requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); @@ -298,6 +302,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeImagesRequest, describeImagesResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); + requestResponseMap.put(describeSecurityGroupFilteredRequest, describeSecurityGroupFilteredResponse); requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2ImageExtensionExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2ImageExtensionExpectTest.java index 4ca6c627e2..11c968a339 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2ImageExtensionExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/extensions/EC2ImageExtensionExpectTest.java @@ -40,11 +40,6 @@ public class EC2ImageExtensionExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeRegionsRequest, describeRegionsResponse); requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse); requestResponseMap.put(describeImagesRequest, describeImagesResponse); - requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); - requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse); - requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); - requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); - requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); requestResponseMap.put(describeInstanceRequest, describeInstanceResponse); HttpRequest createImageRequest = formSigner.filter(HttpRequest.builder().method("POST") 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 index 5bb73bb32a..733edbf9fe 100644 --- 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 @@ -49,6 +49,12 @@ import com.google.common.collect.Sets; @Test(groups = "unit", testName = "EC2SecurityGroupExtensionExpectTest") public class EC2SecurityGroupExtensionExpectTest extends BaseEC2ComputeServiceExpectTest { + public EC2SecurityGroupExtensionExpectTest() { + // Don't use the default (us-east-1) region. Better to ensure we always pass through the + // desired region, rather than it falling back to the default! + region = "eu-west-1"; + } + public void testListSecurityGroups() { HttpRequest describeSecurityGroupsAllRequest = formSigner.filter(HttpRequest.builder() @@ -209,10 +215,24 @@ public class EC2SecurityGroupExtensionExpectTest extends BaseEC2ComputeServiceEx .payload(payloadFromResourceWithContentType( "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build(); + HttpRequest describeSecurityGroupsSingleFilteredRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeSecurityGroups") + .addFormParam("Filter.1.Name", "group-name") + .addFormParam("Filter.1.Value.1", "jclouds#some-group").build()); + + HttpResponse describeSecurityGroupsSingleFilteredResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build(); Builder requestResponseMap = ImmutableMap. builder(); requestResponseMap.put(describeRegionsRequest, describeRegionsResponse); requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse); + requestResponseMap.put(describeSecurityGroupsSingleFilteredRequest, describeSecurityGroupsSingleFilteredResponse); requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse); requestResponseMap.put(createKeyPairRequest, createKeyPairResponse); requestResponseMap.put(createSecurityGroupExtRequest, createSecurityGroupResponse); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java index 4178e74e4e..eb7e397ec2 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceExpectTest.java @@ -46,6 +46,8 @@ public abstract class BaseEC2ComputeServiceExpectTest extends BaseEC2ComputeServ protected HttpResponse createKeyPairResponse; protected HttpRequest createSecurityGroupRequest; protected HttpResponse createSecurityGroupResponse; + protected HttpRequest describeSecurityGroupFilteredRequest; + protected HttpResponse describeSecurityGroupFilteredResponse; protected HttpRequest describeSecurityGroupRequest; protected HttpResponse describeSecurityGroupResponse; protected HttpRequest authorizeSecurityGroupIngressRequest22; @@ -124,6 +126,20 @@ public abstract class BaseEC2ComputeServiceExpectTest extends BaseEC2ComputeServ .payload(payloadFromResourceWithContentType( "/created_securitygroup.xml", MediaType.APPLICATION_XML)).build(); + describeSecurityGroupFilteredRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2." + region + ".amazonaws.com/") + .addHeader("Host", "ec2." + region + ".amazonaws.com") + .addFormParam("Action", "DescribeSecurityGroups") + .addFormParam("Filter.1.Name", "group-name") + .addFormParam("Filter.1.Value.1", "jclouds#test").build()); + + describeSecurityGroupFilteredResponse = + HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType( + "/new_securitygroup.xml", MediaType.APPLICATION_XML)).build(); + describeSecurityGroupRequest = formSigner.filter(HttpRequest.builder() .method("POST") diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiExpectTest.java index 811711a421..0e5d593111 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiExpectTest.java @@ -45,6 +45,30 @@ public class SecurityGroupApiExpectTest extends BaseEC2ApiExpectTest { .addFormParam("Version", "2010-08-31") .addFormParam("AWSAccessKeyId", "identity").build(); + HttpRequest deleteById = HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DeleteSecurityGroup") + .addFormParam("GroupId", "sg-3c6ef654") + .addFormParam("Signature", "FhFx9Uv587s+86KuCOngA2x3DiLRuRrkyd0ZTrXAYbc=") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2012-04-16T15:54:08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + + HttpRequest deleteByName = HttpRequest.builder().method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .addFormParam("Action", "DeleteSecurityGroup") + .addFormParam("GroupName", "jclouds#some-group") + .addFormParam("Signature", "Jw9ZpWcnAEPaNtZNZBsMyOUUFP1qGETKUzvHiAOz5C8=") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2012-04-16T15:54:08.897Z") + .addFormParam("Version", "2010-08-31") + .addFormParam("AWSAccessKeyId", "identity").build(); + public void testFilterWhenResponseIs2xx() { HttpResponse filterResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResourceWithContentType("/describe_securitygroups_extension_single.xml", "text/xml")).build(); @@ -70,4 +94,46 @@ public class SecurityGroupApiExpectTest extends BaseEC2ApiExpectTest { .build()), ImmutableSet.of()); } + + public void testDeleteSecurityGroupById() { + HttpResponse deleteResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/delete_securitygroup.xml", "text/xml")).build(); + + EC2Api apiWhenNotExist = requestsSendResponses( + describeRegionsRequest, describeRegionsResponse, + deleteById, deleteResponse); + + apiWhenNotExist.getSecurityGroupApi().get().deleteSecurityGroupInRegionById("us-east-1", "sg-3c6ef654"); + } + + public void testDeleteSecurityGroupByIdWhen404() { + HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build(); + + EC2Api apiWhenNotExist = requestsSendResponses( + describeRegionsRequest, describeRegionsResponse, + deleteById, deleteResponse); + + apiWhenNotExist.getSecurityGroupApi().get().deleteSecurityGroupInRegionById("us-east-1", "sg-3c6ef654"); + } + + public void testDeleteSecurityGroupByName() { + HttpResponse deleteResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/delete_securitygroup.xml", "text/xml")).build(); + + EC2Api apiWhenNotExist = requestsSendResponses( + describeRegionsRequest, describeRegionsResponse, + deleteByName, deleteResponse); + + apiWhenNotExist.getSecurityGroupApi().get().deleteSecurityGroupInRegion("us-east-1", "jclouds#some-group"); + } + + public void testDeleteSecurityGroupByNameWhen404() { + HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build(); + + EC2Api apiWhenNotExist = requestsSendResponses( + describeRegionsRequest, describeRegionsResponse, + deleteByName, deleteResponse); + + apiWhenNotExist.getSecurityGroupApi().get().deleteSecurityGroupInRegion("us-east-1", "jclouds#some-group"); + } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiLiveTest.java index d2c1238cf0..c37e7e7d8b 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/features/SecurityGroupApiLiveTest.java @@ -52,7 +52,7 @@ public class SecurityGroupApiLiveTest extends BaseComputeServiceContextLiveTest provider = "ec2"; } - private EC2Api ec2Api; + protected EC2Api ec2Api; protected SecurityGroupApi client; @Override diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java index 37ca0e971b..851597f52c 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java @@ -20,6 +20,7 @@ import org.jclouds.aws.ec2.features.AWSAMIApi; import org.jclouds.aws.ec2.features.AWSInstanceApi; import org.jclouds.aws.ec2.features.AWSKeyPairApi; import org.jclouds.aws.ec2.features.AWSSecurityGroupApi; +import org.jclouds.aws.ec2.features.AWSSubnetApi; import org.jclouds.aws.ec2.features.MonitoringApi; import org.jclouds.aws.ec2.features.PlacementGroupApi; import org.jclouds.aws.ec2.features.SpotInstanceApi; @@ -47,7 +48,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate @Override Optional getInstanceApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * {@inheritDoc} @@ -59,7 +60,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate @Override Optional getSecurityGroupApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * {@inheritDoc} @@ -71,7 +72,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate @Override Optional getAMIApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** @@ -82,7 +83,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate Optional getPlacementGroupApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * Provides synchronous access to Monitoring services. @@ -92,7 +93,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate Optional getMonitoringApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * {@inheritDoc} @@ -104,7 +105,7 @@ public interface AWSEC2Api extends EC2Api { @Delegate @Override Optional getKeyPairApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * Provides synchronous access to SpotInstance services. @@ -114,11 +115,21 @@ public interface AWSEC2Api extends EC2Api { @Delegate Optional getSpotInstanceApiForRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); /** * Provides synchronous access to VPC services. */ @Delegate Optional getVPCApi(); + + /** + * Provides access to Subnet services. + */ + @Delegate + Optional getAWSSubnetApi(); + + @Delegate + Optional getAWSSubnetApiForRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); } 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 9e17354e2f..1b2b0337a4 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 @@ -33,6 +33,7 @@ import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions; 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.SecurityGroup; import org.jclouds.logging.Logger; import org.jclouds.net.domain.IpPermission; import org.jclouds.net.domain.IpProtocol; @@ -73,7 +74,7 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader> creating securityGroup region(%s) name(%s)", region, name); @@ -102,7 +103,16 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader securityGroups = securityApi.describeSecurityGroupsInRegionById(region, id); + if (securityGroups.isEmpty()) { + throw new IllegalStateException(String.format("security group %s/%s not found after creating", region, name)); + } else if (securityGroups.size() > 1) { + throw new IllegalStateException(String.format("multiple security groups matching %s/%s found after creating: %s", + region, name, securityGroups)); + } + SecurityGroup securityGroup = Iterables.getOnlyElement(securityGroups); + String myOwnerId = securityGroup.getOwnerId(); permissions.add(IpPermission.builder() .fromPort(0) .toPort(65535) diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java index 782e376ce0..694e1dbb04 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -43,14 +43,15 @@ import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAn import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.Subnet; import org.jclouds.ec2.options.RunInstancesOptions; -import org.jclouds.ec2.util.SubnetFilterBuilder; import org.jclouds.logging.Logger; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.cache.LoadingCache; +import com.google.common.collect.Iterables; @Singleton public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions extends @@ -192,7 +193,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions awsInstanceOptions.withSecurityGroupIds(awsTemplateOptions.getGroupIds()); String subnetId = awsTemplateOptions.getSubnetId(); if (subnetId != null) { - Set groups = getSecurityGroupsForTagAndOptions(region, group, vpcIdForSubnet(subnetId), template.getOptions()); + Set groups = getSecurityGroupsForTagAndOptions(region, group, vpcIdForSubnet(region, subnetId), template.getOptions()); awsInstanceOptions.withSubnetId(subnetId); awsInstanceOptions.withSecurityGroupIds(groups); } else { @@ -202,8 +203,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions } @VisibleForTesting - String vpcIdForSubnet(String subnetId) { - Optional subnet = awsEC2Api.getSubnetApi().get().filter(new SubnetFilterBuilder().subnetId(subnetId).build()).first(); + String vpcIdForSubnet(String region, String subnetId) { + Optional subnet = Iterables.tryFind(awsEC2Api.getAWSSubnetApi().get().describeSubnetsInRegion(region, subnetId), Predicates.notNull()); if (!subnet.isPresent()) { throw new IllegalArgumentException("Subnet " + subnetId + " not found"); } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java index f4e06f6cec..ef998e809f 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java @@ -133,6 +133,15 @@ public interface AWSSecurityGroupApi extends SecurityGroupApi { @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindGroupNamesToIndexedFormParams.class) String... securityGroupNames); + @Named("DescribeSecurityGroups") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeSecurityGroups") + @XMLResponseParser(AWSEC2DescribeSecurityGroupsResponseHandler.class) + @Fallback(EmptySetOnNotFoundOr404.class) + Set describeSecurityGroupsInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + @Named("DescribeSecurityGroups") @POST @Path("/") diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSubnetApi.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSubnetApi.java new file mode 100644 index 0000000000..ccafebeadd --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/AWSSubnetApi.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.aws.ec2.features; + +import static org.jclouds.aws.reference.FormParameters.ACTION; + +import javax.inject.Named; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.Fallbacks; +import org.jclouds.aws.ec2.options.CreateSubnetOptions; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams; +import org.jclouds.ec2.binders.BindSubnetIdsToIndexedFormParams; +import org.jclouds.ec2.domain.Subnet; +import org.jclouds.ec2.features.SubnetApi; +import org.jclouds.ec2.xml.DescribeSubnetsResponseHandler; +import org.jclouds.ec2.xml.SubnetHandler; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SinceApiVersion; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +import com.google.common.collect.FluentIterable; +import com.google.common.collect.Multimap; + +/** + * Provides access to Amazon EC2 via the Query API + *

+ * + * @see doc + */ +@SinceApiVersion("2011-01-01") +@RequestFilters(FormSigner.class) +@VirtualHost +public interface AWSSubnetApi extends SubnetApi { + + /** + * Creates a subnet in an existing VPC. + * + * @param region + * @param vpcId The ID of the VPC. + * @param cidrBlock The network range for the subnet, in CIDR notation. For example, 10.0.0.0/24. + * @param options + * @return AWS Subnet + */ + @Named("CreateSubnet") + @POST + @Path("/") + @XMLResponseParser(SubnetHandler.class) + @FormParams(keys = ACTION, values = "CreateSubnet") + Subnet createSubnetInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("VpcId") String vpcId, @FormParam("CidrBlock") String cidrBlock, + CreateSubnetOptions... options); + + /** + * Deletes a subnet. + * + * @param region + * @param subnetId + * @see doc + */ + @Named("DeleteSubnet") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteSubnet") + void deleteSubnetInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("SubnetId") String subnetId); + + /** + * Describes one or more of your subnets. + * + * @param region Subnet are Region-specific. + * @param subnetIds Subnet to describe. + * @see doc + */ + @Named("DescribeSubnets") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeSubnets") + @XMLResponseParser(DescribeSubnetsResponseHandler.class) + @Fallback(Fallbacks.EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable describeSubnetsInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindSubnetIdsToIndexedFormParams.class) String... subnetIds); + + /** + * Returns information about subnets available to you. If you specify filters, + * information about subnets matching those filters is returned. Otherwise, all + * subnets you have access to are returned. + * + * @param region Subnets are Region-specific. + * @param filter Multimap of filter key/values. + * @see doc + */ + @Named("DescribeSubnets") + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeSubnets") + @XMLResponseParser(DescribeSubnetsResponseHandler.class) + @Fallback(Fallbacks.EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable describeSubnetsInRegionWithFilter( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindFiltersToIndexedFormParams.class) Multimap filter); +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/CreateSecurityGroupOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/CreateSecurityGroupOptions.java index 8e1ec948a6..604a8c0a9b 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/CreateSecurityGroupOptions.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/CreateSecurityGroupOptions.java @@ -31,7 +31,7 @@ import org.jclouds.ec2.options.internal.BaseEC2RequestOptions; * import static org.jclouds.aws.ec2.options.CreateSecurityGroupOptions.Builder.* *

* AWSEC2Api connection = // get connection - * group = connection.getAMIServices().createSecurityGroup(vpcId("123125").noReboot()); + * group = connection.getAMIServices().createSecurityGroup(vpcId("123125")); * * * @see + * Usage The recommended way to instantiate a CreateSubnetOptions + * object is to statically import CreateSubnetOptions.Builder.* and + * invoke a static creation method followed by an instance mutator (if needed): + *

+ * + * import static org.jclouds.aws.ec2.options.CreateSubnetOptions.Builder.* + *

+ * AWSEC2Api connection = // get connection + * String vpcId = "vpc-1a2b3c4d"; + * String cidrBlock = "10.0.1.0/24"; + * group = connection.getAWSSubnetApi().createSubnetInRegion(vpcId, cirdBlock, availabilityZone("us-east-1a")); + * + * + * @see + */ +public class CreateSubnetOptions extends BaseEC2RequestOptions { + + /** + * The Availability Zone for the subnet. + */ + public CreateSubnetOptions availabilityZone(String availabilityZone) { + formParameters.put("AvailabilityZone", checkNotNull(availabilityZone, "availabilityZone")); + return this; + } + + public String getAvailabilityZone() { + return getFirstFormOrNull("AvailabilityZone"); + } + + public CreateSubnetOptions dryRun() { + formParameters.put("DryRun", "true"); + return this; + } + + public boolean isDryRun() { + return Boolean.parseBoolean(getFirstFormOrNull("DryRun")); + } + + public static class Builder { + + /** + * @see CreateSubnetOptions#availabilityZone(String ) + */ + public static CreateSubnetOptions availabilityZone(String availabilityZone) { + CreateSubnetOptions options = new CreateSubnetOptions(); + return options.availabilityZone(availabilityZone); + } + + /** + * @see CreateSubnetOptions#dryRun() + */ + public static CreateSubnetOptions dryRun() { + CreateSubnetOptions options = new CreateSubnetOptions(); + return options.dryRun(); + } + + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceApiMockTest.java index 09f1d10177..cc8121952e 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceApiMockTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceApiMockTest.java @@ -76,10 +76,10 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeAvailabilityZones"); assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&Filter.1.Value.2=801119661308&Filter.1.Value.3=063491364108&Filter.1.Value.4=099720109477&Filter.1.Value.5=411009282317&Filter.2.Name=state&Filter.2.Value.1=available&Filter.3.Name=image-type&Filter.3.Value.1=machine"); assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); - assertPosted(DEFAULT_REGION, "Action=DescribeSubnets&Filter.1.Name=subnet-id&Filter.1.Value.1=subnet-9d4a7b6c"); + assertPosted(DEFAULT_REGION, "Action=DescribeSubnets&SubnetId.1=subnet-9d4a7b6c"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test&VpcId=vpc-1a2b3c4d"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RequestSpotInstances&SpotPrice=1.0&InstanceCount=1&LaunchSpecification.ImageId=ami-" + getDefaultImageId() + "&LaunchSpecification.Placement.AvailabilityZone=us-east-1a&LaunchSpecification.SecurityGroupId.1=sg-3c6ef654&LaunchSpecification.InstanceType=" + getDefaultSmallestInstanceType() + "&LaunchSpecification.SubnetId=subnet-9d4a7b6c&LaunchSpecification.KeyName=Demo&LaunchSpecification.UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK"); assertPosted(DEFAULT_REGION, "Action=DescribeSpotInstanceRequests&SpotInstanceRequestId.1=sir-228e6406"); @@ -118,8 +118,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&Filter.1.Value.2=801119661308&Filter.1.Value.3=063491364108&Filter.1.Value.4=099720109477&Filter.1.Value.5=411009282317&Filter.2.Name=state&Filter.2.Value.1=available&Filter.3.Name=image-type&Filter.3.Value.1=machine"); assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RequestSpotInstances&SpotPrice=1.0&InstanceCount=1&LaunchSpecification.ImageId=ami-" + getDefaultImageId() + "&LaunchSpecification.Placement.AvailabilityZone=us-east-1a&LaunchSpecification.SecurityGroupId.1=sg-3c6ef654&LaunchSpecification.InstanceType=" + getDefaultSmallestInstanceType() + "&LaunchSpecification.UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK&LaunchSpecification.IamInstanceProfile.Arn=arn%3Aaws%3Aiam%3A%3A123456789012%3Ainstance-profile/application_abc/component_xyz/Webserver"); assertPosted(DEFAULT_REGION, "Action=DescribeSpotInstanceRequests&SpotInstanceRequestId.1=sir-228e6406"); @@ -156,8 +156,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&Filter.1.Value.2=801119661308&Filter.1.Value.3=063491364108&Filter.1.Value.4=099720109477&Filter.1.Value.5=411009282317&Filter.2.Name=state&Filter.2.Value.1=available&Filter.3.Name=image-type&Filter.3.Value.1=machine"); assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RequestSpotInstances&SpotPrice=1.0&InstanceCount=1&LaunchSpecification.ImageId=ami-" + getDefaultImageId() + "&LaunchSpecification.Placement.AvailabilityZone=us-east-1a&LaunchSpecification.SecurityGroupId.1=sg-3c6ef654&LaunchSpecification.InstanceType=" + getDefaultSmallestInstanceType() + "&LaunchSpecification.UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK&LaunchSpecification.IamInstanceProfile.Name=Webserver"); assertPosted(DEFAULT_REGION, "Action=DescribeSpotInstanceRequests&SpotInstanceRequestId.1=sir-228e6406"); @@ -190,8 +190,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); assertPosted(DEFAULT_REGION, "Action=DescribeAvailabilityZones"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RunInstances&ImageId=ami-8ce4b5c9&MinCount=1&MaxCount=1&InstanceType=" + getDefaultParavirtualInstanceType() + "&SecurityGroupId.1=sg-3c6ef654&UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK&IamInstanceProfile.Arn=arn%3Aaws%3Aiam%3A%3A123456789012%3Ainstance-profile/application_abc/component_xyz/Webserver"); assertPosted(DEFAULT_REGION, "Action=DescribeInstances&InstanceId.1=i-2baa5550"); @@ -224,8 +224,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); assertPosted(DEFAULT_REGION, "Action=DescribeAvailabilityZones"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RunInstances&ImageId=ami-8ce4b5c9&MinCount=1&MaxCount=1&InstanceType=" + getDefaultParavirtualInstanceType() + "&SecurityGroupId.1=sg-3c6ef654&UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK&IamInstanceProfile.Name=Webserver"); assertPosted(DEFAULT_REGION, "Action=DescribeInstances&InstanceId.1=i-2baa5550"); @@ -258,8 +258,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { assertPosted(DEFAULT_REGION, "Action=DescribeImages&Filter.1.Name=virtualization-type&Filter.1.Value.1=hvm&Filter.2.Name=architecture&Filter.2.Value.1=x86_64&Filter.3.Name=owner-id&Filter.3.Value.1=137112412989&Filter.3.Value.2=099720109477&Filter.4.Name=hypervisor&Filter.4.Value.1=xen&Filter.5.Name=state&Filter.5.Value.1=available&Filter.6.Name=image-type&Filter.6.Value.1=machine&Filter.7.Name=root-device-type&Filter.7.Value.1=ebs"); assertPosted(DEFAULT_REGION, "Action=DescribeAvailabilityZones"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23test&GroupDescription=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23test"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-3c6ef654&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=22&IpPermissions.0.ToPort=22&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=0&IpPermissions.1.ToPort=65535&IpPermissions.1.Groups.0.UserId=993194456877&IpPermissions.1.Groups.0.GroupId=sg-3c6ef654&IpPermissions.2.IpProtocol=udp&IpPermissions.2.FromPort=0&IpPermissions.2.ToPort=65535&IpPermissions.2.Groups.0.UserId=993194456877&IpPermissions.2.Groups.0.GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=RunInstances&ImageId=ami-8ce4b5c9&MinCount=1&MaxCount=1&InstanceType=" + getDefaultParavirtualInstanceType() + "&SecurityGroupId.1=sg-3c6ef654&UserData=I2Nsb3VkLWNvbmZpZwpyZXBvX3VwZ3JhZGU6IG5vbmUK&Placement.Tenancy=host&Placement.HostId=TestHostId"); assertPosted(DEFAULT_REGION, "Action=DescribeInstances&InstanceId.1=i-2baa5550"); @@ -302,8 +302,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { computeService.cleanUpIncidentalResources(DEFAULT_REGION, "sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23sg-3c6ef654"); - assertPosted(DEFAULT_REGION, "Action=DeleteSecurityGroup&GroupName=jclouds%23sg-3c6ef654"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23sg-3c6ef654"); + assertPosted(DEFAULT_REGION, "Action=DeleteSecurityGroup&GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DescribeKeyPairs&Filter.1.Name=key-name&Filter.1.Value.1=jclouds%23sg-3c6ef654%23%2A"); assertPosted(DEFAULT_REGION, "Action=DescribeInstances&Filter.1.Name=instance-state-name&Filter.1.Value.1=terminated&Filter.1.Value.2=shutting-down&Filter.2.Name=key-name&Filter.2.Value.1=jclouds%23sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DeleteKeyPair&KeyName=jclouds%23sg-3c6ef654"); @@ -336,8 +336,8 @@ public class AWSEC2ComputeServiceApiMockTest extends BaseAWSEC2ApiMockTest { computeService.cleanUpIncidentalResources(DEFAULT_REGION, "sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23sg-3c6ef654"); - assertPosted(DEFAULT_REGION, "Action=DeleteSecurityGroup&GroupName=jclouds%23sg-3c6ef654"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23sg-3c6ef654"); + assertPosted(DEFAULT_REGION, "Action=DeleteSecurityGroup&GroupId=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DescribePlacementGroups&GroupName.1=jclouds%23sg-3c6ef654%23us-east-1"); assertPosted(DEFAULT_REGION, "Action=DeletePlacementGroup&GroupName=jclouds%23sg-3c6ef654%23us-east-1"); assertPosted(DEFAULT_REGION, "Action=DescribePlacementGroups&GroupName.1=jclouds%23sg-3c6ef654%23us-east-1"); diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionApiMockTest.java index 24c91e2ed3..d5f022017f 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionApiMockTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/extensions/AWSEC2SecurityGroupExtensionApiMockTest.java @@ -153,8 +153,8 @@ public class AWSEC2SecurityGroupExtensionApiMockTest extends BaseAWSEC2ApiMockTe assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=jclouds%23some-group&GroupDescription=jclouds%23some-group"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23some-group"); - assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=jclouds%23some-group"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23some-group"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=jclouds%23some-group"); assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-3c6ef654"); assertPosted(DEFAULT_REGION, "Action=DescribeAvailabilityZones"); } 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 bf87309dbb..1880a238b8 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 @@ -82,7 +82,8 @@ public class AWSEC2CreateSecurityGroupIfNeededTest { new CreateSecurityGroupOptions().vpcId("vpc"))).andReturn("sg-123456"); expect(group.getOwnerId()).andReturn("ownerId"); client.authorizeSecurityGroupIngressInRegion("region", "sg-123456", permissions.build()); - expect(client.describeSecurityGroupsInRegion("region", "group")).andReturn(Set.class.cast(groups)); + expect(client.describeSecurityGroupsInRegionById("region", "sg-123456")) + .andReturn(Set.class.cast(groups)); replay(client); diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index f73ebc1cd0..3c738a6926 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -308,7 +308,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT expect(options.getSubnetId()).andReturn("1"); expect(options.getUserData()).andReturn(null); expect(options.isMonitoringEnabled()).andReturn(false); - expect(strategy.vpcIdForSubnet("1")).andReturn("vpc1"); + expect(strategy.vpcIdForSubnet("", "1")).andReturn("vpc1"); // replay mocks replay(options); diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiLiveTest.java index 9100a5be8b..dcc2b89cf6 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiLiveTest.java @@ -19,18 +19,26 @@ package org.jclouds.aws.ec2.features; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import java.util.Random; import java.util.Set; +import org.jclouds.aws.ec2.AWSEC2Api; +import org.jclouds.aws.ec2.domain.VPC; +import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions; +import org.jclouds.aws.ec2.options.CreateVpcOptions; +import org.jclouds.ec2.EC2Api; import org.jclouds.ec2.domain.SecurityGroup; import org.jclouds.ec2.domain.UserIdGroupPair; import org.jclouds.ec2.features.SecurityGroupApiLiveTest; import org.jclouds.ec2.util.IpPermissions; import org.jclouds.net.domain.IpPermission; import org.jclouds.net.domain.IpProtocol; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Iterables; @Test(groups = "live", singleThreaded = true) public class AWSSecurityGroupApiLiveTest extends SecurityGroupApiLiveTest { @@ -116,4 +124,40 @@ public class AWSSecurityGroupApiLiveTest extends SecurityGroupApiLiveTest { client.deleteSecurityGroupInRegion(null, group1Name); } } + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setupContext() { + super.setupContext(); + ec2Api = view.unwrapApi(EC2Api.class); + client = ec2Api.getSecurityGroupApi().get(); + } + + @Test + void testCreateSecurityGroupInVpc() { + String region = "us-west-2"; + String groupName = PREFIX + "1" + new Random().nextInt(10000); + String description = "jclouds testCreateSecurityGroupInVpc"; + + VPCApi vpcClient = AWSEC2Api.class.cast(ec2Api).getVPCApi().get(); + AWSSecurityGroupApi sgClient = AWSSecurityGroupApi.class.cast(client); + + VPC vpc = vpcClient.createVpc(region, "10.0.0.0/16", CreateVpcOptions.NONE); + try { + String sgId = sgClient.createSecurityGroupInRegionAndReturnId( + region, groupName, description, CreateSecurityGroupOptions.Builder.vpcId(vpc.id())); + + try { + Set securityGroups = sgClient.describeSecurityGroupsInRegionWithFilter( + region, ImmutableMultimap.of("vpc-id", vpc.id(), "group-id", sgId)); + SecurityGroup sg = Iterables.getOnlyElement(securityGroups); + assertEquals(sg.getId(), sgId); + assertEquals(sg.getId(), sgId); + } finally { + sgClient.deleteSecurityGroupInRegionById(region, sgId); + } + } finally { + vpcClient.deleteVpc(region, vpc.id()); + } + } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiMockTest.java new file mode 100644 index 0000000000..4d6b3822e2 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApiMockTest.java @@ -0,0 +1,270 @@ +/* + * 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.features; + +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest; +import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions; +import org.jclouds.ec2.domain.SecurityGroup; +import org.jclouds.net.domain.IpPermission; +import org.jclouds.net.domain.IpProtocol; +import org.testng.annotations.Test; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.squareup.okhttp.mockwebserver.MockResponse; + +@Test(groups = "unit", testName = "AWSSecurityGroupApiMockTest", singleThreaded = true) +public class AWSSecurityGroupApiMockTest extends BaseAWSEC2ApiMockTest { + + private final String describeSecurityGroupsResponse = Joiner.on("\n").join( + "", + " 59dbff89-35bd-4eac-99ed-be587EXAMPLE", + " ", + " ", + " 123456789012", + " sg-1a2b3c4d", + " WebServers", + " Web Servers", + " vpc-614cc409", + " ", + " ", + " -1", + " ", + " ", + " 123456789012", + " sg-af8661c0", + " ", + " ", + " ", + " ", + " ", + " ", + " tcp", + " 22", + " 22", + " ", + " ", + " ", + " 204.246.162.38/32", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " -1", + " ", + " ", + " ", + " 0.0.0.0/0", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + ""); + + private final String createSecurityGroupResponse = Joiner.on("\n").join( + "", + " 59dbff89-35bd-4eac-99ed-be587EXAMPLE", + " true", + " sg-0a42d66a", + ""); + + private final String authorizeSecurityGroupIngressResponse = Joiner.on("\n").join( + "", + " 59dbff89-35bd-4eac-99ed-be587EXAMPLE", + " true", + ""); + + private final String revokeSecurityGroupIngressResponse = Joiner.on("\n").join( + "", + " 59dbff89-35bd-4eac-99ed-be587EXAMPLE", + " true", + ""); + + private final String deleteSecurityGroupResponse = Joiner.on("\n").join( + "", + " 59dbff89-35bd-4eac-99ed-be587EXAMPLE", + " true", + ""); + + @SuppressWarnings("deprecation") + public void describeSecurityGroups() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(describeSecurityGroupsResponse)); + + Set results = securityGroupApi().describeSecurityGroupsInRegion(DEFAULT_REGION); + SecurityGroup result = Iterables.getOnlyElement(results); + assertEquals(result.getId(), "sg-1a2b3c4d"); + assertEquals(result.getRegion(), "us-east-1"); + assertEquals(result.getName(), "WebServers"); + assertEquals(result.getOwnerId(), "123456789012"); + assertEquals(result.getDescription(), "Web Servers"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups"); + } + + public void describeSecurityGroupsGiving404() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404)); + + Set results = securityGroupApi().describeSecurityGroupsInRegion(DEFAULT_REGION); + assertEquals(results, ImmutableSet.of()); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups"); + } + + public void describeSecurityGroupsById() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(describeSecurityGroupsResponse)); + + Set results = securityGroupApi().describeSecurityGroupsInRegionById(DEFAULT_REGION, "sg-1a2b3c4d"); + SecurityGroup result = Iterables.getOnlyElement(results); + assertEquals(result.getId(), "sg-1a2b3c4d"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupId.1=sg-1a2b3c4d"); + } + + public void describeSecurityGroupsByName() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(describeSecurityGroupsResponse)); + + Set results = securityGroupApi().describeSecurityGroupsInRegion(DEFAULT_REGION, "WebServers"); + SecurityGroup result = Iterables.getOnlyElement(results); + assertEquals(result.getId(), "sg-1a2b3c4d"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&GroupName.1=WebServers"); + } + + public void describeSecurityGroupsFiltered() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(describeSecurityGroupsResponse)); + + Set results = securityGroupApi().describeSecurityGroupsInRegionWithFilter(DEFAULT_REGION, + ImmutableMultimap.of("group-name", "WebServers", "vpc-id", "vpc-614cc409")); + SecurityGroup result = Iterables.getOnlyElement(results); + assertEquals(result.getId(), "sg-1a2b3c4d"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSecurityGroups&Filter.1.Name=group-name&Filter.1.Value.1=WebServers&Filter.2.Name=vpc-id&Filter.2.Value.1=vpc-614cc409"); + } + + public void describeSecurityGroupsDifferentRegion() throws Exception { + String region = "us-west-2"; + enqueueRegions(DEFAULT_REGION, region); + enqueue(region, new MockResponse().setBody(describeSecurityGroupsResponse)); + + Set results = securityGroupApi().describeSecurityGroupsInRegion(region); + SecurityGroup result = Iterables.getOnlyElement(results); + assertEquals(result.getId(), "sg-1a2b3c4d"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(region, "Action=DescribeSecurityGroups"); + } + + public void createSecurityGroupsInRegionAndReturnId() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(createSecurityGroupResponse)); + + String result = securityGroupApi().createSecurityGroupInRegionAndReturnId(DEFAULT_REGION, "WebServers", "Web Servers", CreateSecurityGroupOptions.Builder.vpcId("vpc-614cc409")); + assertEquals(result, "sg-0a42d66a"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=CreateSecurityGroup&GroupName=WebServers&GroupDescription=Web%20Servers&VpcId=vpc-614cc409"); + } + + public void authorizeSecurityGroupIngress() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(authorizeSecurityGroupIngressResponse)); + + IpPermission perm = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8080).toPort(8080).build(); + securityGroupApi().authorizeSecurityGroupIngressInRegion(DEFAULT_REGION, "sg-1a2b3c4d", perm); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-1a2b3c4d&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=8080&IpPermissions.0.ToPort=8080&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0"); + } + + public void authorizeSecurityGroupIngressList() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(authorizeSecurityGroupIngressResponse)); + + IpPermission perm = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8080).toPort(8080).build(); + IpPermission perm2 = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8443).toPort(8443).build(); + securityGroupApi().authorizeSecurityGroupIngressInRegion(DEFAULT_REGION, "sg-1a2b3c4d", ImmutableList.of(perm, perm2)); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=AuthorizeSecurityGroupIngress&GroupId=sg-1a2b3c4d&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=8080&IpPermissions.0.ToPort=8080&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=8443&IpPermissions.1.ToPort=8443&IpPermissions.1.IpRanges.0.CidrIp=0.0.0.0/0"); + } + + public void revokeSecurityGroupIngress() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(revokeSecurityGroupIngressResponse)); + + IpPermission perm = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8080).toPort(8080).build(); + securityGroupApi().revokeSecurityGroupIngressInRegion(DEFAULT_REGION, "sg-1a2b3c4d", perm); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=RevokeSecurityGroupIngress&GroupId=sg-1a2b3c4d&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=8080&IpPermissions.0.ToPort=8080&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0"); + } + + public void revokeSecurityGroupIngressList() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(revokeSecurityGroupIngressResponse)); + + IpPermission perm = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8080).toPort(8080).build(); + IpPermission perm2 = IpPermission.builder().ipProtocol(IpProtocol.TCP).cidrBlock("0.0.0.0/0") + .fromPort(8443).toPort(8443).build(); + securityGroupApi().revokeSecurityGroupIngressInRegion(DEFAULT_REGION, "sg-1a2b3c4d", ImmutableList.of(perm, perm2)); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=RevokeSecurityGroupIngress&GroupId=sg-1a2b3c4d&IpPermissions.0.IpProtocol=tcp&IpPermissions.0.FromPort=8080&IpPermissions.0.ToPort=8080&IpPermissions.0.IpRanges.0.CidrIp=0.0.0.0/0&IpPermissions.1.IpProtocol=tcp&IpPermissions.1.FromPort=8443&IpPermissions.1.ToPort=8443&IpPermissions.1.IpRanges.0.CidrIp=0.0.0.0/0"); + } + + public void deleteSecurityGroups() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody(deleteSecurityGroupResponse)); + + securityGroupApi().deleteSecurityGroupInRegionById(DEFAULT_REGION, "sg-1a2b3c4d"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DeleteSecurityGroup&GroupId=sg-1a2b3c4d"); + } + + private AWSSecurityGroupApi securityGroupApi() { + return api().getSecurityGroupApi().get(); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiLiveTest.java index 0dc9b081ac..b851f3a92e 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiLiveTest.java @@ -16,12 +16,115 @@ */ package org.jclouds.aws.ec2.features; -import org.jclouds.ec2.features.SubnetApiLiveTest; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import org.jclouds.aws.ec2.AWSEC2Api; +import org.jclouds.aws.ec2.domain.VPC; +import org.jclouds.aws.ec2.options.CreateVpcOptions; +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.jclouds.ec2.domain.Subnet; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -@Test(groups = "live", testName = "AWSSubnetApiLiveTest") -public class AWSSubnetApiLiveTest extends SubnetApiLiveTest { +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Iterables; + +/** + * Tests behavior of {@code VPCApi} + */ +@Test(groups = "live", singleThreaded = true) +public class AWSSubnetApiLiveTest extends BaseComputeServiceContextLiveTest { + + private String region; + + private AWSEC2Api api; + private AWSSubnetApi subnetClient; + private VPCApi vpcClient; + + private Subnet subnet; + private VPC vpc; + public AWSSubnetApiLiveTest() { provider = "aws-ec2"; + region = "us-west-2"; + } + + @Override + @BeforeClass(groups = { "integration", "live" }) + public void setupContext() { + super.setupContext(); + api = view.unwrapApi(AWSEC2Api.class); + subnetClient = api.getAWSSubnetApi().get(); + vpcClient = view.unwrapApi(AWSEC2Api.class).getVPCApi().get(); + } + + @Override + @AfterClass(groups = { "integration", "live" }) + public void tearDownContext() { + try { + try { + if (subnet != null) { + subnetClient.deleteSubnetInRegion(region, subnet.getSubnetId()); + } + } finally { + if (vpc != null) { + vpcClient.deleteVpc(region, vpc.id()); + } + } + } finally { + super.tearDownContext(); + } + } + + @Test + public void testCreateSubnetInRegion() { + vpc = vpcClient.createVpc(region, "10.0.0.0/16", CreateVpcOptions.NONE); + subnet = subnetClient.createSubnetInRegion(region, vpc.id(), "10.0.0.0/20"); + assertNotNull(subnet); + assertEquals(subnet.getCidrBlock(), "10.0.0.0/20"); + } + + @Test(dependsOnMethods = "testCreateSubnetInRegion") + public void testGet() { + FluentIterable subnets = subnetClient.describeSubnetsInRegion(region, subnet.getSubnetId()); + Subnet subnetFound = Iterables.getOnlyElement(subnets); + assertEquals(subnetFound.getSubnetId(), subnet.getSubnetId()); + } + + @Test(dependsOnMethods = "testCreateSubnetInRegion") + public void testFilter() { + FluentIterable subnets = subnetClient.describeSubnetsInRegionWithFilter(region, + ImmutableMultimap.of("subnet-id", subnet.getSubnetId())); + Subnet subnetFound = Iterables.getOnlyElement(subnets); + assertEquals(subnetFound.getSubnetId(), subnet.getSubnetId()); + } + + @Test(dependsOnMethods = "testCreateSubnetInRegion") + public void testList() { + FluentIterable subnets = subnetClient.describeSubnetsInRegionWithFilter(region, + ImmutableMultimap.of()); + Optional subnetFound = Iterables.tryFind(subnets, new Predicate() { + @Override + public boolean apply(Subnet input) { + return input != null && input.getSubnetId().equals(subnet.getSubnetId()); + } + }); + assertTrue(subnetFound.isPresent(), "subnets=" + ImmutableList.copyOf(subnets)); + } + + @Test(dependsOnMethods = {"testGet", "testFilter", "testList"}, alwaysRun = true) + public void testDelete() { + if (subnet != null) { + String subnetId = subnet.getSubnetId(); + subnet = null; + subnetClient.deleteSubnetInRegion(region, subnetId); + } } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiMockTest.java new file mode 100644 index 0000000000..b8f81ca9ad --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/AWSSubnetApiMockTest.java @@ -0,0 +1,213 @@ +/* + * 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.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest; +import org.jclouds.aws.ec2.options.CreateSubnetOptions; +import org.jclouds.ec2.domain.Subnet; +import org.testng.annotations.Test; + +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Iterables; +import com.squareup.okhttp.mockwebserver.MockResponse; + +@Test(groups = "unit", testName = "AWSSubnetApiMockTest", singleThreaded = true) +public class AWSSubnetApiMockTest extends BaseAWSEC2ApiMockTest { + + private final String describeSubnetsResponse = "\n" + + " 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE\n" + + " \n" + + " \n" + + " subnet-9d4a7b6c\n" + + " available\n" + + " vpc-1a2b3c4d\n" + + " 10.0.1.0/24 \n" + + " \n" + + " \n" + + " 2001:db8:1234:1a00::/64\n" + + " subnet-cidr-assoc-abababab\n" + + " \n" + + " ASSOCIATED\n" + + " \n" + + " \n" + + " \n" + + " 251\n" + + " us-east-1a\n" + + " false\n" + + " false\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + ""; + + public void createSubnetInRegion() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, new MockResponse().setBody("\n" + + " 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE\n" + + " \n" + + " subnet-9d4a7b6c\n" + + " pending\n" + + " vpc-1a2b3c4d\n" + + " 10.0.1.0/24 \n" + + " 251\n" + + " us-east-1a\n" + + " \n" + + " \n" + + "")); + + Subnet result = subnetApi().createSubnetInRegion(DEFAULT_REGION, "vpc-1a2b3c4d", "10.0.1.0/24"); + assertEquals(result.getVpcId(), "vpc-1a2b3c4d"); + assertEquals(result.getCidrBlock(), "10.0.1.0/24"); + assertEquals(result.getAvailabilityZone(), "us-east-1a"); + assertEquals(result.getSubnetId(), "subnet-9d4a7b6c"); + assertEquals(result.getSubnetState().value(), "pending"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=CreateSubnet&VpcId=vpc-1a2b3c4d&CidrBlock=10.0.1.0/24"); + } + + public void createSubnetInRegion_options() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setBody("\n" + + " 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE\n" + + " \n" + + " subnet-9d4a7b6c\n" + + " pending\n" + + " vpc-1a2b3c4d\n" + + " 10.0.1.0/24 \n" + + " 251\n" + + " us-east-1a\n" + + " \n" + + " \n" + + "")); + + Subnet result = subnetApi().createSubnetInRegion(DEFAULT_REGION, "vpc-1a2b3c4d", "10.0.1.0/24", + new CreateSubnetOptions().dryRun().availabilityZone("us-east-1a")); + assertEquals(result.getVpcId(), "vpc-1a2b3c4d"); + assertEquals(result.getCidrBlock(), "10.0.1.0/24"); + assertEquals(result.getAvailabilityZone(), "us-east-1a"); + assertEquals(result.getSubnetId(), "subnet-9d4a7b6c"); + assertEquals(result.getSubnetState().value(), "pending"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=CreateSubnet&VpcId=vpc-1a2b3c4d&CidrBlock=10.0.1.0/24&DryRun=true&AvailabilityZone=us-east-1a"); + } + + public void deleteSubnetInRegion() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setBody("\n" + + " 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE\n" + + " true\n" + + "")); + + subnetApi().deleteSubnetInRegion(DEFAULT_REGION, "subnet-9d4a7b6c"); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DeleteSubnet&SubnetId=subnet-9d4a7b6c"); + } + + public void describeSubnetInRegion() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setBody(describeSubnetsResponse)); + + FluentIterable results = subnetApi().describeSubnetsInRegion(DEFAULT_REGION); + Subnet result = Iterables.getOnlyElement(results); + assertEquals(result.getSubnetId(), "subnet-9d4a7b6c"); + assertEquals(result.getSubnetState().value(), "available"); + assertEquals(result.getVpcId(), "vpc-1a2b3c4d"); + assertEquals(result.getCidrBlock(), "10.0.1.0/24"); + assertEquals(result.getAvailabilityZone(), "us-east-1a"); + assertEquals(result.getAvailableIpAddressCount(), 251); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSubnets"); + } + + public void describeSubnetInRegionWithFilter() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setBody(describeSubnetsResponse)); + + FluentIterable results = subnetApi().describeSubnetsInRegionWithFilter(DEFAULT_REGION, + ImmutableMultimap.of("vpc-id", "vpc-1a2b3c4d", "availabilityZone", "us-east-1a")); + Subnet result = Iterables.getOnlyElement(results); + assertEquals(result.getSubnetId(), "subnet-9d4a7b6c"); + assertEquals(result.getSubnetState().value(), "available"); + assertEquals(result.getVpcId(), "vpc-1a2b3c4d"); + assertEquals(result.getCidrBlock(), "10.0.1.0/24"); + assertEquals(result.getAvailabilityZone(), "us-east-1a"); + assertEquals(result.getAvailableIpAddressCount(), 251); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSubnets&Filter.1.Name=vpc-id&Filter.1.Value.1=vpc-1a2b3c4d&Filter.2.Name=availabilityZone&Filter.2.Value.1=us-east-1a"); + } + + public void describeSubnetInRegionWhen404() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setResponseCode(404)); + + FluentIterable results = subnetApi().describeSubnetsInRegion(DEFAULT_REGION); + assertTrue(Iterables.isEmpty(results)); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSubnets"); + } + + public void describeSubnetInRegionWithFilterWhen404() throws Exception { + enqueueRegions(DEFAULT_REGION); + enqueue(DEFAULT_REGION, + new MockResponse().setResponseCode(404)); + + FluentIterable results = subnetApi().describeSubnetsInRegionWithFilter(DEFAULT_REGION, + ImmutableMultimap.of("vpc-id", "vpc-1a2b3c4d")); + assertTrue(Iterables.isEmpty(results)); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(DEFAULT_REGION, "Action=DescribeSubnets&Filter.1.Name=vpc-id&Filter.1.Value.1=vpc-1a2b3c4d"); + } + + public void describeSubnetInNonDefaultRegionWhen404() throws Exception { + String region = "us-west-2"; + + enqueueRegions(DEFAULT_REGION, region); + enqueue(region, + new MockResponse().setResponseCode(404)); + + FluentIterable results = subnetApiForRegion(region).list(); + assertTrue(Iterables.isEmpty(results)); + + assertPosted(DEFAULT_REGION, "Action=DescribeRegions"); + assertPosted(region, "Action=DescribeSubnets"); + } + + private AWSSubnetApi subnetApi() { + return api().getAWSSubnetApi().get(); + } + + private AWSSubnetApi subnetApiForRegion(String region) { + return api().getAWSSubnetApiForRegion(region).get(); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/VPCApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/VPCApiLiveTest.java index 06c48735b1..7ee0d31730 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/VPCApiLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/VPCApiLiveTest.java @@ -24,6 +24,7 @@ import org.jclouds.aws.ec2.AWSEC2Api; import org.jclouds.aws.ec2.domain.VPC; import org.jclouds.aws.ec2.options.CreateVpcOptions; import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -48,6 +49,18 @@ public class VPCApiLiveTest extends BaseComputeServiceContextLiveTest { client = view.unwrapApi(AWSEC2Api.class).getVPCApi().get(); } + @Override + @AfterClass(groups = { "integration", "live" }) + public void tearDownContext() { + try { + if (vpc != null) { + client.deleteVpc(null, vpc.id()); + } + } finally { + super.tearDownContext(); + } + } + @Test public void testCreate() { vpc = client.createVpc(null, "10.0.0.0/16", CreateVpcOptions.NONE); @@ -69,7 +82,9 @@ public class VPCApiLiveTest extends BaseComputeServiceContextLiveTest { @Test(dependsOnMethods = {"testList", "testGet"}, alwaysRun = true) public void testDelete() { if (vpc != null) { - assertTrue(client.deleteVpc(null, vpc.id())); + String vpcId = vpc.id(); + vpc = null; + assertTrue(client.deleteVpc(null, vpcId)); } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java index 796cf698fc..060e577674 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/internal/BaseAWSEC2ApiMockTest.java @@ -116,7 +116,7 @@ public class BaseAWSEC2ApiMockTest { } } - @BeforeMethod + @BeforeMethod(alwaysRun = true) public void start() throws IOException { MockWebServer server = new MockWebServer(); server.play();