You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/09/17 20:51:08 UTC
git commit: JCLOUDS-267. Add SecurityGroupExtension support for Nova.
Updated Branches:
refs/heads/master e29cdb142 -> 389ba6c94
JCLOUDS-267. Add SecurityGroupExtension support for Nova.
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/389ba6c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/389ba6c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/389ba6c9
Branch: refs/heads/master
Commit: 389ba6c94a44b3e1331dfa4be5f159f6e5e33bae
Parents: e29cdb1
Author: Andrew Bayer <an...@gmail.com>
Authored: Fri Sep 13 10:31:02 2013 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Tue Sep 17 11:47:42 2013 -0700
----------------------------------------------------------------------
.../config/NovaComputeServiceContextModule.java | 16 +-
.../extensions/NovaSecurityGroupExtension.java | 422 ++++++++++++++++++
.../NovaSecurityGroupInZoneToSecurityGroup.java | 73 ++++
.../NovaSecurityGroupToSecurityGroup.java | 13 +-
.../loaders/FindSecurityGroupOrCreate.java | 3 +-
.../domain/zonescoped/SecurityGroupInZone.java | 2 +-
.../nova/v2_0/extensions/SecurityGroupApi.java | 2 +-
.../predicates/SecurityGroupPredicates.java | 139 +++++-
.../NovaSecurityGroupExtensionExpectTest.java | 423 +++++++++++++++++++
.../NovaSecurityGroupExtensionLiveTest.java | 35 ++
...aSecurityGroupInZoneToSecurityGroupTest.java | 93 ++++
.../NovaSecurityGroupToSecurityGroupTest.java | 89 ++--
.../predicates/SecurityGroupPredicatesTest.java | 93 +++-
.../securitygroup_details_extension.json | 34 ++
...securitygroup_details_extension_norules.json | 10 +
.../resources/securitygroup_list_extension.json | 51 +++
.../securitygrouprule_created_cidr.json | 13 +
.../securitygrouprule_created_group.json | 14 +
.../server_with_security_groups_extension.json | 1 +
19 files changed, 1467 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
index 57a341d..311d4ab 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
@@ -40,6 +40,7 @@ import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.domain.Location;
@@ -49,10 +50,12 @@ import org.jclouds.net.domain.IpPermission;
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeService;
import org.jclouds.openstack.nova.v2_0.compute.NovaComputeServiceAdapter;
import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
+import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaSecurityGroupExtension;
import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNeeded;
import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInZoneToHardware;
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInZoneToImage;
import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
+import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInZoneToSecurityGroup;
import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByZoneId;
import org.jclouds.openstack.nova.v2_0.compute.functions.SecurityGroupRuleToIpPermission;
@@ -119,6 +122,9 @@ public class NovaComputeServiceContextModule extends
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup>>() {
}).to(NovaSecurityGroupToSecurityGroup.class);
+ bind(new TypeLiteral<Function<SecurityGroupInZone, SecurityGroup>>() {
+ }).to(NovaSecurityGroupInZoneToSecurityGroup.class);
+
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
}).to(OrphanedGroupsByZoneId.class);
@@ -153,6 +159,9 @@ public class NovaComputeServiceContextModule extends
bind(new TypeLiteral<ImageExtension>() {
}).to(NovaImageExtension.class);
+
+ bind(new TypeLiteral<SecurityGroupExtension>() {
+ }).to(NovaSecurityGroupExtension.class);
}
@Override
@@ -187,7 +196,7 @@ public class NovaComputeServiceContextModule extends
@Provides
@Singleton
- @Named(TIMEOUT_SECURITYGROUP_PRESENT)
+ @Named("SECURITYGROUP_PRESENT")
protected Predicate<AtomicReference<ZoneAndName>> securityGroupEventualConsistencyDelay(
FindSecurityGroupWithNameAndReturnTrue in,
@Named(TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) {
@@ -269,4 +278,9 @@ public class NovaComputeServiceContextModule extends
protected Optional<ImageExtension> provideImageExtension(Injector i) {
return Optional.of(i.getInstance(ImageExtension.class));
}
+
+ @Override
+ protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
+ return Optional.of(i.getInstance(SecurityGroupExtension.class));
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
new file mode 100644
index 0000000..416e3a9
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
@@ -0,0 +1,422 @@
+/*
+ * 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.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;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleProtocol;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleStartPort;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.location.Zone;
+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.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.zonescoped.SecurityGroupInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+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;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public class NovaSecurityGroupExtension implements SecurityGroupExtension {
+
+ protected final NovaApi api;
+ protected final ListeningExecutorService userExecutor;
+ protected final Supplier<Set<String>> zoneIds;
+ protected final Function<SecurityGroupInZone, SecurityGroup> groupConverter;
+ protected final LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator;
+ protected final GroupNamingConvention.Factory namingConvention;
+
+ @Inject
+ public NovaSecurityGroupExtension(NovaApi api,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ @Zone Supplier<Set<String>> zoneIds,
+ Function<SecurityGroupInZone, SecurityGroup> groupConverter,
+ LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator,
+ GroupNamingConvention.Factory namingConvention) {
+
+ this.api = checkNotNull(api, "api");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ this.zoneIds = checkNotNull(zoneIds, "zoneIds");
+ this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+ this.groupCreator = checkNotNull(groupCreator, "groupCreator");
+ this.namingConvention = checkNotNull(namingConvention, "namingConvention");
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroups() {
+ Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroups();
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
+ String zone = location.getId();
+ if (zone == null) {
+ return ImmutableSet.of();
+ }
+ return listSecurityGroupsInLocation(zone);
+ }
+
+ public Set<SecurityGroup> listSecurityGroupsInLocation(String zone) {
+ Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroupsByZone(zone);
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
+ String zone = zoneAndId.getZone();
+ String instanceId = zoneAndId.getId();
+
+ Optional<? extends ServerWithSecurityGroupsApi> serverApi = api.getServerWithSecurityGroupsExtensionForZone(zone);
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ 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();
+ Set<? extends SecurityGroupInZone> rawGroups =
+ sgApi.get().list().filter(nameIn(groupNames)).transform(groupToGroupInZone(zone)).toSet();
+
+ return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
+ }
+
+ @Override
+ public SecurityGroup getSecurityGroupById(String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
+ String zone = zoneAndId.getZone();
+ String groupId = zoneAndId.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ SecurityGroupInZone rawGroup = new SecurityGroupInZone(sgApi.get().get(groupId), zone);
+
+ return groupConverter.apply(rawGroup);
+ }
+
+ @Override
+ public SecurityGroup createSecurityGroup(String name, Location location) {
+ String zone = location.getId();
+ if (zone == null) {
+ return null;
+ }
+ return createSecurityGroup(name, zone);
+ }
+
+ public SecurityGroup createSecurityGroup(String name, String zone) {
+ String markerGroup = namingConvention.create().sharedNameForGroup(name);
+ ZoneSecurityGroupNameAndPorts zoneAndName = new ZoneSecurityGroupNameAndPorts(zone, markerGroup, ImmutableSet.<Integer> of());
+
+ SecurityGroupInZone rawGroup = groupCreator.apply(zoneAndName);
+ return groupConverter.apply(rawGroup);
+ }
+
+ @Override
+ public boolean removeSecurityGroup(String id) {
+ checkNotNull(id, "id");
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
+ String zone = zoneAndId.getZone();
+ String groupId = zoneAndId.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return false;
+ }
+
+ if (sgApi.get().get(groupId) == null) {
+ return false;
+ }
+
+ sgApi.get().delete(groupId);
+ // TODO: test this clear happens
+ groupCreator.invalidate(new ZoneSecurityGroupNameAndPorts(zone, groupId, ImmutableSet.<Integer> of()));
+ return true;
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ String id = group.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ sgApi.get().createRuleAllowingCidrBlock(id,
+ Ingress.builder()
+ .ipProtocol(ipPermission.getIpProtocol())
+ .fromPort(ipPermission.getFromPort())
+ .toPort(ipPermission.getToPort())
+ .build(),
+ cidr);
+ }
+ }
+
+ if (ipPermission.getGroupIds().size() > 0) {
+ for (String zoneAndGroupRaw : ipPermission.getGroupIds()) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(zoneAndGroupRaw);
+ String groupId = zoneAndId.getId();
+ sgApi.get().createRuleAllowingSecurityGroupId(id,
+ Ingress.builder()
+ .ipProtocol(ipPermission.getIpProtocol())
+ .fromPort(ipPermission.getFromPort())
+ .toPort(ipPermission.getToPort())
+ .build(),
+ groupId);
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ String id = group.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ sgApi.get().createRuleAllowingCidrBlock(id,
+ Ingress.builder()
+ .ipProtocol(protocol)
+ .fromPort(startPort)
+ .toPort(endPort)
+ .build(),
+ cidr);
+ }
+ }
+
+ if (Iterables.size(groupIds) > 0) {
+ for (String zoneAndGroupRaw : groupIds) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(zoneAndGroupRaw);
+ String groupId = zoneAndId.getId();
+ sgApi.get().createRuleAllowingSecurityGroupId(id,
+ Ingress.builder()
+ .ipProtocol(protocol)
+ .fromPort(startPort)
+ .toPort(endPort)
+ .build(),
+ groupId);
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ String id = group.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroup = sgApi.get().get(id);
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleCidr(cidr), ruleProtocol(ipPermission.getIpProtocol()),
+ ruleStartPort(ipPermission.getFromPort()),
+ ruleEndPort(ipPermission.getToPort())))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+ }
+ }
+
+ if (ipPermission.getGroupIds().size() > 0) {
+ for (String groupId : ipPermission.getGroupIds()) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleGroup(groupId), ruleProtocol(ipPermission.getIpProtocol()),
+ ruleStartPort(ipPermission.getFromPort()),
+ ruleEndPort(ipPermission.getToPort())))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ String id = group.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroup = sgApi.get().get(id);
+
+ if (Iterables.size(ipRanges) > 0) {
+ for (String cidr : ipRanges) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleCidr(cidr),
+ ruleProtocol(protocol),
+ ruleStartPort(startPort),
+ ruleEndPort(endPort)))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+ }
+ }
+
+ if (Iterables.size(groupIds) > 0) {
+ for (String groupId : groupIds) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleGroup(groupId),
+ ruleProtocol(protocol),
+ ruleStartPort(startPort),
+ ruleEndPort(endPort)))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupNamePairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupIds() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsPortRangesForGroups() {
+ return false;
+ }
+
+ protected Iterable<? extends SecurityGroupInZone> pollSecurityGroups() {
+ Iterable<? extends Set<? extends SecurityGroupInZone>> groups
+ = transform(zoneIds.get(), allSecurityGroupsInZone());
+
+ return concat(groups);
+ }
+
+
+ protected Iterable<? extends SecurityGroupInZone> pollSecurityGroupsByZone(String zone) {
+ return allSecurityGroupsInZone().apply(zone);
+ }
+
+ protected Function<String, Set<? extends SecurityGroupInZone>> allSecurityGroupsInZone() {
+ return new Function<String, Set<? extends SecurityGroupInZone>>() {
+
+ @Override
+ public Set<? extends SecurityGroupInZone> apply(final String from) {
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(from);
+
+ if (!sgApi.isPresent()) {
+ return ImmutableSet.of();
+ }
+
+
+ return sgApi.get().list().transform(groupToGroupInZone(from)).toSet();
+ }
+
+ };
+ }
+
+ protected Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone> groupToGroupInZone(final String zone) {
+ return new Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone>() {
+ @Override
+ public SecurityGroupInZone apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
+ return new SecurityGroupInZone(group, zone);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
new file mode 100644
index 0000000..124cd65
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming a Nova-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class NovaSecurityGroupInZoneToSecurityGroup implements Function<SecurityGroupInZone, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> baseConverter;
+ protected final Supplier<Map<String, Location>> locationIndex;
+
+ @Inject
+ public NovaSecurityGroupInZoneToSecurityGroup(Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> baseConverter,
+ Supplier<Map<String, Location>> locationIndex) {
+ this.baseConverter = checkNotNull(baseConverter, "baseConverter");
+ this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+ }
+
+ @Override
+ public SecurityGroup apply(SecurityGroupInZone group) {
+ SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(baseConverter.apply(group.getSecurityGroup()));
+
+ Location zone = locationIndex.get().get(group.getZone());
+ checkState(zone != null, "location %s not in locationIndex: %s", group.getZone(), locationIndex.get());
+
+ builder.location(zone);
+
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
index 3b70ae7..d39f849 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
@@ -16,12 +16,8 @@
*/
package org.jclouds.openstack.nova.v2_0.compute.functions;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.transform;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -34,9 +30,6 @@ import org.jclouds.net.domain.IpPermission;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
import com.google.inject.Inject;
@@ -67,8 +60,10 @@ public class NovaSecurityGroupToSecurityGroup implements Function<org.jclouds.op
builder.providerId(group.getId());
builder.ownerId(group.getTenantId());
builder.name(group.getName());
- builder.ipPermissions(transform(group.getRules(), ruleToPermission));
-
+ if (group.getRules() != null) {
+ builder.ipPermissions(transform(group.getRules(), ruleToPermission));
+ }
+
return builder.build();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/loaders/FindSecurityGroupOrCreate.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/loaders/FindSecurityGroupOrCreate.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/loaders/FindSecurityGroupOrCreate.java
index 433f4b9..71951cd 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/loaders/FindSecurityGroupOrCreate.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/loaders/FindSecurityGroupOrCreate.java
@@ -17,7 +17,6 @@
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 static org.jclouds.openstack.nova.v2_0.config.NovaProperties.TIMEOUT_SECURITYGROUP_PRESENT;
import java.util.concurrent.atomic.AtomicReference;
@@ -44,7 +43,7 @@ public class FindSecurityGroupOrCreate extends CacheLoader<ZoneAndName, Security
@Inject
public FindSecurityGroupOrCreate(
- @Named(TIMEOUT_SECURITYGROUP_PRESENT) Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone,
+ @Named("SECURITYGROUP_PRESENT") Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone,
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator) {
this.returnSecurityGroupExistsInZone = checkNotNull(returnSecurityGroupExistsInZone,
"returnSecurityGroupExistsInZone");
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/zonescoped/SecurityGroupInZone.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/zonescoped/SecurityGroupInZone.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/zonescoped/SecurityGroupInZone.java
index dd892a2..28e2b0f 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/zonescoped/SecurityGroupInZone.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/zonescoped/SecurityGroupInZone.java
@@ -31,7 +31,7 @@ public class SecurityGroupInZone extends ZoneAndName {
this.securityGroup = securityGroup;
}
- public SecurityGroup getServer() {
+ public SecurityGroup getSecurityGroup() {
return securityGroup;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
index 9e8d260..867ccd3 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
@@ -77,7 +77,7 @@ public interface SecurityGroupApi {
* @return a new Security Group Rule
*/
SecurityGroupRule createRuleAllowingSecurityGroupId(String parentGroup, Ingress ingress,
- String sourceCidr);
+ String groupId);
/**
* Delete a Security Group Rule.
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicates.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicates.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicates.java
index 108618f..412e37f 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicates.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicates.java
@@ -18,9 +18,14 @@ package org.jclouds.openstack.nova.v2_0.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Set;
+
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
/**
* Predicates handy when working with SecurityGroups
@@ -32,7 +37,7 @@ public class SecurityGroupPredicates {
/**
* matches name of the given security group
- *
+ *
* @param name
* @return predicate that matches name
*/
@@ -53,6 +58,28 @@ public class SecurityGroupPredicates {
}
/**
+ * matches name of the given security group against a list
+ *
+ * @param names
+ * @return predicate that matches one of the names
+ */
+ public static Predicate<SecurityGroup> nameIn(final Set<String> names) {
+ checkNotNull(names, "names must be defined");
+
+ return new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup ext) {
+ return Predicates.in(names).apply(ext.getName());
+ }
+
+ @Override
+ public String toString() {
+ return "nameIn(" + names + ")";
+ }
+ };
+ }
+
+ /**
* matches name of the given security group
*
* @param name
@@ -73,4 +100,114 @@ public class SecurityGroupPredicates {
}
};
}
+
+ /**
+ * matches a security group rule by its cidr
+ *
+ * @param cidr
+ * @return predicate that matches cidr
+ */
+ public static Predicate<SecurityGroupRule> ruleCidr(final String cidr) {
+ checkNotNull(cidr, "cidr must be defined");
+
+ return new Predicate<SecurityGroupRule>() {
+ @Override
+ public boolean apply(SecurityGroupRule ext) {
+ return cidr.equals(ext.getIpRange());
+ }
+
+ @Override
+ public String toString() {
+ return "cidr(" + cidr + ")";
+ }
+ };
+ }
+
+ /**
+ * matches a security group rule by the security group it allows
+ *
+ * @param groupName
+ * @return predicate that matches group
+ */
+ public static Predicate<SecurityGroupRule> ruleGroup(final String groupName) {
+ checkNotNull(groupName, "groupName must be defined");
+
+ return new Predicate<SecurityGroupRule>() {
+ @Override
+ public boolean apply(SecurityGroupRule ext) {
+ return ext.getGroup() != null && groupName.equals(ext.getGroup().getName());
+ }
+
+ @Override
+ public String toString() {
+ return "ruleGroup(" + groupName + ")";
+ }
+ };
+ }
+
+ /**
+ * matches a security group rule by the protocol
+ *
+ * @param protocol
+ * @return predicate that matches protocol
+ */
+ public static Predicate<SecurityGroupRule> ruleProtocol(final IpProtocol protocol) {
+ checkNotNull(protocol, "protocol must be defined");
+
+ return new Predicate<SecurityGroupRule>() {
+ @Override
+ public boolean apply(SecurityGroupRule ext) {
+ return protocol.equals(ext.getIpProtocol());
+ }
+
+ @Override
+ public String toString() {
+ return "ruleProtocol(" + protocol + ")";
+ }
+ };
+ }
+
+ /**
+ * matches a security group rule by the start port
+ *
+ * @param startPort
+ * @return predicate that matches startPort
+ */
+ public static Predicate<SecurityGroupRule> ruleStartPort(final int startPort) {
+ checkNotNull(startPort, "startPort must be defined");
+
+ return new Predicate<SecurityGroupRule>() {
+ @Override
+ public boolean apply(SecurityGroupRule ext) {
+ return startPort == ext.getFromPort();
+ }
+
+ @Override
+ public String toString() {
+ return "ruleStartPort(" + startPort + ")";
+ }
+ };
+ }
+
+ /**
+ * matches a security group rule by the end port
+ *
+ * @param endPort
+ * @return predicate that matches endPort
+ */
+ public static Predicate<SecurityGroupRule> ruleEndPort(final int endPort) {
+ checkNotNull(endPort, "endPort must be defined");
+
+ return new Predicate<SecurityGroupRule>() {
+ @Override
+ public boolean apply(SecurityGroupRule ext) {
+ return endPort == ext.getToPort();
+ }
+
+ @Override
+ public String toString() {
+ return "ruleEndPort(" + endPort + ")";
+ }
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionExpectTest.java
new file mode 100644
index 0000000..b80351e
--- /dev/null
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionExpectTest.java
@@ -0,0 +1,423 @@
+/*
+ * 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 org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Properties;
+import java.util.Set;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+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.internal.BaseNovaComputeServiceExpectTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+/**
+ *
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "NovaSecurityGroupExtensionExpectTest")
+public class NovaSecurityGroupExtensionExpectTest extends BaseNovaComputeServiceExpectTest {
+
+ protected String zone = "az-1.region-a.geo-1";
+
+ @Override
+ protected Properties setupProperties() {
+ Properties overrides = super.setupProperties();
+ overrides.setProperty("jclouds.zones", zone);
+ return overrides;
+ }
+
+ public void testListSecurityGroups() {
+ HttpRequest list = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/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);
+ requestResponseMap.put(list, listResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroups();
+ assertEquals(groups.size(), 1);
+ }
+
+ public void testListSecurityGroupsInLocation() {
+ HttpRequest list = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/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);
+ requestResponseMap.put(list, listResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroupsInLocation(new LocationBuilder()
+ .scope(LocationScope.ZONE)
+ .id(zone)
+ .description("zone")
+ .build());
+ assertEquals(groups.size(), 1);
+ }
+
+ public void testListSecurityGroupsForNode() {
+ HttpRequest serverReq = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-create-server-ext/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb"))
+ .headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse serverResponse = HttpResponse.builder().statusCode(200).payload(
+ 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/v1.1/3456/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);
+ requestResponseMap.put(serverReq, serverResponse);
+ requestResponseMap.put(list, listResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ Set<SecurityGroup> groups = extension.listSecurityGroupsForNode(zone + "/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb");
+ assertEquals(groups.size(), 1);
+ }
+
+ public void testGetSecurityGroupById() {
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess);
+ requestResponseMap.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
+ requestResponseMap.put(getSecurityGroup, getSecurityGroupResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroup group = extension.getSecurityGroupById(zone + "/160");
+ assertEquals(group.getId(), "160");
+ }
+
+ public void testCreateSecurityGroup() {
+ HttpRequest create = HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build())
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"security_group\":{\"name\":\"jclouds-test\",\"description\":\"jclouds-test\"}}",
+ "application/json")).build();
+
+ HttpResponse createResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_created.json")).build();
+
+ HttpRequest list = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/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_extension.json")).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess);
+ requestResponseMap.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
+ requestResponseMap.put(create, createResponse);
+ requestResponseMap.put(list, listResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ SecurityGroup group = extension.createSecurityGroup("test", new LocationBuilder()
+ .scope(LocationScope.ZONE)
+ .id(zone)
+ .description("zone")
+ .build());
+ assertEquals(group.getId(), "160");
+ }
+
+ public void testRemoveSecurityGroup() {
+ HttpRequest delete = HttpRequest.builder().method("DELETE").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160"))
+ .headers(
+ ImmutableMultimap.<String, String>builder().put("Accept", "application/json")
+ .put("X-Auth-Token", authToken).build()).build();
+
+ HttpResponse deleteResponse = HttpResponse.builder().statusCode(202).build();
+
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+ Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
+ requestResponseMap.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess);
+ requestResponseMap.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
+ requestResponseMap.put(getSecurityGroup, getSecurityGroupResponse);
+ requestResponseMap.put(delete, deleteResponse).build();
+
+ SecurityGroupExtension extension = requestsSendResponses(requestResponseMap.build()).getSecurityGroupExtension().get();
+
+ assertTrue(extension.removeSecurityGroup(zone + "/160"), "Expected removal of securitygroup to be successful");
+ }
+
+ public void testAddIpPermissionCidrFromIpPermission() {
+ HttpRequest createRule = HttpRequest
+ .builder()
+ .method("POST")
+ .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-group-rules")
+ .addHeader("Accept", "application/json")
+ .addHeader("X-Auth-Token", authToken)
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"security_group_rule\":{\"parent_group_id\":\"160\",\"cidr\":\"10.2.6.0/24\",\"ip_protocol\":\"tcp\",\"from_port\":\"22\",\"to_port\":\"22\"}}",
+ "application/json")).build();
+
+ HttpResponse createRuleResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygrouprule_created_cidr.json")).build();
+
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupNoRulesResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension_norules.json")).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+
+ SecurityGroupExtension extension = orderedRequestsSendResponses(ImmutableList.of(keystoneAuthWithUsernameAndPasswordAndTenantName,
+ extensionsOfNovaRequest, getSecurityGroup, createRule, getSecurityGroup),
+ ImmutableList.of(responseWithKeystoneAccess, extensionsOfNovaResponse, getSecurityGroupNoRulesResponse,
+ createRuleResponse, getSecurityGroupResponse)).getSecurityGroupExtension().get();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(22);
+ builder.cidrBlock("10.2.6.0/24");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroup origGroup = extension.getSecurityGroupById(zone + "/160");
+
+ assertNotNull(origGroup);
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertNotNull(newGroup);
+ }
+
+ public void testAddIpPermissionCidrFromParams() {
+ HttpRequest createRule = HttpRequest
+ .builder()
+ .method("POST")
+ .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-group-rules")
+ .addHeader("Accept", "application/json")
+ .addHeader("X-Auth-Token", authToken)
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"security_group_rule\":{\"parent_group_id\":\"160\",\"cidr\":\"10.2.6.0/24\",\"ip_protocol\":\"tcp\",\"from_port\":\"22\",\"to_port\":\"22\"}}",
+ "application/json")).build();
+
+ HttpResponse createRuleResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygrouprule_created_cidr.json")).build();
+
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupNoRulesResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension_norules.json")).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+
+ SecurityGroupExtension extension = orderedRequestsSendResponses(ImmutableList.of(keystoneAuthWithUsernameAndPasswordAndTenantName,
+ extensionsOfNovaRequest, getSecurityGroup, createRule, getSecurityGroup),
+ ImmutableList.of(responseWithKeystoneAccess, extensionsOfNovaResponse, getSecurityGroupNoRulesResponse,
+ createRuleResponse, getSecurityGroupResponse)).getSecurityGroupExtension().get();
+
+ SecurityGroup origGroup = extension.getSecurityGroupById(zone + "/160");
+
+ assertNotNull(origGroup);
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 22,
+ emptyMultimap(),
+ ImmutableSet.of("10.2.6.0/24"),
+ emptyStringSet(),
+ origGroup);
+
+ assertNotNull(newGroup);
+ }
+
+ public void testAddIpPermissionGroupFromIpPermission() {
+ HttpRequest createRule = HttpRequest
+ .builder()
+ .method("POST")
+ .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-group-rules")
+ .addHeader("Accept", "application/json")
+ .addHeader("X-Auth-Token", authToken)
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"security_group_rule\":{\"group_id\":\"11111\",\"parent_group_id\":\"160\",\"ip_protocol\":\"tcp\",\"from_port\":\"22\",\"to_port\":\"22\"}}",
+ "application/json")).build();
+
+ HttpResponse createRuleResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygrouprule_created_group.json")).build();
+
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupNoRulesResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension_norules.json")).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+
+ SecurityGroupExtension extension = orderedRequestsSendResponses(ImmutableList.of(keystoneAuthWithUsernameAndPasswordAndTenantName,
+ extensionsOfNovaRequest, getSecurityGroup, createRule, getSecurityGroup),
+ ImmutableList.of(responseWithKeystoneAccess, extensionsOfNovaResponse, getSecurityGroupNoRulesResponse,
+ createRuleResponse, getSecurityGroupResponse)).getSecurityGroupExtension().get();
+
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(IpProtocol.TCP);
+ builder.fromPort(22);
+ builder.toPort(22);
+ builder.groupId("admin/11111");
+
+ IpPermission perm = builder.build();
+
+ SecurityGroup origGroup = extension.getSecurityGroupById(zone + "/160");
+
+ assertNotNull(origGroup);
+ SecurityGroup newGroup = extension.addIpPermission(perm, origGroup);
+
+ assertNotNull(newGroup);
+ }
+
+ public void testAddIpPermissionGroupFromParams() {
+ HttpRequest createRule = HttpRequest
+ .builder()
+ .method("POST")
+ .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-group-rules")
+ .addHeader("Accept", "application/json")
+ .addHeader("X-Auth-Token", authToken)
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"security_group_rule\":{\"group_id\":\"11111\",\"parent_group_id\":\"160\",\"ip_protocol\":\"tcp\",\"from_port\":\"22\",\"to_port\":\"22\"}}",
+ "application/json")).build();
+
+ HttpResponse createRuleResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygrouprule_created_group.json")).build();
+
+ HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-security-groups/160")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse getSecurityGroupNoRulesResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension_norules.json")).build();
+
+ HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/securitygroup_details_extension.json")).build();
+
+
+ SecurityGroupExtension extension = orderedRequestsSendResponses(ImmutableList.of(keystoneAuthWithUsernameAndPasswordAndTenantName,
+ extensionsOfNovaRequest, getSecurityGroup, createRule, getSecurityGroup),
+ ImmutableList.of(responseWithKeystoneAccess, extensionsOfNovaResponse, getSecurityGroupNoRulesResponse,
+ createRuleResponse, getSecurityGroupResponse)).getSecurityGroupExtension().get();
+
+ SecurityGroup origGroup = extension.getSecurityGroupById(zone + "/160");
+
+ assertNotNull(origGroup);
+ SecurityGroup newGroup = extension.addIpPermission(IpProtocol.TCP,
+ 22,
+ 22,
+ emptyMultimap(),
+ emptyStringSet(),
+ ImmutableSet.of("admin/11111"),
+ origGroup);
+
+ assertNotNull(newGroup);
+ }
+
+ private Multimap<String, String> emptyMultimap() {
+ return LinkedHashMultimap.create();
+ }
+
+ private Set<String> emptyStringSet() {
+ return Sets.newLinkedHashSet();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionLiveTest.java
new file mode 100644
index 0000000..4a7dbed
--- /dev/null
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtensionLiveTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.nova.v2_0.compute.extensions;
+
+import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
+import org.testng.annotations.Test;
+
+/**
+ * Live test for openstack-nova {@link org.jclouds.compute.extensions.SecurityGroupExtension} implementation.
+ *
+ * @author Andrew Bayer
+ *
+ */
+@Test(groups = "live", singleThreaded = true, testName = "NovaSecurityGroupExtensionLiveTest")
+public class NovaSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
+
+ public NovaSecurityGroupExtensionLiveTest() {
+ provider = "openstack-nova";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroupTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroupTest.java
new file mode 100644
index 0000000..7c588ad
--- /dev/null
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroupTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.collect.Iterables.transform;
+import static org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroupTest.securityGroupWithCidr;
+import static org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroupTest.securityGroupWithGroup;
+import static org.testng.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "NovaSecurityGroupInZoneToSecurityGroupTest")
+public class NovaSecurityGroupInZoneToSecurityGroupTest {
+
+ private static final SecurityGroupRuleToIpPermission ruleConverter = new SecurityGroupRuleToIpPermission();
+ Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("openstack-nova")
+ .description("openstack-nova").build();
+ Location zone = new LocationBuilder().id("az-1.region-a.geo-1").description("az-1.region-a.geo-1")
+ .scope(LocationScope.ZONE).parent(provider).build();
+ Supplier<Map<String, Location>> locationIndex = Suppliers.<Map<String, Location>> ofInstance(ImmutableMap
+ .<String, Location>of("az-1.region-a.geo-1", zone));
+
+
+ @Test
+ public void testApplyWithGroup() {
+ NovaSecurityGroupInZoneToSecurityGroup parser = createGroupParser();
+
+ SecurityGroupInZone origGroup = new SecurityGroupInZone(securityGroupWithGroup(), zone.getId());
+
+ SecurityGroup newGroup = parser.apply(origGroup);
+
+ assertEquals(newGroup.getId(), origGroup.getSecurityGroup().getId());
+ assertEquals(newGroup.getProviderId(), origGroup.getSecurityGroup().getId());
+ assertEquals(newGroup.getName(), origGroup.getSecurityGroup().getName());
+ assertEquals(newGroup.getOwnerId(), origGroup.getSecurityGroup().getTenantId());
+ assertEquals(newGroup.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getSecurityGroup().getRules(), ruleConverter)));
+ assertEquals(newGroup.getLocation().getId(), origGroup.getZone());
+ }
+
+ @Test
+ public void testApplyWithCidr() {
+
+ NovaSecurityGroupInZoneToSecurityGroup parser = createGroupParser();
+
+ SecurityGroupInZone origGroup = new SecurityGroupInZone(securityGroupWithCidr(), zone.getId());
+
+ SecurityGroup newGroup = parser.apply(origGroup);
+
+ assertEquals(newGroup.getId(), origGroup.getSecurityGroup().getId());
+ assertEquals(newGroup.getProviderId(), origGroup.getSecurityGroup().getId());
+ assertEquals(newGroup.getName(), origGroup.getSecurityGroup().getName());
+ assertEquals(newGroup.getOwnerId(), origGroup.getSecurityGroup().getTenantId());
+ assertEquals(newGroup.getIpPermissions(), ImmutableSet.copyOf(transform(origGroup.getSecurityGroup().getRules(), ruleConverter)));
+ assertEquals(newGroup.getLocation().getId(), origGroup.getZone());
+ }
+
+ private NovaSecurityGroupInZoneToSecurityGroup createGroupParser() {
+ NovaSecurityGroupToSecurityGroup baseParser = new NovaSecurityGroupToSecurityGroup(ruleConverter);
+
+ NovaSecurityGroupInZoneToSecurityGroup parser = new NovaSecurityGroupInZoneToSecurityGroup(baseParser, locationIndex);
+
+ return parser;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
index 8db1e15..16d01d3 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroupTest.java
@@ -18,19 +18,13 @@ package org.jclouds.openstack.nova.v2_0.compute.functions;
import static com.google.common.collect.Iterables.transform;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Set;
import org.jclouds.compute.domain.SecurityGroup;
-import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.net.domain.IpPermission;
import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
import org.testng.annotations.Test;
-import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
/**
@@ -40,32 +34,59 @@ import com.google.common.collect.ImmutableSet;
public class NovaSecurityGroupToSecurityGroupTest {
private static final SecurityGroupRuleToIpPermission ruleConverter = new SecurityGroupRuleToIpPermission();
-
- @Test
- public void testApplyWithGroup() {
+
+ public static org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroupWithGroup() {
TenantIdAndName group = TenantIdAndName.builder().tenantId("tenant").name("name").build();
-
+
+ SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .group(group)
+ .parentGroupId("some-other-id")
+ .build();
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
+ .tenantId("tenant")
+ .id("some-id")
+ .name("some-group")
+ .description("some-description")
+ .rules(ruleToConvert)
+ .build();
+
+ return origGroup;
+ }
+
+ public static org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroupWithCidr() {
SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
- .id("some-id")
- .ipProtocol(IpProtocol.TCP)
- .fromPort(10)
- .toPort(20)
- .group(group)
- .parentGroupId("some-other-id")
- .build();
+ .id("some-id")
+ .ipProtocol(IpProtocol.TCP)
+ .fromPort(10)
+ .toPort(20)
+ .ipRange("0.0.0.0/0")
+ .parentGroupId("some-other-id")
+ .build();
org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
- .tenantId("tenant")
- .id("some-id")
- .name("some-group")
- .description("some-description")
- .rules(ruleToConvert)
- .build();
+ .tenantId("tenant")
+ .id("some-id")
+ .name("some-group")
+ .description("some-description")
+ .rules(ruleToConvert)
+ .build();
+
+ return origGroup;
+ }
+ @Test
+ public void testApplyWithGroup() {
NovaSecurityGroupToSecurityGroup parser = createGroupParser();
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = securityGroupWithGroup();
+
SecurityGroup newGroup = parser.apply(origGroup);
-
+
assertEquals(newGroup.getId(), origGroup.getId());
assertEquals(newGroup.getProviderId(), origGroup.getId());
assertEquals(newGroup.getName(), origGroup.getName());
@@ -75,27 +96,13 @@ public class NovaSecurityGroupToSecurityGroupTest {
@Test
public void testApplyWithCidr() {
- SecurityGroupRule ruleToConvert = SecurityGroupRule.builder()
- .id("some-id")
- .ipProtocol(IpProtocol.TCP)
- .fromPort(10)
- .toPort(20)
- .ipRange("0.0.0.0/0")
- .parentGroupId("some-other-id")
- .build();
-
- org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = org.jclouds.openstack.nova.v2_0.domain.SecurityGroup.builder()
- .tenantId("tenant")
- .id("some-id")
- .name("some-group")
- .description("some-description")
- .rules(ruleToConvert)
- .build();
NovaSecurityGroupToSecurityGroup parser = createGroupParser();
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup origGroup = securityGroupWithCidr();
+
SecurityGroup group = parser.apply(origGroup);
-
+
assertEquals(group.getId(), origGroup.getId());
assertEquals(group.getProviderId(), origGroup.getId());
assertEquals(group.getName(), origGroup.getName());
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicatesTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicatesTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicatesTest.java
index 521d7d5..26e5ce2 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicatesTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/predicates/SecurityGroupPredicatesTest.java
@@ -17,10 +17,22 @@
package org.jclouds.openstack.nova.v2_0.predicates;
import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.nameEquals;
+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;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleProtocol;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleStartPort;
+import static org.testng.Assert.assertTrue;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.TenantIdAndName;
import org.testng.annotations.Test;
+import com.google.common.collect.ImmutableSet;
+
/**
*
* @author Adrian Cole
@@ -28,15 +40,90 @@ import org.testng.annotations.Test;
@Test(groups = "unit", testName = "SecurityGroupPredicatesTest")
public class SecurityGroupPredicatesTest {
SecurityGroup ref = SecurityGroup.builder().id("12345").name("jclouds").description("description").build();
+ SecurityGroupRule ruleRef = SecurityGroupRule.builder().id("6789").parentGroupId("12345").ipRange("0.0.0.0/0")
+ .fromPort(10).toPort(20).ipProtocol(IpProtocol.TCP)
+ .group(TenantIdAndName.builder().tenantId("11111111").name("abcd").build())
+ .build();
- @Test
public void testnameEqualsWhenEqual() {
- assert nameEquals("jclouds").apply(ref);
+ assertTrue(nameEquals("jclouds").apply(ref), "expected 'jclouds' as the name of " + ref);
}
@Test
public void testnameEqualsWhenNotEqual() {
- assert !nameEquals("foo").apply(ref);
+ assertTrue(!nameEquals("foo").apply(ref), "expected 'foo' not to be the name of " + ref);
+ }
+
+ @Test
+ public void testNameInWhenIn() {
+ assertTrue(nameIn(ImmutableSet.of("jclouds", "pants")).apply(ref),
+ "expected the name of " + ref + " to be one of 'jclouds' or 'pants'");
+ }
+
+ @Test
+ public void testNameInWhenNotIn() {
+ assertTrue(!nameIn(ImmutableSet.of("foo", "pants")).apply(ref),
+ "expected the name of " + ref + " to not be either of 'foo' or 'pants'");
+
+ }
+
+ @Test
+ public void testRuleCidrWhenEqual() {
+ assertTrue(ruleCidr("0.0.0.0/0").apply(ruleRef),
+ "expected the CIDR to be '0.0.0.0/0' for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleCidrWhenNotEqual() {
+ assertTrue(!ruleCidr("1.1.1.1/0").apply(ruleRef),
+ "expected the CIDR to not be '1.1.1.1/0' for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleGroupWhenEqual() {
+ assertTrue(ruleGroup("abcd").apply(ruleRef),
+ "expected the group to be equal to 'abcd' for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleGroupWhenNotEqual() {
+ assertTrue(!ruleGroup("pants").apply(ruleRef),
+ "expected the group to not be equal to 'pants' for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleProtocolWhenEqual() {
+ assertTrue(ruleProtocol(IpProtocol.TCP).apply(ruleRef),
+ "expected TCP for " + ruleRef);
}
+ @Test
+ public void testRuleProtocolWhenNotEqual() {
+ assertTrue(!ruleProtocol(IpProtocol.UDP).apply(ruleRef),
+ "expected not UDP for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleStartPortWhenEqual() {
+ assertTrue(ruleStartPort(10).apply(ruleRef),
+ "expected start port 10 for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleStartPortWhenNotEqual() {
+ assertTrue(!ruleStartPort(50).apply(ruleRef),
+ "expected start port not to be 50 for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleEndPortWhenEqual() {
+ assertTrue(ruleEndPort(20).apply(ruleRef),
+ "expected end port 20 for " + ruleRef);
+ }
+
+ @Test
+ public void testRuleEndPortWhenNotEqual() {
+ assertTrue(!ruleEndPort(50).apply(ruleRef),
+ "expected end port not to be 50 for " + ruleRef);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/securitygroup_details_extension.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/securitygroup_details_extension.json b/apis/openstack-nova/src/test/resources/securitygroup_details_extension.json
new file mode 100644
index 0000000..a644296
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/securitygroup_details_extension.json
@@ -0,0 +1,34 @@
+{
+ "security_group":
+ {
+ "rules": [
+ {
+ "from_port": 22,
+ "group": {},
+ "ip_protocol": "tcp",
+ "to_port": 22,
+ "parent_group_id": 160,
+ "ip_range": {
+ "cidr": "10.2.6.0/24"
+ },
+ "id": 108
+ },
+ {
+ "from_port": 22,
+ "group": {
+ "tenant_id": "admin",
+ "name": "11111"
+ },
+ "ip_protocol": "tcp",
+ "to_port": 22,
+ "parent_group_id": 160,
+ "ip_range": {},
+ "id": 109
+ }
+ ],
+ "tenant_id": "tenant0",
+ "id": 160,
+ "name": "name0",
+ "description": "description0"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/securitygroup_details_extension_norules.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/securitygroup_details_extension_norules.json b/apis/openstack-nova/src/test/resources/securitygroup_details_extension_norules.json
new file mode 100644
index 0000000..27aca88
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/securitygroup_details_extension_norules.json
@@ -0,0 +1,10 @@
+{
+ "security_group":
+ {
+ "rules": [],
+ "tenant_id": "tenant0",
+ "id": 160,
+ "name": "name0",
+ "description": "description0"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/securitygroup_list_extension.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/securitygroup_list_extension.json b/apis/openstack-nova/src/test/resources/securitygroup_list_extension.json
new file mode 100644
index 0000000..14866e3
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/securitygroup_list_extension.json
@@ -0,0 +1,51 @@
+{
+ "security_groups":[
+ {
+ "rules":[
+ {
+ "from_port":22,
+ "group":{
+
+ },
+ "ip_protocol":"tcp",
+ "to_port":22,
+ "parent_group_id":3,
+ "ip_range":{
+ "cidr":"0.0.0.0/0"
+ },
+ "id":107
+ },
+ {
+ "from_port":7600,
+ "group":{
+
+ },
+ "ip_protocol":"tcp",
+ "to_port":7600,
+ "parent_group_id":3,
+ "ip_range":{
+ "cidr":"0.0.0.0/0"
+ },
+ "id":118
+ },
+ {
+ "from_port":8084,
+ "group":{
+
+ },
+ "ip_protocol":"tcp",
+ "to_port":8084,
+ "parent_group_id":3,
+ "ip_range":{
+ "cidr":"0.0.0.0/0"
+ },
+ "id":119
+ }
+ ],
+ "tenant_id":"dev_16767499955063",
+ "id":160,
+ "name":"jclouds-test",
+ "description":"jclouds-test"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/securitygrouprule_created_cidr.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/securitygrouprule_created_cidr.json b/apis/openstack-nova/src/test/resources/securitygrouprule_created_cidr.json
new file mode 100644
index 0000000..cc91ac7
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/securitygrouprule_created_cidr.json
@@ -0,0 +1,13 @@
+{
+ "security_group_rule": {
+ "from_port": 22,
+ "group": {},
+ "ip_protocol": "tcp",
+ "to_port": 22,
+ "parent_group_id": 160,
+ "ip_range": {
+ "cidr": "10.2.6.0/24"
+ },
+ "id": 108
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/securitygrouprule_created_group.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/securitygrouprule_created_group.json b/apis/openstack-nova/src/test/resources/securitygrouprule_created_group.json
new file mode 100644
index 0000000..ff17bcd
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/securitygrouprule_created_group.json
@@ -0,0 +1,14 @@
+{
+ "security_group_rule": {
+ "from_port": 22,
+ "group": {
+ "tenant_id": "admin",
+ "name": "11111"
+ },
+ "ip_protocol": "tcp",
+ "to_port": 22,
+ "parent_group_id": 160,
+ "ip_range": {},
+ "id": 109
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/389ba6c9/apis/openstack-nova/src/test/resources/server_with_security_groups_extension.json
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/resources/server_with_security_groups_extension.json b/apis/openstack-nova/src/test/resources/server_with_security_groups_extension.json
new file mode 100644
index 0000000..7a3c4b2
--- /dev/null
+++ b/apis/openstack-nova/src/test/resources/server_with_security_groups_extension.json
@@ -0,0 +1 @@
+{"server": {"status": "ACTIVE", "updated": "2012-05-04T12:15:01Z", "hostId": "02c7c81e36024d2bfdb473cb762900138bc07777922479d3d4f8f690", "user_id": "1e8a56719e0d4ab4b7edb85c77f7290f", "name": "test", "links": [{"href": "http://172.16.89.148:8774/v2/4287930c796741aa898425f40832cb3c/servers/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "rel": "self"}, {"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832cb3c/servers/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "rel": "bookmark"}], "created": "2012-05-04T12:14:57Z", "tenant_id": "4287930c796741aa898425f40832cb3c", "image": {"id": "ea17cc36-f7c9-40cd-b6bf-a952b74870f2", "links": [{"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832cb3c/images/ea17cc36-f7c9-40cd-b6bf-a952b74870f2", "rel": "bookmark"}]}, "addresses": {"private": [{"version": 4, "addr": "10.0.0.8"}]}, "accessIPv4": "", "accessIPv6": "", "key_name": "", "progress": 0, "flavor": {"id": "1", "links": [{"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832c
b3c/flavors/1", "rel": "bookmark"}]}, "config_drive": "", "id": "8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "security_groups": [{"name": "name1"}], "metadata": {}}}
\ No newline at end of file