Adds support for the Security Group extension to neutron
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/commit/67b9f472 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/tree/67b9f472 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/diff/67b9f472 Branch: refs/heads/master Commit: 67b9f47210156ca26139dfadad0eaa2a6b2fd8b8 Parents: de8348d Author: Zack Shoylev <[email protected]> Authored: Fri Aug 15 16:17:39 2014 -0500 Committer: Zack Shoylev <[email protected]> Committed: Fri Aug 29 20:29:59 2014 -0500 ---------------------------------------------------------------------- .../openstack/neutron/v2/NeutronApi.java | 10 + .../neutron/v2/domain/AddressPair.java | 11 +- .../openstack/neutron/v2/domain/Rule.java | 375 +++++++++++ .../neutron/v2/domain/RuleDirection.java | 61 ++ .../neutron/v2/domain/RuleEthertype.java | 61 ++ .../neutron/v2/domain/RuleProtocol.java | 65 ++ .../openstack/neutron/v2/domain/Rules.java | 35 + .../neutron/v2/domain/SecurityGroup.java | 219 +++++++ .../neutron/v2/domain/SecurityGroups.java | 36 + .../neutron/v2/extensions/SecurityGroupApi.java | 186 ++++++ .../v2/fallbacks/EmptyRulesFallback.java | 45 ++ .../fallbacks/EmptySecurityGroupsFallback.java | 45 ++ .../neutron/v2/functions/ParseRules.java | 38 ++ .../v2/functions/ParseSecurityGroups.java | 38 ++ .../v2/functions/RulesToPagedIterable.java | 66 ++ .../SecurityGroupsToPagedIterable.java | 66 ++ .../v2/extensions/SecurityGroupApiLiveTest.java | 88 +++ .../v2/extensions/SecurityGroupApiMockTest.java | 655 +++++++++++++++++++ .../neutron/v2/features/PortApiMockTest.java | 4 +- .../security_group_create_request.json | 6 + .../security_group_create_response.json | 34 + .../resources/security_group_get_response.json | 58 ++ .../resources/security_group_list_response.json | 116 ++++ .../security_group_list_response_paged1.json | 126 ++++ .../security_group_list_response_paged2.json | 122 ++++ .../security_group_rule_create_request.json | 11 + .../security_group_rule_create_response.json | 15 + .../security_group_rule_get_response.json | 14 + .../security_group_rule_list_response.json | 52 ++ ...ecurity_group_rule_list_response_paged1.json | 62 ++ ...ecurity_group_rule_list_response_paged2.json | 58 ++ 31 files changed, 2766 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApi.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApi.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApi.java index 233c41b..358e38f 100644 --- a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApi.java +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/NeutronApi.java @@ -25,6 +25,7 @@ import org.jclouds.Constants; import org.jclouds.location.Region; import org.jclouds.location.functions.RegionToEndpoint; import org.jclouds.openstack.neutron.v2.extensions.RouterApi; +import org.jclouds.openstack.neutron.v2.extensions.SecurityGroupApi; import org.jclouds.openstack.neutron.v2.features.NetworkApi; import org.jclouds.openstack.neutron.v2.features.PortApi; import org.jclouds.openstack.neutron.v2.features.SubnetApi; @@ -89,4 +90,13 @@ public interface NeutronApi extends Closeable { @Delegate Optional<? extends RouterApi> getRouterExtensionApi(@EndpointParam(parser = RegionToEndpoint.class) String region); + /** + * Provides access to SecurityGroup features. + * + * <h3>NOTE</h3> + * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type + * to determine if it is present. + */ + @Delegate + Optional<SecurityGroupApi> getSecurityGroupApi(@EndpointParam(parser = RegionToEndpoint.class) String region); } http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java index 4e317ce..a222908 100644 --- a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java @@ -101,20 +101,11 @@ public class AddressPair { * In this case, both parameters are required. * @return the Builder for AddressPair */ - public static Builder createOptions(String macAddress, String ipAddress) { + public static Builder builder(String macAddress, String ipAddress) { return new Builder(macAddress, ipAddress); } /** - * Returns a builder, but requires the user to specify any parameters required when updating a resource. - * In this case, there are none. - * @return the Builder for AddressPair - */ - public static Builder updateOptions() { - return new Builder(); - } - - /** * Gets a Builder configured as this object. */ public Builder toBuilder() { http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rule.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rule.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rule.java new file mode 100644 index 0000000..e3b7aca --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rule.java @@ -0,0 +1,375 @@ +/* + * 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.neutron.v2.domain; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.beans.ConstructorProperties; +import javax.inject.Named; + +import org.jclouds.javax.annotation.Nullable; +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +/** + * Contains a mapping between a MAC address and an IP address. + */ +public class Rule { + + private String id; + @Named("tenant_id") + private String tenantId; + private RuleDirection direction; + @Named("security_group_id") + private String securityGroupId; + private RuleEthertype ethertype; + @Named("port_range_min") + private Integer portRangeMin; + @Named("port_range_max") + private Integer portRangeMax; + private RuleProtocol protocol; + @Named("remote_group_id") + private String remoteGroupId; + @Named("remote_ip_prefix") + private String remoteIpPrefix; + + @ConstructorProperties({"id", "tenant_id", "direction", "security_group_id", "ethertype", "port_range_min", + "port_range_max", "protocol", "remote_group_id", "remote_ip_prefix"}) + protected Rule(String id, String tenantId, RuleDirection direction, String securityGroupId, + RuleEthertype ethertype, Integer portRangeMin, Integer portRangeMax, + RuleProtocol protocol, String remoteGroupId, String remoteIpPrefix) { + this.id = id; + this.tenantId = tenantId; + this.direction = direction; + this.securityGroupId = securityGroupId; + this.ethertype = ethertype; + this.portRangeMin = portRangeMin; + this.portRangeMax = portRangeMax; + this.protocol = protocol; + this.remoteGroupId = remoteGroupId; + this.remoteIpPrefix = remoteIpPrefix; + } + + private Rule(Rule rule) { + this(rule.id, + rule.tenantId, + rule.direction, + rule.securityGroupId, + rule.ethertype, + rule.portRangeMin, + rule.portRangeMax, + rule.protocol, + rule.remoteGroupId, + rule.remoteIpPrefix + ); + } + + private Rule() {} + + /** + * @return The identifier for this rule. + */ + @Nullable + public String getId() { + return id; + } + + /** + * @return The identifier of the tenant for this rule. + */ + @Nullable + public String getTenantId() { + return tenantId; + } + + /** + * @return The direction in which the security group rule is applied. + */ + @Nullable + public RuleDirection getDirection() { + return direction; + } + + /** + * @return The security group ID to associate with this security group rule. + */ + @Nullable + public String getSecurityGroupId() { + return securityGroupId; + } + + /** + * @return The internet protocol version type of this rule. + */ + @Nullable + public RuleEthertype getEthertype() { + return ethertype; + } + + /** + * @return The minimum port number in the range that is matched by the security group rule. If the protocol is TCP + * or UDP, this value must be less than or equal to the value of the port_range_max attribute. If the protocol is + * ICMP, this value must be an ICMP type. + */ + @Nullable + public Integer getPortRangeMin() { + return portRangeMin; + } + + /** + * @return The maximum port number in the range that is matched by the security group rule. The port_range_min + * attribute constrains the port_range_max attribute. If the protocol is ICMP, this value must be an ICMP type. + */ + @Nullable + public Integer getPortRangeMax() { + return portRangeMax; + } + + /** + * @return The protocol that is matched by the security group rule. Valid values are null, tcp, udp, and icmp. + */ + @Nullable + public RuleProtocol getProtocol() { + return protocol; + } + + /** + * @return The remote group ID to be associated with this security group rule. + */ + @Nullable + public String getRemoteGroupId() { + return remoteGroupId; + } + + /** + * @return The remote IP prefix to be associated with this security group rule. This attribute matches the specified + * IP prefix as the source IP address of the IP packet. + */ + @Nullable + public String getRemoteIpPrefix() { + return remoteIpPrefix; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Rule that = (Rule) o; + + return Objects.equal(this.id, that.id) && + Objects.equal(this.tenantId, that.tenantId) && + Objects.equal(this.direction, that.direction) && + Objects.equal(this.securityGroupId, that.securityGroupId) && + Objects.equal(this.ethertype, that.ethertype) && + Objects.equal(this.portRangeMin, that.portRangeMin) && + Objects.equal(this.portRangeMax, that.portRangeMax) && + Objects.equal(this.protocol, that.protocol) && + Objects.equal(this.remoteGroupId, that.remoteGroupId) && + Objects.equal(this.remoteIpPrefix, that.remoteIpPrefix); + } + + @Override + public int hashCode() { + return Objects.hashCode(id, tenantId, direction, securityGroupId, ethertype, portRangeMin, + portRangeMax, protocol, remoteGroupId, remoteIpPrefix); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("tenantId", tenantId) + .add("direction", direction) + .add("securityGroupId", securityGroupId) + .add("ethertype", ethertype) + .add("portRangeMin", portRangeMin) + .add("portRangeMax", portRangeMax) + .add("protocol", protocol) + .add("remoteGroupId", remoteGroupId) + .add("remoteIpPrefix", remoteIpPrefix) + .toString(); + } + + + /* + * Methods to get the Create and Update builders follow + */ + + /** + * @return the Builder for creating a new SecurityGroupRule + */ + public static CreateBuilder createOptions(RuleDirection direction, String securityGroupId) { + return new CreateBuilder(direction, securityGroupId); + } + + public abstract static class Builder<ParameterizedBuilderType> { + // Keep track of the builder's state. + protected Rule rule; + + private Builder() { + rule = new Rule(); + } + + protected abstract ParameterizedBuilderType self(); + + /** + * The tenant id for this rule. Usually can only be specified by administrators. + * + * @return the Builder. + * @see Rule#getTenantId() + */ + public ParameterizedBuilderType tenantId(String tenantId) { + rule.tenantId = tenantId; + return self(); + } + + /** + * The direction in which the security group rule is applied. + * + * @return the Builder. + * @see Rule#getDirection() + */ + public ParameterizedBuilderType direction(RuleDirection direction) { + rule.direction = direction; + return self(); + } + + /** + * The security group ID to associate with this security group rule. + * + * @return the Builder. + * @see Rule#getSecurityGroupId() + */ + public ParameterizedBuilderType securityGroupId(String securityGroupId) { + rule.securityGroupId = securityGroupId; + return self(); + } + + /** + * The internet protocol version for this rule. + * + * @return the Builder. + * @see Rule#getEthertype() + */ + public ParameterizedBuilderType ethertype(RuleEthertype ethertype) { + rule.ethertype = ethertype; + return self(); + } + + /** + * The minimum port number in the range that is matched by the security group rule. + * + * @return the Builder. + * @see Rule#getPortRangeMin() + */ + public ParameterizedBuilderType portRangeMin(Integer portRangeMin) { + rule.portRangeMin = portRangeMin; + return self(); + } + + /** + * The maximum port number in the range that is matched by the security group rule. + * + * @return the Builder. + * @see Rule#getPortRangeMax() + */ + public ParameterizedBuilderType portRangeMax(Integer portRangeMax) { + rule.portRangeMax = portRangeMax; + return self(); + } + + /** + * The protocol that is matched by the security group rule. Valid values are null, tcp, udp, and icmp. + * + * @return the Builder. + * @see Rule#getProtocol() + */ + public ParameterizedBuilderType protocol(RuleProtocol protocol) { + rule.protocol = protocol; + return self(); + } + + /** + * The remote group ID to be associated with this security group rule. You can specify either remote_group_id or + * remote_ip_prefix in the request body. + * + * @return the Builder. + * @see Rule#getRemoteGroupId() + */ + public ParameterizedBuilderType remoteGroupId(String remoteGroupId) { + rule.remoteGroupId = remoteGroupId; + return self(); + } + + /** + * The remote IP prefix to be associated with this security group rule. You can specify either remote_group_id + * or remote_ip_prefix in the request body. This attribute matches the specified IP prefix as the source IP + * address of the IP packet. + * + * @return the Builder. + * @see Rule#getRemoteIpPrefix() + */ + public ParameterizedBuilderType remoteIpPrefix(String remoteIpPrefix) { + rule.remoteIpPrefix = remoteIpPrefix; + return self(); + } + } + + /** + * This is used to build a CreateOptions object. + */ + public static class CreateBuilder extends Builder<CreateBuilder> { + /** + * Supply required properties for creating a Builder + */ + private CreateBuilder(RuleDirection direction, String securityGroupId) { + rule.direction = direction; + rule.securityGroupId = securityGroupId; + } + + /** + * @return a CreateOptions constructed with this Builder. + */ + public CreateOptions build() { + return new CreateOptions(rule); + } + + protected CreateBuilder self() { + return this; + } + } + + /** + * Create and Update options - extend the domain class, passed to API update and create calls. + * Essentially the same as the domain class. Ensure validation and safe typing. + */ + public static class CreateOptions extends Rule { + private CreateOptions(Rule rule) { + super(rule); + checkNotNull(rule.getDirection(), "direction should not be null"); + checkNotNull(rule.getSecurityGroupId(), "security group id should not be null"); + checkState(rule.getPortRangeMax()>= rule.getPortRangeMin(), + "port range max should be greater than or equal to port range min"); + checkState(rule.getRemoteGroupId()==null || rule.getRemoteIpPrefix()==null, + "You can specify either remote_group_id or remote_ip_prefix in the request body."); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleDirection.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleDirection.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleDirection.java new file mode 100644 index 0000000..759bb8c --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleDirection.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jclouds.openstack.neutron.v2.domain; + +/** + * The direction in which the security group rule is applied. + */ +public enum RuleDirection { + /** + * For a compute instance, an âingressâ security group rule matches traffic that is incoming (ingress) for that instance. + */ + INGRESS("ingress"), + /** + * An âegressâ rule is applied to traffic leaving the instance. + */ + EGRESS("egress"), + /** + * Used by jclouds when the service returns an unknown value other than null. + */ + UNRECOGNIZED("unrecognized"); + + private String name; + + private RuleDirection(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + /** + * This provides GSON enum support in jclouds. + * */ + public static RuleDirection fromValue(String name){ + if (name != null) { + for (RuleDirection value : RuleDirection.values()) { + if (name.equalsIgnoreCase(value.name)) { + return value; + } + } + return UNRECOGNIZED; + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleEthertype.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleEthertype.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleEthertype.java new file mode 100644 index 0000000..1508070 --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleEthertype.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jclouds.openstack.neutron.v2.domain; + +/** + * The direction in which the security group rule is applied. + */ +public enum RuleEthertype { + /** + * Internet Protocol version 4 + */ + IPV4("IPv4"), + /** + * Internet Protocol version 6 + */ + IPV6("IPv6"), + /** + * Used by jclouds when the service returns an unknown value other than null. + */ + UNRECOGNIZED("unrecognized"); + + private String name; + + private RuleEthertype(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + /** + * This provides GSON enum support in jclouds. + * */ + public static RuleEthertype fromValue(String name){ + if (name != null) { + for (RuleEthertype value : RuleEthertype.values()) { + if (name.equalsIgnoreCase(value.name)) { + return value; + } + } + return UNRECOGNIZED; + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleProtocol.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleProtocol.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleProtocol.java new file mode 100644 index 0000000..9ad105f --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/RuleProtocol.java @@ -0,0 +1,65 @@ +/* + * 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.neutron.v2.domain; + +/** + * The protocol that is matched by the security group rule. Valid values are null, tcp, udp, and icmp. + */ +public enum RuleProtocol { + /** + * Transmission Control Protocol + */ + TCP("tcp"), + /** + * User Datagram Protocol + */ + UDP("udp"), + /** + * Internet Control Message Protocol + */ + ICMP("icmp"), + /** + * Used by jclouds when the service returns an unknown value other than null. + */ + UNRECOGNIZED("unrecognized"); + + private String name; + + private RuleProtocol(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + /** + * This provides GSON enum support in jclouds. + * */ + public static RuleProtocol fromValue(String name){ + if (name != null) { + for (RuleProtocol value : RuleProtocol.values()) { + if (name.equalsIgnoreCase(value.name)) { + return value; + } + } + return UNRECOGNIZED; + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rules.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rules.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rules.java new file mode 100644 index 0000000..4794a18 --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Rules.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.neutron.v2.domain; + +import java.beans.ConstructorProperties; + +import org.jclouds.openstack.v2_0.domain.Link; +import org.jclouds.openstack.v2_0.domain.PaginatedCollection; +import com.google.common.collect.ImmutableSet; + +/** + * A collection of Networks + */ +public class Rules extends PaginatedCollection<Rule> { + public static final Rules EMPTY = new Rules(ImmutableSet.<Rule> of(), ImmutableSet.<Link> of()); + + @ConstructorProperties({"security_group_rules", "security_group_rules_links"}) + protected Rules(Iterable<Rule> securityGroups, Iterable<Link> securityGroupRulesLinks) { + super(securityGroups, securityGroupRulesLinks); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroup.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroup.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroup.java new file mode 100644 index 0000000..604776e --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroup.java @@ -0,0 +1,219 @@ +/* + * 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.neutron.v2.domain; + +import java.beans.ConstructorProperties; + +import javax.inject.Named; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; + +/** + * Contains a mapping between a MAC address and an IP address. + */ +public class SecurityGroup { + + private String id; + @Named("tenant_id") + private String tenantId; + private String name; + private String description; + @Named("security_group_rules") + private ImmutableList<Rule> rules; + + @ConstructorProperties({"id", "tenant_id", "name", "description", "security_group_rules"}) + protected SecurityGroup(String id, String tenantId, String name, String description, + ImmutableList<Rule> rules) { + this.id = id; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.rules = rules; + } + + private SecurityGroup(SecurityGroup securityGroup) { + this(securityGroup.id, + securityGroup.tenantId, + securityGroup.name, + securityGroup.description, + securityGroup.rules + ); + } + + private SecurityGroup() {} + + /** + * @return The identifier for this Security Group. + */ + @Nullable + public String getId() { + return id; + } + + /** + * @return The identifier of the tenant for this Security Group. + */ + @Nullable + public String getTenantId() { + return tenantId; + } + + /** + * @return The name of the Security Group. + */ + @Nullable + public String getName() { + return name; + } + + /** + * @return The description of the Security Group. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * @return The collection of rules for this Security Group. + */ + public ImmutableList<Rule> getRules() { + return rules!=null ? rules : ImmutableList.<Rule>of(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + SecurityGroup that = (SecurityGroup) o; + + return Objects.equal(this.id, that.id) && + Objects.equal(this.tenantId, that.tenantId) && + Objects.equal(this.name, that.name) && + Objects.equal(this.description, that.description) && + Objects.equal(this.rules, that.rules); + } + + @Override + public int hashCode() { + return Objects.hashCode(id, tenantId, name, description, rules); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("tenantId", tenantId) + .add("name", name) + .add("description", description) + .add("securityGroupRules", rules) + .toString(); + } + + /* + * Methods to get the Create and Update builders follow + */ + + /** + * @return the Builder for creating a new SecurityGroup + */ + public static CreateBuilder createOptions() { + return new CreateBuilder(); + } + + private abstract static class Builder<ParameterizedBuilderType> { + // Keep track of the builder's state. + protected SecurityGroup securityGroup; + + private Builder() { + securityGroup = new SecurityGroup(); + } + + protected abstract ParameterizedBuilderType self(); + + /** + * The tenant id for this Security Group. Usually can only be specified by administrators. + * + * @return the Builder. + * @see SecurityGroup#getTenantId() + */ + public ParameterizedBuilderType tenantId(String tenantId) { + securityGroup.tenantId = tenantId; + return self(); + } + + /** + * The name for this Security Group. + * + * @return the Builder. + * @see SecurityGroup#getName() + */ + public ParameterizedBuilderType name(String name) { + securityGroup.name = name; + return self(); + } + + /** + * The description for this Security Group. + * + * @return the Builder. + * @see SecurityGroup#getDescription() + */ + public ParameterizedBuilderType description(String description) { + securityGroup.description = description; + return self(); + } + } + + /** + * Create and Update builders (inheriting from Builder) + */ + public static class CreateBuilder extends Builder<CreateBuilder> { + /** + * Supply required properties for creating a Builder + */ + private CreateBuilder() { + } + + /** + * @return a CreateOptions constructed with this Builder. + */ + public CreateOptions build() { + return new CreateOptions(securityGroup); + } + + protected CreateBuilder self() { + return this; + } + } + + /** + * Create and Update options - extend the domain class, passed to API update and create calls. + * Essentially the same as the domain class. Ensure validation and safe typing. + */ + public static class CreateOptions extends SecurityGroup { + private CreateOptions(SecurityGroup securityGroup) { + super(securityGroup); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroups.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroups.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroups.java new file mode 100644 index 0000000..044ce1c --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/SecurityGroups.java @@ -0,0 +1,36 @@ +/* + * 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.neutron.v2.domain; + +import java.beans.ConstructorProperties; + +import org.jclouds.openstack.v2_0.domain.Link; +import org.jclouds.openstack.v2_0.domain.PaginatedCollection; + +import com.google.common.collect.ImmutableSet; + +/** + * A collection of Networks + */ +public class SecurityGroups extends PaginatedCollection<SecurityGroup> { + public static final SecurityGroups EMPTY = new SecurityGroups(ImmutableSet.<SecurityGroup> of(), ImmutableSet.<Link> of()); + + @ConstructorProperties({"security_groups", "security_groups_links"}) + protected SecurityGroups(Iterable<SecurityGroup> securityGroups, Iterable<Link> securityGroupsLinks) { + super(securityGroups, securityGroupsLinks); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApi.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApi.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApi.java new file mode 100644 index 0000000..4c0b4da --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApi.java @@ -0,0 +1,186 @@ +/* + * 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.neutron.v2.extensions; + +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; +import org.jclouds.collect.PagedIterable; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; +import org.jclouds.openstack.neutron.v2.domain.Rule; +import org.jclouds.openstack.neutron.v2.domain.Rules; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroup; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroups; +import org.jclouds.openstack.neutron.v2.fallbacks.EmptyRulesFallback; +import org.jclouds.openstack.neutron.v2.fallbacks.EmptySecurityGroupsFallback; +import org.jclouds.openstack.neutron.v2.functions.ParseRules; +import org.jclouds.openstack.neutron.v2.functions.ParseSecurityGroups; +import org.jclouds.openstack.neutron.v2.functions.RulesToPagedIterable; +import org.jclouds.openstack.neutron.v2.functions.SecurityGroupsToPagedIterable; +import org.jclouds.openstack.v2_0.options.PaginationOptions; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.rest.annotations.Transform; +import org.jclouds.rest.annotations.WrapWith; +import com.google.common.annotations.Beta; + +/** + * Provides access to Security Group extension operations for the OpenStack Networking (Neutron) v2 API. + * <p/> + * Security groups and security group rules allows administrators and tenants the ability to specify the type of + * traffic and direction (ingress/egress) that is allowed to pass through a port. A security group is a container for + * security group rules. + */ +@Beta +@RequestFilters(AuthenticateRequest.class) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface SecurityGroupApi { + /** + * Groups + */ + + /** + * @return all security groups currently defined in Neutron for the current tenant. + */ + @Path("/security-groups") + @Named("security-group:list") + @GET + @ResponseParser(ParseSecurityGroups.class) + @Transform(SecurityGroupsToPagedIterable.class) + @Fallback(EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<SecurityGroup> listSecurityGroups(); + + /** + * @return all security groups currently defined in Neutron for the current tenant. + */ + @Path("/security-groups") + @Named("security-group:list") + @GET + @ResponseParser(ParseSecurityGroups.class) + @Fallback(EmptySecurityGroupsFallback.class) + SecurityGroups listSecurityGroups(PaginationOptions options); + + /** + * @param id the id of the security group to return + * @return SecurityGroup or null if not found. + */ + @Path("/security-groups/{id}") + @Named("security-group:get") + @GET + @SelectJson("security_group") + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + @Nullable + SecurityGroup getSecurityGroup(@PathParam("id") String id); + + /** + * Create a new SecurityGroup. + * + * @param securityGroup Describes the security group to be created. + * @return a reference of the newly-created security group + */ + @Path("/security-groups") + @Named("secuity-group:create") + @POST + @SelectJson("security_group") + SecurityGroup create(@WrapWith("security_group") SecurityGroup.CreateOptions securityGroup); + + /** + * Deletes the specified Security Group. + * + * @param id the id of the security group to delete + * @return true if delete was successful, false if not + */ + @Path("/security-groups/{id}") + @Named("security-group:delete") + @DELETE + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + boolean deleteSecurityGroup(@PathParam("id") String id); + + /** + * Rules + */ + + /** + * @return all security groups rules currently defined in Neutron for the current tenant. + */ + @Path("/security-group-rules") + @Named("security-group-rule:list") + @GET + @ResponseParser(ParseRules.class) + @Transform(RulesToPagedIterable.class) + @Fallback(EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<Rule> listRules(); + + /** + * @return all security groups rules currently defined in Neutron for the current tenant. + */ + @Path("/security-group-rules") + @Named("security-group-rule:list") + @GET + @ResponseParser(ParseRules.class) + @Fallback(EmptyRulesFallback.class) + Rules listRules(PaginationOptions options); + + /** + * @param id the id of the security group rule to return. + * @return SecurityGroupRule or null if not found. + */ + @Path("/security-group-rules/{id}") + @Named("security-group-rule:get") + @GET + @SelectJson("security_group_rule") + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + @Nullable + Rule get(@PathParam("id") String id); + + /** + * Create a new Security Group Rule. + * + * @param securityGroupRule Describes the security group rule to be created. + * @return a reference of the newly-created security group rule. + */ + @Path("/security-group-rules") + @Named("security-group-rule:create") + @POST + @SelectJson("security_group_rule") + Rule create(@WrapWith("security_group_rule") Rule.CreateOptions securityGroupRule); + + /** + * Deletes the specified Security Group Rule. + * + * @param id the id of the security group rule to delete. + * @return true if delete was successful, false if not. + */ + @Path("/security-group-rules/{id}") + @Named("security-group-rule:delete") + @DELETE + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + boolean deleteRule(@PathParam("id") String id); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptyRulesFallback.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptyRulesFallback.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptyRulesFallback.java new file mode 100644 index 0000000..a559f4f --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptyRulesFallback.java @@ -0,0 +1,45 @@ +/* + * 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.neutron.v2.fallbacks; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.util.concurrent.Futures.immediateFuture; +import static org.jclouds.http.HttpUtils.contains404; +import static org.jclouds.util.Throwables2.getFirstThrowableOfType; + +import org.jclouds.Fallback; +import org.jclouds.openstack.neutron.v2.domain.Rules; +import org.jclouds.rest.ResourceNotFoundException; +import com.google.common.util.concurrent.ListenableFuture; + +public class EmptyRulesFallback implements Fallback<Rules> { + + public ListenableFuture<Rules> create(Throwable t) throws Exception { + return immediateFuture(createOrPropagate(t)); + } + + @Override + public Rules createOrPropagate(Throwable t) throws Exception { + if ((getFirstThrowableOfType(checkNotNull(t, "throwable"), ResourceNotFoundException.class) != null) + || contains404(t)) { + return Rules.EMPTY; + } + throw propagate(t); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptySecurityGroupsFallback.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptySecurityGroupsFallback.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptySecurityGroupsFallback.java new file mode 100644 index 0000000..5343c3f --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/fallbacks/EmptySecurityGroupsFallback.java @@ -0,0 +1,45 @@ +/* + * 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.neutron.v2.fallbacks; + +import com.google.common.util.concurrent.ListenableFuture; +import org.jclouds.Fallback; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroups; +import org.jclouds.rest.ResourceNotFoundException; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.util.concurrent.Futures.immediateFuture; +import static org.jclouds.http.HttpUtils.contains404; +import static org.jclouds.util.Throwables2.getFirstThrowableOfType; + +public class EmptySecurityGroupsFallback implements Fallback<SecurityGroups> { + + public ListenableFuture<SecurityGroups> create(Throwable t) throws Exception { + return immediateFuture(createOrPropagate(t)); + } + + @Override + public SecurityGroups createOrPropagate(Throwable t) throws Exception { + if ((getFirstThrowableOfType(checkNotNull(t, "throwable"), ResourceNotFoundException.class) != null) + || contains404(t)) { + return SecurityGroups.EMPTY; + } + throw propagate(t); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseRules.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseRules.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseRules.java new file mode 100644 index 0000000..954180b --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseRules.java @@ -0,0 +1,38 @@ +/* + * 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.neutron.v2.functions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.openstack.neutron.v2.domain.Rules; + +import com.google.inject.TypeLiteral; + +/** + * Used by jclouds to provide more specific collections and fallbacks. + */ +@Singleton +public class ParseRules extends ParseJson<Rules> { + + @Inject + public ParseRules(Json json) { + super(json, TypeLiteral.get(Rules.class)); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseSecurityGroups.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseSecurityGroups.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseSecurityGroups.java new file mode 100644 index 0000000..fbc3fd4 --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/ParseSecurityGroups.java @@ -0,0 +1,38 @@ +/* + * 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.neutron.v2.functions; + +import com.google.inject.TypeLiteral; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroup; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroups; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Used by jclouds to provide more specific collections and fallbacks. + */ +@Singleton +public class ParseSecurityGroups extends ParseJson<SecurityGroups> { + + @Inject + public ParseSecurityGroups(Json json) { + super(json, TypeLiteral.get(SecurityGroups.class)); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/RulesToPagedIterable.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/RulesToPagedIterable.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/RulesToPagedIterable.java new file mode 100644 index 0000000..d664cd6 --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/RulesToPagedIterable.java @@ -0,0 +1,66 @@ +/* + * 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.neutron.v2.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; + +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.internal.Arg0ToPagedIterable; +import org.jclouds.openstack.neutron.v2.NeutronApi; +import org.jclouds.openstack.neutron.v2.domain.Rule; +import org.jclouds.openstack.neutron.v2.extensions.SecurityGroupApi; +import org.jclouds.openstack.v2_0.options.PaginationOptions; + +import com.google.common.base.Function; +import com.google.common.base.Optional; + +/** + * Ensures Routers works as PagedIterable. + */ +public class RulesToPagedIterable extends + Arg0ToPagedIterable.FromCaller<Rule, RulesToPagedIterable> { + + private final NeutronApi api; + + @Inject + protected RulesToPagedIterable(NeutronApi api) { + this.api = checkNotNull(api, "api"); + } + + @Override + protected Function<Object, IterableWithMarker<Rule>> markerToNextForArg0(Optional<Object> arg0) { + String region = arg0.isPresent() ? arg0.get().toString() : null; + final SecurityGroupApi securityGroupApi = api.getSecurityGroupApi(region).get(); + return new Function<Object, IterableWithMarker<Rule>>() { + + @SuppressWarnings("unchecked") + @Override + public IterableWithMarker<Rule> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return IterableWithMarker.class.cast(securityGroupApi.listRules(paginationOptions)); + } + + @Override + public String toString() { + return "listRules()"; + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/SecurityGroupsToPagedIterable.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/SecurityGroupsToPagedIterable.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/SecurityGroupsToPagedIterable.java new file mode 100644 index 0000000..15c7c14 --- /dev/null +++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/functions/SecurityGroupsToPagedIterable.java @@ -0,0 +1,66 @@ +/* + * 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.neutron.v2.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; + +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.internal.Arg0ToPagedIterable; +import org.jclouds.openstack.neutron.v2.NeutronApi; +import org.jclouds.openstack.neutron.v2.domain.SecurityGroup; +import org.jclouds.openstack.neutron.v2.extensions.SecurityGroupApi; +import org.jclouds.openstack.v2_0.options.PaginationOptions; + +import com.google.common.base.Function; +import com.google.common.base.Optional; + +/** + * Ensures Routers works as PagedIterable. + */ +public class SecurityGroupsToPagedIterable extends + Arg0ToPagedIterable.FromCaller<SecurityGroup, SecurityGroupsToPagedIterable> { + + private final NeutronApi api; + + @Inject + protected SecurityGroupsToPagedIterable(NeutronApi api) { + this.api = checkNotNull(api, "api"); + } + + @Override + protected Function<Object, IterableWithMarker<SecurityGroup>> markerToNextForArg0(Optional<Object> arg0) { + String region = arg0.isPresent() ? arg0.get().toString() : null; + final SecurityGroupApi securityGroupApi = api.getSecurityGroupApi(region).get(); + return new Function<Object, IterableWithMarker<SecurityGroup>>() { + + @SuppressWarnings("unchecked") + @Override + public IterableWithMarker<SecurityGroup> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return IterableWithMarker.class.cast(securityGroupApi.listSecurityGroups(paginationOptions)); + } + + @Override + public String toString() { + return "listSecurityGroups()"; + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/67b9f472/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApiLiveTest.java ---------------------------------------------------------------------- diff --git a/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApiLiveTest.java b/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApiLiveTest.java new file mode 100644 index 0000000..8771a3e --- /dev/null +++ b/openstack-neutron/src/test/java/org/jclouds/openstack/neutron/v2/extensions/SecurityGroupApiLiveTest.java @@ -0,0 +1,88 @@ +/* + * 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.neutron.v2.extensions; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +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.domain.SecurityGroup; +import org.jclouds.openstack.neutron.v2.internal.BaseNeutronApiLiveTest; +import org.testng.annotations.Test; + +/** + * Tests parsing and Guice wiring of RouterApi + */ +@Test(groups = "live", testName = "SecurityGroupApiLiveTest") +public class SecurityGroupApiLiveTest extends BaseNeutronApiLiveTest { + + /** + * Smoke test for the Security Group extension for Neutron + */ + public void testCreateUpdateAndDeleteSecurityGroup() { + for (String region : api.getConfiguredRegions()) { + SecurityGroupApi sgApi = api.getSecurityGroupApi(region).get(); + + SecurityGroup securityGroup = sgApi.create( + SecurityGroup.createOptions().name("jclouds-test").description("jclouds test security group").build()); + assertNotNull(securityGroup); + + Rule rule = sgApi.create( + Rule.createOptions(RuleDirection.EGRESS, securityGroup.getId()) + .ethertype(RuleEthertype.IPV6) + .portRangeMax(90) + .portRangeMin(80) + .protocol(RuleProtocol.TCP) + .build()); + + assertNotNull(rule); + + // Refresh + securityGroup = sgApi.getSecurityGroup(securityGroup.getId()); + + assertEquals(securityGroup.getName(), "jclouds-test"); + assertEquals(securityGroup.getDescription(), "jclouds test security group"); + + assertEquals(securityGroup.getRules().size(), 3, "Expected 2 default rules"); + + Rule newSecGroupRule = null; + for(Rule sgr : securityGroup.getRules()) { + if(sgr.getId().equals(rule.getId())) { + newSecGroupRule = sgr; + break; + } + } + assertNotNull(newSecGroupRule, "Did not find the new rule in the group."); + + assertEquals(rule, newSecGroupRule); + + assertEquals(rule.getEthertype(), RuleEthertype.IPV6); + assertEquals(rule.getProtocol(), RuleProtocol.TCP); + assertEquals(rule.getPortRangeMax().intValue(), 90); + assertEquals(rule.getPortRangeMin().intValue(), 80); + assertEquals(rule.getDirection(), RuleDirection.EGRESS); + + assertTrue(sgApi.deleteRule(rule.getId())); + assertTrue(sgApi.deleteSecurityGroup(securityGroup.getId())); + } + } +}
