This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch netris-integration-upstream in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 2ae0703ae529a15dcb8d3c97fc1c61545f0d7f28 Author: Pearl Dsilva <[email protected]> AuthorDate: Thu Nov 28 10:33:01 2024 -0500 Add support to create Netris VPC / Network offerings (#22) * Add support to create Netris VPC / Network offerings * fix support services for netris provider type --- .../admin/network/CreateNetworkOfferingCmd.java | 41 ++++-- .../command/admin/vpc/CreateVPCOfferingCmd.java | 31 +++-- .../cloud/configuration/ConfigurationManager.java | 3 +- .../configuration/ConfigurationManagerImpl.java | 17 +-- .../java/com/cloud/network/vpc/VpcManagerImpl.java | 3 +- .../cloud/vpc/MockConfigurationManagerImpl.java | 2 +- .../networkoffering/CreateNetworkOfferingTest.java | 20 +-- ui/src/components/CheckBoxSelectPair.vue | 8 +- ui/src/views/offering/AddNetworkOffering.vue | 140 +++++++++++++++------ ui/src/views/offering/AddVpcOffering.vue | 93 ++++++++++++-- 10 files changed, 263 insertions(+), 95 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index af3db374a7c..362e9c8b3bb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.admin.network; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -140,12 +141,19 @@ public class CreateNetworkOfferingCmd extends BaseCmd { description = "true if network offering is meant to be used for VPC, false otherwise.") private Boolean forVpc; + @Deprecated @Parameter(name = ApiConstants.FOR_NSX, type = CommandType.BOOLEAN, description = "true if network offering is meant to be used for NSX, false otherwise.", since = "4.20.0") private Boolean forNsx; + @Parameter(name = ApiConstants.PROVIDER, + type = CommandType.STRING, + description = "Name of the provider providing the service", + since = "4.20.0") + private String provider; + @Parameter(name = ApiConstants.NSX_SUPPORT_LB, type = CommandType.BOOLEAN, description = "true if network offering for NSX network offering supports Load balancer service.", @@ -257,8 +265,25 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return serviceOfferingId; } + public boolean isExternalNetworkProvider() { + return Arrays.asList("NSX", "Netris").stream() + .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider)); + } + + public boolean isForNsx() { + return provider != null && provider.equalsIgnoreCase("NSX"); + } + + public boolean isForNetris() { + return provider != null && provider.equalsIgnoreCase("Netris"); + } + + public String getProvider() { + return provider; + } + public List<String> getSupportedServices() { - if (!isForNsx()) { + if (!isExternalNetworkProvider()) { return supportedServices == null ? new ArrayList<String>() : supportedServices; } else { List<String> services = new ArrayList<>(List.of( @@ -308,10 +333,6 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return forVpc; } - public boolean isForNsx() { - return BooleanUtils.isTrue(forNsx); - } - public String getNetworkMode() { return networkMode; } @@ -345,7 +366,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd { public Map<String, List<String>> getServiceProviders() { Map<String, List<String>> serviceProviderMap = new HashMap<>(); - if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) { + if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) { Collection servicesCollection = serviceProviderList.values(); Iterator iter = servicesCollection.iterator(); while (iter.hasNext()) { @@ -361,13 +382,13 @@ public class CreateNetworkOfferingCmd extends BaseCmd { providerList.add(provider); serviceProviderMap.put(service, providerList); } - } else if (Boolean.TRUE.equals(forNsx)) { - getServiceProviderMapForNsx(serviceProviderMap); + } else if (isExternalNetworkProvider()) { + getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName()); } return serviceProviderMap; } - private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) { + private void getServiceProviderMapForExternalProvider(Map<String, List<String>> serviceProviderMap, String provider) { String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() : VirtualRouterProvider.Type.VirtualRouter.name(); List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "SecurityGroup", "Connectivity", @@ -385,7 +406,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd { if (routerSupported.contains(service)) serviceProviderMap.put(service, List.of(routerProvider)); else - serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName())); + serviceProviderMap.put(service, List.of(provider)); if (!getNsxSupportsLbService()) { serviceProviderMap.remove(Lb.getName()); } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java index 73b4f5df196..020e28e23f4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.admin.vpc; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -112,12 +113,19 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { since = "4.13") private List<Long> zoneIds; + @Deprecated @Parameter(name = ApiConstants.FOR_NSX, type = CommandType.BOOLEAN, description = "true if network offering is meant to be used for NSX, false otherwise.", since = "4.20.0") private Boolean forNsx; + @Parameter(name = ApiConstants.PROVIDER, + type = CommandType.STRING, + description = "Name of the provider providing the service", + since = "4.20.0") + private String provider; + @Parameter(name = ApiConstants.NSX_SUPPORT_LB, type = CommandType.BOOLEAN, description = "true if network offering for NSX VPC offering supports Load balancer service.", @@ -158,11 +166,16 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { return StringUtils.isEmpty(displayText) ? vpcOfferingName : displayText; } + public boolean isExternalNetworkProvider() { + return Arrays.asList("NSX", "Netris").stream() + .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider)); + } + public List<String> getSupportedServices() { - if (!isForNsx() && CollectionUtils.isEmpty(supportedServices)) { + if (!isExternalNetworkProvider() && CollectionUtils.isEmpty(supportedServices)) { throw new InvalidParameterValueException("Supported services needs to be provided"); } - if (isForNsx()) { + if (isExternalNetworkProvider()) { supportedServices = new ArrayList<>(List.of( Dhcp.getName(), Dns.getName(), @@ -179,8 +192,8 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { return supportedServices; } - public boolean isForNsx() { - return BooleanUtils.isTrue(forNsx); + public String getProvider() { + return provider; } public String getNetworkMode() { @@ -193,7 +206,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { public Map<String, List<String>> getServiceProviders() { Map<String, List<String>> serviceProviderMap = new HashMap<>(); - if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) { + if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) { Collection<? extends Map<String, String>> servicesCollection = serviceProviderList.values(); Iterator<? extends Map<String, String>> iter = servicesCollection.iterator(); while (iter.hasNext()) { @@ -213,14 +226,14 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { providerList.add(provider); serviceProviderMap.put(service, providerList); } - } else if (Boolean.TRUE.equals(forNsx)) { - getServiceProviderMapForNsx(serviceProviderMap); + } else if (isExternalNetworkProvider()) { + getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName()); } return serviceProviderMap; } - private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) { + private void getServiceProviderMapForExternalProvider(Map<String, List<String>> serviceProviderMap, String provider) { List<String> unsupportedServices = List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity", "Gateway", "Firewall"); List<String> routerSupported = List.of("Dhcp", "Dns", "UserData"); @@ -231,7 +244,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { if (routerSupported.contains(service)) serviceProviderMap.put(service, List.of(VirtualRouterProvider.Type.VPCVirtualRouter.name())); else - serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName())); + serviceProviderMap.put(service, List.of(provider)); } if (!getNsxSupportsLbService()) { serviceProviderMap.remove(Lb.getName()); 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 c982ff41f6f..ad8b34eb6ce 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 @@ -214,6 +214,7 @@ public interface ConfigurationManager { * @param forVpc * @param forTungsten * @param forNsx + * @param forNetris * @param domainIds * @param zoneIds * @return network offering object @@ -223,7 +224,7 @@ public interface ConfigurationManager { Integer networkRate, Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, boolean forNsx, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol, + Boolean forTungsten, boolean forNsx, boolean forNetris, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol, NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP, diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 9a47e567126..17c2385cdaa 100644 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -6228,7 +6228,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Map<String, String> detailsStr = cmd.getDetails(); final Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy(); Boolean forVpc = cmd.getForVpc(); - Boolean forNsx = cmd.isForNsx(); + boolean forNsx = cmd.isForNsx(); + boolean forNetris = cmd.isForNetris(); Boolean forTungsten = cmd.getForTungsten(); String networkModeStr = cmd.getNetworkMode(); boolean nsxSupportInternalLbSvc = cmd.getNsxSupportsInternalLbService(); @@ -6267,8 +6268,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - if (Boolean.TRUE.equals(forNsx) && Boolean.TRUE.equals(forTungsten)) { - throw new InvalidParameterValueException("Network Offering cannot be for both Tungsten-Fabric and NSX"); + if ((Boolean.TRUE.equals(forTungsten) ? 1 : 0) + (forNetris ? 1 : 0) + (forNsx ? 1 : 0) > 1) { + throw new InvalidParameterValueException("Network Offering cannot be for multiple providers - Tungsten-Fabric, NSX and Netris"); } NetworkOffering.NetworkMode networkMode = null; @@ -6481,7 +6482,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // offering final Map<Capability, String> sourceNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.SourceNat); if (!serviceProviderMap.containsKey(Service.SourceNat) && sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) { - throw new InvalidParameterValueException("Capabilities for source NAT service can be specifed only when source NAT service is enabled for network offering."); + throw new InvalidParameterValueException("Capabilities for source NAT service can be specified only when source NAT service is enabled for network offering."); } validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap); @@ -6489,7 +6490,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // offering final Map<Capability, String> staticNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.StaticNat); if (!serviceProviderMap.containsKey(Service.StaticNat) && sourceNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) { - throw new InvalidParameterValueException("Capabilities for static NAT service can be specifed only when static NAT service is enabled for network offering."); + throw new InvalidParameterValueException("Capabilities for static NAT service can be specified only when static NAT service is enabled for network offering."); } validateStaticNatServiceCapablities(staticNatServiceCapabilityMap); @@ -6550,7 +6551,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } final NetworkOfferingVO offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, - serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, forTungsten, forNsx, networkMode, domainIds, zoneIds, enable, internetProtocol, routingMode, specifyAsNumber); + serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, forTungsten, forNsx, forNetris, networkMode, domainIds, zoneIds, enable, internetProtocol, routingMode, specifyAsNumber); if (Boolean.TRUE.equals(forNsx) && nsxSupportInternalLbSvc) { offering.setInternalLb(true); offering.setPublicLb(false); @@ -6717,7 +6718,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Long serviceOfferingId, final boolean conserveMode, final Map<Service, Map<Capability, String>> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent, final Map<Detail, String> details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, boolean forNsx, NetworkOffering.NetworkMode networkMode, final List<Long> domainIds, final List<Long> zoneIds, final boolean enableOffering, final NetUtils.InternetProtocol internetProtocol, + Boolean forTungsten, boolean forNsx, boolean forNetris, NetworkOffering.NetworkMode networkMode, final List<Long> domainIds, final List<Long> zoneIds, final boolean enableOffering, final NetUtils.InternetProtocol internetProtocol, final NetworkOffering.RoutingMode routingMode, final boolean specifyAsNumber) { String servicePackageUuid; @@ -7014,7 +7015,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati logger.trace("Added service for the network offering: " + offService + " with provider " + provider.getName()); } - if (vpcOff && !forNsx) { + if (vpcOff && !forNsx && !forNetris) { final List<Service> supportedSvcs = new ArrayList<Service>(); supportedSvcs.addAll(serviceProviderMap.keySet()); _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs); 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 39fbe9bb0fe..64abcff84ef 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -511,7 +511,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis final Long serviceOfferingId = cmd.getServiceOfferingId(); final List<Long> domainIds = cmd.getDomainIds(); final List<Long> zoneIds = cmd.getZoneIds(); - final Boolean forNsx = cmd.isForNsx(); + final String provider = cmd.getProvider(); + final Boolean forNsx = Objects.nonNull(provider) && provider.equalsIgnoreCase("NSX"); final String networkModeStr = cmd.getNetworkMode(); final boolean enable = cmd.getEnable(); diff --git a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java index fe058b0a402..ddcac5f31fb 100644 --- a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -547,7 +547,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu Integer networkRate, Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, boolean forNsx, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, NetUtils.InternetProtocol internetProtocol, + Boolean forTungsten, boolean forNsx, boolean forNetris, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, NetUtils.InternetProtocol internetProtocol, NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber) { // TODO Auto-generated method stub return null; diff --git a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index 403b14965b1..1f1dcef50a2 100644 --- a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -131,7 +131,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithVlan() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + null, false, null, true, false, null, false, null, true, false, false, false, false,null,null, null, false, null, null, false); assertNotNull("Shared network offering with specifyVlan=true failed to create ", off); } @@ -139,7 +139,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithNoVlan() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, false, Availability.Optional, 200, null, false, Network.GuestType.Shared, - false, null, false, null, true, false, null, false, null, true, false, false, false, null, null,null, false, null, null, false); + false, null, false, null, true, false, null, false, null, true, false, false, false, false,null, null,null, false, null, null, false); assertNotNull("Shared network offering with specifyVlan=false was created", off); } @@ -147,7 +147,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithSpecifyIpRanges() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + null, false, null, true, false, null, false, null, true, false, false, false, false,null,null, null, false, null, null, false); assertNotNull("Shared network offering with specifyIpRanges=true failed to create ", off); } @@ -156,7 +156,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithoutSpecifyIpRanges() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, - false, null, false, null, false, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + false, null, false, null, false, false, null, false, null, true, false, false, false,false, null,null, null, false, null, null, false); assertNull("Shared network offering with specifyIpRanges=false was created", off); } @@ -169,7 +169,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null, null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, false,null, null, null, false, null, null, false); assertNotNull("Isolated network offering with specifyIpRanges=false failed to create ", off); } @@ -182,7 +182,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, false,null,null, null, false, null, null, false); assertNotNull("Isolated network offering with specifyVlan=true wasn't created", off); } @@ -195,7 +195,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, false,null,null, null, false, null, null, false); assertNull("Isolated network offering with specifyIpRanges=true and source nat service enabled, was created", off); } @@ -206,7 +206,7 @@ public class CreateNetworkOfferingTest extends TestCase { Set<Network.Provider> vrProvider = new HashSet<Network.Provider>(); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, false,null,null, null, false, null, null, false); assertNotNull("Isolated network offering with specifyIpRanges=true and with no sourceNatService, failed to create", off); } @@ -224,7 +224,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.Lb, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null, false, null, null, false); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc provider ", off); } @@ -244,7 +244,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.Lb, lbProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, false, null, null, false); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null, false, null, null, false); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc and Netscaler provider ", off); } diff --git a/ui/src/components/CheckBoxSelectPair.vue b/ui/src/components/CheckBoxSelectPair.vue index 4fba1da2556..480e515be29 100644 --- a/ui/src/components/CheckBoxSelectPair.vue +++ b/ui/src/components/CheckBoxSelectPair.vue @@ -21,7 +21,7 @@ <a-col :md="24" :lg="layout === 'horizontal' ? 10 : 24"> <a-checkbox :checked="checked" - :disabled="forNsx" + :disabled="forExternalNetProvider" @change="handleCheckChange"> {{ checkBoxLabel }} </a-checkbox> @@ -32,7 +32,7 @@ :label="selectLabel"> <a-select v-model:value="selected" - :disabled="forNsx" + :disabled="forExternalNetProvider" showSearch optionFilterProp="label" :filterOption="(input, option) => { @@ -86,7 +86,7 @@ export default { type: Boolean, default: false }, - forNsx: { + forExternalNetProvider: { type: Boolean, default: false } @@ -123,7 +123,7 @@ export default { return this.option || this.selectedOption }, option () { - if (this.forNsx) { + if (this.forExternalNetProvider) { return this.selectOptions[0]?.name || null } return null diff --git a/ui/src/views/offering/AddNetworkOffering.vue b/ui/src/views/offering/AddNetworkOffering.vue index 2ee2f61cf0d..47ce0ce9366 100644 --- a/ui/src/views/offering/AddNetworkOffering.vue +++ b/ui/src/views/offering/AddNetworkOffering.vue @@ -41,7 +41,7 @@ v-model:value="form.displaytext" :placeholder="apiParams.displaytext.description"/> </a-form-item> - <a-form-item name="networkrate" ref="networkrate" v-if="!forNsx"> + <a-form-item name="networkrate" ref="networkrate" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <template #label> <tooltip-label :title="$t('label.networkrate')" :tooltip="apiParams.networkrate.description"/> </template> @@ -60,10 +60,10 @@ <a-radio-button value="isolated"> {{ $t('label.isolated') }} </a-radio-button> - <a-radio-button value="l2" v-if="!forNsx"> + <a-radio-button value="l2" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> {{ $t('label.l2') }} </a-radio-button> - <a-radio-button value="shared" v-if="!forNsx"> + <a-radio-button value="shared" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> {{ $t('label.shared') }} </a-radio-button> </a-radio-group> @@ -93,7 +93,7 @@ </a-radio-button> </a-radio-group> </a-form-item> - <a-row :gutter="12" v-if="!forNsx"> + <a-row :gutter="12" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <a-col :md="12" :lg="12"> <a-form-item name="specifyvlan" ref="specifyvlan"> <template #label> @@ -117,19 +117,31 @@ <template #label> <tooltip-label :title="$t('label.vpc')" :tooltip="apiParams.forvpc.description"/> </template> - <a-switch v-model:checked="form.forvpc" @change="val => { handleForVpcChange(val) }" /> + <a-switch v-model:checked="form.forvpc" @change="handleForVpcChange" /> </a-form-item> </a-col> <a-col :md="12" :lg="12"> - <a-form-item name="fornsx" ref="fornsx" v-if="guestType === 'isolated'"> + <a-form-item name="provider" ref="provider"> <template #label> - <tooltip-label :title="$t('label.nsx')" :tooltip="apiParams.fornsx.description"/> + <tooltip-label :title="$t('label.provider')" :tooltip="apiParams.provider.description"/> </template> - <a-switch v-model:checked="form.fornsx" @change="val => { handleForNsxChange(val) }" /> + <a-select + v-model:value="form.provider" + v-focus="true" + @change="handleProviderChange" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :placeholder="apiParams.provider.description" > + <a-select-option :value="'NSX'" :label="$t('label.nsx')"> {{ $t('label.nsx') }} </a-select-option> + <a-select-option :value="'Netris'" :label="$t('label.netris')"> {{ $t('label.netris') }} </a-select-option> + </a-select> </a-form-item> </a-col> </a-row> - <a-row :gutter="12" v-if="forNsx"> + <a-row :gutter="12" v-if="form.provider === 'NSX'"> <a-col :md="12" :lg="12"> <a-form-item name="nsxsupportlb" ref="nsxsupportlb" v-if="guestType === 'isolated'"> <template #label> @@ -180,7 +192,7 @@ </a-radio-button> </a-radio-group> </a-form-item> - <a-row :gutter="12" v-if="routingMode === 'dynamic' && !forVpc && forNsx"> + <a-row :gutter="12" v-if="routingMode === 'dynamic' && !forVpc && form.provider === 'NSX'"> <a-col :md="12" :lg="12"> <a-form-item name="specifyasnumber" ref="specifyasnumber"> <template #label> @@ -195,7 +207,7 @@ </a-form-item> <a-row :gutter="12"> <a-col :md="12" :lg="12"> - <a-form-item name="promiscuousmode" ref="promiscuousmode" v-if="!forNsx"> + <a-form-item name="promiscuousmode" ref="promiscuousmode" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <template #label> <tooltip-label :title="$t('label.promiscuousmode')" :tooltip="$t('message.network.offering.promiscuous.mode')"/> </template> @@ -213,7 +225,7 @@ </a-radio-button> </a-radio-group> </a-form-item> - <a-form-item name="macaddresschanges" ref="macaddresschanges" v-if="!forNsx"> + <a-form-item name="macaddresschanges" ref="macaddresschanges" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <template #label> <tooltip-label :title="$t('label.macaddresschanges')" :tooltip="$t('message.network.offering.mac.address.changes')"/> </template> @@ -233,7 +245,7 @@ </a-form-item> </a-col> <a-col :md="12" :lg="12"> - <a-form-item name="forgedtransmits" ref="forgedtransmits" v-if="!forNsx"> + <a-form-item name="forgedtransmits" ref="forgedtransmits" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <template #label> <tooltip-label :title="$t('label.forgedtransmits')" :tooltip="$t('message.network.offering.forged.transmits')"/> </template> @@ -251,7 +263,7 @@ </a-radio-button> </a-radio-group> </a-form-item> - <a-form-item name="maclearning" ref="maclearning" v-if="!forNsx"> + <a-form-item name="maclearning" ref="maclearning" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> <template #label> <tooltip-label :title="$t('label.maclearning')" :tooltip="$t('message.network.offering.mac.learning')"/> </template> @@ -290,8 +302,8 @@ <CheckBoxSelectPair :resourceKey="item.name" :checkBoxLabel="item.description" - :forNsx="forNsx" - :defaultCheckBoxValue="forNsx" + :forExternalNetProvider="form.provider === 'NSX' || form.provider === 'Netris'" + :defaultCheckBoxValue="form.provider === 'NSX' || form.provider === 'Netris'" :selectOptions="!supportedServiceLoading ? item.provider: []" @handle-checkselectpair-change="handleSupportedServiceChange"/> </a-list-item> @@ -452,7 +464,8 @@ <a-form-item name="conservemode" ref="conservemode" - v-if="(guestType === 'shared' || guestType === 'isolated') && !forNsx && networkmode !== 'ROUTED'"> + v-if="(guestType === 'shared' || guestType === 'isolated') && !isVpcVirtualRouterForAtLeastOneService && + (form.provider !== 'NSX' && form.provider !== 'Netris') && networkmode !== 'ROUTED'"> <template #label> <tooltip-label :title="$t('label.conservemode')" :tooltip="apiParams.conservemode.description"/> </template> @@ -587,7 +600,7 @@ export default { selectedDomains: [], selectedZones: [], forVpc: false, - forNsx: false, + provider: '', lbType: 'publicLb', macLearningValue: '', supportedServices: [], @@ -644,7 +657,13 @@ export default { description: 'Nsx', enabled: true }, - nsxSupportedServicesMap: {} + Netris: { + name: 'Netris', + description: 'Netris', + enabled: true + }, + nsxSupportedServicesMap: {}, + netrisSupportedServicesMap: {} } }, beforeCreate () { @@ -883,7 +902,7 @@ export default { this.supportedServiceLoading = true var supportedServices = this.supportedServices var self = this - if (!this.forNsx) { + if (this.provider !== 'NSX' && this.provider !== 'Netris') { if (this.networkmode === 'ROUTED' && this.guestType === 'isolated') { supportedServices = supportedServices.filter(service => { return !['SourceNat', 'StaticNat', 'Lb', 'PortForwarding', 'Vpn'].includes(service.name) @@ -900,7 +919,7 @@ export default { } provider.enabled = enabledProviders.includes(provider.name) } else { // *** non-vpc *** - provider.enabled = !['InternalLbVm', 'VpcVirtualRouter', 'Nsx'].includes(provider.name) + provider.enabled = !['InternalLbVm', 'VpcVirtualRouter', 'Nsx', 'Netris'].includes(provider.name) } providers[providerIndex] = provider }) @@ -916,11 +935,25 @@ export default { } else { supportedServices = this.supportedSvcs supportedServices = supportedServices.filter(svc => { - return Object.keys(this.nsxSupportedServicesMap).includes(svc.name) + if (this.provider === 'NSX') { + return Object.keys(this.nsxSupportedServicesMap).includes(svc.name) + } else if (this.provider === 'Netris') { + return Object.keys(this.netrisSupportedServicesMap).includes(svc.name) + } }) supportedServices = supportedServices.map(svc => { if (!['Dhcp', 'Dns', 'UserData'].includes(svc.name)) { - svc.provider = [this.NSX] + if (this.provider === 'NSX') { + svc.provider = [this.NSX] + } else if (this.provider === 'Netris') { + svc.provider = [this.Netris] + } + } else { + if (this.forVpc) { + svc.provider = [this.VPCVR] + } else { + svc.provider = [this.VR] + } } return svc }) @@ -931,7 +964,7 @@ export default { }, handleForVpcChange (forVpc) { this.forVpc = forVpc - if (this.forNsx) { + if (this.provider === 'NSX') { this.nsxSupportedServicesMap = { Dhcp: this.forVpc ? this.VPCVR : this.VR, Dns: this.forVpc ? this.VPCVR : this.VR, @@ -943,21 +976,47 @@ export default { ...(forVpc && { NetworkACL: this.NSX }), ...(!forVpc && { Firewall: this.NSX }) } + } else if (this.provider === 'Netris') { + this.netrisSupportedServicesMap = { + Dhcp: this.forVpc ? this.VPCVR : this.VR, + Dns: this.forVpc ? this.VPCVR : this.VR, + UserData: this.forVpc ? this.VPCVR : this.VR, + SourceNat: this.Netris, + StaticNat: this.Netris, + PortForwarding: this.Netris, + Lb: this.Netris, + ...(forVpc && { NetworkACL: this.Netris }), + ...(!forVpc && { Firewall: this.Netris }) + } } this.updateSupportedServices() }, - handleForNsxChange (forNsx) { - this.forNsx = 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, - StaticNat: this.NSX, - PortForwarding: this.NSX, - Lb: this.NSX, - ...(this.forVpc && { NetworkACL: this.NSX }), - ...(!this.forVpc && { Firewall: this.NSX }) + handleProviderChange (provider) { + this.provider = provider + if (this.provider === 'NSX') { + 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, + StaticNat: this.NSX, + PortForwarding: this.NSX, + Lb: this.NSX, + ...(this.forVpc && { NetworkACL: this.NSX }), + ...(!this.forVpc && { Firewall: this.NSX }) + } + } else if (this.provider === 'Netris') { + this.netrisSupportedServicesMap = { + Dhcp: this.forVpc ? this.VPCVR : this.VR, + Dns: this.forVpc ? this.VPCVR : this.VR, + UserData: this.forVpc ? this.VPCVR : this.VR, + SourceNat: this.Netris, + StaticNat: this.Netris, + PortForwarding: this.Netris, + Lb: this.Netris, + ...(this.forVpc && { NetworkACL: this.Netris }), + ...(!this.forVpc && { Firewall: this.Netris }) + } } this.fetchSupportedServiceData() }, @@ -1084,11 +1143,16 @@ export default { params.specifyasnumber = values.specifyasnumber } params.routingmode = values.routingmode - if (values.fornsx === true) { - params.fornsx = true + const forNsx = values.provider === 'NSX' + if (forNsx === true) { + params.provider = 'NSX' params.nsxsupportlb = values.nsxsupportlb params.nsxsupportsinternallb = values.nsxsupportsinternallb } + const forNetris = values.provider === 'Netris' + if (forNetris) { + params.provider = 'Netris' + } if (values.guestiptype === 'isolated') { params.networkmode = values.networkmode } diff --git a/ui/src/views/offering/AddVpcOffering.vue b/ui/src/views/offering/AddVpcOffering.vue index 450ee117715..d43a55bd856 100644 --- a/ui/src/views/offering/AddVpcOffering.vue +++ b/ui/src/views/offering/AddVpcOffering.vue @@ -69,14 +69,26 @@ </a-form-item> <a-row :gutter="12"> <a-col :md="12" :lg="12"> - <a-form-item name="fornsx" ref="fornsx"> + <a-form-item name="provider" ref="provider"> <template #label> - <tooltip-label :title="$t('label.nsx')" :tooltip="apiParams.fornsx.description"/> + <tooltip-label :title="$t('label.provider')" :tooltip="apiParams.provider.description"/> </template> - <a-switch v-model:checked="form.fornsx" @change="val => { handleForNsxChange(val) }" /> + <a-select + v-model:value="form.provider" + v-focus="true" + @change="val => handleProviderChange(val)" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :placeholder="apiParams.provider.description" > + <a-select-option :value="'NSX'" :label="$t('label.nsx')"> {{ $t('label.nsx') }} </a-select-option> + <a-select-option :value="'Netris'" :label="$t('label.netris')"> {{ $t('label.netris') }} </a-select-option> + </a-select> </a-form-item> </a-col> - <a-col :md="12" :lg="12" v-if="forNsx"> + <a-col :md="12" :lg="12" v-if="form.provider === 'NSX'"> <a-form-item name="nsxsupportlb" ref="nsxsupportlb"> <template #label> <tooltip-label :title="$t('label.nsx.supports.lb')" :tooltip="apiParams.nsxsupportlb.description"/> @@ -85,7 +97,7 @@ </a-form-item> </a-col> </a-row> - <a-row :gutter="12" v-if="routingMode === 'dynamic' && forNsx"> + <a-row :gutter="12" v-if="routingMode === 'dynamic' && form.provider === 'NSX'"> <a-col :md="12" :lg="12"> <a-form-item name="specifyasnumber" ref="specifyasnumber"> <template #label> @@ -139,8 +151,8 @@ <CheckBoxSelectPair :resourceKey="item.name" :checkBoxLabel="item.description" - :forNsx="forNsx" - :defaultCheckBoxValue="forNsx" + :forExternalNetProvider="form.provider === 'NSX' || form.provider === 'Netris'" + :defaultCheckBoxValue="form.provider === 'NSX' || form.provider === 'Netris'" :selectOptions="item.provider" @handle-checkselectpair-change="handleSupportedServiceChange"/> </a-list-item> @@ -273,6 +285,7 @@ export default { zones: [], zoneLoading: false, forNsx: false, + provider: '', loading: false, supportedServices: [], supportedServiceLoading: false, @@ -306,6 +319,11 @@ export default { description: 'Nsx', enabled: true }, + Netris: { + name: 'Netris', + description: 'Netris', + enabled: true + }, nsxSupportedServicesMap: {} } }, @@ -402,7 +420,7 @@ export default { }, fetchSupportedServiceData () { var services = [] - if (this.forNsx) { + if (this.provider === 'NSX') { services.push({ name: 'Dhcp', enabled: true, @@ -445,6 +463,49 @@ export default { enabled: true, provider: [{ name: 'VpcVirtualRouter' }] }) + } else if (this.provider === 'Netris') { + services.push({ + name: 'Dhcp', + enabled: true, + provider: [ + { name: 'VpcVirtualRouter' } + ] + }) + services.push({ + name: 'Dns', + enabled: true, + provider: [{ name: 'VpcVirtualRouter' }] + }) + services.push({ + name: 'Lb', + enabled: true, + provider: [{ name: 'Netris' }] + }) + services.push({ + name: 'StaticNat', + enabled: true, + provider: [{ name: 'Netris' }] + }) + services.push({ + name: 'SourceNat', + enabled: true, + provider: [{ name: 'Netris' }] + }) + services.push({ + name: 'NetworkACL', + enabled: true, + provider: [{ name: 'Netris' }] + }) + services.push({ + name: 'PortForwarding', + enabled: true, + provider: [{ name: 'Netris' }] + }) + services.push({ + name: 'UserData', + enabled: true, + provider: [{ name: 'VpcVirtualRouter' }] + }) } else { services.push({ name: 'Dhcp', @@ -534,15 +595,16 @@ export default { self.supportedServiceLoading = false }, 50) }, - async handleForNsxChange (forNsx) { - this.forNsx = forNsx - if (forNsx) { + async handleProviderChange (value) { + this.provider = value + if (this.provider === 'NSX') { this.form.nsxsupportlb = true this.handleNsxLbService(true) } this.fetchSupportedServiceData() }, handleNsxLbService (supportLb) { + console.log(supportLb) if (!supportLb) { this.supportedServices = this.supportedServices.filter(svc => svc.name !== 'Lb') } @@ -632,10 +694,15 @@ export default { if (values.internetprotocol) { params.internetprotocol = values.internetprotocol } - if (values.fornsx === true) { - params.fornsx = true + const forNsx = values.provider === 'NSX' + if (forNsx) { + params.provider = 'NSX' params.nsxsupportlb = values.nsxsupportlb } + const forNetris = values.provider === 'Netris' + if (forNetris) { + params.provider = 'Netris' + } params.networkmode = values.networkmode if (!values.forVpc) { params.specifyasnumber = values.specifyasnumber
