Merge pull request #1179 from rackspace/rax-clb-access-list

The access list API for Rackspace Cloud Load Balancers.
This commit is contained in:
Adrian Cole 2013-01-16 10:03:16 -08:00
commit 184ff81f3d
19 changed files with 628 additions and 132 deletions

View File

@ -25,6 +25,7 @@ import javax.ws.rs.PathParam;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone; import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint; import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.rackspace.cloudloadbalancers.features.AccessRuleApi;
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi; import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi;
import org.jclouds.rackspace.cloudloadbalancers.features.NodeApi; import org.jclouds.rackspace.cloudloadbalancers.features.NodeApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -62,4 +63,11 @@ public interface CloudLoadBalancersApi {
NodeApi getNodeApiForZoneAndLoadBalancer( NodeApi getNodeApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Access Rule features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
AccessRuleApi getAccessRuleApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
} }

View File

@ -48,7 +48,8 @@ import com.google.inject.Module;
*/ */
public class CloudLoadBalancersApiMetadata extends BaseRestApiMetadata { public class CloudLoadBalancersApiMetadata extends BaseRestApiMetadata {
public static final TypeToken<RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>> CONTEXT_TOKEN = new TypeToken<RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>>() { public static final TypeToken<RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>> CONTEXT_TOKEN =
new TypeToken<RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>>() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
}; };

View File

@ -26,6 +26,7 @@ import javax.ws.rs.PathParam;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone; import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint; import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.rackspace.cloudloadbalancers.features.AccessRuleApi;
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerAsyncApi; import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.features.NodeAsyncApi; import org.jclouds.rackspace.cloudloadbalancers.features.NodeAsyncApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -63,4 +64,11 @@ public interface CloudLoadBalancersAsyncApi {
NodeAsyncApi getNodeApiForZoneAndLoadBalancer( NodeAsyncApi getNodeApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Access Rule features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
AccessRuleApi getAccessRuleApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
} }

View File

@ -28,6 +28,8 @@ import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersAsyncApi; import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi; import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi;
import org.jclouds.rackspace.cloudloadbalancers.features.AccessRuleApi;
import org.jclouds.rackspace.cloudloadbalancers.features.AccessRuleAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerAsyncApi; import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi; import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi;
import org.jclouds.rackspace.cloudloadbalancers.features.NodeAsyncApi; import org.jclouds.rackspace.cloudloadbalancers.features.NodeAsyncApi;
@ -52,6 +54,7 @@ public class CloudLoadBalancersRestClientModule extends
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(LoadBalancerApi.class, LoadBalancerAsyncApi.class) .put(LoadBalancerApi.class, LoadBalancerAsyncApi.class)
.put(NodeApi.class, NodeAsyncApi.class) .put(NodeApi.class, NodeAsyncApi.class)
.put(AccessRuleApi.class, AccessRuleAsyncApi.class)
.build(); .build();
public CloudLoadBalancersRestClientModule() { public CloudLoadBalancersRestClientModule() {

View File

@ -24,41 +24,49 @@ import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Objects.ToStringHelper;
/** /**
* The access list management feature allows fine-grained network access controls to be applied to the load balancer's * The access rule management feature allows fine-grained network access controls to be applied to the load balancer's
* virtual IP address. A single IP address, multiple IP addresses, or entire network subnets can be added as an access * virtual IP address. A single IP address, multiple IP addresses, or entire network subnets can be added as an access
* rule. Items that are configured with the ALLOW type will always take precedence over items with the DENY type. To * rule. Rules that are configured with the ALLOW type will always take precedence over rules with the DENY type. To
* reject traffic from all items except for those with the ALLOW type, add an access rules with an address of * reject traffic from all rules except for those with the ALLOW type, add an access rules with an address of
* "0.0.0.0/0" and a DENY type. * "0.0.0.0/0" and a DENY type.
* *
* @author Everett Toews * @author Everett Toews
*/ */
public class AccessRule { public class AccessRule {
private final int id;
private final Type type; private final Type type;
private final String address; private final String address;
/**
* Use this method to easily construct {@link Type#ALLOW} rules for the address.
*/
public static AccessRule allow(String address) {
return new AccessRule(address, Type.ALLOW);
}
/**
* Use this method to easily construct {@link Type#DENY} rules for the address.
*/
public static AccessRule deny(String address) {
return new AccessRule(address, Type.DENY);
}
protected AccessRule(int id, Type type, String address) { public AccessRule(String address, Type type) {
this.id = id;
this.type = checkNotNull(type, "type");
this.address = checkNotNull(address, "address"); this.address = checkNotNull(address, "address");
} this.type = checkNotNull(type, "type");
public int getId() {
return this.id;
}
public Type getType() {
return this.type;
} }
public String getAddress() { public String getAddress() {
return this.address; return this.address;
} }
public Type getType() {
return this.type;
}
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(id); return Objects.hashCode(address);
} }
@Override @Override
@ -67,12 +75,12 @@ public class AccessRule {
if (obj == null || getClass() != obj.getClass()) return false; if (obj == null || getClass() != obj.getClass()) return false;
AccessRule that = AccessRule.class.cast(obj); AccessRule that = AccessRule.class.cast(obj);
return Objects.equal(this.id, that.id); return Objects.equal(this.address, that.address);
} }
protected ToStringHelper string() { protected ToStringHelper string() {
return Objects.toStringHelper(this) return Objects.toStringHelper(this).omitNullValues()
.add("id", id).add("type", type).add("address", address); .add("address", address).add("type", type);
} }
@Override @Override
@ -82,12 +90,12 @@ public class AccessRule {
public static enum Type { public static enum Type {
/** /**
* Specifies items that will always take precedence over items with the DENY type. * Specifies rules that will always take precedence over rules with the DENY type.
*/ */
ALLOW, ALLOW,
/** /**
* Specifies items to which traffic can be denied. * Specifies rules to which traffic can be denied.
*/ */
DENY, DENY,
@ -101,53 +109,4 @@ public class AccessRule {
} }
} }
} }
public static class Builder {
private int id;
private Type type;
private String address;
/**
* @see AccessRule#getId()
*/
public Builder id(int id) {
this.id = id;
return this;
}
/**
* @see Type
*/
public Builder type(Type type) {
this.type = type;
return this;
}
/**
* IP address for item to add to access list.
*/
public Builder address(String address) {
this.address = address;
return this;
}
public AccessRule build() {
return new AccessRule(id, type, address);
}
public Builder from(AccessRule in) {
return this
.id(in.getId())
.type(in.getType())
.address(in.getAddress());
}
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().from(this);
}
} }

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudloadbalancers.domain;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/**
* The same as {@link AccessRule} but this will have an id as assigned by the Cloud Load Balancers service.
*
* @author Everett Toews
*/
public class AccessRuleWithId extends AccessRule {
private final int id;
public AccessRuleWithId(int id, String address, Type type) {
super(address, type);
this.id = id;
}
public int getId() {
return this.id;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
AccessRuleWithId that = AccessRuleWithId.class.cast(obj);
return Objects.equal(this.id, that.id);
}
protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues()
.add("id", id).add("address", getAddress()).add("type", getType());
}
@Override
public String toString() {
return string().toString();
}
}

View File

@ -49,6 +49,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
private final int nodeCount; private final int nodeCount;
private final SSLTermination sslTermination; private final SSLTermination sslTermination;
private final SourceAddresses sourceAddresses; private final SourceAddresses sourceAddresses;
private final Set<AccessRuleWithId> accessRules;
public LoadBalancer(String region, int id, String name, String protocol, @Nullable Integer port, Set<Node> nodes, public LoadBalancer(String region, int id, String name, String protocol, @Nullable Integer port, Set<Node> nodes,
@Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status, @Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status,
@ -56,10 +57,10 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
String clusterName, Date created, Date updated, @Nullable Map<String, Boolean> connectionLogging, String clusterName, Date created, Date updated, @Nullable Map<String, Boolean> connectionLogging,
@Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount, @Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount,
@Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination, @Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination,
SourceAddresses sourceAddresses, @Nullable Set<AccessRule> accessRules, SourceAddresses sourceAddresses, Set<AccessRuleWithId> accessRules,
@Nullable Set<Metadata> metadata) { @Nullable Set<Metadata> metadata) {
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
connectionThrottle, healthMonitor, accessRules, metadata); connectionThrottle, healthMonitor, metadata);
this.region = checkNotNull(region, "region"); this.region = checkNotNull(region, "region");
checkArgument(id != -1, "id must be specified"); checkArgument(id != -1, "id must be specified");
this.id = id; this.id = id;
@ -72,6 +73,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
this.nodeCount = nodeCount; this.nodeCount = nodeCount;
this.sslTermination = sslTermination; this.sslTermination = sslTermination;
this.sourceAddresses = sourceAddresses; this.sourceAddresses = sourceAddresses;
this.accessRules = accessRules == null ? ImmutableSet.<AccessRuleWithId> of() : ImmutableSet.copyOf(accessRules);
} }
public String getRegion() { public String getRegion() {
@ -151,6 +153,10 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
return sourceAddresses; return sourceAddresses;
} }
public Set<AccessRuleWithId> getAccessRules() {
return accessRules;
}
protected ToStringHelper string() { protected ToStringHelper string() {
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status) return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status)
.add("name", name).add("protocol", protocol).add("port", port).add("nodeCount", getNodeCount()) .add("name", name).add("protocol", protocol).add("port", port).add("nodeCount", getNodeCount())
@ -159,7 +165,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
.add("contentCaching", contentCaching).add("sessionPersistenceType", getSessionPersistenceType()) .add("contentCaching", contentCaching).add("sessionPersistenceType", getSessionPersistenceType())
.add("sslTermination", sslTermination).add("connectionLogging", isConnectionLogging()) .add("sslTermination", sslTermination).add("connectionLogging", isConnectionLogging())
.add("connectionThrottle", connectionThrottle).add("healthMonitor", healthMonitor) .add("connectionThrottle", connectionThrottle).add("healthMonitor", healthMonitor)
.add("accessRules", accessList).add("metadata", getMetadata()).add("sourceAddresses", sourceAddresses) .add("accessRules", accessRules).add("metadata", getMetadata()).add("sourceAddresses", sourceAddresses)
.add("virtualIPs", virtualIPs); .add("virtualIPs", virtualIPs);
} }
@ -253,6 +259,7 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
private int nodeCount = 0; private int nodeCount = 0;
private SSLTermination sslTermination; private SSLTermination sslTermination;
private SourceAddresses sourceAddresses; private SourceAddresses sourceAddresses;
private Set<AccessRuleWithId> accessRules;
public Builder region(String region) { public Builder region(String region) {
this.region = region; this.region = region;
@ -302,16 +309,22 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
return this; return this;
} }
public Builder sslTermination(@Nullable SSLTermination sslTermination) { public Builder sslTermination(SSLTermination sslTermination) {
this.sslTermination = sslTermination; this.sslTermination = checkNotNull(sslTermination, "sslTermination");
return this; return this;
} }
public Builder sourceAddresses(@Nullable SourceAddresses sourceAddresses) { public Builder sourceAddresses(SourceAddresses sourceAddresses) {
this.sourceAddresses = sourceAddresses; this.sourceAddresses = checkNotNull(sourceAddresses, "sourceAddresses");
return this; return this;
} }
public Builder accessRules(Iterable<AccessRuleWithId> accessRules) {
this.accessRules = ImmutableSet.copyOf(checkNotNull(accessRules, "accessRules"));
return this;
}
public LoadBalancer build() { public LoadBalancer build() {
return new LoadBalancer(region, id, name, protocol, port, nodes, timeout, halfClosed, algorithm, status, return new LoadBalancer(region, id, name, protocol, port, nodes, timeout, halfClosed, algorithm, status,
virtualIPs, sessionPersistence, clusterName, created, updated, connectionLogging, connectionThrottle, virtualIPs, sessionPersistence, clusterName, created, updated, connectionLogging, connectionThrottle,
@ -416,14 +429,6 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
return Builder.class.cast(super.healthMonitor(healthMonitor)); return Builder.class.cast(super.healthMonitor(healthMonitor));
} }
/**
* {@inheritDoc}
*/
@Override
public Builder accessRules(@Nullable Set<AccessRule> accessRules) {
return Builder.class.cast(super.accessRules(accessRules));
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */

View File

@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableSet;
public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalancerRequest> { public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalancerRequest> {
private final Set<Map<String, String>> virtualIps; private final Set<Map<String, String>> virtualIps;
private final Set<AccessRule> accessRules;
public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes, public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes,
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
@ -48,8 +49,8 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules, @Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
@Nullable Set<Metadata> metadata, VirtualIP.Type virtualIPType, Integer virtualIPId) { @Nullable Set<Metadata> metadata, VirtualIP.Type virtualIPType, Integer virtualIPId) {
this(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, this(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
connectionThrottle, healthMonitor, accessRules, metadata, getVirtualIPsFromOptions(virtualIPType, connectionThrottle, healthMonitor, accessRules, metadata,
virtualIPId)); getVirtualIPsFromOptions(virtualIPType, virtualIPId));
} }
public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes, public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes,
@ -59,8 +60,9 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules, @Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
@Nullable Set<Metadata> metadata, Set<Map<String, String>> virtualIPsFromOptions) { @Nullable Set<Metadata> metadata, Set<Map<String, String>> virtualIPsFromOptions) {
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
connectionThrottle, healthMonitor, accessRules, metadata); connectionThrottle, healthMonitor, metadata);
this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions"); this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions");
this.accessRules = accessRules;
} }
static Set<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) { static Set<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) {
@ -79,7 +81,7 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
.add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm) .add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm)
.add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType()) .add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType())
.add("connectionLogging", isConnectionLogging()).add("connectionThrottle", connectionThrottle) .add("connectionLogging", isConnectionLogging()).add("connectionThrottle", connectionThrottle)
.add("healthMonitor", healthMonitor).add("accessRules", accessList).add("metadata", metadata) .add("healthMonitor", healthMonitor).add("accessRules", accessRules).add("metadata", metadata)
.add("virtualIps", virtualIps); .add("virtualIps", virtualIps);
} }
@ -92,22 +94,43 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
private VirtualIP.Type virtualIPType; private VirtualIP.Type virtualIPType;
private Integer virtualIPId; private Integer virtualIPId;
private Set<Map<String, String>> virtualIps; private Set<Map<String, String>> virtualIps;
private Set<AccessRule> accessRules;
/**
* @see VirtualIP
*/
public Builder virtualIPId(Integer virtualIPId) { public Builder virtualIPId(Integer virtualIPId) {
this.virtualIPId = virtualIPId; this.virtualIPId = virtualIPId;
return this; return this;
} }
/**
* @see VirtualIP
*/
public Builder virtualIPType(VirtualIP.Type virtualIPType) { public Builder virtualIPType(VirtualIP.Type virtualIPType) {
this.virtualIPType = virtualIPType; this.virtualIPType = virtualIPType;
return this; return this;
} }
/**
* @see VirtualIP
*/
private Builder virtualIPs(Set<Map<String, String>> virtualIPs) { private Builder virtualIPs(Set<Map<String, String>> virtualIPs) {
this.virtualIps = virtualIPs; this.virtualIps = virtualIPs;
return this; return this;
} }
/**
* The access list management feature allows fine-grained network access controls to be applied to the load
* balancer's virtual IP address.
*
* @see AccessRule
*/
public Builder accessRules(Iterable<AccessRule> accessRules) {
this.accessRules = ImmutableSet.<AccessRule> copyOf(checkNotNull(accessRules, "accessRules"));
return this;
}
public LoadBalancerRequest build() { public LoadBalancerRequest build() {
if (virtualIps == null) { if (virtualIps == null) {
return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed, return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed,
@ -147,14 +170,6 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
return Builder.class.cast(super.algorithm(algorithm)); return Builder.class.cast(super.algorithm(algorithm));
} }
/**
* {@inheritDoc}
*/
@Override
public Builder from(LoadBalancerRequest in) {
return Builder.class.cast(super.from(in)).virtualIPs(in.virtualIps);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -179,6 +194,13 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
return Builder.class.cast(super.protocol(protocol)); return Builder.class.cast(super.protocol(protocol));
} }
/**
* {@inheritDoc}
*/
@Override
public Builder from(LoadBalancerRequest in) {
return Builder.class.cast(super.from(in)).virtualIPs(in.virtualIps);
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -25,7 +25,6 @@ import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle; import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle;
import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor; import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
@ -62,7 +61,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
protected Map<String, Boolean> connectionLogging; protected Map<String, Boolean> connectionLogging;
protected ConnectionThrottle connectionThrottle; protected ConnectionThrottle connectionThrottle;
protected HealthMonitor healthMonitor; protected HealthMonitor healthMonitor;
protected Set<AccessRule> accessList;
protected Set<Metadata> metadata; protected Set<Metadata> metadata;
// for serialization only // for serialization only
@ -73,8 +71,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
@Nullable Map<String, SessionPersistenceType> sessionPersistence, @Nullable Map<String, SessionPersistenceType> sessionPersistence,
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle, @Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules, @Nullable HealthMonitor healthMonitor, @Nullable Set<Metadata> metadata) {
@Nullable Set<Metadata> metadata) {
this.name = checkNotNull(name, "name"); this.name = checkNotNull(name, "name");
this.protocol = protocol;// null on deleted LB this.protocol = protocol;// null on deleted LB
this.port = port;// null on deleted LB this.port = port;// null on deleted LB
@ -86,7 +83,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
this.connectionLogging = connectionLogging; this.connectionLogging = connectionLogging;
this.connectionThrottle = connectionThrottle; this.connectionThrottle = connectionThrottle;
this.healthMonitor = healthMonitor; this.healthMonitor = healthMonitor;
this.accessList = accessRules;
this.metadata = metadata; this.metadata = metadata;
} }
@ -171,14 +167,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
return healthMonitor; return healthMonitor;
} }
/**
* @return accessRules, which may be null if accessRules has not been set.
*/
@Nullable
public Set<AccessRule> getAccessRules() {
return accessList;
}
/** /**
* @return metadata, which may be null if metadata has not been set. * @return metadata, which may be null if metadata has not been set.
*/ */
@ -192,7 +180,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
.add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm) .add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm)
.add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType()) .add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType())
.add("connectionLogging", connectionLogging).add("connectionThrottle", connectionThrottle) .add("connectionLogging", connectionLogging).add("connectionThrottle", connectionThrottle)
.add("healthMonitor", healthMonitor).add("accessRules", accessList).add("metadata", metadata); .add("healthMonitor", healthMonitor).add("metadata", metadata);
} }
@Override @Override
@ -300,7 +288,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
protected Map<String, Boolean> connectionLogging; protected Map<String, Boolean> connectionLogging;
protected ConnectionThrottle connectionThrottle; protected ConnectionThrottle connectionThrottle;
protected HealthMonitor healthMonitor; protected HealthMonitor healthMonitor;
protected Set<AccessRule> accessRules;
protected Set<Metadata> metadata; protected Set<Metadata> metadata;
/** /**
@ -427,17 +414,6 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
return this; return this;
} }
/**
* The access list management feature allows fine-grained network access controls to be applied to the load
* balancer's virtual IP address.
*
* @see AccessRule
*/
public Builder<N, T> accessRules(@Nullable Set<AccessRule> accessRules) {
this.accessRules = accessRules;
return this;
}
/** /**
* Information (metadata) that can be associated with each load balancer for the client's personal use. * Information (metadata) that can be associated with each load balancer for the client's personal use.
*/ */
@ -448,7 +424,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
public BaseLoadBalancer<N, T> build() { public BaseLoadBalancer<N, T> build() {
return new BaseLoadBalancer<N, T>(name, protocol, port, nodes, algorithm, timeout, halfClosed, return new BaseLoadBalancer<N, T>(name, protocol, port, nodes, algorithm, timeout, halfClosed,
sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, accessRules, metadata); sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, metadata);
} }
public Builder<N, T> from(T baseLB) { public Builder<N, T> from(T baseLB) {
@ -456,8 +432,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
.algorithm(baseLB.getAlgorithm()).timeout(baseLB.getTimeout()).halfClosed(baseLB.isHalfClosed()) .algorithm(baseLB.getAlgorithm()).timeout(baseLB.getTimeout()).halfClosed(baseLB.isHalfClosed())
.nodes(baseLB.getNodes()).sessionPersistenceType(baseLB.getSessionPersistenceType()) .nodes(baseLB.getNodes()).sessionPersistenceType(baseLB.getSessionPersistenceType())
.connectionLogging(baseLB.isConnectionLogging()).connectionThrottle(baseLB.getConnectionThrottle()) .connectionLogging(baseLB.isConnectionLogging()).connectionThrottle(baseLB.getConnectionThrottle())
.healthMonitor(baseLB.getHealthMonitor()).accessRules(baseLB.getAccessRules()) .healthMonitor(baseLB.getHealthMonitor()).metadata(baseLB.getMetadata());
.metadata(baseLB.getMetadata());
} }
} }

View File

@ -0,0 +1,62 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudloadbalancers.features;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
/**
* The access list management feature allows fine-grained network access controls to be applied to the load balancer's
* virtual IP address.
* <p/>
*
* @see AccessRuleAsyncApi
* @author Everett Toews
*/
public interface AccessRuleApi {
/**
* Create a new access list or append to an existing access list.
*
* When creating an access list, one or more AccessRules are required. If a populated access list already exists
* for the load balancer, it will be appended to with subsequent creates. One access list may include up to 100
* AccessRules. A single address or subnet definition is considered unique and cannot be duplicated between rules
* in an access list.
*/
void create(Iterable<AccessRule> accessList);
/**
* List the AccessRules
*/
Iterable<AccessRuleWithId> list();
/**
* Remove an access rule from the access list.
*/
void remove(int id);
/**
* Batch delete the access rules given the specified ids.
*/
void remove(Iterable<Integer> ids);
/**
* Remove the entire access list.
*/
void removeAll();
}

View File

@ -0,0 +1,98 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudloadbalancers.features;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see AccessRuleApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface AccessRuleAsyncApi {
/**
* @see AccessRuleApi#create(Iterable)
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/accesslist")
ListenableFuture<Void> create(@WrapWith("accessList") Iterable<AccessRule> accessList);
/**
* @see AccessRuleApi#list()
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@SelectJson("accessList")
@Path("/accesslist")
ListenableFuture<Iterable<AccessRuleWithId>> list();
/**
* @see AccessRuleApi#remove(int)
*/
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@Path("/accesslist/{id}")
@Consumes("*/*")
ListenableFuture<Void> remove(@PathParam("id") int id);
/**
* @see AccessRuleApi#remove(Iterable)
*/
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
ListenableFuture<Void> remove(@QueryParam("id") Iterable<Integer> ids);
/**
* @see AccessRuleApi#removeAll()
*/
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
ListenableFuture<Void> removeAll();
}

View File

@ -22,10 +22,12 @@ import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Builder; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Builder;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@ -56,7 +58,7 @@ public class ConvertLB implements Function<LB, LoadBalancer> {
.timeout(lb.getTimeout()).algorithm(lb.getAlgorithm()).halfClosed(lb.isHalfClosed()) .timeout(lb.getTimeout()).algorithm(lb.getAlgorithm()).halfClosed(lb.isHalfClosed())
.sessionPersistenceType(lb.getSessionPersistenceType()).connectionLogging(lb.isConnectionLogging()) .sessionPersistenceType(lb.getSessionPersistenceType()).connectionLogging(lb.isConnectionLogging())
.connectionThrottle(lb.getConnectionThrottle()).healthMonitor(lb.getHealthMonitor()) .connectionThrottle(lb.getConnectionThrottle()).healthMonitor(lb.getHealthMonitor())
.accessRules(lb.getAccessRules()).metadata(lb.getMetadata()).virtualIPs(lb.virtualIps); .metadata(lb.getMetadata()).virtualIPs(lb.virtualIps);
if (lb.cluster.size() == 1) if (lb.cluster.size() == 1)
builder.clusterName(Iterables.get(lb.cluster.values(), 0)); builder.clusterName(Iterables.get(lb.cluster.values(), 0));
@ -70,6 +72,10 @@ public class ConvertLB implements Function<LB, LoadBalancer> {
builder.sslTermination(lb.sslTermination); builder.sslTermination(lb.sslTermination);
if (lb.sourceAddresses != null) if (lb.sourceAddresses != null)
builder.sourceAddresses(lb.sourceAddresses); builder.sourceAddresses(lb.sourceAddresses);
if (lb.accessList == null)
builder.accessRules(ImmutableSet.<AccessRuleWithId> of());
else
builder.accessRules(lb.accessList);
return builder.build(); return builder.build();
} }

View File

@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Status; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Status;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rackspace.cloudloadbalancers.domain.Node; import org.jclouds.rackspace.cloudloadbalancers.domain.Node;
import org.jclouds.rackspace.cloudloadbalancers.domain.SSLTermination; import org.jclouds.rackspace.cloudloadbalancers.domain.SSLTermination;
import org.jclouds.rackspace.cloudloadbalancers.domain.SourceAddresses; import org.jclouds.rackspace.cloudloadbalancers.domain.SourceAddresses;
@ -47,6 +48,7 @@ class LB extends BaseLoadBalancer<Node, LB> {
Map<String, Boolean> contentCaching = Maps.newLinkedHashMap(); Map<String, Boolean> contentCaching = Maps.newLinkedHashMap();
SSLTermination sslTermination; SSLTermination sslTermination;
SourceAddresses sourceAddresses; SourceAddresses sourceAddresses;
Set<AccessRuleWithId> accessList;
@Override @Override
public int hashCode() { public int hashCode() {

View File

@ -0,0 +1,116 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudloadbalancers.features;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.List;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpResponse;
import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancerApiExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* @author Everett Toews
*/
@Test(groups = "unit")
public class AccessRuleApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudLoadBalancersApi> {
public void testListAccessList() {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/accesslist");
AccessRuleApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/accesslist-list.json")).build()
).getAccessRuleApiForZoneAndLoadBalancer("DFW", 2000);
Iterable<AccessRuleWithId> accessList = api.list();
assertEquals(accessList, getAccessList());
}
public void testCreateAccessList() {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/accesslist");
AccessRuleApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("POST").endpoint(endpoint).payload(payloadFromResource("/accesslist-create.json")).build(),
HttpResponse.builder().statusCode(200).build()
).getAccessRuleApiForZoneAndLoadBalancer("DFW", 2000);
AccessRule accessRule1 = AccessRule.deny("206.160.163.21");
AccessRule accessRule2 = AccessRule.deny("206.160.165.11");
AccessRule accessRule3 = AccessRule.deny("206.160.163.22");
List<AccessRule> accessList = ImmutableList.<AccessRule> of(accessRule1, accessRule2, accessRule3);
api.create(accessList);
}
public void testRemoveSingleAccessRule() {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/accesslist/23");
AccessRuleApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
HttpResponse.builder().statusCode(200).build()
).getAccessRuleApiForZoneAndLoadBalancer("DFW", 2000);
api.remove(23);
}
public void testRemoveManyAccessRules() {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/accesslist?id=23&id=24");
AccessRuleApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
HttpResponse.builder().statusCode(200).build()
).getAccessRuleApiForZoneAndLoadBalancer("DFW", 2000);
List<Integer> accessRuleIds = ImmutableList.<Integer> of(23, 24);
api.remove(accessRuleIds);
}
public void testRemoveAllAccessRules() {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000/accesslist");
AccessRuleApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey,
responseWithAccess,
authenticatedGET().method("DELETE").endpoint(endpoint).replaceHeader("Accept", MediaType.WILDCARD).build(),
HttpResponse.builder().statusCode(200).build()
).getAccessRuleApiForZoneAndLoadBalancer("DFW", 2000);
api.removeAll();
}
private Iterable<AccessRule> getAccessList() {
AccessRule accessRule1 = new AccessRuleWithId(23, "206.160.163.21", AccessRule.Type.DENY);
AccessRule accessRule2 = new AccessRuleWithId(24, "206.160.165.11", AccessRule.Type.DENY);
AccessRule accessRule3 = new AccessRuleWithId(25, "206.160.163.22", AccessRule.Type.DENY);
return ImmutableList.<AccessRule> of(accessRule1, accessRule2, accessRule3);
}
}

View File

@ -0,0 +1,145 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudloadbalancers.features;
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitAvailable;
import static org.jclouds.rackspace.cloudloadbalancers.predicates.LoadBalancerPredicates.awaitDeleted;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.rackspace.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP.Type;
import org.jclouds.rackspace.cloudloadbalancers.internal.BaseCloudLoadBalancersApiLiveTest;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
/**
* @author Everett Toews
*/
@Test(groups = "live", singleThreaded = true, testName = "AccessListApiLiveTest")
public class AccessRuleApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
private LoadBalancer lb;
private String zone;
private AccessRule accessRule1;
private AccessRule accessRule2;
private AccessRule accessRule3;
private AccessRule accessRule4;
private Map<String, AccessRule> accessRules;
@Override
@BeforeGroups(groups = { "live" })
public void setupContext() {
super.setupContext();
accessRule1 = AccessRule.deny("206.160.163.21");
accessRule2 = AccessRule.deny("206.160.165.11");
accessRule3 = AccessRule.deny("206.160.163.22");
accessRule4 = AccessRule.deny("206.160.168.22");
accessRules = new HashMap<String, AccessRule>();
accessRules.put(accessRule1.getAddress(), accessRule1);
accessRules.put(accessRule2.getAddress(), accessRule2);
accessRules.put(accessRule3.getAddress(), accessRule3);
accessRules.put(accessRule4.getAddress(), accessRule4);
}
public void testCreateLoadBalancer() {
NodeRequest nodeRequest = NodeRequest.builder().address("192.168.1.1").port(8080).build();
LoadBalancerRequest lbRequest = LoadBalancerRequest.builder()
.name(prefix+"-jclouds").protocol("HTTP").port(80).virtualIPType(Type.PUBLIC).node(nodeRequest).build();
zone = Iterables.getFirst(clbApi.getConfiguredZones(), null);
lb = clbApi.getLoadBalancerApiForZone(zone).create(lbRequest);
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
}
@Test(dependsOnMethods = "testCreateLoadBalancer")
public void testCreateAccessList() throws Exception {
clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).create(accessRules.values());
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
assertExpectedAccessRules(accessRules);
}
@Test(dependsOnMethods = "testCreateAccessList")
public void testRemoveSingleAccessRule() throws Exception {
Iterable<AccessRuleWithId> actualAccessList = clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).list();
AccessRuleWithId removedAccessRule = Iterables.getFirst(actualAccessList, null);
accessRules.remove(removedAccessRule.getAddress());
clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).remove(removedAccessRule.getId());
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
assertExpectedAccessRules(accessRules);
}
@Test(dependsOnMethods = "testRemoveSingleAccessRule")
public void testRemoveManyAccessRules() throws Exception {
Iterable<AccessRuleWithId> actualAccessList = clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).list();
AccessRuleWithId removedAccessRule1 = Iterables.getFirst(actualAccessList, null);
AccessRuleWithId removedAccessRule2 = Iterables.getLast(actualAccessList);
List<Integer> removedAccessRuleIds = ImmutableList.<Integer> of(removedAccessRule1.getId(), removedAccessRule2.getId());
accessRules.remove(removedAccessRule1.getAddress());
accessRules.remove(removedAccessRule2.getAddress());
clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).remove(removedAccessRuleIds);
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
assertExpectedAccessRules(accessRules);
}
@Test(dependsOnMethods = "testRemoveManyAccessRules")
public void testRemoveAllAccessRules() throws Exception {
clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).removeAll();
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
assertExpectedAccessRules(new HashMap<String, AccessRule>());
}
private void assertExpectedAccessRules(Map<String, AccessRule> expectedAccessList) {
Iterable<AccessRuleWithId> actualAccessList = clbApi.getAccessRuleApiForZoneAndLoadBalancer(zone, lb.getId()).list();
for (AccessRule actualAccessRule: actualAccessList) {
assertEquals(expectedAccessList.containsKey(actualAccessRule.getAddress()), true,
"The AccessRule " + actualAccessRule + " was not found in " + expectedAccessList);
}
}
@Override
@AfterGroups(groups = "live")
protected void tearDownContext() {
assertTrue(awaitAvailable(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
clbApi.getLoadBalancerApiForZone(zone).remove(lb.getId());
assertTrue(awaitDeleted(clbApi.getLoadBalancerApiForZone(zone)).apply(lb));
super.tearDownContext();
}
}

View File

@ -58,7 +58,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
assertEquals(loadBalancers, testLoadBalancers()); assertEquals(loadBalancers, testLoadBalancers());
} }
public void testGetLoadBalancer() { public void testGetLoadBalancer() throws Exception {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000"); URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers/2000");
LoadBalancerApi api = requestsSendResponses( LoadBalancerApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey, rackspaceAuthWithUsernameAndApiKey,
@ -71,7 +71,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
assertEquals(loadBalancer, testLoadBalancer()); assertEquals(loadBalancer, testLoadBalancer());
} }
public void testCreateLoadBalancer() { public void testCreateLoadBalancer() throws Exception {
URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers"); URI endpoint = URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123123/loadbalancers");
LoadBalancerApi api = requestsSendResponses( LoadBalancerApi api = requestsSendResponses(
rackspaceAuthWithUsernameAndApiKey, rackspaceAuthWithUsernameAndApiKey,

View File

@ -22,6 +22,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule; import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRuleWithId;
import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle; import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle;
import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor; import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor;
import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor.Type; import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor.Type;
@ -75,8 +76,8 @@ public class ParseLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
.sourceAddresses(SourceAddresses.builder().ipv6Public("2001:4800:7901::5/64").ipv4Public("174.143.139.137").ipv4Servicenet("10.183.250.137").build()) .sourceAddresses(SourceAddresses.builder().ipv6Public("2001:4800:7901::5/64").ipv4Public("174.143.139.137").ipv4Servicenet("10.183.250.137").build())
.connectionThrottle(ConnectionThrottle.builder().maxConnections(100).minConnections(10).maxConnectionRate(50).rateInterval(60).build()) .connectionThrottle(ConnectionThrottle.builder().maxConnections(100).minConnections(10).maxConnectionRate(50).rateInterval(60).build())
.accessRules(ImmutableSet.of( .accessRules(ImmutableSet.of(
AccessRule.builder().id(22215).type(AccessRule.Type.DENY).address("1.2.3.4/32").build(), new AccessRuleWithId(22215, "1.2.3.4/32", AccessRule.Type.DENY),
AccessRule.builder().id(22217).type(AccessRule.Type.ALLOW).address("12.0.0.0/8").build())) new AccessRuleWithId(22217, "12.0.0.0/8", AccessRule.Type.ALLOW)))
.virtualIPs(ImmutableSet.of( .virtualIPs(ImmutableSet.of(
VirtualIP.builder().id(1000).address("206.10.10.210").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV4).build(), VirtualIP.builder().id(1000).address("206.10.10.210").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV4).build(),
VirtualIP.builder().id(1001).address("2001:4800:7901:0000:9a32:3c2a:0000:0001").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV6).build())) VirtualIP.builder().id(1001).address("2001:4800:7901:0000:9a32:3c2a:0000:0001").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV6).build()))

View File

@ -0,0 +1 @@
{"accessList":[{"address":"206.160.163.21","type":"DENY"},{"address":"206.160.165.11","type":"DENY"},{"address":"206.160.163.22","type":"DENY"}]}

View File

@ -0,0 +1,19 @@
{
"accessList": [
{
"address": "206.160.163.21",
"id": 23,
"type": "DENY"
},
{
"address": "206.160.165.11",
"id": 24,
"type": "DENY"
},
{
"address": "206.160.163.22",
"id": 25,
"type": "DENY"
}
]
}