mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-2700:on network/vpc delete, portable IP should be still
associated with account Unlike public ip which gets dis-associated (released) with the account on network/VPC delete, portable IP should continue to be associated with the account even when the network/VPC with which it is currently associated in deleted. This fix ensures portable IP are associated to account even after network/vpc is deleted.
This commit is contained in:
parent
ad48c83808
commit
883333c214
@ -55,7 +55,7 @@ public interface NetworkService {
|
||||
IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
|
||||
InsufficientAddressCapacityException, ConcurrentOperationException;
|
||||
|
||||
boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
|
||||
boolean releasePortableIpAddress(long ipAddressId);
|
||||
|
||||
Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException,
|
||||
ResourceAllocationException;
|
||||
|
||||
@ -268,6 +268,11 @@ public interface NetworkManager {
|
||||
IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
|
||||
InsufficientAddressCapacityException, ConcurrentOperationException;
|
||||
|
||||
IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID)
|
||||
throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException;
|
||||
|
||||
boolean releasePortableIpAddress(long addrId);
|
||||
|
||||
IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
|
||||
InsufficientAddressCapacityException, ConcurrentOperationException;
|
||||
|
||||
@ -362,10 +367,6 @@ public interface NetworkManager {
|
||||
IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId,
|
||||
DataCenter zone) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException;
|
||||
|
||||
|
||||
IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID)
|
||||
throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException;
|
||||
|
||||
Map<String, String> finalizeServicesAndProvidersForNetwork(NetworkOffering offering,
|
||||
Long physicalNetworkId);
|
||||
|
||||
|
||||
@ -1118,7 +1118,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
|
||||
@DB
|
||||
private void releasePortableIpAddress(long addrId) {
|
||||
@Override
|
||||
public boolean releasePortableIpAddress(long addrId) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
|
||||
|
||||
@ -1133,12 +1134,13 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
// removed the provisioned vlan
|
||||
VlanVO vlan = _vlanDao.findById(ip.getVlanId());
|
||||
_vlanDao.expunge(vlan.getId());
|
||||
_vlanDao.remove(vlan.getId());
|
||||
|
||||
// remove the provisioned public ip address
|
||||
_ipAddressDao.expunge(ip.getId());
|
||||
_ipAddressDao.remove(ip.getId());
|
||||
|
||||
txn.commit();
|
||||
return true;
|
||||
} finally {
|
||||
portableIpLock.releaseRef();
|
||||
}
|
||||
@ -3537,8 +3539,16 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null);
|
||||
for (IPAddressVO ipToRelease : ipsToRelease) {
|
||||
if (ipToRelease.getVpcId() == null) {
|
||||
IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId());
|
||||
assert (ip != null) : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable.";
|
||||
if (!ipToRelease.isPortable()) {
|
||||
IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId());
|
||||
assert (ip != null) : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable.";
|
||||
} else {
|
||||
// portable IP address are associated with owner, until explicitly requested to be disassociated
|
||||
// so as part of network clean up just break IP association with guest network
|
||||
ipToRelease.setAssociatedWithNetworkId(null);
|
||||
_ipAddressDao.update(ipToRelease.getId(), ipToRelease);
|
||||
s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any network");
|
||||
}
|
||||
} else {
|
||||
_vpcMgr.unassignIPFromVpcNetwork(ipToRelease.getId(), network.getId());
|
||||
}
|
||||
|
||||
@ -591,8 +591,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RELEASE, eventDescription = "disassociating portable Ip", async = true)
|
||||
public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
|
||||
return releaseIpAddressInternal(ipAddressId);
|
||||
public boolean releasePortableIpAddress(long ipAddressId) {
|
||||
try {
|
||||
return releaseIpAddressInternal(ipAddressId);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -880,7 +884,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
boolean success = _networkMgr.disassociatePublicIpAddress(ipAddressId, userId, caller);
|
||||
|
||||
if (success) {
|
||||
if (!ipVO.isPortable()) {
|
||||
if (ipVO.isPortable()) {
|
||||
return success;
|
||||
}
|
||||
Long networkId = ipVO.getAssociatedWithNetworkId();
|
||||
|
||||
@ -490,10 +490,9 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
"a part of enable static nat");
|
||||
return false;
|
||||
}
|
||||
performedIpAssoc = true;
|
||||
} else if (ipAddress.isPortable()) {
|
||||
s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network, so" +
|
||||
"associate IP with the network " + networkId);
|
||||
s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network yet "
|
||||
+ " so associate IP with the network " + networkId);
|
||||
try {
|
||||
// check if StaticNat service is enabled in the network
|
||||
_networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
|
||||
@ -504,13 +503,12 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
}
|
||||
|
||||
// associate portable IP with guest network
|
||||
_networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
|
||||
ipAddress = _networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " +
|
||||
"a part of enable static nat");
|
||||
return false;
|
||||
}
|
||||
performedIpAssoc = true;
|
||||
}
|
||||
} else if (ipAddress.getAssociatedWithNetworkId() != networkId) {
|
||||
if (ipAddress.isPortable()) {
|
||||
@ -520,14 +518,16 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
// check if portable IP can be transferred across the networks
|
||||
if (_networkMgr.isPortableIpTransferableFromNetwork(ipId, ipAddress.getAssociatedWithNetworkId() )) {
|
||||
try {
|
||||
// transfer the portable IP and refresh IP details
|
||||
_networkMgr.transferPortableIP(ipId, ipAddress.getAssociatedWithNetworkId(), networkId);
|
||||
ipAddress = _ipAddressDao.findById(ipId);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " +
|
||||
"a part of enable static nat");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services" +
|
||||
throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services " +
|
||||
"in network " + ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " +
|
||||
" network " + networkId);
|
||||
}
|
||||
|
||||
@ -1217,9 +1217,18 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null);
|
||||
s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup");
|
||||
for (IPAddressVO ipToRelease : ipsToRelease) {
|
||||
success = success && _ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
|
||||
if (!success) {
|
||||
s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup");
|
||||
if (ipToRelease.isPortable()) {
|
||||
// portable IP address are associated with owner, until explicitly requested to be disassociated.
|
||||
// so as part of VPC clean up just break IP association with VPC
|
||||
ipToRelease.setVpcId(null);
|
||||
ipToRelease.setAssociatedWithNetworkId(null);
|
||||
_ipAddressDao.update(ipToRelease.getId(), ipToRelease);
|
||||
s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any VPC");
|
||||
} else {
|
||||
success = success && _ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
|
||||
if (!success) {
|
||||
s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -731,6 +731,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
_resourceCountDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
|
||||
_resourceLimitDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
|
||||
|
||||
// release account specific acquired portable IP's. Since all the portable IP's must have been already
|
||||
// disassociated with VPC/guest network (due to deletion), so just mark portable IP as free.
|
||||
List<? extends IpAddress> portableIpsToRelease = _ipAddressDao.listByAccount(accountId);
|
||||
for (IpAddress ip : portableIpsToRelease) {
|
||||
s_logger.debug("Releasing portable ip " + ip + " as a part of account id=" + accountId + " cleanup");
|
||||
_networkMgr.releasePortableIpAddress(ip.getId());
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
s_logger.warn("Failed to cleanup account " + account + " due to ", ex);
|
||||
|
||||
@ -887,7 +887,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
|
||||
public boolean releasePortableIpAddress(long ipAddressId) {
|
||||
return false;// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
|
||||
public boolean releasePortableIpAddress(long ipAddressId) {
|
||||
return false;// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user