blob: 937271004c7a1f57815527fd0f84aee058882306 [file] [log] [blame]
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
import org.jclouds.ec2.domain.IpPermission;
import org.jclouds.ec2.domain.IpProtocol;
import org.jclouds.ec2.domain.SecurityGroup;
import org.jclouds.ec2.domain.UserIdGroupPair;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Module;
/**
* Tests behavior of {@code SecurityGroupClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true)
public class SecurityGroupClientLiveTest {
protected SecurityGroupClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
protected String provider = "ec2";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides;
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
client = context.getApi().getSecurityGroupServices();
}
@Test
void testDescribe() {
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
Region.AP_SOUTHEAST_1, Region.AP_NORTHEAST_1)) {
SortedSet<SecurityGroup> allResults = ImmutableSortedSet.<SecurityGroup> copyOf(client
.describeSecurityGroupsInRegion(region));
assertNotNull(allResults);
if (allResults.size() >= 1) {
SecurityGroup group = allResults.last();
SortedSet<SecurityGroup> result = ImmutableSortedSet.<SecurityGroup> copyOf(client
.describeSecurityGroupsInRegion(region, group.getName()));
assertNotNull(result);
SecurityGroup compare = result.last();
assertEquals(compare, group);
}
}
}
@Test
void testCreateSecurityGroup() {
String groupName = PREFIX + "1";
cleanupAndSleep(groupName);
try {
String groupDescription = PREFIX + "1 description";
client.deleteSecurityGroupInRegion(null, groupName);
client.createSecurityGroupInRegion(null, groupName, groupDescription);
verifySecurityGroup(groupName, groupDescription);
} finally {
client.deleteSecurityGroupInRegion(null, groupName);
}
}
protected void cleanupAndSleep(String groupName) {
try {
client.deleteSecurityGroupInRegion(null, groupName);
Thread.sleep(2000);
} catch (Exception e) {
}
}
@Test
void testAuthorizeSecurityGroupIngressCidr() {
String groupName = PREFIX + "ingress";
cleanupAndSleep(groupName);
try {
client.createSecurityGroupInRegion(null, groupName, groupName);
client.authorizeSecurityGroupIngressInRegion(null, groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasPermission(client, groupName, new TCPPort80AllIPs()));
client.revokeSecurityGroupIngressInRegion(null, groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasNoPermissions(client, groupName));
} finally {
client.deleteSecurityGroupInRegion(null, groupName);
}
}
@Test
void testAuthorizeSecurityGroupIngressSourcePort() {
String groupName = PREFIX + "ingress";
cleanupAndSleep(groupName);
try {
client.createSecurityGroupInRegion(null, groupName, groupName);
client.authorizeSecurityGroupIngressInRegion(null, groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasPermission(client, groupName, new TCPPort80AllIPs()));
client.revokeSecurityGroupIngressInRegion(null, groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasNoPermissions(client, groupName));
} finally {
client.deleteSecurityGroupInRegion(null, groupName);
}
}
private void verifySecurityGroup(String groupName, String description) {
Set<SecurityGroup> oneResult = client.describeSecurityGroupsInRegion(null, groupName);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup listPair = oneResult.iterator().next();
assertEquals(listPair.getName(), groupName);
assertEquals(listPair.getDescription(), description);
}
@Test
void testAuthorizeSecurityGroupIngressSourceGroup() {
final String group1Name = PREFIX + "ingress1";
String group2Name = PREFIX + "ingress2";
cleanupAndSleep(group2Name);
cleanupAndSleep(group1Name);
try {
client.createSecurityGroupInRegion(null, group1Name, group1Name);
client.createSecurityGroupInRegion(null, group2Name, group2Name);
ensureGroupsExist(group1Name, group2Name);
client.authorizeSecurityGroupIngressInRegion(null, group1Name, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasPermission(client, group1Name, new TCPPort80AllIPs()));
Set<SecurityGroup> oneResult = client.describeSecurityGroupsInRegion(null, group1Name);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
final SecurityGroup group = oneResult.iterator().next();
assertEquals(group.getName(), group1Name);
final UserIdGroupPair to = new UserIdGroupPair(group.getOwnerId(), group1Name);
client.authorizeSecurityGroupIngressInRegion(null, group2Name, to);
assertEventually(new GroupHasPermission(client, group2Name, new Predicate<IpPermission>() {
@Override
public boolean apply(IpPermission arg0) {
return arg0.getUserIdGroupPairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name));
}
}));
client.revokeSecurityGroupIngressInRegion(null, group2Name,
new UserIdGroupPair(group.getOwnerId(), group1Name));
assertEventually(new GroupHasNoPermissions(client, group2Name));
} finally {
client.deleteSecurityGroupInRegion(null, group2Name);
client.deleteSecurityGroupInRegion(null, group1Name);
}
}
public final class TCPPort80AllIPs implements Predicate<IpPermission> {
@Override
public boolean apply(IpPermission arg0) {
return arg0.getIpProtocol() == IpProtocol.TCP && arg0.getFromPort() == 80 && arg0.getToPort() == 80
&& arg0.getIpRanges().equals(ImmutableSet.of("0.0.0.0/0"));
}
}
public static final class GroupHasPermission implements Runnable {
private final SecurityGroupClient client;
private final String group;
private final Predicate<IpPermission> permission;
public GroupHasPermission(SecurityGroupClient client, String group, Predicate<IpPermission> permission) {
this.client = client;
this.group = group;
this.permission = permission;
}
public void run() {
try {
Set<SecurityGroup> oneResult = client.describeSecurityGroupsInRegion(null, group);
assert Iterables.all(Iterables.getOnlyElement(oneResult).getIpPermissions(), permission) : permission
+ ": " + oneResult;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
public static final class GroupHasNoPermissions implements Runnable {
private final SecurityGroupClient client;
private final String group;
public GroupHasNoPermissions(SecurityGroupClient client, String group) {
this.client = client;
this.group = group;
}
public void run() {
try {
Set<SecurityGroup> oneResult = client.describeSecurityGroupsInRegion(null, group);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup listPair = oneResult.iterator().next();
assertEquals(listPair.getIpPermissions().size(), 0);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
protected void ensureGroupsExist(String group1Name, String group2Name) {
SortedSet<SecurityGroup> twoResults = ImmutableSortedSet.copyOf(client.describeSecurityGroupsInRegion(null,
group1Name, group2Name));
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
Iterator<SecurityGroup> iterator = twoResults.iterator();
SecurityGroup listPair1 = iterator.next();
assertEquals(listPair1.getName(), group1Name);
assertEquals(listPair1.getDescription(), group1Name);
SecurityGroup listPair2 = iterator.next();
assertEquals(listPair2.getName(), group2Name);
assertEquals(listPair2.getDescription(), group2Name);
}
private static final int INCONSISTENCY_WINDOW = 5000;
/**
* Due to eventual consistency, container commands may not return correctly
* immediately. Hence, we will try up to the inconsistency window to see if
* the assertion completes.
*/
protected static void assertEventually(Runnable assertion) {
long start = System.currentTimeMillis();
AssertionError error = null;
for (int i = 0; i < 30; i++) {
try {
assertion.run();
if (i > 0)
System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System.currentTimeMillis() - start,
assertion.getClass().getSimpleName());
return;
} catch (AssertionError e) {
error = e;
}
try {
Thread.sleep(INCONSISTENCY_WINDOW / 30);
} catch (InterruptedException e) {
}
}
if (error != null)
throw error;
}
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
@AfterTest
public void shutdown() {
context.close();
}
}