Add support for routed NSX Isolated networks \n and non RFC 1918 compliant IPs

This commit is contained in:
Pearl Dsilva 2023-11-14 10:39:31 -05:00
parent e7f5c59b27
commit 770a96ae40
11 changed files with 59 additions and 12 deletions

View File

@ -296,6 +296,7 @@ public class ApiConstants {
public static final String MEMORY = "memory";
public static final String MODE = "mode";
public static final String NSX_MODE = "nsxmode";
public static final String NSX_ENABLED = "isnsxenabled";
public static final String NAME = "name";
public static final String METHOD_NAME = "methodname";
public static final String NETWORK_DOMAIN = "networkdomain";

View File

@ -145,6 +145,10 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
@Param(description = "the type of the zone - core or edge", since = "4.18.0")
String type;
@SerializedName(ApiConstants.NSX_ENABLED)
@Param(description = "true, if zone is NSX enabled", since = "4.20.0")
private boolean nsxEnabled = false;
public ZoneResponse() {
tags = new LinkedHashSet<ResourceTagResponse>();
}
@ -368,4 +372,8 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
public String getType() {
return type;
}
public void setNsxEnabled(boolean nsxEnabled) {
this.nsxEnabled = nsxEnabled;
}
}

View File

@ -63,6 +63,9 @@ public interface ConfigurationManager {
static final String VM_USERDATA_MAX_LENGTH_STRING = "vm.userdata.max.length";
static final ConfigKey<Integer> VM_USERDATA_MAX_LENGTH = new ConfigKey<>("Advanced", Integer.class, VM_USERDATA_MAX_LENGTH_STRING, "32768",
"Max length of vm userdata after base64 decoding. Default is 32768 and maximum is 1048576", true);
public static final ConfigKey<Boolean> AllowNonRFC1918CompliantIPs = new ConfigKey<Boolean>(Boolean.class,
"allow.non.rfc1918.compliant.ips", "Advanced", "false",
"Allows non-compliant RFC 1918 IPs for Shared, Isolated networks and VPCs", true);
/**
* @param offering

View File

@ -2862,7 +2862,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
// Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
if (cidr != null && ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) {
if (!NetUtils.validateGuestCidr(cidr)) {
if (!ConfigurationManager.AllowNonRFC1918CompliantIPs.value() && !NetUtils.validateGuestCidr(cidr)) {
throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
}
}

View File

@ -1900,10 +1900,10 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
defaultKubernetesServiceNetworkOfferingProviders.put(Service.SourceNat, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.PortForwarding, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
if (!forNsx) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
}
NetworkOfferingVO defaultKubernetesServiceNetworkOffering =

View File

@ -80,8 +80,9 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
public boolean canHandle(NetworkOffering offering, DataCenter.NetworkType networkType,
PhysicalNetwork physicalNetwork) {
return networkType == DataCenter.NetworkType.Advanced && isMyTrafficType(offering.getTrafficType())
&& isMyIsolationMethod(physicalNetwork) && networkOfferingServiceMapDao.isProviderForNetworkOffering(
offering.getId(), Network.Provider.Nsx);
&& isMyIsolationMethod(physicalNetwork) && (NetworkOffering.NsxMode.ROUTED.name().equals(offering.getNsxMode())
|| (networkOfferingServiceMapDao.isProviderForNetworkOffering(
offering.getId(), Network.Provider.Nsx) && NetworkOffering.NsxMode.NATTED.name().equals(offering.getNsxMode())));
}
@Override

View File

@ -28,10 +28,13 @@ import com.cloud.network.nsx.NsxService;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
@ -60,6 +63,10 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
private NsxControllerUtils nsxControllerUtils;
@Inject
private NsxService nsxService;
@Inject
private VpcOfferingDao vpcOfferingDao;
@Inject
private NetworkOfferingDao offeringDao;
private static final Logger s_logger = Logger.getLogger(NsxPublicNetworkGuru.class);
@ -139,6 +146,19 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
throw new CloudRuntimeException(msg);
}
boolean hasNatSupport = false;
if (vpc == null) {
NetworkOffering offering = offeringDao.findById(network.getNetworkOfferingId());
hasNatSupport = NetworkOffering.NsxMode.NATTED.name().equals(offering.getNsxMode());
} else {
VpcOffering vpcOffering = vpcOfferingDao.findById(vpc.getVpcOfferingId());
hasNatSupport = NetworkOffering.NsxMode.NATTED.name().equals(vpcOffering.getNsxMode());
}
if (!hasNatSupport) {
return nic;
}
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, dataCenterId, resourceId, isForVpc);
String translatedIp = ipAddress.getAddress().addr();
s_logger.debug(String.format("Creating NSX Nat Rule for Tier1 GW %s for translated IP %s", tier1GatewayName, translatedIp));

View File

@ -17,9 +17,12 @@
package com.cloud.api.query.dao;
import java.util.List;
import java.util.Objects;
import javax.inject.Inject;
import com.cloud.network.dao.NsxProviderDao;
import com.cloud.network.element.NsxProviderVO;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
@ -53,6 +56,8 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
public AccountManager _accountMgr;
@Inject
private AnnotationDao annotationDao;
@Inject
private NsxProviderDao nsxProviderDao;
protected DataCenterJoinDaoImpl() {
@ -119,6 +124,11 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
}
}
NsxProviderVO nsxProviderVO = nsxProviderDao.findByZoneId(dataCenter.getId());
if (Objects.nonNull(nsxProviderVO)) {
zoneResponse.setNsxEnabled(true);
}
zoneResponse.setResourceDetails(ApiDBUtils.getResourceDetails(dataCenter.getId(), ResourceObjectType.Zone));
zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));

View File

@ -2648,7 +2648,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
zoneName = zone.getName();
}
if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
if (guestCidr != null && !AllowNonRFC1918CompliantIPs.value() && !NetUtils.validateGuestCidr(guestCidr)) {
throw new InvalidParameterValueException("Please enter a valid guest cidr");
}
@ -2817,7 +2817,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
// checking the following params outside checkzoneparams method as we do
// not use these params for updatezone
// hence the method below is generic to check for common params
if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
if (guestCidr != null && !AllowNonRFC1918CompliantIPs.value() && !NetUtils.validateGuestCidr(guestCidr)) {
throw new InvalidParameterValueException("Please enter a valid guest cidr");
}
@ -6563,6 +6563,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
offeringFinal.setForTungsten(Objects.requireNonNullElse(forTungsten, false));
offeringFinal.setForNsx(Objects.requireNonNullElse(forNsx, false));
if (Boolean.TRUE.equals(forNsx)) {
offeringFinal.setNsxMode(mode);
}
if (enableOffering) {
offeringFinal.setState(NetworkOffering.State.Enabled);
@ -7716,8 +7719,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH,
BYTES_MAX_READ_LENGTH, BYTES_MAX_WRITE_LENGTH, ADD_HOST_ON_SERVICE_RESTART_KVM, SET_HOST_DOWN_TO_MAINTENANCE, VM_SERVICE_OFFERING_MAX_CPU_CORES,
VM_SERVICE_OFFERING_MAX_RAM_SIZE, VM_USERDATA_MAX_LENGTH, MIGRATE_VM_ACROSS_CLUSTERS,
ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN, ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, ALLOW_DOMAIN_ADMINS_TO_CREATE_TAGGED_OFFERINGS
VM_SERVICE_OFFERING_MAX_RAM_SIZE, VM_USERDATA_MAX_LENGTH, MIGRATE_VM_ACROSS_CLUSTERS, ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN,
ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, ALLOW_DOMAIN_ADMINS_TO_CREATE_TAGGED_OFFERINGS, AllowNonRFC1918CompliantIPs
};
}

View File

@ -3125,7 +3125,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
if (!NetUtils.isValidIp4Cidr(guestVmCidr)) {
throw new InvalidParameterValueException("Invalid format of Guest VM CIDR.");
}
if (!NetUtils.validateGuestCidr(guestVmCidr)) {
if (!ConfigurationManager.AllowNonRFC1918CompliantIPs.value() && !NetUtils.validateGuestCidr(guestVmCidr)) {
throw new InvalidParameterValueException("Invalid format of Guest VM CIDR. Make sure it is RFC1918 compliant. ");
}

View File

@ -40,6 +40,7 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.network.nsx.NsxService;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.alert.AlertService;
@ -1215,7 +1216,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
// cidr has to be RFC 1918 complient
if (!NetUtils.validateGuestCidr(cidr)) {
if (!ConfigurationManager.AllowNonRFC1918CompliantIPs.value() && !NetUtils.validateGuestCidr(cidr)) {
throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant");
}
@ -1884,7 +1885,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// 2) Only Isolated networks with Source nat service enabled can be
// added to vpc
if (!(guestNtwkOff.getGuestType() == GuestType.Isolated && supportedSvcs.contains(Service.SourceNat))) {
if (!guestNtwkOff.isForNsx() && !(guestNtwkOff.getGuestType() == GuestType.Isolated && supportedSvcs.contains(Service.SourceNat))) {
throw new InvalidParameterValueException("Only network offerings of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName()
+ " are valid for vpc ");
@ -1895,7 +1896,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
* TODO This should have never been hardcoded like this in the first
* place if (guestNtwkOff.getRedundantRouter()) { throw new
* InvalidParameterValueException
* ("No redunant router support when network belnogs to VPC"); }
* ("No redundant router support when network belongs to VPC"); }
*/
// 4) Conserve mode should be off