NSX: Add support to add firewall rule / Network ACL

This commit is contained in:
Pearl Dsilva 2023-11-12 19:50:38 -05:00
parent daea80d12b
commit b17c80e35e
19 changed files with 260 additions and 35 deletions

View File

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

View File

@ -141,6 +141,10 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
@Param(description = "The maximum value the MTU can have on the VR's public interfaces", since = "4.18.0") @Param(description = "The maximum value the MTU can have on the VR's public interfaces", since = "4.18.0")
private Integer routerPublicInterfaceMaxMtu; private Integer routerPublicInterfaceMaxMtu;
@SerializedName(ApiConstants.NSX_ENABLED)
@Param(description = "true, if zone is NSX enabled", since = "4.20.0")
private boolean nsxEnabled = false;
@SerializedName(ApiConstants.TYPE) @SerializedName(ApiConstants.TYPE)
@Param(description = "the type of the zone - core or edge", since = "4.18.0") @Param(description = "the type of the zone - core or edge", since = "4.18.0")
String type; String type;
@ -368,4 +372,8 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
public String getType() { public String getType() {
return type; 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 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", 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); "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 * @param offering

View File

@ -1736,7 +1736,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
//apply network ACLs //apply network ACLs
// TODO: remove check for NSX // TODO: remove check for NSX
if (!offering.isForNsx() && !_networkACLMgr.applyACLToNetwork(networkId)) { if (!_networkACLMgr.applyACLToNetwork(networkId)) {
s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart"); s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart");
success = false; success = false;
} }
@ -2863,7 +2863,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
// Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4 // 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 (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"); throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
} }
} }
@ -4720,7 +4720,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
"Time (in seconds) to wait before shutting down a network that's not in used", false, Scope.Global, null); "Time (in seconds) to wait before shutting down a network that's not in used", false, Scope.Global, null);
public static final ConfigKey<Integer> NetworkGcInterval = new ConfigKey<Integer>(Integer.class, "network.gc.interval", "Advanced", "600", public static final ConfigKey<Integer> NetworkGcInterval = new ConfigKey<Integer>(Integer.class, "network.gc.interval", "Advanced", "600",
"Seconds to wait before checking for networks to shutdown", true, Scope.Global, null); "Seconds to wait before checking for networks to shutdown", true, Scope.Global, null);
// 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);
@Override @Override
public ConfigKey<?>[] getConfigKeys() { public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,

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.SourceNat, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, 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.PortForwarding, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, forNsx ? Network.Provider.Nsx : Network.Provider.VirtualRouter);
if (!forNsx) { if (!forNsx) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter); defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
} }
NetworkOfferingVO defaultKubernetesServiceNetworkOffering = NetworkOfferingVO defaultKubernetesServiceNetworkOffering =
@ -1914,6 +1914,9 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
true, false, false, false, false, true, false, false, false, false,
false, false, false, true, true, false, false, false, false, true, true, false,
false, true, false, false); false, true, false, false);
if (forNsx) {
defaultKubernetesServiceNetworkOffering.setNsxMode(NetworkOffering.NsxMode.NATTED.name());
}
defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true); defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true);
defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled); defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled);
defaultKubernetesServiceNetworkOffering = networkOfferingDao.persistDefaultNetworkOffering(defaultKubernetesServiceNetworkOffering); defaultKubernetesServiceNetworkOffering = networkOfferingDao.persistDefaultNetworkOffering(defaultKubernetesServiceNetworkOffering);

View File

@ -0,0 +1,52 @@
package org.apache.cloudstack.agent.api;
import java.util.List;
public class CreateNsxDistributedFirewallRuleCommand extends NsxNetworkCommand {
private List<String> sourceCidrList;
private String protocol;
private String trafficType;
private String action;
public CreateNsxDistributedFirewallRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId,
String networkResourceName, boolean isResourceVpc,
List<String> sourceCidrList, String protocol,
String trafficType, String action) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc);
this.sourceCidrList = sourceCidrList;
this.protocol = protocol;
this.action = action;
this.trafficType = trafficType;
}
public List<String> getSourceCidrList() {
return sourceCidrList;
}
public void setSourceCidrList(List<String> sourceCidrList) {
this.sourceCidrList = sourceCidrList;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getTrafficType() {
return trafficType;
}
public void setTrafficType(String trafficType) {
this.trafficType = trafficType;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}

View File

@ -34,6 +34,9 @@ public class NsxNetworkRule {
private String protocol; private String protocol;
private String algorithm; private String algorithm;
private List<NsxLoadBalancerMember> memberList; private List<NsxLoadBalancerMember> memberList;
private String aclAction;
private List<String> cidrList;
private String trafficType;
public long getDomainId() { public long getDomainId() {
return domainId; return domainId;
@ -155,6 +158,30 @@ public class NsxNetworkRule {
this.memberList = memberList; this.memberList = memberList;
} }
public String getAclAction() {
return aclAction;
}
public void setAclAction(String aclAction) {
this.aclAction = aclAction;
}
public List<String> getCidrList() {
return cidrList;
}
public void setCidrList(List<String> cidrList) {
this.cidrList = cidrList;
}
public String getTrafficType() {
return trafficType;
}
public void setTrafficType(String trafficType) {
this.trafficType = trafficType;
}
public static final class Builder { public static final class Builder {
private long domainId; private long domainId;
private long accountId; private long accountId;
@ -172,6 +199,9 @@ public class NsxNetworkRule {
private String protocol; private String protocol;
private String algorithm; private String algorithm;
private List<NsxLoadBalancerMember> memberList; private List<NsxLoadBalancerMember> memberList;
private String aclAction;
private List<String> cidrList;
private String trafficType;
public Builder() { public Builder() {
} }
@ -252,6 +282,21 @@ public class NsxNetworkRule {
return this; return this;
} }
public Builder setAclAction(String aclAction) {
this.aclAction = aclAction;
return this;
}
public Builder setCidrList(List<String> cidrList) {
this.cidrList = cidrList;
return this;
}
public Builder setTrafficType(String trafficType) {
this.trafficType = trafficType;
return this;
}
public NsxNetworkRule build() { public NsxNetworkRule build() {
NsxNetworkRule rule = new NsxNetworkRule(); NsxNetworkRule rule = new NsxNetworkRule();
rule.setDomainId(this.domainId); rule.setDomainId(this.domainId);
@ -269,6 +314,9 @@ public class NsxNetworkRule {
rule.setRuleId(this.ruleId); rule.setRuleId(this.ruleId);
rule.setAlgorithm(this.algorithm); rule.setAlgorithm(this.algorithm);
rule.setMemberList(this.memberList); rule.setMemberList(this.memberList);
rule.setAclAction(this.aclAction);
rule.setCidrList(this.cidrList);
rule.setTrafficType(this.trafficType);
return rule; return rule;
} }
} }

View File

@ -36,6 +36,7 @@ import com.vmware.nsx_policy.model.SiteListResult;
import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.StartupNsxCommand; import org.apache.cloudstack.StartupNsxCommand;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand; import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand; import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand; import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
@ -123,6 +124,8 @@ public class NsxResource implements ServerResource {
return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd); return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) { } else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) {
return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd); return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof CreateNsxDistributedFirewallRuleCommand) {
return executeRequest((CreateNsxDistributedFirewallRuleCommand) cmd);
} else { } else {
return Answer.createUnsupportedCommandAnswer(cmd); return Answer.createUnsupportedCommandAnswer(cmd);
} }
@ -290,7 +293,7 @@ public class NsxResource implements ServerResource {
private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) { private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) {
String name = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc()); String name = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
boolean sourceNatEnabled = cmd.isSourceNatEnabled(); boolean sourceNatEnabled = cmd.isSourceNatEnabled() || !cmd.isResourceVpc();
try { try {
nsxApiClient.createTier1Gateway(name, tier0Gateway, edgeCluster, sourceNatEnabled); nsxApiClient.createTier1Gateway(name, tier0Gateway, edgeCluster, sourceNatEnabled);
return new NsxAnswer(cmd, true, ""); return new NsxAnswer(cmd, true, "");
@ -454,6 +457,12 @@ public class NsxResource implements ServerResource {
return new NsxAnswer(cmd, true, null); return new NsxAnswer(cmd, true, null);
} }
private NsxAnswer executeRequest(CreateNsxDistributedFirewallRuleCommand cmd) {
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.isResourceVpc() ? cmd.getNetworkResourceId() : null, cmd.isResourceVpc() ? null : cmd.getNetworkResourceId());
// TODO: execute apiclient
}
@Override @Override
public boolean start() { public boolean start() {
return true; return true;

View File

@ -29,6 +29,7 @@ import com.vmware.nsx_policy.infra.Segments;
import com.vmware.nsx_policy.infra.Services; import com.vmware.nsx_policy.infra.Services;
import com.vmware.nsx_policy.infra.Sites; import com.vmware.nsx_policy.infra.Sites;
import com.vmware.nsx_policy.infra.Tier1s; import com.vmware.nsx_policy.infra.Tier1s;
import com.vmware.nsx_policy.infra.domains.security_policies.Rules;
import com.vmware.nsx_policy.infra.sites.EnforcementPoints; import com.vmware.nsx_policy.infra.sites.EnforcementPoints;
import com.vmware.nsx_policy.infra.tier_0s.LocaleServices; import com.vmware.nsx_policy.infra.tier_0s.LocaleServices;
import com.vmware.nsx_policy.infra.tier_1s.nat.NatRules; import com.vmware.nsx_policy.infra.tier_1s.nat.NatRules;
@ -46,6 +47,7 @@ import com.vmware.nsx_policy.model.LBVirtualServerListResult;
import com.vmware.nsx_policy.model.LocaleServicesListResult; import com.vmware.nsx_policy.model.LocaleServicesListResult;
import com.vmware.nsx_policy.model.PolicyNatRule; import com.vmware.nsx_policy.model.PolicyNatRule;
import com.vmware.nsx_policy.model.PolicyNatRuleListResult; import com.vmware.nsx_policy.model.PolicyNatRuleListResult;
import com.vmware.nsx_policy.model.Rule;
import com.vmware.nsx_policy.model.Segment; import com.vmware.nsx_policy.model.Segment;
import com.vmware.nsx_policy.model.SegmentSubnet; import com.vmware.nsx_policy.model.SegmentSubnet;
import com.vmware.nsx_policy.model.ServiceListResult; import com.vmware.nsx_policy.model.ServiceListResult;
@ -71,18 +73,13 @@ import org.apache.log4j.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServerPoolMemberName; import static org.apache.cloudstack.utils.NsxControllerUtils.*;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServerPoolName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServiceName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getVirtualServerName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServiceEntryName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerAlgorithm;
public class NsxApiClient { public class NsxApiClient {
@ -133,6 +130,17 @@ public class NsxApiClient {
XLARGE XLARGE
} }
private enum firewallActions {
ALLOW,
DROP,
REJECT,
JUMP_TO_APPLICATION
}
private Map<String,String> actionMap = Map.of(
"Allow", firewallActions.ALLOW.name(),
"Deny", firewallActions.DROP.name());
public enum RouteAdvertisementType { TIER1_STATIC_ROUTES, TIER1_CONNECTED, TIER1_NAT, public enum RouteAdvertisementType { TIER1_STATIC_ROUTES, TIER1_CONNECTED, TIER1_NAT,
TIER1_LB_VIP, TIER1_LB_SNAT, TIER1_DNS_FORWARDER_IP, TIER1_IPSEC_LOCAL_ENDPOINT TIER1_LB_VIP, TIER1_LB_SNAT, TIER1_DNS_FORWARDER_IP, TIER1_IPSEC_LOCAL_ENDPOINT
} }
@ -699,6 +707,25 @@ public class NsxApiClient {
} }
} }
public void createNsxFirewallRule(String policyName, String ruleName, String action, List<String> cidrList, String protocol, String trafficType) {
try {
Rules rules = (Rules) nsxService.apply(Rules.class);
Rule rule = new Rule.Builder()
.setId(ruleName)
.setDisplayName(ruleName)
.setAction(actionMap.get(action))
.setSourceGroups(cidrList)
.build();
//TODO: get default domain
rules.patch("default", policyName, ruleName, rule);
} catch (Error error) {
ApiError ae = error.getData()._convertTo(ApiError.class);
String msg = String.format("Failed to create NSX infra service, due to: %s", ae.getErrorMessage());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
}
private String getServiceById(String ruleName) { private String getServiceById(String ruleName) {
try { try {
Services service = (Services) nsxService.apply(Services.class); Services service = (Services) nsxService.apply(Services.class);

View File

@ -56,6 +56,7 @@ import com.cloud.network.element.DhcpServiceProvider;
import com.cloud.network.element.DnsServiceProvider; import com.cloud.network.element.DnsServiceProvider;
import com.cloud.network.element.IpDeployer; import com.cloud.network.element.IpDeployer;
import com.cloud.network.element.LoadBalancingServiceProvider; import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.element.NetworkACLServiceProvider;
import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.PortForwardingServiceProvider;
import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.VpcProvider; import com.cloud.network.element.VpcProvider;
@ -87,6 +88,7 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
import com.vmware.nsx_policy.infra.firewall.Rules;
import net.sf.ehcache.config.InvalidConfigurationException; import net.sf.ehcache.config.InvalidConfigurationException;
import org.apache.cloudstack.StartupNsxCommand; import org.apache.cloudstack.StartupNsxCommand;
import org.apache.cloudstack.resource.NsxLoadBalancerMember; import org.apache.cloudstack.resource.NsxLoadBalancerMember;
@ -107,7 +109,7 @@ import java.util.function.LongFunction;
@Component @Component
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider, public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
LoadBalancingServiceProvider, ResourceStateAdapter, Listener { LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
@ -159,7 +161,14 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
capabilities.put(Network.Service.Lb, null); capabilities.put(Network.Service.Lb, null);
capabilities.put(Network.Service.PortForwarding, null); capabilities.put(Network.Service.PortForwarding, null);
capabilities.put(Network.Service.NetworkACL, null); capabilities.put(Network.Service.NetworkACL, null);
capabilities.put(Network.Service.Firewall, null); Map<Network.Capability, String> firewallCapabilities = new HashMap<>();
firewallCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp");
firewallCapabilities.put(Network.Capability.SupportedEgressProtocols, "tcp,udp,icmp,all");
firewallCapabilities.put(Network.Capability.MultipleIps, "true");
firewallCapabilities.put(Network.Capability.TrafficStatistics, "per public ip");
firewallCapabilities.put(Network.Capability.SupportedTrafficDirection, "ingress, egress");
capabilities.put(Network.Service.Firewall, firewallCapabilities);
Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>(); Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true"); sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount"); sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
@ -646,4 +655,16 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
} }
return lbMembers; return lbMembers;
} }
@Override
public boolean applyNetworkACLs(Network config, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
if (!canHandle(config, Network.Service.NetworkACL)) {
return false;
}
NsxNetworkRule networkRule = new NsxNetworkRule.Builder().build();
for (NetworkACLItem rule : rules) {
nsxService.addFirewallRule(networkRule);
}
return true;
}
} }

View File

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

View File

@ -28,10 +28,13 @@ import com.cloud.network.nsx.NsxService;
import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
import com.cloud.network.guru.PublicNetworkGuru; import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile; import com.cloud.vm.NicProfile;
@ -60,6 +63,10 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
private NsxControllerUtils nsxControllerUtils; private NsxControllerUtils nsxControllerUtils;
@Inject @Inject
private NsxService nsxService; private NsxService nsxService;
@Inject
private VpcOfferingDao vpcOfferingDao;
@Inject
private NetworkOfferingDao offeringDao;
private static final Logger s_logger = Logger.getLogger(NsxPublicNetworkGuru.class); private static final Logger s_logger = Logger.getLogger(NsxPublicNetworkGuru.class);
@ -128,7 +135,7 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
long dataCenterId = vpc.getZoneId(); long dataCenterId = vpc.getZoneId();
boolean isForVpc = true; boolean isForVpc = true;
long resourceId = isForVpc ? vpc.getId() : network.getId(); long resourceId = isForVpc ? vpc.getId() : network.getId();
Network.Service[] services = { Network.Service.SourceNat }; Network.Service[] services = {Network.Service.SourceNat};
boolean sourceNatEnabled = vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), services); boolean sourceNatEnabled = vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), services);
s_logger.info(String.format("Creating Tier 1 Gateway for VPC %s", vpc.getName())); s_logger.info(String.format("Creating Tier 1 Gateway for VPC %s", vpc.getName()));
@ -139,16 +146,27 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
throw new CloudRuntimeException(msg); throw new CloudRuntimeException(msg);
} }
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, dataCenterId, resourceId, isForVpc); boolean hasNatSupport = false;
String translatedIp = ipAddress.getAddress().addr(); if (vpc == null) {
s_logger.debug(String.format("Creating NSX Nat Rule for Tier1 GW %s for translated IP %s", tier1GatewayName, translatedIp)); NetworkOffering offering = offeringDao.findById(network.getNetworkOfferingId());
String natRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, dataCenterId, resourceId, isForVpc); hasNatSupport = NetworkOffering.NsxMode.NATTED.name().equals(offering.getNsxMode());
CreateOrUpdateNsxTier1NatRuleCommand cmd = NsxHelper.createOrUpdateNsxNatRuleCommand(domainId, accountId, dataCenterId, tier1GatewayName, "SNAT", translatedIp, natRuleId); } else {
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(cmd, dataCenterId); VpcOffering vpcOffering = vpcOfferingDao.findById(vpc.getVpcOfferingId());
if (!nsxAnswer.getResult()) { hasNatSupport = NetworkOffering.NsxMode.NATTED.name().equals(vpcOffering.getNsxMode());
String msg = String.format("Could not create NSX Nat Rule on Tier1 Gateway %s for IP %s", tier1GatewayName, translatedIp); }
s_logger.error(msg);
throw new CloudRuntimeException(msg); if (hasNatSupport) {
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));
String natRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, dataCenterId, resourceId, isForVpc);
CreateOrUpdateNsxTier1NatRuleCommand cmd = NsxHelper.createOrUpdateNsxNatRuleCommand(domainId, accountId, dataCenterId, tier1GatewayName, "SNAT", translatedIp, natRuleId);
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(cmd, dataCenterId);
if (!nsxAnswer.getResult()) {
String msg = String.format("Could not create NSX Nat Rule on Tier1 Gateway %s for IP %s", tier1GatewayName, translatedIp);
s_logger.error(msg);
throw new CloudRuntimeException(msg);
}
} }
} }
} }

View File

@ -26,6 +26,7 @@ import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand; import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand; import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand; import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
@ -172,4 +173,13 @@ public class NsxServiceImpl implements NsxService {
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId()); NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
return result.getResult(); return result.getResult();
} }
public boolean addFirewallRule(NsxNetworkRule netRule) {
CreateNsxDistributedFirewallRuleCommand command = new CreateNsxDistributedFirewallRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getCidrList(), netRule.getProtocol(),
netRule.getTrafficType(), netRule.getAclAction());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
return result.getResult();
}
} }

View File

@ -125,6 +125,10 @@ public class NsxControllerUtils {
return tier1GatewayName + "-VM" + vmId; return tier1GatewayName + "-VM" + vmId;
} }
public static String getFirewallRuleId(String segmentName, long ruleId) {
return segmentName + "-R" + ruleId;
}
public static String getLoadBalancerAlgorithm(String algorithm) { public static String getLoadBalancerAlgorithm(String algorithm) {
switch (algorithm) { switch (algorithm) {
case "leastconn": case "leastconn":

View File

@ -17,9 +17,12 @@
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.inject.Inject; 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.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao; import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ResponseObject.ResponseView;
@ -53,6 +56,8 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
public AccountManager _accountMgr; public AccountManager _accountMgr;
@Inject @Inject
private AnnotationDao annotationDao; private AnnotationDao annotationDao;
@Inject
private NsxProviderDao nsxProviderDao;
protected DataCenterJoinDaoImpl() { 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.setResourceDetails(ApiDBUtils.getResourceDetails(dataCenter.getId(), ResourceObjectType.Zone));
zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(), zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId()))); _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));

View File

@ -2648,7 +2648,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
zoneName = zone.getName(); 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"); 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 // checking the following params outside checkzoneparams method as we do
// not use these params for updatezone // not use these params for updatezone
// hence the method below is generic to check for common params // 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"); 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.setForTungsten(Objects.requireNonNullElse(forTungsten, false));
offeringFinal.setForNsx(Objects.requireNonNullElse(forNsx, false)); offeringFinal.setForNsx(Objects.requireNonNullElse(forNsx, false));
if (Boolean.TRUE.equals(forNsx)) {
offeringFinal.setNsxMode(mode);
}
if (enableOffering) { if (enableOffering) {
offeringFinal.setState(NetworkOffering.State.Enabled); offeringFinal.setState(NetworkOffering.State.Enabled);
@ -7717,7 +7720,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH, 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, 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, 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 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)) { if (!NetUtils.isValidIp4Cidr(guestVmCidr)) {
throw new InvalidParameterValueException("Invalid format of Guest VM CIDR."); 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. "); 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.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.network.nsx.NsxService; import com.cloud.network.nsx.NsxService;
import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.alert.AlertService; 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 // 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"); 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 // 2) Only Isolated networks with Source nat service enabled can be
// added to vpc // 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() throw new InvalidParameterValueException("Only network offerings of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName()
+ " are valid for vpc "); + " 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 * TODO This should have never been hardcoded like this in the first
* place if (guestNtwkOff.getRedundantRouter()) { throw new * place if (guestNtwkOff.getRedundantRouter()) { throw new
* InvalidParameterValueException * 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 // 4) Conserve mode should be off

View File

@ -1247,10 +1247,14 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
serviceProviderMap.put(Service.Dns, routerProvider); serviceProviderMap.put(Service.Dns, routerProvider);
serviceProviderMap.put(Service.UserData, routerProvider); serviceProviderMap.put(Service.UserData, routerProvider);
if (nsxMode == NetworkOffering.NsxMode.NATTED) { if (nsxMode == NetworkOffering.NsxMode.NATTED) {
serviceProviderMap.put(Service.SourceNat, Provider.Nsx);
serviceProviderMap.put(Service.StaticNat, Provider.Nsx); serviceProviderMap.put(Service.StaticNat, Provider.Nsx);
serviceProviderMap.put(Service.PortForwarding, Provider.Nsx); serviceProviderMap.put(Service.PortForwarding, Provider.Nsx);
serviceProviderMap.put(Service.Lb, Provider.Nsx); serviceProviderMap.put(Service.Lb, Provider.Nsx);
if (forVpc) {
serviceProviderMap.put(Service.NetworkACL, Provider.Nsx);
} else {
serviceProviderMap.put(Service.Firewall, Provider.Nsx);
}
} }
return serviceProviderMap; return serviceProviderMap;
} }