From 6304a92c231476fb968896dea94245e20e971fd8 Mon Sep 17 00:00:00 2001 From: alena Date: Fri, 21 Jan 2011 21:45:43 -0800 Subject: [PATCH] bug 7881: fixed publicIpAllocation to an account. status 7881: resolved fixed Also fixed the issue with account delete when nonSourceNat ip addresses were not being released --- .../api/commands/CreateVlanIpRangeCmd.java | 5 +- .../configuration/ConfigurationService.java | 6 +- .../configuration/ConfigurationManager.java | 17 +- .../ConfigurationManagerImpl.java | 178 +--- .../src/com/cloud/network/NetworkManager.java | 29 +- .../com/cloud/network/NetworkManagerImpl.java | 897 +++++++++--------- .../com/cloud/network/dao/IPAddressDao.java | 4 +- .../cloud/network/dao/IPAddressDaoImpl.java | 31 +- .../VirtualNetworkApplianceManagerImpl.java | 4 - .../com/cloud/user/AccountManagerImpl.java | 21 +- 10 files changed, 560 insertions(+), 632 deletions(-) diff --git a/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java b/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java index d746eace132..66300fa072b 100644 --- a/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/CreateVlanIpRangeCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.dc.Vlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; @Implementation(description="Creates a VLAN IP range.", responseObject=VlanIpRangeResponse.class) public class CreateVlanIpRangeCmd extends BaseCmd { @@ -132,7 +133,7 @@ public class CreateVlanIpRangeCmd extends BaseCmd { } @Override - public void execute(){ + public void execute() throws ResourceUnavailableException{ try { Vlan result = _configService.createVlanAndPublicIpRange(this); if (result != null) { @@ -148,6 +149,6 @@ public class CreateVlanIpRangeCmd extends BaseCmd { } catch (InsufficientCapacityException ex) { s_logger.info(ex); throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); - } + } } } diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/com/cloud/configuration/ConfigurationService.java index 0bb032b22ae..b4e9f404890 100644 --- a/api/src/com/cloud/configuration/ConfigurationService.java +++ b/api/src/com/cloud/configuration/ConfigurationService.java @@ -28,6 +28,8 @@ import com.cloud.dc.Vlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Networks.TrafficType; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -174,7 +176,7 @@ public interface ConfigurationService { * @throws * @return The new Vlan object */ - Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; + Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException, ResourceUnavailableException; boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd); @@ -191,5 +193,7 @@ public interface ConfigurationService { Integer getNetworkRate(long networkOfferingId); Account getVlanAccount(long vlanId); + + List listNetworkOfferings(TrafficType trafficType, boolean systemOnly); } diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index b2581be9bfe..4a03a5c8a86 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -25,10 +25,10 @@ import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.Vlan; import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering.Availability; @@ -111,17 +111,6 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @throws */ DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId, NetworkType zoneType); - - /** - * Associates an ip address list to an account. The list of ip addresses are all addresses associated with the given vlan id. - * @param userId - * @param accountId - * @param zoneId - * @param vlanId - * @throws InsufficientAddressCapacityException - * @throws - */ - public void associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId) throws InsufficientAddressCapacityException, ConcurrentOperationException; /** * Deletes a VLAN from the database, along with all of its IP addresses. Will not delete VLANs that have allocated IP addresses. @@ -180,9 +169,11 @@ public interface ConfigurationManager extends ConfigurationService, Manager { */ NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, TrafficType trafficType, String tags, Integer maxConnections, boolean specifyVlan, Availability availability); - Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; + Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException, ResourceUnavailableException; void createDefaultNetworks(long zoneId) throws ConcurrentOperationException; DataCenterVO getZone(long id); + + boolean deleteAccountSpecificVirtualRanges(long accountId); } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 204e5b86c99..de590016e00 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -21,13 +21,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.Vector; import javax.ejb.Local; import javax.naming.ConfigurationException; @@ -82,12 +80,11 @@ import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.dao.EventDao; import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; import com.cloud.network.Network; import com.cloud.network.Network.GuestIpType; import com.cloud.network.NetworkManager; @@ -123,14 +120,12 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.SecondaryStorageVmDao; @@ -1583,7 +1578,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } @Override - public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException { + public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException, ResourceUnavailableException { Long zoneId = cmd.getZoneId(); Long podId = cmd.getPodId(); String startIP = cmd.getStartIp(); @@ -1687,7 +1682,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override - public Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException{ + public Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException, ResourceUnavailableException{ // Check that the pod ID is valid if (podId != null && ((_podDao.findById(podId)) == null)) { @@ -1773,7 +1768,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("Direct Attached IP ranges for a pod must be untagged."); } - // Make sure there aren't any account VLANs in this zone List accountVlanMaps = _accountVlanMapDao.listAllIncludingRemoved(); for (AccountVlanMapVO accountVlanMap : accountVlanMaps) { @@ -1880,14 +1874,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId); vlan = _vlanDao.persist(vlan); - // Persist the IP range - if (account != null && vlanType.equals(VlanType.VirtualNetwork)){ - if(!savePublicIPRangeForAccount(startIP, endIP, zoneId, vlan.getId(), account.getId(), account.getDomainId())) { - deletePublicIPRange(vlan.getId()); - _vlanDao.expunge(vlan.getId()); - throw new CloudRuntimeException("Failed to save IP range. Please contact Cloud Support."); //It can be Direct IP or Public IP. - } - }else if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId())) { + if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId())) { deletePublicIPRange(vlan.getId()); _vlanDao.expunge(vlan.getId()); throw new CloudRuntimeException("Failed to save IP range. Please contact Cloud Support."); //It can be Direct IP or Public IP. @@ -1910,81 +1897,13 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura eventMsg += "."; if (associateIpRangeToAccount) { // if this is an account VLAN, now associate the IP Addresses to the account - associateIpAddressListToAccount(userId, account.getId(), zoneId, vlan.getId()); + 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; } - - @Override @DB - public void associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId) throws InsufficientAddressCapacityException, - ConcurrentOperationException { - - Transaction txn = Transaction.currentTxn(); - AccountVO account = null; - - try { - //Acquire Lock - account = _accountDao.acquireInLockTable(accountId); - if (account == null) { - s_logger.warn("Unable to lock account: " + accountId); - throw new ConcurrentOperationException("Unable to acquire account lock"); - } - s_logger.debug("Associate IP address lock acquired"); - - //Get Router - DomainRouterVO router = _domrDao.findBy(accountId, zoneId); - if (router == null) { - s_logger.debug("No router found for account: " + account.getAccountName() + "."); - return; - } - - if (router.getState() == State.Running) { - //Get Vlans associated with the account - List vlansForAccount = new ArrayList(); - if (vlanId == null){ - vlansForAccount.addAll(_vlanDao.listVlansForAccountByType(zoneId, account.getId(), VlanType.VirtualNetwork)); - s_logger.debug("vlansForAccount "+ vlansForAccount); - }else{ - vlansForAccount.add(_vlanDao.findById(vlanId)); - } - - // Creating a list of all the ips that can be assigned to this account - txn.start(); - List ipAddrsList = new ArrayList(); - for (VlanVO vlan : vlansForAccount){ - ipAddrsList.addAll(_publicIpAddressDao.assignAcccountSpecificIps(accountId, account.getDomainId(), vlan.getId(), false)); - - long size = ipAddrsList.size(); - _accountMgr.incrementResourceCount(accountId, ResourceType.public_ip, size); - s_logger.debug("Assigning new ip addresses " +ipAddrsList); - } - if(ipAddrsList.isEmpty()) { - return; - } - - // Associate the IP's to DomR - boolean success = _networkMgr.associateIP(router,ipAddrsList, true, 0); - String errorMsg = "Unable to assign public IP address pool"; - if (!success) { - s_logger.debug(errorMsg); - throw new CloudRuntimeException(errorMsg); - } - txn.commit(); - } - } catch (CloudRuntimeException iee) { - s_logger.error("Associate IP threw an CloudRuntimeException.", iee); - throw iee; - } catch (Throwable t) { - s_logger.error("Associate IP address threw an exception.", t); - throw new CloudRuntimeException("Associate IP address exception"); - } finally { - if (account != null) { - _accountDao.releaseFromLockTable(accountId); - s_logger.debug("Associate IP address lock released"); - } - } - - } @Override public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId) throws InvalidParameterValueException { @@ -1993,16 +1912,11 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("Please specify a valid IP range id."); } - // Check if the VLAN has any allocated public IPs - if (_publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true) > 0) { - throw new InvalidParameterValueException("The IP range can't be deleted because it has allocated public IP addresses."); - } - - // Check if the VLAN is being used by any domain router - if (_domrDao.listByVlanDbId(vlanDbId).size() > 0) { - throw new InvalidParameterValueException("The IP range can't be deleted because it is being used by a domain router."); - } - + // Check if the VLAN has any allocated public IPs + if (_publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true) > 0) { + throw new InvalidParameterValueException("The IP range can't be deleted because it has allocated public IP addresses."); + } + // Delete all public IPs in the VLAN if (!deletePublicIPRange(vlanDbId)) { return false; @@ -2143,33 +2057,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return true; } - @DB - protected boolean savePublicIPRangeForAccount(String startIP, String endIP, long zoneId, long vlanDbId, long accountId, long domainId) { - IPRangeConfig config = new IPRangeConfig(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - long startIPLong = NetUtils.ip2Long(startIP); - long endIPLong = NetUtils.ip2Long(endIP); - Vector ips = config.savePublicIPRange(txn, startIPLong, endIPLong, zoneId, vlanDbId); - List skip = new ArrayList(ips.size()); - for (String ip : ips) { - skip.add(NetUtils.ip2Long(ip)); - } - for (long ip = startIPLong; ip <= endIPLong; ip++) { - if (skip.contains(ip)) { - continue; - } - - IPAddressVO addr = _publicIpAddressDao.findById(new Ip(ip)); - addr.setAllocatedInDomainId(domainId); - addr.setAllocatedTime(new Date()); - addr.setAllocatedToAccountId(accountId); - _publicIpAddressDao.update(addr.getAddress(), addr); - } - txn.commit(); - return true; - } - @DB protected List savePrivateIPRange(String startIP, String endIP, long podId, long zoneId) { Transaction txn = Transaction.currentTxn(); @@ -2474,10 +2361,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (vlan == null) { throw new InvalidParameterValueException("Please specify a valid IP range id."); } - -// if (vlan.getNetworkId() != null) { -// throw new InvalidParameterValueException("Fail to delete a vlan range as there are networks associated with it"); -// } return deleteVlanAndPublicIpRange(userId, vlanDbId); @@ -2789,4 +2672,39 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return _accountMgr.getAccount(accountId); } + + @Override + public List listNetworkOfferings(TrafficType trafficType, boolean systemOnly) { + Filter searchFilter = new Filter(NetworkOfferingVO.class, "created", false, null, null); + SearchCriteria sc = _networkOfferingDao.createSearchCriteria(); + if (trafficType != null) { + sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType); + } + sc.addAnd("systemOnly", SearchCriteria.Op.EQ, systemOnly); + + return _networkOfferingDao.search(sc, searchFilter); + } + + @Override @DB + public boolean deleteAccountSpecificVirtualRanges(long accountId) { + List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId); + boolean result = true; + if (maps != null && !maps.isEmpty()) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (AccountVlanMapVO map : maps) { + if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId())) { + result = false; + } + } + if (result) { + txn.commit(); + } else { + s_logger.error("Failed to delete account specific virtual ip ranges for account id=" + accountId); + } + } else { + s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to delete"); + } + return result; + } } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index a6cb5ff5bef..fdb8a2a0685 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -20,6 +20,7 @@ package com.cloud.network; import java.util.List; import java.util.Map; +import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DeployDestination; @@ -27,6 +28,8 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; @@ -40,7 +43,6 @@ import com.cloud.user.Account; import com.cloud.user.AccountVO; import com.cloud.utils.Pair; import com.cloud.utils.net.Ip; -import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -89,16 +91,6 @@ public interface NetworkManager extends NetworkService { */ public boolean releasePublicIpAddress(Ip ipAddress, long ownerId, long userId); - /** - * Associates or disassociates a list of public IP address for a router. - * @param router router object to send the association to - * @param ipAddrList list of public IP addresses - * @param add true if associate, false if disassociate - * @param vmId - * @return - */ - boolean associateIP(DomainRouterVO router, List ipAddrList, boolean add, long vmId) throws ConcurrentOperationException; - /** * Lists IP addresses that belong to VirtualNetwork VLANs * @param accountId - account that the IP address should belong to @@ -149,5 +141,18 @@ public interface NetworkManager extends NetworkService { void shutdownNetwork(long networkId); boolean destroyNetwork(long networkId, long callerUserId); - + + Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String startIP, String endIP, String netmask, String vlanId, String networkDomain, Account owner) throws InvalidParameterValueException, PermissionDeniedException; + + /** + * Associates an ip address list to an account. The list of ip addresses are all addresses associated with the given vlan id. + * @param userId + * @param accountId + * @param zoneId + * @param vlanId + * @throws InsufficientAddressCapacityException + * @throws + */ + boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId) throws InsufficientAddressCapacityException, + ConcurrentOperationException, ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 5d0e38893a9..bbe8b78f8de 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -48,6 +48,7 @@ import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceLimitDao; +import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; @@ -123,7 +124,6 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -138,36 +138,58 @@ import com.cloud.vm.dao.UserVmDao; /** * NetworkManagerImpl implements NetworkManager. */ -@Local(value={NetworkManager.class, NetworkService.class}) +@Local(value = { NetworkManager.class, NetworkService.class }) public class NetworkManagerImpl implements NetworkManager, NetworkService, Manager { private static final Logger s_logger = Logger.getLogger(NetworkManagerImpl.class); String _name; - @Inject DataCenterDao _dcDao = null; - @Inject VlanDao _vlanDao = null; - @Inject IPAddressDao _ipAddressDao = null; - @Inject AccountDao _accountDao = null; - @Inject DomainDao _domainDao = null; - @Inject UserStatisticsDao _userStatsDao = null; - @Inject EventDao _eventDao = null; - @Inject ConfigurationDao _configDao; - @Inject UserVmDao _vmDao = null; - @Inject ResourceLimitDao _limitDao = null; - @Inject CapacityDao _capacityDao = null; - @Inject AlertManager _alertMgr; - @Inject AccountManager _accountMgr; - @Inject ConfigurationManager _configMgr; - @Inject AccountVlanMapDao _accountVlanMapDao; - @Inject NetworkOfferingDao _networkOfferingDao = null; - @Inject NetworkDao _networksDao = null; - @Inject NicDao _nicDao = null; - @Inject RulesManager _rulesMgr; - @Inject LoadBalancingRulesManager _lbMgr; - @Inject UsageEventDao _usageEventDao; - @Inject PodVlanMapDao _podVlanMapDao; - @Inject(adapter=NetworkGuru.class) + @Inject + DataCenterDao _dcDao = null; + @Inject + VlanDao _vlanDao = null; + @Inject + IPAddressDao _ipAddressDao = null; + @Inject + AccountDao _accountDao = null; + @Inject + DomainDao _domainDao = null; + @Inject + UserStatisticsDao _userStatsDao = null; + @Inject + EventDao _eventDao = null; + @Inject + ConfigurationDao _configDao; + @Inject + UserVmDao _vmDao = null; + @Inject + ResourceLimitDao _limitDao = null; + @Inject + CapacityDao _capacityDao = null; + @Inject + AlertManager _alertMgr; + @Inject + AccountManager _accountMgr; + @Inject + ConfigurationManager _configMgr; + @Inject + AccountVlanMapDao _accountVlanMapDao; + @Inject + NetworkOfferingDao _networkOfferingDao = null; + @Inject + NetworkDao _networksDao = null; + @Inject + NicDao _nicDao = null; + @Inject + RulesManager _rulesMgr; + @Inject + LoadBalancingRulesManager _lbMgr; + @Inject + UsageEventDao _usageEventDao; + @Inject + PodVlanMapDao _podVlanMapDao; + @Inject(adapter = NetworkGuru.class) Adapters _networkGurus; - @Inject(adapter=NetworkElement.class) + @Inject(adapter = NetworkElement.class) Adapters _networkElements; private HashMap _systemNetworks = new HashMap(5); @@ -178,22 +200,22 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag SearchBuilder AssignIpAddressSearch; SearchBuilder AssignIpAddressFromPodVlanSearch; SearchBuilder IpAddressSearch; - + int _networkGcWait; int _networkGcInterval; String _networkDomain; private Map _configs; - + HashMap _lastNetworkIdsToFree = new HashMap(); @Override public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, owner, type, networkId, false, true); + return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true); } - - @DB - public PublicIp fetchNewPublicIp(long dcId, Long podId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign) throws InsufficientAddressCapacityException { + + @DB + public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign) throws InsufficientAddressCapacityException { Transaction txn = Transaction.currentTxn(); txn.start(); SearchCriteria sc = null; @@ -204,37 +226,42 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc = AssignIpAddressSearch.create(); } + if (vlanDbId != null) { + sc.addAnd("vlanId", SearchCriteria.Op.EQ, vlanDbId); + } + sc.setParameters("dc", dcId); - - //for direct network take ip addresses only from the vlans belonging to the network + + // for direct network take ip addresses only from the vlans belonging to the network if (vlanUse == VlanType.DirectAttached) { sc.setJoinParameters("vlan", "networkId", networkId); } sc.setJoinParameters("vlan", "type", vlanUse); - + Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l); - + List addrs = _ipAddressDao.lockRows(sc, filter, true); - + if (addrs.size() == 0) { throw new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); } - + assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size(); - + IPAddressVO addr = addrs.get(0); - addr.setSourceNat(sourceNat); + addr.setSourceNat(sourceNat); addr.setAllocatedTime(new Date()); addr.setAllocatedInDomainId(owner.getDomainId()); addr.setAllocatedToAccountId(owner.getId()); + addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); - + if (vlanUse == VlanType.DirectAttached) { addr.setState(IpAddress.State.Allocated); } else { addr.setAssociatedWithNetworkId(networkId); } - + if (!_ipAddressDao.update(addr.getAddress(), addr)) { throw new CloudRuntimeException("Found address to allocate but unable to update: " + addr); } @@ -243,23 +270,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getAccountId(), dcId, isSourceNat, addr.getAddress().toString()); _usageEventDao.persist(usageEvent); } - + txn.commit(); long macAddress = NetUtils.createSequenceBasedMacAddress(addr.getMacAddress()); return new PublicIp(addr, _vlanDao.findById(addr.getVlanId()), macAddress); } - + @Override @DB public PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException { assert (network.getTrafficType() != null) : "You're asking for a source nat but your network can't participate in source nat. What do you have to say for yourself?"; - + long dcId = network.getDataCenterId(); long ownerId = owner.getId(); PublicIp ip = null; - + Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -273,18 +300,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } IPAddressVO sourceNat = null; - List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, dcId, null); + List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, dcId, null); if (addrs.size() == 0) { // Check that the maximum number of public IPs for the given accountId will not be exceeded if (_accountMgr.resourceLimitExceeded(owner, ResourceType.public_ip)) { throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); } - + if (s_logger.isDebugEnabled()) { s_logger.debug("assigning a new ip address in " + dcId + " to " + owner); - } + } + + //If account has Account specific ip ranges, try to allocate ip from there + Long vlanId = null; + List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId); + if (maps != null && !maps.isEmpty()) { + vlanId = maps.get(0).getVlanDbId(); + } - ip = fetchNewPublicIp(dcId, null, owner, VlanType.VirtualNetwork, network.getId(), true, false); + ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false); sourceNat = ip.ip(); sourceNat.setState(IpAddress.State.Allocated); _ipAddressDao.update(sourceNat.getAddress(), sourceNat); @@ -293,18 +327,17 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountMgr.incrementResourceCount(ownerId, ResourceType.public_ip); } else { // Account already has ip addresses - for (IPAddressVO addr : addrs) { if (addr.isSourceNat()) { sourceNat = addr; break; } } - - assert(sourceNat != null) : "How do we get a bunch of ip addresses but none of them are source nat? account=" + ownerId + "; dc=" + dcId; + + assert (sourceNat != null) : "How do we get a bunch of ip addresses but none of them are source nat? account=" + ownerId + "; dc=" + dcId; ip = new PublicIp(sourceNat, _vlanDao.findById(sourceNat.getVlanId()), NetUtils.createSequenceBasedMacAddress(sourceNat.getMacAddress())); } - + UserStatisticsVO stats = _userStatsDao.findBy(ownerId, dcId, null, null); if (stats == null) { if (s_logger.isDebugEnabled()) { @@ -317,7 +350,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return ip; } finally { if (owner != null) { - if(s_logger.isDebugEnabled()) { + if (s_logger.isDebugEnabled()) { s_logger.debug("Releasing lock account " + ownerId); } @@ -329,96 +362,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - - - @Override - public boolean associateIP(final DomainRouterVO router, final List ipAddrList, final boolean add, long vmId) { -// Commands cmds = new Commands(OnError.Continue); -// boolean sourceNat = false; -// Map> vlanIpMap = new HashMap>(); -// for (final String ipAddress: ipAddrList) { -// IPAddressVO ip = _ipAddressDao.findById(new Ip(ipAddress)); -// -// VlanVO vlan = _vlanDao.findById(ip.getVlanId()); -// ArrayList ipList = vlanIpMap.get(vlan.getId()); -// if (ipList == null) { -// ipList = new ArrayList(); -// } -// ipList.add(ip); -// vlanIpMap.put(vlan, ipList); -// } -// for (Map.Entry> vlanAndIp: vlanIpMap.entrySet()) { -// boolean firstIP = true; -// ArrayList ipList = vlanAndIp.getValue(); -// Collections.sort(ipList, new Comparator() { -// @Override -// public int compare(IPAddressVO o1, IPAddressVO o2) { -// return o1.getAddress().compareTo(o2.getAddress()); -// } }); -// -// for (final IPAddressVO ip: ipList) { -// sourceNat = ip.isSourceNat(); -// VlanVO vlan = vlanAndIp.getKey(); -// String vlanId = vlan.getVlanTag(); -// String vlanGateway = vlan.getVlanGateway(); -// String vlanNetmask = vlan.getVlanNetmask(); -// -// String vifMacAddress = null; -// if (firstIP && add) { -// String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId()); -// vifMacAddress = macAddresses[1]; -// } -// String vmGuestAddress = null; -// if(vmId!=0){ -// vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); -// } -// -// //cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress)); -// -// firstIP = false; -// } -// } -// -// Answer[] answers = null; -// try { -// answers = _agentMgr.send(router.getHostId(), cmds); -// } catch (final AgentUnavailableException e) { -// s_logger.warn("Agent unavailable", e); -// return false; -// } catch (final OperationTimedoutException e) { -// s_logger.warn("Timed Out", e); -// return false; -// } -// -// if (answers == null) { -// return false; -// } -// -// if (answers.length != ipAddrList.size()) { -// return false; -// } -// -// // FIXME: this used to be a loop for all answers, but then we always returned the -// // first one in the array, so what should really be done here? -// if (answers.length > 0) { -// Answer ans = answers[0]; -// return ans.getResult(); -// } - - return true; - } - - /** Returns the target account for an api command - * @param accountName - non-null if the account name was passed in in the command - * @param domainId - non-null if the domainId was passed in in the command. + /** + * Returns the target account for an api command + * + * @param accountName + * - non-null if the account name was passed in in the command + * @param domainId + * - non-null if the domainId was passed in in the command. * @return */ - protected Account getAccountForApiCommand(String accountName, Long domainId) throws InvalidParameterValueException, PermissionDeniedException{ + protected Account getAccountForApiCommand(String accountName, Long domainId) throws InvalidParameterValueException, PermissionDeniedException { Account account = UserContext.current().getCaller(); if (_accountMgr.isAdmin(account.getType())) { - //The admin is making the call, determine if it is for someone else or for himself + // The admin is making the call, determine if it is for someone else or for himself if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, , permission denied"); @@ -434,13 +392,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { // the admin is calling the api on his own behalf return account; - } - } + } + } return account; } - + public boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException { - List userIps = _ipAddressDao.listByNetwork(network.getId()); + List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId()); List publicIps = new ArrayList(); if (userIps != null && !userIps.isEmpty()) { for (IPAddressVO userIp : userIps) { @@ -448,7 +406,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag publicIps.add(publicIp); } } - + boolean success = true; for (NetworkElement element : _networkElements) { try { @@ -462,7 +420,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - + if (success) { for (IPAddressVO addr : userIps) { if (addr.getState() == IpAddress.State.Allocating) { @@ -474,22 +432,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - + return success; } - + @Override public List getVirtualNetworksOwnedByAccountInZone(String accountName, long domainId, long zoneId) { Account owner = _accountMgr.getActiveAccount(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } - + return _networksDao.listBy(owner.getId(), zoneId, GuestIpType.Virtual); } - @Override @DB - public IpAddress associateIP(AssociateIPAddrCmd cmd) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { + @Override + @DB + public IpAddress associateIP(AssociateIPAddrCmd cmd) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { String accountName = cmd.getAccountName(); long domainId = cmd.getDomainId(); Long zoneId = cmd.getZoneId(); @@ -500,9 +459,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } - + _accountMgr.checkAccess(caller, owner); - + long ownerId = owner.getId(); Long networkId = cmd.getNetworkId(); Network network = null; @@ -515,7 +474,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag PublicIp ip = null; boolean success = false; - + Transaction txn = Transaction.currentTxn(); Account accountToLock = null; try { @@ -541,16 +500,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } txn.start(); - ip = fetchNewPublicIp(zoneId, null, owner, VlanType.VirtualNetwork, network.getId(), false, false); - + ip = fetchNewPublicIp(zoneId, null, null, owner, VlanType.VirtualNetwork, network.getId(), false, false); + if (ip == null) { 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()); txn.commit(); @@ -561,7 +520,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { s_logger.warn("Failed to associate ip address " + ip + " for account " + owner.getId() + " in zone " + network.getDataCenterId()); } - + return ip; } catch (ResourceUnavailableException e) { s_logger.error("Unable to associate ip address due to resource unavailable exception", e); @@ -571,7 +530,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountDao.releaseFromLockTable(ownerId); s_logger.debug("Associate IP address lock released"); } - + if (!success) { if (ip != null) { try { @@ -598,11 +557,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (ip == null) { return true; } - + if (s_logger.isDebugEnabled()) { s_logger.debug("Releasing ip " + addr + "; sourceNat = " + ip.isSourceNat()); } - + boolean success = true; try { if (!_rulesMgr.revokeAllRules(addr, userId)) { @@ -613,12 +572,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.warn("Unable to revoke all the port forwarding rules for ip " + ip, e); success = false; } - + if (!_lbMgr.removeAllLoadBalanacers(addr)) { s_logger.warn("Unable to revoke all the load balancer rules for ip " + ip); success = false; } - + if (ip.getAssociatedWithNetworkId() != null) { Network network = _networksDao.findById(ip.getAssociatedWithNetworkId()); try { @@ -630,7 +589,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new CloudRuntimeException("We should nver get to here because we used true when applyIpAssociations", e); } } - + if (success) { _ipAddressDao.unassignIpAddress(addr); s_logger.debug("released a public ip: " + addr); @@ -638,17 +597,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ownerId, ip.getDataCenterId(), 0, addr.toString()); _usageEventDao.persist(usageEvent); } - } - - return success; - } - private Integer getIntegerConfigValue(String configKey, Integer dflt) { - String value = _configs.get(configKey); - if (value != null) { - return Integer.parseInt(value); + _accountMgr.decrementResourceCount(ownerId, ResourceType.public_ip); } - return dflt; + + return success; } @Override @@ -658,7 +611,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _configs = _configDao.getConfiguration("AgentManager", params); _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600); _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); - + _configs = _configDao.getConfiguration("Network", params); _networkDomain = _configs.get(Config.GuestDomainSuffix.key()); @@ -677,28 +630,31 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO guestNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SysteGuestNetwork, TrafficType.Guest); guestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(guestNetworkOffering); _systemNetworks.put(NetworkOfferingVO.SysteGuestNetwork, guestNetworkOffering); - - NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, false, false, null, null, null, true, Availability.Required, false, false, false, false, false, false, false); + + NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, false, false, null, null, null, true, Availability.Required, false, false, false, false, + false, false, false); defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestNetworkOffering); - NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, false, false, null, null, null, true, Availability.Required, false, false, false, false, false, false, false); + NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, false, false, null, null, null, true, Availability.Required, false, false, false, false, false, + false, false); defaultGuestDirectNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectNetworkOffering); - + AccountsUsingNetworkSearch = _accountDao.createSearchBuilder(); SearchBuilder networkAccountSearch = _networksDao.createSearchBuilderForAccount(); AccountsUsingNetworkSearch.join("nc", networkAccountSearch, AccountsUsingNetworkSearch.entity().getId(), networkAccountSearch.entity().getAccountId(), JoinType.INNER); networkAccountSearch.and("config", networkAccountSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); networkAccountSearch.and("owner", networkAccountSearch.entity().isOwner(), SearchCriteria.Op.EQ); AccountsUsingNetworkSearch.done(); - + AssignIpAddressSearch = _ipAddressDao.createSearchBuilder(); AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ); AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL); + AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.EQ); SearchBuilder vlanSearch = _vlanDao.createSearchBuilder(); vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ); vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ); AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressSearch.done(); - + AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder(); AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ); AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL); @@ -707,10 +663,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ); SearchBuilder podVlanMapSB = _podVlanMapDao.createSearchBuilder(); podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ); - AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); + AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressFromPodVlanSearch.done(); - + IpAddressSearch = _ipAddressDao.createSearchBuilder(); IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ); IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ); @@ -718,14 +674,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ); IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER); IpAddressSearch.done(); - + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger")); s_logger.info("Network Manager is configured."); return true; } - + @Override public String getName() { return _name; @@ -763,7 +719,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return setupNetwork(owner, offering, null, plan, name, displayText, isShared, isDefault); } - @Override @DB + @Override + @DB public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean isShared, boolean isDefault) throws ConcurrentOperationException { Transaction.currentTxn(); Account locked = _accountDao.acquireInLockTable(owner.getId()); @@ -771,7 +728,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new ConcurrentOperationException("Unable to acquire lock on " + owner); } try { - + if (predefined == null || (predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) { List configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId()); if (configs.size() > 0) { @@ -780,40 +737,40 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } return configs; } - } - + } + List configs = new ArrayList(); - + long related = -1; - + for (NetworkGuru guru : _networkGurus) { Network config = guru.design(offering, plan, predefined, owner); if (config == null) { continue; } - + if (config.getId() != -1) { if (config instanceof NetworkVO) { - configs.add((NetworkVO)config); + configs.add((NetworkVO) config); } else { configs.add(_networksDao.findById(config.getId())); } continue; } - + long id = _networksDao.getNextInSequence(Long.class, "id"); if (related == -1) { related = id; - } - + } + NetworkVO vo = new NetworkVO(id, config, offering.getId(), plan.getDataCenterId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, isShared, isDefault); configs.add(_networksDao.persist(vo, vo.getGuestType() != null)); } - + if (configs.size() < 1) { throw new CloudRuntimeException("Unable to convert network offering to network profile: " + offering.getId()); } - + return configs; } finally { s_logger.debug("Releasing lock for " + locked); @@ -834,7 +791,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return offerings; } - @Override @DB + @Override + @DB public void allocate(VirtualMachineProfile vm, List> networks) throws InsufficientCapacityException, ConcurrentOperationException { Transaction txn = Transaction.currentTxn(); txn.start(); @@ -855,11 +813,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag requested.setMode(config.getMode()); } NicProfile profile = concierge.allocate(config, requested, vm); - + if (vm != null && vm.getVirtualMachine().getType() == Type.User && config.isDefault()) { profile.setDefaultNic(true); } - + if (profile == null) { continue; } @@ -890,7 +848,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag deviceIds[devId] = true; nics.add(vo); - + NetworkOffering no = _configMgr.getNetworkOffering(config.getNetworkOfferingId()); Integer networkRate = _configMgr.getNetworkRate(no.getId()); vm.addNic(new NicProfile(vo, network.first(), vo.getBroadcastUri(), vo.getIsolationUri(), networkRate)); @@ -906,10 +864,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) { if (profile.getDeviceId() != null) { vo.setDeviceId(profile.getDeviceId()); - } else if (deviceId != null ) { + } else if (deviceId != null) { vo.setDeviceId(deviceId++); } - + vo.setReservationStrategy(profile.getReservationStrategy()); vo.setDefaultNic(profile.isDefaultNic()); @@ -965,7 +923,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag to.setDns1(profile.getDns1()); to.setDns2(profile.getDns2()); } - + Integer networkRate = _configMgr.getNetworkRate(config.getNetworkOfferingId()); to.setNetworkRateMbps(networkRate); @@ -998,7 +956,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); network.setReservationId(context.getReservationId()); network.setState(Network.State.Implementing); - + _networksDao.update(networkId, network); Network result = guru.implement(network, offering, dest, context); @@ -1016,7 +974,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } element.implement(network, offering, dest, context); } - + network.setState(Network.State.Implemented); _networksDao.update(network.getId(), network); implemented.set(guru, network); @@ -1031,7 +989,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _networksDao.releaseFromLockTable(networkId); } } - + @DB protected void updateNic(NicVO nic, long networkId, int count) { Transaction txn = Transaction.currentTxn(); @@ -1080,7 +1038,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag nic.setState(Nic.State.Reserved); updateNic(nic, network.getId(), 1); } - + for (NetworkElement element : _networkElements) { if (s_logger.isDebugEnabled()) { s_logger.debug("Asking " + element.getName() + " to prepare for " + nic); @@ -1091,7 +1049,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag vmProfile.addNic(profile); } } - + @Override public void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest) { List nics = _nicDao.listBy(vm.getId()); @@ -1099,13 +1057,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Network network = _networksDao.findById(nic.getNetworkId()); NetworkOffering no = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); Integer networkRate = _configMgr.getNetworkRate(no.getId()); - + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate); - + vm.addNic(profile); } } - @Override public void release(VirtualMachineProfile vmProfile, boolean forced) { @@ -1131,7 +1088,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag nic.setState(Nic.State.Allocated); updateNic(nic, network.getId(), -1); } - } + } } } @@ -1158,7 +1115,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Verify input parameters Account accountByIp = findAccountByIpAddress(ipAddress); - if(accountByIp == null) { + if (accountByIp == null) { throw new InvalidParameterValueException("Unable to find account owner for ip " + ipAddress); } @@ -1191,8 +1148,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // FIXME: is the user visible in the admin account's domain???? if (!BaseCmd.isAdmin(account.getType())) { if (s_logger.isDebugEnabled()) { - s_logger.debug("permission denied disassociating IP address " + ipAddress + "; acct: " + accountId + "; ip (acct / dc / dom / alloc): " - + ipVO.getAllocatedToAccountId() + " / " + ipVO.getDataCenterId() + " / " + ipVO.getAllocatedInDomainId() + " / " + ipVO.getAllocatedTime()); + s_logger.debug("permission denied disassociating IP address " + ipAddress + "; acct: " + accountId + "; ip (acct / dc / dom / alloc): " + ipVO.getAllocatedToAccountId() + " / " + ipVO.getDataCenterId() + " / " + + ipVO.getAllocatedInDomainId() + " / " + ipVO.getAllocatedTime()); } throw new PermissionDeniedException("User/account does not own supplied address"); } @@ -1211,16 +1168,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new IllegalArgumentException("only ip addresses that belong to a virtual network may be disassociated."); } - //Check for account wide pool. It will have an entry for account_vlan_map. - if (_accountVlanMapDao.findAccountVlanMap(accountId,ipVO.getVlanId()) != null){ + // Check for account wide pool. It will have an entry for account_vlan_map. + if (_accountVlanMapDao.findAccountVlanMap(accountId, ipVO.getVlanId()) != null) { throw new PermissionDeniedException(ipAddress + " belongs to Account wide IP pool and cannot be disassociated"); } - boolean success = releasePublicIpAddress(ipAddress, accountId, userId); - if (success) { - _accountMgr.decrementResourceCount(accountId, ResourceType.public_ip); - } - return success; + return releasePublicIpAddress(ipAddress, accountId, userId); } catch (PermissionDeniedException pde) { throw pde; @@ -1232,7 +1185,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - @Override public List getAccountsUsingNetwork(long networkId) { SearchCriteria sc = AccountsUsingNetworkSearch.create(); @@ -1265,27 +1217,28 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (mac == null) { throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId); } - + return mac; } - @Override @DB + @Override + @DB public Network getNetwork(long id) { return _networksDao.findById(id); } - + @Override public List getRemoteAccessVpnElements() { List elements = new ArrayList(); for (NetworkElement element : _networkElements) { if (element instanceof RemoteAccessVpnElement) { - elements.add((RemoteAccessVpnElement)element); + elements.add((RemoteAccessVpnElement) element); } } - + return elements; } - + @Override public void cleanupNics(VirtualMachineProfile vm) { List nics = _nicDao.listBy(vm.getId()); @@ -1299,11 +1252,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _nicDao.remove(nic.getId()); } } - - @Override @DB - public Network createNetwork(CreateNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{ - Account ctxAccount = UserContext.current().getCaller(); - Long userId = UserContext.current().getCallerUserId(); + + @Override + public Network createNetwork(CreateNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { Long networkOfferingId = cmd.getNetworkOfferingId(); Long zoneId = cmd.getZoneId(); String gateway = cmd.getGateway(); @@ -1311,30 +1262,43 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String endIP = cmd.getEndIp(); String netmask = cmd.getNetmask(); String networkDomain = cmd.getNetworkDomain(); - String cidr = null; - Boolean isDefault = cmd.isDefault(); - if (gateway != null && netmask != null) { - cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); - } - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); String vlanId = cmd.getVlan(); String name = cmd.getNetworkName(); String displayText = cmd.getDisplayText(); Boolean isShared = cmd.getIsShared(); + Boolean isDefault = cmd.isDefault(); - //if end ip is not specified, default it to startIp + //finalize owner for the network + Account ctxAccount = UserContext.current().getCaller(); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + + Account owner = _accountMgr.finalizeOwner(ctxAccount, accountName, domainId); + + return createNetwork(networkOfferingId, name, displayText, isShared, isDefault, zoneId, gateway, startIP, endIP, netmask, vlanId, networkDomain, owner); + } + + @Override @DB + public Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String startIP, String endIP, String netmask, String vlanId, String networkDomain, Account owner) throws InvalidParameterValueException, PermissionDeniedException { + Account ctxAccount = UserContext.current().getCaller(); + Long userId = UserContext.current().getCallerUserId(); + String cidr = null; + if (gateway != null && netmask != null) { + cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + } + + // if end ip is not specified, default it to startIp if (endIP == null && startIP != null) { endIP = startIP; } - - //Check if network offering exists + + // Check if network offering exists NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); if (networkOffering == null || networkOffering.isSystemOnly()) { throw new InvalidParameterValueException("Unable to find network offeirng by id " + networkOfferingId); } - - //allow isDefault to be set only for Virtual network + + // allow isDefault to be set only for Virtual network if (networkOffering.getTrafficType() == TrafficType.Guest) { if (isDefault != null) { throw new InvalidParameterValueException("Can specify isDefault parameter only for Public network. "); @@ -1346,113 +1310,111 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag isDefault = false; } } - - //If networkDomain is not specified, take it from the global configuration + + // If networkDomain is not specified, take it from the global configuration if (networkDomain == null) { networkDomain = _networkDomain; } - - //Check if zone exists + + // Check if zone exists if (zoneId == null || ((_dcDao.findById(zoneId)) == null)) { throw new InvalidParameterValueException("Please specify a valid zone."); - } - + } + DataCenter zone = _dcDao.findById(zoneId); if (zone.getNetworkType() == NetworkType.Basic) { throw new InvalidParameterValueException("Network creation is not allowed in zone with network type " + NetworkType.Basic); } - - Account owner = _accountMgr.finalizeOwner(ctxAccount, accountName, domainId); - - //Don't allow to create network with vlan that already exists in the system + + // Don't allow to create network with vlan that already exists in the system if (vlanId != null) { - String uri ="vlan://" + vlanId; + String uri = "vlan://" + vlanId; List networks = _networksDao.listBy(zoneId, uri); if ((networks != null && !networks.isEmpty())) { throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); } } - - //VlanId can be specified only when network offering supports it + + // VlanId can be specified only when network offering supports it if (ctxAccount.getType() == Account.ACCOUNT_TYPE_NORMAL && vlanId != null && !networkOffering.getSpecifyVlan()) { throw new InvalidParameterValueException("Can't specify vlan because network offering doesn't support it"); } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - //Create network - DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null); - NetworkVO userNetwork = new NetworkVO(); - userNetwork.setNetworkDomain(networkDomain); - - //cidr should be set only when the user is admin - if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN) { - if (cidr != null && gateway != null) { - userNetwork.setCidr(cidr); - userNetwork.setGateway(gateway); - if (vlanId != null) { - userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId)); - userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); - if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); - } else { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); - } - } - } - } - - List networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, isShared, isDefault); - Long networkId = null; - - Network network = null; - if (networks == null || networks.isEmpty()) { - txn.rollback(); - throw new CloudRuntimeException("Fail to create a network"); - } else { - network = networks.get(0); - networkId = networks.get(0).getId(); - if (network.getGuestType() == GuestIpType.Virtual) { - s_logger.debug("Creating a source natp ip for " + network); - PublicIp ip = assignSourceNatIpAddress(owner, network, userId); - if (ip == null) { - throw new InsufficientAddressCapacityException("Unable to assign source nat ip address to owner for this network", DataCenter.class, zoneId); - } - } - } - - Long ownerId = owner.getId(); - //Don't pass owner to create vlan when network offering is of type Direct - done to prevent accountVlanMap entry creation when vlan is mapped to network - if (network.getGuestType() == GuestIpType.Direct) { - owner = null; - } - - if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && network.getGuestType() == GuestIpType.Direct && startIP != null && endIP != null && gateway != null) { - //Create vlan ip range - Vlan vlan = _configMgr.createVlanAndPublicIpRange(userId, zoneId, null, startIP, endIP, gateway, netmask, false, vlanId, owner, networkId); - if (vlan == null) { - txn.rollback(); - throw new CloudRuntimeException("Failed to create a vlan"); - } - } - txn.commit(); - - return networks.get(0); - } catch (Exception ex) { - s_logger.warn("Unexpected exception while creating network ", ex); - txn.rollback(); - } finally { - txn.close(); - } - return null; + + Transaction txn = Transaction.currentTxn(); + txn.start(); + try { + // Create network + DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null); + NetworkVO userNetwork = new NetworkVO(); + userNetwork.setNetworkDomain(networkDomain); + + // cidr should be set only when the user is admin + if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN) { + if (cidr != null && gateway != null) { + userNetwork.setCidr(cidr); + userNetwork.setGateway(gateway); + if (vlanId != null) { + userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId)); + userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); + if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); + } else { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); + } + } + } + } + + List networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, isShared, isDefault); + Long networkId = null; + + Network network = null; + if (networks == null || networks.isEmpty()) { + txn.rollback(); + throw new CloudRuntimeException("Fail to create a network"); + } else { + network = networks.get(0); + networkId = networks.get(0).getId(); + if (network.getGuestType() == GuestIpType.Virtual) { + s_logger.debug("Creating a source natp ip for " + network); + PublicIp ip = assignSourceNatIpAddress(owner, network, userId); + if (ip == null) { + throw new InsufficientAddressCapacityException("Unable to assign source nat ip address to owner for this network", DataCenter.class, zoneId); + } + } + } + + // Don't pass owner to create vlan when network offering is of type Direct - done to prevent accountVlanMap entry + // creation when vlan is mapped to network + if (network.getGuestType() == GuestIpType.Direct) { + owner = null; + } + + if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && network.getGuestType() == GuestIpType.Direct && startIP != null && endIP != null && gateway != null) { + // Create vlan ip range + Vlan vlan = _configMgr.createVlanAndPublicIpRange(userId, zoneId, null, startIP, endIP, gateway, netmask, false, vlanId, owner, networkId); + if (vlan == null) { + txn.rollback(); + throw new CloudRuntimeException("Failed to create a vlan"); + } + } + txn.commit(); + + return networks.get(0); + } catch (Exception ex) { + s_logger.warn("Unexpected exception while creating network ", ex); + txn.rollback(); + } finally { + txn.close(); + } + return null; } - + @Override - public List searchForNetworks(ListNetworksCmd cmd) { - Object id = cmd.getId(); + public List searchForNetworks(ListNetworksCmd cmd) { + Object id = cmd.getId(); Object keyword = cmd.getKeyword(); - Long zoneId= cmd.getZoneId(); + Long zoneId = cmd.getZoneId(); Account account = UserContext.current().getCaller(); Long domainId = cmd.getDomainId(); String accountName = cmd.getAccountName(); @@ -1462,16 +1424,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Boolean isShared = cmd.getIsShared(); Boolean isDefault = cmd.isDefault(); Long accountId = null; - + if (isSystem == null) { isSystem = false; } - - //Account/domainId parameters and isSystem are mutually exclusive + + // Account/domainId parameters and isSystem are mutually exclusive if (isSystem && (accountName != null || domainId != null)) { throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified"); } - + if (_accountMgr.isAdmin(account.getType())) { if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { @@ -1493,83 +1455,84 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag domainId = account.getDomainId(); accountId = account.getId(); } - + Filter searchFilter = new Filter(NetworkVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _networksDao.createSearchBuilder(); - - //Don't display networks created of system network offerings - SearchBuilder networkOfferingSearch = _networkOfferingDao.createSearchBuilder(); + + // Don't display networks created of system network offerings + SearchBuilder networkOfferingSearch = _networkOfferingDao.createSearchBuilder(); networkOfferingSearch.and("systemOnly", networkOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ); if (isSystem) { networkOfferingSearch.and("trafficType", networkOfferingSearch.entity().getTrafficType(), SearchCriteria.Op.EQ); - } - sb.join("networkOfferingSearch", networkOfferingSearch, sb.entity().getNetworkOfferingId(), networkOfferingSearch.entity().getId(), JoinBuilder.JoinType.INNER); - - SearchBuilder zoneSearch = _dcDao.createSearchBuilder(); + } + sb.join("networkOfferingSearch", networkOfferingSearch, sb.entity().getNetworkOfferingId(), networkOfferingSearch.entity().getId(), JoinBuilder.JoinType.INNER); + + SearchBuilder zoneSearch = _dcDao.createSearchBuilder(); zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ); sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER); - + SearchCriteria sc = sb.create(); - + if (!isSystem) { sc.setJoinParameters("networkOfferingSearch", "systemOnly", false); } else { sc.setJoinParameters("networkOfferingSearch", "systemOnly", true); sc.setJoinParameters("zoneSearch", "networkType", NetworkType.Advanced.toString()); } - + if (keyword != null) { SearchCriteria ssc = _networksDao.createSearchCriteria(); ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } + } if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); } - + if (zoneId != null) { sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } - + if (type != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, type); } - + if (!isSystem && (isShared == null || !isShared) && accountName != null && domainId != null) { - sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); - sc.addAnd("isShared", SearchCriteria.Op.EQ, false); + sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); + sc.addAnd("isShared", SearchCriteria.Op.EQ, false); } - + if (isShared != null) { sc.addAnd("isShared", SearchCriteria.Op.EQ, isShared); } - + if (isDefault != null) { sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); } - + if (trafficType != null) { sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType); } - - List networks = _networksDao.search(sc, searchFilter); - + + List networks = _networksDao.search(sc, searchFilter); + return networks; } - - @Override @DB - public boolean deleteNetwork(long networkId) throws InvalidParameterValueException, PermissionDeniedException{ + + @Override + @DB + public boolean deleteNetwork(long networkId) throws InvalidParameterValueException, PermissionDeniedException { Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); - //Verify network id + // Verify network id NetworkVO network = _networksDao.findById(networkId); if (network == null) { throw new InvalidParameterValueException("unable to find network " + networkId); - } - - //Perform permission check + } + + // Perform permission check if (!_accountMgr.isAdmin(caller.getType())) { if (network.getAccountId() != caller.getId()) { throw new PermissionDeniedException("Account " + caller.getAccountName() + " does not own network id=" + networkId + ", permission denied"); @@ -1578,11 +1541,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account owner = _accountMgr.getAccount(network.getAccountId()); _accountMgr.checkAccess(caller, owner); } - - return this.destroyNetwork(networkId, userId); + + return this.destroyNetwork(networkId, userId); } - - @Override @DB + + @Override + @DB public void shutdownNetwork(long networkId) { Transaction txn = Transaction.currentTxn(); txn.start(); @@ -1598,7 +1562,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag network.setState(Network.State.Shutdown); _networksDao.update(network.getId(), network); txn.commit(); - + boolean success = true; for (NetworkElement element : _networkElements) { try { @@ -1617,13 +1581,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag success = false; } } - + txn.start(); if (success) { if (s_logger.isDebugEnabled()) { s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now."); } - NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NetworkGuru guru = _networkGurus.get(network.getGuruName()); guru.destroy(network, _networkOfferingDao.findById(network.getNetworkOfferingId())); network.setBroadcastUri(null); network.setState(Network.State.Allocated); @@ -1635,20 +1599,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } txn.commit(); } - - - @DB @Override + + @DB + @Override public boolean destroyNetwork(long networkId, long callerUserId) { NetworkVO network = _networksDao.findById(networkId); if (network == null) { s_logger.debug("Unable to find network with id: " + networkId); return false; } - - //Shutdown network first + + // Shutdown network first shutdownNetwork(networkId); - - //get updated state for the network + + // get updated state for the network network = _networksDao.findById(networkId); if (network.getState() != Network.State.Allocated && network.getState() != Network.State.Setup) { s_logger.debug("Network is not not in the correct state to be destroyed: " + network.getState()); @@ -1656,6 +1620,22 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } boolean success = true; + + //release ip addresses associated with the network if there are any + List ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId); + if (ipsToRelease != null && !ipsToRelease.isEmpty()) { + for (IPAddressVO ip : ipsToRelease) { + if (!releasePublicIpAddress(ip.getAddress(), ip.getAccountId(), callerUserId)) { + s_logger.warn("Failed to deallocate ip address as a part of network id=" + networkId + " destroy"); + success = false; + } + } + + if (success) { + s_logger.debug("Ip addresses are deallocated successfully as a part of network id=" + networkId + " destroy"); + } + } + for (NetworkElement element : _networkElements) { try { if (s_logger.isDebugEnabled()) { @@ -1673,33 +1653,33 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag success = false; } } - + if (success) { if (s_logger.isDebugEnabled()) { s_logger.debug("Network id=" + networkId + " is destroyed successfully, cleaning up corresponding resources now."); } - NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NetworkGuru guru = _networkGurus.get(network.getGuruName()); Account owner = _accountMgr.getAccount(network.getAccountId()); - + Transaction txn = Transaction.currentTxn(); - txn.start(); + txn.start(); guru.trash(network, _networkOfferingDao.findById(network.getNetworkOfferingId()), owner); + if (!deleteVlansInNetwork(network.getId(), callerUserId)) { success = false; s_logger.warn("Failed to delete network " + network + "; was unable to cleanup corresponding ip ranges"); } else { - //commit transaction only when ips and vlans for the network are released successfully + // commit transaction only when ips and vlans for the network are released successfully network.setState(Network.State.Destroy); _networksDao.update(network.getId(), network); _networksDao.remove(network.getId()); txn.commit(); } - } - + } + return success; } - - + private boolean deleteVlansInNetwork(long networkId, long userId) { List vlans = _vlanDao.listVlansByNetworkId(networkId); boolean result = true; @@ -1707,18 +1687,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!_configMgr.deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), vlan.getId())) { s_logger.warn("Failed to delete vlan " + vlan.getId() + ");"); result = false; - } + } } return result; } - + @Override public boolean applyRules(List rules, boolean continueOnError) throws ResourceUnavailableException { if (rules == null || rules.size() == 0) { s_logger.debug("There are no rules to forward to the network elements"); return true; } - + boolean success = true; Network network = _networksDao.findById(rules.get(0).getNetworkId()); for (NetworkElement ne : _networkElements) { @@ -1733,10 +1713,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag success = false; } } - + return success; } - + public class NetworkGarbageCollector implements Runnable { @Override @@ -1745,7 +1725,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List shutdownList = new ArrayList(); long currentTime = System.currentTimeMillis() >> 10; HashMap stillFree = new HashMap(); - + List networkIds = _networksDao.findNetworksToGarbageCollect(); for (Long networkId : networkIds) { Long time = _lastNetworkIdsToFree.remove(networkId); @@ -1763,9 +1743,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag shutdownList.add(networkId); } } - + _lastNetworkIdsToFree = stillFree; - + for (Long networkId : shutdownList) { try { shutdownNetwork(networkId); @@ -1778,11 +1758,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - + @Override public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { - //This method reapplies Ip addresses, LoadBalancer and PortForwarding rules - Account caller = UserContext.current().getCaller(); + // This method reapplies Ip addresses, LoadBalancer and PortForwarding rules + Account caller = UserContext.current().getCaller(); Long networkId = cmd.getNetworkId(); Network network = null; if (networkId != null) { @@ -1791,7 +1771,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InvalidParameterValueException("Network id is invalid: " + networkId); } } - + Account owner = _accountMgr.getActiveAccount(cmd.getEntityOwnerId()); if (!_accountMgr.isAdmin(caller.getType())) { _accountMgr.checkAccess(caller, network); @@ -1799,26 +1779,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Domain domain = _domainDao.findById(owner.getDomainId()); _accountMgr.checkAccess(caller, domain); } - + s_logger.debug("Restarting network " + networkId + "..."); - + if (!applyIpAssociations(network, false)) { s_logger.warn("Failed to apply ips as a part of network " + networkId + " restart"); return false; } else { s_logger.debug("Ip addresses are reapplied successfully as a part of network " + networkId + " restart"); } - + List lbRules = _lbMgr.listByNetworkId(networkId); - + if (!applyRules(lbRules, true)) { s_logger.warn("Failed to apply load balancing rules as a part of network " + network.getId() + " restart"); return false; } else { s_logger.debug("Load balancing rules are reapplied successfully as a part of network " + networkId + " restart"); } - - //Reapply pf rules + + // Reapply pf rules List pfRules = _rulesMgr.listByNetworkId(networkId); if (!applyRules(pfRules, true)) { s_logger.warn("Failed to apply port forwarding rules as a part of network " + network.getId() + " restart"); @@ -1826,25 +1806,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { s_logger.debug("Port forwarding rules are reapplied successfully as a part of network " + networkId + " restart"); } - + s_logger.debug("Network " + networkId + " is restarted successfully."); return true; } - + @Override public int getActiveNicsInNetwork(long networkId) { return _networksDao.getActiveNicsIn(networkId); } - + @Override public Map> getZoneCapabilities(long zoneId) { DataCenterVO dc = _dcDao.findById(zoneId); if (dc == null) { throw new InvalidParameterValueException("Zone id=" + zoneId + " doesn't exist in the system."); } - - //Get all service providers from the datacenter - Map providers = new HashMap(); + + // Get all service providers from the datacenter + Map providers = new HashMap(); providers.put(Service.Firewall, dc.getFirewallProvider()); providers.put(Service.Lb, dc.getLoadBalancerProvider()); providers.put(Service.Vpn, dc.getVpnProvider()); @@ -1852,9 +1832,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag providers.put(Service.Gateway, dc.getGatewayProvider()); providers.put(Service.UserData, dc.getUserDataProvider()); providers.put(Service.Dhcp, dc.getDhcpProvider()); - + Map> networkCapabilities = new HashMap>(); - + for (NetworkElement element : _networkElements) { if (providers.isEmpty()) { break; @@ -1869,66 +1849,66 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (zoneProvider.equalsIgnoreCase(element.getProvider().getName())) { if (elementCapabilities.containsKey(service)) { Map capabilities = elementCapabilities.get(service); - //Verify if Service support capability + // Verify if Service support capability if (capabilities != null) { - for (Capability capability : capabilities.keySet()) { - assert(service.containsCapability(capability)) : "Capability " + capability.getName() + " is not supported by the service " + service.getName(); + for (Capability capability : capabilities.keySet()) { + assert (service.containsCapability(capability)) : "Capability " + capability.getName() + " is not supported by the service " + service.getName(); } } networkCapabilities.put(service, capabilities); it.remove(); } } - } + } } } } return networkCapabilities; } - + @Override public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) { - //find system public network offering + // find system public network offering Long networkOfferingId = null; List offerings = _networkOfferingDao.listSystemNetworkOfferings(); - for (NetworkOfferingVO offering: offerings) { + for (NetworkOfferingVO offering : offerings) { if (offering.getTrafficType() == trafficType) { networkOfferingId = offering.getId(); break; } } - + if (networkOfferingId == null) { throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType); } - + List networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); if (networks == null) { throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); } return networks.get(0); } - + @Override public PublicIpAddress getPublicIpAddress(Ip ip) { IPAddressVO addr = _ipAddressDao.findById(ip); if (addr == null) { return null; } - + return new PublicIp(addr, _vlanDao.findById(addr.getVlanId()), NetUtils.createSequenceBasedMacAddress(addr.getMacAddress())); } - + @Override public List listPodVlans(long podId) { List vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached); return vlans; } - + @Override public List listNetworksUsedByVm(long vmId, boolean isSystem) { List networks = new ArrayList(); - + List nics = _nicDao.listBy(vmId); if (nics != null) { for (Nic nic : nics) { @@ -1937,10 +1917,61 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (no.isSystemOnly() == isSystem) { networks.add(network); } - } + } } - + return networks; } + @Override @DB + public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId) throws InsufficientAddressCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + Account account = _accountMgr.getActiveAccount(accountId); + if (account == null) { + s_logger.warn("Unable to find active account: " + accountId); + } + + Network network = null; + long allocatedIps = 0; + + //create new Virtual network for the user if it doesn't exist + List networks = getVirtualNetworksOwnedByAccountInZone(account.getAccountName(), account.getDomainId(), zoneId); + if (networks.size() == 0) { + List offerings = _configMgr.listNetworkOfferings(TrafficType.Guest, false); + network = createNetwork(offerings.get(0).getId(), account.getAccountName() + "-network", account.getAccountName() + "-network", false, null, zoneId, null, null, null, null, null, null, account); + + if (network == null){ + s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); + return false; + } else { + //sourceNat ip is allocated as a part of networkCreate + allocatedIps++; + } + } else { + assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete"; + network = networks.get(0); + } + + //Associate ip addresses + long ipCount = _ipAddressDao.countIPs(zoneId, vlanId, false); + if (ipCount > 0) { + while (allocatedIps < ipCount) { + fetchNewPublicIp(zoneId, null, vlanId, account, VlanType.VirtualNetwork, network.getId(), false, true); + allocatedIps++; + } + + if (network.getState() == Network.State.Implemented) { + s_logger.debug("Applying ip associations for vlan id=" + vlanId + " in network " + network); + return applyIpAssociations(network, false); + } else { + s_logger.trace("Network id=" + network.getId() + " is not Implemented, no need to apply ipAssociations"); + return true; + } + } else { + s_logger.trace("Found 0 ips to assign in vlan id=" + vlanId); + return true; + } + } + } diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index f7a179ff1ec..43f4859e068 100644 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -34,15 +34,13 @@ public interface IPAddressDao extends GenericDao { List listByDcIdIpAddress(long dcId, String ipAddress); - List listByNetwork(long networkId); + List listByAssociatedNetwork(long networkId); int countIPs(long dcId, long vlanDbId, boolean onlyCountAllocated); int countIPs(long dcId, Long accountId, String vlanId, String vlanGateway, String vlanNetmask); boolean mark(long dcId, Ip ip); - - List assignAcccountSpecificIps(long accountId, long longValue, Long vlanDbId, boolean sourceNat); int countIPsForDashboard(long dcId, boolean onlyCountAllocated); } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index a587266504b..4a0579fd4be 100644 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -109,35 +109,6 @@ public class IPAddressDaoImpl extends GenericDaoBase implements return update(vo, sc) >= 1; } - @Override - @DB - public List assignAcccountSpecificIps(long accountId, long domainId, Long vlanDbId, boolean sourceNat) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("vlan", vlanDbId); - sc.setParameters("sourceNat", sourceNat); - - List ipList = lockRows(sc, null, true); - List ipStringList = new ArrayList(); - - for (IPAddressVO ip : ipList) { - - ip.setAllocatedToAccountId(accountId); - ip.setAllocatedTime(new Date()); - ip.setAllocatedInDomainId(domainId); - ip.setSourceNat(sourceNat); - ip.setState(State.Allocated); - - if (!update(ip.getAddress(), ip)) { - throw new CloudRuntimeException("Unable to update a locked ip address " + ip.getAddress()); - } - ipStringList.add(ip.getAddress().toString()); - } - txn.commit(); - return ipStringList; - } - /** * @deprecated This method is now deprecated because vlan has been * added. The actual method is now within NetworkManager. @@ -203,7 +174,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implements } @Override - public List listByNetwork(long networkId) { + public List listByAssociatedNetwork(long networkId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("network", networkId); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index ca1707c3b46..c5e68b094f8 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -73,9 +73,6 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.domain.dao.DomainDao; -import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; -import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; @@ -156,7 +153,6 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index af6e0290c06..d7f1f9fbc1f 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -49,6 +49,7 @@ import com.cloud.api.commands.UpdateAccountCmd; import com.cloud.api.commands.UpdateResourceLimitCmd; import com.cloud.api.commands.UpdateUserCmd; import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.ResourceLimitVO; import com.cloud.configuration.dao.ConfigurationDao; @@ -131,6 +132,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Inject private StorageManager _storageMgr; @Inject private TemplateManager _tmpltMgr; @Inject private VirtualNetworkApplianceManager _routerMgr; + @Inject private ConfigurationManager _configMgr; private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker")); @@ -857,21 +859,32 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.info("deleteAccount: Deleted " + numRemoved + " network groups for account " + accountId); //Delete all the networks + boolean networksDeleted = true; s_logger.debug("Deleting networks for account " + account.getId()); List networks = _networkDao.listByOwner(accountId); if (networks != null) { for (NetworkVO network : networks) { if (!_networkMgr.deleteNetwork(network.getId())) { - s_logger.warn("Unable to destroy network " + network + " as a part of account cleanup"); + s_logger.warn("Unable to destroy network " + network + " as a part of account id=" + accountId +" cleanup."); accountCleanupNeeded = true; - } - s_logger.debug("Network " + network.getId() + " successfully deleted."); + networksDeleted = false; + } else { + s_logger.debug("Network " + network.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup."); + } + } + } + + //delete account specific vlans - only when networks are cleaned up successfully + if (networksDeleted) { + if (!_configMgr.deleteAccountSpecificVirtualRanges(accountId)){ + accountCleanupNeeded = true; + } else { + s_logger.debug("Account specific Virtual IP ranges " + " are successfully deleted as a part of account id=" + accountId + " cleanup."); } } return true; } finally { s_logger.info("Cleanup for account " + account.getId() + (accountCleanupNeeded ? " is needed." : " is not needed.")); - if (accountCleanupNeeded) { _accountDao.markForCleanup(accountId); }