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

Pearl1594 pushed a commit to branch netris-improvements
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 0c0f22c9ad35a576e58c362623b6048a70868e7e
Author: Pearl Dsilva <[email protected]>
AuthorDate: Fri Jul 10 09:27:10 2026 -0400

    Allocate IP from Netris (Provider) range when IP is not specified during 
associate
    
    * Allocate IP from Netris (Provider) range when IP is not specified during 
associate
    
    * update javadoc and method name
    
    ---------
    
    Co-authored-by: Pearl Dsilva <[email protected]>
---
 .../com/cloud/network/IpAddressManagerImpl.java    | 35 ++++++++++++++++++++--
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java 
b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
index 6a4f3745f1b..2d5102d8848 100644
--- a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
@@ -1417,6 +1417,31 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
         }
     }
 
+    /**
+     * When the zone is linked to external provider Netris and no explicit IP 
was requested:
+     * restrict the candidate pool to the VLANs reserved for Netris, so that 
generic acquisitions
+     * (e.g. associateIpAddress called by the CloudStack 
cloud-controller-manager on behalf of a
+     * Kubernetes Service of type LoadBalancer) don't fall back to the VR's 
public range.
+     * Returns null when the zone has no Netris provider, meaning no 
restriction is applied.
+     *
+     * returns VLAN IDS tagged with forNetris = true
+     */
+    private List<Long> getNetrisVlanDbIds(DataCenter zone) {
+        long zoneId = zone.getId();
+        NetrisProviderVO netrisProvider = 
netrisProviderDao.findByZoneId(zoneId);
+        if (netrisProvider == null) {
+            return null;
+        }
+        List<Long> vlanIds = 
_vlanDao.listVlansForExternalNetworkProvider(zoneId, 
ApiConstants.NETRIS_DETAIL_KEY).stream()
+                .map(VlanVO::getId).collect(Collectors.toList());
+        if (vlanIds.isEmpty()) {
+            throw new CloudRuntimeException(String.format(
+                    "Cannot allocate public IP in zone %s: no VLANs tagged 
'%s=true' found for the external provider",
+                    zone.getName(), ApiConstants.NETRIS_DETAIL_KEY));
+        }
+        return vlanIds;
+    }
+
     @DB
     @Override
     public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, 
Account caller, User callerUser, final DataCenter zone, final Boolean 
displayIp, final String ipaddress)
@@ -1425,8 +1450,6 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
         final VlanType vlanType = VlanType.VirtualNetwork;
         final boolean assign = false;
 
-        checkPublicIpOnExternalProviderZone(zone, ipaddress);
-
         if (Grouping.AllocationState.Disabled == zone.getAllocationState() && 
!_accountMgr.isRootAdmin(caller.getId())) {
             // zone is of type DataCenter. See DataCenterVO.java.
             PermissionDeniedException ex = new 
PermissionDeniedException(generateErrorMessageForOperationOnDisabledZone("allocate
 IP addresses", zone));
@@ -1434,6 +1457,12 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
             throw ex;
         }
 
+        checkPublicIpOnExternalProviderZone(zone, ipaddress);
+
+        // Only steer the range when no explicit IP was requested: an explicit 
ipaddress is already
+        // validated against the provider's pool above by 
checkPublicIpOnExternalProviderZone.
+        final List<Long> vlanDbIds = ipaddress == null ? 
getNetrisVlanDbIds(zone) : null;
+
         PublicIp ip = null;
 
         Account accountToLock = null;
@@ -1461,7 +1490,7 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
             ip = Transaction.execute(new 
TransactionCallbackWithException<PublicIp, 
InsufficientAddressCapacityException>() {
                 @Override
                 public PublicIp doInTransaction(TransactionStatus status) 
throws InsufficientAddressCapacityException {
-                    PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, 
ipOwner, vlanType, null, false, assign, ipaddress, null, isSystem, null, 
displayIp, false);
+                    PublicIp ip = fetchNewPublicIp(zone.getId(), null, 
vlanDbIds, ipOwner, vlanType, null, false, assign, ipaddress, null, isSystem, 
null, displayIp, false);
 
                     if (ip == null) {
                         InsufficientAddressCapacityException ex = new 
InsufficientAddressCapacityException("Unable to find available public IP 
addresses", DataCenter.class, zone

Reply via email to