NSX: Add support to add firewall rule / Network ACL
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index 3a2b603..ee64caa 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -296,6 +296,7 @@
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";
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
index 4e8e665..5d31adb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -141,6 +141,10 @@
@Param(description = "The maximum value the MTU can have on the VR's public interfaces", since = "4.18.0")
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)
@Param(description = "the type of the zone - core or edge", since = "4.18.0")
String type;
@@ -368,4 +372,8 @@
public String getType() {
return type;
}
+
+ public void setNsxEnabled(boolean nsxEnabled) {
+ this.nsxEnabled = nsxEnabled;
+ }
}
diff --git a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
index 6fb7c4e..c975e8f 100644
--- a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
+++ b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
@@ -63,6 +63,9 @@
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
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 7a2c345..ec37788 100644
--- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -1736,7 +1736,7 @@
//apply network ACLs
// 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");
success = false;
}
@@ -2863,7 +2863,7 @@
// 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");
}
}
@@ -4720,7 +4720,9 @@
"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",
"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
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
index 56af161..8d5caee 100644
--- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
+++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
@@ -1900,10 +1900,10 @@
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 =
@@ -1914,6 +1914,9 @@
true, false, false, false, false,
false, false, false, true, true, false,
false, true, false, false);
+ if (forNsx) {
+ defaultKubernetesServiceNetworkOffering.setNsxMode(NetworkOffering.NsxMode.NATTED.name());
+ }
defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true);
defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled);
defaultKubernetesServiceNetworkOffering = networkOfferingDao.persistDefaultNetworkOffering(defaultKubernetesServiceNetworkOffering);
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDistributedFirewallRuleCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDistributedFirewallRuleCommand.java
new file mode 100644
index 0000000..35ce74b
--- /dev/null
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDistributedFirewallRuleCommand.java
@@ -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;
+ }
+}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java
index 5d830f1..a562b1b 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java
@@ -34,6 +34,9 @@
private String protocol;
private String algorithm;
private List<NsxLoadBalancerMember> memberList;
+ private String aclAction;
+ private List<String> cidrList;
+ private String trafficType;
public long getDomainId() {
return domainId;
@@ -155,6 +158,30 @@
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 {
private long domainId;
private long accountId;
@@ -172,6 +199,9 @@
private String protocol;
private String algorithm;
private List<NsxLoadBalancerMember> memberList;
+ private String aclAction;
+ private List<String> cidrList;
+ private String trafficType;
public Builder() {
}
@@ -252,6 +282,21 @@
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() {
NsxNetworkRule rule = new NsxNetworkRule();
rule.setDomainId(this.domainId);
@@ -269,6 +314,9 @@
rule.setRuleId(this.ruleId);
rule.setAlgorithm(this.algorithm);
rule.setMemberList(this.memberList);
+ rule.setAclAction(this.aclAction);
+ rule.setCidrList(this.cidrList);
+ rule.setTrafficType(this.trafficType);
return rule;
}
}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
index 7ca38bb..633b812 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
@@ -36,6 +36,7 @@
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.StartupNsxCommand;
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.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
@@ -123,6 +124,8 @@
return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) {
return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd);
+ } else if (cmd instanceof CreateNsxDistributedFirewallRuleCommand) {
+ return executeRequest((CreateNsxDistributedFirewallRuleCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
@@ -290,7 +293,7 @@
private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) {
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 {
nsxApiClient.createTier1Gateway(name, tier0Gateway, edgeCluster, sourceNatEnabled);
return new NsxAnswer(cmd, true, "");
@@ -454,6 +457,12 @@
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
public boolean start() {
return true;
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
index 3f4203c..baf463c 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
@@ -29,6 +29,7 @@
import com.vmware.nsx_policy.infra.Services;
import com.vmware.nsx_policy.infra.Sites;
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.tier_0s.LocaleServices;
import com.vmware.nsx_policy.infra.tier_1s.nat.NatRules;
@@ -46,6 +47,7 @@
import com.vmware.nsx_policy.model.LocaleServicesListResult;
import com.vmware.nsx_policy.model.PolicyNatRule;
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.SegmentSubnet;
import com.vmware.nsx_policy.model.ServiceListResult;
@@ -71,18 +73,13 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
-import static org.apache.cloudstack.utils.NsxControllerUtils.getServerPoolMemberName;
-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;
+import static org.apache.cloudstack.utils.NsxControllerUtils.*;
public class NsxApiClient {
@@ -133,6 +130,17 @@
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,
TIER1_LB_VIP, TIER1_LB_SNAT, TIER1_DNS_FORWARDER_IP, TIER1_IPSEC_LOCAL_ENDPOINT
}
@@ -699,6 +707,25 @@
}
}
+ 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) {
try {
Services service = (Services) nsxService.apply(Services.class);
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
index 031c445..394d82c 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
@@ -56,6 +56,7 @@
import com.cloud.network.element.DnsServiceProvider;
import com.cloud.network.element.IpDeployer;
import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.element.NetworkACLServiceProvider;
import com.cloud.network.element.PortForwardingServiceProvider;
import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.VpcProvider;
@@ -87,6 +88,7 @@
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.VMInstanceDao;
+import com.vmware.nsx_policy.infra.firewall.Rules;
import net.sf.ehcache.config.InvalidConfigurationException;
import org.apache.cloudstack.StartupNsxCommand;
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
@@ -107,7 +109,7 @@
@Component
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
- StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider,
+ StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
@@ -159,7 +161,14 @@
capabilities.put(Network.Service.Lb, null);
capabilities.put(Network.Service.PortForwarding, 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<>();
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
@@ -646,4 +655,16 @@
}
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;
+ }
}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java
index d507d91..31eedb5 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java
@@ -80,8 +80,9 @@
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
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxPublicNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxPublicNetworkGuru.java
index b9fcb53..14429ae 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxPublicNetworkGuru.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxPublicNetworkGuru.java
@@ -28,10 +28,13 @@
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 @@
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);
@@ -128,7 +135,7 @@
long dataCenterId = vpc.getZoneId();
boolean isForVpc = true;
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);
s_logger.info(String.format("Creating Tier 1 Gateway for VPC %s", vpc.getName()));
@@ -139,16 +146,27 @@
throw new CloudRuntimeException(msg);
}
- 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);
+ 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) {
+ 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);
+ }
}
}
}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java
index 6fe5285..f73910c 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java
@@ -26,6 +26,7 @@
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.utils.exception.CloudRuntimeException;
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.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
@@ -172,4 +173,13 @@
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
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();
+ }
}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java
index ce6e799..d7d4911 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java
+++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java
@@ -125,6 +125,10 @@
return tier1GatewayName + "-VM" + vmId;
}
+ public static String getFirewallRuleId(String segmentName, long ruleId) {
+ return segmentName + "-R" + ruleId;
+ }
+
public static String getLoadBalancerAlgorithm(String algorithm) {
switch (algorithm) {
case "leastconn":
diff --git a/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
index 50c5275..a90b40a 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
@@ -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 AccountManager _accountMgr;
@Inject
private AnnotationDao annotationDao;
+ @Inject
+ private NsxProviderDao nsxProviderDao;
protected DataCenterJoinDaoImpl() {
@@ -119,6 +124,11 @@
}
}
+ 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())));
diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 755a239..595a7a7 100644
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2648,7 +2648,7 @@
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 @@
// 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 @@
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);
@@ -7717,7 +7720,7 @@
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
+ ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN, ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, ALLOW_DOMAIN_ADMINS_TO_CREATE_TAGGED_OFFERINGS, AllowNonRFC1918CompliantIPs
};
}
diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
index e891d93..da5c318 100644
--- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -3125,7 +3125,7 @@
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. ");
}
diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
index de94663..7e46a4c 100644
--- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
@@ -40,6 +40,7 @@
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 @@
}
// 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 @@
// 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 @@
* 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
diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
index 69574b2..3490350 100644
--- a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
@@ -1247,10 +1247,14 @@
serviceProviderMap.put(Service.Dns, routerProvider);
serviceProviderMap.put(Service.UserData, routerProvider);
if (nsxMode == NetworkOffering.NsxMode.NATTED) {
- serviceProviderMap.put(Service.SourceNat, Provider.Nsx);
serviceProviderMap.put(Service.StaticNat, Provider.Nsx);
serviceProviderMap.put(Service.PortForwarding, 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;
}