diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1edbbfdf9a8..ca4be99520f 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1839,10 +1839,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } eventMsg += "."; if (associateIpRangeToAccount) { - // if this is an account VLAN, now associate the IP Addresses to the account - long ipCount = _publicIpAddressDao.countIPs(zoneId, vlan.getId(), false); - _accountMgr.incrementResourceCount(account.getId(), ResourceType.public_ip, ipCount); - s_logger.trace("Updated " + ResourceType.public_ip + " resource count on " + ipCount + " for account " + account); _networkMgr.associateIpAddressListToAccount(userId, account.getId(), zoneId, vlan.getId()); } return vlan; diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 04b2eb8cad4..d4ba5289853 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -168,5 +168,7 @@ public interface NetworkManager extends NetworkService { List getPasswordResetElements(); boolean zoneIsConfiguredForExternalNetworking(long zoneId); + + void unassignPublicIpAddress(IPAddressVO addr); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 8edfaee41f4..d4c4c6fbb5e 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -259,26 +259,57 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); - if (vlanUse == VlanType.DirectAttached) { - addr.setState(IpAddress.State.Allocated); - } else { + if (vlanUse != VlanType.DirectAttached) { addr.setAssociatedWithNetworkId(networkId); } - - if (!_ipAddressDao.update(addr.getId(), addr)) { - throw new CloudRuntimeException("Found address to allocate but unable to update: " + addr); - } - if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - long isSourceNat = (sourceNat) ? 1 : 0; - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getAccountId(), dcId, isSourceNat, addr.getAddress().toString()); - _usageEventDao.persist(usageEvent); - } - + + _ipAddressDao.update(addr.getId(), addr); + txn.commit(); long macAddress = NetUtils.createSequenceBasedMacAddress(addr.getMacAddress()); return new PublicIp(addr, _vlanDao.findById(addr.getVlanId()), macAddress); } + + @DB + protected void markPublicIpAsAllocated(IPAddressVO addr) { + Transaction txn = Transaction.currentTxn(); + + Account owner = _accountMgr.getAccount(addr.getAccountId()); + long isSourceNat = (addr.isSourceNat()) ? 1 : 0; + + txn.start(); + addr.setState(IpAddress.State.Allocated); + _ipAddressDao.update(addr.getId(), addr); + + //Save usage event + if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), isSourceNat, addr.getAddress().toString()); + _usageEventDao.persist(usageEvent); + } + + _accountMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); + txn.commit(); + } + + @Override @DB + public void unassignPublicIpAddress(IPAddressVO addr) { + Transaction txn = Transaction.currentTxn(); + Account owner = _accountMgr.getAccount(addr.getAccountId()); + long isSourceNat = (addr.isSourceNat()) ? 1 : 0; + + txn.start(); + + _ipAddressDao.unassignIpAddress(addr.getId()); + if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, owner.getId(), addr.getDataCenterId(), isSourceNat, addr.getAddress().toString()); + _usageEventDao.persist(usageEvent); + } + + _accountMgr.decrementResourceCount(owner.getId(), ResourceType.public_ip); + + txn.commit(); + } @Override @DB @@ -323,11 +354,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false); sourceNat = ip.ip(); - sourceNat.setState(IpAddress.State.Allocated); + + markPublicIpAsAllocated(sourceNat); _ipAddressDao.update(sourceNat.getId(), sourceNat); - + + // Increment the number of public IPs for this accountId in the database - _accountMgr.incrementResourceCount(ownerId, ResourceType.public_ip); + } else { // Account already has ip addresses for (IPAddressVO addr : addrs) { @@ -426,12 +459,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (success) { for (IPAddressVO addr : userIps) { + if (addr.getState() == IpAddress.State.Allocating) { - addr.setState(IpAddress.State.Allocated); + addr.setAssociatedWithNetworkId(network.getId()); - _ipAddressDao.update(addr.getId(), addr); + markPublicIpAsAllocated(addr); + } else if (addr.getState() == IpAddress.State.Releasing) { - _ipAddressDao.unassignIpAddress(addr.getId()); + unassignPublicIpAddress(addr); } } } @@ -508,8 +543,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zoneId); } - _accountMgr.incrementResourceCount(ownerId, ResourceType.public_ip); - Ip ipAddress = ip.getAddress(); s_logger.debug("Got " + ipAddress + " to assign for account " + owner.getId() + " in zone " + network.getDataCenterId()); @@ -526,7 +559,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - @DB public IpAddress associateIP(AssociateIPAddrCmd cmd) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); Account owner = null; @@ -542,7 +574,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Network network = _networksDao.findById(ipToAssoc.getAssociatedWithNetworkId()); - IpAddress ip = _ipAddressDao.findById(cmd.getEntityId()); + IPAddressVO ip = _ipAddressDao.findById(cmd.getEntityId()); boolean success = false; try { success = applyIpAssociations(network, false); @@ -556,21 +588,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.error("Unable to associate ip address due to resource unavailable exception", e); return null; } finally { - Transaction txn = Transaction.currentTxn(); if (!success) { if (ip != null) { try { s_logger.warn("Failed to associate ip address " + ip); _ipAddressDao.markAsUnavailable(ip.getId()); - applyIpAssociations(network, true); + if (!applyIpAssociations(network, true)) { + //if fail to apply ip assciations again, unassign ip address without updating resource count and generating usage event as there is no need to keep it in the db + _ipAddressDao.unassignIpAddress(ip.getId()); + } } catch (Exception e) { s_logger.warn("Unable to disassociate ip address for recovery", e); } - txn.start(); - _ipAddressDao.unassignIpAddress(ip.getId()); - _accountMgr.decrementResourceCount(owner.getId(), ResourceType.public_ip); - - txn.commit(); } } } @@ -617,14 +646,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (success) { - _ipAddressDao.unassignIpAddress(addrId); s_logger.debug("released a public ip id=" + addrId); - if (ownerId != Account.ACCOUNT_ID_SYSTEM) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ownerId, ip.getDataCenterId(), addrId, null); - _usageEventDao.persist(usageEvent); - } - - _accountMgr.decrementResourceCount(ownerId, ResourceType.public_ip); } return success; @@ -1716,11 +1738,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId); if (ipsToRelease != null && !ipsToRelease.isEmpty()) { for (IPAddressVO ip : ipsToRelease) { - _ipAddressDao.unassignIpAddress(ip.getId()); - if (ip.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ip.getAccountId(), ip.getDataCenterId(), 0, ip.getAddress().toString()); - _usageEventDao.persist(usageEvent); - } + unassignPublicIpAddress(ip); } s_logger.debug("Ip addresses are unassigned successfully as a part of network id=" + networkId + " destroy"); @@ -2054,7 +2072,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag long ipCount = _ipAddressDao.countIPs(zoneId, vlanId, false); if (ipCount > 0) { while (allocatedIps < ipCount) { - fetchNewPublicIp(zoneId, null, vlanId, account, VlanType.VirtualNetwork, network.getId(), false, true); + PublicIp ip = fetchNewPublicIp(zoneId, null, vlanId, account, VlanType.VirtualNetwork, network.getId(), false, true); + markPublicIpAsAllocated(ip.ip()); allocatedIps++; } diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index a7052f6e390..c90e097080b 100644 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -155,7 +155,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { IPAddressVO ip = _ipAddressDao.findByAccountAndIp(vm.getVirtualMachine().getAccountId(), nic.getIp4Address()); if (ip != null) { - _ipAddressDao.unassignIpAddress(ip.getId()); + _networkMgr.unassignPublicIpAddress(ip); } nic.deallocate(); }