This is an automated email from the ASF dual-hosted git repository.

pearl11594 pushed a commit to branch fr03-nsx-reorder-acl-rules
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 2ba97ab5f4c5860dd031a9ed8c4489d2a9bf1315
Author: Pearl Dsilva <pearl1...@gmail.com>
AuthorDate: Mon Jan 29 10:52:16 2024 -0500

    Nsx: Support internal LB (#4)
    
    * NSX: Support internal LB service in NSX
    
    * add lb removal logic
    
    * Fix UI issue hiding internal LB tab
    
    * Refactor method name
    
    ---------
    
    Co-authored-by: nvazquez <nicovazque...@gmail.com>
---
 .../com/cloud/network/VirtualRouterProvider.java   |   2 +-
 .../java/com/cloud/offering/NetworkOffering.java   |   1 +
 .../org/apache/cloudstack/api/ApiConstants.java    |   2 +
 .../admin/network/CreateNetworkOfferingCmd.java    |  10 ++
 .../api/response/NetworkOfferingResponse.java      |   8 ++
 .../apache/cloudstack/resource/NsxResource.java    |   2 +
 .../apache/cloudstack/service/NsxApiClient.java    |   8 +-
 .../org/apache/cloudstack/service/NsxElement.java  | 102 ++++++++++++++++++++-
 .../api/query/dao/NetworkOfferingJoinDaoImpl.java  |   1 +
 .../configuration/ConfigurationManagerImpl.java    |   6 ++
 .../com/cloud/server/ConfigurationServerImpl.java  |  22 +++--
 ui/public/locales/en.json                          |   1 +
 ui/src/views/network/VpcTiersTab.vue               |  20 +++-
 ui/src/views/offering/AddNetworkOffering.vue       |   9 ++
 14 files changed, 176 insertions(+), 18 deletions(-)

diff --git a/api/src/main/java/com/cloud/network/VirtualRouterProvider.java 
b/api/src/main/java/com/cloud/network/VirtualRouterProvider.java
index aca526b1832..98410ca09f8 100644
--- a/api/src/main/java/com/cloud/network/VirtualRouterProvider.java
+++ b/api/src/main/java/com/cloud/network/VirtualRouterProvider.java
@@ -21,7 +21,7 @@ import org.apache.cloudstack.api.InternalIdentity;
 
 public interface VirtualRouterProvider extends InternalIdentity, Identity {
     public enum Type {
-        VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, 
NetScalerVm
+        VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, 
NetScalerVm, Nsx
     }
 
     public Type getType();
diff --git a/api/src/main/java/com/cloud/offering/NetworkOffering.java 
b/api/src/main/java/com/cloud/offering/NetworkOffering.java
index 064b962fd2f..cf01fbf30e2 100644
--- a/api/src/main/java/com/cloud/offering/NetworkOffering.java
+++ b/api/src/main/java/com/cloud/offering/NetworkOffering.java
@@ -58,6 +58,7 @@ public interface NetworkOffering extends 
InfrastructureEntity, InternalIdentity,
     public final static String DefaultSharedNetworkOfferingWithSGService = 
"DefaultSharedNetworkOfferingWithSGService";
     public static final String 
DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE = 
"DefaultTungstenSharedNetworkOfferingWithSGService";
     public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC = 
"DefaultNATNSXNetworkOfferingForVpc";
+    public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC_WITH_ILB = 
"DefaultNATNSXNetworkOfferingForVpcWithInternalLB";
     public static final String DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC = 
"DefaultRoutedNSXNetworkOfferingForVpc";
     public static final String DEFAULT_NAT_NSX_OFFERING = 
"DefaultNATNSXNetworkOffering";
     public static final String DEFAULT_ROUTED_NSX_OFFERING = 
"DefaultRoutedNSXNetworkOffering";
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java 
b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index 51523b1863e..775ab83e9c0 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -825,6 +825,7 @@ public class ApiConstants {
     public static final String FOR_VPC = "forvpc";
     public static final String FOR_NSX = "fornsx";
     public static final String NSX_SUPPORT_LB = "nsxsupportlb";
+    public static final String NSX_SUPPORTS_INTERNAL_LB = 
"nsxsupportsinternallb";
     public static final String FOR_TUNGSTEN = "fortungsten";
     public static final String SHRINK_OK = "shrinkok";
     public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
@@ -963,6 +964,7 @@ public class ApiConstants {
     public static final String SUPPORTS_REGION_LEVEL_VPC = 
"supportsregionLevelvpc";
     public static final String SUPPORTS_STRECHED_L2_SUBNET = 
"supportsstrechedl2subnet";
     public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
+    public static final String SUPPORTS_INTERNAL_LB = "supportsinternallb";
     public static final String SUPPORTS_VM_AUTOSCALING = 
"supportsvmautoscaling";
     public static final String REGION_LEVEL_VPC = "regionlevelvpc";
     public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
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 e2ae2b42861..d4cf3660af1 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
@@ -160,6 +160,12 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
             since = "4.20.0")
     private Boolean nsxSupportsLbService;
 
+    @Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
+            type = CommandType.BOOLEAN,
+            description = "true if network offering for NSX network offering 
supports Internal Load balancer service.",
+            since = "4.20.0")
+    private Boolean nsxSupportsInternalLbService;
+
     @Parameter(name = ApiConstants.FOR_TUNGSTEN,
             type = CommandType.BOOLEAN,
             description = "true if network offering is meant to be used for 
Tungsten-Fabric, false otherwise.")
@@ -306,6 +312,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
         return BooleanUtils.isTrue(nsxSupportsLbService);
     }
 
+    public boolean getNsxSupportsInternalLbService() {
+        return BooleanUtils.isTrue(nsxSupportsInternalLbService);
+    }
+
     public Boolean getForTungsten() {
         return forTungsten;
     }
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
index 2594488c5be..b73163a5d05 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
@@ -135,6 +135,10 @@ public class NetworkOfferingResponse extends 
BaseResponseWithAnnotations {
     @Param(description = "true if network offering supports public access for 
guest networks", since = "4.10.0")
     private Boolean supportsPublicAccess;
 
+    @SerializedName(ApiConstants.SUPPORTS_INTERNAL_LB)
+    @Param(description = "true if network offering supports public access for 
guest networks", since = "4.20.0")
+    private Boolean supportsInternalLb;
+
     @SerializedName(ApiConstants.DOMAIN_ID)
     @Param(description = "the domain ID(s) this disk offering belongs to. 
Ignore this information as it is not currently applicable.")
     private String domainId;
@@ -259,6 +263,10 @@ public class NetworkOfferingResponse extends 
BaseResponseWithAnnotations {
         this.supportsPublicAccess = supportsPublicAccess;
     }
 
+    public void setSupportsInternalLb(Boolean supportsInternalLb) {
+        this.supportsInternalLb = supportsInternalLb;
+    }
+
     public String getDomainId() {
         return domainId;
     }
diff --git 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
index ec4de6b3ef7..bf16b056e6c 100644
--- 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
+++ 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java
@@ -308,7 +308,9 @@ public class NsxResource implements ServerResource {
 
     private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) {
         String tier1Id = 
NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), 
cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
+        String lbName = NsxControllerUtils.getLoadBalancerName(tier1Id);
         try {
+            nsxApiClient.deleteLoadBalancer(lbName);
             nsxApiClient.deleteTier1Gateway(tier1Id);
         } catch (Exception e) {
             return new NsxAnswer(cmd, new 
CloudRuntimeException(e.getMessage()));
diff --git 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
index cdcb83ec572..cb81a736c37 100644
--- 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
+++ 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
@@ -707,8 +707,7 @@ public class NsxApiClient {
             LBPoolListResult lbPoolListResult = lbPools.list(null, null, null, 
null, null, null);
             if (CollectionUtils.isEmpty(lbVsListResult.getResults()) && 
CollectionUtils.isEmpty(lbPoolListResult.getResults())) {
                 String lbName = getLoadBalancerName(tier1GatewayName);
-                LbServices lbServices = (LbServices) 
nsxService.apply(LbServices.class);
-                lbServices.delete(lbName, true);
+                deleteLoadBalancer(lbName);
             }
 
         } catch (Error error) {
@@ -719,6 +718,11 @@ public class NsxApiClient {
         }
     }
 
+    public void deleteLoadBalancer(String lbName) {
+        LbServices lbServices = (LbServices) 
nsxService.apply(LbServices.class);
+        lbServices.delete(lbName, true);
+    }
+
     private String getLbPoolPath(String lbPoolName) {
         try {
             LbPools lbPools = (LbPools) nsxService.apply(LbPools.class);
diff --git 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
index 571e68496d6..dfb075aa312 100644
--- 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
+++ 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
@@ -44,6 +44,7 @@ import com.cloud.network.NetworkModel;
 import com.cloud.network.Networks;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PublicIpAddress;
+import com.cloud.network.VirtualRouterProvider;
 import com.cloud.network.dao.IPAddressDao;
 import com.cloud.network.dao.IPAddressVO;
 import com.cloud.network.dao.LoadBalancerVMMapDao;
@@ -51,7 +52,9 @@ import com.cloud.network.dao.LoadBalancerVMMapVO;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.VirtualRouterProviderDao;
 import com.cloud.network.element.DhcpServiceProvider;
 import com.cloud.network.element.DnsServiceProvider;
 import com.cloud.network.element.FirewallServiceProvider;
@@ -60,9 +63,12 @@ import 
com.cloud.network.element.LoadBalancingServiceProvider;
 import com.cloud.network.element.NetworkACLServiceProvider;
 import com.cloud.network.element.PortForwardingServiceProvider;
 import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.VirtualRouterElement;
+import com.cloud.network.element.VirtualRouterProviderVO;
 import com.cloud.network.element.VpcProvider;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.LoadBalancerContainer;
 import com.cloud.network.rules.PortForwardingRule;
 import com.cloud.network.rules.StaticNat;
 import com.cloud.network.vpc.NetworkACLItem;
@@ -82,6 +88,8 @@ import com.cloud.user.AccountManager;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
@@ -90,6 +98,10 @@ import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.VMInstanceDao;
 import net.sf.ehcache.config.InvalidConfigurationException;
 import org.apache.cloudstack.StartupNsxCommand;
+import 
org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
+import 
org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
+import 
org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
+import 
org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
 import org.apache.cloudstack.resource.NsxLoadBalancerMember;
 import org.apache.cloudstack.resource.NsxNetworkRule;
 import org.apache.cloudstack.resource.NsxOpObject;
@@ -111,7 +123,7 @@ import java.util.function.LongFunction;
 @Component
 public class NsxElement extends AdapterBase implements  DhcpServiceProvider, 
DnsServiceProvider, VpcProvider,
         StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, 
NetworkACLServiceProvider,
-        LoadBalancingServiceProvider, FirewallServiceProvider, 
ResourceStateAdapter, Listener {
+        LoadBalancingServiceProvider, FirewallServiceProvider, 
InternalLoadBalancerElementService, ResourceStateAdapter, Listener {
 
 
     @Inject
@@ -142,6 +154,10 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
     VpcDao vpcDao;
     @Inject
     LoadBalancerVMMapDao lbVmMapDao;
+    @Inject
+    VirtualRouterProviderDao vrProviderDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao pNtwkSvcProviderDao;
 
     private static final Logger LOGGER = Logger.getLogger(NsxElement.class);
 
@@ -159,7 +175,16 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
         capabilities.put(Network.Service.Dns, dnsCapabilities);
 
         capabilities.put(Network.Service.StaticNat, null);
-        capabilities.put(Network.Service.Lb, null);
+
+        // Set capabilities for LB service
+        Map<Network.Capability, String> lbCapabilities = new 
HashMap<Network.Capability, String>();
+        lbCapabilities.put(Network.Capability.SupportedLBAlgorithms, 
"roundrobin,leastconn");
+        lbCapabilities.put(Network.Capability.SupportedLBIsolation, 
"dedicated");
+        lbCapabilities.put(Network.Capability.SupportedProtocols, "tcp, udp");
+        lbCapabilities.put(Network.Capability.SupportedStickinessMethods, 
VirtualRouterElement.getHAProxyStickinessCapability());
+        lbCapabilities.put(Network.Capability.LbSchemes, String.join(",", 
LoadBalancerContainer.Scheme.Internal.name(), 
LoadBalancerContainer.Scheme.Public.name()));
+
+        capabilities.put(Network.Service.Lb, lbCapabilities);
         capabilities.put(Network.Service.PortForwarding, null);
         capabilities.put(Network.Service.NetworkACL, null);
 
@@ -633,7 +658,8 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
                     .setNetworkResourceName(nsxObject.getNetworkResourceName())
                     .setVpcResource(nsxObject.isVpcResource())
                     .setMemberList(lbMembers)
-                    .setPublicIp(publicIp.getAddress().addr())
+                    .setPublicIp(LoadBalancerContainer.Scheme.Public == 
loadBalancingRule.getScheme() ?
+                            publicIp.getAddress().addr() : 
loadBalancingRule.getSourceIp().addr())
                     
.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()))
                     
.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()))
                     .setRuleId(loadBalancingRule.getId())
@@ -778,4 +804,74 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
         }
         return list;
     }
+
+    @Override
+    public VirtualRouterProvider configureInternalLoadBalancerElement(long id, 
boolean enable) {
+        VirtualRouterProviderVO element = vrProviderDao.findById(id);
+        if (element == null || element.getType() != 
VirtualRouterProvider.Type.Nsx) {
+            throw new InvalidParameterValueException("Can't find " + getName() 
+ " " +
+                    "element with network service provider id " + id + " to be 
used as a provider for " +
+                    getName());
+        }
+
+        element.setEnabled(enable);
+        element = vrProviderDao.persist(element);
+
+        return element;
+    }
+
+    @Override
+    public VirtualRouterProvider addInternalLoadBalancerElement(long 
ntwkSvcProviderId) {
+        VirtualRouterProviderVO element = 
vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, 
VirtualRouterProvider.Type.Nsx);
+        if (element != null) {
+            LOGGER.debug("There is already an " + getName() + " with service 
provider id " + ntwkSvcProviderId);
+            return null;
+        }
+
+        PhysicalNetworkServiceProvider provider = 
pNtwkSvcProviderDao.findById(ntwkSvcProviderId);
+        if (provider == null || 
!provider.getProviderName().equalsIgnoreCase(getName())) {
+            throw new InvalidParameterValueException("Invalid network service 
provider is specified");
+        }
+
+        element = new VirtualRouterProviderVO(ntwkSvcProviderId, 
VirtualRouterProvider.Type.Nsx);
+        element = vrProviderDao.persist(element);
+        return element;
+    }
+
+    @Override
+    public VirtualRouterProvider getInternalLoadBalancerElement(long id) {
+        VirtualRouterProvider provider = vrProviderDao.findById(id);
+        if (provider == null || provider.getType() != 
VirtualRouterProvider.Type.Nsx) {
+            throw new InvalidParameterValueException("Unable to find " + 
getName() + " by id");
+        }
+        return provider;
+    }
+
+    @Override
+    public List<? extends VirtualRouterProvider> 
searchForInternalLoadBalancerElements(Long id, Long ntwkSvsProviderId, Boolean 
enabled) {
+        QueryBuilder<VirtualRouterProviderVO> sc = 
QueryBuilder.create(VirtualRouterProviderVO.class);
+        if (id != null) {
+            sc.and(sc.entity().getId(), SearchCriteria.Op.EQ, id);
+        }
+        if (ntwkSvsProviderId != null) {
+            sc.and(sc.entity().getNspId(), SearchCriteria.Op.EQ, 
ntwkSvsProviderId);
+        }
+        if (enabled != null) {
+            sc.and(sc.entity().isEnabled(), SearchCriteria.Op.EQ, enabled);
+        }
+
+        //return only Internal LB elements
+        sc.and(sc.entity().getType(), SearchCriteria.Op.EQ, 
VirtualRouterProvider.Type.Nsx);
+
+        return sc.list();
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateInternalLoadBalancerElementCmd.class);
+        cmdList.add(ConfigureInternalLoadBalancerElementCmd.class);
+        cmdList.add(ListInternalLoadBalancerElementsCmd.class);
+        return cmdList;
+    }
 }
diff --git 
a/server/src/main/java/com/cloud/api/query/dao/NetworkOfferingJoinDaoImpl.java 
b/server/src/main/java/com/cloud/api/query/dao/NetworkOfferingJoinDaoImpl.java
index d50f1610e69..e291f8d2af0 100644
--- 
a/server/src/main/java/com/cloud/api/query/dao/NetworkOfferingJoinDaoImpl.java
+++ 
b/server/src/main/java/com/cloud/api/query/dao/NetworkOfferingJoinDaoImpl.java
@@ -108,6 +108,7 @@ public class NetworkOfferingJoinDaoImpl extends 
GenericDaoBase<NetworkOfferingJo
         
networkOfferingResponse.setConcurrentConnections(offering.getConcurrentConnections());
         
networkOfferingResponse.setSupportsStrechedL2Subnet(offering.isSupportingStrechedL2());
         
networkOfferingResponse.setSupportsPublicAccess(offering.isSupportingPublicAccess());
+        networkOfferingResponse.setSupportsInternalLb(offering.isInternalLb());
         networkOfferingResponse.setCreated(offering.getCreated());
         if (offering.getGuestType() != null) {
             
networkOfferingResponse.setGuestIpType(offering.getGuestType().toString());
diff --git 
a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java 
b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 09e7e96bd88..d54fa8b36f9 100644
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -5956,6 +5956,7 @@ public class ConfigurationManagerImpl extends ManagerBase 
implements Configurati
         Boolean forNsx = cmd.isForNsx();
         Boolean forTungsten = cmd.getForTungsten();
         String nsxMode = cmd.getNsxMode();
+        boolean nsxSupportInternalLbSvc = 
cmd.getNsxSupportsInternalLbService();
         Integer maxconn = null;
         boolean enableKeepAlive = false;
         String servicePackageuuid = cmd.getServicePackageId();
@@ -6274,6 +6275,11 @@ 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, nsxMode, domainIds, zoneIds, 
enable, internetProtocol);
+        if (Boolean.TRUE.equals(forNsx) && nsxSupportInternalLbSvc) {
+            offering.setInternalLb(true);
+            offering.setPublicLb(false);
+            _networkOfferingDao.update(offering.getId(), offering);
+        }
         CallContext.current().setEventDetails(" Id: " + offering.getId() + " 
Name: " + name);
         CallContext.current().putContextParameter(NetworkOffering.class, 
offering.getId());
         return offering;
diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java 
b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
index 4669f00070d..039a5edaf68 100644
--- a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
@@ -1203,35 +1203,41 @@ public class ConfigurationServerImpl extends 
ManagerBase implements Configuratio
 
                 // Offering #9 - network offering for NSX provider - NATTED 
mode
                 
createAndPersistDefaultNsxOffering(NetworkOffering.DEFAULT_NAT_NSX_OFFERING, 
"Offering for NSX enabled networks - NAT mode",
-                        NetworkOffering.NsxMode.NATTED, false);
+                        NetworkOffering.NsxMode.NATTED, false, true);
 
                 // Offering #10 - network offering for NSX provider - ROUTED 
mode
                 
createAndPersistDefaultNsxOffering(NetworkOffering.DEFAULT_ROUTED_NSX_OFFERING, 
"Offering for NSX enabled networks - ROUTED mode",
-                        NetworkOffering.NsxMode.ROUTED, false);
+                        NetworkOffering.NsxMode.ROUTED, false, true);
 
                 // Offering #11 - network offering for NSX provider for VPCs - 
NATTED mode
                 
createAndPersistDefaultNsxOffering(NetworkOffering.DEFAULT_NAT_NSX_OFFERING_FOR_VPC,
 "Offering for NSX enabled networks on VPCs - NAT mode",
-                        NetworkOffering.NsxMode.NATTED, true);
+                        NetworkOffering.NsxMode.NATTED, true, true);
 
                 // Offering #12 - network offering for NSX provider for VPCs - 
ROUTED mode
                 
createAndPersistDefaultNsxOffering(NetworkOffering.DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC,
 "Offering for NSX enabled networks on VPCs - ROUTED mode",
-                        NetworkOffering.NsxMode.ROUTED, true);
+                        NetworkOffering.NsxMode.ROUTED, true, true);
+
+                // Offering #13 - network offering for NSX provider for VPCs 
with Internal LB - NATTED mode
+                
createAndPersistDefaultNsxOffering(NetworkOffering.DEFAULT_NAT_NSX_OFFERING_FOR_VPC_WITH_ILB,
 "Offering for NSX enabled networks on VPCs with internal LB - NAT mode",
+                        NetworkOffering.NsxMode.NATTED, true, false);
             }
         });
     }
 
-    private void createAndPersistDefaultNsxOffering(String name, String 
displayText, NetworkOffering.NsxMode nsxMode, boolean forVpc) {
+    private void createAndPersistDefaultNsxOffering(String name, String 
displayText, NetworkOffering.NsxMode nsxMode,
+                                                    boolean forVpc, boolean 
publicLB) {
         NetworkOfferingVO defaultNatNSXNetworkOffering =
                 new NetworkOfferingVO(name, displayText, TrafficType.Guest, 
false, false, null,
                         null, true, Availability.Optional, null, 
GuestType.Isolated, false,
                         false, false, false, false, forVpc);
-        defaultNatNSXNetworkOffering.setPublicLb(true);
+        defaultNatNSXNetworkOffering.setPublicLb(publicLB);
+        defaultNatNSXNetworkOffering.setInternalLb(!publicLB);
         defaultNatNSXNetworkOffering.setForNsx(true);
         defaultNatNSXNetworkOffering.setNsxMode(nsxMode.name());
         defaultNatNSXNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultNatNSXNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultNatNSXNetworkOffering);
 
-        Map<Service, Provider> serviceProviderMap = 
getServicesAndProvidersForNSXNetwork(nsxMode, forVpc);
+        Map<Service, Provider> serviceProviderMap = 
getServicesAndProvidersForNSXNetwork(nsxMode, forVpc, publicLB);
         for (Map.Entry<Network.Service, Network.Provider> service : 
serviceProviderMap.entrySet()) {
             NetworkOfferingServiceMapVO offService =
                     new 
NetworkOfferingServiceMapVO(defaultNatNSXNetworkOffering.getId(), 
service.getKey(), service.getValue());
@@ -1240,7 +1246,7 @@ public class ConfigurationServerImpl extends ManagerBase 
implements Configuratio
         }
     }
 
-    private Map<Service, Provider> 
getServicesAndProvidersForNSXNetwork(NetworkOffering.NsxMode nsxMode, boolean 
forVpc) {
+    private Map<Service, Provider> 
getServicesAndProvidersForNSXNetwork(NetworkOffering.NsxMode nsxMode, boolean 
forVpc, boolean publicLB) {
         final Map<Network.Service, Network.Provider> serviceProviderMap = new 
HashMap<>();
         Provider routerProvider = forVpc ? Provider.VPCVirtualRouter : 
Provider.VirtualRouter;
         serviceProviderMap.put(Service.Dhcp, routerProvider);
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 6098bec5346..380c94a497f 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -1444,6 +1444,7 @@
 "label.nsx.provider.edgecluster": "NSX provider edge cluster",
 "label.nsx.provider.tier0gateway": "NSX provider tier-0 gateway",
 "label.nsx.provider.transportzone": "NSX provider transport zone",
+"label.nsx.supports.internal.lb": "Enable NSX internal LB service",
 "label.nsx.supports.lb": "Enable NSX LB service",
 "label.num.cpu.cores": "# of CPU cores",
 "label.number": "#Rule",
diff --git a/ui/src/views/network/VpcTiersTab.vue 
b/ui/src/views/network/VpcTiersTab.vue
index 8bb84392bd3..ddfd8fe0e8d 100644
--- a/ui/src/views/network/VpcTiersTab.vue
+++ b/ui/src/views/network/VpcTiersTab.vue
@@ -112,7 +112,7 @@
                 </template>
               </a-pagination>
             </a-collapse-panel>
-            <a-collapse-panel :header="$t('label.internal.lb')" key="ilb" 
:style="customStyle" :collapsible="!showIlb(network) ? 'disabled' : null" >
+            <a-collapse-panel :header="$t('label.internal.lb')" key="ilb" 
:style="customStyle" :collapsible="displayCollapsible[network.id] ? null: 
'disabled'" >
               <a-button
                 type="dashed"
                 style="margin-bottom: 15px; width: 100%"
@@ -438,7 +438,8 @@ export default {
       publicLBExists: false,
       setMTU: false,
       isNsxEnabled: false,
-      isOfferingNatMode: false
+      isOfferingNatMode: false,
+      displayCollapsible: []
     }
   },
   created () {
@@ -461,8 +462,8 @@ export default {
       this.form = reactive({})
       this.rules = reactive({})
     },
-    showIlb (network) {
-      return network.service.filter(s => (s.name === 'Lb') && 
(s.capability.filter(c => c.name === 'LbSchemes' && c.value === 
'Internal').length > 0)).length > 0 || false
+    showIlb (network, networkOffering) {
+      return ((networkOffering.supportsinternallb && network.service.filter(s 
=> (s.name === 'Lb') && (s.capability.filter(c => c.name === 'LbSchemes' && 
c.value.split(',').includes('Internal')).length > 0)).length > 0)) || false
     },
     updateMtu () {
       if (this.form.privatemtu > this.privateMtuMax) {
@@ -482,6 +483,7 @@ export default {
       for (const network of this.networks) {
         this.fetchLoadBalancers(network.id)
         this.fetchVMs(network.id)
+        this.updateDisplayCollapsible(network.networkofferingid, network)
       }
       this.publicLBNetworkExists()
     },
@@ -519,6 +521,16 @@ export default {
         })
       })
     },
+    updateDisplayCollapsible (offeringId, network) {
+      api('listNetworkOfferings', {
+        id: offeringId
+      }).then(json => {
+        var networkOffering = 
json.listnetworkofferingsresponse.networkoffering[0]
+        this.displayCollapsible[network.id] = this.showIlb(network, 
networkOffering)
+      }).catch(e => {
+        this.$notifyError(e)
+      })
+    },
     getVpcNetworkOffering () {
       return new Promise((resolve, reject) => {
         api('listVPCOfferings', {
diff --git a/ui/src/views/offering/AddNetworkOffering.vue 
b/ui/src/views/offering/AddNetworkOffering.vue
index a9d8bc529ed..500e3dc0a72 100644
--- a/ui/src/views/offering/AddNetworkOffering.vue
+++ b/ui/src/views/offering/AddNetworkOffering.vue
@@ -138,6 +138,14 @@
               <a-switch v-model:checked="form.nsxsupportlb" @change="val => { 
handleNsxLbService(val) }" />
             </a-form-item>
           </a-col>
+          <a-col :md="12" :lg="12" v-if="form.nsxsupportlb && form.forvpc">
+            <a-form-item name="nsxsupportsinternallb" 
ref="nsxsupportsinternallb" v-if="guestType === 'isolated'">
+              <template #label>
+                <tooltip-label :title="$t('label.nsx.supports.internal.lb')" 
:tooltip="apiParams.nsxsupportsinternallb.description"/>
+              </template>
+              <a-switch v-model:checked="form.nsxsupportsinternallb"/>
+            </a-form-item>
+          </a-col>
         </a-row>
         <a-form-item name="nsxmode" ref="nsxmode" v-if="forNsx">
           <template #label>
@@ -1025,6 +1033,7 @@ export default {
           params.fornsx = true
           params.nsxmode = values.nsxmode
           params.nsxsupportlb = values.nsxsupportlb
+          params.nsxsupportsinternallb = values.nsxsupportsinternallb
         }
         if (values.guestiptype === 'shared' || values.guestiptype === 
'isolated') {
           if (values.conservemode !== true) {

Reply via email to