This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch add-firewall-rule in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit b17c80e35ef07bdd6819abec85637df760ebcade Author: Pearl Dsilva <[email protected]> AuthorDate: Sun Nov 12 19:50:38 2023 -0500 NSX: Add support to add firewall rule / Network ACL --- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../cloudstack/api/response/ZoneResponse.java | 8 ++++ .../cloud/configuration/ConfigurationManager.java | 3 ++ .../engine/orchestration/NetworkOrchestrator.java | 8 ++-- .../cluster/KubernetesClusterManagerImpl.java | 5 ++- .../CreateNsxDistributedFirewallRuleCommand.java | 52 ++++++++++++++++++++++ .../apache/cloudstack/resource/NsxNetworkRule.java | 48 ++++++++++++++++++++ .../apache/cloudstack/resource/NsxResource.java | 11 ++++- .../apache/cloudstack/service/NsxApiClient.java | 41 ++++++++++++++--- .../org/apache/cloudstack/service/NsxElement.java | 25 ++++++++++- .../cloudstack/service/NsxGuestNetworkGuru.java | 5 ++- .../cloudstack/service/NsxPublicNetworkGuru.java | 40 ++++++++++++----- .../apache/cloudstack/service/NsxServiceImpl.java | 10 +++++ .../cloudstack/utils/NsxControllerUtils.java | 4 ++ .../cloud/api/query/dao/DataCenterJoinDaoImpl.java | 10 +++++ .../configuration/ConfigurationManagerImpl.java | 9 ++-- .../java/com/cloud/network/NetworkServiceImpl.java | 2 +- .../java/com/cloud/network/vpc/VpcManagerImpl.java | 7 +-- .../com/cloud/server/ConfigurationServerImpl.java | 6 ++- 19 files changed, 260 insertions(+), 35 deletions(-) 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 3a2b6037602..ee64caabed0 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 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"; 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 4e8e665836c..5d31adb1e14 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 @@ 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") 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 class ZoneResponse extends BaseResponseWithAnnotations implements SetReso 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 6fb7c4e0d0a..c975e8f351f 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 @@ 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 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 7a2c3456376..ec37788618a 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 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra //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 @@ 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"); } } @@ -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); 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 56af161b4d7..8d5caeecced 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 @@ 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 = @@ -1914,6 +1914,9 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne 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 00000000000..35ce74be49c --- /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 5d830f1347a..a562b1bd3ea 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 @@ public class NsxNetworkRule { 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 @@ public class NsxNetworkRule { 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 @@ public class NsxNetworkRule { 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 @@ public class NsxNetworkRule { 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 @@ public class NsxNetworkRule { 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 7ca38bb748c..633b812a623 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 com.vmware.nsx_policy.model.SiteListResult; 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 @@ public class NsxResource implements ServerResource { 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 @@ public class NsxResource implements ServerResource { 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 @@ public class NsxResource implements ServerResource { 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 3f4203c37ea..baf463c1847 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.Segments; 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.LBVirtualServerListResult; 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 org.apache.log4j.Logger; 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 @@ public class NsxApiClient { 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 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) { 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 031c445e074..394d82c0e0e 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.DhcpServiceProvider; 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.ReservationContext; 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 @@ import java.util.function.LongFunction; @Component public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider, - StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, + StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider, 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.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 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns } 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 d507d9199a7..31eedb5ccbe 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 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 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 b9fcb53883a..14429ae86ae 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.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); @@ -128,7 +135,7 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru { 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 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru { 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 6fe5285231c..f73910c15bf 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.VpcVO; 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 @@ public class NsxServiceImpl implements NsxService { 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 ce6e7992533..d7d49113e9b 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 @@ public class NsxControllerUtils { 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 50c5275390e..a90b40a2908 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 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()))); diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 755a239221b..595a7a70034 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 @@ 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); @@ -7717,7 +7720,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati 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 e891d932437..da5c31891d4 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 @@ 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. "); } 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 de946634fe4..7e46a4c1ed0 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.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 diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java index 69574b29ff7..3490350444e 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 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio 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; }
