NSX: Add CKS Support & Firewall rules for Isolated Networks (#8189)

* NSX: Add ALL LB IP to the list of route advertisements in tier1

* NSX: Support Source NAT on NSX Isolated networks

* NSX: Cks Support

* NSX: Create segment group on segment creation

* Add unit tests

* Remove group for segment before removing segment

* Create Distributed Firewall rules

* Remove distributed firewall policy on segment deletion

* Fix policy rule ID and add more unit tests

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

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

* Add Firewall rules

* build failure - fix unit test

* fix npes

* Add support to delete firewall rules

* update nsx cks offering

* add license

* update order of ports in PF & FW rules

* fix filter for getting transport zones

* CKS support changed - MTU updated, etc

* add LB for CKS on VPC

* address comments

* adapt upstream cks logic for vpc

* rever mtu hack

* update UI changes as per upstream fix

* change display test for CKS n/w offerings for isolated and VPC tiers

* add extra line for linter

* address comment

* revert list change

---------

Co-authored-by: nvazquez <nicovazquez90@gmail.com>
This commit is contained in:
Pearl Dsilva 2023-12-07 14:43:56 -05:00 committed by GitHub
parent c42c6168bd
commit 389dbe895a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 403 additions and 141 deletions

View File

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

View File

@ -59,6 +59,7 @@ import static com.cloud.network.Network.Service.SourceNat;
import static com.cloud.network.Network.Service.PortForwarding;
import static com.cloud.network.Network.Service.NetworkACL;
import static com.cloud.network.Network.Service.UserData;
import static com.cloud.network.Network.Service.Firewall;
@APICommand(name = "createNetworkOffering", description = "Creates a network offering.", responseObject = NetworkOfferingResponse.class, since = "3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@ -251,7 +252,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
));
if (Boolean.TRUE.equals(forVpc)) {
services.add(NetworkACL.getName());
return services;
} else {
services.add(Firewall.getName());
}
return services;
}
@ -338,10 +340,15 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) {
String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
VirtualRouterProvider.Type.VirtualRouter.name();
List<String> unsupportedServices = List.of("Vpn", "SecurityGroup", "Connectivity",
"Gateway", "Firewall", "BaremetalPxeService");
List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "SecurityGroup", "Connectivity",
"Gateway", "BaremetalPxeService"));
List<String> routerSupported = List.of("Dhcp", "Dns", "UserData");
List<String> allServices = Service.listAllServices().stream().map(Service::getName).collect(Collectors.toList());
if (routerProvider.equals(VirtualRouterProvider.Type.VPCVirtualRouter.name())) {
unsupportedServices.add("Firewall");
} else {
unsupportedServices.add("NetworkACL");
}
for (String service : allServices) {
if (unsupportedServices.contains(service))
continue;

View File

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

View File

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

View File

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

View File

@ -58,4 +58,4 @@ FROM
LEFT JOIN
`cloud`.`vpc_offering_details` AS `offering_details` ON `offering_details`.`offering_id` = `vpc_offerings`.`id` AND `offering_details`.`name`='internetprotocol'
GROUP BY
`vpc_offerings`.`id`;
`vpc_offerings`.`id`;

View File

@ -184,6 +184,11 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
private static final Logger LOGGER = Logger.getLogger(KubernetesClusterManagerImpl.class);
private static final String DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNetworkOfferingforKubernetesService";
private static final String DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering used for CloudStack Kubernetes service";
private static final String DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNSXNetworkOfferingforKubernetesService";
private static final String DEFAULT_NSX_VPC_TIER_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNSXVPCNetworkOfferingforKubernetesService";
private static final String DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering for NSX CloudStack Kubernetes Service";
private static final String DEFAULT_NSX_VPC_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering for NSX CloudStack Kubernetes service on VPC";
protected StateMachine2<KubernetesCluster.State, KubernetesCluster.Event, KubernetesCluster> _stateMachine = KubernetesCluster.State.getStateMachine();
@ -1885,26 +1890,54 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
@Override
public boolean start() {
createNetworkOfferingForKubernetes(DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT, false, false);
createNetworkOfferingForKubernetes(DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT, true, false);
createNetworkOfferingForKubernetes(DEFAULT_NSX_VPC_TIER_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NSX_VPC_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT , true, true);
_gcExecutor.scheduleWithFixedDelay(new KubernetesClusterGarbageCollector(), 300, 300, TimeUnit.SECONDS);
_stateScanner.scheduleWithFixedDelay(new KubernetesClusterStatusScanner(), 300, 30, TimeUnit.SECONDS);
return true;
}
private void createNetworkOfferingForKubernetes(String offeringName, String offeringDesc, boolean forNsx, boolean forVpc) {
final Map<Network.Service, Network.Provider> defaultKubernetesServiceNetworkOfferingProviders = new HashMap<Service, Network.Provider>();
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dhcp, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dns, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.UserData, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Firewall, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Lb, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.SourceNat, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.PortForwarding, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
Network.Provider provider = forVpc ? Network.Provider.VPCVirtualRouter : Network.Provider.VirtualRouter;
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dhcp, provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dns, provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.UserData, provider);
if (forVpc) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.NetworkACL, forNsx ? Network.Provider.Nsx : provider);
} else {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Firewall, forNsx ? Network.Provider.Nsx : provider);
}
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Lb, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.SourceNat, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.PortForwarding, forNsx ? Network.Provider.Nsx : provider);
if (!forNsx) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
}
NetworkOfferingVO defaultKubernetesServiceNetworkOffering =
new NetworkOfferingVO(DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
"Network Offering used for CloudStack Kubernetes service", Networks.TrafficType.Guest,
new NetworkOfferingVO(offeringName,
offeringDesc, Networks.TrafficType.Guest,
false, false, null, null, true,
NetworkOffering.Availability.Required, null, Network.GuestType.Isolated, true,
true, false, false, false, false,
false, false, false, true, true, false,
false, true, false, false);
forVpc, true, false, false);
if (forNsx) {
defaultKubernetesServiceNetworkOffering.setNsxMode(NetworkOffering.NsxMode.NATTED.name());
defaultKubernetesServiceNetworkOffering.setForNsx(true);
}
defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true);
defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled);
defaultKubernetesServiceNetworkOffering = networkOfferingDao.persistDefaultNetworkOffering(defaultKubernetesServiceNetworkOffering);
@ -1916,11 +1949,6 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
networkOfferingServiceMapDao.persist(offService);
LOGGER.trace("Added service for the network offering: " + offService);
}
_gcExecutor.scheduleWithFixedDelay(new KubernetesClusterGarbageCollector(), 300, 300, TimeUnit.SECONDS);
_stateScanner.scheduleWithFixedDelay(new KubernetesClusterStatusScanner(), 300, 30, TimeUnit.SECONDS);
return true;
}
@Override

View File

@ -31,6 +31,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
@ -149,6 +151,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected VolumeApiService volumeService;
@Inject
protected VolumeDao volumeDao;
@Inject
protected NetworkOfferingDao networkOfferingDao;
protected String kubernetesClusterNodeNamePrefix;
@ -738,12 +742,24 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected void setupKubernetesClusterVpcTierRules(IpAddress publicIp, Network network, List<Long> clusterVMIds) throws ManagementServerException {
// Create ACL rules
createVpcTierAclRules(network);
// Add port forwarding for API access
try {
provisionPublicIpPortForwardingRule(publicIp, network, owner, clusterVMIds.get(0), CLUSTER_API_PORT, CLUSTER_API_PORT);
} catch (ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to activate API port forwarding rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
NetworkOffering offering = networkOfferingDao.findById(network.getNetworkOfferingId());
if (offering.isConserveMode()) {
// Add load balancing for API access
try {
provisionLoadBalancerRule(publicIp, network, owner, clusterVMIds, CLUSTER_API_PORT);
} catch (InsufficientAddressCapacityException e) {
throw new ManagementServerException(String.format("Failed to activate API load balancing rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
}
} else {
// Add port forwarding for API access
try {
provisionPublicIpPortForwardingRule(publicIp, network, owner, clusterVMIds.get(0), CLUSTER_API_PORT, CLUSTER_API_PORT);
} catch (ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to activate API port forwarding rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
}
}
// Add port forwarding rule for SSH access on each node VM
try {
provisionSshPortForwardingRules(publicIp, network, owner, clusterVMIds);

View File

@ -23,6 +23,7 @@ import java.util.List;
public class CreateNsxLoadBalancerRuleCommand extends NsxNetworkCommand {
private final String publicPort;
private final String privatePort;
private final String algorithm;
private final String protocol;
List<NsxLoadBalancerMember> memberList;
@ -31,11 +32,12 @@ public class CreateNsxLoadBalancerRuleCommand extends NsxNetworkCommand {
public CreateNsxLoadBalancerRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId,
String networkResourceName, boolean isResourceVpc,
List<NsxLoadBalancerMember> memberList, long lbId, String publicPort,
String algorithm, String protocol) {
String privatePort, String algorithm, String protocol) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc);
this.lbId = lbId;
this.memberList = memberList;
this.publicPort = publicPort;
this.privatePort = privatePort;
this.algorithm = algorithm;
this.protocol = protocol;
}
@ -49,6 +51,10 @@ public class CreateNsxLoadBalancerRuleCommand extends NsxNetworkCommand {
return publicPort;
}
public String getPrivatePort() {
return privatePort;
}
public List<NsxLoadBalancerMember> getMemberList() {
return memberList;
}

View File

@ -1,4 +1,3 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
@ -21,8 +20,8 @@ import org.apache.cloudstack.resource.NsxNetworkRule;
import java.util.List;
public class DeletedNsxDistributedFirewallRulesCommand extends CreateNsxDistributedFirewallRulesCommand {
public DeletedNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId, Long vpcId, long networkId, List<NsxNetworkRule> rules) {
public class DeleteNsxDistributedFirewallRulesCommand extends CreateNsxDistributedFirewallRulesCommand {
public DeleteNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId, Long vpcId, long networkId, List<NsxNetworkRule> rules) {
super(domainId, accountId, zoneId, vpcId, networkId, rules);
}
}
}

View File

@ -42,36 +42,14 @@ public class NsxNetworkRule {
private String algorithm;
private List<NsxLoadBalancerMember> memberList;
private NsxRuleAction aclAction;
private List<String> cidrList;
private String trafficType;
private List<String> sourceCidrList;
private List<String> destinationCidrList;
private Integer icmpCode;
private Integer icmpType;
private String trafficType;
private Network.Service service;
public Integer getIcmpCode() {
return icmpCode;
}
public void setIcmpCode(Integer icmpCode) {
this.icmpCode = icmpCode;
}
public Integer getIcmpType() {
return icmpType;
}
public void setIcmpType(Integer icmpType) {
this.icmpType = icmpType;
}
public Network.Service getService() {
return service;
}
public void setService(Network.Service service) {
this.service = service;
}
public long getDomainId() {
return domainId;
}
@ -200,12 +178,44 @@ public class NsxNetworkRule {
this.aclAction = aclAction;
}
public List<String> getCidrList() {
return cidrList;
public Network.Service getService() {
return service;
}
public void setCidrList(List<String> cidrList) {
this.cidrList = cidrList;
public void setService(Network.Service service) {
this.service = service;
}
public Integer getIcmpCode() {
return icmpCode;
}
public void setIcmpCode(Integer icmpCode) {
this.icmpCode = icmpCode;
}
public Integer getIcmpType() {
return icmpType;
}
public void setIcmpType(Integer icmpType) {
this.icmpType = icmpType;
}
public List<String> getSourceCidrList() {
return sourceCidrList;
}
public void setSourceCidrList(List<String> sourceCidrList) {
this.sourceCidrList = sourceCidrList;
}
public List<String> getDestinationCidrList() {
return destinationCidrList;
}
public void setDestinationCidrList(List<String> destinationCidrList) {
this.destinationCidrList = destinationCidrList;
}
public String getTrafficType() {
@ -234,7 +244,8 @@ public class NsxNetworkRule {
private String algorithm;
private List<NsxLoadBalancerMember> memberList;
private NsxRuleAction aclAction;
private List<String> cidrList;
private List<String> sourceCidrList;
private List<String> destinationidrList;
private String trafficType;
private Integer icmpType;
private Integer icmpCode;
@ -319,16 +330,12 @@ public class NsxNetworkRule {
return this;
}
public Builder setAclAction(NsxRuleAction 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;
@ -344,6 +351,16 @@ public class NsxNetworkRule {
return this;
}
public Builder setSourceCidrList(List<String> sourceCidrList) {
this.sourceCidrList = sourceCidrList;
return this;
}
public Builder setDestinationCidrList(List<String> destinationCidrList) {
this.destinationidrList = destinationCidrList;
return this;
}
public Builder setService(Network.Service service) {
this.service = service;
return this;
@ -367,11 +384,12 @@ public class NsxNetworkRule {
rule.setAlgorithm(this.algorithm);
rule.setMemberList(this.memberList);
rule.setAclAction(this.aclAction);
rule.setCidrList(this.cidrList);
rule.setTrafficType(this.trafficType);
rule.setIcmpType(this.icmpType);
rule.setIcmpCode(this.icmpCode);
rule.setService(this.service);
rule.setSourceCidrList(this.sourceCidrList);
rule.setDestinationCidrList(this.destinationidrList);
rule.setTrafficType(this.trafficType);
rule.setService(service);
return rule;
}
}

View File

@ -43,11 +43,11 @@ import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.DeletedNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.service.NsxApiClient;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.commons.collections.CollectionUtils;
@ -125,8 +125,8 @@ public class NsxResource implements ServerResource {
return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) {
return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeletedNsxDistributedFirewallRulesCommand) {
return executeRequest((DeletedNsxDistributedFirewallRulesCommand) cmd);
} else if (cmd instanceof DeleteNsxDistributedFirewallRulesCommand) {
return executeRequest((DeleteNsxDistributedFirewallRulesCommand) cmd);
} else if (cmd instanceof CreateNsxDistributedFirewallRulesCommand) {
return executeRequest((CreateNsxDistributedFirewallRulesCommand) cmd);
} else {
@ -474,7 +474,7 @@ public class NsxResource implements ServerResource {
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(DeletedNsxDistributedFirewallRulesCommand cmd) {
private NsxAnswer executeRequest(DeleteNsxDistributedFirewallRulesCommand cmd) {
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(),
cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
List<NsxNetworkRule> rules = cmd.getRules();

View File

@ -81,6 +81,7 @@ 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;
@ -146,6 +147,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
}
@ -358,7 +370,7 @@ public class NsxApiClient {
public TransportZoneListResult getTransportZones() {
try {
com.vmware.nsx.TransportZones transportZones = (com.vmware.nsx.TransportZones) nsxService.apply(com.vmware.nsx.TransportZones.class);
return transportZones.list(null, null, true, null, true, null, null, null, TransportType.OVERLAY.name(), null);
return transportZones.list(null, null, true, null, null, null, null, null, TransportType.OVERLAY.name(), null);
} catch (Exception e) {
throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage()));
}
@ -687,6 +699,7 @@ public class NsxApiClient {
}
}
private com.vmware.nsx_policy.model.Service getInfraService(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) {
Services service = (Services) nsxService.apply(Services.class);
String serviceName = getServiceName(ruleName, port, protocol, icmpType, icmpCode);
@ -816,7 +829,7 @@ public class NsxApiClient {
public void deleteDistributedFirewallRules(String segmentName, List<NsxNetworkRule> nsxRules) {
for(NsxNetworkRule rule : nsxRules) {
String ruleId = NsxControllerUtils.getNsxDistributedFirewallPolicyRuleId(segmentName, rule.getRuleId());
String svcName = getServiceName(ruleId, rule.getPrivatePort(), rule.getProtocol(), rule.getIcmpType(), rule.getIcmpCode());
String svcName = getServiceName(ruleId, rule.getPrivatePort(), rule.getProtocol(), rule.getIcmpType(), rule.getIcmpCode());
// delete rules
Rules rules = (Rules) nsxService.apply(Rules.class);
rules.delete(DEFAULT_DOMAIN, segmentName, ruleId);
@ -863,19 +876,21 @@ public class NsxApiClient {
protected List<String> getGroupsForTraffic(NsxNetworkRule rule,
String segmentName, boolean source) {
List<String> segmentGroup = List.of(String.format("%s/%s", GROUPS_PATH_PREFIX, segmentName));
List<String> ruleCidrList = rule.getCidrList();
List<String> sourceCidrList = rule.getSourceCidrList();
List<String> destCidrList = rule.getDestinationCidrList();
String trafficType = rule.getTrafficType();
if (trafficType.equalsIgnoreCase("ingress")) {
return source ? ruleCidrList : segmentGroup;
return source ? sourceCidrList : (rule.getService() == Network.Service.NetworkACL ? segmentGroup : destCidrList);
} else if (trafficType.equalsIgnoreCase("egress")) {
return source ? segmentGroup : ruleCidrList;
}
return source ? segmentGroup : (rule.getService() == Network.Service.NetworkACL ? sourceCidrList : destCidrList);
}
String err = String.format("Unsupported traffic type %s", trafficType);
LOGGER.error(err);
throw new CloudRuntimeException(err);
}
private List<Group> listNsxGroups() {
try {
Groups groups = (Groups) nsxService.apply(Groups.class);
@ -895,5 +910,4 @@ public class NsxApiClient {
return matchingGroup.map(Group::getPath).orElse(null);
}
}

View File

@ -54,6 +54,7 @@ import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.element.DhcpServiceProvider;
import com.cloud.network.element.DnsServiceProvider;
import com.cloud.network.element.FirewallServiceProvider;
import com.cloud.network.element.IpDeployer;
import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.element.NetworkACLServiceProvider;
@ -110,7 +111,7 @@ import java.util.function.LongFunction;
@Component
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
LoadBalancingServiceProvider, FirewallServiceProvider, ResourceStateAdapter, Listener {
@Inject
@ -526,7 +527,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
long zoneId = Objects.nonNull(vpc) ? vpc.getZoneId() : networkVO.getDataCenterId();
String publicPort = getPublicPortRange(rule);
String privatePort = getPrivatePortRange(rule);
String privatePort = getPrivatePFPortRange(rule);
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setDomainId(domainId)
@ -574,12 +575,18 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
}
private static String getPublicPortRange(PortForwardingRule rule) {
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
String.valueOf(rule.getSourcePortStart()) :
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
}
private static String getPrivatePFPortRange(PortForwardingRule rule) {
return rule.getDestinationPortStart() == rule.getDestinationPortEnd() ?
String.valueOf(rule.getDestinationPortStart()) :
String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
}
private static String getPrivatePortRange(PortForwardingRule rule) {
private static String getPrivatePortRange(FirewallRule rule) {
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
String.valueOf(rule.getSourcePortStart()) :
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
@ -620,6 +627,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
.setMemberList(lbMembers)
.setPublicIp(publicIp.getAddress().addr())
.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()))
.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()))
.setRuleId(loadBalancingRule.getId())
.setProtocol(loadBalancingRule.getProtocol().toUpperCase(Locale.ROOT))
.setAlgorithm(loadBalancingRule.getAlgorithm())
@ -672,10 +680,9 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
for (NetworkACLItem rule : rules) {
String privatePort = getPrivatePortRangeForACLRule(rule);
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setRuleId(rule.getId())
.setCidrList(transformCidrListValues(rule.getSourceCidrList()))
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
.setAclAction(transformActionValue(rule.getAction()))
.setTrafficType(rule.getTrafficType().toString())
.setProtocol(rule.getProtocol().toUpperCase())
@ -701,6 +708,44 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
return success && nsxService.addFirewallRules(network, nsxAddNetworkRules);
}
@Override
public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
if (!canHandle(network, Network.Service.Firewall)) {
return false;
}
List<NsxNetworkRule> nsxAddNetworkRules = new ArrayList<>();
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
for (FirewallRule rule : rules) {
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setRuleId(rule.getId())
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ?
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
.setDestinationCidrList(Objects.nonNull(rule.getDestinationCidrList()) ?
transformCidrListValues(rule.getDestinationCidrList()) : List.of("ANY"))
.setIcmpCode(rule.getIcmpCode())
.setIcmpType(rule.getIcmpType())
.setPrivatePort(getPrivatePortRange(rule))
.setTrafficType(rule.getTrafficType().toString())
.setService(Network.Service.Firewall)
.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
.build();
if (rule.getState() == FirewallRule.State.Add) {
nsxAddNetworkRules.add(networkRule);
} else if (rule.getState() == FirewallRule.State.Revoke) {
nsxDelNetworkRules.add(networkRule);
}
}
boolean success = true;
if (!nsxDelNetworkRules.isEmpty()) {
success = nsxService.deleteFirewallRules(network, nsxDelNetworkRules);
if (!success) {
LOGGER.warn("Not all firewall rules were successfully deleted");
}
}
return success && nsxService.addFirewallRules(network, nsxAddNetworkRules);
}
protected NsxNetworkRule.NsxRuleAction transformActionValue(NetworkACLItem.Action action) {
if (action == NetworkACLItem.Action.Allow) {
return NsxNetworkRule.NsxRuleAction.ALLOW;

View File

@ -28,15 +28,18 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Network;
import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.guru.GuestNetworkGuru;
import com.cloud.network.vpc.VpcVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
@ -50,6 +53,7 @@ import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.cloudstack.utils.NsxHelper;
@ -70,6 +74,10 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
AccountDao accountDao;
@Inject
DomainDao domainDao;
@Inject
NetworkModel networkModel;
@Inject
NetworkOfferingDao networkOfferingDao;
public NsxGuestNetworkGuru() {
super();
@ -80,8 +88,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
@ -218,6 +227,25 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
throw new CloudRuntimeException(msg);
}
if (isNull(network.getVpcId())) {
long domainId = domain.getId();
long accountId = account.getId();
long dataCenterId = zone.getId();
long resourceId = network.getId();
PublicIpAddress ipAddress = networkModel.getSourceNatIpAddressForGuestNetwork(account, network);
String translatedIp = ipAddress.getAddress().addr();
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, dataCenterId, resourceId, false);
LOGGER.debug(String.format("Creating NSX NAT Rule for Tier1 GW %s for translated IP %s for Isolated network %s", tier1GatewayName, translatedIp, network.getName()));
String natRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, dataCenterId, resourceId, false);
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 for Isolated network %s", tier1GatewayName, translatedIp, network.getName());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
}
// Create the DHCP relay config for the segment
String iPv4Address = nicProfile.getIPv4Address();
List<String> addresses = List.of(iPv4Address);
@ -289,7 +317,9 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
vpcName = vpc.getName();
} else {
LOGGER.debug(String.format("Creating a Tier 1 Gateway for the network %s before creating the NSX segment", networkVO.getName()));
CreateNsxTier1GatewayCommand nsxTier1GatewayCommand = NsxHelper.createNsxTier1GatewayCommand(domain, account, zone, networkVO.getId(), networkVO.getName(), false);
boolean isSourceNatSupported = networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(networkVO.getNetworkOfferingId(), Network.Service.SourceNat);
CreateNsxTier1GatewayCommand nsxTier1GatewayCommand = new CreateNsxTier1GatewayCommand(domain.getId(), account.getId(), zone.getId(), networkVO.getId(), networkVO.getName(), false, isSourceNatSupported);
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(nsxTier1GatewayCommand, zone.getId());
if (!nsxAnswer.getResult()) {
String msg = String.format("Could not create a Tier 1 Gateway for network %s: %s", networkVO.getName(), nsxAnswer.getDetails());

View File

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

View File

@ -32,11 +32,11 @@ import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.DeletedNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.cloudstack.utils.NsxHelper;
@ -161,7 +161,7 @@ public class NsxServiceImpl implements NsxService {
CreateNsxLoadBalancerRuleCommand command = new CreateNsxLoadBalancerRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getMemberList(), netRule.getRuleId(),
netRule.getPublicPort(), netRule.getAlgorithm(), netRule.getProtocol());
netRule.getPublicPort(), netRule.getPrivatePort(), netRule.getAlgorithm(), netRule.getProtocol());
command.setPublicIp(netRule.getPublicIp());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
return result.getResult();
@ -184,7 +184,7 @@ public class NsxServiceImpl implements NsxService {
}
public boolean deleteFirewallRules(Network network, List<NsxNetworkRule> netRules) {
DeletedNsxDistributedFirewallRulesCommand command = new DeletedNsxDistributedFirewallRulesCommand(network.getDomainId(),
DeleteNsxDistributedFirewallRulesCommand command = new DeleteNsxDistributedFirewallRulesCommand(network.getDomainId(),
network.getAccountId(), network.getDataCenterId(), network.getVpcId(), network.getId(), netRules);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, network.getDataCenterId());
return result.getResult();

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.service;
import com.cloud.network.Network;
import com.vmware.nsx_policy.infra.domains.Groups;
import com.vmware.nsx_policy.model.Group;
import com.vmware.nsx_policy.model.PathExpression;
@ -70,8 +71,9 @@ public class NsxApiClientTest {
@Test
public void testGetGroupsForTrafficIngress() {
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getTrafficType()).thenReturn("Ingress");
Mockito.when(rule.getService()).thenReturn(Network.Service.NetworkACL);
String segmentName = "segment";
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);
@ -82,8 +84,9 @@ public class NsxApiClientTest {
@Test
public void testGetGroupsForTrafficEgress() {
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getTrafficType()).thenReturn("Egress");
Mockito.when(rule.getService()).thenReturn(Network.Service.NetworkACL);
String segmentName = "segment";
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);

View File

@ -128,6 +128,7 @@ public class NsxGuestNetworkGuruTest {
when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated);
when(offering.getNsxMode()).thenReturn(NetworkOffering.NsxMode.NATTED.name());
when(offering.getId()).thenReturn(1L);
when(plan.getDataCenterId()).thenReturn(1L);

View File

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

View File

@ -2652,7 +2652,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
zoneName = zone.getName();
}
if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr, !AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Please enter a valid guest cidr");
}
@ -2821,7 +2821,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 && !NetUtils.validateGuestCidr(guestCidr, !AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Please enter a valid guest cidr");
}
@ -6580,6 +6580,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);
@ -7733,8 +7736,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH,
BYTES_MAX_READ_LENGTH, BYTES_MAX_WRITE_LENGTH, ADD_HOST_ON_SERVICE_RESTART_KVM, SET_HOST_DOWN_TO_MAINTENANCE, VM_SERVICE_OFFERING_MAX_CPU_CORES,
VM_SERVICE_OFFERING_MAX_RAM_SIZE, VM_USERDATA_MAX_LENGTH, MIGRATE_VM_ACROSS_CLUSTERS,
ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN, ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, ALLOW_DOMAIN_ADMINS_TO_CREATE_TAGGED_OFFERINGS
VM_SERVICE_OFFERING_MAX_RAM_SIZE, VM_USERDATA_MAX_LENGTH, MIGRATE_VM_ACROSS_CLUSTERS, ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN,
ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, ALLOW_DOMAIN_ADMINS_TO_CREATE_TAGGED_OFFERINGS, AllowNonRFC1918CompliantIPs
};
}

View File

@ -491,7 +491,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
@Override
public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
if (!offering.isConserveMode()) {
if (!offering.isConserveMode() && !offering.isForNsx()) {
for (PublicIpAddress ip : ipToServices.keySet()) {
Set<Service> services = new HashSet<Service>();
services.addAll(ipToServices.get(ip));
@ -1617,7 +1617,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
if (!canIpUsedForService(publicIp, service, networkId)) {
return false;
}
if (!offering.isConserveMode()) {
if (!offering.isConserveMode() && !offering.isForNsx()) {
return canIpUsedForNonConserveService(publicIp, service);
}
return true;

View File

@ -3132,7 +3132,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 (!NetUtils.validateGuestCidr(guestVmCidr, !ConfigurationManager.AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Invalid format of Guest VM CIDR. Make sure it is RFC1918 compliant. ");
}

View File

@ -41,6 +41,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;
@ -1158,8 +1159,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final boolean useDistributedRouter = vpcOff.isSupportsDistributedRouter();
final VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, owner.getId(), owner.getDomainId(), vpcOffId, cidr, networkDomain, useDistributedRouter, isRegionLevelVpcOff,
vpcOff.isRedundantRouter(), ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
vpc.setPublicMtu(publicMtu);
vpc.setDisplay(Boolean.TRUE.equals(displayVpc));
vpc.setPublicMtu(publicMtu);
vpc.setDisplay(Boolean.TRUE.equals(displayVpc));
return createVpc(displayVpc, vpc);
}
@ -1220,7 +1221,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
// cidr has to be RFC 1918 complient
if (!NetUtils.validateGuestCidr(cidr)) {
if (!NetUtils.validateGuestCidr(cidr, !ConfigurationManager.AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant");
}
@ -1889,7 +1890,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 ");
@ -1900,12 +1901,12 @@ 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
// 4) Conserve mode should be off in older versions ( < 4.19.0.0)
if (guestNtwkOff.isConserveMode()) {
throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC");
s_logger.info("Creating a network with conserve mode in VPC");
}
// 5) If Netscaler is LB provider make sure it is in dedicated mode

View File

@ -891,6 +891,7 @@
"label.forgedtransmits": "Forged transmits",
"label.format": "Format",
"label.fornsx": "NSX",
"label.forvpc": "VPC",
"label.free": "Free",
"label.french.azerty.keyboard": "French AZERTY keyboard",
"label.friday": "Friday",
@ -1409,7 +1410,7 @@
"label.not.suitable": "Not suitable",
"label.notifications": "Notifications",
"label.nsx": "NSX",
"label.nsx.mode": "NSX Mode",
"label.nsxmode": "NSX Mode",
"label.nsx.provider": "NSX Provider",
"label.nsx.provider.name": "NSX provider name",
"label.nsx.provider.hostname": "NSX provider hostname",
@ -2471,11 +2472,11 @@
"message.remove.ip.v6.firewall.rule.processing": "Removing IPv6 firewall rule...",
"message.remove.ip.v6.firewall.rule.success": "Removed IPv6 firewall rule",
"message.add.nsx.controller": "Add NSX Provider",
"message.add.network": "Add a new Network for zone: <b><span id=\"zone_name\"></span></b>",
"message.add.network.acl.failed": "Adding Network ACL list failed.",
"message.add.network.acl.processing": "Adding Network ACL list...",
"message.add.network.failed": "Adding Network failed.",
"message.add.network.processing": "Adding Network...",
"message.add.network": "Add a new network for zone: <b><span id=\"zone_name\"></span></b>",
"message.add.network.acl.failed": "Adding network ACL list failed.",
"message.add.network.acl.processing": "Adding network ACL list...",
"message.add.network.failed": "Adding network failed.",
"message.add.network.processing": "Adding network...",
"message.add.new.gateway.to.vpc": "Please specify the information to add a new gateway to this VPC.",
"message.add.physical.network.failed": "Adding physical network failed",
"message.add.physical.network.processing": "Adding a new physical network...",

View File

@ -114,15 +114,7 @@ export default {
handler (newItem, oldItem) {
if (newItem.id === oldItem.id) return
if (this.resource.associatednetworkid) {
api('listNetworks', { id: this.resource.associatednetworkid, listall: true }).then(response => {
if (response && response.listnetworksresponse && response.listnetworksresponse.network) {
this.networkService = response.listnetworksresponse.network[0]
} else {
this.networkService = {}
}
})
}
this.fetchData()
}
},
'$route.fullPath': function () {
@ -140,8 +132,20 @@ export default {
window.addEventListener('popstate', function () {
self.setActiveTab()
})
this.fetchData()
},
methods: {
fetchData () {
if (this.resource.associatednetworkid) {
api('listNetworks', { id: this.resource.associatednetworkid, listall: true }).then(response => {
if (response && response.listnetworksresponse && response.listnetworksresponse.network) {
this.networkService = response.listnetworksresponse.network[0]
} else {
this.networkService = {}
}
})
}
},
onTabChange (key) {
this.activeTab = key
const query = Object.assign({}, this.$route.query)

View File

@ -70,6 +70,16 @@ export default {
defaultTabs: [{
name: 'details',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
},
{
name: 'events',
resourceType: 'IpAddress',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/EventsTab.vue'))),
show: () => { return 'listEvents' in this.$store.getters.apis }
},
{
name: 'comments',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/AnnotationsTab.vue')))
}],
activeTab: ''
}
@ -134,19 +144,25 @@ export default {
}
if (this.resource && this.resource.vpcid) {
// VPC IPs don't have firewall
let tabs = this.$route.meta.tabs.filter(tab => tab.name !== 'firewall')
const tabs = this.$route.meta.tabs.filter(tab => tab.name !== 'firewall')
const network = await this.fetchNetwork()
if (network && network.networkofferingconservemode) {
this.tabs = tabs
return
}
this.portFWRuleCount = await this.fetchPortFWRule()
this.loadBalancerRuleCount = await this.fetchLoadBalancerRule()
// VPC IPs with PF only have PF
if (this.portFWRuleCount > 0) {
tabs = this.defaultTabs.concat(this.$route.meta.tabs.filter(tab => tab.name === 'portforwarding'))
tabs = tabs.filter(tab => tab.name !== 'loadbalancing')
}
// VPC IPs with LB rules only have LB
if (this.loadBalancerRuleCount > 0) {
tabs = this.defaultTabs.concat(this.$route.meta.tabs.filter(tab => tab.name === 'loadbalancing'))
tabs = tabs.filter(tab => tab.name !== 'portforwarding')
}
this.tabs = tabs
return
@ -171,6 +187,20 @@ export default {
fetchAction () {
this.actions = this.$route.meta.actions || []
},
fetchNetwork () {
return new Promise((resolve, reject) => {
api('listNetworks', {
listAll: true,
projectid: this.resource.projectid,
id: this.resource.associatednetworkid
}).then(json => {
const network = json.listnetworksresponse?.network?.[0] || null
resolve(network)
}).catch(e => {
reject(e)
})
})
},
fetchPortFWRule () {
return new Promise((resolve, reject) => {
api('listPortForwardingRules', {
@ -202,6 +232,7 @@ export default {
})
},
changeResource (resource) {
console.log(resource)
this.resource = resource
},
toggleLoading () {

View File

@ -131,7 +131,7 @@
</a-row>
<a-form-item name="nsxmode" ref="nsxmode" v-if="forNsx">
<template #label>
<tooltip-label :title="$t('label.nsx.mode')" :tooltip="apiParams.nsxmode.description"/>
<tooltip-label :title="$t('label.nsxmode')" :tooltip="apiParams.nsxmode.description"/>
</template>
<a-select
v-if="showMode"
@ -548,6 +548,7 @@ export default {
lbType: 'publicLb',
macLearningValue: '',
supportedServices: [],
supportedSvcs: [],
supportedServiceLoading: false,
isVirtualRouterForAtLeastOneService: false,
isVpcVirtualRouterForAtLeastOneService: false,
@ -841,17 +842,16 @@ export default {
}
})
setTimeout(() => {
self.supportedSvcs = self.supportedServices
self.supportedServices = supportedServices
self.supportedServiceLoading = false
}, 50)
} else {
supportedServices = this.supportedSvcs
supportedServices = supportedServices.filter(svc => {
return Object.keys(this.nsxSupportedServicesMap).includes(svc.name)
})
supportedServices.forEach(function (svc, index) {
svc.provider = [self.nsxSupportedServicesMap[svc.name]]
supportedServices[index] = svc
})
self.supportedSvcs = self.supportedServices
self.supportedServices = supportedServices
self.supportedServiceLoading = false
}
@ -863,19 +863,29 @@ export default {
Dhcp: this.forVpc ? this.VPCVR : this.VR,
Dns: this.forVpc ? this.VPCVR : this.VR,
UserData: this.forVpc ? this.VPCVR : this.VR,
SourceNat: this.NSX
SourceNat: this.NSX,
StaticNat: this.NSX,
PortForwarding: this.NSX,
Lb: this.NSX,
...(forVpc && { NetworkACL: this.NSX }),
...(!forVpc && { Firewall: this.NSX })
}
}
this.updateSupportedServices()
},
async handleForNsxChange (forNsx) {
handleForNsxChange (forNsx) {
this.forNsx = forNsx
this.showMode = forNsx
this.nsxSupportedServicesMap = {
Dhcp: this.forVpc ? this.VPCVR : this.VR,
Dns: this.forVpc ? this.VPCVR : this.VR,
UserData: this.forVpc ? this.VPCVR : this.VR,
SourceNat: this.NSX
SourceNat: this.NSX,
StaticNat: this.NSX,
PortForwarding: this.NSX,
Lb: this.NSX,
...(this.forVpc && { NetworkACL: this.NSX }),
...(!this.forVpc && { Firewall: this.NSX })
}
this.fetchSupportedServiceData()
},

View File

@ -1117,7 +1117,7 @@ public class NetUtils {
return false;
}
public static boolean validateGuestCidr(final String cidr) {
public static boolean validateGuestCidr(final String cidr, boolean checkCompliance) {
// RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the
// following three blocks of the IP address space for private internets:
// 10.0.0.0 - 10.255.255.255 (10/8 prefix)
@ -1134,6 +1134,9 @@ public class NetUtils {
return false;
}
if (!checkCompliance) {
return true;
}
for (String block: allowedNetBlocks) {
if (isNetworkAWithinNetworkB(cidr, block)) {
return true;
@ -1236,9 +1239,9 @@ public class NetUtils {
return true;
}
public static boolean validateGuestCidrList(final String guestCidrList) {
public static boolean validateGuestCidrList(final String guestCidrList, boolean checkCompliance) {
for (final String guestCidr : guestCidrList.split(",")) {
if (!validateGuestCidr(guestCidr)) {
if (!validateGuestCidr(guestCidr, checkCompliance)) {
return false;
}
}

View File

@ -354,10 +354,10 @@ public class NetUtilsTest {
final String[] invalidCidrs = {"172.33.1.0/16", "100.128.1.0/10"};
for (String cidr: validCidrs) {
assertTrue(NetUtils.validateGuestCidr(cidr));
assertTrue(NetUtils.validateGuestCidr(cidr, true));
}
for (String cidr: invalidCidrs) {
assertFalse(NetUtils.validateGuestCidr(cidr));
assertFalse(NetUtils.validateGuestCidr(cidr, true));
}
}