Skip to content

Commit e16a971

Browse files
authored
Fix resource count discrepancy while associating IP address to a network or vpc (#9563)
1 parent 89482a2 commit e16a971

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

server/src/main/java/com/cloud/network/IpAddressManagerImpl.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
import com.cloud.network.dao.PublicIpQuarantineDao;
3737
import com.cloud.network.vo.PublicIpQuarantineVO;
38+
import com.cloud.resourcelimit.CheckedReservation;
3839
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
3940
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
4041
import org.apache.cloudstack.annotation.AnnotationService;
@@ -53,6 +54,7 @@
5354
import org.apache.cloudstack.region.PortableIpDao;
5455
import org.apache.cloudstack.region.PortableIpVO;
5556
import org.apache.cloudstack.region.Region;
57+
import org.apache.cloudstack.reservation.dao.ReservationDao;
5658
import org.apache.commons.collections.CollectionUtils;
5759
import org.apache.log4j.Logger;
5860

@@ -261,6 +263,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
261263
@Inject
262264
ResourceLimitService _resourceLimitMgr;
263265

266+
@Inject
267+
ReservationDao reservationDao;
264268
@Inject
265269
NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
266270
@Inject
@@ -1556,21 +1560,25 @@ public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean
15561560

15571561
s_logger.debug("Associating ip " + ipToAssoc + " to network " + network);
15581562

1559-
IPAddressVO ip = _ipAddressDao.findById(ipId);
1560-
//update ip address with networkId
1561-
ip.setAssociatedWithNetworkId(networkId);
1562-
ip.setSourceNat(isSourceNat);
1563-
_ipAddressDao.update(ipId, ip);
1564-
15651563
boolean success = false;
1566-
try {
1564+
IPAddressVO ip = null;
1565+
try (CheckedReservation publicIpReservation = new CheckedReservation(owner, ResourceType.public_ip, 1l, reservationDao, _resourceLimitMgr)) {
1566+
ip = _ipAddressDao.findById(ipId);
1567+
//update ip address with networkId
1568+
ip.setAssociatedWithNetworkId(networkId);
1569+
ip.setSourceNat(isSourceNat);
1570+
_ipAddressDao.update(ipId, ip);
1571+
15671572
success = applyIpAssociations(network, false);
15681573
if (success) {
15691574
s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
15701575
} else {
15711576
s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
15721577
}
15731578
return _ipAddressDao.findById(ipId);
1579+
} catch (Exception e) {
1580+
s_logger.error(String.format("Failed to associate ip address %s to network %s", ipToAssoc, network), e);
1581+
throw new CloudRuntimeException(String.format("Failed to associate ip address %s to network %s", ipToAssoc, network), e);
15741582
} finally {
15751583
if (!success && releaseOnFailure) {
15761584
if (ip != null) {

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import javax.inject.Inject;
4343
import javax.naming.ConfigurationException;
4444

45+
import com.cloud.resourcelimit.CheckedReservation;
4546
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
4647
import org.apache.cloudstack.alert.AlertService;
4748
import org.apache.cloudstack.annotation.AnnotationService;
@@ -63,6 +64,7 @@
6364
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
6465
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
6566
import org.apache.cloudstack.query.QueryService;
67+
import org.apache.cloudstack.reservation.dao.ReservationDao;
6668
import org.apache.commons.collections.CollectionUtils;
6769
import org.apache.commons.lang3.ObjectUtils;
6870
import org.apache.log4j.Logger;
@@ -237,6 +239,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
237239
@Inject
238240
ResourceLimitService _resourceLimitMgr;
239241
@Inject
242+
ReservationDao reservationDao;
243+
@Inject
240244
VpcServiceMapDao _vpcSrvcDao;
241245
@Inject
242246
DataCenterDao _dcDao;
@@ -2927,9 +2931,10 @@ public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws Reso
29272931
s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc);
29282932

29292933
final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(vpc.getAccountId(), vpcId) == null;
2930-
Transaction.execute(new TransactionCallbackNoReturn() {
2931-
@Override
2932-
public void doInTransactionWithoutResult(final TransactionStatus status) {
2934+
try (CheckedReservation publicIpReservation = new CheckedReservation(owner, ResourceType.public_ip, 1l, reservationDao, _resourceLimitMgr)) {
2935+
Transaction.execute(new TransactionCallbackNoReturn() {
2936+
@Override
2937+
public void doInTransactionWithoutResult(final TransactionStatus status) {
29332938
final IPAddressVO ip = _ipAddressDao.findById(ipId);
29342939
// update ip address with networkId
29352940
ip.setVpcId(vpcId);
@@ -2939,8 +2944,12 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
29392944

29402945
// mark ip as allocated
29412946
_ipAddrMgr.markPublicIpAsAllocated(ip);
2942-
}
2943-
});
2947+
}
2948+
});
2949+
} catch (Exception e) {
2950+
s_logger.error("Failed to associate ip " + ipToAssoc + " to vpc " + vpc, e);
2951+
throw new CloudRuntimeException("Failed to associate ip " + ipToAssoc + " to vpc " + vpc, e);
2952+
}
29442953

29452954
s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc);
29462955
CallContext.current().putContextParameter(IpAddress.class, ipToAssoc.getUuid());

0 commit comments

Comments
 (0)