Merge pull request #299 from andreisavu/complete-firewall-client

Complete the Firewall Client API
This commit is contained in:
Adrian Cole 2012-01-09 17:28:22 -08:00
commit 777ec8e504
21 changed files with 1376 additions and 132 deletions

View File

@ -28,6 +28,7 @@ import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.Account; import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.Account.State; import org.jclouds.cloudstack.domain.Account.State;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.User; import org.jclouds.cloudstack.domain.User;
@ -47,11 +48,12 @@ import com.google.inject.TypeLiteral;
/** /**
* Configures the cloudstack parsers. * Configures the cloudstack parsers.
* *
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
public class CloudStackParserModule extends AbstractModule { public class CloudStackParserModule extends AbstractModule {
public static class PortForwardingRuleAdaptor implements JsonSerializer<PortForwardingRule>, JsonDeserializer<PortForwardingRule> { @Singleton
public static class PortForwardingRuleAdapter implements JsonSerializer<PortForwardingRule>, JsonDeserializer<PortForwardingRule> {
public JsonElement serialize(PortForwardingRule src, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(PortForwardingRule src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src); return context.serialize(src);
@ -85,10 +87,10 @@ public class CloudStackParserModule extends AbstractModule {
private long IPAddressId; private long IPAddressId;
@SerializedName("privateport") @SerializedName("privateport")
private int privatePort; private int privatePort;
private String protocol; private PortForwardingRule.Protocol protocol;
@SerializedName("publicport") @SerializedName("publicport")
public int publicPort; public int publicPort;
private String state; private PortForwardingRule.State state;
@SerializedName("virtualmachinedisplayname") @SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
@SerializedName("virtualmachineid") @SerializedName("virtualmachineid")
@ -104,6 +106,52 @@ public class CloudStackParserModule extends AbstractModule {
} }
} }
@Singleton
public static class FirewallRuleAdapter implements JsonSerializer<FirewallRule>, JsonDeserializer<FirewallRule> {
public JsonElement serialize(FirewallRule src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
public FirewallRule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return apply(context.<FirewallRuleInternal>deserialize(json, FirewallRuleInternal.class));
}
public FirewallRule apply(FirewallRuleInternal in) {
Set<String> cidrSet;
if (in.CIDRs != null) {
String[] elements = in.CIDRs.split(",");
cidrSet = Sets.newTreeSet(Arrays.asList(elements));
} else {
cidrSet = Collections.emptySet();
}
return FirewallRule.builder().id(in.id).CIDRs(cidrSet).startPort(in.startPort).endPort(in.endPort)
.icmpCode(in.icmpCode).icmpType(in.icmpType).ipAddress(in.ipAddress).ipAddressId(in.ipAddressId)
.protocol(in.protocol).state(in.state).build();
}
static final class FirewallRuleInternal {
private long id;
@SerializedName("cidrlist")
private String CIDRs;
@SerializedName("startport")
private int startPort;
@SerializedName("endport")
private int endPort;
@SerializedName("icmpcode")
private String icmpCode;
@SerializedName("icmptype")
private String icmpType;
@SerializedName("ipaddress")
private String ipAddress;
@SerializedName("ipaddressid")
private long ipAddressId;
private FirewallRule.Protocol protocol;
private FirewallRule.State state;
}
}
@Singleton @Singleton
public static class LoadBalancerRuleAdapter implements JsonSerializer<LoadBalancerRule>, JsonDeserializer<LoadBalancerRule> { public static class LoadBalancerRuleAdapter implements JsonSerializer<LoadBalancerRule>, JsonDeserializer<LoadBalancerRule> {
@ -240,7 +288,8 @@ public class CloudStackParserModule extends AbstractModule {
}).toInstance(ImmutableMap.<Type, Object>of( }).toInstance(ImmutableMap.<Type, Object>of(
Account.class, new BreakGenericSetAdapter(), Account.class, new BreakGenericSetAdapter(),
LoadBalancerRule.class, new LoadBalancerRuleAdapter(), LoadBalancerRule.class, new LoadBalancerRuleAdapter(),
PortForwardingRule.class, new PortForwardingRuleAdaptor() PortForwardingRule.class, new PortForwardingRuleAdapter(),
FirewallRule.class, new FirewallRuleAdapter()
)); ));
} }

View File

@ -0,0 +1,288 @@
/**
* 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.cloudstack.domain;
import com.google.common.base.CaseFormat;
import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.SerializedName;
import org.omg.PortableInterceptor.ACTIVE;
import java.util.Set;
/**
* @author Andrei Savu
*/
public class FirewallRule implements Comparable<FirewallRule> {
public static enum Protocol {
TCP,
UDP,
ICMP,
UNKNOWN;
public static Protocol fromValue(String value) {
try {
return valueOf(value.toUpperCase());
} catch(IllegalArgumentException e) {
return UNKNOWN;
}
}
@Override
public String toString() {
return name().toUpperCase();
}
}
public static enum State {
STAGED, // Rule been created but has never got through network rule conflict detection.
// Rules in this state can not be sent to network elements.
ADD, // Add means the rule has been created and has gone through network rule conflict detection.
ACTIVE, // Rule has been sent to the network elements and reported to be active.
DELETEING, // Revoke means this rule has been revoked. If this rule has been sent to the
// network elements, the rule will be deleted from database.
UNKNOWN;
public static State fromValue(String value) {
try {
return valueOf(value.toUpperCase());
} catch(IllegalArgumentException e) {
return UNKNOWN;
}
}
@Override
public String toString() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id;
private Set<String> CIDRs;
private int startPort;
private int endPort;
private String icmpCode;
private String icmpType;
private String ipAddress;
private long ipAddressId;
private Protocol protocol;
private State state;
public Builder id(long id) {
this.id = id;
return this;
}
public Builder CIDRs(Set<String> CIDRs) {
this.CIDRs = ImmutableSet.copyOf(CIDRs);
return this;
}
public Builder startPort(int startPort) {
this.startPort = startPort;
return this;
}
public Builder endPort(int endPort) {
this.endPort = endPort;
return this;
}
public Builder icmpCode(String icmpCode) {
this.icmpCode = icmpCode;
return this;
}
public Builder icmpType(String icmpType) {
this.icmpType = icmpType;
return this;
}
public Builder ipAddress(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public Builder ipAddressId(long ipAddressId) {
this.ipAddressId = ipAddressId;
return this;
}
public Builder protocol(Protocol protocol) {
this.protocol = protocol;
return this;
}
public Builder state(State state) {
this.state = state;
return this;
}
public FirewallRule build() {
return new FirewallRule(id, CIDRs, startPort, endPort, icmpCode,
icmpType, ipAddress, ipAddressId, protocol, state);
}
}
private long id;
@SerializedName("cidrlist")
private Set<String> CIDRs;
@SerializedName("startport")
private int startPort;
@SerializedName("endport")
private int endPort;
@SerializedName("icmpcode")
private String icmpCode;
@SerializedName("icmptype")
private String icmpType;
@SerializedName("ipaddress")
private String ipAddress;
@SerializedName("ipaddressid")
private long ipAddressId;
private Protocol protocol;
private State state;
public FirewallRule(long id, Set<String> CIDRs, int startPort, int endPort,
String icmpCode, String icmpType, String ipAddress, long ipAddressId,
Protocol protocol, State state) {
this.id = id;
this.CIDRs = ImmutableSet.copyOf(CIDRs);
this.startPort = startPort;
this.endPort = endPort;
this.icmpCode = icmpCode;
this.icmpType = icmpType;
this.ipAddress = ipAddress;
this.ipAddressId = ipAddressId;
this.protocol = protocol;
this.state = state;
}
@Override
public int compareTo(FirewallRule arg0) {
return new Long(id).compareTo(arg0.getId());
}
public long getId() {
return id;
}
public Set<String> getCIDRs() {
return CIDRs;
}
public int getStartPort() {
return startPort;
}
public int getEndPort() {
return endPort;
}
public String getIcmpCode() {
return icmpCode;
}
public String getIcmpType() {
return icmpType;
}
public String getIpAddress() {
return ipAddress;
}
public long getIpAddressId() {
return ipAddressId;
}
public Protocol getProtocol() {
return protocol;
}
public State getState() {
return state;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FirewallRule that = (FirewallRule) o;
if (endPort != that.endPort) return false;
if (id != that.id) return false;
if (startPort != that.startPort) return false;
if (CIDRs != null ? !CIDRs.equals(that.CIDRs) : that.CIDRs != null)
return false;
if (icmpCode != null ? !icmpCode.equals(that.icmpCode) : that.icmpCode != null)
return false;
if (icmpType != null ? !icmpType.equals(that.icmpType) : that.icmpType != null)
return false;
if (ipAddress != null ? !ipAddress.equals(that.ipAddress) : that.ipAddress != null)
return false;
if (ipAddressId != that.ipAddressId)
return false;
if (protocol != null ? !protocol.equals(that.protocol) : that.protocol != null)
return false;
if (state != null ? !state.equals(that.state) : that.state != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (CIDRs != null ? CIDRs.hashCode() : 0);
result = 31 * result + startPort;
result = 31 * result + endPort;
result = 31 * result + (icmpCode != null ? icmpCode.hashCode() : 0);
result = 31 * result + (icmpType != null ? icmpType.hashCode() : 0);
result = 31 * result + (ipAddress != null ? ipAddress.hashCode() : 0);
result = 31 * result + (int) (ipAddressId ^ (ipAddressId >>> 32));
result = 31 * result + (protocol != null ? protocol.hashCode() : 0);
result = 31 * result + (state != null ? state.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "FirewallRule{" +
"id=" + id +
", CIDRs='" + CIDRs + '\'' +
", startPort=" + startPort +
", endPort=" + endPort +
", icmpCode='" + icmpCode + '\'' +
", icmpType='" + icmpType + '\'' +
", ipAddress='" + ipAddress + '\'' +
", ipAddressId='" + ipAddressId + '\'' +
", protocol='" + protocol + '\'' +
", state='" + state + '\'' +
'}';
}
}

View File

@ -20,15 +20,58 @@ package org.jclouds.cloudstack.domain;
import java.util.Set; import java.util.Set;
import com.google.common.base.Joiner; import com.google.common.base.CaseFormat;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
public class PortForwardingRule implements Comparable<PortForwardingRule> { public class PortForwardingRule implements Comparable<PortForwardingRule> {
public static enum Protocol {
TCP,
UDP,
ICMP,
UNKNOWN;
public static Protocol fromValue(String value) {
try {
return valueOf(value.toUpperCase());
} catch (IllegalArgumentException e) {
return UNKNOWN;
}
}
@Override
public String toString() {
return name().toLowerCase();
}
}
public static enum State {
STAGED, // Rule been created but has never got through network rule conflict detection.
// Rules in this state can not be sent to network elements.
ADD, // Add means the rule has been created and has gone through network rule conflict detection.
ACTIVE, // Rule has been sent to the network elements and reported to be active.
DELETEING, // Revoke means this rule has been revoked. If this rule has been sent to the
// network elements, the rule will be deleted from database.
UNKNOWN;
public static State fromValue(String value) {
try {
return valueOf(value.toUpperCase());
} catch (IllegalArgumentException e) {
return UNKNOWN;
}
}
@Override
public String toString() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
}
}
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
@ -38,9 +81,9 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
private String IPAddress; private String IPAddress;
private long IPAddressId; private long IPAddressId;
private int privatePort; private int privatePort;
private String protocol; private Protocol protocol;
public int publicPort; public int publicPort;
private String state; private State state;
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
public long virtualMachineId; public long virtualMachineId;
private String virtualMachineName; private String virtualMachineName;
@ -68,7 +111,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
return this; return this;
} }
public Builder protocol(String protocol) { public Builder protocol(Protocol protocol) {
this.protocol = protocol; this.protocol = protocol;
return this; return this;
} }
@ -78,7 +121,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
return this; return this;
} }
public Builder state(String state) { public Builder state(State state) {
this.state = state; this.state = state;
return this; return this;
} }
@ -126,10 +169,10 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
private long IPAddressId; private long IPAddressId;
@SerializedName("privateport") @SerializedName("privateport")
private int privatePort; private int privatePort;
private String protocol; private Protocol protocol;
@SerializedName("publicport") @SerializedName("publicport")
public int publicPort; public int publicPort;
private String state; private State state;
@SerializedName("virtualmachinedisplayname") @SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
@SerializedName("virtualmachineid") @SerializedName("virtualmachineid")
@ -143,8 +186,8 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
@SerializedName("publicendport") @SerializedName("publicendport")
private int publicEndPort; private int publicEndPort;
public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, String protocol, public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, Protocol protocol,
int publicPort, String state, String virtualMachineDisplayName, long virtualMachineId, int publicPort, State state, String virtualMachineDisplayName, long virtualMachineId,
String virtualMachineName, Set<String> CIDRs, int privateEndPort, int publicEndPort) { String virtualMachineName, Set<String> CIDRs, int privateEndPort, int publicEndPort) {
this.id = id; this.id = id;
this.IPAddress = iPAddress; this.IPAddress = iPAddress;
@ -197,7 +240,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
/** /**
* @return the protocol of the port forwarding rule * @return the protocol of the port forwarding rule
*/ */
public String getProtocol() { public Protocol getProtocol() {
return protocol; return protocol;
} }
@ -211,7 +254,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
/** /**
* @return the state of the rule * @return the state of the rule
*/ */
public String getState() { public State getState() {
return state; return state;
} }

View File

@ -26,15 +26,20 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.filters.QuerySigner; import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions; import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Unwrap; import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -43,14 +48,53 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides asynchronous access to cloudstack via their REST API. * Provides asynchronous access to cloudstack via their REST API.
* <p/> * <p/>
* *
* @author Adrian Cole
* @see FirewallClient * @see FirewallClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface FirewallAsyncClient { public interface FirewallAsyncClient {
/**
* @see FirewallClient#listFirewallRules
*/
@GET
@QueryParams(keys = "command", values = "listFirewallRules")
@SelectJson("firewallrule")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<FirewallRule>> listFirewallRules(ListFirewallRulesOptions... options);
/**
* @see FirewallClient#getFirewallRule
*/
@GET
@QueryParams(keys = "command", values = "listFirewallRules")
@SelectJson("firewallrule")
@OnlyElement
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<FirewallRule> getFirewallRule(@QueryParam("id") long id);
/**
* @see FirewallClient#createFirewallRuleForIpAndProtocol
*/
@GET
@QueryParams(keys = "command", values = "createFirewallRule")
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<AsyncCreateResponse> createFirewallRuleForIpAndProtocol(@QueryParam("ipaddressid") long ipAddressId,
@QueryParam("protocol") FirewallRule.Protocol protocol, CreateFirewallRuleOptions... options);
/**
* @see FirewallClient#deleteFirewallRule
*/
@GET
@QueryParams(keys = "command", values = "deleteFirewallRule")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteFirewallRule(@QueryParam("id") long id);
/** /**
* @see FirewallClient#listPortForwardingRules * @see FirewallClient#listPortForwardingRules
*/ */
@ -61,6 +105,17 @@ public interface FirewallAsyncClient {
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<PortForwardingRule>> listPortForwardingRules(ListPortForwardingRulesOptions... options); ListenableFuture<Set<PortForwardingRule>> listPortForwardingRules(ListPortForwardingRulesOptions... options);
/**
* @see FirewallClient#getPortForwardingRule
*/
@GET
@QueryParams(keys = "command", values = "listPortForwardingRules")
@SelectJson("portforwardingrule")
@OnlyElement
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<PortForwardingRule> getPortForwardingRule(@QueryParam("id") long id);
/** /**
* @see FirewallClient#createPortForwardingRuleForVirtualMachine * @see FirewallClient#createPortForwardingRuleForVirtualMachine
*/ */
@ -69,9 +124,9 @@ public interface FirewallAsyncClient {
@Unwrap @Unwrap
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<AsyncCreateResponse> createPortForwardingRuleForVirtualMachine( ListenableFuture<AsyncCreateResponse> createPortForwardingRuleForVirtualMachine(
@QueryParam("virtualmachineid") long virtualMachineId, @QueryParam("ipaddressid") long IPAddressId, @QueryParam("ipaddressid") long ipAddressId, @QueryParam("protocol") PortForwardingRule.Protocol protocol,
@QueryParam("protocol") String protocol, @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort, @QueryParam("virtualmachineid") long virtualMachineId,
@QueryParam("publicport") int publicPort); @QueryParam("privateport") int privatePort);
/** /**
* @see FirewallClient#deletePortForwardingRule * @see FirewallClient#deletePortForwardingRule

View File

@ -22,7 +22,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions; import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
@ -36,6 +39,49 @@ import org.jclouds.concurrent.Timeout;
*/ */
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface FirewallClient { public interface FirewallClient {
/**
* List the firewall rules
*
* @param options
* if present, how to constrain the list.
* @return
* set of firewall rules or empty set if no rules are found
*/
Set<FirewallRule> listFirewallRules(ListFirewallRulesOptions... options);
/**
* Get a firewall rule by ID
*
* @param id
* the ID of the firewall rule
* @return
* firewall rule instance or null
*/
FirewallRule getFirewallRule(long id);
/**
* Create new firewall rule for a specific IP address
*
* @param ipAddressId
* the IP address id of the port forwarding rule
* @param protocol
* the protocol for the firewall rule. Valid values are TCP/UDP/ICMP
* @param options
* optional arguments for firewall rule creation
* @return
*/
AsyncCreateResponse createFirewallRuleForIpAndProtocol(long ipAddressId,
FirewallRule.Protocol protocol, CreateFirewallRuleOptions... options);
/**
* Deletes a firewall rule
*
* @param id
* the ID of the firewall rule
*/
Void deleteFirewallRule(long id);
/** /**
* List the port forwarding rules * List the port forwarding rules
* *
@ -46,24 +92,33 @@ public interface FirewallClient {
*/ */
Set<PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesOptions... options); Set<PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesOptions... options);
/**
* Get a port forwarding rule by ID
*
* @param id
* port forwarding rule ID
* @return
* rule instance or null
*/
PortForwardingRule getPortForwardingRule(long id);
/** /**
* Creates an port forwarding rule * Creates an port forwarding rule
* *
* @param virtualMachineId *
* the ID of the virtual machine for the port forwarding rule * @param ipAddressId
* @param IPAddressId
* the public IP address id of the forwarding rule, already
* associated via associatePort
* @param protocol * @param protocol
* the protocol for the rule. Valid values are TCP or UDP. * the protocol for the rule. Valid values are TCP or UDP.
* @param privatePort
* the private port of the port forwarding rule
* @param publicPort * @param publicPort
* the public port of the port forwarding rule * the public port of the port forwarding rule
* @param virtualMachineId
* the ID of the virtual machine for the port forwarding rule
* @param privatePort
* the private port of the port forwarding rule
* @return response used to track creation * @return response used to track creation
*/ */
AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long virtualMachineId, long IPAddressId, AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long ipAddressId,
String protocol, int privatePort, int publicPort); PortForwardingRule.Protocol protocol, int publicPort, long virtualMachineId, int privatePort);
/** /**
* Deletes an port forwarding rule * Deletes an port forwarding rule
@ -71,5 +126,5 @@ public interface FirewallClient {
* @param id * @param id
* the id of the forwarding rule * the id of the forwarding rule
*/ */
void deletePortForwardingRule(long id); Void deletePortForwardingRule(long id);
} }

View File

@ -0,0 +1,126 @@
/**
* 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.cloudstack.options;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import org.jclouds.http.options.BaseHttpRequestOptions;
import java.util.Set;
/**
* Options used to control how a firewall rule is created
*
* @see <a href=
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/createFirewallRule.html"
* />
* @author Andrei Savu
*/
public class CreateFirewallRuleOptions extends BaseHttpRequestOptions {
public static final CreateFirewallRuleOptions NONE = new CreateFirewallRuleOptions();
/**
* @param CIDRs
* the list of CIDRs to forward traffic from
*/
public CreateFirewallRuleOptions CIDRs(Set<String> CIDRs) {
this.queryParameters.replaceValues("cidrlist", ImmutableSet.of(Joiner.on(",").join(CIDRs)));
return this;
}
/**
* @param startPort
* the starting port of firewall rule
*/
public CreateFirewallRuleOptions startPort(int startPort) {
this.queryParameters.replaceValues("startport", ImmutableSet.of(startPort + ""));
return this;
}
/**
* @param endPort
* the ending port of firewall rule
*/
public CreateFirewallRuleOptions endPort(int endPort) {
this.queryParameters.replaceValues("endport", ImmutableSet.of(endPort + ""));
return this;
}
/**
* @param icmpCode
* error code for this icmp message
*/
public CreateFirewallRuleOptions icmpCode(String icmpCode) {
this.queryParameters.replaceValues("icmpcode", ImmutableSet.of(icmpCode));
return this;
}
/**
* @param icmpType
* type of the icmp message being sent
*/
public CreateFirewallRuleOptions icmpType(String icmpType) {
this.queryParameters.replaceValues("icmptype", ImmutableSet.of(icmpType));
return this;
}
public static class Builder {
/**
* @see CreateFirewallRuleOptions#CIDRs
*/
public static CreateFirewallRuleOptions CIDRs(Set<String> CIDRs) {
CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
return options.CIDRs(CIDRs);
}
/**
* @see CreateFirewallRuleOptions#startPort
*/
public static CreateFirewallRuleOptions startPort(int startPort) {
CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
return options.startPort(startPort);
}
/**
* @see CreateFirewallRuleOptions#endPort
*/
public static CreateFirewallRuleOptions endPort(int endPort) {
CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
return options.endPort(endPort);
}
/**
* @see CreateFirewallRuleOptions#icmpCode
*/
public static CreateFirewallRuleOptions icmpCode(String icmpCode) {
CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
return options.icmpCode(icmpCode);
}
/**
* @see CreateFirewallRuleOptions#icmpType
*/
public static CreateFirewallRuleOptions icmpType(String icmpType) {
CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
return options.icmpType(icmpType);
}
}
}

View File

@ -0,0 +1,147 @@
/**
* 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.cloudstack.options;
import com.google.common.collect.ImmutableSet;
/**
* Options used to control what firewall rules are returned
*
* @see <a href=
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listFirewallRules.html"
* />
* @author Andrei Savu
*/
public class ListFirewallRulesOptions extends AccountInDomainOptions {
public static final ListFirewallRulesOptions NONE = new ListFirewallRulesOptions();
/**
* @param id
* firewall rule ID
*/
public ListFirewallRulesOptions id(long id) {
this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
return this;
}
/**
* @param ipAddressId
* the id of IP address of the firwall services
*/
public ListFirewallRulesOptions ipAddressId(long ipAddressId) {
this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(ipAddressId + ""));
return this;
}
/**
* @param keyword
* list by keyword
*/
public ListFirewallRulesOptions keyword(String keyword) {
this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
return this;
}
public ListFirewallRulesOptions page(long page) {
this.queryParameters.replaceValues("page", ImmutableSet.of(page + ""));
return this;
}
public ListFirewallRulesOptions pageSize(long pageSize) {
this.queryParameters.replaceValues("pagesize", ImmutableSet.of(pageSize + ""));
return this;
}
public static class Builder {
/**
* @see ListFirewallRulesOptions#id
*/
public static ListFirewallRulesOptions id(long id) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.id(id);
}
/**
* @see ListFirewallRulesOptions#ipAddressId
*/
public static ListFirewallRulesOptions ipAddressId(long ipAddressId) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.ipAddressId(ipAddressId);
}
/**
* @see ListFirewallRulesOptions#keyword
*/
public static ListFirewallRulesOptions keyword(String keyword) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.keyword(keyword);
}
/**
* @see ListFirewallRulesOptions#page
*/
public static ListFirewallRulesOptions page(long page) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.page(page);
}
/**
* @see ListFirewallRulesOptions#pageSize
*/
public static ListFirewallRulesOptions pageSize(long pageSize) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.pageSize(pageSize);
}
/**
* @see ListFirewallRulesOptions#accountInDomain
*/
public static ListFirewallRulesOptions accountInDomain(String account, long domain) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.accountInDomain(account, domain);
}
/**
* @see ListFirewallRulesOptions#domainId
*/
public static ListFirewallRulesOptions domainId(long id) {
ListFirewallRulesOptions options = new ListFirewallRulesOptions();
return options.domainId(id);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListFirewallRulesOptions accountInDomain(String account, long domain) {
return ListFirewallRulesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListFirewallRulesOptions domainId(long domainId) {
return ListFirewallRulesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -23,26 +23,52 @@ import com.google.common.collect.ImmutableSet;
/** /**
* Options used to control what port forwarding rules are returned * Options used to control what port forwarding rules are returned
* *
* @see <a href=
* "http://download.cloud.com/releases/2.2.0/api/user/listIpForwardingRules.html"
* />
* @author Adrian Cole * @author Adrian Cole
* @see <a href=
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listPortForwardingRules.html"
* />
*/ */
public class ListPortForwardingRulesOptions extends AccountInDomainOptions { public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions(); public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions();
/**
* @param id
* lists rule with the specified ID
*/
public ListPortForwardingRulesOptions id(long id) {
this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
return this;
}
/** /**
* @param IPAddressId * @param IPAddressId
* list the rule belonging to this public ip address * list the rule belonging to this public ip address
*/ */
public ListPortForwardingRulesOptions IPAddressId(long IPAddressId) { public ListPortForwardingRulesOptions ipAddressId(long IPAddressId) {
this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(IPAddressId + "")); this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(IPAddressId + ""));
return this; return this;
} }
public static class Builder { public static class Builder {
/**
* @see ListPortForwardingRulesOptions#id
*/
public static ListPortForwardingRulesOptions id(long id) {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.id(id);
}
/**
* @see ListPortForwardingRulesOptions#ipAddressId
*/
public static ListPortForwardingRulesOptions ipAddressId(long ipAddressId) {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.ipAddressId(ipAddressId);
}
/** /**
* @see ListPortForwardingRulesOptions#accountInDomain * @see ListPortForwardingRulesOptions#accountInDomain
*/ */
@ -51,14 +77,6 @@ public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
return options.accountInDomain(account, domain); return options.accountInDomain(account, domain);
} }
/**
* @see ListPortForwardingRulesOptions#IPAddressId
*/
public static ListPortForwardingRulesOptions IPAddressId(long IPAddressId) {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.IPAddressId(IPAddressId);
}
/** /**
* @see ListPortForwardingRulesOptions#domainId * @see ListPortForwardingRulesOptions#domainId
*/ */
@ -66,7 +84,6 @@ public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions(); ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.domainId(id); return options.domainId(id);
} }
} }
/** /**

View File

@ -21,6 +21,7 @@ package org.jclouds.cloudstack.features;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions; import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed; import org.jclouds.http.functions.ParseFirstJsonValueNamed;
@ -64,7 +65,7 @@ public class FirewallAsyncClientTest extends BaseCloudStackAsyncClientTest<Firew
public void testListPortForwardingRulesOptions() throws SecurityException, NoSuchMethodException, IOException { public void testListPortForwardingRulesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = FirewallAsyncClient.class.getMethod("listPortForwardingRules", Method method = FirewallAsyncClient.class.getMethod("listPortForwardingRules",
ListPortForwardingRulesOptions[].class); ListPortForwardingRulesOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.IPAddressId(3)); HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.ipAddressId(3));
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listPortForwardingRules&ipaddressid=3 HTTP/1.1"); "GET http://localhost:8080/client/api?response=json&command=listPortForwardingRules&ipaddressid=3 HTTP/1.1");
@ -82,12 +83,12 @@ public class FirewallAsyncClientTest extends BaseCloudStackAsyncClientTest<Firew
public void testCreatePortForwardingRuleForVirtualMachine() throws SecurityException, NoSuchMethodException, public void testCreatePortForwardingRuleForVirtualMachine() throws SecurityException, NoSuchMethodException,
IOException { IOException {
Method method = FirewallAsyncClient.class.getMethod("createPortForwardingRuleForVirtualMachine", long.class, Method method = FirewallAsyncClient.class.getMethod("createPortForwardingRuleForVirtualMachine", long.class,
long.class, String.class, int.class, int.class); PortForwardingRule.Protocol.class, int.class, long.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, 6, 7, "tcp", 22, 22); HttpRequest httpRequest = processor.createRequest(method, 6L, PortForwardingRule.Protocol.TCP, 22, 7L, 22);
assertRequestLineEquals( assertRequestLineEquals(
httpRequest, httpRequest,
"GET http://localhost:8080/client/api?response=json&command=createPortForwardingRule&virtualmachineid=6&protocol=tcp&ipaddressid=7&privateport=22&publicport=22 HTTP/1.1"); "GET http://localhost:8080/client/api?response=json&command=createPortForwardingRule&ipaddressid=6&publicport=22&protocol=tcp&virtualmachineid=7&privateport=22 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);

View File

@ -0,0 +1,323 @@
/**
* 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.cloudstack.features;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import java.net.URI;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
/**
* Test the CloudStack FirewallClient
*
* @author Andrei Savu
*/
@Test(groups = "unit", testName = "FirewallClientExpectTest")
public class FirewallClientExpectTest extends BaseCloudStackRestClientExpectTest {
public void testListFirewallRulesWhenResponseIs2xx() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
"apiKey=identity&signature=MktZKKH3USVKiC9SlYTSHMCaCcg%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/listfirewallrulesresponse.json"))
.build())
.getFirewallClient();
Set<String> CIDRs = ImmutableSet.of("0.0.0.0/0");
assertEquals(client.listFirewallRules(),
ImmutableSet.of(
FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
.endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
.CIDRs(CIDRs).build(),
FirewallRule.builder().id(2016).protocol(FirewallRule.Protocol.TCP).startPort(22)
.endPort(22).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
.CIDRs(CIDRs).build(),
FirewallRule.builder().id(10).protocol(FirewallRule.Protocol.TCP).startPort(22)
.endPort(22).ipAddressId(8).ipAddress("10.27.27.57").state(FirewallRule.State.ACTIVE)
.CIDRs(CIDRs).build()
));
}
public void testListFirewallRulesWhenReponseIs404() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
"apiKey=identity&signature=MktZKKH3USVKiC9SlYTSHMCaCcg%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(404)
.build())
.getFirewallClient();
assertEquals(client.listFirewallRules(), ImmutableSet.of());
}
public void testGetFirewallRuleWhenResponseIs2xx() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
"id=2017&apiKey=identity&signature=0r5iL%2Bzix9rmD07lJIOhY68mYY0%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/getfirewallrulesresponse.json"))
.build())
.getFirewallClient();
assertEquals(client.getFirewallRule(2017),
FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
.endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
.CIDRs(ImmutableSet.of("0.0.0.0/0")).build()
);
}
public void testGetFirewallRuleWhenResponseIs404() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
"id=4&apiKey=identity&signature=PPX5U9kmaS116SgG4Ihf8xK%2BcSE%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(404)
.build())
.getFirewallClient();
assertNull(client.getFirewallRule(4));
}
public void testCreateFirewallRuleForIpAndProtocol() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=createFirewallRule&" +
"ipaddressid=2&protocol=TCP&apiKey=identity&signature=d0MZ%2FyhQPAaV%2BYQmfZsQtQL2C28%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/createfirewallrulesresponse.json"))
.build())
.getFirewallClient();
AsyncCreateResponse response = client.createFirewallRuleForIpAndProtocol(2, FirewallRule.Protocol.TCP);
assertEquals(response.getJobId(), 2036);
assertEquals(response.getId(), 2017);
}
public void testDeleteFirewallRule() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=deleteFirewallRule&id=2015&apiKey=identity&signature=%2FT5FAO2yGPctaPmg7TEtIEFW3EU%3D"))
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/deletefirewallrulesresponse.json"))
.build())
.getFirewallClient();
client.deleteFirewallRule(2015);
}
public void testListPortForwardingRulesWhenResponseIs2xx() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listPortForwardingRules&apiKey=identity&signature=YFBu1VOSkiDKxm0K42sIXJWy%2BBo%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/listportforwardingrulesresponse.json"))
.build())
.getFirewallClient();
Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
assertEquals(client.listPortForwardingRules(),
ImmutableSet.<PortForwardingRule>of(
PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
.IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build(),
PortForwardingRule.builder().id(18).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.publicPort(22).virtualMachineId(89).virtualMachineName("i-3-89-VM").IPAddressId(34)
.IPAddress("72.52.126.63").state(PortForwardingRule.State.ACTIVE).build())
);
}
public void testListPortForwardingRulesWhenReponseIs404() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listPortForwardingRules&apiKey=identity&signature=YFBu1VOSkiDKxm0K42sIXJWy%2BBo%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(404)
.build())
.getFirewallClient();
assertEquals(client.listPortForwardingRules(), ImmutableSet.of());
}
public void testGetPortForwardingRuleWhenResponseIs2xx() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listPortForwardingRules&id=15&apiKey=identity&signature=ABJsciF4n2tXaiyUmEvc3oYh9MA%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/getportforwardingrulesresponse.json"))
.build())
.getFirewallClient();
Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
assertEquals(client.getPortForwardingRule(15),
PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
.IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build());
}
public void testGetPortForwardingRuleWhenResponseIs404() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listPortForwardingRules&id=4&apiKey=identity&signature=CTOmmIOGIiZx0YATqh%2FFk0zIplw%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(404)
.build())
.getFirewallClient();
assertNull(client.getPortForwardingRule(4));
}
public void testCreatePortForwardingRuleForVirtualMachine() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=createPortForwardingRule&" +
"ipaddressid=2&publicport=22&protocol=tcp&virtualmachineid=1234&privateport=22&" +
"apiKey=identity&signature=84dtGzQp0G6k3z3Gkc3F%2FHBNS2Y%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/createportforwardingrulesresponse.json"))
.build())
.getFirewallClient();
AsyncCreateResponse response = client.createPortForwardingRuleForVirtualMachine(
2, PortForwardingRule.Protocol.TCP, 22, 1234, 22);
assertEquals(response.getJobId(), 2035);
assertEquals(response.getId(), 2015);
}
public void testDeletePortForwardingRule() {
FirewallClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=deletePortForwardingRule&id=2015&apiKey=identity&signature=2UE7KB3wm5ocmR%2BGMNFKPKfiDo8%3D"))
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/deleteportforwardingrulesresponse.json"))
.build())
.getFirewallClient();
client.deletePortForwardingRule(2015);
}
}

View File

@ -19,18 +19,22 @@
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Iterables.find;
import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsPortForwarding;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import com.google.common.base.Predicates;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.predicates.NetworkPredicates; import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
@ -38,6 +42,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import javax.annotation.Nullable;
/** /**
* Tests behavior of {@code FirewallClientLiveTest} * Tests behavior of {@code FirewallClientLiveTest}
* *
@ -47,7 +53,10 @@ import com.google.common.base.Predicate;
public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest { public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null; private PublicIPAddress ip = null;
private VirtualMachine vm; private VirtualMachine vm;
private PortForwardingRule rule;
private FirewallRule firewallRule;
private PortForwardingRule portForwardingRule;
private Network network; private Network network;
private boolean networksDisabled; private boolean networksDisabled;
@ -56,13 +65,25 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
super.setupClient(); super.setupClient();
prefix += "rule"; prefix += "rule";
try { try {
network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.supportsPortForwarding()); network = find(client.getNetworkClient().listNetworks(), Predicates.and(supportsPortForwarding(),
new Predicate<Network>() {
@Override
public boolean apply(@Nullable Network network) {
return network.isDefault()
&& !network.isSecurityGroupEnabled()
&& network.getAccount().equals(user.getAccount());
}
}));
Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null; Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network,
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete, defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
virtualMachineRunning); client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption()) if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
networksDisabled = true; networksDisabled = true;
} }
@ -71,30 +92,75 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
public void testCreatePortForwardingRule() throws Exception { public void testCreatePortForwardingRule() throws Exception {
if (networksDisabled) if (networksDisabled)
return; return;
while (rule == null) { while (portForwardingRule == null) {
ip = reuseOrAssociate.apply(network); ip = reuseOrAssociate.apply(network);
try { try {
AsyncCreateResponse job = client.getFirewallClient().createPortForwardingRuleForVirtualMachine(vm.getId(), AsyncCreateResponse job = client.getFirewallClient()
ip.getId(), "tcp", 22, 22); .createPortForwardingRuleForVirtualMachine(ip.getId(), PortForwardingRule.Protocol.TCP, 22, vm.getId(), 22);
assertTrue(jobComplete.apply(job.getJobId())); assertTrue(jobComplete.apply(job.getJobId()));
rule = findRuleWithId(job.getId()); portForwardingRule = client.getFirewallClient().getPortForwardingRule(job.getId());
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
Logger.CONSOLE.error("Failed while trying to allocate ip: " + e);
// very likely an ip conflict, so retry; // very likely an ip conflict, so retry;
} }
} }
assertEquals(rule.getIPAddressId(), ip.getId()); assertEquals(portForwardingRule.getIPAddressId(), ip.getId());
assertEquals(rule.getVirtualMachineId(), vm.getId()); assertEquals(portForwardingRule.getVirtualMachineId(), vm.getId());
assertEquals(rule.getPublicPort(), 22); assertEquals(portForwardingRule.getPublicPort(), 22);
assertEquals(rule.getProtocol(), "tcp"); assertEquals(portForwardingRule.getProtocol(), "tcp");
checkRule(rule);
checkPortForwardingRule(portForwardingRule);
checkSSH(new IPSocket(ip.getIPAddress(), 22)); checkSSH(new IPSocket(ip.getIPAddress(), 22));
} }
@Test(dependsOnMethods = "testCreatePortForwardingRule")
public void testListPortForwardingRules() throws Exception {
Set<PortForwardingRule> response = client.getFirewallClient().listPortForwardingRules();
assert null != response;
assertTrue(response.size() >= 0);
for (final PortForwardingRule rule : response) {
checkPortForwardingRule(rule);
}
}
@Test(dependsOnMethods = "testCreatePortForwardingRule")
public void testCreateFirewallRule() {
if (networksDisabled)
return;
AsyncCreateResponse job = client.getFirewallClient().createFirewallRuleForIpAndProtocol(
ip.getId(), FirewallRule.Protocol.TCP, CreateFirewallRuleOptions.Builder.startPort(30).endPort(35));
assertTrue(jobComplete.apply(job.getJobId()));
firewallRule = client.getFirewallClient().getFirewallRule(job.getId());
assertEquals(firewallRule.getStartPort(), 30);
assertEquals(firewallRule.getEndPort(), 35);
assertEquals(firewallRule.getProtocol(), FirewallRule.Protocol.TCP);
checkFirewallRule(firewallRule);
}
@Test(dependsOnMethods = "testCreateFirewallRule")
public void testListFirewallRules() {
Set<FirewallRule> rules = client.getFirewallClient().listFirewallRules();
assert rules != null;
assertTrue(rules.size() > 0);
for(FirewallRule rule : rules) {
checkFirewallRule(rule);
}
}
@AfterGroups(groups = "live") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {
if (rule != null) { if (firewallRule != null) {
client.getFirewallClient().deletePortForwardingRule(rule.getId()); client.getFirewallClient().deleteFirewallRule(firewallRule.getId());
}
if (portForwardingRule != null) {
client.getFirewallClient().deletePortForwardingRule(portForwardingRule.getId());
} }
if (vm != null) { if (vm != null) {
jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId())); jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
@ -105,30 +171,18 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
super.tearDown(); super.tearDown();
} }
public void testListPortForwardingRules() throws Exception { protected void checkFirewallRule(FirewallRule rule) {
Set<PortForwardingRule> response = client.getFirewallClient().listPortForwardingRules(); assertEquals(rule,
assert null != response; client.getFirewallClient().getFirewallRule(rule.getId()));
assertTrue(response.size() >= 0); assert rule.getId() > 0 : rule;
for (final PortForwardingRule rule : response) { assert rule.getStartPort() > 0 : rule;
PortForwardingRule newDetails = findRuleWithId(rule.getId()); assert rule.getEndPort() >= rule.getStartPort() : rule;
assertEquals(rule.getId(), newDetails.getId()); assert rule.getProtocol() != null;
checkRule(rule);
}
} }
private PortForwardingRule findRuleWithId(final long id) { protected void checkPortForwardingRule(PortForwardingRule rule) {
return find(client.getFirewallClient().listPortForwardingRules(), new Predicate<PortForwardingRule>() { assertEquals(rule,
client.getFirewallClient().getPortForwardingRule(rule.getId()));
@Override
public boolean apply(PortForwardingRule arg0) {
return arg0.getId() == id;
}
});
}
protected void checkRule(PortForwardingRule rule) {
assertEquals(rule.getId(), findRuleWithId(rule.getId()).getId());
assert rule.getId() > 0 : rule; assert rule.getId() > 0 : rule;
assert rule.getIPAddress() != null : rule; assert rule.getIPAddress() != null : rule;
assert rule.getIPAddressId() > 0 : rule; assert rule.getIPAddressId() > 0 : rule;

View File

@ -18,9 +18,9 @@
*/ */
package org.jclouds.cloudstack.options; package org.jclouds.cloudstack.options;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.IPAddressId;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.accountInDomain; import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.accountInDomain;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.domainId; import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.domainId;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.ipAddressId;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -48,12 +48,12 @@ public class ListPortForwardingRulesOptionsTest {
} }
public void testName() { public void testName() {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().IPAddressId(9); ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid")); assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
} }
public void testNameStatic() { public void testNameStatic() {
ListPortForwardingRulesOptions options = IPAddressId(9); ListPortForwardingRulesOptions options = ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid")); assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
} }

View File

@ -0,0 +1,72 @@
/**
* 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.cloudstack.parse;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import java.util.Set;
/**
*
* @author Andrei Savu
*/
@Test(groups = "unit")
public class ListFirewallRulesResponseTest extends BaseSetParserTest<FirewallRule> {
@Override
protected Injector injector() {
return Guice.createInjector(new CloudStackParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
@Override
public String resource() {
return "/listfirewallrulesresponse.json";
}
@Override
@SelectJson("firewallrule")
public Set<FirewallRule> expected() {
Set<String> CIDRs = ImmutableSet.of("0.0.0.0/0");
return ImmutableSet.of(
FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
.endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build(),
FirewallRule.builder().id(2016).protocol(FirewallRule.Protocol.TCP).startPort(22)
.endPort(22).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build(),
FirewallRule.builder().id(10).protocol(FirewallRule.Protocol.TCP).startPort(22)
.endPort(22).ipAddressId(8).ipAddress("10.27.27.57").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build()
);
}
}

View File

@ -61,10 +61,12 @@ public class ListPortForwardingRulesResponseTest extends BaseSetParserTest<PortF
public Set<PortForwardingRule> expected() { public Set<PortForwardingRule> expected() {
Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1"); Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
return ImmutableSet.<PortForwardingRule> of( return ImmutableSet.<PortForwardingRule> of(
PortForwardingRule.builder().id(15).privatePort(22).protocol("tcp").publicPort(2022).virtualMachineId(3) PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.virtualMachineName("i-3-3-VM").IPAddressId(3).IPAddress("72.52.126.32").state("Active").CIDRs(cidrs).build(), .publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
PortForwardingRule.builder().id(18).privatePort(22).protocol("tcp").publicPort(22).virtualMachineId(89) .IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build(),
.virtualMachineName("i-3-89-VM").IPAddressId(34).IPAddress("72.52.126.63").state("Active").build()); PortForwardingRule.builder().id(18).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.publicPort(22).virtualMachineId(89).virtualMachineName("i-3-89-VM").IPAddressId(34)
.IPAddress("72.52.126.63").state(PortForwardingRule.State.ACTIVE).build());
} }
} }

View File

@ -0,0 +1 @@
{ "createfirewallruleresponse" : {"jobid":2036,"id":2017} }

View File

@ -0,0 +1 @@
{ "createportforwardingruleresponse" : {"jobid":2035,"id":2015} }

View File

@ -0,0 +1 @@
{ "deletefirewallruleresponse" : {"jobid":2037} }

View File

@ -0,0 +1 @@
{ "deleteportforwardingruleresponse" : {"jobid":2038} }

View File

@ -0,0 +1,2 @@
{ "listfirewallrulesresponse" : { "count":1 ,"firewallrule" : [
{"id":2017,"protocol":"tcp","startport":"30","endport":"35","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"} ] } }

View File

@ -0,0 +1,2 @@
{ "listportforwardingrulesresponse" : { "portforwardingrule" : [
{"id":15,"privateport":"22","protocol":"tcp","publicport":"2022","virtualmachineid":3,"virtualmachinename":"i-3-3-VM","ipaddressid":3,"ipaddress":"72.52.126.32","state":"Active","cidrlist":"0.0.0.0/1,128.0.0.0/1"} ] } }

View File

@ -0,0 +1,4 @@
{ "listfirewallrulesresponse" : { "count":3 ,"firewallrule" : [
{"id":2017,"protocol":"tcp","startport":"30","endport":"35","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"},
{"id":2016,"protocol":"tcp","startport":"22","endport":"22","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"},
{"id":10,"protocol":"tcp","startport":"22","endport":"22","ipaddressid":8,"ipaddress":"10.27.27.57","state":"Active","cidrlist":"0.0.0.0/0"} ] } }