mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-2035: Fix source NAT configuration with Cisco VNMC/ASA
Due to VNMC limitation source nat ip cannot be assigned to ASA 1000v outside interface. Working around this issue by acquiring additional public ip during network implement and assigning that to outside interface of ASA. Also made changes to ensure that source nat policy comes after pf and static nat policies in terms of evaluation by assigning a high 'order' value for it.
This commit is contained in:
parent
dfad178a9e
commit
c704c90b11
@ -279,7 +279,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
String xml = VnmcXml.CREATE_VDC.getXml();
|
||||
String service = VnmcXml.CREATE_VDC.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "descr", "VDC for Tenant" + tenantName);
|
||||
xml = replaceXmlValue(xml, "descr", "VDC for Tenant " + tenantName);
|
||||
xml = replaceXmlValue(xml, "name", getNameForTenantVDC(tenantName));
|
||||
xml = replaceXmlValue(xml, "dn", getDnForTenantVDC(tenantName));
|
||||
|
||||
@ -304,7 +304,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
String xml = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getXml();
|
||||
String service = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Device Profile for Tenant VDC" + tenantName);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Device Profile for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceServiceProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "dn", getDnForTenantVDCEdgeDeviceProfile(tenantName));
|
||||
|
||||
@ -407,7 +407,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
String xml = VnmcXml.CREATE_EDGE_SECURITY_PROFILE.getXml();
|
||||
String service = VnmcXml.CREATE_EDGE_SECURITY_PROFILE.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "egressref", "default-egress");
|
||||
@ -505,7 +505,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
return createTenantVDCNatPolicyRef(
|
||||
getDnForSourceNatPolicyRef(tenantName),
|
||||
getNameForSourceNatPolicy(tenantName),
|
||||
tenantName);
|
||||
tenantName,
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -545,7 +546,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
String xml = VnmcXml.RESOLVE_NAT_POLICY_SET.getXml();
|
||||
String service = VnmcXml.RESOLVE_NAT_POLICY_SET.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "natpolicysetname", getNameForNatPolicySet(tenantName));
|
||||
@ -656,7 +657,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
String xml = VnmcXml.RESOLVE_ACL_POLICY_SET.getXml();
|
||||
String service = VnmcXml.RESOLVE_ACL_POLICY_SET.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName);
|
||||
xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName);
|
||||
xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName));
|
||||
xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName));
|
||||
//xml = replaceXmlValue(xml, "egresspolicysetname", getNameForAclPolicySet(tenantName, false));
|
||||
@ -838,17 +839,23 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
return verifySuccess(response);
|
||||
}
|
||||
|
||||
private boolean createTenantVDCNatPolicyRef(String policyRefDn, String name, String tenantName) throws ExecutionException {
|
||||
private boolean createTenantVDCNatPolicyRef(String policyRefDn, String name, String tenantName, boolean isSourceNat) throws ExecutionException {
|
||||
String xml = VnmcXml.CREATE_NAT_POLICY_REF.getXml();
|
||||
String service = VnmcXml.CREATE_NAT_POLICY_REF.getService();
|
||||
xml = replaceXmlValue(xml, "cookie", _cookie);
|
||||
xml = replaceXmlValue(xml, "natpolicyrefdn", policyRefDn);
|
||||
xml = replaceXmlValue(xml, "natpolicyname", name);
|
||||
|
||||
List<String> policies = listNatPolicies(tenantName);
|
||||
int order = 100;
|
||||
if (policies != null) {
|
||||
order += policies.size();
|
||||
// PF and static NAT policies need to come before source NAT, so leaving buffer
|
||||
// and creating source NAT with a high order value.
|
||||
// Initially tried setting MAX_INT as the order but VNMC complains about it
|
||||
int order = 10000; // TODO: For now value should be sufficient, if required may need to increase
|
||||
if (!isSourceNat) {
|
||||
List<String> policies = listNatPolicies(tenantName);
|
||||
order = 100; // order starts at 100
|
||||
if (policies != null) {
|
||||
order += policies.size();
|
||||
}
|
||||
}
|
||||
xml = replaceXmlValue(xml, "order", Integer.toString(order));
|
||||
|
||||
@ -1062,7 +1069,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
return createTenantVDCNatPolicyRef(
|
||||
getDnForPFPolicyRef(tenantName, identifier),
|
||||
getNameForPFPolicy(tenantName, identifier),
|
||||
tenantName);
|
||||
tenantName,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1180,7 +1188,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection {
|
||||
return createTenantVDCNatPolicyRef(
|
||||
getDnForDNatPolicyRef(tenantName, identifier),
|
||||
getNameForDNatPolicy(tenantName, identifier),
|
||||
tenantName);
|
||||
tenantName,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -70,6 +70,7 @@ import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.host.DetailVO;
|
||||
import com.cloud.host.Host;
|
||||
@ -113,6 +114,7 @@ import com.cloud.resource.ResourceStateAdapter;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.UnableDeleteHostException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -338,10 +340,31 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro
|
||||
publicGateways.add(vlanVO.getVlanGateway());
|
||||
}
|
||||
|
||||
// due to VNMC limitation of not allowing source NAT ip as the outside ip of firewall,
|
||||
// an additional public ip needs to acquired for assigning as firewall outside ip
|
||||
IpAddress outsideIp = null;
|
||||
try {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long callerUserId = UserContext.current().getCallerUserId();
|
||||
outsideIp = _networkMgr.allocateIp(owner, false, caller, callerUserId, zone);
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.error("Unable to allocate additional public Ip address. Exception details " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
outsideIp = _networkMgr.associateIPToGuestNetwork(outsideIp.getId(), network.getId(), true);
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.error("Unable to assign allocated additional public Ip " + outsideIp.getAddress().addr() + " to network with vlan " + vlanId + ". Exception details " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create logical edge firewall in VNMC
|
||||
String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr());
|
||||
// due to ASA limitation of allowing single subnet to be assigned to firewall interfaces,
|
||||
// all public ip addresses must be from same subnet, this essentially means single public subnet in zone
|
||||
if (!createLogicalEdgeFirewall(vlanId, network.getGateway(), gatewayNetmask,
|
||||
sourceNatIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) {
|
||||
outsideIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) {
|
||||
s_logger.error("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName());
|
||||
return false;
|
||||
}
|
||||
@ -356,10 +379,10 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro
|
||||
}
|
||||
|
||||
// configure source NAT
|
||||
//if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) {
|
||||
// s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName());
|
||||
// return false;
|
||||
//}
|
||||
if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) {
|
||||
s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
// associate Asa 1000v instance with logical edge firewall
|
||||
if (!associateAsaWithLogicalEdgeFirewall(vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user