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 <pearl1954@gmail.com>
This commit is contained in:
Pearl Dsilva 2026-07-10 09:27:10 -04:00 committed by Pearl Dsilva
parent 4ac23ee7b9
commit 0c0f22c9ad

View File

@ -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