Update the Logical Router NatRules to be compatible with the NVP 3.x.x

platform

Use the Gson adapters to serialize/deserialize the NatRules

Switch the NiciraNvpApi to a single gson Object with the proper adapters

Fix missing order setting for static nat rules and portforwarding rules

Return an error when a port range is passed in a portforwarding rule

The serializer is not required

Fix a bug where an ip address could be released even if it was still in
use for SourceNat

Throw a json parse exception when the type is unknown to the adapter
This commit is contained in:
Hugo Trippaers 2013-05-17 13:02:33 +02:00
parent 83f84adda2
commit 4e09079640
9 changed files with 493 additions and 500 deletions

View File

@ -0,0 +1,89 @@
package com.cloud.network.nicira;
public class DestinationNatRule extends NatRule {
private String toDestinationIpAddress;
private Integer toDestinationPort;
public DestinationNatRule() {
setType("DestinationNatRule");
}
public String getToDestinationIpAddress() {
return toDestinationIpAddress;
}
public void setToDestinationIpAddress(String toDestinationIpAddress) {
this.toDestinationIpAddress = toDestinationIpAddress;
}
public Integer getToDestinationPort() {
return toDestinationPort;
}
public void setToDestinationPort(Integer toDestinationPort) {
this.toDestinationPort = toDestinationPort;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime
* result
+ ((toDestinationIpAddress == null) ? 0
: toDestinationIpAddress.hashCode());
result = prime
* result
+ ((toDestinationPort == null) ? 0 : toDestinationPort
.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
DestinationNatRule other = (DestinationNatRule) obj;
if (toDestinationIpAddress == null) {
if (other.toDestinationIpAddress != null)
return false;
} else if (!toDestinationIpAddress.equals(other.toDestinationIpAddress))
return false;
if (toDestinationPort == null) {
if (other.toDestinationPort != null)
return false;
} else if (!toDestinationPort.equals(other.toDestinationPort))
return false;
return true;
}
@Override
public boolean equalsIgnoreUuid(Object obj) {
if (this == obj)
return true;
if (!super.equalsIgnoreUuid(obj))
return false;
if (getClass() != obj.getClass())
return false;
DestinationNatRule other = (DestinationNatRule) obj;
if (toDestinationIpAddress == null) {
if (other.toDestinationIpAddress != null)
return false;
} else if (!toDestinationIpAddress.equals(other.toDestinationIpAddress))
return false;
if (toDestinationPort == null) {
if (other.toDestinationPort != null)
return false;
} else if (!toDestinationPort.equals(other.toDestinationPort))
return false;
return true;
}
}

View File

@ -22,15 +22,9 @@ package com.cloud.network.nicira;
public class Match {
private Integer protocol;
private String source_ip_addresses;
private Boolean source_ip_addresses_not;
private String destination_ip_addresses;
private Boolean destination_ip_addresses_not;
private Integer source_port_min;
private Integer source_port_max;
private Boolean source_port_not;
private Integer destination_port_min;
private Integer destination_port_max;
private Boolean destination_port_not;
private Integer source_port;
private Integer destination_port;
private String ethertype = "IPv4";
public Integer getProtocol() {
@ -41,54 +35,22 @@ public class Match {
this.protocol = protocol;
}
public Integer getSourcePortMin() {
return source_port_min;
public Integer getSourcePort() {
return source_port;
}
public void setSourcePortMin(Integer source_port_min) {
this.source_port_min = source_port_min;
public void setSourcePort(Integer source_port) {
this.source_port = source_port;
}
public Integer getDestinationPort() {
return destination_port;
}
public Integer getSourcePortMax() {
return source_port_max;
public void setDestinationPort(Integer destination_port) {
this.destination_port = destination_port;
}
public void setSourcePortMax(Integer source_port_max) {
this.source_port_max = source_port_max;
}
public Boolean isSourcePortNot() {
return source_port_not;
}
public void setSourcePortNot(Boolean source_port_not) {
this.source_port_not = source_port_not;
}
public Integer getDestinationPortMin() {
return destination_port_min;
}
public void setDestinationPortMin(Integer destination_port_min) {
this.destination_port_min = destination_port_min;
}
public Integer getDestinationPortMax() {
return destination_port_max;
}
public void setDestinationPortMax(Integer destination_port_max) {
this.destination_port_max = destination_port_max;
}
public Boolean isDestinationPortNot() {
return destination_port_not;
}
public void setDestinationPortNot(Boolean destination_port_not) {
this.destination_port_not = destination_port_not;
}
public String getEthertype() {
return ethertype;
}
@ -105,14 +67,6 @@ public class Match {
this.source_ip_addresses = source_ip_addresses;
}
public boolean isSourceIpAddressesNot() {
return source_ip_addresses_not;
}
public void setSourceIpAddresses_not(boolean source_ip_addresses_not) {
this.source_ip_addresses_not = source_ip_addresses_not;
}
public String getDestinationIpAddresses() {
return destination_ip_addresses;
}
@ -121,14 +75,6 @@ public class Match {
this.destination_ip_addresses = destination_ip_addresses;
}
public Boolean isDestinationIpAddressesNot() {
return destination_ip_addresses_not;
}
public void setDestinationIpAddressesNot(Boolean destination_ip_addresses_not) {
this.destination_ip_addresses_not = destination_ip_addresses_not;
}
@Override
public int hashCode() {
final int prime = 31;
@ -139,19 +85,7 @@ public class Match {
: destination_ip_addresses.hashCode());
result = prime
* result
+ ((destination_ip_addresses_not == null) ? 0
: destination_ip_addresses_not.hashCode());
result = prime
* result
+ ((destination_port_max == null) ? 0 : destination_port_max
.hashCode());
result = prime
* result
+ ((destination_port_min == null) ? 0 : destination_port_min
.hashCode());
result = prime
* result
+ ((destination_port_not == null) ? 0 : destination_port_not
+ ((destination_port == null) ? 0 : destination_port
.hashCode());
result = prime * result
+ ((ethertype == null) ? 0 : ethertype.hashCode());
@ -161,16 +95,8 @@ public class Match {
* result
+ ((source_ip_addresses == null) ? 0 : source_ip_addresses
.hashCode());
result = prime
* result
+ ((source_ip_addresses_not == null) ? 0
: source_ip_addresses_not.hashCode());
result = prime * result
+ ((source_port_max == null) ? 0 : source_port_max.hashCode());
result = prime * result
+ ((source_port_min == null) ? 0 : source_port_min.hashCode());
result = prime * result
+ ((source_port_not == null) ? 0 : source_port_not.hashCode());
+ ((source_port == null) ? 0 : source_port.hashCode());
return result;
}
@ -189,26 +115,10 @@ public class Match {
} else if (!destination_ip_addresses
.equals(other.destination_ip_addresses))
return false;
if (destination_ip_addresses_not == null) {
if (other.destination_ip_addresses_not != null)
if (destination_port == null) {
if (other.destination_port != null)
return false;
} else if (!destination_ip_addresses_not
.equals(other.destination_ip_addresses_not))
return false;
if (destination_port_max == null) {
if (other.destination_port_max != null)
return false;
} else if (!destination_port_max.equals(other.destination_port_max))
return false;
if (destination_port_min == null) {
if (other.destination_port_min != null)
return false;
} else if (!destination_port_min.equals(other.destination_port_min))
return false;
if (destination_port_not == null) {
if (other.destination_port_not != null)
return false;
} else if (!destination_port_not.equals(other.destination_port_not))
} else if (!destination_port.equals(other.destination_port))
return false;
if (ethertype == null) {
if (other.ethertype != null)
@ -225,26 +135,10 @@ public class Match {
return false;
} else if (!source_ip_addresses.equals(other.source_ip_addresses))
return false;
if (source_ip_addresses_not == null) {
if (other.source_ip_addresses_not != null)
if (source_port == null) {
if (other.source_port != null)
return false;
} else if (!source_ip_addresses_not
.equals(other.source_ip_addresses_not))
return false;
if (source_port_max == null) {
if (other.source_port_max != null)
return false;
} else if (!source_port_max.equals(other.source_port_max))
return false;
if (source_port_min == null) {
if (other.source_port_min != null)
return false;
} else if (!source_port_min.equals(other.source_port_min))
return false;
if (source_port_not == null) {
if (other.source_port_not != null)
return false;
} else if (!source_port_not.equals(other.source_port_not))
} else if (!source_port.equals(other.source_port))
return false;
return true;
}

View File

@ -16,267 +16,114 @@
// under the License.
package com.cloud.network.nicira;
import java.util.UUID;
/**
*
*/
public class NatRule {
protected Match match;
protected String to_source_ip_address_min;
protected String to_source_ip_address_max;
protected Integer to_source_port_min;
protected Integer to_source_port_max;
protected String uuid;
protected String type;
protected String to_destination_ip_address_min;
protected String to_destination_ip_address_max;
protected Integer to_destination_port;
public NatRule() {}
public Match getMatch() {
return match;
}
public void setMatch(Match match) {
this.match = match;
}
public String getToSourceIpAddressMin() {
return to_source_ip_address_min;
}
public void setToSourceIpAddressMin(String to_source_ip_address_min) {
this.to_source_ip_address_min = to_source_ip_address_min;
}
public String getToSourceIpAddressMax() {
return to_source_ip_address_max;
}
public void setToSourceIpAddressMax(String to_source_ip_address_max) {
this.to_source_ip_address_max = to_source_ip_address_max;
}
public Integer getToSourcePortMin() {
return to_source_port_min;
}
public void setToSourcePortMin(Integer to_source_port_min) {
this.to_source_port_min = to_source_port_min;
}
public Integer getToSourcePortMax() {
return to_source_port_max;
}
public void setToSourcePortMax(Integer to_source_port_max) {
this.to_source_port_max = to_source_port_max;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getToDestinationIpAddressMin() {
return to_destination_ip_address_min;
}
public void setToDestinationIpAddressMin(
String to_destination_ip_address_min) {
this.to_destination_ip_address_min = to_destination_ip_address_min;
}
public String getToDestinationIpAddressMax() {
return to_destination_ip_address_max;
}
public void setToDestinationIpAddressMax(
String to_destination_ip_address_max) {
this.to_destination_ip_address_max = to_destination_ip_address_max;
}
public Integer getToDestinationPort() {
return to_destination_port;
}
public void setToDestinationPort(Integer to_destination_port) {
this.to_destination_port = to_destination_port;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public abstract class NatRule {
protected Match match;
protected UUID uuid;
protected String type;
protected int order;
@Override
public int hashCode() {
final int prime = 42;
int result = 1;
result = prime * result + ((match == null) ? 0 : match.hashCode());
result = prime
* result
+ ((to_destination_ip_address_max == null) ? 0
: to_destination_ip_address_max.hashCode());
result = prime
* result
+ ((to_destination_ip_address_min == null) ? 0
: to_destination_ip_address_min.hashCode());
result = prime
* result
+ ((to_destination_port == null) ? 0 : to_destination_port
.hashCode());
result = prime
* result
+ ((to_source_ip_address_max == null) ? 0
: to_source_ip_address_max.hashCode());
result = prime
* result
+ ((to_source_ip_address_min == null) ? 0
: to_source_ip_address_min.hashCode());
result = prime
* result
+ ((to_source_port_max == null) ? 0 : to_source_port_max
.hashCode());
result = prime
* result
+ ((to_source_port_min == null) ? 0 : to_source_port_min
.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
public NatRule() {
}
public Match getMatch() {
return match;
}
public void setMatch(Match match) {
this.match = match;
}
public UUID getUuid() {
return uuid;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((match == null) ? 0 : match.hashCode());
result = prime * result + order;
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NatRule other = (NatRule) obj;
if (match == null) {
if (other.match != null)
return false;
} else if (!match.equals(other.match))
return false;
if (order != other.order)
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
public boolean equalsIgnoreUuid(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NatRule other = (NatRule) obj;
if (match == null) {
if (other.match != null)
return false;
} else if (!match.equals(other.match))
return false;
if (order != other.order)
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NatRule other = (NatRule) obj;
if (match == null) {
if (other.match != null)
return false;
} else if (!match.equals(other.match))
return false;
if (to_destination_ip_address_max == null) {
if (other.to_destination_ip_address_max != null)
return false;
} else if (!to_destination_ip_address_max
.equals(other.to_destination_ip_address_max))
return false;
if (to_destination_ip_address_min == null) {
if (other.to_destination_ip_address_min != null)
return false;
} else if (!to_destination_ip_address_min
.equals(other.to_destination_ip_address_min))
return false;
if (to_destination_port == null) {
if (other.to_destination_port != null)
return false;
} else if (!to_destination_port.equals(other.to_destination_port))
return false;
if (to_source_ip_address_max == null) {
if (other.to_source_ip_address_max != null)
return false;
} else if (!to_source_ip_address_max
.equals(other.to_source_ip_address_max))
return false;
if (to_source_ip_address_min == null) {
if (other.to_source_ip_address_min != null)
return false;
} else if (!to_source_ip_address_min
.equals(other.to_source_ip_address_min))
return false;
if (to_source_port_max == null) {
if (other.to_source_port_max != null)
return false;
} else if (!to_source_port_max.equals(other.to_source_port_max))
return false;
if (to_source_port_min == null) {
if (other.to_source_port_min != null)
return false;
} else if (!to_source_port_min.equals(other.to_source_port_min))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
public boolean equalsIgnoreUuid(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NatRule other = (NatRule) obj;
if (match == null) {
if (other.match != null)
return false;
} else if (!match.equals(other.match))
return false;
if (to_destination_ip_address_max == null) {
if (other.to_destination_ip_address_max != null)
return false;
} else if (!to_destination_ip_address_max
.equals(other.to_destination_ip_address_max))
return false;
if (to_destination_ip_address_min == null) {
if (other.to_destination_ip_address_min != null)
return false;
} else if (!to_destination_ip_address_min
.equals(other.to_destination_ip_address_min))
return false;
if (to_destination_port == null) {
if (other.to_destination_port != null)
return false;
} else if (!to_destination_port.equals(other.to_destination_port))
return false;
if (to_source_ip_address_max == null) {
if (other.to_source_ip_address_max != null)
return false;
} else if (!to_source_ip_address_max
.equals(other.to_source_ip_address_max))
return false;
if (to_source_ip_address_min == null) {
if (other.to_source_ip_address_min != null)
return false;
} else if (!to_source_ip_address_min
.equals(other.to_source_ip_address_min))
return false;
if (to_source_port_max == null) {
if (other.to_source_port_max != null)
return false;
} else if (!to_source_port_max.equals(other.to_source_port_max))
return false;
if (to_source_port_min == null) {
if (other.to_source_port_min != null)
return false;
} else if (!to_source_port_min.equals(other.to_source_port_min))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}

View File

@ -34,6 +34,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
@ -41,7 +43,6 @@ import javax.net.ssl.X509TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
@ -59,7 +60,15 @@ import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.log4j.Logger;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class NiciraNvpApi {
@ -73,6 +82,9 @@ public class NiciraNvpApi {
private String _adminpass;
private HttpClient _client;
private String _nvpversion;
private Gson _gson;
/* This factory method is protected so we can extend this
* in the unittests.
@ -118,6 +130,11 @@ public class NiciraNvpApi {
s_logger.warn("Failed to register the TrustingProtocolSocketFactory, falling back to default SSLSocketFactory", e);
}
_gson = new GsonBuilder()
.registerTypeAdapter(NatRule.class, new NatRuleAdapter())
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
}
public void setControllerAddress(String address) {
@ -170,6 +187,12 @@ public class NiciraNvpApi {
throw new NiciraNvpApiException("Nicira NVP API login failed " + pm.getStatusText());
}
// Extract the version for later use
if (pm.getResponseHeader("Server") != null) {
_nvpversion = pm.getResponseHeader("Server").getValue();
s_logger.debug("NVP Controller reports version " + _nvpversion);
}
// Success; the cookie required for login is kept in _client
}
@ -290,8 +313,8 @@ public class NiciraNvpApi {
executeUpdateObject(natRule, uri, Collections.<String,String>emptyMap());
}
public void deleteLogicalRouterNatRule(String logicalRouterUuid, String natRuleUuid) throws NiciraNvpApiException {
String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRuleUuid;
public void deleteLogicalRouterNatRule(String logicalRouterUuid, UUID natRuleUuid) throws NiciraNvpApiException {
String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRuleUuid.toString();
executeDeleteObject(uri);
}
@ -342,13 +365,11 @@ public class NiciraNvpApi {
throw new NiciraNvpApiException("Hostname/credentials are null or empty");
}
Gson gson = new Gson();
PutMethod pm = (PutMethod) createMethod("put", uri);
pm.setRequestHeader("Content-Type", "application/json");
try {
pm.setRequestEntity(new StringRequestEntity(
gson.toJson(newObject),"application/json", null));
_gson.toJson(newObject),"application/json", null));
} catch (UnsupportedEncodingException e) {
throw new NiciraNvpApiException("Failed to encode json request body", e);
}
@ -371,13 +392,11 @@ public class NiciraNvpApi {
throw new NiciraNvpApiException("Hostname/credentials are null or empty");
}
Gson gson = new Gson();
PostMethod pm = (PostMethod) createMethod("post", uri);
pm.setRequestHeader("Content-Type", "application/json");
try {
pm.setRequestEntity(new StringRequestEntity(
gson.toJson(newObject),"application/json", null));
_gson.toJson(newObject),"application/json", null));
} catch (UnsupportedEncodingException e) {
throw new NiciraNvpApiException("Failed to encode json request body", e);
}
@ -393,7 +412,7 @@ public class NiciraNvpApi {
T result;
try {
result = (T)gson.fromJson(pm.getResponseBodyAsString(), TypeToken.get(newObject.getClass()).getType());
result = (T)_gson.fromJson(pm.getResponseBodyAsString(), TypeToken.get(newObject.getClass()).getType());
} catch (IOException e) {
throw new NiciraNvpApiException("Failed to decode json response body", e);
} finally {
@ -450,10 +469,9 @@ public class NiciraNvpApi {
throw new NiciraNvpApiException("Failed to retrieve object : " + errorMessage);
}
Gson gson = new Gson();
T returnValue;
try {
returnValue = (T)gson.fromJson(gm.getResponseBodyAsString(), returnObjectType);
returnValue = (T)_gson.fromJson(gm.getResponseBodyAsString(), returnObjectType);
} catch (IOException e) {
s_logger.error("IOException while retrieving response body",e);
throw new NiciraNvpApiException(e);
@ -577,5 +595,28 @@ public class NiciraNvpApi {
}
public static class NatRuleAdapter implements JsonDeserializer<NatRule> {
@Override
public NatRule deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();
NatRule natRule = null;
if (!jsonObject.has("type")) {
throw new JsonParseException("Deserializing as a NatRule, but no type present in the json object");
}
String natRuleType = jsonObject.get("type").getAsString();
if ("SourceNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, SourceNatRule.class);
}
else if ("DestinationNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, DestinationNatRule.class);
}
throw new JsonParseException("Failed to deserialize type \"" + natRuleType + "\"");
}
}
}

View File

@ -0,0 +1,107 @@
package com.cloud.network.nicira;
public class SourceNatRule extends NatRule {
private String toSourceIpAddressMax;
private String toSourceIpAddressMin;
private Integer toSourcePort;
public SourceNatRule() {
setType("SourceNatRule");
}
public String getToSourceIpAddressMax() {
return toSourceIpAddressMax;
}
public void setToSourceIpAddressMax(String toSourceIpAddressMax) {
this.toSourceIpAddressMax = toSourceIpAddressMax;
}
public String getToSourceIpAddressMin() {
return toSourceIpAddressMin;
}
public void setToSourceIpAddressMin(String toSourceIpAddressMin) {
this.toSourceIpAddressMin = toSourceIpAddressMin;
}
public Integer getToSourcePort() {
return toSourcePort;
}
public void setToSourcePort(Integer toSourcePort) {
this.toSourcePort = toSourcePort;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime
* result
+ ((toSourceIpAddressMax == null) ? 0 : toSourceIpAddressMax
.hashCode());
result = prime
* result
+ ((toSourceIpAddressMin == null) ? 0 : toSourceIpAddressMin
.hashCode());
result = prime * result
+ ((toSourcePort == null) ? 0 : toSourcePort.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
SourceNatRule other = (SourceNatRule) obj;
if (toSourceIpAddressMax == null) {
if (other.toSourceIpAddressMax != null)
return false;
} else if (!toSourceIpAddressMax.equals(other.toSourceIpAddressMax))
return false;
if (toSourceIpAddressMin == null) {
if (other.toSourceIpAddressMin != null)
return false;
} else if (!toSourceIpAddressMin.equals(other.toSourceIpAddressMin))
return false;
if (toSourcePort == null) {
if (other.toSourcePort != null)
return false;
} else if (!toSourcePort.equals(other.toSourcePort))
return false;
return true;
}
@Override
public boolean equalsIgnoreUuid(Object obj) {
if (this == obj)
return true;
if (!super.equalsIgnoreUuid(obj))
return false;
if (getClass() != obj.getClass())
return false;
SourceNatRule other = (SourceNatRule) obj;
if (toSourceIpAddressMax == null) {
if (other.toSourceIpAddressMax != null)
return false;
} else if (!toSourceIpAddressMax.equals(other.toSourceIpAddressMax))
return false;
if (toSourceIpAddressMin == null) {
if (other.toSourceIpAddressMin != null)
return false;
} else if (!toSourceIpAddressMin.equals(other.toSourceIpAddressMin))
return false;
if (toSourcePort == null) {
if (other.toSourcePort != null)
return false;
} else if (!toSourcePort.equals(other.toSourcePort))
return false;
return true;
}
}

View File

@ -61,6 +61,7 @@ import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.network.nicira.ControlClusterStatus;
import com.cloud.network.nicira.DestinationNatRule;
import com.cloud.network.nicira.L3GatewayAttachment;
import com.cloud.network.nicira.LogicalRouterConfig;
import com.cloud.network.nicira.LogicalRouterPort;
@ -75,6 +76,7 @@ import com.cloud.network.nicira.NiciraNvpTag;
import com.cloud.network.nicira.PatchAttachment;
import com.cloud.network.nicira.RouterNextHop;
import com.cloud.network.nicira.SingleDefaultRouteImplictRoutingConfig;
import com.cloud.network.nicira.SourceNatRule;
import com.cloud.network.nicira.TransportZoneBinding;
import com.cloud.network.nicira.VifAttachment;
import com.cloud.resource.ServerResource;
@ -449,13 +451,13 @@ public class NiciraNvpResource implements ServerResource {
new PatchAttachment(lrpi.getUuid()));
// Setup the source nat rule
NatRule snr = new NatRule();
snr.setType("SourceNatRule");
SourceNatRule snr = new SourceNatRule();
snr.setToSourceIpAddressMin(publicNetworkIpAddress.split("/")[0]);
snr.setToSourceIpAddressMax(publicNetworkIpAddress.split("/")[0]);
Match match = new Match();
match.setSourceIpAddresses(internalNetworkAddress);
snr.setMatch(match);
snr.setOrder(200);
_niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), snr);
} catch (NiciraNvpApiException e) {
// We need to destroy the router if we already created it
@ -604,7 +606,8 @@ public class NiciraNvpResource implements ServerResource {
continue;
}
if (rule.getDstPortRange()[0] != rule.getDstPortRange()[1]) {
if (rule.getDstPortRange()[0] != rule.getDstPortRange()[1] ||
rule.getSrcPortRange()[0] != rule.getSrcPortRange()[1] ) {
return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, false, "Nicira NVP doesn't support port ranges for port forwarding");
}
@ -700,32 +703,24 @@ public class NiciraNvpResource implements ServerResource {
natRuleStr.append(" ");
natRuleStr.append(m.getSourceIpAddresses());
natRuleStr.append(" [");
natRuleStr.append(m.getSourcePortMin());
natRuleStr.append("-");
natRuleStr.append(m.getSourcePortMax());
natRuleStr.append(m.getSourcePort());
natRuleStr.append(" ] -> ");
natRuleStr.append(m.getDestinationIpAddresses());
natRuleStr.append(" [");
natRuleStr.append(m.getDestinationPortMin());
natRuleStr.append("-");
natRuleStr.append(m.getDestinationPortMax());
natRuleStr.append(m.getDestinationPort());
natRuleStr.append(" ]) -->");
if ("SourceNatRule".equals(rule.getType())) {
natRuleStr.append(rule.getToSourceIpAddressMin());
natRuleStr.append(((SourceNatRule)rule).getToSourceIpAddressMin());
natRuleStr.append("-");
natRuleStr.append(rule.getToSourceIpAddressMax());
natRuleStr.append(((SourceNatRule)rule).getToSourceIpAddressMax());
natRuleStr.append(" [");
natRuleStr.append(rule.getToSourcePortMin());
natRuleStr.append("-");
natRuleStr.append(rule.getToSourcePortMax());
natRuleStr.append(((SourceNatRule)rule).getToSourcePort());
natRuleStr.append(" ])");
}
else {
natRuleStr.append(rule.getToDestinationIpAddressMin());
natRuleStr.append("-");
natRuleStr.append(rule.getToDestinationIpAddressMax());
natRuleStr.append(((DestinationNatRule)rule).getToDestinationIpAddress());
natRuleStr.append(" [");
natRuleStr.append(rule.getToDestinationPort());
natRuleStr.append(((DestinationNatRule)rule).getToDestinationPort());
natRuleStr.append(" ])");
}
return natRuleStr.toString();
@ -742,23 +737,24 @@ public class NiciraNvpResource implements ServerResource {
protected NatRule[] generateStaticNatRulePair(String insideIp, String outsideIp) {
NatRule[] rulepair = new NatRule[2];
rulepair[0] = new NatRule();
rulepair[0] = new DestinationNatRule();
rulepair[0].setType("DestinationNatRule");
rulepair[1] = new NatRule();
rulepair[0].setOrder(100);
rulepair[1] = new SourceNatRule();
rulepair[1].setType("SourceNatRule");
rulepair[1].setOrder(100);
Match m = new Match();
m.setDestinationIpAddresses(outsideIp);
rulepair[0].setMatch(m);
rulepair[0].setToDestinationIpAddressMin(insideIp);
rulepair[0].setToDestinationIpAddressMax(insideIp);
((DestinationNatRule)rulepair[0]).setToDestinationIpAddress(insideIp);
// create matching snat rule
m = new Match();
m.setSourceIpAddresses(insideIp);
rulepair[1].setMatch(m);
rulepair[1].setToSourceIpAddressMin(outsideIp);
rulepair[1].setToSourceIpAddressMax(outsideIp);
((SourceNatRule)rulepair[1]).setToSourceIpAddressMin(outsideIp);
((SourceNatRule)rulepair[1]).setToSourceIpAddressMax(outsideIp);
return rulepair;
@ -768,9 +764,9 @@ public class NiciraNvpResource implements ServerResource {
// Start with a basic static nat rule, then add port and protocol details
NatRule[] rulepair = generateStaticNatRulePair(insideIp, outsideIp);
rulepair[0].setToDestinationPort(insidePorts[0]);
rulepair[0].getMatch().setDestinationPortMin(outsidePorts[0]);
rulepair[0].getMatch().setDestinationPortMax(outsidePorts[1]);
((DestinationNatRule)rulepair[0]).setToDestinationPort(insidePorts[0]);
rulepair[0].getMatch().setDestinationPort(outsidePorts[0]);
rulepair[0].setOrder(50);
rulepair[0].getMatch().setEthertype("IPv4");
if ("tcp".equals(protocol)) {
rulepair[0].getMatch().setProtocol(6);
@ -779,10 +775,9 @@ public class NiciraNvpResource implements ServerResource {
rulepair[0].getMatch().setProtocol(17);
}
rulepair[1].setToSourcePortMin(outsidePorts[0]);
rulepair[1].setToSourcePortMax(outsidePorts[1]);
rulepair[1].getMatch().setSourcePortMin(insidePorts[0]);
rulepair[1].getMatch().setSourcePortMax(insidePorts[1]);
((SourceNatRule)rulepair[1]).setToSourcePort(outsidePorts[0]);
rulepair[1].getMatch().setSourcePort(insidePorts[0]);
rulepair[1].setOrder(50);
rulepair[1].getMatch().setEthertype("IPv4");
if ("tcp".equals(protocol)) {
rulepair[1].getMatch().setProtocol(6);

View File

@ -20,28 +20,33 @@ import static org.junit.Assert.*;
import org.junit.Test;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class NatRuleTest {
Gson gson = new Gson();
@Test
public void testNatRuleEncoding() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(NatRule.class, new com.cloud.network.nicira.NiciraNvpApi.NatRuleAdapter())
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
DestinationNatRule rn1 = new DestinationNatRule();
rn1.setToDestinationIpAddress("10.10.10.10");
rn1.setToDestinationPort(80);
Match mr1 = new Match();
mr1.setSourceIpAddresses("11.11.11.11/24");
mr1.setEthertype("IPv4");
mr1.setProtocol(6);
rn1.setMatch(mr1);
String jsonString = gson.toJson(rn1);
NatRule dnr = gson.fromJson(jsonString, NatRule.class);
assertTrue(dnr instanceof DestinationNatRule);
assertTrue(rn1.equals(dnr));
}
@Test
public void testNatRuleEncoding() {
NatRule rn1 = new NatRule();
rn1.setToDestinationIpAddressMax("10.10.10.10");
rn1.setToDestinationIpAddressMin("10.10.10.10");
rn1.setToDestinationPort(80);
Match mr1 = new Match();
mr1.setSourceIpAddresses("11.11.11.11/24");
mr1.setEthertype("IPv4");
mr1.setProtocol(6);
rn1.setMatch(mr1);
String jsonString = gson.toJson(rn1);
NatRule dnr = gson.fromJson(jsonString, NatRule.class);
assertTrue(rn1.equals(dnr));
}
}

View File

@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.naming.ConfigurationException;
@ -61,6 +62,7 @@ import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.host.Host;
import com.cloud.network.nicira.Attachment;
import com.cloud.network.nicira.ControlClusterStatus;
import com.cloud.network.nicira.DestinationNatRule;
import com.cloud.network.nicira.LogicalRouterConfig;
import com.cloud.network.nicira.LogicalRouterPort;
import com.cloud.network.nicira.LogicalSwitch;
@ -69,6 +71,7 @@ import com.cloud.network.nicira.NatRule;
import com.cloud.network.nicira.NiciraNvpApi;
import com.cloud.network.nicira.NiciraNvpApiException;
import com.cloud.network.nicira.NiciraNvpList;
import com.cloud.network.nicira.SourceNatRule;
public class NiciraNvpResourceTest {
NiciraNvpApi _nvpApi = mock(NiciraNvpApi.class);
@ -440,8 +443,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generateStaticNatRulePair("10.10.10.10", "11.11.11.11");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
ConfigureStaticNatRulesOnLogicalRouterAnswer a = (ConfigureStaticNatRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
@ -452,11 +455,11 @@ public class NiciraNvpResourceTest {
public boolean matches(Object argument) {
NatRule rule = (NatRule) argument;
if (rule.getType().equals("DestinationNatRule") &&
rule.getToDestinationIpAddressMin().equals("10.10.10.10")) {
((DestinationNatRule)rule).getToDestinationIpAddress().equals("10.10.10.10")) {
return true;
}
if (rule.getType().equals("SourceNatRule") &&
rule.getToSourceIpAddressMin().equals("11.11.11.11")) {
((SourceNatRule)rule).getToSourceIpAddressMin().equals("11.11.11.11")) {
return true;
}
return false;
@ -481,8 +484,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generateStaticNatRulePair("10.10.10.10", "11.11.11.11");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
// Mock the api find call
@ -500,11 +503,11 @@ public class NiciraNvpResourceTest {
public boolean matches(Object argument) {
NatRule rule = (NatRule) argument;
if (rule.getType().equals("DestinationNatRule") &&
rule.getToDestinationIpAddressMin().equals("10.10.10.10")) {
((DestinationNatRule)rule).getToDestinationIpAddress().equals("10.10.10.10")) {
return true;
}
if (rule.getType().equals("SourceNatRule") &&
rule.getToSourceIpAddressMin().equals("11.11.11.11")) {
((SourceNatRule)rule).getToSourceIpAddressMin().equals("11.11.11.11")) {
return true;
}
return false;
@ -529,8 +532,10 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generateStaticNatRulePair("10.10.10.10", "11.11.11.11");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
final UUID rule0Uuid = UUID.randomUUID();
final UUID rule1Uuid = UUID.randomUUID();
rulepair[0].setUuid(rule0Uuid);
rulepair[1].setUuid(rule1Uuid);
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
// Mock the api find call
@ -543,11 +548,11 @@ public class NiciraNvpResourceTest {
ConfigureStaticNatRulesOnLogicalRouterAnswer a = (ConfigureStaticNatRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
assertTrue(a.getResult());
verify(_nvpApi, atLeast(2)).deleteLogicalRouterNatRule(eq("aaaaa"), argThat(new ArgumentMatcher<String>() {
verify(_nvpApi, atLeast(2)).deleteLogicalRouterNatRule(eq("aaaaa"), argThat(new ArgumentMatcher<UUID>() {
@Override
public boolean matches(Object argument) {
String uuid = (String) argument;
if ("bbbbb".equals(uuid) || "ccccc".equals(uuid)) {
UUID uuid = (UUID) argument;
if (rule0Uuid.equals(uuid) || rule1Uuid.equals(uuid)) {
return true;
}
return false;
@ -572,8 +577,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generateStaticNatRulePair("10.10.10.10", "11.11.11.11");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenThrow(new NiciraNvpApiException());
// Mock the api find call
@ -585,7 +590,7 @@ public class NiciraNvpResourceTest {
ConfigureStaticNatRulesOnLogicalRouterAnswer a = (ConfigureStaticNatRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
assertFalse(a.getResult());
verify(_nvpApi, atLeastOnce()).deleteLogicalRouterNatRule(eq("aaaaa"), eq("bbbbb"));
verify(_nvpApi, atLeastOnce()).deleteLogicalRouterNatRule(eq("aaaaa"), eq(rulepair[0].getUuid()));
}
@Test
@ -611,8 +616,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generatePortForwardingRulePair("10.10.10.10", new int[] { 8080, 8080 }, "11.11.11.11", new int[] { 80, 80}, "tcp");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
ConfigurePortForwardingRulesOnLogicalRouterAnswer a = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
@ -623,11 +628,11 @@ public class NiciraNvpResourceTest {
public boolean matches(Object argument) {
NatRule rule = (NatRule) argument;
if (rule.getType().equals("DestinationNatRule") &&
rule.getToDestinationIpAddressMin().equals("10.10.10.10")) {
((DestinationNatRule)rule).getToDestinationIpAddress().equals("10.10.10.10")) {
return true;
}
if (rule.getType().equals("SourceNatRule") &&
rule.getToSourceIpAddressMin().equals("11.11.11.11")) {
((SourceNatRule)rule).getToSourceIpAddressMin().equals("11.11.11.11")) {
return true;
}
return false;
@ -652,8 +657,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generatePortForwardingRulePair("10.10.10.10", new int[] { 8080, 8080 }, "11.11.11.11", new int[] { 80, 80}, "tcp");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
// Mock the api find call
@ -671,11 +676,11 @@ public class NiciraNvpResourceTest {
public boolean matches(Object argument) {
NatRule rule = (NatRule) argument;
if (rule.getType().equals("DestinationNatRule") &&
rule.getToDestinationIpAddressMin().equals("10.10.10.10")) {
((DestinationNatRule)rule).getToDestinationIpAddress().equals("10.10.10.10")) {
return true;
}
if (rule.getType().equals("SourceNatRule") &&
rule.getToSourceIpAddressMin().equals("11.11.11.11")) {
((SourceNatRule)rule).getToSourceIpAddressMin().equals("11.11.11.11")) {
return true;
}
return false;
@ -700,8 +705,10 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generatePortForwardingRulePair("10.10.10.10", new int[] { 8080, 8080 }, "11.11.11.11", new int[] { 80, 80}, "tcp");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
final UUID rule0Uuid = UUID.randomUUID();
final UUID rule1Uuid = UUID.randomUUID();
rulepair[0].setUuid(rule0Uuid);
rulepair[1].setUuid(rule1Uuid);
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
// Mock the api find call
@ -714,11 +721,11 @@ public class NiciraNvpResourceTest {
ConfigurePortForwardingRulesOnLogicalRouterAnswer a = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
assertTrue(a.getResult());
verify(_nvpApi, atLeast(2)).deleteLogicalRouterNatRule(eq("aaaaa"), argThat(new ArgumentMatcher<String>() {
verify(_nvpApi, atLeast(2)).deleteLogicalRouterNatRule(eq("aaaaa"), argThat(new ArgumentMatcher<UUID>() {
@Override
public boolean matches(Object argument) {
String uuid = (String) argument;
if ("bbbbb".equals(uuid) || "ccccc".equals(uuid)) {
UUID uuid = (UUID) argument;
if (rule0Uuid.equals(uuid) || rule1Uuid.equals(uuid)) {
return true;
}
return false;
@ -743,8 +750,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generatePortForwardingRulePair("10.10.10.10", new int[] { 8080, 8080 }, "11.11.11.11", new int[] { 80, 80}, "tcp");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenThrow(new NiciraNvpApiException());
// Mock the api find call
@ -756,7 +763,7 @@ public class NiciraNvpResourceTest {
ConfigurePortForwardingRulesOnLogicalRouterAnswer a = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
assertFalse(a.getResult());
verify(_nvpApi, atLeastOnce()).deleteLogicalRouterNatRule(eq("aaaaa"), eq("bbbbb"));
verify(_nvpApi, atLeastOnce()).deleteLogicalRouterNatRule(eq("aaaaa"), eq(rulepair[0].getUuid()));
}
@Test
@ -782,8 +789,8 @@ public class NiciraNvpResourceTest {
// Mock the api create calls
NatRule[] rulepair = _resource.generatePortForwardingRulePair("10.10.10.10", new int[] { 80, 85 }, "11.11.11.11", new int[] { 80, 85}, "tcp");
rulepair[0].setUuid("bbbbb");
rulepair[1].setUuid("ccccc");
rulepair[0].setUuid(UUID.randomUUID());
rulepair[1].setUuid(UUID.randomUUID());
when(_nvpApi.createLogicalRouterNatRule(eq("aaaaa"), (NatRule)any())).thenReturn(rulepair[0]).thenReturn(rulepair[1]);
ConfigurePortForwardingRulesOnLogicalRouterAnswer a = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _resource.executeRequest(cmd);
@ -799,13 +806,15 @@ public class NiciraNvpResourceTest {
assertTrue("DestinationNatRule".equals(rules[0].getType()));
assertTrue("SourceNatRule".equals(rules[1].getType()));
assertTrue(rules[0].getToDestinationIpAddressMin().equals("10.10.10.10") && rules[0].getToDestinationIpAddressMax().equals("10.10.10.10"));
assertTrue(rules[0].getToDestinationPort() == null);
assertTrue(rules[0].getMatch().getDestinationIpAddresses().equals("11.11.11.11"));
DestinationNatRule dnr = (DestinationNatRule) rules[0];
assertTrue(dnr.getToDestinationIpAddress().equals("10.10.10.10"));
assertTrue(dnr.getToDestinationPort() == null);
assertTrue(dnr.getMatch().getDestinationIpAddresses().equals("11.11.11.11"));
assertTrue(rules[1].getToSourceIpAddressMin().equals("11.11.11.11") && rules[1].getToSourceIpAddressMax().equals("11.11.11.11"));
assertTrue(rules[1].getToSourcePortMin() == null && rules[1].getToSourcePortMax() == null);
assertTrue(rules[1].getMatch().getSourceIpAddresses().equals("10.10.10.10"));
SourceNatRule snr = (SourceNatRule) rules[1];
assertTrue(snr.getToSourceIpAddressMin().equals("11.11.11.11") && snr.getToSourceIpAddressMax().equals("11.11.11.11"));
assertTrue(snr.getToSourcePort() == null);
assertTrue(snr.getMatch().getSourceIpAddresses().equals("10.10.10.10"));
}
@Test
@ -814,17 +823,19 @@ public class NiciraNvpResourceTest {
assertTrue("DestinationNatRule".equals(rules[0].getType()));
assertTrue("SourceNatRule".equals(rules[1].getType()));
assertTrue(rules[0].getToDestinationIpAddressMin().equals("10.10.10.10") && rules[0].getToDestinationIpAddressMax().equals("10.10.10.10"));
assertTrue(rules[0].getToDestinationPort() == 8080);
assertTrue(rules[0].getMatch().getDestinationIpAddresses().equals("11.11.11.11"));
assertTrue(rules[0].getMatch().getDestinationPortMin() == 80 && rules[0].getMatch().getDestinationPortMax() == 80);
assertTrue(rules[0].getMatch().getEthertype().equals("IPv4") && rules[0].getMatch().getProtocol() == 6);
DestinationNatRule dnr = (DestinationNatRule) rules[0];
assertTrue(dnr.getToDestinationIpAddress().equals("10.10.10.10"));
assertTrue(dnr.getToDestinationPort() == 8080);
assertTrue(dnr.getMatch().getDestinationIpAddresses().equals("11.11.11.11"));
assertTrue(dnr.getMatch().getDestinationPort() == 80 );
assertTrue(dnr.getMatch().getEthertype().equals("IPv4") && dnr.getMatch().getProtocol() == 6);
assertTrue(rules[1].getToSourceIpAddressMin().equals("11.11.11.11") && rules[1].getToSourceIpAddressMax().equals("11.11.11.11"));
assertTrue(rules[1].getToSourcePortMin() == 80 && rules[1].getToSourcePortMax() == 80);
assertTrue(rules[1].getMatch().getSourceIpAddresses().equals("10.10.10.10"));
assertTrue(rules[1].getMatch().getSourcePortMin() == 8080 && rules[1].getMatch().getSourcePortMax() == 8080);
assertTrue(rules[1].getMatch().getEthertype().equals("IPv4") && rules[1].getMatch().getProtocol() == 6);
SourceNatRule snr = (SourceNatRule) rules[1];
assertTrue(snr.getToSourceIpAddressMin().equals("11.11.11.11") && snr.getToSourceIpAddressMax().equals("11.11.11.11"));
assertTrue(snr.getToSourcePort() == 80);
assertTrue(snr.getMatch().getSourceIpAddresses().equals("10.10.10.10"));
assertTrue(snr.getMatch().getSourcePort() == 8080);
assertTrue(snr.getMatch().getEthertype().equals("IPv4") && rules[1].getMatch().getProtocol() == 6);
}
}

View File

@ -320,8 +320,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
} else {
if (rulesRevoked) {
// no active rules/revoked rules are associated with this public IP, so remove the
// association with the provider
ip.setState(State.Releasing);
// association with the provider
if (ip.isSourceNat()) {
s_logger.debug("Not releasing ip " + ip.getAddress().addr() + " as it is in use for SourceNat");
} else {
ip.setState(State.Releasing);
}
} else {
if (ip.getState() == State.Releasing) {
// rules are not revoked yet, so don't let the network service provider revoke the IP