Account specific vlan ranges - fixed deleteVlanRange

Conflicts:

	api/src/com/cloud/api/commands/DeleteVlanIpRangeCmd.java
	server/src/com/cloud/configuration/ConfigurationManagerImpl.java
This commit is contained in:
Alena Prokharchyk 2012-04-24 15:43:27 -07:00
parent 8d2a00874b
commit afb97f128b
4 changed files with 78 additions and 19 deletions

View File

@ -12,8 +12,6 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.api.commands;
import java.util.UUID;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;

View File

@ -137,9 +137,10 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
*
* @param userId
* @param vlanDbId
* @param caller TODO
* @return success/failure
*/
boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId);
boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller);
/**
* Converts a comma separated list of tags to a List

View File

@ -38,8 +38,8 @@ import org.apache.log4j.Logger;
import com.cloud.acl.SecurityChecker;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiConstants.LDAPParams;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.CreateDiskOfferingCmd;
import com.cloud.api.commands.CreateNetworkOfferingCmd;
import com.cloud.api.commands.CreateServiceOfferingCmd;
@ -110,6 +110,7 @@ import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.PhysicalNetworkDao;
@ -155,6 +156,7 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.NicDao;
import edu.emory.mathcs.backport.java.util.Arrays;
@ -219,6 +221,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
SwiftManager _swiftMgr;
@Inject
PhysicalNetworkTrafficTypeDao _trafficTypeDao;
@Inject
NicDao _nicDao;
@Inject
FirewallRulesDao _firewallDao;
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class);
@ -2425,24 +2431,78 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
@Override
public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId) {
@DB
public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller) {
VlanVO vlan = _vlanDao.findById(vlanDbId);
if (vlan == null) {
throw new InvalidParameterValueException("Please specify a valid IP range id.");
}
boolean isAccountSpecific = false;
List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlan.getId());
// Check for account wide pool. It will have an entry for account_vlan_map.
if (acctVln != null && !acctVln.isEmpty()) {
isAccountSpecific = true;
}
// 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.");
long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true);
boolean success = true;
if (allocIpCount > 0) {
if (isAccountSpecific) {
try {
vlan = _vlanDao.acquireInLockTable(vlanDbId, 30);
if (vlan == null) {
throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("lock vlan " + vlanDbId + " is acquired");
}
List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
for (IPAddressVO ip : ips) {
if (ip.isOneToOneNat()) {
throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId +
" as ip " + ip + " belonging to the range is used for static nat purposes. Cleanup the rules first");
}
if (ip.isSourceNat() && _nicDao.findByIp4AddressAndNetworkId(ip.getAddress().addr(), ip.getSourceNetworkId()) != null) {
throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId +
" as ip " + ip + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId() +
". Either delete the network, or Virtual Router instance using this ip address");
}
if (_firewallDao.countRulesByIpId(ip.getId()) > 0) {
throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId +
" as ip " + ip + " belonging to the range has firewall rules applied. Cleanup the rules first");
}
//release public ip address here
success = success && _networkMgr.releasePublicIpAddress(ip.getId(), userId, caller);
}
if (!success) {
s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal");
}
} finally {
_vlanDao.releaseFromLockTable(vlanDbId);
}
} else {
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)) {
if (success) {
// Delete all public IPs in the VLAN
if (!deletePublicIPRange(vlanDbId)) {
return false;
}
// Delete the VLAN
return _vlanDao.expunge(vlanDbId);
} else {
return false;
}
// Delete the VLAN
return _vlanDao.expunge(vlanDbId);
}
@Override
@ -2766,8 +2826,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
throw new InvalidParameterValueException("Please specify a valid IP range id.");
}
return deleteVlanAndPublicIpRange(UserContext.current().getCallerUserId(), vlanDbId);
return deleteVlanAndPublicIpRange(UserContext.current().getCallerUserId(), vlanDbId, UserContext.current().getCaller());
}
@Override
@ -3620,7 +3679,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
Transaction txn = Transaction.currentTxn();
txn.start();
for (AccountVlanMapVO map : maps) {
if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId())) {
if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId(),
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
result = false;
}
}

View File

@ -614,7 +614,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} else if (addr.getState() == IpAddress.State.Releasing) {
// Cleanup all the resources for ip address if there are any, and only then un-assign ip in the
// system
// system
if (cleanupIpResources(addr.getId(), Account.ACCOUNT_ID_SYSTEM, _accountMgr.getSystemAccount())) {
_ipAddressDao.unassignIpAddress(addr.getId());
} else {
@ -3144,7 +3144,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
txn.start();
guru.trash(network, _networkOfferingDao.findById(network.getNetworkOfferingId()), owner);
if (!deleteVlansInNetwork(network.getId(), context.getCaller().getId())) {
if (!deleteVlansInNetwork(network.getId(), context.getCaller().getId(), callerAccount)) {
success = false;
s_logger.warn("Failed to delete network " + network + "; was unable to cleanup corresponding ip ranges");
} else {
@ -3159,11 +3159,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
return success;
}
private boolean deleteVlansInNetwork(long networkId, long userId) {
private boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) {
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
boolean result = true;
for (VlanVO vlan : vlans) {
if (!_configMgr.deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), vlan.getId())) {
if (!_configMgr.deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), vlan.getId(), callerAccount)) {
s_logger.warn("Failed to delete vlan " + vlan.getId() + ");");
result = false;
}