mirror of https://github.com/apache/jclouds.git
JCLOUDS-101 - Add SecurityGroupExtension for compute
- Adds the SecurityGroupExtension to compute, with tests and stub support. - Gets everything else to actually build against this. - Unifies on compute's IpPermission/IpProtocol, eliminating EC2's. - Converters from EC2/Nova/CloudStack SecurityGroup (and rules, for the latter two) to the compute SecurityGroup (and rules, etc). - EC2SecurityGroupExtension and tests. - AWSEC2SecurityGroupExtension and tests - depends on JCLOUDS-99.
This commit is contained in:
parent
a906f9f4ec
commit
5f524ee6c9
|
@ -43,6 +43,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
|
@ -113,12 +114,13 @@ public class CloudStackComputeService extends BaseComputeService {
|
|||
Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId,
|
||||
GroupNamingConvention.Factory namingConvention,
|
||||
Supplier<LoadingCache<String, Zone>> zoneIdToZone,
|
||||
Optional<ImageExtension> imageExtension) {
|
||||
Optional<ImageExtension> imageExtension,
|
||||
Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
|
||||
this.zoneIdToZone = checkNotNull(zoneIdToZone, "zoneIdToZone");
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
|
||||
|
|
|
@ -32,6 +32,8 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.cloudstack.CloudStackClient;
|
||||
import org.jclouds.cloudstack.compute.CloudStackComputeService;
|
||||
import org.jclouds.cloudstack.compute.extensions.CloudStackImageExtension;
|
||||
import org.jclouds.cloudstack.compute.functions.CloudStackSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.cloudstack.compute.functions.IngressRuleToIpPermission;
|
||||
import org.jclouds.cloudstack.compute.functions.OrphanedGroupsByZoneId;
|
||||
import org.jclouds.cloudstack.compute.functions.ServiceOfferingToHardware;
|
||||
import org.jclouds.cloudstack.compute.functions.TemplateToImage;
|
||||
|
@ -46,6 +48,7 @@ import org.jclouds.cloudstack.compute.strategy.BasicNetworkOptionsConverter;
|
|||
import org.jclouds.cloudstack.compute.strategy.CloudStackComputeServiceAdapter;
|
||||
import org.jclouds.cloudstack.compute.strategy.OptionsConverter;
|
||||
import org.jclouds.cloudstack.domain.FirewallRule;
|
||||
import org.jclouds.cloudstack.domain.IngressRule;
|
||||
import org.jclouds.cloudstack.domain.IPForwardingRule;
|
||||
import org.jclouds.cloudstack.domain.Network;
|
||||
import org.jclouds.cloudstack.domain.NetworkType;
|
||||
|
@ -77,6 +80,7 @@ import org.jclouds.compute.domain.OperatingSystem;
|
|||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
|
||||
|
@ -112,6 +116,10 @@ public class CloudStackComputeServiceContextModule extends
|
|||
}).to(CloudStackComputeServiceAdapter.class);
|
||||
bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
|
||||
}).to(VirtualMachineToNodeMetadata.class);
|
||||
bind(new TypeLiteral<Function<SecurityGroup, org.jclouds.compute.domain.SecurityGroup>>() {
|
||||
}).to(CloudStackSecurityGroupToSecurityGroup.class);
|
||||
bind(new TypeLiteral<Function<IngressRule, IpPermission>>() {
|
||||
}).to(IngressRuleToIpPermission.class);
|
||||
bind(new TypeLiteral<Function<Template, org.jclouds.compute.domain.Image>>() {
|
||||
}).to(TemplateToImage.class);
|
||||
bind(new TypeLiteral<Function<ServiceOffering, org.jclouds.compute.domain.Hardware>>() {
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.cloudstack.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.cloudstack.domain.IngressRule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
|
||||
/**
|
||||
* A function for transforming a CloudStack-specific SecurityGroup into a generic
|
||||
* SecurityGroup object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudStackSecurityGroupToSecurityGroup implements Function<org.jclouds.cloudstack.domain.SecurityGroup, SecurityGroup> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final Function<IngressRule,IpPermission> ruleToPermission;
|
||||
|
||||
@Inject
|
||||
public CloudStackSecurityGroupToSecurityGroup(Function<IngressRule,IpPermission> ruleToPermission) {
|
||||
this.ruleToPermission = ruleToPermission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup apply(org.jclouds.cloudstack.domain.SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
|
||||
builder.id(group.getId());
|
||||
builder.providerId(group.getId());
|
||||
builder.name(group.getName());
|
||||
builder.ownerId(group.getAccount());
|
||||
builder.ipPermissions(transform(group.getIngressRules(), ruleToPermission));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.cloudstack.compute.functions;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.cloudstack.domain.IngressRule;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
||||
/**
|
||||
* A function for transforming a CloudStack-specific IngressRule into a generic
|
||||
* IpPermission object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class IngressRuleToIpPermission implements Function<IngressRule, IpPermission> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public IngressRuleToIpPermission() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpPermission apply(IngressRule rule) {
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
builder.ipProtocol(IpProtocol.fromValue(rule.getProtocol()));
|
||||
builder.fromPort(rule.getStartPort());
|
||||
builder.toPort(rule.getEndPort());
|
||||
builder.cidrBlock(rule.getCIDR());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.cloudstack.compute.functions;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.cloudstack.domain.IngressRule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Test(groups = "unit", testName = "CloudStackSecurityGroupToSecurityGroupTest")
|
||||
public class CloudStackSecurityGroupToSecurityGroupTest {
|
||||
|
||||
private static final IngressRuleToIpPermission ruleConverter = new IngressRuleToIpPermission();
|
||||
|
||||
@Test
|
||||
public void testApply() {
|
||||
IngressRule ruleToConvert = IngressRule.builder()
|
||||
.id("some-id")
|
||||
.account("some-account")
|
||||
.securityGroupName("some-group-name")
|
||||
.protocol(IpProtocol.TCP.toString())
|
||||
.startPort(10)
|
||||
.endPort(20)
|
||||
.CIDR("0.0.0.0/0")
|
||||
.build();
|
||||
|
||||
org.jclouds.cloudstack.domain.SecurityGroup origGroup = org.jclouds.cloudstack.domain.SecurityGroup.builder()
|
||||
.id("some-id")
|
||||
.name("some-group")
|
||||
.description("some-description")
|
||||
.account("some-account")
|
||||
.ingressRules(ImmutableSet.of(ruleToConvert))
|
||||
.build();
|
||||
|
||||
CloudStackSecurityGroupToSecurityGroup parser = createGroupParser();
|
||||
|
||||
SecurityGroup group = parser.apply(origGroup);
|
||||
|
||||
assertEquals(group.getId(), origGroup.getId());
|
||||
assertEquals(group.getProviderId(), origGroup.getId());
|
||||
assertEquals(group.getName(), origGroup.getName());
|
||||
assertEquals(group.getOwnerId(), origGroup.getAccount());
|
||||
assertEquals(group.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getIngressRules(), ruleConverter)));
|
||||
}
|
||||
|
||||
private CloudStackSecurityGroupToSecurityGroup createGroupParser() {
|
||||
CloudStackSecurityGroupToSecurityGroup parser = new CloudStackSecurityGroupToSecurityGroup(ruleConverter);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.cloudstack.compute.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.jclouds.cloudstack.domain.IngressRule;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the function for transforming a cloudstack specific IngressRule into a generic
|
||||
* IpPermission object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class IngressRuleToIpPermissionTest {
|
||||
|
||||
@Test
|
||||
public void testApplyWithTCP() {
|
||||
IngressRule ruleToConvert = IngressRule.builder()
|
||||
.id("some-id")
|
||||
.account("some-account")
|
||||
.securityGroupName("some-group-name")
|
||||
.protocol(IpProtocol.TCP.toString())
|
||||
.startPort(10)
|
||||
.endPort(20)
|
||||
.CIDR("0.0.0.0/0")
|
||||
.build();
|
||||
|
||||
IngressRuleToIpPermission converter = new IngressRuleToIpPermission();
|
||||
|
||||
IpPermission convertedPerm = converter.apply(ruleToConvert);
|
||||
|
||||
assertEquals(convertedPerm.getIpProtocol(), IpProtocol.fromValue(ruleToConvert.getProtocol()));
|
||||
assertEquals(convertedPerm.getFromPort(), ruleToConvert.getStartPort());
|
||||
assertEquals(convertedPerm.getToPort(), ruleToConvert.getEndPort());
|
||||
assertEquals(convertedPerm.getCidrBlocks(), ImmutableSet.of("0.0.0.0/0"));
|
||||
assertTrue(convertedPerm.getTenantIdGroupNamePairs().size() == 0);
|
||||
assertTrue(convertedPerm.getGroupIds().size() == 0);
|
||||
}
|
||||
}
|
|
@ -21,9 +21,9 @@
|
|||
org.jclouds.ec2.security-group2
|
||||
(:require (org.jclouds [compute2 :as compute])
|
||||
[org.jclouds.ec2.ebs2 :as ebs])
|
||||
(:import org.jclouds.ec2.domain.IpProtocol
|
||||
org.jclouds.ec2.domain.SecurityGroup
|
||||
org.jclouds.ec2.services.SecurityGroupClient))
|
||||
(:import org.jclouds.ec2.domain.SecurityGroup
|
||||
org.jclouds.ec2.services.SecurityGroupClient
|
||||
org.jclouds.net.domain.IpProtocol))
|
||||
|
||||
(defn #^SecurityGroupClient
|
||||
sg-service
|
||||
|
|
|
@ -19,9 +19,9 @@ package org.jclouds.ec2.binders;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.util.IpPermissions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,9 +19,9 @@ package org.jclouds.ec2.binders;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.util.IpPermissions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention.Factory;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
|
@ -128,12 +129,13 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
|
||||
@Named("SECURITY") LoadingCache<RegionAndName, String> securityGroupMap,
|
||||
Optional<ImageExtension> imageExtension, GroupNamingConvention.Factory namingConvention,
|
||||
@Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames) {
|
||||
@Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames,
|
||||
Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
|
||||
this.client = client;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jclouds.compute.ComputeServiceContext;
|
|||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.loaders.RegionAndIdToImage;
|
||||
|
@ -137,5 +138,9 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
|
|||
return Optional.of(i.getInstance(ImageExtension.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
|
||||
return Optional.of(i.getInstance(SecurityGroupExtension.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,18 +29,22 @@ import org.jclouds.compute.ComputeService;
|
|||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadata.Status;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.extensions.EC2ImageExtension;
|
||||
import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
|
||||
import org.jclouds.ec2.compute.functions.AddElasticIpsToNodemetadata;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.EC2ImageParser;
|
||||
import org.jclouds.ec2.compute.functions.EC2SecurityGroupToSecurityGroup;
|
||||
import org.jclouds.ec2.compute.functions.PasswordCredentialsFromWindowsInstance;
|
||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||
import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
|
||||
|
@ -129,8 +133,12 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule {
|
|||
}).to(PasswordCredentialsFromWindowsInstance.class);
|
||||
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.Image, Image>>() {
|
||||
}).to(EC2ImageParser.class);
|
||||
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup>>() {
|
||||
}).to(EC2SecurityGroupToSecurityGroup.class);
|
||||
bind(new TypeLiteral<ImageExtension>() {
|
||||
}).to(EC2ImageExtension.class);
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {
|
||||
}).to(EC2SecurityGroupExtension.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.base.Predicates.notNull;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.collect.Iterables.toArray;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention.Factory;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.UncheckedTimeoutException;
|
||||
|
||||
/**
|
||||
* An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
|
||||
* is optional by providers.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class EC2SecurityGroupExtension implements SecurityGroupExtension {
|
||||
|
||||
protected final EC2Client client;
|
||||
protected final ListeningExecutorService userExecutor;
|
||||
protected final Supplier<Set<String>> regions;
|
||||
protected final Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter;
|
||||
protected final Supplier<Set<? extends Location>> locations;
|
||||
protected final LoadingCache<RegionAndName, String> groupCreator;
|
||||
protected final Factory namingConvention;
|
||||
|
||||
@Inject
|
||||
public EC2SecurityGroupExtension(EC2Client client,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
@Region Supplier<Set<String>> regions,
|
||||
Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter,
|
||||
@Memoized Supplier<Set<? extends Location>> locations,
|
||||
@Named("SECURITY") LoadingCache<RegionAndName, String> groupCreator,
|
||||
GroupNamingConvention.Factory namingConvention) {
|
||||
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.userExecutor = checkNotNull(userExecutor, "userExecutor");
|
||||
this.regions = checkNotNull(regions, "regions");
|
||||
this.groupConverter = checkNotNull(groupConverter, "groupConverter");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.groupCreator = checkNotNull(groupCreator, "groupCreator");
|
||||
this.namingConvention = checkNotNull(namingConvention, "namingConvention");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroups() {
|
||||
Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = pollSecurityGroups();
|
||||
Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
|
||||
groupConverter);
|
||||
return ImmutableSet.copyOf(groups);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(location);
|
||||
if (region == null) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
return listSecurityGroupsInLocation(region);
|
||||
}
|
||||
|
||||
public Set<SecurityGroup> listSecurityGroupsInLocation(String region) {
|
||||
Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = pollSecurityGroupsByRegion(region);
|
||||
Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
|
||||
groupConverter);
|
||||
return ImmutableSet.copyOf(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
|
||||
checkNotNull(id, "id");
|
||||
String[] parts = AWSUtils.parseHandle(id);
|
||||
String region = parts[0];
|
||||
String instanceId = parts[1];
|
||||
|
||||
RunningInstance instance = getOnlyElement(Iterables.concat(client.getInstanceServices().describeInstancesInRegion(region, instanceId)));
|
||||
|
||||
if (instance == null) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
Set<String> groupNames = instance.getGroupNames();
|
||||
Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
|
||||
client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, Iterables.toArray(groupNames, String.class));
|
||||
|
||||
return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup getSecurityGroupById(String id) {
|
||||
checkNotNull(id, "id");
|
||||
String[] parts = AWSUtils.parseHandle(id);
|
||||
String region = parts[0];
|
||||
String groupId = parts[1];
|
||||
|
||||
Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
|
||||
client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupId);
|
||||
|
||||
return getOnlyElement(transform(filter(rawGroups, notNull()), groupConverter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup createSecurityGroup(String name, Location location) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(location);
|
||||
if (region != null) {
|
||||
return createSecurityGroup(name, region);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityGroup createSecurityGroup(String name, String region) {
|
||||
String markerGroup = namingConvention.create().sharedNameForGroup(name);
|
||||
RegionNameAndIngressRules regionAndName = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
|
||||
false);
|
||||
|
||||
groupCreator.getUnchecked(regionAndName);
|
||||
|
||||
return getSecurityGroupById(regionAndName.slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSecurityGroup(String id) {
|
||||
checkNotNull(id, "id");
|
||||
String[] parts = AWSUtils.parseHandle(id);
|
||||
String region = parts[0];
|
||||
String groupName = parts[1];
|
||||
|
||||
if (client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupName).size() > 0) {
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName);
|
||||
// TODO: test this clear happens
|
||||
groupCreator.invalidate(new RegionNameAndIngressRules(region, groupName, null, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
if (ipPermission.getCidrBlocks().size() > 0) {
|
||||
for (String cidr : ipPermission.getCidrBlocks()) {
|
||||
client.getSecurityGroupServices().
|
||||
authorizeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
ipPermission.getIpProtocol(),
|
||||
ipPermission.getFromPort(),
|
||||
ipPermission.getToPort(),
|
||||
cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
|
||||
for (String userId : ipPermission.getTenantIdGroupNamePairs().keySet()) {
|
||||
for (String groupName : ipPermission.getTenantIdGroupNamePairs().get(userId)) {
|
||||
client.getSecurityGroupServices().
|
||||
authorizeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
new UserIdGroupPair(userId, groupName));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("group: " + group);
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
for (String cidr : ipRanges) {
|
||||
client.getSecurityGroupServices().
|
||||
authorizeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
protocol,
|
||||
startPort,
|
||||
endPort,
|
||||
cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
for (String userId : tenantIdGroupNamePairs.keySet()) {
|
||||
for (String groupName : tenantIdGroupNamePairs.get(userId)) {
|
||||
client.getSecurityGroupServices().
|
||||
authorizeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
new UserIdGroupPair(userId, groupName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
if (ipPermission.getCidrBlocks().size() > 0) {
|
||||
for (String cidr : ipPermission.getCidrBlocks()) {
|
||||
client.getSecurityGroupServices().
|
||||
revokeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
ipPermission.getIpProtocol(),
|
||||
ipPermission.getFromPort(),
|
||||
ipPermission.getToPort(),
|
||||
cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
|
||||
for (String userId : ipPermission.getTenantIdGroupNamePairs().keySet()) {
|
||||
for (String groupName : ipPermission.getTenantIdGroupNamePairs().get(userId)) {
|
||||
client.getSecurityGroupServices().
|
||||
revokeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
new UserIdGroupPair(userId, groupName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
for (String cidr : ipRanges) {
|
||||
client.getSecurityGroupServices().
|
||||
revokeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
protocol,
|
||||
startPort,
|
||||
endPort,
|
||||
cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
for (String userId : tenantIdGroupNamePairs.keySet()) {
|
||||
for (String groupName : tenantIdGroupNamePairs.get(userId)) {
|
||||
client.getSecurityGroupServices().
|
||||
revokeSecurityGroupIngressInRegion(region,
|
||||
name,
|
||||
new UserIdGroupPair(userId, groupName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTenantIdGroupNamePairs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPortRangesForGroups() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> pollSecurityGroups() {
|
||||
Iterable<? extends Set<? extends org.jclouds.ec2.domain.SecurityGroup>> groups
|
||||
= transform(regions.get(), allSecurityGroupsInRegion());
|
||||
|
||||
return concat(groups);
|
||||
}
|
||||
|
||||
|
||||
protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> pollSecurityGroupsByRegion(String region) {
|
||||
return allSecurityGroupsInRegion().apply(region);
|
||||
}
|
||||
|
||||
protected Function<String, Set<? extends org.jclouds.ec2.domain.SecurityGroup>> allSecurityGroupsInRegion() {
|
||||
return new Function<String, Set<? extends org.jclouds.ec2.domain.SecurityGroup>>() {
|
||||
|
||||
@Override
|
||||
public Set<? extends org.jclouds.ec2.domain.SecurityGroup> apply(String from) {
|
||||
return client.getSecurityGroupServices().describeSecurityGroupsInRegion(from);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
protected Location findLocationWithId(final String locationId) {
|
||||
if (locationId == null)
|
||||
return null;
|
||||
try {
|
||||
Location location = Iterables.find(locations.get(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(locationId);
|
||||
}
|
||||
|
||||
});
|
||||
return location;
|
||||
|
||||
} catch (NoSuchElementException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
|
||||
/**
|
||||
* A function for transforming an EC2-specific SecurityGroup into a generic
|
||||
* SecurityGroup object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Singleton
|
||||
public class EC2SecurityGroupToSecurityGroup implements Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final Supplier<Set<? extends Location>> locations;
|
||||
|
||||
@Inject
|
||||
public EC2SecurityGroupToSecurityGroup(@Memoized Supplier<Set<? extends Location>> locations) {
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup apply(org.jclouds.ec2.domain.SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
Location location = findLocationWithId(group.getRegion());
|
||||
builder.location(location);
|
||||
builder.id(group.getName());
|
||||
builder.providerId(group.getId());
|
||||
builder.name(group.getName());
|
||||
builder.ipPermissions(group);
|
||||
builder.ownerId(group.getOwnerId());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Location findLocationWithId(final String locationId) {
|
||||
if (locationId == null)
|
||||
return null;
|
||||
try {
|
||||
Location location = Iterables.find(locations.get(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(locationId);
|
||||
}
|
||||
|
||||
});
|
||||
return location;
|
||||
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,10 +27,10 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-IpPermissionType.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class IpPermission {
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int fromPort;
|
||||
private int toPort;
|
||||
private IpProtocol ipProtocol;
|
||||
private Multimap<String, String> userIdGroupPairs = LinkedHashMultimap.create();
|
||||
private Set<String> groupIds = Sets.newLinkedHashSet();
|
||||
private Set<String> ipRanges = Sets.newLinkedHashSet();
|
||||
|
||||
public Builder fromPort(int fromPort) {
|
||||
this.fromPort = fromPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder toPort(int toPort) {
|
||||
this.toPort = toPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ipProtocol(IpProtocol ipProtocol) {
|
||||
this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder userIdGroupPair(String userId, String groupNameOrId) {
|
||||
this.userIdGroupPairs.put(checkNotNull(userId, "userId"), checkNotNull(groupNameOrId, "groupNameOrId of %s", userId));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder userIdGroupPairs(Multimap<String, String> userIdGroupPairs) {
|
||||
this.userIdGroupPairs.putAll(checkNotNull(userIdGroupPairs, "userIdGroupPairs"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ipRange(String ipRange) {
|
||||
this.ipRanges.add(ipRange);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ipRanges(Iterable<String> ipRanges) {
|
||||
Iterables.addAll(this.ipRanges, checkNotNull(ipRanges, "ipRanges"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder groupId(String groupId) {
|
||||
this.groupIds.add(checkNotNull(groupId, "groupId"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder groupIds(Iterable<String> groupIds) {
|
||||
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IpPermission build() {
|
||||
return new IpPermission(ipProtocol, fromPort, toPort, userIdGroupPairs, groupIds, ipRanges);
|
||||
}
|
||||
}
|
||||
|
||||
private final int fromPort;
|
||||
private final int toPort;
|
||||
private final Multimap<String, String> userIdGroupPairs;
|
||||
private final Set<String> groupIds;
|
||||
private final IpProtocol ipProtocol;
|
||||
private final Set<String> ipRanges;
|
||||
|
||||
public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort, Multimap<String, String> userIdGroupPairs,
|
||||
Iterable<String> groupIds, Iterable<String> ipRanges) {
|
||||
this.fromPort = fromPort;
|
||||
this.toPort = toPort;
|
||||
this.userIdGroupPairs = ImmutableMultimap.copyOf(checkNotNull(userIdGroupPairs, "userIdGroupPairs"));
|
||||
this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
|
||||
this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds"));
|
||||
this.ipRanges = ImmutableSet.copyOf(checkNotNull(ipRanges, "ipRanges"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start of port range for the TCP and UDP protocols, or an ICMP type number.
|
||||
* An ICMP type number of -1 indicates a wildcard (i.e., any ICMP type
|
||||
* number).
|
||||
*/
|
||||
public int getFromPort() {
|
||||
return fromPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP
|
||||
* code of -1 indicates a wildcard (i.e., any ICMP code).
|
||||
*/
|
||||
public int getToPort() {
|
||||
return toPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of security group and user ID pairs.
|
||||
*/
|
||||
public Multimap<String, String> getUserIdGroupPairs() {
|
||||
return userIdGroupPairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of security group Ids
|
||||
*/
|
||||
public Set<String> getGroupIds() {
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP protocol
|
||||
*/
|
||||
public IpProtocol getIpProtocol() {
|
||||
return ipProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP ranges.
|
||||
*/
|
||||
public Set<String> getIpRanges() {
|
||||
return ipRanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(fromPort, toPort, groupIds, ipProtocol, ipRanges, userIdGroupPairs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
IpPermission that = IpPermission.class.cast(obj);
|
||||
return Objects.equal(this.fromPort, that.fromPort) && Objects.equal(this.toPort, that.toPort)
|
||||
&& Objects.equal(this.groupIds, that.groupIds) && Objects.equal(this.ipProtocol, that.ipProtocol)
|
||||
&& Objects.equal(this.ipRanges, that.ipRanges)
|
||||
&& Objects.equal(this.userIdGroupPairs, that.userIdGroupPairs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).omitNullValues().add("fromPort", fromPort == -1 ? null : fromPort)
|
||||
.add("toPort", toPort == -1 ? null : toPort).add("groupIds", groupIds.size() == 0 ? null : groupIds)
|
||||
.add("ipProtocol", ipProtocol).add("ipRanges", ipRanges.size() == 0 ? null : ipRanges)
|
||||
.add("userIdGroupPairs", userIdGroupPairs.size() == 0 ? null : userIdGroupPairs).toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Set;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
|
|
|
@ -30,12 +30,12 @@ import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
|||
import org.jclouds.aws.filters.FormSigner;
|
||||
import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
|
||||
import org.jclouds.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
package org.jclouds.ec2.services;
|
||||
|
||||
import java.util.Set;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
/**
|
||||
* Provides access to EC2 via their REST API.
|
||||
|
|
|
@ -21,8 +21,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.util.Maps2;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
@ -58,7 +58,7 @@ public class IpPermissions extends IpPermission {
|
|||
headers.put("IpPermissions.%d.ToPort", permission.getToPort() + "");
|
||||
String prefix = "IpPermissions.%d.IpRanges.";
|
||||
int i = 0;
|
||||
for (String cidrIp : checkNotNull(permission.getIpRanges(), "cidrIps")) {
|
||||
for (String cidrIp : checkNotNull(permission.getCidrBlocks(), "cidrIps")) {
|
||||
headers.put(prefix + i++ + ".CidrIp", cidrIp);
|
||||
}
|
||||
prefix = "IpPermissions.%d.Groups.";
|
||||
|
@ -68,15 +68,15 @@ public class IpPermissions extends IpPermission {
|
|||
}
|
||||
prefix = "IpPermissions.%d.Groups.";
|
||||
i = 0;
|
||||
for (Entry<String, String> userIdGroupNamePair : checkNotNull(permission.getUserIdGroupPairs(),
|
||||
"userIdGroupNamePairs").entries()) {
|
||||
headers.put(prefix + i + ".UserId", userIdGroupNamePair.getKey());
|
||||
headers.put(prefix + i + ".GroupName", userIdGroupNamePair.getValue());
|
||||
for (Entry<String, String> tenantIdGroupNamePair : checkNotNull(permission.getTenantIdGroupNamePairs(),
|
||||
"tenantIdGroupNamePairs").entries()) {
|
||||
headers.put(prefix + i + ".UserId", tenantIdGroupNamePair.getKey());
|
||||
headers.put(prefix + i + ".GroupName", tenantIdGroupNamePair.getValue());
|
||||
i++;
|
||||
}
|
||||
prefix = "IpPermissions.%d.IpRanges.";
|
||||
i = 0;
|
||||
for (String cidrIp : checkNotNull(permission.getIpRanges(), "cidrIps")) {
|
||||
for (String cidrIp : checkNotNull(permission.getCidrBlocks(), "cidrIps")) {
|
||||
headers.put(prefix + i++ + ".CidrIp", cidrIp);
|
||||
}
|
||||
return Multimaps.forMap(Maps2.transformKeys(headers, new Function<String, String>() {
|
||||
|
@ -165,7 +165,7 @@ public class IpPermissions extends IpPermission {
|
|||
}
|
||||
|
||||
public IpPermissions toVPCSecurityGroups(Iterable<String> groupIds) {
|
||||
return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), getUserIdGroupPairs(), groupIds,
|
||||
return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), getTenantIdGroupNamePairs(), groupIds,
|
||||
ImmutableSet.<String> of());
|
||||
}
|
||||
}
|
||||
|
@ -189,8 +189,8 @@ public class IpPermissions extends IpPermission {
|
|||
checkNotNull(groupName, "groupName")));
|
||||
}
|
||||
|
||||
public IpPermissions toEC2SecurityGroups(Multimap<String, String> userIdGroupNamePairs) {
|
||||
return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), userIdGroupNamePairs, getGroupIds(),
|
||||
public IpPermissions toEC2SecurityGroups(Multimap<String, String> tenantIdGroupNamePairs) {
|
||||
return new IpPermissions(getIpProtocol(), getFromPort(), getToPort(), tenantIdGroupNamePairs, getGroupIds(),
|
||||
ImmutableSet.<String> of());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ package org.jclouds.ec2.xml;
|
|||
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
|
@ -66,14 +66,14 @@ public class IpPermissionHandler extends ParseSax.HandlerForGeneratedRequestWith
|
|||
// EC2)
|
||||
builder.toPort(Integer.parseInt(currentOrNegative(currentText)));
|
||||
} else if (equalsOrSuffix(qName, "cidrIp")) {
|
||||
builder.ipRange(currentOrNull(currentText));
|
||||
builder.cidrBlock(currentOrNull(currentText));
|
||||
} else if (equalsOrSuffix(qName, "userId")) {
|
||||
this.userId = currentOrNull(currentText);
|
||||
} else if (equalsOrSuffix(qName, "groupName") || equalsOrSuffix(qName, "groupId")) {
|
||||
this.groupId = currentOrNull(currentText);
|
||||
} else if (equalsOrSuffix(qName, "item")) {
|
||||
if (userId != null && groupId != null)
|
||||
builder.userIdGroupPair(userId, groupId);
|
||||
builder.tenantIdGroupNamePair(userId, groupId);
|
||||
userId = groupId = null;
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.jclouds.ec2.domain.BlockDevice;
|
|||
import org.jclouds.ec2.domain.Image.EbsBlockDevice;
|
||||
import org.jclouds.ec2.domain.InstanceState;
|
||||
import org.jclouds.ec2.domain.InstanceType;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
|
||||
import org.jclouds.ec2.domain.Reservation;
|
||||
|
@ -49,6 +48,7 @@ import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
|||
import org.jclouds.ec2.predicates.InstanceHasIpAddress;
|
||||
import org.jclouds.ec2.predicates.InstanceStateRunning;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.jclouds.ec2.domain.Image.Architecture;
|
|||
import org.jclouds.ec2.domain.Image.ImageType;
|
||||
import org.jclouds.ec2.domain.InstanceState;
|
||||
import org.jclouds.ec2.domain.InstanceType;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.Reservation;
|
||||
import org.jclouds.ec2.domain.RootDeviceType;
|
||||
|
@ -58,6 +57,7 @@ import org.jclouds.ec2.predicates.VolumeAttached;
|
|||
import org.jclouds.ec2.predicates.VolumeAvailable;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.jclouds.ec2.EC2ApiMetadata;
|
|||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDevice;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
|
@ -51,6 +50,7 @@ import org.jclouds.ec2.services.ElasticBlockStoreClient;
|
|||
import org.jclouds.ec2.services.InstanceClient;
|
||||
import org.jclouds.ec2.services.KeyPairClient;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.jclouds.util.InetAddresses2;
|
||||
|
|
|
@ -0,0 +1,585 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.compute.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.internal.BaseEC2ComputeServiceExpectTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "EC2SecurityGroupExtensionExpectTest")
|
||||
public class EC2SecurityGroupExtensionExpectTest extends BaseEC2ComputeServiceExpectTest {
|
||||
|
||||
public void testListSecurityGroups() {
|
||||
HttpRequest describeSecurityGroupsAllRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsAllResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_new.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsAllRequest, describeSecurityGroupsAllResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(describeInstanceRequest, describeInstanceResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
Set<SecurityGroup> groups = extension.listSecurityGroups();
|
||||
assertEquals(2, groups.size());
|
||||
}
|
||||
|
||||
public void testListSecurityGroupsInLocation() {
|
||||
HttpRequest describeSecurityGroupsAllRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsAllResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_new.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsAllRequest, describeSecurityGroupsAllResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(describeInstanceRequest, describeInstanceResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
Set<SecurityGroup> groups = extension.listSecurityGroupsInLocation(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
assertEquals(2, groups.size());
|
||||
}
|
||||
|
||||
|
||||
public void testListSecurityGroupsForNode() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "sg-3c6ef654").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
HttpResponse describeInstanceWithSGResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_instances_running_securitygroups.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(describeInstanceRequest, describeInstanceWithSGResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
Set<SecurityGroup> groups = extension.listSecurityGroupsForNode(new RegionAndName(region, "i-2baa5550").slashEncode());
|
||||
assertEquals(1, groups.size());
|
||||
}
|
||||
|
||||
public void testGetSecurityGroupById() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroup group = extension.getSecurityGroupById(new RegionAndName(region, "jclouds#some-group").slashEncode());
|
||||
assertEquals("sg-3c6ef654", group.getProviderId());
|
||||
assertEquals("jclouds#some-group", group.getId());
|
||||
}
|
||||
|
||||
public void testCreateSecurityGroup() {
|
||||
HttpRequest createSecurityGroupExtRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "CreateSecurityGroup")
|
||||
.addFormParam("GroupDescription", "jclouds#some-group")
|
||||
.addFormParam("GroupName", "jclouds#some-group").build());
|
||||
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupExtRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroup group = extension.createSecurityGroup("some-group", new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
assertEquals("sg-3c6ef654", group.getProviderId());
|
||||
assertEquals("jclouds#some-group", group.getId());
|
||||
}
|
||||
|
||||
public void testRemoveSecurityGroup() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_single.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
HttpRequest deleteSecurityGroupRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DeleteSecurityGroup")
|
||||
.addFormParam("GroupName", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse deleteSecurityGroupResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/delete_securitygroup.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(deleteSecurityGroupRequest, deleteSecurityGroupResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse);
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
assertTrue(extension.removeSecurityGroup(new RegionAndName(region, "jclouds#some-group").slashEncode()));
|
||||
}
|
||||
|
||||
public void testAddIpPermissionCidrFromIpPermission() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestRange =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("CidrIp", "0.0.0.0/0")
|
||||
.addFormParam("FromPort", "22")
|
||||
.addFormParam("ToPort", "40")
|
||||
.addFormParam("GroupName", "jclouds#some-group")
|
||||
.addFormParam("IpProtocol", "tcp").build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(22);
|
||||
builder.toPort(40);
|
||||
builder.cidrBlock("0.0.0.0/0");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(1, newPerm.getCidrBlocks().size());
|
||||
assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
|
||||
}
|
||||
|
||||
public void testAddIpPermissionCidrFromParams() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestRange =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("CidrIp", "0.0.0.0/0")
|
||||
.addFormParam("FromPort", "22")
|
||||
.addFormParam("ToPort", "40")
|
||||
.addFormParam("GroupName", "jclouds#some-group")
|
||||
.addFormParam("IpProtocol", "tcp").build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
|
||||
22,
|
||||
40,
|
||||
emptyMultimap(),
|
||||
ImmutableSet.of("0.0.0.0/0"),
|
||||
emptyStringSet(),
|
||||
origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(1, newPerm.getCidrBlocks().size());
|
||||
assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
|
||||
}
|
||||
|
||||
|
||||
public void testAddIpPermissionGroupFromIpPermission() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("SourceSecurityGroupName", "jclouds#some-group")
|
||||
.addFormParam("SourceSecurityGroupOwnerId", "993194456877")
|
||||
.addFormParam("GroupName", "jclouds#some-group").build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(22);
|
||||
builder.toPort(40);
|
||||
builder.tenantIdGroupNamePair("993194456877", "jclouds#some-group");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
groupBuilder.ownerId("993194456877");
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(0, newPerm.getCidrBlocks().size());
|
||||
assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
|
||||
}
|
||||
|
||||
public void testAddIpPermissionGroupFromParams() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("SourceSecurityGroupName", "jclouds#some-group")
|
||||
.addFormParam("SourceSecurityGroupOwnerId", "993194456877")
|
||||
.addFormParam("GroupName", "jclouds#some-group").build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.ownerId("993194456877");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
ImmutableMultimap.Builder<String, String> permBuilder = ImmutableMultimap.builder();
|
||||
permBuilder.put(origGroup.getOwnerId(), origGroup.getName());
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
|
||||
22,
|
||||
40,
|
||||
permBuilder.build(),
|
||||
emptyStringSet(),
|
||||
emptyStringSet(),
|
||||
origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(0, newPerm.getCidrBlocks().size());
|
||||
assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
|
||||
}
|
||||
|
||||
private Multimap<String, String> emptyMultimap() {
|
||||
return LinkedHashMultimap.create();
|
||||
}
|
||||
|
||||
private Set<String> emptyStringSet() {
|
||||
return Sets.newLinkedHashSet();
|
||||
}
|
||||
}
|
|
@ -14,35 +14,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.domain;
|
||||
package org.jclouds.ec2.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
* Live test for ec2 {@link SecurityGroupExtension} implementation
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*
|
||||
*/
|
||||
public enum IpProtocol {
|
||||
@Test(groups = "live", singleThreaded = true, testName = "EC2SecurityGroupExtensionLiveTest")
|
||||
public class EC2SecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
TCP, UDP, ICMP, ALL, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return this == ALL ? "-1" : name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static IpProtocol fromValue(String protocol) {
|
||||
try {
|
||||
if (protocol.equalsIgnoreCase("-1"))
|
||||
return ALL;
|
||||
return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
public EC2SecurityGroupExtensionLiveTest() {
|
||||
provider = "ec2";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.ec2.compute.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.ec2.util.IpPermissions;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Test(groups = "unit", testName = "EC2SecurityGroupToSecurityGroupTest")
|
||||
public class EC2SecurityGroupToSecurityGroupTest {
|
||||
|
||||
static Location provider = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1")
|
||||
.description("us-east-1").build();
|
||||
|
||||
@Test
|
||||
public void testApply() {
|
||||
IpPermissions authorization = IpPermissions.permitAnyProtocol();
|
||||
|
||||
org.jclouds.ec2.domain.SecurityGroup origGroup = org.jclouds.ec2.domain.SecurityGroup.builder()
|
||||
.region("us-east-1")
|
||||
.id("some-id")
|
||||
.name("some-group")
|
||||
.ownerId("some-owner")
|
||||
.description("some-description")
|
||||
.ipPermission(authorization)
|
||||
.build();
|
||||
|
||||
EC2SecurityGroupToSecurityGroup parser = createGroupParser(ImmutableSet.of(provider));
|
||||
|
||||
SecurityGroup group = parser.apply(origGroup);
|
||||
|
||||
assertEquals(group.getLocation(), provider);
|
||||
assertEquals(group.getId(), origGroup.getName());
|
||||
assertEquals(group.getProviderId(), origGroup.getId());
|
||||
assertEquals(group.getName(), origGroup.getName());
|
||||
assertEquals(group.getIpPermissions(), (Set<IpPermission>)origGroup);
|
||||
assertEquals(group.getOwnerId(), origGroup.getOwnerId());
|
||||
}
|
||||
|
||||
private EC2SecurityGroupToSecurityGroup createGroupParser(final ImmutableSet<Location> locations) {
|
||||
Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() {
|
||||
|
||||
@Override
|
||||
public Set<? extends Location> get() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EC2SecurityGroupToSecurityGroup parser = new EC2SecurityGroupToSecurityGroup(locationSupplier);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
}
|
|
@ -29,10 +29,10 @@ import java.util.concurrent.ExecutionException;
|
|||
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
|
|
@ -22,12 +22,12 @@ import java.io.IOException;
|
|||
|
||||
import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@ import java.util.Set;
|
|||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||
import org.jclouds.ec2.EC2ApiMetadata;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -174,7 +174,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
|
|||
assertEventually(new GroupHasPermission(client, group2Name, new Predicate<IpPermission>() {
|
||||
@Override
|
||||
public boolean apply(IpPermission arg0) {
|
||||
return arg0.getUserIdGroupPairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name));
|
||||
return arg0.getTenantIdGroupNamePairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name));
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -191,7 +191,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe
|
|||
@Override
|
||||
public boolean apply(IpPermission arg0) {
|
||||
return arg0.getIpProtocol() == IpProtocol.TCP && arg0.getFromPort() == 80 && arg0.getToPort() == 80
|
||||
&& arg0.getIpRanges().equals(ImmutableSet.of("0.0.0.0/0"));
|
||||
&& arg0.getCidrBlocks().equals(ImmutableSet.of("0.0.0.0/0"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.jclouds.ec2.util;
|
|||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
|
|
@ -21,10 +21,10 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
@ -46,10 +46,10 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
|
|||
InputStream is = getClass().getResourceAsStream("/describe_securitygroups.xml");
|
||||
|
||||
Set<SecurityGroup> expected = ImmutableSet.of(
|
||||
new SecurityGroup(defaultRegion, null, "WebServers", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers",
|
||||
new SecurityGroup(defaultRegion, "sg-3c6ef654", "WebServers", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Web Servers",
|
||||
ImmutableSet.of(new IpPermission(IpProtocol.TCP, 80, 80, ImmutableMultimap.<String, String> of(),
|
||||
ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0")))),
|
||||
new SecurityGroup(defaultRegion, null, "RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Group A",
|
||||
new SecurityGroup(defaultRegion, "sg-867309ab", "RangedPortsBySource", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Group A",
|
||||
ImmutableSet.of(new IpPermission(IpProtocol.TCP, 6000, 7000, ImmutableMultimap
|
||||
.<String, String> of(), ImmutableSet.<String> of(), ImmutableSet.<String> of()))));
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class DescribeSecurityGroupsResponseHandlerTest extends BaseEC2HandlerTes
|
|||
userIdGroupPairs.put("UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "jclouds#cluster#world");
|
||||
|
||||
Set<SecurityGroup> expected = ImmutableSet.of(
|
||||
new SecurityGroup(defaultRegion, null, "jclouds#cluster#world", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Cluster",
|
||||
new SecurityGroup(defaultRegion, "sg-3c6ef654", "jclouds#cluster#world", "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", "Cluster",
|
||||
ImmutableSet.of(
|
||||
new IpPermission(IpProtocol.TCP, 22, 22, ImmutableMultimap.<String, String> of(),
|
||||
ImmutableSet.<String> of(), ImmutableSet.of("0.0.0.0/0")),
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<DeleteSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/2013-02-01/">
|
||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||
<return>true</return>
|
||||
</DeleteSecurityGroupResponse>
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2011-05-15/">
|
||||
<requestId>f6d3252e-35e5-4ef5-b2c5-62da95dd829b</requestId>
|
||||
<reservationSet>
|
||||
<item>
|
||||
<reservationId>r-205ad944</reservationId>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupSet>
|
||||
<item>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
</item>
|
||||
</groupSet>
|
||||
<instancesSet>
|
||||
<item>
|
||||
<instanceId>i-2baa5550</instanceId>
|
||||
<imageId>ami-aecd60c7</imageId>
|
||||
<instanceState>
|
||||
<code>16</code>
|
||||
<name>running</name>
|
||||
</instanceState>
|
||||
<privateDnsName>ip-10-28-89-195.ec2.internal</privateDnsName>
|
||||
<dnsName>ec2-50-16-1-166.compute-1.amazonaws.com</dnsName>
|
||||
<reason/>
|
||||
<keyName>jclouds#mygroup2#81</keyName>
|
||||
<amiLaunchIndex>0</amiLaunchIndex>
|
||||
<productCodes/>
|
||||
<instanceType>t1.micro</instanceType>
|
||||
<launchTime>2012-08-02T04:28:30.000Z</launchTime>
|
||||
<placement>
|
||||
<availabilityZone>us-east-1e</availabilityZone>
|
||||
<groupName/>
|
||||
<tenancy>default</tenancy>
|
||||
</placement>
|
||||
<kernelId>aki-88aa75e1</kernelId>
|
||||
<monitoring>
|
||||
<state>disabled</state>
|
||||
</monitoring>
|
||||
<privateIpAddress>10.28.89.195</privateIpAddress>
|
||||
<ipAddress>50.16.1.166</ipAddress>
|
||||
<groupSet>
|
||||
<item>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
</item>
|
||||
</groupSet>
|
||||
<architecture>x86_64</architecture>
|
||||
<rootDeviceType>ebs</rootDeviceType>
|
||||
<rootDeviceName>/dev/sda1</rootDeviceName>
|
||||
<blockDeviceMapping>
|
||||
<item>
|
||||
<deviceName>/dev/sda1</deviceName>
|
||||
<ebs>
|
||||
<volumeId>vol-f2d7c993</volumeId>
|
||||
<status>attached</status>
|
||||
<attachTime>2012-08-02T04:28:56.000Z</attachTime>
|
||||
<deleteOnTermination>true</deleteOnTermination>
|
||||
</ebs>
|
||||
</item>
|
||||
</blockDeviceMapping>
|
||||
<virtualizationType>paravirtual</virtualizationType>
|
||||
<clientToken/>
|
||||
<tagSet>
|
||||
<item>
|
||||
<key>Name</key>
|
||||
<value>mygroup2-2baa5550</value>
|
||||
</item>
|
||||
</tagSet>
|
||||
<hypervisor>xen</hypervisor>
|
||||
</item>
|
||||
</instancesSet>
|
||||
</item>
|
||||
</reservationSet>
|
||||
</DescribeInstancesResponse>
|
|
@ -3,6 +3,7 @@
|
|||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>WebServers</groupName>
|
||||
<groupDescription>Web Servers</groupDescription>
|
||||
<ipPermissions>
|
||||
|
@ -21,7 +22,8 @@
|
|||
</item>
|
||||
<item>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
<groupName>RangedPortsBySource</groupName>
|
||||
<groupId>sg-867309ab</groupId>
|
||||
<groupName>RangedPortsBySource</groupName>
|
||||
<groupDescription>Group A</groupDescription>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<ipRanges />
|
||||
<groups>
|
||||
<item>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>jclouds#cluster#world</groupName>
|
||||
<userId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</userId>
|
||||
</item>
|
||||
|
@ -31,6 +32,7 @@
|
|||
</item>
|
||||
</ipPermissions>
|
||||
<groupName>jclouds#cluster#world</groupName>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupDescription>Cluster</groupDescription>
|
||||
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
|
||||
</item>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<DescribeSecurityGroupsResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
<groupDescription>jclouds#some-group</groupDescription>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
<ipProtocol>tcp</ipProtocol>
|
||||
<fromPort>22</fromPort>
|
||||
<toPort>40</toPort>
|
||||
<groups />
|
||||
<ipRanges>
|
||||
<item>
|
||||
<cidrIp>0.0.0.0/0</cidrIp>
|
||||
</item>
|
||||
</ipRanges>
|
||||
</item>
|
||||
</ipPermissions>
|
||||
</item>
|
||||
</securityGroupInfo>
|
||||
</DescribeSecurityGroupsResponse>
|
|
@ -0,0 +1,26 @@
|
|||
<DescribeSecurityGroupsResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
<groupDescription>jclouds#some-group</groupDescription>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
<ipProtocol>tcp</ipProtocol>
|
||||
<fromPort>22</fromPort>
|
||||
<toPort>40</toPort>
|
||||
<groups>
|
||||
<item>
|
||||
<userId>993194456877</userId>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
</item>
|
||||
</groups>
|
||||
<ipRanges/>
|
||||
</item>
|
||||
</ipPermissions>
|
||||
</item>
|
||||
</securityGroupInfo>
|
||||
</DescribeSecurityGroupsResponse>
|
|
@ -0,0 +1,27 @@
|
|||
<DescribeSecurityGroupsResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
<groupDescription>jclouds#some-group</groupDescription>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<ipPermissions/>
|
||||
</item>
|
||||
<item>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupId>sg-3a2b3c4d</groupId>
|
||||
<groupName>group-a</groupName>
|
||||
<groupDescription>Group A</groupDescription>
|
||||
<ipPermissions>
|
||||
<item>
|
||||
<ipProtocol>tcp</ipProtocol>
|
||||
<fromPort>6000</fromPort>
|
||||
<toPort>7000</toPort>
|
||||
<groups />
|
||||
<ipRanges />
|
||||
</item>
|
||||
</ipPermissions>
|
||||
</item>
|
||||
</securityGroupInfo>
|
||||
</DescribeSecurityGroupsResponse>
|
|
@ -0,0 +1,12 @@
|
|||
<DescribeSecurityGroupsResponse
|
||||
xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||
<securityGroupInfo>
|
||||
<item>
|
||||
<ownerId>993194456877</ownerId>
|
||||
<groupName>jclouds#some-group</groupName>
|
||||
<groupDescription>jclouds#some-group</groupDescription>
|
||||
<groupId>sg-3c6ef654</groupId>
|
||||
<ipPermissions/>
|
||||
</item>
|
||||
</securityGroupInfo>
|
||||
</DescribeSecurityGroupsResponse>
|
|
@ -40,6 +40,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
|
@ -107,12 +108,13 @@ public class NovaComputeService extends BaseComputeService {
|
|||
LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap,
|
||||
LoadingCache<ZoneAndName, KeyPair> keyPairCache,
|
||||
Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId,
|
||||
GroupNamingConvention.Factory namingConvention, Optional<ImageExtension> imageExtension) {
|
||||
GroupNamingConvention.Factory namingConvention, Optional<ImageExtension> imageExtension,
|
||||
Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
|
||||
this.novaApi = checkNotNull(novaApi, "novaApi");
|
||||
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
|
||||
this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache");
|
||||
|
|
|
@ -38,12 +38,14 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeService;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
|
||||
|
@ -51,7 +53,9 @@ import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNe
|
|||
import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInZoneToHardware;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInZoneToImage;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByZoneId;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.SecurityGroupRuleToIpPermission;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInZoneToNodeMetadata;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.loaders.CreateUniqueKeyPair;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.loaders.FindSecurityGroupOrCreate;
|
||||
|
@ -60,6 +64,7 @@ import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
|
|||
import org.jclouds.openstack.nova.v2_0.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
|
||||
|
@ -108,6 +113,12 @@ public class NovaComputeServiceContextModule extends
|
|||
bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
|
||||
}).to(ServerInZoneToNodeMetadata.class);
|
||||
|
||||
bind(new TypeLiteral<Function<SecurityGroupRule, IpPermission>>() {
|
||||
}).to(SecurityGroupRuleToIpPermission.class);
|
||||
|
||||
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup>>() {
|
||||
}).to(NovaSecurityGroupToSecurityGroup.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
|
||||
}).to(OrphanedGroupsByZoneId.class);
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
|
||||
/**
|
||||
* A function for transforming a Nova-specific SecurityGroup into a generic
|
||||
* SecurityGroup object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Singleton
|
||||
public class NovaSecurityGroupToSecurityGroup implements Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected Function<SecurityGroupRule,IpPermission> ruleToPermission;
|
||||
|
||||
@Inject
|
||||
public NovaSecurityGroupToSecurityGroup(Function<SecurityGroupRule,IpPermission> ruleToPermission) {
|
||||
this.ruleToPermission = ruleToPermission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
|
||||
builder.id(group.getId());
|
||||
builder.providerId(group.getId());
|
||||
builder.ownerId(group.getTenantId());
|
||||
builder.name(group.getName());
|
||||
builder.ipPermissions(transform(group.getRules(), ruleToPermission));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
||||
/**
|
||||
* A function for transforming a nova-specific SecurityGroupRule into a generic
|
||||
* IpPermission object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class SecurityGroupRuleToIpPermission implements Function<SecurityGroupRule, IpPermission> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public SecurityGroupRuleToIpPermission() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpPermission apply(SecurityGroupRule rule) {
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
builder.ipProtocol(rule.getIpProtocol());
|
||||
builder.fromPort(rule.getFromPort());
|
||||
builder.toPort(rule.getToPort());
|
||||
if (rule.getGroup() != null)
|
||||
builder.tenantIdGroupNamePair(rule.getGroup().getTenantId(), rule.getGroup().getName());
|
||||
if (rule.getIpRange() != null)
|
||||
builder.cidrBlock(rule.getIpRange());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import java.beans.ConstructorProperties;
|
|||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.beans.ConstructorProperties;
|
|||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Test(groups = "unit", testName = "NovaSecurityGroupToSecurityGroupTest")
|
||||
public class NovaSecurityGroupToSecurityGroupTest {
|
||||
|
||||
private static final SecurityGroupRuleToIpPermission ruleConverter = new SecurityGroupRuleToIpPermission();
|
||||
|
||||
@Test
|
||||
public void testApplyWithGroup() {
|
||||
TenantIdAndName group = TenantIdAndName.builder().tenantId("tenant").name("name").build();
|
||||
|
||||
SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
|
||||
.id("some-id")
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(10)
|
||||
.toPort(20)
|
||||
.group(group)
|
||||
.parentGroupId("some-other-id")
|
||||
.build();
|
||||
|
||||
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
|
||||
.tenantId("tenant")
|
||||
.id("some-id")
|
||||
.name("some-group")
|
||||
.description("some-description")
|
||||
.rules(ruleToConvert)
|
||||
.build();
|
||||
|
||||
NovaSecurityGroupToSecurityGroup parser = createGroupParser();
|
||||
|
||||
SecurityGroup newGroup = parser.apply(origGroup);
|
||||
|
||||
assertEquals(newGroup.getId(), origGroup.getId());
|
||||
assertEquals(newGroup.getProviderId(), origGroup.getId());
|
||||
assertEquals(newGroup.getName(), origGroup.getName());
|
||||
assertEquals(newGroup.getOwnerId(), origGroup.getTenantId());
|
||||
assertEquals(newGroup.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getRules(), ruleConverter)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyWithCidr() {
|
||||
SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
|
||||
.id("some-id")
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(10)
|
||||
.toPort(20)
|
||||
.ipRange("0.0.0.0/0")
|
||||
.parentGroupId("some-other-id")
|
||||
.build();
|
||||
|
||||
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
|
||||
.tenantId("tenant")
|
||||
.id("some-id")
|
||||
.name("some-group")
|
||||
.description("some-description")
|
||||
.rules(ruleToConvert)
|
||||
.build();
|
||||
|
||||
NovaSecurityGroupToSecurityGroup parser = createGroupParser();
|
||||
|
||||
SecurityGroup group = parser.apply(origGroup);
|
||||
|
||||
assertEquals(group.getId(), origGroup.getId());
|
||||
assertEquals(group.getProviderId(), origGroup.getId());
|
||||
assertEquals(group.getName(), origGroup.getName());
|
||||
assertEquals(group.getOwnerId(), origGroup.getTenantId());
|
||||
assertEquals(group.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getRules(), ruleConverter)));
|
||||
}
|
||||
|
||||
private NovaSecurityGroupToSecurityGroup createGroupParser() {
|
||||
NovaSecurityGroupToSecurityGroup parser = new NovaSecurityGroupToSecurityGroup(ruleConverter);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the function for transforming a nova specific SecurityGroupRule into a generic
|
||||
* IpPermission object.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class SecurityGroupRuleToIpPermissionTest {
|
||||
|
||||
@Test
|
||||
public void testApplyWithGroup() {
|
||||
|
||||
TenantIdAndName group = TenantIdAndName.builder().tenantId("tenant").name("name").build();
|
||||
|
||||
SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
|
||||
.id("some-id")
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(10)
|
||||
.toPort(20)
|
||||
.group(group)
|
||||
.parentGroupId("some-other-id")
|
||||
.build();
|
||||
|
||||
SecurityGroupRuleToIpPermission converter = new SecurityGroupRuleToIpPermission();
|
||||
|
||||
IpPermission convertedPerm = converter.apply(ruleToConvert);
|
||||
|
||||
assertEquals(convertedPerm.getIpProtocol(), ruleToConvert.getIpProtocol());
|
||||
assertEquals(convertedPerm.getFromPort(), ruleToConvert.getFromPort());
|
||||
assertEquals(convertedPerm.getToPort(), ruleToConvert.getToPort());
|
||||
assertTrue(convertedPerm.getTenantIdGroupNamePairs().containsKey(group.getTenantId()));
|
||||
assertTrue(convertedPerm.getTenantIdGroupNamePairs().containsValue(group.getName()));
|
||||
assertTrue(convertedPerm.getCidrBlocks().size() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyWithCidr() {
|
||||
SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
|
||||
.id("some-id")
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(10)
|
||||
.toPort(20)
|
||||
.ipRange("0.0.0.0/0")
|
||||
.parentGroupId("some-other-id")
|
||||
.build();
|
||||
|
||||
SecurityGroupRuleToIpPermission converter = new SecurityGroupRuleToIpPermission();
|
||||
|
||||
IpPermission convertedPerm = converter.apply(ruleToConvert);
|
||||
|
||||
assertEquals(convertedPerm.getIpProtocol(), ruleToConvert.getIpProtocol());
|
||||
assertEquals(convertedPerm.getFromPort(), ruleToConvert.getFromPort());
|
||||
assertEquals(convertedPerm.getToPort(), ruleToConvert.getToPort());
|
||||
assertEquals(convertedPerm.getCidrBlocks(), ImmutableSet.of("0.0.0.0/0"));
|
||||
assertTrue(convertedPerm.getTenantIdGroupNamePairs().size() == 0);
|
||||
}
|
||||
}
|
|
@ -24,9 +24,9 @@ import java.net.URI;
|
|||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
|
||||
|
|
|
@ -20,8 +20,8 @@ import static org.testng.Assert.assertNotNull;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Ingress;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
|
||||
|
|
|
@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
|
|
|
@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.json.BaseSetParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
|
|
|
@ -23,8 +23,8 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
@ -84,12 +85,12 @@ public class TerremarkVCloudComputeService extends BaseComputeService {
|
|||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, CleanupOrphanKeys cleanupOrphanKeys,
|
||||
Optional<ImageExtension> imageExtension) {
|
||||
Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
|
||||
this.cleanupOrphanKeys = cleanupOrphanKeys;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
@ -383,5 +384,13 @@ public interface ComputeService {
|
|||
@Beta
|
||||
Optional<ImageExtension> getImageExtension();
|
||||
|
||||
/**
|
||||
* Returns the {@link SecurityGroupExtension} for this provider if it implements it.
|
||||
*
|
||||
* @return an optional of the {@link SecurityGroupExtension} or {@link Optional#absent()} if not
|
||||
* implemented
|
||||
*/
|
||||
@Beta
|
||||
Optional<SecurityGroupExtension> getSecurityGroupExtension();
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.jclouds.compute.domain.OsFamily;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
||||
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
|
||||
import org.jclouds.compute.functions.TemplateOptionsToStatement;
|
||||
|
@ -306,5 +307,11 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
|||
return Optional.absent();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i){
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,6 @@ package org.jclouds.compute.domain;
|
|||
*/
|
||||
public enum ComputeType {
|
||||
|
||||
NODE, IMAGE, HARDWARE;
|
||||
NODE, IMAGE, HARDWARE, SECURITYGROUP;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.ResourceMetadata;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Describes a security group containing a set of @{link IpPermission}s
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class SecurityGroup extends ComputeMetadataImpl {
|
||||
|
||||
private final Set<IpPermission> ipPermissions;
|
||||
private final String ownerId;
|
||||
|
||||
public SecurityGroup(String providerId, String name, String id, @Nullable Location location, URI uri,
|
||||
Map<String, String> userMetadata, Set<String> tags,
|
||||
Iterable<IpPermission> ipPermissions,
|
||||
@Nullable String ownerId) {
|
||||
super(ComputeType.SECURITYGROUP, providerId, name, id, location, uri, userMetadata, tags);
|
||||
this.ipPermissions = ImmutableSet.copyOf(checkNotNull(ipPermissions, "ipPermissions"));
|
||||
this.ownerId = ownerId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The set of @{link IpPermission}s for this security group
|
||||
*/
|
||||
public Set<IpPermission> getIpPermissions() {
|
||||
return ipPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the owner ID. Can be null.
|
||||
*/
|
||||
public String getOwnerId() {
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ToStringHelper string() {
|
||||
ToStringHelper helper = computeToStringPrefix();
|
||||
if (ipPermissions.size() > 0)
|
||||
helper.add("ipPermissions", ipPermissions);
|
||||
return addComputeToStringSuffix(helper);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class SecurityGroupBuilder extends ComputeMetadataBuilder {
|
||||
private ImmutableSet.Builder<IpPermission> ipPermissions = ImmutableSet.<IpPermission> builder();
|
||||
private String ownerId;
|
||||
|
||||
public SecurityGroupBuilder() {
|
||||
super(ComputeType.SECURITYGROUP);
|
||||
}
|
||||
|
||||
public SecurityGroupBuilder ipPermissions() {
|
||||
this.ipPermissions = ImmutableSet.<IpPermission> builder();
|
||||
return this;
|
||||
}
|
||||
|
||||
public SecurityGroupBuilder ipPermissions(Iterable<IpPermission> ipPermissions) {
|
||||
this.ipPermissions.addAll(checkNotNull(ipPermissions, "ipPermissions"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SecurityGroupBuilder ipPermission(IpPermission ipPermission) {
|
||||
this.ipPermissions.add(checkNotNull(ipPermission, "ipPermission"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SecurityGroupBuilder ownerId(String ownerId) {
|
||||
this.ownerId = ownerId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder id(String id) {
|
||||
return SecurityGroupBuilder.class.cast(super.id(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder tags(Iterable<String> tags) {
|
||||
return SecurityGroupBuilder.class.cast(super.tags(tags));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder ids(String id) {
|
||||
return SecurityGroupBuilder.class.cast(super.ids(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder providerId(String providerId) {
|
||||
return SecurityGroupBuilder.class.cast(super.providerId(providerId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder name(String name) {
|
||||
return SecurityGroupBuilder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder location(Location location) {
|
||||
return SecurityGroupBuilder.class.cast(super.location(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder uri(URI uri) {
|
||||
return SecurityGroupBuilder.class.cast(super.uri(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupBuilder userMetadata(Map<String, String> userMetadata) {
|
||||
return SecurityGroupBuilder.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup build() {
|
||||
return new SecurityGroup(providerId, name, id, location, uri, userMetadata, tags,
|
||||
ipPermissions.build(), ownerId);
|
||||
}
|
||||
|
||||
public static SecurityGroupBuilder fromSecurityGroup(SecurityGroup group) {
|
||||
return new SecurityGroupBuilder().providerId(group.getProviderId())
|
||||
.name(group.getName())
|
||||
.id(group.getId())
|
||||
.location(group.getLocation())
|
||||
.uri(group.getUri())
|
||||
.userMetadata(group.getUserMetadata())
|
||||
.tags(group.getTags())
|
||||
.ipPermissions(group.getIpPermissions())
|
||||
.ownerId(group.getOwnerId());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
|
||||
* is optional by providers.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public interface SecurityGroupExtension {
|
||||
|
||||
/**
|
||||
* List security groups.
|
||||
*
|
||||
* @return The set of @{link SecurityGroup}s we have access to.
|
||||
*/
|
||||
Set<SecurityGroup> listSecurityGroups();
|
||||
|
||||
/**
|
||||
* List security groups in a given @{link Location}.
|
||||
*
|
||||
* @return The set of @{link SecurityGroup}s we have access to in the given location.
|
||||
*/
|
||||
Set<SecurityGroup> listSecurityGroupsInLocation(Location location);
|
||||
|
||||
/**
|
||||
* List security groups for a given instance given the instance's ID.
|
||||
*
|
||||
* @return The set of @{link SecurityGroup}s for the given instance..
|
||||
*/
|
||||
Set<SecurityGroup> listSecurityGroupsForNode(String id);
|
||||
|
||||
/**
|
||||
* Get a security group by id.
|
||||
*
|
||||
* @return The @{link SecurityGroup}, if it exists.
|
||||
*/
|
||||
SecurityGroup getSecurityGroupById(String id);
|
||||
|
||||
/**
|
||||
* Create a new @{link SecurityGroup} from the parameters given.
|
||||
*
|
||||
* @param name
|
||||
* The name of the security group
|
||||
* @param location
|
||||
* The @{link Location} of the security group
|
||||
*
|
||||
* @return The SecurityGroup that has been created.
|
||||
*/
|
||||
SecurityGroup createSecurityGroup(String name, Location location);
|
||||
|
||||
/**
|
||||
* Remove an existing @{link SecurityGroup}, and its permissions.
|
||||
*
|
||||
* @param id
|
||||
* The id of the SecurityGroup to delete.
|
||||
*
|
||||
* @return true if we were able to remove the group, false otherwise.
|
||||
*/
|
||||
boolean removeSecurityGroup(String id);
|
||||
|
||||
/**
|
||||
* Add a @{link IpPermission} to an existing @{link SecurityGroup}. Applies the permission to the
|
||||
* security group on the provider.
|
||||
*
|
||||
* @param rule
|
||||
* The IpPermission to add.
|
||||
* @param group
|
||||
* The SecurityGroup to add the permission to.
|
||||
*
|
||||
* @return The SecurityGroup with the new permission added, after the permission has been applied on the provider.
|
||||
*/
|
||||
SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group);
|
||||
|
||||
/**
|
||||
* Remove a @{link IpPermission} from an existing @{link SecurityGroup}. Removes the permission from the
|
||||
* security group on the provider.
|
||||
*
|
||||
* @param rule
|
||||
* The IpPermission to remove.
|
||||
* @param group
|
||||
* The SecurityGroup to remove the permission from.
|
||||
*
|
||||
* @return The SecurityGroup with the permission removed, after the permission has been removed on the provider.
|
||||
*/
|
||||
SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group);
|
||||
|
||||
/**
|
||||
* Add a @{link IpPermission} to an existing @{link SecurityGroup}, based on the parameters given.
|
||||
* Applies the permission to the security group on the provider.
|
||||
*
|
||||
* @param protocol
|
||||
* The @{link IpProtocol} for the permission.
|
||||
* @param startPort
|
||||
* The first port in the range to be opened, or -1 for ICMP.
|
||||
* @param endPort
|
||||
* The last port in the range to be opened, or -1 for ICMP.
|
||||
* @param tenantIdGroupNamePairs
|
||||
* source of traffic allowed is on basis of another group in a tenant, as opposed to by cidr
|
||||
* @param ipRanges
|
||||
* An Iterable of Strings representing the IP range(s) the permission should allow.
|
||||
* @param groupIds
|
||||
* An Iterable of @{link SecurityGroup} IDs this permission should allow.
|
||||
* @param group
|
||||
* The SecurityGroup to add the permission to.
|
||||
*
|
||||
* @return The SecurityGroup with the new permission added, after the permission has been applied on the provider.
|
||||
*/
|
||||
SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group);
|
||||
|
||||
/**
|
||||
* Remove a @{link IpPermission} from an existing @{link SecurityGroup}, based on the parameters given.
|
||||
* Removes the permission from the security group on the provider.
|
||||
*
|
||||
* @param protocol
|
||||
* The @{link IpProtocol} for the permission.
|
||||
* @param startPort
|
||||
* The first port in the range to be opened, or -1 for ICMP.
|
||||
* @param endPort
|
||||
* The last port in the range to be opened, or -1 for ICMP.
|
||||
* @param tenantIdGroupNamePairs
|
||||
* source of traffic allowed is on basis of another group in a tenant, as opposed to by cidr
|
||||
* @param ipRanges
|
||||
* An Iterable of Strings representing the IP range(s) the permission should allow.
|
||||
* @param groupIds
|
||||
* An Iterable of @{link SecurityGroup} IDs this permission should allow.
|
||||
* @param group
|
||||
* The SecurityGroup to remove the permission from.
|
||||
*
|
||||
* @return The SecurityGroup with the permission removed, after the permission has been removed from the provider.
|
||||
*/
|
||||
SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group);
|
||||
|
||||
/**
|
||||
* Returns true if this SecurityGroupExtension supports tenant ID + group name pairs.
|
||||
*/
|
||||
boolean supportsTenantIdGroupNamePairs();
|
||||
|
||||
/**
|
||||
* Returns true if this SecurityGroupExtension supports group IDs.
|
||||
*/
|
||||
boolean supportsGroupIds();
|
||||
|
||||
/**
|
||||
* Returns true if this SecurityGroupExtension supports port ranges for group authorization.
|
||||
*/
|
||||
boolean supportsPortRangesForGroups();
|
||||
|
||||
}
|
|
@ -66,6 +66,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
|
@ -141,6 +142,7 @@ public class BaseComputeService implements ComputeService {
|
|||
private final RunScriptOnNode.Factory runScriptOnNodeFactory;
|
||||
private final ListeningExecutorService userExecutor;
|
||||
private final Optional<ImageExtension> imageExtension;
|
||||
private final Optional<SecurityGroupExtension> securityGroupExtension;
|
||||
|
||||
@Inject
|
||||
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
|
@ -158,7 +160,7 @@ public class BaseComputeService implements ComputeService {
|
|||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
|
||||
Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
Optional<ImageExtension> imageExtension) {
|
||||
Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
this.images = checkNotNull(images, "images");
|
||||
|
@ -184,6 +186,7 @@ public class BaseComputeService implements ComputeService {
|
|||
this.persistNodeCredentials = checkNotNull(persistNodeCredentials, "persistNodeCredentials");
|
||||
this.userExecutor = checkNotNull(userExecutor, "userExecutor");
|
||||
this.imageExtension = checkNotNull(imageExtension, "imageExtension");
|
||||
this.securityGroupExtension = checkNotNull(securityGroupExtension, "securityGroupExtension");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -714,4 +717,11 @@ public class BaseComputeService implements ComputeService {
|
|||
return imageExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Optional<SecurityGroupExtension> getSecurityGroupExtension() {
|
||||
return securityGroupExtension;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
to.inboundPorts(this.getInboundPorts());
|
||||
if (this.getRunScript() != null)
|
||||
to.runScript(this.getRunScript());
|
||||
if (this.getGroups().size() > 0)
|
||||
to.securityGroups(this.getGroups());
|
||||
if (this.getPrivateKey() != null)
|
||||
to.installPrivateKey(this.getPrivateKey());
|
||||
if (this.getPublicKey() != null)
|
||||
|
@ -294,6 +296,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
throw new IllegalArgumentException("tags are immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getGroups() {
|
||||
return delegate.getGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions securityGroups(Iterable<String> securityGroups) {
|
||||
throw new IllegalArgumentException("tags are immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions securityGroups(String... securityGroups) {
|
||||
throw new IllegalArgumentException("tags are immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
throw new IllegalArgumentException("userMetadata is immutable");
|
||||
|
@ -321,6 +338,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
|
||||
protected Set<String> tags = ImmutableSet.of();
|
||||
|
||||
protected Set<String> securityGroups = ImmutableSet.of();
|
||||
|
||||
protected String privateKey;
|
||||
|
||||
protected String publicKey;
|
||||
|
@ -339,13 +358,13 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return super.equals(that) && equal(this.inboundPorts, that.inboundPorts) && equal(this.script, that.script)
|
||||
&& equal(this.publicKey, that.publicKey) && equal(this.privateKey, that.privateKey)
|
||||
&& equal(this.blockUntilRunning, that.blockUntilRunning) && equal(this.tags, that.tags)
|
||||
&& equal(this.userMetadata, that.userMetadata);
|
||||
&& equal(this.securityGroups, that.securityGroups) && equal(this.userMetadata, that.userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(), inboundPorts, script, publicKey, privateKey, blockUntilRunning, tags,
|
||||
userMetadata);
|
||||
securityGroups, userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -363,6 +382,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
toString.add("blockUntilRunning", blockUntilRunning);
|
||||
if (tags.size() != 0)
|
||||
toString.add("tags", tags);
|
||||
if (securityGroups.size() != 0)
|
||||
toString.add("securityGroups", securityGroups);
|
||||
if (userMetadata.size() != 0)
|
||||
toString.add("userMetadata", userMetadata);
|
||||
return toString;
|
||||
|
@ -380,6 +401,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return tags;
|
||||
}
|
||||
|
||||
public Set<String> getGroups() {
|
||||
return securityGroups;
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
@ -450,6 +475,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* assigns the created nodes to these security groups
|
||||
*/
|
||||
public TemplateOptions securityGroups(Iterable<String> securityGroups) {
|
||||
this.securityGroups = ImmutableSet.copyOf(checkNotNull(securityGroups, "securityGroups"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#securityGroups(Iterable<String>)
|
||||
*/
|
||||
public TemplateOptions securityGroups(String... securityGroups) {
|
||||
return securityGroups(ImmutableSet.copyOf(securityGroups));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the set of ports to public access.
|
||||
*/
|
||||
|
@ -521,6 +561,22 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return options.tags(tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#securityGroups
|
||||
*/
|
||||
public static TemplateOptions securityGroups(Iterable<String> securityGroups) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.securityGroups(securityGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#securityGroups
|
||||
*/
|
||||
public static TemplateOptions securityGroups(String... securityGroups) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.securityGroups(securityGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#blockUntilRunning(boolean)
|
||||
*/
|
||||
|
|
|
@ -41,13 +41,18 @@ import org.jclouds.compute.domain.NodeMetadata.Status;
|
|||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.predicates.ImagePredicates;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.location.suppliers.all.JustProvider;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -55,6 +60,7 @@ import com.google.common.collect.ImmutableList.Builder;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
|
||||
|
@ -66,20 +72,25 @@ import com.google.common.util.concurrent.ListeningExecutorService;
|
|||
public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
|
||||
private final Supplier<Location> location;
|
||||
private final ConcurrentMap<String, NodeMetadata> nodes;
|
||||
private final Multimap<String, SecurityGroup> groupsForNodes;
|
||||
private final ListeningExecutorService ioExecutor;
|
||||
private final Provider<Integer> idProvider;
|
||||
private final Provider<Integer> groupIdProvider;
|
||||
private final String publicIpPrefix;
|
||||
private final String privateIpPrefix;
|
||||
private final String passwordPrefix;
|
||||
private final Supplier<Set<? extends Location>> locationSupplier;
|
||||
private final Map<OsFamily, Map<String, String>> osToVersionMap;
|
||||
private final Optional<SecurityGroupExtension> securityGroupExtension;
|
||||
|
||||
@Inject
|
||||
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes,
|
||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, Supplier<Location> location,
|
||||
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
||||
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
|
||||
JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap) {
|
||||
JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap,
|
||||
Multimap<String, SecurityGroup> groupsForNodes, @Named("GROUP_ID") Provider<Integer> groupIdProvider,
|
||||
Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
this.nodes = nodes;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.location = location;
|
||||
|
@ -89,6 +100,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
this.passwordPrefix = passwordPrefix;
|
||||
this.locationSupplier = locationSupplier;
|
||||
this.osToVersionMap = osToVersionMap;
|
||||
this.groupsForNodes = groupsForNodes;
|
||||
this.groupIdProvider = groupIdProvider;
|
||||
this.securityGroupExtension = securityGroupExtension;
|
||||
}
|
||||
|
||||
protected void setStateOnNode(Status status, NodeMetadata node) {
|
||||
|
@ -133,6 +147,22 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
builder.credentials(LoginCredentials.builder().user("root").password(passwordPrefix + id).build());
|
||||
NodeMetadata node = builder.build();
|
||||
nodes.put(node.getId(), node);
|
||||
|
||||
if (template.getOptions().getGroups().size() > 0) {
|
||||
final String groupId = Iterables.getFirst(template.getOptions().getGroups(), "0");
|
||||
Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroups(),
|
||||
new Predicate<SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(SecurityGroup input) {
|
||||
return input.getId().equals(groupId);
|
||||
}
|
||||
});
|
||||
|
||||
if (secGroup.isPresent()) {
|
||||
groupsForNodes.put(node.getId(), secGroup.get());
|
||||
}
|
||||
}
|
||||
|
||||
setStateOnNodeAfterDelay(Status.RUNNING, node, 100);
|
||||
return new NodeWithInitialCredentials(node);
|
||||
}
|
||||
|
@ -195,6 +225,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
return;
|
||||
setStateOnNodeAfterDelay(Status.PENDING, node, 0);
|
||||
setStateOnNodeAfterDelay(Status.TERMINATED, node, 50);
|
||||
groupsForNodes.removeAll(id);
|
||||
|
||||
ioExecutor.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
package org.jclouds.compute.stub.config;
|
||||
|
||||
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.concurrent.SingleThreaded;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -35,4 +39,10 @@ public class StubComputeServiceContextModule extends JCloudsNativeComputeService
|
|||
install(new StubComputeServiceDependenciesModule());
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
|
||||
return Optional.of(i.getInstance(SecurityGroupExtension.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,8 +29,11 @@ import org.jclouds.compute.domain.Hardware;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadata.Status;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.Volume;
|
||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.stub.extensions.StubSecurityGroupExtension;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
|
@ -40,9 +43,12 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -52,6 +58,8 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {
|
||||
}).to(StubSecurityGroupExtension.class);
|
||||
|
||||
}
|
||||
|
||||
|
@ -73,6 +81,40 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
|
|||
return backing.get(creds.get().identity);
|
||||
}
|
||||
|
||||
protected static final LoadingCache<String, ConcurrentMap<String, SecurityGroup>> groupBacking = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<String, ConcurrentMap<String, SecurityGroup>>() {
|
||||
|
||||
@Override
|
||||
public ConcurrentMap<String, SecurityGroup> load(String arg0) throws Exception {
|
||||
return new ConcurrentHashMap<String, SecurityGroup>();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected ConcurrentMap<String, SecurityGroup> provideGroups(@Provider Supplier<Credentials> creds)
|
||||
throws ExecutionException {
|
||||
return groupBacking.get(creds.get().identity);
|
||||
}
|
||||
|
||||
protected static final LoadingCache<String, Multimap<String, SecurityGroup>> groupsForNodeBacking = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<String, Multimap<String, SecurityGroup>>() {
|
||||
|
||||
@Override
|
||||
public Multimap<String, SecurityGroup> load(String arg0) throws Exception {
|
||||
return LinkedHashMultimap.create();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Multimap<String, SecurityGroup> provideGroupsForNode(@Provider Supplier<Credentials> creds)
|
||||
throws ExecutionException {
|
||||
return groupsForNodeBacking.get(creds.get().identity);
|
||||
}
|
||||
|
||||
protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<String, AtomicInteger>() {
|
||||
|
||||
|
@ -89,6 +131,22 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
|
|||
return nodeIds.get(creds.get().identity).incrementAndGet();
|
||||
}
|
||||
|
||||
protected static final LoadingCache<String, AtomicInteger> groupIds = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<String, AtomicInteger>() {
|
||||
|
||||
@Override
|
||||
public AtomicInteger load(String arg0) throws Exception {
|
||||
return new AtomicInteger(0);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Provides
|
||||
@Named("GROUP_ID")
|
||||
protected Integer provideGroupIdForIdentity(@Provider Supplier<Credentials> creds) throws ExecutionException {
|
||||
return groupIds.get(creds.get().identity).incrementAndGet();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
@Named("PUBLIC_IP_PREFIX")
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.stub.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.location.suppliers.all.JustProvider;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
|
||||
/**
|
||||
* An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
|
||||
* is optional by providers.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class StubSecurityGroupExtension implements SecurityGroupExtension {
|
||||
|
||||
private final Supplier<Location> location;
|
||||
private final Provider<Integer> groupIdProvider;
|
||||
private final Supplier<Set<? extends Location>> locationSupplier;
|
||||
private final ListeningExecutorService ioExecutor;
|
||||
private final ConcurrentMap<String, SecurityGroup> groups;
|
||||
private final Multimap<String, SecurityGroup> groupsForNodes;
|
||||
|
||||
@Inject
|
||||
public StubSecurityGroupExtension(ConcurrentMap<String, SecurityGroup> groups,
|
||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
||||
Supplier<Location> location,
|
||||
@Named("GROUP_ID") Provider<Integer> groupIdProvider,
|
||||
JustProvider locationSupplier,
|
||||
Multimap<String, SecurityGroup> groupsForNodes) {
|
||||
this.groups = groups;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.location = location;
|
||||
this.groupIdProvider = groupIdProvider;
|
||||
this.locationSupplier = locationSupplier;
|
||||
this.groupsForNodes = groupsForNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroups() {
|
||||
return ImmutableSet.copyOf(groups.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
|
||||
return ImmutableSet.copyOf(filter(groups.values(), new Predicate<SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(SecurityGroup group) {
|
||||
return group.getLocation().equals(location);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsForNode(String nodeId) {
|
||||
return ImmutableSet.copyOf(groupsForNodes.get(nodeId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup getSecurityGroupById(String id) {
|
||||
return groups.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup createSecurityGroup(String name, Location location) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
|
||||
String id = groupIdProvider.get() + "";
|
||||
builder.ids(id);
|
||||
builder.name(name);
|
||||
builder.location(location);
|
||||
|
||||
SecurityGroup group = builder.build();
|
||||
|
||||
groups.put(group.getId(), group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSecurityGroup(String id) {
|
||||
if (groups.containsKey(id)) {
|
||||
groups.remove(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group"));
|
||||
|
||||
builder.ipPermission(checkNotNull(ipPermission, "ipPermission"));
|
||||
|
||||
SecurityGroup newGroup = builder.build();
|
||||
|
||||
if (groups.containsKey(newGroup.getId())) {
|
||||
groups.remove(newGroup.getId());
|
||||
}
|
||||
|
||||
groups.put(newGroup.getId(), newGroup);
|
||||
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
IpPermission.Builder ipBuilder = IpPermission.builder();
|
||||
|
||||
ipBuilder.ipProtocol(protocol);
|
||||
ipBuilder.fromPort(startPort);
|
||||
ipBuilder.toPort(endPort);
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
ipBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
|
||||
}
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
ipBuilder.cidrBlocks(ipRanges);
|
||||
}
|
||||
if (Iterables.size(groupIds) > 0) {
|
||||
ipBuilder.groupIds(groupIds);
|
||||
}
|
||||
|
||||
IpPermission perm = ipBuilder.build();
|
||||
|
||||
SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group"));
|
||||
|
||||
builder.ipPermission(perm);
|
||||
|
||||
SecurityGroup newGroup = builder.build();
|
||||
|
||||
if (groups.containsKey(newGroup.getId())) {
|
||||
groups.remove(newGroup.getId());
|
||||
}
|
||||
|
||||
groups.put(newGroup.getId(), newGroup);
|
||||
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group"));
|
||||
|
||||
builder.ipPermissions();
|
||||
|
||||
builder.ipPermissions(filter(group.getIpPermissions(), not(equalTo(ipPermission))));
|
||||
|
||||
SecurityGroup newGroup = builder.build();
|
||||
|
||||
if (groups.containsKey(newGroup.getId())) {
|
||||
groups.remove(newGroup.getId());
|
||||
}
|
||||
|
||||
groups.put(newGroup.getId(), newGroup);
|
||||
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
IpPermission.Builder ipBuilder = IpPermission.builder();
|
||||
|
||||
ipBuilder.ipProtocol(protocol);
|
||||
ipBuilder.fromPort(startPort);
|
||||
ipBuilder.toPort(endPort);
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
ipBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
|
||||
}
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
ipBuilder.cidrBlocks(ipRanges);
|
||||
}
|
||||
if (Iterables.size(groupIds) > 0) {
|
||||
ipBuilder.groupIds(groupIds);
|
||||
}
|
||||
|
||||
IpPermission perm = ipBuilder.build();
|
||||
|
||||
SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(checkNotNull(group, "group"));
|
||||
|
||||
builder.ipPermissions();
|
||||
|
||||
builder.ipPermissions(filter(group.getIpPermissions(), not(equalTo(perm))));
|
||||
|
||||
SecurityGroup newGroup = builder.build();
|
||||
|
||||
if (groups.containsKey(newGroup.getId())) {
|
||||
groups.remove(newGroup.getId());
|
||||
}
|
||||
|
||||
groups.put(newGroup.getId(), newGroup);
|
||||
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTenantIdGroupNamePairs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPortRangesForGroups() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -17,11 +17,15 @@
|
|||
package org.jclouds.net.domain;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.util.Strings2.isCidrFormat;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
@ -100,6 +104,7 @@ public class IpPermission implements Comparable<IpPermission> {
|
|||
* @see IpPermission#getCidrBlocks()
|
||||
*/
|
||||
public Builder cidrBlock(String cidrBlock) {
|
||||
checkArgument(isCidrFormat(cidrBlock), "cidrBlock %s is not a valid CIDR", cidrBlock);
|
||||
this.cidrBlocks.add(cidrBlock);
|
||||
return this;
|
||||
}
|
||||
|
@ -108,7 +113,16 @@ public class IpPermission implements Comparable<IpPermission> {
|
|||
* @see IpPermission#getCidrBlocks()
|
||||
*/
|
||||
public Builder cidrBlocks(Iterable<String> cidrBlocks) {
|
||||
Iterables.addAll(this.cidrBlocks, cidrBlocks);
|
||||
Iterables.addAll(this.cidrBlocks, transform(cidrBlocks,
|
||||
new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(String input) {
|
||||
checkArgument(isCidrFormat(input),
|
||||
"input %s is not a valid CIDR",
|
||||
input);
|
||||
return input;
|
||||
}
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -140,7 +154,7 @@ public class IpPermission implements Comparable<IpPermission> {
|
|||
private final IpProtocol ipProtocol;
|
||||
private final Set<String> cidrBlocks;
|
||||
|
||||
protected IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
|
||||
public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks) {
|
||||
this.fromPort = fromPort;
|
||||
this.toPort = toPort;
|
||||
|
@ -227,8 +241,8 @@ public class IpPermission implements Comparable<IpPermission> {
|
|||
|
||||
protected ToStringHelper string() {
|
||||
return Objects.toStringHelper("").add("ipProtocol", ipProtocol).add("fromPort", fromPort).add("toPort", toPort)
|
||||
.add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds).add("groupIds",
|
||||
groupIds);
|
||||
.add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds).add("cidrBlocks",
|
||||
cidrBlocks);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,12 +29,22 @@ public enum IpProtocol {
|
|||
|
||||
TCP, UDP, ICMP, ALL, UNRECOGNIZED;
|
||||
|
||||
public String value() {
|
||||
return this == ALL ? "-1" : name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static IpProtocol fromValue(String protocol) {
|
||||
try {
|
||||
if (protocol.equalsIgnoreCase("-1"))
|
||||
return ALL;
|
||||
return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.extensions.internal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
|
||||
/**
|
||||
* Base test for {@link SecurityGroupExtension} implementations.
|
||||
*
|
||||
* @author David Alves
|
||||
*
|
||||
*/
|
||||
public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServiceContextLiveTest {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected String groupId;
|
||||
|
||||
/**
|
||||
* Returns the template for the base node, override to test different templates.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Template getNodeTemplate() {
|
||||
return view.getComputeService().templateBuilder().build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true)
|
||||
public void testCreateSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Location location = getNodeTemplate().getLocation();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
|
||||
assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
|
||||
|
||||
SecurityGroup group = securityGroupExtension.get().createSecurityGroup("test-create-security-group", location);
|
||||
|
||||
logger.info("Group created: %s", group);
|
||||
|
||||
assertTrue(group.getName().contains("test-create-security-group"));
|
||||
|
||||
groupId = group.getId();
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testCreateSecurityGroup")
|
||||
public void testGetSecurityGroupById() throws RunNodesException, InterruptedException, ExecutionException {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Location location = getNodeTemplate().getLocation();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
|
||||
assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
|
||||
|
||||
SecurityGroup group = securityGroupExtension.get().getSecurityGroupById(groupId);
|
||||
|
||||
logger.info("Group found: %s", group);
|
||||
|
||||
assertTrue(group.getName().contains("test-create-security-group"));
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testGetSecurityGroupById")
|
||||
public void testAddIpPermission() {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
|
||||
|
||||
Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
|
||||
|
||||
assertTrue(optGroup.isPresent());
|
||||
|
||||
SecurityGroup group = optGroup.get();
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(10);
|
||||
builder.toPort(20);
|
||||
builder.cidrBlock("0.0.0.0/0");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroup newGroup = securityGroupExtension.get().addIpPermission(perm, group);
|
||||
|
||||
assertEquals(perm, Iterables.getOnlyElement(newGroup.getIpPermissions()));
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermission")
|
||||
public void testRemoveIpPermission() {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
|
||||
|
||||
Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
|
||||
|
||||
assertTrue(optGroup.isPresent());
|
||||
|
||||
SecurityGroup group = optGroup.get();
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(10);
|
||||
builder.toPort(20);
|
||||
builder.cidrBlock("0.0.0.0/0");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroup newGroup = securityGroupExtension.get().removeIpPermission(perm, group);
|
||||
|
||||
assertEquals(0, Iterables.size(newGroup.getIpPermissions()));
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testRemoveIpPermission")
|
||||
public void testAddIpPermissionsFromSpec() {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
|
||||
|
||||
Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
|
||||
|
||||
assertTrue(optGroup.isPresent());
|
||||
|
||||
SecurityGroup group = optGroup.get();
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(50);
|
||||
builder.toPort(60);
|
||||
builder.cidrBlock("0.0.0.0/0");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroup newGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
|
||||
50,
|
||||
60,
|
||||
emptyMultimap(),
|
||||
ImmutableSet.of("0.0.0.0/0"),
|
||||
emptyStringSet(),
|
||||
group);
|
||||
|
||||
assertTrue(newGroup.getIpPermissions().contains(perm));
|
||||
|
||||
if (securityGroupExtension.get().supportsGroupIds()) {
|
||||
IpPermission.Builder secondBuilder = IpPermission.builder();
|
||||
|
||||
int fromPort;
|
||||
int toPort;
|
||||
|
||||
if (securityGroupExtension.get().supportsPortRangesForGroups()) {
|
||||
fromPort = 70;
|
||||
toPort = 80;
|
||||
} else {
|
||||
fromPort = 1;
|
||||
toPort = 65535;
|
||||
}
|
||||
secondBuilder.ipProtocol(IpProtocol.TCP);
|
||||
secondBuilder.fromPort(fromPort);
|
||||
secondBuilder.toPort(toPort);
|
||||
secondBuilder.groupId(group.getId());
|
||||
|
||||
IpPermission secondPerm = secondBuilder.build();
|
||||
|
||||
SecurityGroup secondNewGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
|
||||
fromPort,
|
||||
toPort,
|
||||
emptyMultimap(),
|
||||
emptyStringSet(),
|
||||
ImmutableSet.of(group.getId()),
|
||||
newGroup);
|
||||
|
||||
assertTrue(secondNewGroup.getIpPermissions().contains(secondPerm));
|
||||
}
|
||||
|
||||
if (securityGroupExtension.get().supportsTenantIdGroupNamePairs()) {
|
||||
IpPermission.Builder thirdBuilder = IpPermission.builder();
|
||||
|
||||
int fromPort;
|
||||
int toPort;
|
||||
|
||||
if (securityGroupExtension.get().supportsPortRangesForGroups()) {
|
||||
fromPort = 90;
|
||||
toPort = 100;
|
||||
} else {
|
||||
fromPort = 1;
|
||||
toPort = 65535;
|
||||
}
|
||||
thirdBuilder.ipProtocol(IpProtocol.TCP);
|
||||
thirdBuilder.fromPort(fromPort);
|
||||
thirdBuilder.toPort(toPort);
|
||||
thirdBuilder.tenantIdGroupNamePair(group.getOwnerId(), group.getId());
|
||||
|
||||
IpPermission thirdPerm = thirdBuilder.build();
|
||||
|
||||
SecurityGroup thirdNewGroup = securityGroupExtension.get().addIpPermission(IpProtocol.TCP,
|
||||
fromPort,
|
||||
toPort,
|
||||
thirdPerm.getTenantIdGroupNamePairs(),
|
||||
emptyStringSet(),
|
||||
emptyStringSet(),
|
||||
newGroup);
|
||||
|
||||
assertTrue(thirdNewGroup.getIpPermissions().contains(thirdPerm));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionsFromSpec")
|
||||
public void testCreateNodeWithSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
|
||||
assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
|
||||
|
||||
Template template = view.getComputeService().templateBuilder()
|
||||
.options(TemplateOptions.Builder.securityGroups(groupId))
|
||||
.build();
|
||||
|
||||
NodeMetadata node = Iterables.getOnlyElement(computeService.createNodesInGroup("test-create-node-with-group", 1, template));
|
||||
|
||||
Set<SecurityGroup> groups = securityGroupExtension.get().listSecurityGroupsForNode(node.getId());
|
||||
|
||||
assertTrue(groups.size() > 0, "node has no groups");
|
||||
|
||||
Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroupsForNode(node.getId()),
|
||||
new Predicate<SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(SecurityGroup input) {
|
||||
return input.getId().equals(groupId);
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(secGroup.isPresent());
|
||||
|
||||
computeService.destroyNodesMatching(inGroup(node.getGroup()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
// testDeleteSecurityGroup currently disabled until I can find a way to get it to delete the security group while a terminated
|
||||
// instance is still floating around in EC2. - abayer, 6/14/13
|
||||
/*
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testCreateNodeWithSecurityGroup")
|
||||
public void testDeleteSecurityGroup() {
|
||||
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
|
||||
|
||||
Optional<SecurityGroup> optGroup = getGroup(securityGroupExtension.get());
|
||||
|
||||
assertTrue(optGroup.isPresent());
|
||||
|
||||
SecurityGroup group = optGroup.get();
|
||||
|
||||
assertTrue(securityGroupExtension.get().removeSecurityGroup(group.getId()));
|
||||
}
|
||||
*/
|
||||
|
||||
private Multimap<String, String> emptyMultimap() {
|
||||
return LinkedHashMultimap.create();
|
||||
}
|
||||
|
||||
private Set<String> emptyStringSet() {
|
||||
return Sets.newLinkedHashSet();
|
||||
}
|
||||
|
||||
private Optional<SecurityGroup> getGroup(SecurityGroupExtension ext) {
|
||||
return Iterables.tryFind(ext.listSecurityGroups(), new Predicate<SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(SecurityGroup input) {
|
||||
return input.getId().equals(groupId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.compute.extensions.internal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
|
||||
/**
|
||||
* Base test for {@link SecurityGroupExtension} implementations.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true, testName="StubSecurityGroupExtensionIntegrationTest")
|
||||
public class StubSecurityGroupExtensionIntegrationTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
public StubSecurityGroupExtensionIntegrationTest() {
|
||||
provider = "stub";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = super.setupProperties();
|
||||
// This is a hack to make sure we get a different set of node IDs, nodes, groups, etc from StubComputeServiceIntegrationTest.
|
||||
overrides.setProperty(provider + ".identity", "sec-stub");
|
||||
|
||||
return overrides;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,20 @@ public class IpPermissionsTest {
|
|||
.cidrBlock("0.0.0.0/0").build());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testAllProtocolInvalidCidr() {
|
||||
IpPermissions authorization = IpPermissions.permitAnyProtocol();
|
||||
assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
|
||||
.cidrBlock("a.0.0.0/0").build());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testAllProtocolInvalidCidrMultiple() {
|
||||
IpPermissions authorization = IpPermissions.permitAnyProtocol();
|
||||
assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
|
||||
.cidrBlocks(ImmutableSet.of("a.0.0.0/0", "0.0.0.0/0")).build());
|
||||
}
|
||||
|
||||
public void testAllProtocolCidrBound() {
|
||||
IpPermissions authorization = IpPermissions.permit(IpProtocol.ALL).originatingFromCidrBlock("1.1.1.1/32");
|
||||
assertEquals(authorization, IpPermission.builder().ipProtocol(IpProtocol.ALL).fromPort(1).toPort(65535)
|
||||
|
|
|
@ -87,7 +87,16 @@ public class Strings2 {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
private static final String IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})";
|
||||
private static final String SLASH_FORMAT = IP_ADDRESS + "/(\\d{1,3})";
|
||||
private static final Pattern ADDRESS_PATTERN = Pattern.compile(IP_ADDRESS);
|
||||
private static final Pattern CIDR_PATTERN = Pattern.compile(SLASH_FORMAT);
|
||||
|
||||
public static boolean isCidrFormat(String in) {
|
||||
return CIDR_PATTERN.matcher(in).matches();
|
||||
}
|
||||
|
||||
private static final Pattern URL_ENCODED_PATTERN = Pattern.compile(".*%[a-fA-F0-9][a-fA-F0-9].*");
|
||||
|
||||
public static boolean isUrlEncoded(String in) {
|
||||
|
|
|
@ -53,4 +53,12 @@ public class Strings2Test {
|
|||
assertEquals(actual, urlDecode(urlEncode(actual)));
|
||||
}
|
||||
|
||||
public void testIsCidrFormat() {
|
||||
assert Strings2.isCidrFormat("1.2.3.4/5");
|
||||
assert Strings2.isCidrFormat("0.0.0.0/0");
|
||||
assert !Strings2.isCidrFormat("banana");
|
||||
assert !Strings2.isCidrFormat("1.2.3.4");
|
||||
assert !Strings2.isCidrFormat("500.500.500.500/2423");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
@ -104,13 +105,14 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
@Named("PLACEMENT") LoadingCache<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted, Optional<ImageExtension> imageExtension,
|
||||
GroupNamingConvention.Factory namingConvention,
|
||||
@Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames) {
|
||||
@Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames,
|
||||
Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, runScriptOnNodeFactory, initAdminAccess,
|
||||
persistNodeCredentials, timeouts, userExecutor, client, credentialsMap, securityGroupMap, imageExtension,
|
||||
namingConvention, generateInstanceNames);
|
||||
namingConvention, generateInstanceNames, securityGroupExtension);
|
||||
this.client = client;
|
||||
this.placementGroupMap = placementGroupMap;
|
||||
this.placementGroupDeleted = placementGroupDeleted;
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.jclouds.aws.ec2.compute.suppliers.AWSEC2HardwareSupplier;
|
|||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.ec2.compute.config.EC2BindComputeStrategiesByClass;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
|
@ -173,4 +174,9 @@ public class AWSEC2ComputeServiceContextModule extends BaseComputeServiceContext
|
|||
protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||
return Optional.of(i.getInstance(ImageExtension.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
|
||||
return Optional.of(i.getInstance(SecurityGroupExtension.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.compute.extensions.AWSEC2SecurityGroupExtension;
|
||||
import org.jclouds.aws.ec2.compute.loaders.AWSEC2CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.aws.ec2.compute.suppliers.CallForImages;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup;
|
||||
|
@ -41,8 +42,10 @@ import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
|
|||
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
|
@ -50,9 +53,11 @@ import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule;
|
|||
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.extensions.EC2ImageExtension;
|
||||
import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
|
||||
import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair;
|
||||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.EC2ImageParser;
|
||||
import org.jclouds.ec2.compute.functions.EC2SecurityGroupToSecurityGroup;
|
||||
import org.jclouds.ec2.compute.functions.PasswordCredentialsFromWindowsInstance;
|
||||
import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
|
@ -105,8 +110,12 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep
|
|||
install(new FactoryModuleBuilder().build(CallForImages.Factory.class));
|
||||
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.Image, Image>>() {
|
||||
}).to(EC2ImageParser.class);
|
||||
bind(new TypeLiteral<Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup>>() {
|
||||
}).to(EC2SecurityGroupToSecurityGroup.class);
|
||||
bind(new TypeLiteral<ImageExtension>() {
|
||||
}).to(EC2ImageExtension.class);
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {
|
||||
}).to(AWSEC2SecurityGroupExtension.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.aws.ec2.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.base.Predicates.notNull;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.collect.Iterables.toArray;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention.Factory;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.UncheckedTimeoutException;
|
||||
|
||||
/**
|
||||
* An extension to compute service to allow for the manipulation of {@link SecurityGroup}s. Implementation
|
||||
* is optional by providers.
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
public class AWSEC2SecurityGroupExtension extends EC2SecurityGroupExtension {
|
||||
protected final AWSEC2Client client;
|
||||
|
||||
@Inject
|
||||
public AWSEC2SecurityGroupExtension(AWSEC2Client client,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
@Region Supplier<Set<String>> regions,
|
||||
Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter,
|
||||
@Memoized Supplier<Set<? extends Location>> locations,
|
||||
@Named("SECURITY") LoadingCache<RegionAndName, String> groupCreator,
|
||||
GroupNamingConvention.Factory namingConvention) {
|
||||
super(client, userExecutor, regions, groupConverter, locations, groupCreator, namingConvention);
|
||||
this.client = checkNotNull(client, "client");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, ipPermission);
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(protocol);
|
||||
builder.fromPort(startPort);
|
||||
builder.toPort(endPort);
|
||||
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
for (String cidr : ipRanges) {
|
||||
builder.cidrBlock(cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
for (String userId : tenantIdGroupNamePairs.keySet()) {
|
||||
for (String groupName : tenantIdGroupNamePairs.get(userId)) {
|
||||
builder.tenantIdGroupNamePair(userId, groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, builder.build());
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
client.getSecurityGroupServices().revokeSecurityGroupIngressInRegion(region, name, ipPermission);
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(group.getLocation());
|
||||
String name = group.getName();
|
||||
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(protocol);
|
||||
builder.fromPort(startPort);
|
||||
builder.toPort(endPort);
|
||||
|
||||
if (Iterables.size(ipRanges) > 0) {
|
||||
for (String cidr : ipRanges) {
|
||||
builder.cidrBlock(cidr);
|
||||
}
|
||||
}
|
||||
|
||||
if (tenantIdGroupNamePairs.size() > 0) {
|
||||
for (String userId : tenantIdGroupNamePairs.keySet()) {
|
||||
for (String groupName : tenantIdGroupNamePairs.get(userId)) {
|
||||
builder.tenantIdGroupNamePair(userId, groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.getSecurityGroupServices().revokeSecurityGroupIngressInRegion(region, name, builder.build());
|
||||
|
||||
return getSecurityGroupById(new RegionAndName(region, group.getName()).slashEncode());
|
||||
}
|
||||
}
|
|
@ -32,10 +32,10 @@ import org.jclouds.aws.ec2.services.AWSSecurityGroupClient;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
@ -95,7 +95,7 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader<RegionAndName
|
|||
.fromPort(range.getKey())
|
||||
.toPort(range.getValue())
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.ipRange("0.0.0.0/0")
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build());
|
||||
}
|
||||
|
||||
|
@ -104,13 +104,13 @@ public class AWSEC2CreateSecurityGroupIfNeeded extends CacheLoader<RegionAndName
|
|||
.fromPort(0)
|
||||
.toPort(65535)
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.userIdGroupPair(myOwnerId, name)
|
||||
.tenantIdGroupNamePair(myOwnerId, name)
|
||||
.build());
|
||||
permissions.add(IpPermission.builder()
|
||||
.fromPort(0)
|
||||
.toPort(65535)
|
||||
.ipProtocol(IpProtocol.UDP)
|
||||
.userIdGroupPair(myOwnerId, name)
|
||||
.tenantIdGroupNamePair(myOwnerId, name)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@ import org.jclouds.aws.filters.FormSigner;
|
|||
import org.jclouds.ec2.binders.BindGroupIdsToIndexedFormParams;
|
||||
import org.jclouds.ec2.binders.BindIpPermissionToIndexedFormParams;
|
||||
import org.jclouds.ec2.binders.BindIpPermissionsToIndexedFormParams;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.services.SecurityGroupAsyncClient;
|
||||
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
|
|
|
@ -18,10 +18,10 @@ package org.jclouds.aws.ec2.services;
|
|||
|
||||
import java.util.Set;
|
||||
import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@ import org.jclouds.compute.predicates.NodePredicates;
|
|||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.services.InstanceClient;
|
||||
import org.jclouds.ec2.services.KeyPairClient;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.aws.ec2.compute.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.aws.ec2.compute.internal.BaseAWSEC2ComputeServiceExpectTest;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*/
|
||||
@Test(groups = "unit", testName = "AWSEC2SecurityGroupExtensionExpectTest")
|
||||
public class AWSEC2SecurityGroupExtensionExpectTest extends BaseAWSEC2ComputeServiceExpectTest {
|
||||
|
||||
public void testAddIpPermissionCidrFromIpPermission() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestRange =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("GroupId", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.FromPort", "22")
|
||||
.addFormParam("IpPermissions.0.IpProtocol", "tcp")
|
||||
.addFormParam("IpPermissions.0.IpRanges.0.CidrIp", "0.0.0.0/0")
|
||||
.addFormParam("IpPermissions.0.ToPort", "40")
|
||||
.build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(22);
|
||||
builder.toPort(40);
|
||||
builder.cidrBlock("0.0.0.0/0");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(1, newPerm.getCidrBlocks().size());
|
||||
assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
|
||||
}
|
||||
|
||||
public void testAddIpPermissionCidrFromParams() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_cidr.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestRange =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("GroupId", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.FromPort", "22")
|
||||
.addFormParam("IpPermissions.0.IpProtocol", "tcp")
|
||||
.addFormParam("IpPermissions.0.IpRanges.0.CidrIp", "0.0.0.0/0")
|
||||
.addFormParam("IpPermissions.0.ToPort", "40")
|
||||
.build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestRange, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
|
||||
22,
|
||||
40,
|
||||
emptyMultimap(),
|
||||
ImmutableSet.of("0.0.0.0/0"),
|
||||
emptyStringSet(),
|
||||
origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(1, newPerm.getCidrBlocks().size());
|
||||
assertTrue(newPerm.getCidrBlocks().contains("0.0.0.0/0"));
|
||||
}
|
||||
|
||||
public void testAddIpPermissionGroupFromIpPermission() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("GroupId", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.FromPort", "22")
|
||||
.addFormParam("IpPermissions.0.Groups.0.GroupName", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.Groups.0.UserId", "993194456877")
|
||||
.addFormParam("IpPermissions.0.IpProtocol", "tcp")
|
||||
.addFormParam("IpPermissions.0.ToPort", "40")
|
||||
.build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
builder.fromPort(22);
|
||||
builder.toPort(40);
|
||||
builder.tenantIdGroupNamePair("993194456877", "jclouds#some-group");
|
||||
|
||||
IpPermission perm = builder.build();
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
groupBuilder.ownerId("993194456877");
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(0, newPerm.getCidrBlocks().size());
|
||||
assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
|
||||
}
|
||||
|
||||
|
||||
public void testAddIpPermissionGroupFromParams() {
|
||||
HttpRequest describeSecurityGroupsSingleRequest =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "DescribeSecurityGroups")
|
||||
.addFormParam("GroupName.1", "jclouds#some-group").build());
|
||||
|
||||
HttpResponse describeSecurityGroupsSingleResponse =
|
||||
HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType(
|
||||
"/describe_securitygroups_extension_group.xml", MediaType.APPLICATION_XML)).build();
|
||||
|
||||
|
||||
HttpRequest authorizeSecurityGroupIngressRequestGroupTenant =
|
||||
formSigner.filter(HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://ec2." + region + ".amazonaws.com/")
|
||||
.addHeader("Host", "ec2." + region + ".amazonaws.com")
|
||||
.addFormParam("Action", "AuthorizeSecurityGroupIngress")
|
||||
.addFormParam("GroupId", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.FromPort", "22")
|
||||
.addFormParam("IpPermissions.0.Groups.0.GroupName", "jclouds#some-group")
|
||||
.addFormParam("IpPermissions.0.Groups.0.UserId", "993194456877")
|
||||
.addFormParam("IpPermissions.0.IpProtocol", "tcp")
|
||||
.addFormParam("IpPermissions.0.ToPort", "40")
|
||||
.build());
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(describeRegionsRequest, describeRegionsResponse);
|
||||
requestResponseMap.put(describeAvailabilityZonesRequest, describeAvailabilityZonesResponse);
|
||||
requestResponseMap.put(describeSecurityGroupsSingleRequest, describeSecurityGroupsSingleResponse);
|
||||
requestResponseMap.put(createKeyPairRequest, createKeyPairResponse);
|
||||
requestResponseMap.put(createSecurityGroupRequest, createSecurityGroupResponse);
|
||||
|
||||
requestResponseMap.put(authorizeSecurityGroupIngressRequestGroupTenant, authorizeSecurityGroupIngressResponse);
|
||||
|
||||
SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
|
||||
|
||||
SecurityGroupBuilder groupBuilder = new SecurityGroupBuilder();
|
||||
groupBuilder.id("jclouds#some-group");
|
||||
groupBuilder.providerId("sg-3c6ef654");
|
||||
groupBuilder.name("jclouds#some-group");
|
||||
groupBuilder.ownerId("993194456877");
|
||||
groupBuilder.location(new LocationBuilder()
|
||||
.scope(LocationScope.REGION)
|
||||
.id(region)
|
||||
.description("region")
|
||||
.build());
|
||||
|
||||
SecurityGroup origGroup = groupBuilder.build();
|
||||
|
||||
ImmutableMultimap.Builder<String, String> permBuilder = ImmutableMultimap.builder();
|
||||
permBuilder.put(origGroup.getOwnerId(), origGroup.getName());
|
||||
|
||||
SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
|
||||
22,
|
||||
40,
|
||||
permBuilder.build(),
|
||||
emptyStringSet(),
|
||||
emptyStringSet(),
|
||||
origGroup);
|
||||
|
||||
assertEquals(1, newGroup.getIpPermissions().size());
|
||||
|
||||
IpPermission newPerm = Iterables.getOnlyElement(newGroup.getIpPermissions());
|
||||
|
||||
assertNotNull(newPerm);
|
||||
assertEquals(IpProtocol.TCP, newPerm.getIpProtocol());
|
||||
assertEquals(22, newPerm.getFromPort());
|
||||
assertEquals(40, newPerm.getToPort());
|
||||
assertEquals(0, newPerm.getCidrBlocks().size());
|
||||
assertEquals(1, newPerm.getTenantIdGroupNamePairs().size());
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().keySet().contains(origGroup.getOwnerId()));
|
||||
assertTrue(newPerm.getTenantIdGroupNamePairs().values().contains(origGroup.getName()));
|
||||
}
|
||||
|
||||
private Multimap<String, String> emptyMultimap() {
|
||||
return LinkedHashMultimap.create();
|
||||
}
|
||||
|
||||
private Set<String> emptyStringSet() {
|
||||
return Sets.newLinkedHashSet();
|
||||
}
|
||||
}
|
|
@ -14,26 +14,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.domain;
|
||||
package org.jclouds.aws.ec2.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
public enum IpProtocol {
|
||||
TCP, UDP, ICMP, UNRECOGNIZED;
|
||||
public String value() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
import com.google.inject.Module;
|
||||
|
||||
public static IpProtocol fromValue(String protocol) {
|
||||
try {
|
||||
return valueOf(checkNotNull(protocol, "protocol").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
/**
|
||||
* Live test for aws-ec2 {@link SecurityGroupExtension} implementation
|
||||
*
|
||||
* @author Andrew Bayer
|
||||
*
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "AWSEC2SecurityGroupExtensionLiveTest")
|
||||
public class AWSEC2SecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
public AWSEC2SecurityGroupExtensionLiveTest() {
|
||||
provider = "aws-ec2";
|
||||
}
|
||||
}
|
|
@ -30,10 +30,10 @@ import java.util.concurrent.ExecutionException;
|
|||
import org.jclouds.aws.ec2.services.AWSSecurityGroupClient;
|
||||
import org.jclouds.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.domain.UserIdGroupPair;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -63,20 +63,20 @@ public class AWSEC2CreateSecurityGroupIfNeededTest {
|
|||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.ipRange("0.0.0.0/0")
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build());
|
||||
|
||||
permissions.add(IpPermission.builder()
|
||||
.fromPort(0)
|
||||
.toPort(65535)
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.userIdGroupPair("ownerId", "group")
|
||||
.tenantIdGroupNamePair("ownerId", "group")
|
||||
.build());
|
||||
permissions.add(IpPermission.builder()
|
||||
.fromPort(0)
|
||||
.toPort(65535)
|
||||
.ipProtocol(IpProtocol.UDP)
|
||||
.userIdGroupPair("ownerId", "group")
|
||||
.tenantIdGroupNamePair("ownerId", "group")
|
||||
.build());
|
||||
|
||||
client.createSecurityGroupInRegion("region", "group", "group");
|
||||
|
|
|
@ -25,12 +25,12 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.xml.BaseEC2HandlerTest;
|
||||
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.reflect.Invocation;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -69,7 +69,7 @@ public class DescribeSecurityGroupsResponseTest extends BaseEC2HandlerTest {
|
|||
// .vpcId("vpc-99999999")
|
||||
.ipPermission(IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.ALL)
|
||||
.userIdGroupPair("123123123123","sg-11111111").build())
|
||||
.tenantIdGroupNamePair("123123123123","sg-11111111").build())
|
||||
// .ipPermissionEgress(IpPermission.builder()
|
||||
// .ipProtocol(IpProtocol.ALL)
|
||||
// .ipRange("0.0.0.0/0").build())
|
||||
|
|
|
@ -22,13 +22,13 @@ import java.io.IOException;
|
|||
|
||||
import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.util.IpPermissions;
|
||||
import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ import static org.testng.Assert.assertNotNull;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.ec2.domain.IpPermission;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.ec2.services.SecurityGroupClientLiveTest;
|
||||
import org.jclouds.ec2.util.IpPermissions;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -69,7 +69,7 @@ public class AWSSecurityGroupClientLiveTest extends SecurityGroupClientLiveTest
|
|||
assertEventually(new GroupHasPermission(client, group2Name, new Predicate<IpPermission>() {
|
||||
@Override
|
||||
public boolean apply(IpPermission arg0) {
|
||||
return arg0.getUserIdGroupPairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name))
|
||||
return arg0.getTenantIdGroupNamePairs().equals(ImmutableMultimap.of(group.getOwnerId(), group1Name))
|
||||
&& arg0.getFromPort() == 80 && arg0.getToPort() == 80 && arg0.getIpProtocol() == IpProtocol.TCP;
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
@ -81,12 +82,12 @@ public class GoGridComputeService extends BaseComputeService {
|
|||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
|
||||
Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
Optional<ImageExtension> imageExtension) {
|
||||
Optional<ImageExtension> imageExtension, Optional<SecurityGroupExtension> securityGroupExtension) {
|
||||
super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue