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

pearl11594 pushed a commit to branch netris-update-vpc-and-tier-names
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 57609c79c42bd1a0debab6cf9fbc37d8c6ca56a3
Author: Pearl Dsilva <pearl1...@gmail.com>
AuthorDate: Sat Jan 11 21:12:32 2025 -0500

    Add support to add IPv6 Public IP range as IPAM Allocation / Subnet on 
Netris (#36)
    
    * Add support to add IPv6 Public IP range as IPAM Allocation / Subnet on 
Netris
    
    * Add ipam alloc and subnet for the ipv6 subnet associated to the vpc tier 
network
    
    * remove commented code
---
 .../engine/orchestration/NetworkOrchestrator.java  |  8 +++
 .../src/main/java/com/cloud/dc/dao/VlanDao.java    |  2 +
 .../main/java/com/cloud/dc/dao/VlanDaoImpl.java    | 27 ++++++++
 .../agent/api/CreateNetrisVnetCommand.java         |  9 +++
 .../cloudstack/service/NetrisApiClientImpl.java    | 34 +++++++---
 .../cloudstack/service/NetrisServiceImpl.java      | 77 +++++++++++-----------
 .../java/com/cloud/network/NetworkServiceImpl.java |  4 --
 ui/src/views/infra/network/IpRangesTabPublic.vue   | 10 +++
 8 files changed, 121 insertions(+), 50 deletions(-)

diff --git 
a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
 
b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 99a3ec3caca..7e1ca652f47 100644
--- 
a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ 
b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -43,6 +43,7 @@ import com.cloud.bgp.BGPService;
 import com.cloud.dc.VlanDetailsVO;
 import com.cloud.dc.dao.ASNumberDao;
 import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
 import com.cloud.network.dao.NetrisProviderDao;
 import com.cloud.network.dao.NsxProviderDao;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
@@ -361,6 +362,8 @@ public class NetworkOrchestrator extends ManagerBase 
implements NetworkOrchestra
     private ASNumberDao asNumberDao;
     @Inject
     private BGPService bgpService;
+    @Inject
+    private Ipv6GuestPrefixSubnetNetworkMapDao 
ipv6GuestPrefixSubnetNetworkMapDao;
 
     @Override
     public List<NetworkGuru> getNetworkGurus() {
@@ -824,6 +827,11 @@ public class NetworkOrchestrator extends ManagerBase 
implements NetworkOrchestra
                         if (domainId != null && aclType == ACLType.Domain) {
                             _networksDao.addDomainToNetwork(id, domainId, 
subdomainAccess == null || subdomainAccess);
                         }
+                        String ipv6Cidr = network.getIp6Cidr();
+                        String ipv6Gateway = network.getIp6Gateway();
+                        if (StringUtils.isNoneBlank(ipv6Cidr, ipv6Gateway)) {
+                            ipv6Service.assignIpv6SubnetToNetwork(ipv6Cidr, 
networkPersisted.getId());
+                        }
                     }
                 });
                 guru.setup(network, relatedFile);
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java 
b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
index 84f38f05441..a6c267bb189 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
@@ -64,4 +64,6 @@ public interface VlanDao extends GenericDao<VlanVO, Long> {
     List<VlanVO> listIpv6RangeByZoneIdAndVlanId(long zoneId, String vlanId);
 
     List<VlanVO> listIpv6SupportingVlansByZone(long zoneId);
+
+    List<VlanVO> listVlansForExternalNetworkProvider(long zoneId, String 
detailKey);
 }
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java 
b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
index 461a9a13b10..d9fad3cad12 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.dc.VlanDetailsVO;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
@@ -67,6 +68,8 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> 
implements VlanDao
     protected SearchBuilder<VlanVO> ZoneVlanIp6Search;
     protected SearchBuilder<VlanVO> ZoneIp6Search;
     protected SearchBuilder<VlanVO> ZoneVlansSearch;
+    protected SearchBuilder<VlanVO> ProviderVlanSearch;
+    protected SearchBuilder<VlanDetailsVO> VlanDetailsProviderSearch;
 
     protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch;
     protected SearchBuilder<DomainVlanMapVO> DomainVlanMapSearch;
@@ -79,6 +82,8 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> 
implements VlanDao
     protected DomainVlanMapDao _domainVlanMapDao;
     @Inject
     protected IPAddressDao _ipAddressDao;
+    @Inject
+    protected VlanDetailsDao vlanDetailsDao;
 
     @Override
     public VlanVO findByZoneAndVlanId(long zoneId, String vlanId) {
@@ -277,6 +282,19 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, 
Long> implements VlanDao
         ZoneVlansSearch.and("zoneId", 
ZoneVlansSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
         ZoneVlansSearch.and("vlan", ZoneVlansSearch.entity().getVlanTag(), 
SearchCriteria.Op.IN);
         ZoneVlansSearch.done();
+
+        ProviderVlanSearch = createSearchBuilder();
+        ProviderVlanSearch.and("removed", 
ProviderVlanSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        ProviderVlanSearch.and("dataCenterId", 
ProviderVlanSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        VlanDetailsProviderSearch = vlanDetailsDao.createSearchBuilder();
+        VlanDetailsProviderSearch.and("name", 
VlanDetailsProviderSearch.entity().getName(), SearchCriteria.Op.EQ);
+        VlanDetailsProviderSearch.and("value", 
VlanDetailsProviderSearch.entity().getValue(), SearchCriteria.Op.EQ);
+        ProviderVlanSearch.join("VlanDetailsProviderSearch", 
VlanDetailsProviderSearch, ProviderVlanSearch.entity().getId(),
+                VlanDetailsProviderSearch.entity().getResourceId(), 
JoinBuilder.JoinType.INNER);
+
+        VlanDetailsProviderSearch.done();
+        ProviderVlanSearch.done();
+
         return result;
     }
 
@@ -434,4 +452,13 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, 
Long> implements VlanDao
         return listBy(sc);
     }
 
+    @Override
+    public List<VlanVO> listVlansForExternalNetworkProvider(long zoneId, 
String detailKey) {
+        SearchCriteria<VlanVO> sc = ProviderVlanSearch.create();
+        sc.setParameters("dataCenterId", zoneId);
+        sc.setJoinParameters("VlanDetailsProviderSearch", "name", detailKey);
+        sc.setJoinParameters("VlanDetailsProviderSearch", "value", "true");
+        return search(sc, null);
+    }
+
 }
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
index 7ba6c9250fd..7095c4549b1 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
@@ -23,6 +23,7 @@ public class CreateNetrisVnetCommand extends NetrisCommand {
     private Integer vxlanId;
     private String gateway;
     private String netrisTag;
+    private String ipv6Cidr;
 
     public CreateNetrisVnetCommand(Long zoneId, Long accountId, Long domainId, 
String vpcName, Long vpcId, String vNetName, Long networkId, String cidr, 
String gateway, boolean isVpc) {
         super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
@@ -64,4 +65,12 @@ public class CreateNetrisVnetCommand extends NetrisCommand {
     public void setNetrisTag(String netrisTag) {
         this.netrisTag = netrisTag;
     }
+
+    public String getIpv6Cidr() {
+        return ipv6Cidr;
+    }
+
+    public void setIpv6Cidr(String ipv6Cidr) {
+        this.ipv6Cidr = ipv6Cidr;
+    }
 }
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
index 8d6d088407e..bfed67a915a 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
@@ -594,6 +594,7 @@ public class NetrisApiClientImpl implements NetrisApiClient 
{
         String netrisTag = cmd.getNetrisTag();
         String netmask = vnetCidr.split("/")[1];
         String netrisGateway = cmd.getGateway() + "/" + netmask;
+        String netrisV6Cidr = cmd.getIpv6Cidr();
         boolean isVpc = cmd.isVpc();
 
         String suffix = getNetrisVpcNameSuffix(vpcId, vpcName, networkId, 
networkName, isVpc);
@@ -614,9 +615,18 @@ public class NetrisApiClientImpl implements 
NetrisApiClient {
         String netrisSubnetName = 
NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, 
NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, vnetCidr) ;
 
         createIpamSubnetInternal(netrisSubnetName, vnetCidr, 
SubnetBody.PurposeEnum.COMMON, associatedVpc);
+        if (Objects.nonNull(netrisV6Cidr)) {
+            String netrisV6IpamAllocationName = 
NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, 
NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, netrisV6Cidr);
+            String netrisV6SubnetName = 
NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, 
NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, netrisV6Cidr) ;
+            InlineResponse2004Data createdIpamAllocation = 
createIpamAllocationInternal(netrisV6IpamAllocationName, netrisV6Cidr, 
associatedVpc);
+            if (Objects.isNull(createdIpamAllocation)) {
+                throw new CloudRuntimeException(String.format("Failed to 
create Netris IPAM Allocation %s for VPC %s", netrisV6IpamAllocationName, 
netrisVpcName));
+            }
+            createIpamSubnetInternal(netrisV6SubnetName, netrisV6Cidr, 
SubnetBody.PurposeEnum.COMMON, associatedVpc);
+        }
         logger.debug("Successfully created IPAM Subnet {} for network {} on 
Netris", netrisSubnetName, networkName);
 
-        VnetResAddBody vnetResponse = createVnetInternal(associatedVpc, 
netrisVnetName, netrisGateway, vxlanId, netrisTag);
+        VnetResAddBody vnetResponse = createVnetInternal(associatedVpc, 
netrisVnetName, netrisGateway, netrisV6Cidr, vxlanId, netrisTag);
         if (vnetResponse == null || !vnetResponse.isIsSuccess()) {
             String reason = vnetResponse == null ? "Empty response" : 
"Operation failed on Netris";
             logger.debug("The Netris vNet creation {} failed: {}", vNetName, 
reason);
@@ -1107,25 +1117,33 @@ public class NetrisApiClientImpl implements 
NetrisApiClient {
         }
     }
 
-    VnetResAddBody createVnetInternal(VPCListing associatedVpc, String 
netrisVnetName, String netrisGateway, Integer vxlanId, String netrisTag) {
+    VnetResAddBody createVnetInternal(VPCListing associatedVpc, String 
netrisVnetName, String netrisGateway, String netrisV6Gateway, Integer vxlanId, 
String netrisTag) {
         logger.debug("Creating Netris VPC vNet {} for CIDR {}", 
netrisVnetName, netrisGateway);
         try {
             VnetAddBody vnetBody = new VnetAddBody();
 
             vnetBody.setCustomAnycastMac("");
 
-            VnetAddBodyGateways gateways = new VnetAddBodyGateways();
-            gateways.prefix(netrisGateway);
-            gateways.setDhcpEnabled(false);
+            VnetAddBodyGateways gatewayV4 = new VnetAddBodyGateways();
+            gatewayV4.prefix(netrisGateway);
+            gatewayV4.setDhcpEnabled(false);
             VnetAddBodyDhcp dhcp = new VnetAddBodyDhcp();
             dhcp.setEnd("");
             dhcp.setStart("");
             dhcp.setOptionSet(new VnetAddBodyDhcpOptionSet());
-            gateways.setDhcp(dhcp);
+            gatewayV4.setDhcp(dhcp);
             List<VnetAddBodyGateways> gatewaysList = new ArrayList<>();
-            gatewaysList.add(gateways);
-            vnetBody.setGateways(gatewaysList);
+            gatewaysList.add(gatewayV4);
+
+            if (Objects.nonNull(netrisV6Gateway)) {
+                VnetAddBodyGateways gatewayV6 = new VnetAddBodyGateways();
+                gatewayV6.prefix(netrisV6Gateway);
+                gatewayV6.setDhcpEnabled(false);
+                gatewayV6.setDhcp(dhcp);
+                gatewaysList.add(gatewayV6);
+            }
 
+            vnetBody.setGateways(gatewaysList);
             vnetBody.setGuestTenants(new ArrayList<>());
             vnetBody.setL3vpn(false);
             vnetBody.setName(netrisVnetName);
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
index cb2047e32e8..0a9fe4ac239 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
@@ -18,17 +18,15 @@ package org.apache.cloudstack.service;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
-import com.cloud.dc.VlanDetailsVO;
 import com.cloud.dc.VlanVO;
 import com.cloud.dc.dao.VlanDao;
-import com.cloud.dc.dao.VlanDetailsDao;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.network.IpAddress;
+import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMapVO;
 import com.cloud.network.Network;
 import com.cloud.network.Networks;
 import com.cloud.network.SDNProviderNetworkRule;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
 import com.cloud.network.dao.NetrisProviderDao;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
@@ -37,6 +35,7 @@ import com.cloud.network.dao.PhysicalNetworkVO;
 import com.cloud.network.element.NetrisProviderVO;
 import com.cloud.network.netris.NetrisService;
 import com.cloud.network.vpc.Vpc;
+import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.net.NetUtils;
 import inet.ipaddr.IPAddress;
@@ -82,11 +81,9 @@ public class NetrisServiceImpl implements NetrisService, 
Configurable {
     @Inject
     private PhysicalNetworkDao physicalNetworkDao;
     @Inject
-    private IPAddressDao ipAddressDao;
-    @Inject
     private VlanDao vlanDao;
     @Inject
-    private VlanDetailsDao vlanDetailsDao;
+    private Ipv6GuestPrefixSubnetNetworkMapDao  ipv6PrefixNetworkMapDao;
 
     @Override
     public String getConfigComponentName() {
@@ -138,10 +135,10 @@ public class NetrisServiceImpl implements NetrisService, 
Configurable {
     /**
      * Prepare the Netris Public Range to be used by CloudStack after the zone 
is created and the Netris provider is added
      */
-    public SetupNetrisPublicRangeCommand createSetupPublicRangeCommand(long 
zoneId, String gateway, String netmask, String ipRange) {
+    private Pair<String, String> getAllocationAndSubnet(String gateway, String 
netmask, String ipRange) {
         String superCidr = NetUtils.getCidrFromGatewayAndNetmask(gateway, 
netmask);
         String subnetNatCidr = calculateSubnetCidrFromIpRange(ipRange);
-        return new SetupNetrisPublicRangeCommand(zoneId, superCidr, 
subnetNatCidr);
+        return new Pair<>(superCidr, subnetNatCidr);
     }
 
     @Override
@@ -151,38 +148,38 @@ public class NetrisServiceImpl implements NetrisService, 
Configurable {
         if (CollectionUtils.isEmpty(physicalNetworks)) {
             return false;
         }
-        for (PhysicalNetworkVO physicalNetwork : physicalNetworks) {
-            List<IPAddressVO> publicIps = 
ipAddressDao.listByPhysicalNetworkId(physicalNetwork.getId());
-            List<Long> vlanDbIds = publicIps.stream()
-                    .filter(x -> !x.isForSystemVms())
-                    .map(IPAddressVO::getVlanId)
-                    .collect(Collectors.toList());
-            if (CollectionUtils.isEmpty(vlanDbIds)) {
-                String msg = "Cannot find a public IP range VLAN range for the 
Netris Public traffic";
-                logger.error(msg);
-                throw new CloudRuntimeException(msg);
+
+        List<VlanVO> providerVlanIds = 
vlanDao.listVlansForExternalNetworkProvider(zoneId, 
ApiConstants.NETRIS_DETAIL_KEY);
+        List<Long> vlanDbIds = 
providerVlanIds.stream().map(VlanVO::getId).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(vlanDbIds)) {
+            String msg = "Cannot find a public IP range VLAN range for the 
Netris Public traffic";
+            logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        for (Long vlanDbId : vlanDbIds) {
+            VlanVO vlanRecord = vlanDao.findById(vlanDbId);
+
+            String gateway = Objects.nonNull(vlanRecord.getVlanGateway()) ? 
vlanRecord.getVlanGateway() : vlanRecord.getIp6Gateway();
+            String netmask = vlanRecord.getVlanNetmask();
+            String ipRange = vlanRecord.getIpRange();
+            String ip6Cidr = vlanRecord.getIp6Cidr();
+            SetupNetrisPublicRangeCommand cmd = null;
+            if (NetUtils.isValidIp4(gateway)) {
+                Pair<String, String> allocationAndSubnet = 
getAllocationAndSubnet(gateway, netmask, ipRange);
+                cmd = new SetupNetrisPublicRangeCommand(zoneId, 
allocationAndSubnet.first(), allocationAndSubnet.second());
+            } else if (NetUtils.isValidIp6(gateway)) {
+                cmd = new SetupNetrisPublicRangeCommand(zoneId, ip6Cidr, 
ip6Cidr);
             }
-            for (Long vlanDbId : vlanDbIds) {
-                VlanVO vlanRecord = vlanDao.findById(vlanDbId);
-                if (vlanRecord == null) {
-                    logger.error("Cannot set up the Netris Public IP range as 
it cannot find the public range on database");
-                    return false;
-                }
-                VlanDetailsVO vlanDetail = vlanDetailsDao.findDetail(vlanDbId, 
ApiConstants.NETRIS_DETAIL_KEY);
-                if (vlanDetail == null) {
-                    logger.debug("Skipping the Public IP range {} creation on 
Netris as it does not belong to the Netris Public IP Pool", 
vlanRecord.getIpRange());
-                    continue;
-                }
-                String gateway = vlanRecord.getVlanGateway();
-                String netmask = vlanRecord.getVlanNetmask();
-                String ipRange = vlanRecord.getIpRange();
-                SetupNetrisPublicRangeCommand cmd = 
createSetupPublicRangeCommand(zoneId, gateway, netmask, ipRange);
-                NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
-                if (!answer.getResult()) {
-                    throw new CloudRuntimeException("Netris Public IP Range 
setup failed, please check the logs");
-                }
+
+            if (cmd == null) {
+                throw new CloudRuntimeException("Incorrect gateway and netmask 
details provided for the Netris Public IP range setup");
+            }
+            NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
+            if (!answer.getResult()) {
+                throw new CloudRuntimeException("Netris Public IP Range setup 
failed, please check the logs");
             }
         }
+
         return true;
     }
 
@@ -208,6 +205,10 @@ public class NetrisServiceImpl implements NetrisService, 
Configurable {
         cmd.setVxlanId(Integer.parseInt(vxlanId));
         NetrisProviderVO netrisProvider = 
netrisProviderDao.findByZoneId(zoneId);
         cmd.setNetrisTag(netrisProvider.getNetrisTag());
+        if (Objects.nonNull(networkId)) {
+            Ipv6GuestPrefixSubnetNetworkMapVO ipv6PrefixNetworkMapVO = 
ipv6PrefixNetworkMapDao.findByNetworkId(networkId);
+            cmd.setIpv6Cidr(ipv6PrefixNetworkMapVO.getSubnet());
+        }
         NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
         return answer.getResult();
     }
diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java 
b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
index 15ff36b6c9e..3d218f3b0a5 100644
--- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -1800,10 +1800,6 @@ public class NetworkServiceImpl extends ManagerBase 
implements NetworkService, C
             _networkDetailsDao.persist(new NetworkDetailVO(network.getId(), 
Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
         }
 
-        if (ip6GatewayCidr != null) {
-            ipv6Service.assignIpv6SubnetToNetwork(ip6Cidr, network.getId());
-        }
-
         // assign to network
         if 
(NetworkOffering.NetworkMode.ROUTED.equals(ntwkOff.getNetworkMode())) {
             routedIpv4Manager.assignIpv4SubnetToNetwork(network);
diff --git a/ui/src/views/infra/network/IpRangesTabPublic.vue 
b/ui/src/views/infra/network/IpRangesTabPublic.vue
index 0f3610f5e05..62f2418c975 100644
--- a/ui/src/views/infra/network/IpRangesTabPublic.vue
+++ b/ui/src/views/infra/network/IpRangesTabPublic.vue
@@ -230,6 +230,16 @@
           <a-form-item name="ip6cidr" ref="ip6cidr" :label="$t('label.cidr')" 
class="form__item">
             <a-input v-model:value="form.ip6cidr" />
           </a-form-item>
+          <a-form-item name="provider" ref="provider">
+            <template #label>
+              <tooltip-label :title="$t('label.provider')"/>
+            </template>
+            <a-select v-model:value="form.provider">
+              <a-select-option value=""></a-select-option>
+              <a-select-option value="NSX">{{ $t('label.nsx') 
}}</a-select-option>
+              <a-select-option value="Netris">{{ $t('label.netris') 
}}</a-select-option>
+            </a-select>
+          </a-form-item>
         </div>
         <div v-else>
           <a-form-item name="gateway" ref="gateway" 
:label="$t('label.gateway')" class="form__item">

Reply via email to