mirror of
https://github.com/apache/jclouds.git
synced 2025-02-07 10:39:03 +00:00
[JCLOUDS-1377] add support for injectable Neutron Context into Nova
- fix NovaComputeServiceExpectTest - fix NovaComputeServiceExpectTest - fix CreateSecurityGroupIfNeededTest - fix FindSecurityGroupInRegionOrCreateTest - fix checkstyle - fix removal from security group cache - fix listSecurityGroupsForNode - change both Nova and Neutron listSecurityGroupsForNode to use NovaApi.listSecurityGroupForServer
This commit is contained in:
parent
2a56db0957
commit
09936b57fc
@ -53,6 +53,11 @@
|
||||
<artifactId>openstack-keystone</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.api</groupId>
|
||||
<artifactId>openstack-neutron</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- for the extension namespaces -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.jclouds.openstack.nova.v2_0;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||
import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
|
||||
import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
|
||||
import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
|
||||
@ -78,6 +79,7 @@ public class NovaApiMetadata extends BaseHttpApiMetadata<NovaApi> {
|
||||
// before expiry by default. We choose a value less than the latter
|
||||
// since the former persists between jclouds invocations.
|
||||
properties.setProperty(PROPERTY_SESSION_INTERVAL, 30 * 60 + "");
|
||||
properties.put(TEMPLATE, "osFamily=UBUNTU,os64Bit=true,osVersionMatches=16.*");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ public class NovaComputeServiceAdapter implements
|
||||
logger.warn(message);
|
||||
String tagString = metadataAndTagsAsCommaDelimitedValue.get("jclouds_tags");
|
||||
Set<String> tags = Sets.newHashSet(Splitter.on(',').split(tagString));
|
||||
cleanupResources.removeSecurityGroupCreatedByJcloudsAndInvalidateCache(regionId, tags);
|
||||
cleanupResources.removeSecurityGroupCreatedByJcloudsAndInvalidateCache(tags);
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
logger.trace("<< server(%s)", lightweightServer.getId());
|
||||
|
@ -17,21 +17,22 @@
|
||||
package org.jclouds.openstack.nova.v2_0.compute.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_ALLOCATE_FLOATING_IPS;
|
||||
import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_GENERATE_KEYPAIRS;
|
||||
import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.TIMEOUT_SECURITYGROUP_PRESENT;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import org.jclouds.Context;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
@ -53,6 +54,7 @@ import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
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.NeutronSecurityGroupExtension;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaSecurityGroupExtension;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.CleanupResources;
|
||||
@ -60,7 +62,9 @@ import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNe
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInRegionToHardware;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInRegionToImage;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NeutronSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInRegionToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByRegionId;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInRegionToNodeMetadata;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.loaders.FindSecurityGroupOrCreate;
|
||||
@ -77,7 +81,6 @@ import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ServerInRegion;
|
||||
import org.jclouds.openstack.nova.v2_0.predicates.FindSecurityGroupWithNameAndReturnTrue;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
@ -137,10 +140,10 @@ public class NovaComputeServiceContextModule extends
|
||||
bind(new TypeLiteral<CacheLoader<RegionAndId, Iterable<? extends FloatingIP>>>() {
|
||||
}).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
|
||||
|
||||
bind(new TypeLiteral<Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion>>() {
|
||||
bind(new TypeLiteral<Function<RegionSecurityGroupNameAndPorts, SecurityGroup>>() {
|
||||
}).to(CreateSecurityGroupIfNeeded.class);
|
||||
|
||||
bind(new TypeLiteral<CacheLoader<RegionAndName, SecurityGroupInRegion>>() {
|
||||
bind(new TypeLiteral<CacheLoader<RegionAndName, SecurityGroup>>() {
|
||||
}).to(FindSecurityGroupOrCreate.class);
|
||||
|
||||
bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
||||
@ -149,11 +152,37 @@ public class NovaComputeServiceContextModule extends
|
||||
bind(new TypeLiteral<ImageExtension>() {
|
||||
}).to(NovaImageExtension.class);
|
||||
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {
|
||||
}).to(NovaSecurityGroupExtension.class);
|
||||
|
||||
bind(new TypeLiteral<Function<NodeMetadata, Boolean>>() {
|
||||
}).to(CleanupResources.class);
|
||||
|
||||
install(new FactoryModuleBuilder().build(NeutronSecurityGroupToSecurityGroup.Factory.class));
|
||||
install(new FactoryModuleBuilder().build(NovaSecurityGroupToSecurityGroup.Factory.class));
|
||||
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {
|
||||
}).toProvider(SecurityGroupExtensionProvider.class);
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class SecurityGroupExtensionProvider implements Provider<SecurityGroupExtension> {
|
||||
@Inject(optional = true)
|
||||
@Named("openstack-neutron")
|
||||
protected Supplier<Context> neutronApiContextSupplier;
|
||||
|
||||
private final NeutronSecurityGroupExtension neutronSecurityGroupExtension;
|
||||
private final NovaSecurityGroupExtension novaSecurityGroupExtension;
|
||||
|
||||
@Inject
|
||||
SecurityGroupExtensionProvider(NeutronSecurityGroupExtension neutronSecurityGroupExtension,
|
||||
NovaSecurityGroupExtension novaSecurityGroupExtension) {
|
||||
this.neutronSecurityGroupExtension = neutronSecurityGroupExtension;
|
||||
this.novaSecurityGroupExtension = novaSecurityGroupExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupExtension get() {
|
||||
return neutronApiContextSupplier != null ? neutronSecurityGroupExtension : novaSecurityGroupExtension;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -192,8 +221,8 @@ public class NovaComputeServiceContextModule extends
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected final LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap(
|
||||
CacheLoader<RegionAndName, SecurityGroupInRegion> in) {
|
||||
protected final LoadingCache<RegionAndName, SecurityGroup> securityGroupMap(
|
||||
CacheLoader<RegionAndName, SecurityGroup> in) {
|
||||
return CacheBuilder.newBuilder().build(in);
|
||||
}
|
||||
|
||||
@ -203,15 +232,6 @@ public class NovaComputeServiceContextModule extends
|
||||
OsFamily.UBUNTU, LoginCredentials.builder().user("ubuntu").build());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("SECURITYGROUP_PRESENT")
|
||||
protected final Predicate<AtomicReference<RegionAndName>> securityGroupEventualConsistencyDelay(
|
||||
FindSecurityGroupWithNameAndReturnTrue in,
|
||||
@Named(TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) {
|
||||
return retry(in, msDelay, 100L, MILLISECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected final Supplier<Map<String, Location>> createLocationIndexedById(
|
||||
|
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* 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.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.notNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Context;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.neutron.v2.NeutronApi;
|
||||
import org.jclouds.openstack.neutron.v2.domain.Rule;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleDirection;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleEthertype;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleProtocol;
|
||||
import org.jclouds.openstack.neutron.v2.features.SecurityGroupApi;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NeutronSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.rest.ApiContext;
|
||||
|
||||
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.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
|
||||
* is optional by providers.
|
||||
*/
|
||||
public class NeutronSecurityGroupExtension implements SecurityGroupExtension {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final NovaApi api;
|
||||
private final Supplier<Set<String>> regionIds;
|
||||
private final GroupNamingConvention.Factory namingConvention;
|
||||
private final LoadingCache<RegionAndName, SecurityGroup> groupCreator;
|
||||
private final Supplier<Map<String, Location>> locationIndex;
|
||||
private final NeutronSecurityGroupToSecurityGroup.Factory neutronSecurityGroupToSecurityGroup;
|
||||
private final NovaSecurityGroupToSecurityGroup.Factory novaSecurityGroupToSecurityGroup;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("openstack-neutron")
|
||||
private Supplier<Context> neutronContextSupplier;
|
||||
|
||||
@Inject
|
||||
NeutronSecurityGroupExtension(NovaApi api,
|
||||
@Region Supplier<Set<String>> regionIds,
|
||||
GroupNamingConvention.Factory namingConvention, LoadingCache<RegionAndName, SecurityGroup> groupCreator,
|
||||
Supplier<Map<String, Location>> locationIndex,
|
||||
NeutronSecurityGroupToSecurityGroup.Factory neutronSecurityGroupToSecurityGroup,
|
||||
NovaSecurityGroupToSecurityGroup.Factory novaSecurityGroupToSecurityGroup) {
|
||||
this.api = api;
|
||||
this.regionIds = checkNotNull(regionIds, "regionIds");
|
||||
this.namingConvention = checkNotNull(namingConvention, "namingConvention");
|
||||
this.groupCreator = groupCreator;
|
||||
this.locationIndex = locationIndex;
|
||||
this.neutronSecurityGroupToSecurityGroup = neutronSecurityGroupToSecurityGroup;
|
||||
this.novaSecurityGroupToSecurityGroup = novaSecurityGroupToSecurityGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup createSecurityGroup(String name, Location location) {
|
||||
String region = location.getId();
|
||||
if (region == null) {
|
||||
return null;
|
||||
}
|
||||
logger.debug(">> creating security group %s in %s...", name, location);
|
||||
|
||||
String markerGroup = namingConvention.create().sharedNameForGroup(name);
|
||||
RegionSecurityGroupNameAndPorts regionAndName = new RegionSecurityGroupNameAndPorts(region, markerGroup, ImmutableSet.<Integer> of());
|
||||
return groupCreator.getUnchecked(regionAndName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroups() {
|
||||
Set<SecurityGroup> securityGroups = Sets.newHashSet();
|
||||
|
||||
for (String regionId : regionIds.get()) {
|
||||
Location location = locationIndex.get().get(regionId);
|
||||
securityGroups.addAll(listSecurityGroupsInLocation(location));
|
||||
}
|
||||
return ImmutableSet.copyOf(securityGroups);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
|
||||
String region = location.getId();
|
||||
if (region == null) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
return getSecurityGroupApi(region).listSecurityGroups().concat().transform(neutronSecurityGroupToSecurityGroup.create(location)).toSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(checkNotNull(id, "id"));
|
||||
String region = regionAndId.getRegion();
|
||||
Location location = locationIndex.get().get(region);
|
||||
Set<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup> allGroups = api.getServerApi(region).listSecurityGroupForServer(regionAndId.getId());
|
||||
return ImmutableSet.copyOf(transform(filter(allGroups, notNull()), novaSecurityGroupToSecurityGroup.create(location)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup getSecurityGroupById(String id) {
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(checkNotNull(id, "id"));
|
||||
String region = regionAndId.getRegion();
|
||||
String groupId = regionAndId.getId();
|
||||
|
||||
SecurityGroupApi securityGroupApi = getSecurityGroupApi(region);
|
||||
|
||||
Location location = locationIndex.get().get(region);
|
||||
return neutronSecurityGroupToSecurityGroup.create(location).apply(securityGroupApi.getSecurityGroup(groupId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSecurityGroup(String id) {
|
||||
checkNotNull(id, "id");
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String region = regionAndId.getRegion();
|
||||
String groupId = regionAndId.getId();
|
||||
|
||||
SecurityGroupApi securityGroupApi = getSecurityGroupApi(region);
|
||||
|
||||
// Would be nice to delete the group and invalidate the cache atomically - i.e. use a mutex.
|
||||
// Will make sure that a create operation in parallel won't see inconsistent state.
|
||||
|
||||
boolean deleted = securityGroupApi.deleteSecurityGroup(groupId);
|
||||
|
||||
for (SecurityGroup cachedSg : groupCreator.asMap().values()) {
|
||||
if (id.equals(cachedSg.getId())) {
|
||||
String groupName = cachedSg.getName();
|
||||
groupCreator.invalidate(new RegionSecurityGroupNameAndPorts(region, groupName, ImmutableSet.<Integer>of()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
|
||||
String region = group.getLocation().getId();
|
||||
RegionAndId groupRegionAndId = RegionAndId.fromSlashEncoded(group.getId());
|
||||
String id = groupRegionAndId.getId();
|
||||
SecurityGroupApi securityGroupApi = getSecurityGroupApi(region);
|
||||
|
||||
if (!ipPermission.getCidrBlocks().isEmpty()) {
|
||||
for (String cidr : ipPermission.getCidrBlocks()) {
|
||||
securityGroupApi.create(Rule.CreateRule.createBuilder(RuleDirection.INGRESS, group.getProviderId())
|
||||
.protocol(RuleProtocol.fromValue(ipPermission.getIpProtocol().name()))
|
||||
.ethertype(RuleEthertype.IPV4)
|
||||
.portRangeMin(ipPermission.getFromPort())
|
||||
.portRangeMax(ipPermission.getToPort())
|
||||
.remoteIpPrefix(cidr)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
if (!ipPermission.getGroupIds().isEmpty()) {
|
||||
for (String regionAndGroupRaw : ipPermission.getGroupIds()) {
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(regionAndGroupRaw);
|
||||
String groupId = regionAndId.getId();
|
||||
securityGroupApi.create(Rule.CreateRule.createBuilder(RuleDirection.INGRESS, groupId)
|
||||
.protocol(RuleProtocol.fromValue(ipPermission.getIpProtocol().name()))
|
||||
.ethertype(RuleEthertype.IPV4)
|
||||
.portRangeMin(ipPermission.getFromPort())
|
||||
.portRangeMax(ipPermission.getToPort())
|
||||
.remoteGroupId(groupId)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
return getSecurityGroupById(RegionAndId.fromRegionAndId(region, id).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
IpPermission.Builder permBuilder = IpPermission.builder();
|
||||
permBuilder.ipProtocol(protocol);
|
||||
permBuilder.fromPort(startPort);
|
||||
permBuilder.toPort(endPort);
|
||||
permBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
|
||||
permBuilder.cidrBlocks(ipRanges);
|
||||
permBuilder.groupIds(groupIds);
|
||||
|
||||
return addIpPermission(permBuilder.build(), group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(final IpPermission ipPermission, SecurityGroup group) {
|
||||
String region = group.getLocation().getId();
|
||||
RegionAndId groupRegionAndId = RegionAndId.fromSlashEncoded(group.getId());
|
||||
String id = groupRegionAndId.getId();
|
||||
|
||||
SecurityGroupApi securityGroupApi = getSecurityGroupApi(region);
|
||||
|
||||
org.jclouds.openstack.neutron.v2.domain.SecurityGroup securityGroup = securityGroupApi.getSecurityGroup(id);
|
||||
|
||||
if (!ipPermission.getCidrBlocks().isEmpty()) {
|
||||
for (final String cidr : ipPermission.getCidrBlocks()) {
|
||||
for (Rule rule : filter(securityGroup.getRules(),
|
||||
new Predicate<Rule>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable Rule input) {
|
||||
return input.getRemoteIpPrefix() != null && input.getRemoteIpPrefix().equals(cidr) &&
|
||||
input.getProtocol() != null && input.getProtocol().name().equals(ipPermission.getIpProtocol().name()) &&
|
||||
input.getPortRangeMin() != null && input.getPortRangeMin() == ipPermission.getFromPort() &&
|
||||
input.getPortRangeMax() != null && input.getPortRangeMax() == ipPermission.getToPort();
|
||||
}
|
||||
})) {
|
||||
securityGroupApi.deleteRule(rule.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ipPermission.getGroupIds().isEmpty()) {
|
||||
for (final String groupId : ipPermission.getGroupIds()) {
|
||||
for (Rule rule : filter(securityGroup.getRules(),
|
||||
new Predicate<Rule>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable Rule input) {
|
||||
return input.getRemoteGroupId() != null && input.getRemoteGroupId().equals(groupId) &&
|
||||
input.getProtocol() != null && input.getProtocol().name().equals(ipPermission.getIpProtocol().name()) &&
|
||||
input.getPortRangeMin() != null && input.getPortRangeMin() == ipPermission.getFromPort() &&
|
||||
input.getPortRangeMax() != null && input.getPortRangeMax() == ipPermission.getToPort();
|
||||
}
|
||||
})) {
|
||||
securityGroupApi.deleteRule(rule.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getSecurityGroupById(RegionAndId.fromRegionAndId(region, id).slashEncode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
|
||||
Multimap<String, String> tenantIdGroupNamePairs,
|
||||
Iterable<String> ipRanges,
|
||||
Iterable<String> groupIds, SecurityGroup group) {
|
||||
IpPermission.Builder permBuilder = IpPermission.builder();
|
||||
permBuilder.ipProtocol(protocol);
|
||||
permBuilder.fromPort(startPort);
|
||||
permBuilder.toPort(endPort);
|
||||
permBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
|
||||
permBuilder.cidrBlocks(ipRanges);
|
||||
permBuilder.groupIds(groupIds);
|
||||
|
||||
return removeIpPermission(permBuilder.build(), group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTenantIdGroupNamePairs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTenantIdGroupIdPairs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPortRangesForGroups() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExclusionCidrBlocks() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private SecurityGroupApi getSecurityGroupApi(String region) {
|
||||
return ((ApiContext<NeutronApi>) neutronContextSupplier.get()).getApi().getSecurityGroupApi(region);
|
||||
}
|
||||
|
||||
}
|
@ -16,14 +16,12 @@
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.compute.extensions;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.and;
|
||||
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.transform;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.nameIn;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleCidr;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleEndPort;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleGroup;
|
||||
@ -32,9 +30,9 @@ import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
@ -46,13 +44,11 @@ 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.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
@ -73,7 +69,7 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
|
||||
protected final ListeningExecutorService userExecutor;
|
||||
protected final Supplier<Set<String>> regionIds;
|
||||
protected final Function<SecurityGroupInRegion, SecurityGroup> groupConverter;
|
||||
protected final LoadingCache<RegionAndName, SecurityGroupInRegion> groupCreator;
|
||||
protected final LoadingCache<RegionAndName, SecurityGroup> groupCreator;
|
||||
protected final GroupNamingConvention.Factory namingConvention;
|
||||
|
||||
@Inject
|
||||
@ -81,7 +77,7 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
@Region Supplier<Set<String>> regionIds,
|
||||
Function<SecurityGroupInRegion, SecurityGroup> groupConverter,
|
||||
LoadingCache<RegionAndName, SecurityGroupInRegion> groupCreator,
|
||||
LoadingCache<RegionAndName, SecurityGroup> groupCreator,
|
||||
GroupNamingConvention.Factory namingConvention) {
|
||||
|
||||
this.api = checkNotNull(api, "api");
|
||||
@ -121,25 +117,9 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
|
||||
public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(checkNotNull(id, "id"));
|
||||
String region = regionAndId.getRegion();
|
||||
String instanceId = regionAndId.getId();
|
||||
|
||||
Optional<? extends ServerWithSecurityGroupsApi> serverApi = api.getServerWithSecurityGroupsApi(region);
|
||||
Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
|
||||
|
||||
if (!serverApi.isPresent() || !sgApi.isPresent()) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
ServerWithSecurityGroups instance = serverApi.get().get(instanceId);
|
||||
if (instance == null) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
Set<String> groupNames = instance.getSecurityGroupNames();
|
||||
final FluentIterable<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup> allGroups = sgApi.get().list();
|
||||
Set<? extends SecurityGroupInRegion> rawGroups =
|
||||
allGroups.filter(nameIn(groupNames)).transform(groupToGroupInRegion(allGroups, region)).toSet();
|
||||
|
||||
Set<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup> allGroups = api.getServerApi(region).listSecurityGroupForServer(regionAndId.getId());
|
||||
Set<? extends SecurityGroupInRegion> rawGroups =
|
||||
FluentIterable.from(allGroups).transform(groupToGroupInRegion(allGroups, region)).toSet();
|
||||
return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
|
||||
}
|
||||
|
||||
@ -174,8 +154,8 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
|
||||
String markerGroup = namingConvention.create().sharedNameForGroup(name);
|
||||
RegionSecurityGroupNameAndPorts regionAndName = new RegionSecurityGroupNameAndPorts(region, markerGroup, ImmutableSet.<Integer> of());
|
||||
|
||||
SecurityGroupInRegion rawGroup = groupCreator.getUnchecked(regionAndName);
|
||||
return groupConverter.apply(rawGroup);
|
||||
SecurityGroup rawGroup = groupCreator.getUnchecked(regionAndName);
|
||||
return rawGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -196,8 +176,8 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
|
||||
|
||||
boolean deleted = sgApi.get().delete(groupId);
|
||||
|
||||
for (SecurityGroupInRegion cachedSg : groupCreator.asMap().values()) {
|
||||
if (groupId.equals(cachedSg.getSecurityGroup().getId())) {
|
||||
for (SecurityGroup cachedSg : groupCreator.asMap().values()) {
|
||||
if (id.equals(cachedSg.getId())) {
|
||||
String groupName = cachedSg.getName();
|
||||
groupCreator.invalidate(new RegionSecurityGroupNameAndPorts(region, groupName, ImmutableSet.<Integer>of()));
|
||||
break;
|
||||
|
@ -27,13 +27,12 @@ import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
@ -47,38 +46,29 @@ public class CleanupResources implements Function<NodeMetadata, Boolean> {
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final NovaApi novaApi;
|
||||
protected final RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate;
|
||||
protected final LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap;
|
||||
protected final LoadingCache<RegionAndName, SecurityGroup> securityGroupMap;
|
||||
|
||||
private final SecurityGroupExtension securityGroupExtension;
|
||||
|
||||
@Inject
|
||||
public CleanupResources(NovaApi novaApi, RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate,
|
||||
LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap) {
|
||||
|
||||
this.novaApi = novaApi;
|
||||
public CleanupResources(RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate,
|
||||
LoadingCache<RegionAndName, SecurityGroup> securityGroupMap, SecurityGroupExtension securityGroupExtension) {
|
||||
this.removeFloatingIpFromNodeAndDeallocate = removeFloatingIpFromNodeAndDeallocate;
|
||||
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
|
||||
this.securityGroupExtension = securityGroupExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(NodeMetadata node) {
|
||||
final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(node.getId());
|
||||
removeFloatingIpFromNodeifAny(regionAndId);
|
||||
return removeSecurityGroupCreatedByJcloudsAndInvalidateCache(regionAndId.getRegion(), node.getTags());
|
||||
return removeSecurityGroupCreatedByJcloudsAndInvalidateCache(node.getTags());
|
||||
}
|
||||
|
||||
public boolean removeSecurityGroupCreatedByJcloudsAndInvalidateCache(String regionId, Set<String> tags) {
|
||||
public boolean removeSecurityGroupCreatedByJcloudsAndInvalidateCache(Set<String> tags) {
|
||||
String securityGroupIdCreatedByJclouds = getSecurityGroupIdCreatedByJclouds(tags);
|
||||
if (securityGroupIdCreatedByJclouds != null) {
|
||||
SecurityGroup securityGroup = novaApi.getSecurityGroupApi(regionId).get().get(securityGroupIdCreatedByJclouds);
|
||||
RegionAndName regionAndName = RegionAndName.fromRegionAndName(regionId, securityGroup.getName());
|
||||
logger.debug(">> deleting securityGroup(%s)", regionAndName);
|
||||
novaApi.getSecurityGroupApi(regionId).get().delete(securityGroupIdCreatedByJclouds);
|
||||
securityGroupMap.invalidate(regionAndName);
|
||||
logger.debug("<< deleted securityGroup(%s)", regionAndName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return securityGroupExtension.removeSecurityGroup(securityGroupIdCreatedByJclouds);
|
||||
}
|
||||
|
||||
private void removeFloatingIpFromNodeifAny(RegionAndId regionAndId) {
|
||||
@ -88,7 +78,7 @@ public class CleanupResources implements Function<NodeMetadata, Boolean> {
|
||||
logger.warn(e, "<< error removing and deallocating ip from node(%s): %s", regionAndId, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getSecurityGroupIdCreatedByJclouds(Set<String> tags) {
|
||||
return FluentIterable.from(tags).filter(new Predicate<String>() {
|
||||
@Override
|
||||
|
@ -17,73 +17,153 @@
|
||||
package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.nameEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.jclouds.Context;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.neutron.v2.NeutronApi;
|
||||
import org.jclouds.openstack.neutron.v2.domain.Rule;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleDirection;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleProtocol;
|
||||
import org.jclouds.openstack.neutron.v2.features.SecurityGroupApi;
|
||||
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.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
|
||||
import org.jclouds.rest.ApiContext;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@Singleton
|
||||
public class CreateSecurityGroupIfNeeded implements Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> {
|
||||
public class CreateSecurityGroupIfNeeded implements Function<RegionSecurityGroupNameAndPorts, SecurityGroup> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final NovaApi novaApi;
|
||||
private final Supplier<Map<String, Location>> locationIndex;
|
||||
private final Function<SecurityGroupInRegion, SecurityGroup> securityGroupInRegionSecurityGroupFunction;
|
||||
private final NeutronSecurityGroupToSecurityGroup.Factory neutronSecurityGroupToSecurityGroup;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("openstack-neutron")
|
||||
Supplier<Context> neutronContextSupplier;
|
||||
|
||||
@Inject
|
||||
public CreateSecurityGroupIfNeeded(NovaApi novaApi) {
|
||||
this.novaApi = checkNotNull(novaApi, "novaApi");
|
||||
@VisibleForTesting
|
||||
public CreateSecurityGroupIfNeeded(NovaApi novaApi, Supplier<Map<String, Location>> locationIndex,
|
||||
Function<SecurityGroupInRegion, SecurityGroup> securityGroupInRegionSecurityGroupFunction,
|
||||
NeutronSecurityGroupToSecurityGroup.Factory neutronSecurityGroupToSecurityGroup) {
|
||||
this.novaApi = novaApi;
|
||||
this.locationIndex = locationIndex;
|
||||
this.securityGroupInRegionSecurityGroupFunction = securityGroupInRegionSecurityGroupFunction;
|
||||
this.neutronSecurityGroupToSecurityGroup = neutronSecurityGroupToSecurityGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupInRegion apply(RegionSecurityGroupNameAndPorts regionSecurityGroupNameAndPorts) {
|
||||
checkNotNull(regionSecurityGroupNameAndPorts, "regionSecurityGroupNameAndPorts");
|
||||
|
||||
public SecurityGroup apply(final RegionSecurityGroupNameAndPorts regionSecurityGroupNameAndPorts) {
|
||||
String regionId = regionSecurityGroupNameAndPorts.getRegion();
|
||||
Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupApi(regionId);
|
||||
checkArgument(api.isPresent(), "Security groups are required, but the extension is not available in region %s!", regionId);
|
||||
final FluentIterable<SecurityGroup> allGroups = api.get().list();
|
||||
logger.debug(">> creating securityGroup %s", regionSecurityGroupNameAndPorts);
|
||||
try {
|
||||
SecurityGroup securityGroup = api.get().createWithDescription(
|
||||
regionSecurityGroupNameAndPorts.getName(), regionSecurityGroupNameAndPorts.getName());
|
||||
Location location = locationIndex.get().get(regionId);
|
||||
|
||||
logger.debug("<< created securityGroup(%s)", securityGroup);
|
||||
for (int port : regionSecurityGroupNameAndPorts.getPorts()) {
|
||||
authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), securityGroup, port);
|
||||
logger.debug(">> creating securityGroup %s", regionSecurityGroupNameAndPorts);
|
||||
|
||||
SecurityGroupApi securityGroupApi = getNeutronSecurityGroupApi(regionId);
|
||||
if (securityGroupApi != null) {
|
||||
org.jclouds.openstack.neutron.v2.domain.SecurityGroup group = securityGroupApi
|
||||
.create(org.jclouds.openstack.neutron.v2.domain.SecurityGroup.CreateSecurityGroup.createBuilder()
|
||||
.name(regionSecurityGroupNameAndPorts.getName()).description("security group created by jclouds")
|
||||
.build());
|
||||
return createSecurityGroupFrom(group, location, regionSecurityGroupNameAndPorts.getPorts());
|
||||
} else {
|
||||
// try to use Nova
|
||||
Optional<? extends org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi> api = novaApi
|
||||
.getSecurityGroupApi(regionId);
|
||||
checkArgument(api.isPresent(),
|
||||
"Security groups are required, but the extension is not available in region %s!", regionId);
|
||||
final FluentIterable<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup> allGroups = api.get().list();
|
||||
logger.debug(">> creating securityGroup %s", regionSecurityGroupNameAndPorts);
|
||||
try {
|
||||
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup novaSecurityGroup = api.get().createWithDescription(
|
||||
regionSecurityGroupNameAndPorts.getName(), regionSecurityGroupNameAndPorts.getName());
|
||||
|
||||
logger.debug("<< created securityGroup(%s)", novaSecurityGroup);
|
||||
for (int port : regionSecurityGroupNameAndPorts.getPorts()) {
|
||||
authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), novaSecurityGroup, port);
|
||||
}
|
||||
return securityGroupInRegionSecurityGroupFunction
|
||||
.apply(new SecurityGroupInRegion(api.get().get(novaSecurityGroup.getId()), regionId, allGroups));
|
||||
} catch (IllegalStateException e) {
|
||||
logger.trace("<< trying to find securityGroup(%s): %s", regionSecurityGroupNameAndPorts, e.getMessage());
|
||||
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group = find(allGroups,
|
||||
nameEquals(regionSecurityGroupNameAndPorts.getName()));
|
||||
logger.debug("<< reused securityGroup(%s)", group.getId());
|
||||
return securityGroupInRegionSecurityGroupFunction
|
||||
.apply(new SecurityGroupInRegion(group, regionId, allGroups));
|
||||
}
|
||||
return new SecurityGroupInRegion(api.get().get(securityGroup.getId()), regionId, allGroups);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.trace("<< trying to find securityGroup(%s): %s", regionSecurityGroupNameAndPorts, e.getMessage());
|
||||
SecurityGroup group = find(allGroups, nameEquals(regionSecurityGroupNameAndPorts.getName()));
|
||||
logger.debug("<< reused securityGroup(%s)", group.getId());
|
||||
return new SecurityGroupInRegion(group, regionId, allGroups);
|
||||
}
|
||||
}
|
||||
|
||||
private void authorizeGroupToItselfAndAllIPsToTCPPort(SecurityGroupApi securityGroupApi,
|
||||
SecurityGroup securityGroup, int port) {
|
||||
logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
securityGroupApi.createRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
|
||||
IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
|
||||
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
private SecurityGroup createSecurityGroupFrom(final org.jclouds.openstack.neutron.v2.domain.SecurityGroup group,
|
||||
Location location, Set<Integer> ports) {
|
||||
SecurityGroup securityGroup = neutronSecurityGroupToSecurityGroup.create(location).apply(group);
|
||||
logger.debug("<< created securityGroup(%s)", securityGroup);
|
||||
|
||||
SecurityGroupApi securityGroupApi = getNeutronSecurityGroupApi(location.getId());
|
||||
try {
|
||||
for (int inboundPort : ports) {
|
||||
logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, inboundPort);
|
||||
securityGroupApi.create(
|
||||
Rule.CreateRule.createBuilder(RuleDirection.INGRESS, RegionAndId.fromSlashEncoded(securityGroup.getId()).getId()).protocol(RuleProtocol.TCP)
|
||||
.portRangeMin(inboundPort).portRangeMax(inboundPort).remoteIpPrefix("0.0.0.0/0").build());
|
||||
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, inboundPort);
|
||||
}
|
||||
return securityGroup;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.trace("<< trying to find securityGroup(%s): %s", group, e.getMessage());
|
||||
|
||||
return securityGroupApi.listSecurityGroups().concat()
|
||||
.filter(new Predicate<org.jclouds.openstack.neutron.v2.domain.SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable org.jclouds.openstack.neutron.v2.domain.SecurityGroup input) {
|
||||
return input.getName().equals(group.getName());
|
||||
}
|
||||
}).transform(neutronSecurityGroupToSecurityGroup.create(location)).first().orNull();
|
||||
}
|
||||
}
|
||||
|
||||
private SecurityGroupApi getNeutronSecurityGroupApi(String region) {
|
||||
if (neutronContextSupplier == null)
|
||||
return null;
|
||||
return ((ApiContext<NeutronApi>) neutronContextSupplier.get()).getApi().getSecurityGroupApi(region);
|
||||
}
|
||||
|
||||
private void authorizeGroupToItselfAndAllIPsToTCPPort(
|
||||
org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi securityGroupApi,
|
||||
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroup, int port) {
|
||||
logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
securityGroupApi.createRuleAllowingCidrBlock(securityGroup.getId(),
|
||||
Ingress.builder().ipProtocol(IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
|
||||
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.openstack.nova.v2_0.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.neutron.v2.domain.Rule;
|
||||
import org.jclouds.openstack.neutron.v2.domain.RuleDirection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
public class NeutronSecurityGroupToSecurityGroup implements Function<org.jclouds.openstack.neutron.v2.domain.SecurityGroup, SecurityGroup> {
|
||||
|
||||
public interface Factory {
|
||||
NeutronSecurityGroupToSecurityGroup create(Location location);
|
||||
}
|
||||
|
||||
private final Location location;
|
||||
|
||||
@Inject
|
||||
public NeutronSecurityGroupToSecurityGroup(@Assisted Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup apply(@Nullable org.jclouds.openstack.neutron.v2.domain.SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
builder.providerId(group.getId());
|
||||
builder.ownerId(group.getTenantId());
|
||||
builder.name(group.getName());
|
||||
final String regionId = location.getId();
|
||||
builder.location(location);
|
||||
|
||||
builder.id(regionId + "/" + group.getId());
|
||||
if (group.getRules() != null) {
|
||||
builder.ipPermissions(filter(transform(group.getRules(), new Function<Rule, IpPermission>() {
|
||||
@Override
|
||||
public IpPermission apply(Rule from) {
|
||||
if (from.getDirection() == RuleDirection.EGRESS) return null;
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
if (from.getProtocol() != null) {
|
||||
builder.ipProtocol(IpProtocol.fromValue(from.getProtocol().name()));
|
||||
} else {
|
||||
builder.ipProtocol(IpProtocol.TCP);
|
||||
}
|
||||
if (from.getPortRangeMin() != null) builder.fromPort(from.getPortRangeMin());
|
||||
if (from.getPortRangeMax() != null) builder.toPort(from.getPortRangeMax());
|
||||
if (from.getRemoteGroupId() != null) {
|
||||
builder.groupId(regionId + "/" + from.getRemoteGroupId());
|
||||
} else if (from.getRemoteIpPrefix() != null){
|
||||
builder.cidrBlock(from.getRemoteIpPrefix());
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
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 org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* A function for transforming a Nova-specific SecurityGroup into a generic
|
||||
* SecurityGroup object.
|
||||
*/
|
||||
public class NovaSecurityGroupToSecurityGroup
|
||||
implements Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public interface Factory {
|
||||
NovaSecurityGroupToSecurityGroup create(Location location);
|
||||
}
|
||||
|
||||
private final Location location;
|
||||
|
||||
@Inject
|
||||
public NovaSecurityGroupToSecurityGroup(@Assisted Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup apply(@Nullable org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
|
||||
SecurityGroupBuilder builder = new SecurityGroupBuilder();
|
||||
builder.providerId(group.getId());
|
||||
builder.ownerId(group.getTenantId());
|
||||
builder.name(group.getName());
|
||||
final String regionId = location.getId();
|
||||
builder.location(location);
|
||||
|
||||
builder.id(regionId + "/" + group.getId());
|
||||
if (group.getRules() != null) {
|
||||
builder.ipPermissions(filter(transform(group.getRules(), new Function<SecurityGroupRule, IpPermission>() {
|
||||
@Override
|
||||
public IpPermission apply(SecurityGroupRule input) {
|
||||
return securityGroupRuleToIpPermission(input);
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private IpPermission securityGroupRuleToIpPermission(SecurityGroupRule rule) {
|
||||
IpPermission.Builder builder = IpPermission.builder();
|
||||
builder.ipProtocol(rule.getIpProtocol());
|
||||
builder.fromPort(rule.getFromPort());
|
||||
builder.toPort(rule.getToPort());
|
||||
final TenantIdAndName ruleGroup = rule.getGroup();
|
||||
if (ruleGroup != null) {
|
||||
builder.groupId(location.getId() + "/" + ruleGroup.getTenantId());
|
||||
}
|
||||
if (rule.getIpRange() != null) {
|
||||
builder.cidrBlock(rule.getIpRange());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
@ -19,54 +19,31 @@ package org.jclouds.openstack.nova.v2_0.compute.loaders;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.util.concurrent.Atomics;
|
||||
|
||||
public class FindSecurityGroupOrCreate extends CacheLoader<RegionAndName, SecurityGroupInRegion> {
|
||||
public class FindSecurityGroupOrCreate extends CacheLoader<RegionAndName, SecurityGroup> {
|
||||
|
||||
protected final Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion;
|
||||
protected final Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator;
|
||||
protected final Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator;
|
||||
|
||||
@Inject
|
||||
public FindSecurityGroupOrCreate(
|
||||
@Named("SECURITYGROUP_PRESENT") Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion,
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator) {
|
||||
this.returnSecurityGroupExistsInRegion = checkNotNull(returnSecurityGroupExistsInRegion,
|
||||
"returnSecurityGroupExistsInRegion");
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator) {
|
||||
this.groupCreator = checkNotNull(groupCreator, "groupCreator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupInRegion load(RegionAndName in) {
|
||||
AtomicReference<RegionAndName> securityGroupInRegionRef = Atomics.newReference(checkNotNull(in,
|
||||
"regionSecurityGroupNameAndPorts"));
|
||||
if (returnSecurityGroupExistsInRegion.apply(securityGroupInRegionRef)) {
|
||||
return returnExistingSecurityGroup(securityGroupInRegionRef);
|
||||
} else {
|
||||
public SecurityGroup load(RegionAndName in) {
|
||||
return createNewSecurityGroup(in);
|
||||
}
|
||||
}
|
||||
|
||||
private SecurityGroupInRegion returnExistingSecurityGroup(AtomicReference<RegionAndName> securityGroupInRegionRef) {
|
||||
RegionAndName securityGroupInRegion = securityGroupInRegionRef.get();
|
||||
checkState(securityGroupInRegion instanceof SecurityGroupInRegion,
|
||||
"programming error: predicate %s should update the atomic reference to the actual security group found",
|
||||
returnSecurityGroupExistsInRegion);
|
||||
return SecurityGroupInRegion.class.cast(securityGroupInRegion);
|
||||
}
|
||||
|
||||
private SecurityGroupInRegion createNewSecurityGroup(RegionAndName in) {
|
||||
private SecurityGroup createNewSecurityGroup(RegionAndName in) {
|
||||
checkState(
|
||||
checkNotNull(in, "regionSecurityGroupNameAndPorts") instanceof RegionSecurityGroupNameAndPorts,
|
||||
"programming error: when issuing get to this cacheloader, you need to pass an instance of RegionSecurityGroupNameAndPorts, not %s",
|
||||
|
@ -80,6 +80,7 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
|
||||
eTo.configDrive(getConfigDrive());
|
||||
eTo.novaNetworks(getNovaNetworks());
|
||||
eTo.availabilityZone(getAvailabilityZone());
|
||||
eTo.blockDeviceMappings(getBlockDeviceMappings());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -33,25 +32,25 @@ import javax.inject.Singleton;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.config.CustomizationResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.AllocateAndAddFloatingIpToNode;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.options.NodeAndNovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -70,8 +69,9 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||
public static final String JCLOUDS_SG_PREFIX = "jclouds_sg";
|
||||
|
||||
private final AllocateAndAddFloatingIpToNode createAndAddFloatingIpToNode;
|
||||
protected final LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupCache;
|
||||
protected final NovaApi novaApi;
|
||||
private final LoadingCache<RegionAndName, SecurityGroup> securityGroupCache;
|
||||
private final NovaApi novaApi;
|
||||
private final SecurityGroupExtension securityGroupExtension;
|
||||
|
||||
@Inject
|
||||
protected ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet(
|
||||
@ -81,13 +81,16 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
AllocateAndAddFloatingIpToNode createAndAddFloatingIpToNode,
|
||||
LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupCache, NovaApi novaApi) {
|
||||
LoadingCache<RegionAndName, SecurityGroup> securityGroupCache,
|
||||
NovaApi novaApi,
|
||||
SecurityGroupExtension securityGroupExtension) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, userExecutor,
|
||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||
this.securityGroupCache = checkNotNull(securityGroupCache, "securityGroupCache");
|
||||
this.createAndAddFloatingIpToNode = checkNotNull(createAndAddFloatingIpToNode,
|
||||
"createAndAddFloatingIpToNode");
|
||||
this.novaApi = checkNotNull(novaApi, "novaApi");
|
||||
this.securityGroupExtension = securityGroupExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,14 +109,8 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||
checkArgument(novaApi.getKeyPairApi(region).isPresent(),
|
||||
"Key Pairs are required by options, but the extension is not available! options: %s", templateOptions);
|
||||
}
|
||||
|
||||
final List<Integer> inboundPorts = Ints.asList(templateOptions.getInboundPorts());
|
||||
if (!templateOptions.getGroups().isEmpty() || !inboundPorts.isEmpty()) {
|
||||
checkArgument(novaApi.getSecurityGroupApi(region).isPresent(),
|
||||
"Security groups are required by options, but the extension is not available! options: %s",
|
||||
templateOptions);
|
||||
}
|
||||
|
||||
|
||||
KeyPair keyPair = null;
|
||||
if (templateOptions.shouldGenerateKeyPair()) {
|
||||
keyPair = generateKeyPair(region, namingConvention.create().sharedNameForGroup(group));
|
||||
@ -132,29 +129,29 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||
ImmutableList.Builder<String> tagsBuilder = ImmutableList.builder();
|
||||
|
||||
if (!templateOptions.getGroups().isEmpty()) {
|
||||
Set<String> securityGroupNames = novaApi.getSecurityGroupApi(region).get().list()
|
||||
.transform(new Function<SecurityGroup, String>() {
|
||||
@Override
|
||||
public String apply(SecurityGroup input) {
|
||||
return input.getName();
|
||||
}
|
||||
})
|
||||
.toSet();
|
||||
Iterable<String> securityGroupNames = Iterables.transform(securityGroupExtension.listSecurityGroups(), new Function<org.jclouds.compute.domain.SecurityGroup, String>() {
|
||||
@Override
|
||||
public String apply(@Nullable org.jclouds.compute.domain.SecurityGroup input) {
|
||||
return input.getName();
|
||||
}
|
||||
});
|
||||
for (String securityGroupName : templateOptions.getGroups()) {
|
||||
checkState(securityGroupNames.contains(securityGroupName), "Cannot find security group with name " + securityGroupName + ". \nSecurity groups available are: \n" + Iterables.toString(securityGroupNames)); // {
|
||||
checkState(Iterables.contains(securityGroupNames, securityGroupName), "Cannot find security group with name " + securityGroupName + ". \nSecurity groups available are: \n" + Iterables.toString(securityGroupNames)); // {
|
||||
}
|
||||
}
|
||||
else if (!inboundPorts.isEmpty()) {
|
||||
SecurityGroupInRegion securityGroupInRegion;
|
||||
|
||||
} else if (!inboundPorts.isEmpty()) {
|
||||
String securityGroupName = namingConvention.create().sharedNameForGroup(group);
|
||||
try {
|
||||
securityGroupInRegion = securityGroupCache.get(new RegionSecurityGroupNameAndPorts(region, securityGroupName, inboundPorts));
|
||||
} catch (ExecutionException e) {
|
||||
throw Throwables.propagate(e.getCause());
|
||||
|
||||
// populate the security group cache with existing security groups
|
||||
for (SecurityGroup existingSecurityGroup : securityGroupExtension.listSecurityGroupsInLocation(template.getLocation())) {
|
||||
securityGroupCache.put(new RegionSecurityGroupNameAndPorts(region, existingSecurityGroup.getName(), inboundPorts), existingSecurityGroup);
|
||||
}
|
||||
templateOptions.securityGroups(securityGroupName);
|
||||
tagsBuilder.add(String.format("%s-%s", JCLOUDS_SG_PREFIX, securityGroupInRegion.getSecurityGroup().getId()));
|
||||
|
||||
SecurityGroup securityGroup = securityGroupCache.getUnchecked(new RegionSecurityGroupNameAndPorts(region, securityGroupName, inboundPorts));
|
||||
templateOptions.securityGroups(securityGroup.getName());
|
||||
tagsBuilder.add(String.format("%s-%s", JCLOUDS_SG_PREFIX, securityGroup.getId()));
|
||||
}
|
||||
|
||||
templateOptions.tags(tagsBuilder.build());
|
||||
|
||||
Map<?, ListenableFuture<Void>> responses = super.execute(group, count, template, goodNodes, badNodes,
|
||||
|
@ -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.openstack.nova.v2_0.domain.regionscoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.openstack.neutron.v2.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
|
||||
|
||||
import com.google.common.base.MoreObjects.ToStringHelper;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
public class NeutronSecurityGroupInRegion extends RegionAndName {
|
||||
protected final SecurityGroup securityGroup;
|
||||
|
||||
protected final Multimap<TenantIdAndName, SecurityGroup> groupsByName;
|
||||
|
||||
public NeutronSecurityGroupInRegion(SecurityGroup securityGroup, String regionId, Iterable<SecurityGroup> allGroupsInRegion) {
|
||||
super(regionId, checkNotNull(securityGroup, "securityGroup").getName());
|
||||
this.securityGroup = securityGroup;
|
||||
this.groupsByName = HashMultimap.create();
|
||||
for (SecurityGroup groupInRegion : allGroupsInRegion) {
|
||||
final TenantIdAndName tenantIdAndName = TenantIdAndName.builder()
|
||||
.tenantId(groupInRegion.getTenantId())
|
||||
.name(groupInRegion.getName())
|
||||
.build();
|
||||
this.groupsByName.put(tenantIdAndName, groupInRegion);
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityGroup getSecurityGroup() {
|
||||
return securityGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of group {@link TenantIdAndName}s to groups.
|
||||
*
|
||||
* The returned value is a collection, to take into account the possibility that certain clouds
|
||||
* may permit duplicate group names.
|
||||
*
|
||||
* @return The map of names to (collections of) groups.
|
||||
*/
|
||||
public Map<TenantIdAndName, Collection<SecurityGroup>> getGroupsByName() {
|
||||
return groupsByName.asMap();
|
||||
}
|
||||
|
||||
// superclass hashCode/equals are good enough, and help us use RegionAndName and SecurityGroupInRegion
|
||||
// interchangeably as Map keys
|
||||
|
||||
@Override
|
||||
protected ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("securityGroup", securityGroup)
|
||||
.add("groupsByName", groupsByName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ package org.jclouds.openstack.nova.v2_0.features;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
@ -31,6 +32,7 @@ import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks;
|
||||
import org.jclouds.Fallbacks.AbsentOn403Or404Or500;
|
||||
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
@ -40,6 +42,7 @@ import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
||||
@ -362,8 +365,8 @@ public interface ServerApi {
|
||||
*
|
||||
* @param id
|
||||
* id of the image
|
||||
* @param metadata
|
||||
* a Map containing the metadata
|
||||
* @param key
|
||||
* a key containing the metadata
|
||||
* @return the value or null if not present
|
||||
*/
|
||||
@Named("server:getMetadata")
|
||||
@ -428,4 +431,19 @@ public interface ServerApi {
|
||||
@ResponseParser(ParseDiagnostics.class)
|
||||
@Fallback(AbsentOn403Or404Or500.class)
|
||||
Optional<Map<String, String>> getDiagnostics(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* Lists Security Groups for a server.
|
||||
|
||||
* @param id
|
||||
* id of the server
|
||||
* @return a list of security groups attached to the server
|
||||
*/
|
||||
@Named("server:getSecurityGroups")
|
||||
@GET
|
||||
@Path("/{id}/os-security-groups")
|
||||
@SelectJson("security_groups")
|
||||
@Fallback(Fallbacks.EmptySetOnNotFoundOr404.class)
|
||||
Set<SecurityGroup> listSecurityGroupForServer(@PathParam("id") String id);
|
||||
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"networks\": [{\"uuid\": \"4ebd35cf-bfe7-4d93-b0d8-eb468ce2245a\"}]}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"networks\":[{\"uuid\":\"4ebd35cf-bfe7-4d93-b0d8-eb468ce2245a\"}]}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -101,7 +101,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"OS-DCF:diskConfig\":\"AUTO\"}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"OS-DCF:diskConfig\":\"AUTO\"}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -136,7 +136,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"config_drive\":\"true\"}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"config_drive\":\"true\"}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -170,7 +170,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"networks\":[{\"uuid\":\"12345\", \"port\":\"67890\", \"fixed_ip\":\"192.168.0.1\"},{\"uuid\":\"54321\", \"port\":\"09876\", \"fixed_ip\":\"192.168.0.2\"},{\"uuid\":\"non-nova-uuid\"}]}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"networks\":[{\"uuid\":\"12345\",\"port\":\"67890\",\"fixed_ip\":\"192.168.0.1\"},{\"uuid\":\"54321\",\"port\":\"09876\",\"fixed_ip\":\"192.168.0.2\"},{\"uuid\":\"non-nova-uuid\"}]}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -217,7 +217,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"security_groups\":[{\"name\":\"group1\"}, {\"name\":\"group2\"}]}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"security_groups\":[{\"name\":\"group1\"},{\"name\":\"group2\"}]}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -258,7 +258,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"key_name\":\"foo\"}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\",\"key_name\":\"foo\"}}", "application/json"))
|
||||
.build();
|
||||
|
||||
|
||||
@ -301,7 +301,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\"}}", "application/json"))
|
||||
"{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"2235\",\"flavorRef\":\"100\"}}", "application/json"))
|
||||
.build();
|
||||
|
||||
HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
|
@ -225,7 +225,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-1\",\"imageRef\":\"14\",\"flavorRef\":\"1\",\"metadata\":{\"jclouds_tags\":\"jclouds_sg-2769\"},\"key_name\":\"jclouds-test-0\",\"security_groups\":[{\"name\":\"jclouds-test\"}]}}",
|
||||
"{\"server\":{\"name\":\"test-1\",\"imageRef\":\"2235\",\"flavorRef\":\"1\",\"metadata\":{\"jclouds_tags\":\"jclouds_sg-RegionOne/2769\"},\"key_name\":\"jclouds-test-0\",\"security_groups\":[{\"name\":\"jclouds-test\"}]}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpResponse createdServer = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -280,7 +280,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-0\",\"imageRef\":\"14\",\"flavorRef\":\"1\",\"metadata\":{\"jclouds_tags\":\"jclouds_sg-2769\"},\"key_name\":\"testkeypair\",\"security_groups\":[{\"name\":\"jclouds-test\"}]}}",
|
||||
"{\"server\":{\"name\":\"test-0\",\"imageRef\":\"2235\",\"flavorRef\":\"1\",\"metadata\":{\"jclouds_tags\":\"jclouds_sg-RegionOne/2769\"},\"key_name\":\"testkeypair\",\"security_groups\":[{\"name\":\"jclouds-test\"}]}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpResponse createdServer = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
@ -349,7 +349,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"server\":{\"name\":\"test-0\",\"imageRef\":\"14\",\"flavorRef\":\"1\",\"key_name\":\"testkeypair\",\"security_groups\":[{\"name\":\"name1\"}]}}",
|
||||
"{\"server\":{\"name\":\"test-0\",\"imageRef\":\"2235\",\"flavorRef\":\"1\",\"key_name\":\"testkeypair\",\"security_groups\":[{\"name\":\"name1\"}]}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpResponse createdServer = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
|
@ -21,12 +21,15 @@ import static java.util.logging.Logger.getAnonymousLogger;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.logging.config.LoggingModule;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.openstack.keystone.config.KeystoneProperties;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaProperties;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
@Test(groups = "live", singleThreaded = true, testName = "NovaComputeServiceLiveTest")
|
||||
@ -40,7 +43,17 @@ public class NovaComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
protected Module getSshModule() {
|
||||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected LoggingModule getLoggingModule() {
|
||||
return new SLF4JLoggingModule();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Module> setupModules() {
|
||||
return ImmutableSet.of(getLoggingModule(), credentialStoreModule, getSshModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testOptionToNotBlock() {
|
||||
// start call is blocking anyway.
|
||||
@ -49,12 +62,14 @@ public class NovaComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||
public void testSuspendResume() throws Exception {
|
||||
try {
|
||||
// may fail because of lack of AdminActions extension or non-admin user, so log and continue
|
||||
// may fail because of lack of AdminActions extension or non-admin user, so log
|
||||
// and continue
|
||||
super.testSuspendResume();
|
||||
} catch (AuthorizationException e) {
|
||||
getAnonymousLogger().info("testSuspendResume() threw, probably due to lack of privileges: " + e.getMessage());
|
||||
} catch (UnsupportedOperationException e) {
|
||||
getAnonymousLogger().info("testSuspendResume() threw, probably due to unavailable AdminActions extension: " + e.getMessage());
|
||||
getAnonymousLogger().info(
|
||||
"testSuspendResume() threw, probably due to unavailable AdminActions extension: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.extensions;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.jclouds.Context;
|
||||
import org.jclouds.ContextBuilder;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.extensions.SecurityGroupExtension;
|
||||
import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.config.ContextLinking;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.openstack.neutron.v2.NeutronApi;
|
||||
import org.jclouds.rest.ApiContext;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Module;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Live test for openstack-neutron {@link SecurityGroupExtension} implementation.
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "NeutronSecurityGroupExtensionLiveTest")
|
||||
public class NeutronSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.CONSOLE;
|
||||
|
||||
private Context neutronApiContext;
|
||||
|
||||
public NeutronSecurityGroupExtensionLiveTest() {
|
||||
provider = "openstack-nova";
|
||||
|
||||
Properties overrides = setupProperties();
|
||||
neutronApiContext = ContextBuilder.newBuilder("openstack-neutron")
|
||||
.endpoint(setIfTestSystemPropertyPresent(overrides,
|
||||
"openstack-nova.endpoint"))
|
||||
.credentials(setIfTestSystemPropertyPresent(overrides,
|
||||
"openstack-nova.identity"),
|
||||
setIfTestSystemPropertyPresent(overrides, "openstack-nova.credential"))
|
||||
.modules(ImmutableSet.<Module>of(
|
||||
new SshjSshClientModule(),
|
||||
new SLF4JLoggingModule())
|
||||
)
|
||||
.build(new TypeToken<ApiContext<NeutronApi>>() {});
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true)
|
||||
public void testListSecurityGroups() throws RunNodesException, InterruptedException, ExecutionException {
|
||||
skipIfSecurityGroupsNotSupported();
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
|
||||
|
||||
for (SecurityGroup securityGroup : securityGroupExtension.get().listSecurityGroups()) {
|
||||
logger.info(securityGroup.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, singleThreaded = true)
|
||||
public void testListSecurityGroupsForNode() throws RunNodesException, InterruptedException, ExecutionException {
|
||||
skipIfSecurityGroupsNotSupported();
|
||||
ComputeService computeService = view.getComputeService();
|
||||
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
|
||||
|
||||
for (SecurityGroup securityGroup : securityGroupExtension.get().listSecurityGroupsForNode("uk-1/97374b9f-c706-4c4a-ae5a-48b6d2e58db9")) {
|
||||
logger.info(securityGroup.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@Override
|
||||
protected void tearDownContext() {
|
||||
super.tearDownContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Module> setupModules() {
|
||||
return ImmutableSet.<Module> of(ContextLinking.linkContext(neutronApiContext), getLoggingModule(), credentialStoreModule, getSshModule());
|
||||
}
|
||||
|
||||
}
|
@ -113,14 +113,13 @@ public class NovaSecurityGroupExtensionExpectTest extends BaseNovaComputeService
|
||||
payloadFromResource("/server_with_security_groups_extension.json")).build();
|
||||
|
||||
HttpRequest list = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/os-security-groups")).headers(
|
||||
URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb/os-security-groups")).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResource("/securitygroup_list.json")).build();
|
||||
|
||||
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
|
||||
requestResponseMap.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess);
|
||||
requestResponseMap.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
|
||||
|
@ -46,7 +46,6 @@ import com.google.common.collect.Iterables;
|
||||
@Test(groups = "live", singleThreaded = true, testName = "NovaSecurityGroupExtensionLiveTest")
|
||||
public class NovaSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.CONSOLE;
|
||||
|
@ -17,11 +17,13 @@
|
||||
package org.jclouds.openstack.nova.v2_0.compute.loaders;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.jclouds.compute.domain.SecurityGroup;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
@ -29,111 +31,99 @@ import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@Test(groups = "unit", singleThreaded = true, testName = "FindSecurityGroupOrCreateTest")
|
||||
public class FindSecurityGroupOrCreateTest {
|
||||
@Test(groups = "unit", singleThreaded = true, testName = "FindSecurityGroupInRegionOrCreateTest")
|
||||
public class FindSecurityGroupInRegionOrCreateTest {
|
||||
|
||||
@Test
|
||||
public void testWhenNotFoundCreatesANewSecurityGroup() throws Exception {
|
||||
Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion = Predicates.alwaysFalse();
|
||||
|
||||
SecurityGroupInRegion securityGroupInRegion = createMock(SecurityGroupInRegion.class);
|
||||
SecurityGroup securityGroup = createMock(SecurityGroup.class);
|
||||
|
||||
RegionSecurityGroupNameAndPorts input = new RegionSecurityGroupNameAndPorts("region", "groupName", ImmutableSet
|
||||
.<Integer> of(22, 8080));
|
||||
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator = Functions.forMap(ImmutableMap
|
||||
.<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> of(input, securityGroupInRegion));
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator = Functions.forMap(ImmutableMap
|
||||
.of(input, securityGroup));
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInRegion, groupCreator);
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(groupCreator);
|
||||
|
||||
assertEquals(parser.load(input), securityGroupInRegion);
|
||||
assertEquals(parser.load(input), securityGroup);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false) // TODO does it apply now?
|
||||
public void testWhenFoundReturnsSecurityGroupFromAtomicReferenceValueUpdatedDuringPredicateCheck() throws Exception {
|
||||
SecurityGroup expected = new SecurityGroupBuilder().id("region/id").name("name").build();
|
||||
final SecurityGroupInRegion securityGroupInRegion = createMock(SecurityGroupInRegion.class);
|
||||
final org.jclouds.openstack.nova.v2_0.domain.SecurityGroup novaSecurityGroup = createMock(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.class);
|
||||
|
||||
Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion = new Predicate<AtomicReference<RegionAndName>>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(AtomicReference<RegionAndName> input) {
|
||||
input.set(securityGroupInRegion);
|
||||
return true;
|
||||
}
|
||||
expect(novaSecurityGroup.getId()).andReturn("id").anyTimes();
|
||||
expect(novaSecurityGroup.getName()).andReturn("name");
|
||||
replay(novaSecurityGroup);
|
||||
|
||||
};
|
||||
expect(securityGroupInRegion.getRegion()).andReturn("region");
|
||||
expect(securityGroupInRegion.getSecurityGroup()).andReturn(novaSecurityGroup).anyTimes();
|
||||
replay(securityGroupInRegion);
|
||||
|
||||
RegionAndName input = RegionAndName.fromRegionAndName("region", "groupName");
|
||||
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion>() {
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroup>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInRegion apply(RegionSecurityGroupNameAndPorts input) {
|
||||
public SecurityGroup apply(RegionSecurityGroupNameAndPorts input) {
|
||||
fail();
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInRegion, groupCreator);
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(groupCreator);
|
||||
|
||||
assertEquals(parser.load(input), securityGroupInRegion);
|
||||
assertEquals(parser.load(input), expected);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
@Test(expectedExceptions = IllegalStateException.class, enabled = false) // TODO does it apply now?
|
||||
public void testWhenFoundPredicateMustUpdateAtomicReference() throws Exception {
|
||||
|
||||
Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion = Predicates.alwaysTrue();
|
||||
|
||||
RegionAndName input = RegionAndName.fromRegionAndName("region", "groupName");
|
||||
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion>() {
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroup>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInRegion apply(RegionSecurityGroupNameAndPorts input) {
|
||||
public SecurityGroup apply(RegionSecurityGroupNameAndPorts input) {
|
||||
fail();
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInRegion, groupCreator);
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(groupCreator);
|
||||
|
||||
parser.load(input);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testWhenNotFoundInputMustBeRegionSecurityGroupNameAndPorts() throws Exception {
|
||||
Predicate<AtomicReference<RegionAndName>> returnSecurityGroupExistsInRegion = Predicates.alwaysFalse();
|
||||
|
||||
RegionAndName input = RegionAndName.fromRegionAndName("region", "groupName");
|
||||
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion>() {
|
||||
Function<RegionSecurityGroupNameAndPorts, SecurityGroup> groupCreator = new Function<RegionSecurityGroupNameAndPorts, SecurityGroup>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInRegion apply(RegionSecurityGroupNameAndPorts input) {
|
||||
public SecurityGroup apply(RegionSecurityGroupNameAndPorts input) {
|
||||
fail();
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInRegion, groupCreator);
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(groupCreator);
|
||||
|
||||
parser.load(input);
|
||||
|
@ -19,6 +19,7 @@ package org.jclouds.openstack.nova.v2_0.features;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
@ -30,6 +31,7 @@ import org.jclouds.openstack.nova.v2_0.options.RebuildServerOptions;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseCreatedServerTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataListTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataUpdateTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseSecurityGroupListTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseServerDetailsStatesTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseServerDiagnostics;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseServerListTest;
|
||||
@ -498,4 +500,35 @@ public class ServerApiExpectTest extends BaseNovaApiExpectTest {
|
||||
HttpResponse.builder().statusCode(statusCode).build()).getServerApi("az-1.region-a.geo-1").getDiagnostics(serverId).isPresent());
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSecurityGroupsForServerWhenResponseIs200() throws Exception {
|
||||
String serverId = "123";
|
||||
HttpRequest getDiagnostics = HttpRequest.builder()
|
||||
.method("GET")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/" + serverId + "/os-security-groups")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.build();
|
||||
|
||||
HttpResponse serverDiagnosticsResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
|
||||
.payload(payloadFromResourceWithContentType("/securitygroup_list.json", "application/json; charset=UTF-8")).build();
|
||||
|
||||
NovaApi apiWithNewServer = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, getDiagnostics, serverDiagnosticsResponse);
|
||||
assertEquals(Iterables.toString(apiWithNewServer.getServerApi("az-1.region-a.geo-1").listSecurityGroupForServer(serverId)),
|
||||
Iterables.toString(new ParseSecurityGroupListTest().expected()));
|
||||
}
|
||||
|
||||
public void testListSecurityGroupsForServerWhenResponseIs404() throws Exception {
|
||||
String serverId = "123";
|
||||
HttpRequest getSecurityGroups = HttpRequest.builder()
|
||||
.method("GET")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/" + serverId + "/os-security-groups")
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.build();
|
||||
|
||||
assertTrue(requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess, getSecurityGroups,
|
||||
HttpResponse.builder().statusCode(404).build()).getServerApi("az-1.region-a.geo-1").listSecurityGroupForServer(serverId).isEmpty());
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.BlockDeviceMapping;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Network;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.ServerCreated;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneApi;
|
||||
@ -88,7 +89,7 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
|
||||
for (String regionId : regions) {
|
||||
ServerApi serverApi = api.getServerApi(regionId);
|
||||
Optional<? extends AvailabilityZoneApi> availabilityZoneApi = api.getAvailabilityZoneApi(regionId);
|
||||
availabilityZone = availabilityZoneApi.isPresent() ? Iterables.getLast(availabilityZoneApi.get().list()).getName() : "nova";
|
||||
availabilityZone = availabilityZoneApi.isPresent() ? Iterables.get(availabilityZoneApi.get().list(), 0).getName() : "nova";
|
||||
try {
|
||||
serverId = createServer(regionId, availabilityZone).getId();
|
||||
Server server = serverApi.get(serverId);
|
||||
@ -226,6 +227,18 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(description = "GET /v${apiVersion}/servers/{id}/os-security-groups")
|
||||
public void testListSecurityGroupForServer() throws Exception {
|
||||
for (String regionId : regions) {
|
||||
ServerApi serverApi = api.getServerApi(regionId);
|
||||
for (Resource server : serverApi.list().concat()) {
|
||||
for (SecurityGroup securityGroup : serverApi.listSecurityGroupForServer(server.getId())) {
|
||||
checkSecurityGroup(securityGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Server createServer(String regionId, String availabilityZoneId) {
|
||||
ServerApi serverApi = api.getServerApi(regionId);
|
||||
|
||||
@ -250,4 +263,10 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
|
||||
checkResource(server);
|
||||
assertNotNull(server.getFlavor());
|
||||
}
|
||||
|
||||
private void checkSecurityGroup(SecurityGroup securityGroup) {
|
||||
assertNotNull(securityGroup.getId());
|
||||
assertNotNull(securityGroup.getName());
|
||||
assertNotNull(securityGroup.getRules());
|
||||
}
|
||||
}
|
||||
|
@ -19,16 +19,28 @@ package org.jclouds.openstack.nova.v2_0.functions;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.inject.Injector;
|
||||
import org.jclouds.compute.domain.SecurityGroupBuilder;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.net.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NeutronSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInRegionToSecurityGroup;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseComputeServiceTypicalSecurityGroupTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -48,6 +60,18 @@ public class CreateSecurityGroupIfNeededTest extends BaseNovaApiExpectTest {
|
||||
"{\"security_group\":{\"name\":\"jclouds_mygroup\",\"description\":\"jclouds_mygroup\"}}",
|
||||
"application/json")).build();
|
||||
|
||||
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("openstack-nova").description(
|
||||
"openstack-nova").build();
|
||||
Location region = new LocationBuilder().id("az-1.region-a.geo-1").description("az-1.region-a.geo-1").scope(
|
||||
LocationScope.REGION).parent(provider).build();
|
||||
Supplier<Map<String, Location>> locationIndex = Suppliers.<Map<String, Location>> ofInstance(ImmutableMap
|
||||
.<String, Location> of("az-1.region-a.geo-1", region));
|
||||
|
||||
Function<SecurityGroupInRegion, org.jclouds.compute.domain.SecurityGroup> securityGroupInRegionSecurityGroupFunction = new NovaSecurityGroupInRegionToSecurityGroup(locationIndex);
|
||||
|
||||
Injector injector = createInjector(Functions.forMap(ImmutableMap.<HttpRequest, HttpResponse>of()), createModule(), setupProperties());
|
||||
NeutronSecurityGroupToSecurityGroup.Factory factory = injector.getInstance(NeutronSecurityGroupToSecurityGroup.Factory.class);
|
||||
|
||||
private final int groupId = 2769;
|
||||
|
||||
public void testCreateNewGroup() throws Exception {
|
||||
@ -126,13 +150,46 @@ public class CreateSecurityGroupIfNeededTest extends BaseNovaApiExpectTest {
|
||||
|
||||
NovaApi apiCanCreateSecurityGroup = requestsSendResponses(builder.build());
|
||||
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(apiCanCreateSecurityGroup);
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(apiCanCreateSecurityGroup, locationIndex, securityGroupInRegionSecurityGroupFunction, factory);
|
||||
|
||||
// we can find it
|
||||
final SecurityGroup expected = new ParseComputeServiceTypicalSecurityGroupTest().expected();
|
||||
org.jclouds.compute.domain.SecurityGroup expected = new SecurityGroupBuilder()
|
||||
.id("az-1.region-a.geo-1/2769")
|
||||
.providerId("2769")
|
||||
.name("jclouds_mygroup")
|
||||
.location(locationIndex.get().get("az-1.region-a.geo-1"))
|
||||
.ipPermissions(ImmutableList.of(
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.groupIds(ImmutableList.of("az-1.region-a.geo-1/2769"))
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(8080)
|
||||
.toPort(8080)
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(8080)
|
||||
.toPort(8080)
|
||||
.groupIds(ImmutableList.of("az-1.region-a.geo-1/2769"))
|
||||
.build()
|
||||
)
|
||||
)
|
||||
.build();
|
||||
|
||||
assertEquals(
|
||||
fn.apply(new RegionSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds_mygroup", ImmutableSet.of(22, 8080))).toString(),
|
||||
new SecurityGroupInRegion(expected, "az-1.region-a.geo-1", ImmutableList.of(expected)).toString());
|
||||
fn.apply(new RegionSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds_mygroup", ImmutableSet.of(22, 8080))).toString(),
|
||||
expected.toString().trim());
|
||||
|
||||
}
|
||||
|
||||
@ -163,12 +220,45 @@ public class CreateSecurityGroupIfNeededTest extends BaseNovaApiExpectTest {
|
||||
|
||||
NovaApi apiWhenSecurityGroupsExist = requestsSendResponses(builder.build());
|
||||
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(apiWhenSecurityGroupsExist);
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(apiWhenSecurityGroupsExist, locationIndex, securityGroupInRegionSecurityGroupFunction, factory);
|
||||
|
||||
// we can find it
|
||||
final SecurityGroup expected = new ParseComputeServiceTypicalSecurityGroupTest().expected();
|
||||
org.jclouds.compute.domain.SecurityGroup expected = new SecurityGroupBuilder()
|
||||
.id("az-1.region-a.geo-1/2769")
|
||||
.providerId("2769")
|
||||
.name("jclouds_mygroup")
|
||||
.location(locationIndex.get().get("az-1.region-a.geo-1"))
|
||||
.ipPermissions(ImmutableList.of(
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.groupIds(ImmutableList.of("az-1.region-a.geo-1/2769"))
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(8080)
|
||||
.toPort(8080)
|
||||
.cidrBlock("0.0.0.0/0")
|
||||
.build(),
|
||||
IpPermission.builder()
|
||||
.ipProtocol(IpProtocol.TCP)
|
||||
.fromPort(8080)
|
||||
.toPort(8080)
|
||||
.groupIds(ImmutableList.of("az-1.region-a.geo-1/2769"))
|
||||
.build()
|
||||
)
|
||||
)
|
||||
.build();
|
||||
assertEquals(
|
||||
fn.apply(new RegionSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds_mygroup", ImmutableSet.of(22, 8080))).toString(),
|
||||
new SecurityGroupInRegion(expected, "az-1.region-a.geo-1", ImmutableList.of(expected)).toString());
|
||||
fn.apply(new RegionSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds_mygroup", ImmutableSet.of(22, 8080))).toString(),
|
||||
expected.toString().trim()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -49,23 +49,21 @@ public class ParseComputeServiceTypicalSecurityGroupTest extends BaseItemParserT
|
||||
public SecurityGroup expected() {
|
||||
|
||||
Set<SecurityGroupRule> securityGroupRules = ImmutableSet.of(
|
||||
SecurityGroupRule.builder().fromPort(22)
|
||||
.ipProtocol(IpProtocol.TCP).toPort(22).parentGroupId("2769")
|
||||
SecurityGroupRule.builder().fromPort(22).ipProtocol(IpProtocol.TCP).toPort(22).parentGroupId("2769")
|
||||
.ipRange("0.0.0.0/0").id("10331").build(),
|
||||
SecurityGroupRule.builder().fromPort(22).group(TenantIdAndName.builder().tenantId("37936628937291").name("jclouds_mygroup").build())
|
||||
.ipProtocol(IpProtocol.TCP).toPort(22).parentGroupId("2769")
|
||||
.id("10332").build(),
|
||||
SecurityGroupRule.builder().fromPort(8080)
|
||||
.ipProtocol(IpProtocol.TCP).toPort(8080).parentGroupId("2769")
|
||||
SecurityGroupRule.builder().fromPort(22)
|
||||
.group(TenantIdAndName.builder().tenantId("37936628937291").name("jclouds_mygroup").build())
|
||||
.ipProtocol(IpProtocol.TCP).toPort(22).parentGroupId("2769").id("10332").build(),
|
||||
SecurityGroupRule.builder().fromPort(8080).ipProtocol(IpProtocol.TCP).toPort(8080).parentGroupId("2769")
|
||||
.ipRange("0.0.0.0/0").id("10333").build(),
|
||||
SecurityGroupRule.builder().fromPort(8080).group(TenantIdAndName.builder().tenantId("37936628937291").name("jclouds_mygroup").build())
|
||||
.ipProtocol(IpProtocol.TCP).toPort(8080).parentGroupId("2769")
|
||||
.id("10334").build()
|
||||
);
|
||||
SecurityGroupRule.builder().fromPort(8080)
|
||||
.group(TenantIdAndName.builder().tenantId("37936628937291").name("jclouds_mygroup").build())
|
||||
.ipProtocol(IpProtocol.TCP).toPort(8080).parentGroupId("2769").id("10334").build());
|
||||
|
||||
return SecurityGroup.builder().description("jclouds_mygroup").id("2769").tenantId("37936628937291").rules(securityGroupRules)
|
||||
.name("jclouds_mygroup").build();
|
||||
return SecurityGroup.builder().description("jclouds_mygroup").id("2769").tenantId("37936628937291")
|
||||
.rules(securityGroupRules).name("jclouds_mygroup").build();
|
||||
}
|
||||
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
|
@ -416,6 +416,33 @@
|
||||
"project_id": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": "ACTIVE",
|
||||
"updated": "2012-03-12T07:49:23Z",
|
||||
"name": "Ubuntu Lucid 16.04 LTS Server 64-bit (Kernel)",
|
||||
"links": [
|
||||
{
|
||||
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/37936628937291/images/1235",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1235",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created": "2011-12-21T11:39:58Z",
|
||||
"progress": 100,
|
||||
"id": "2235",
|
||||
"metadata": {
|
||||
"image_location": "local",
|
||||
"image_state": "available",
|
||||
"min_ram": 0,
|
||||
"min_disk": 0,
|
||||
"architecture": "amd64",
|
||||
"owner": null,
|
||||
"project_id": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": "ACTIVE",
|
||||
"updated": "2012-03-12T07:49:05Z",
|
||||
|
@ -71,6 +71,33 @@
|
||||
"owner": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": "ACTIVE",
|
||||
"updated": "2012-03-12T07:49:23Z",
|
||||
"name": "Ubuntu Lucid 16.04 LTS Server 64-bit (Kernel)",
|
||||
"links": [
|
||||
{
|
||||
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/37936628937291/images/1235",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1235",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"created": "2011-12-21T11:39:58Z",
|
||||
"progress": 100,
|
||||
"id": "2235",
|
||||
"metadata": {
|
||||
"image_location": "local",
|
||||
"image_state": "available",
|
||||
"min_ram": 0,
|
||||
"min_disk": 0,
|
||||
"architecture": "amd64",
|
||||
"owner": null,
|
||||
"project_id": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": "ACTIVE",
|
||||
"updated": "2012-02-02T19:10:33Z",
|
||||
|
@ -13,7 +13,7 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
<appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>target/jclouds-compute.log</file>
|
||||
<file>target/test-data/jclouds-compute.log</file>
|
||||
<encoder>
|
||||
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||
</encoder>
|
||||
|
@ -406,17 +406,18 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
|
||||
|
||||
@Test(groups = {"integration", "live"}, singleThreaded = true)
|
||||
public void testSecurityGroupCacheInvalidatedWhenDeletedExternally() throws Exception {
|
||||
String testSecurityGroupName = secGroupNameToDelete + "-externally";
|
||||
ComputeService computeService = view.getComputeService();
|
||||
Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
|
||||
assertTrue(securityGroupExtension.isPresent(), "security extension was not present");
|
||||
final SecurityGroupExtension security = securityGroupExtension.get();
|
||||
final SecurityGroup seedGroup = security.createSecurityGroup(secGroupNameToDelete, getNodeTemplate().getLocation());
|
||||
final SecurityGroup seedGroup = security.createSecurityGroup(testSecurityGroupName, getNodeTemplate().getLocation());
|
||||
|
||||
deleteSecurityGroupFromAnotherView(seedGroup);
|
||||
|
||||
boolean deleted = security.removeSecurityGroup(seedGroup.getId());
|
||||
assertFalse(deleted, "SG deleted externally so should've failed deletion");
|
||||
final SecurityGroup recreatedGroup = security.createSecurityGroup(secGroupNameToDelete, getNodeTemplate().getLocation());
|
||||
final SecurityGroup recreatedGroup = security.createSecurityGroup(testSecurityGroupName, getNodeTemplate().getLocation());
|
||||
|
||||
// Makes sure the security group exists and is re-created and is not just returned from cache
|
||||
security.addIpPermission(IpPermission.builder()
|
||||
|
Loading…
x
Reference in New Issue
Block a user