|
38 | 38 |
|
39 | 39 | import com.cloud.acl.SecurityChecker;
|
40 | 40 | import com.cloud.alert.AlertManager;
|
41 |
| -import com.cloud.api.ApiDBUtils; |
42 | 41 | import com.cloud.api.ApiConstants.LDAPParams;
|
| 42 | +import com.cloud.api.ApiDBUtils; |
43 | 43 | import com.cloud.api.commands.CreateDiskOfferingCmd;
|
44 | 44 | import com.cloud.api.commands.CreateNetworkOfferingCmd;
|
45 | 45 | import com.cloud.api.commands.CreateServiceOfferingCmd;
|
|
110 | 110 | import com.cloud.network.Networks.TrafficType;
|
111 | 111 | import com.cloud.network.PhysicalNetwork;
|
112 | 112 | import com.cloud.network.PhysicalNetworkVO;
|
| 113 | +import com.cloud.network.dao.FirewallRulesDao; |
113 | 114 | import com.cloud.network.dao.IPAddressDao;
|
114 | 115 | import com.cloud.network.dao.NetworkDao;
|
115 | 116 | import com.cloud.network.dao.PhysicalNetworkDao;
|
|
155 | 156 | import com.cloud.utils.exception.CloudRuntimeException;
|
156 | 157 | import com.cloud.utils.net.NetUtils;
|
157 | 158 | import com.cloud.vm.VirtualMachine;
|
| 159 | +import com.cloud.vm.dao.NicDao; |
158 | 160 |
|
159 | 161 | import edu.emory.mathcs.backport.java.util.Arrays;
|
160 | 162 |
|
@@ -219,6 +221,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
219 | 221 | SwiftManager _swiftMgr;
|
220 | 222 | @Inject
|
221 | 223 | PhysicalNetworkTrafficTypeDao _trafficTypeDao;
|
| 224 | + @Inject |
| 225 | + NicDao _nicDao; |
| 226 | + @Inject |
| 227 | + FirewallRulesDao _firewallDao; |
222 | 228 |
|
223 | 229 | // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
|
224 | 230 | protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class);
|
@@ -2425,24 +2431,78 @@ public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physica
|
2425 | 2431 | }
|
2426 | 2432 |
|
2427 | 2433 | @Override
|
2428 |
| - public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId) { |
| 2434 | + @DB |
| 2435 | + public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller) { |
2429 | 2436 | VlanVO vlan = _vlanDao.findById(vlanDbId);
|
2430 | 2437 | if (vlan == null) {
|
2431 | 2438 | throw new InvalidParameterValueException("Please specify a valid IP range id.");
|
2432 | 2439 | }
|
| 2440 | + |
| 2441 | + boolean isAccountSpecific = false; |
| 2442 | + List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlan.getId()); |
| 2443 | + // Check for account wide pool. It will have an entry for account_vlan_map. |
| 2444 | + if (acctVln != null && !acctVln.isEmpty()) { |
| 2445 | + isAccountSpecific = true; |
| 2446 | + } |
2433 | 2447 |
|
2434 | 2448 | // Check if the VLAN has any allocated public IPs
|
2435 |
| - if (_publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true) > 0) { |
2436 |
| - throw new InvalidParameterValueException("The IP range can't be deleted because it has allocated public IP addresses."); |
| 2449 | + long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true); |
| 2450 | + boolean success = true; |
| 2451 | + if (allocIpCount > 0) { |
| 2452 | + if (isAccountSpecific) { |
| 2453 | + try { |
| 2454 | + vlan = _vlanDao.acquireInLockTable(vlanDbId, 30); |
| 2455 | + if (vlan == null) { |
| 2456 | + throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId); |
| 2457 | + } |
| 2458 | + |
| 2459 | + if (s_logger.isDebugEnabled()) { |
| 2460 | + s_logger.debug("lock vlan " + vlanDbId + " is acquired"); |
| 2461 | + } |
| 2462 | + |
| 2463 | + List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId); |
| 2464 | + |
| 2465 | + for (IPAddressVO ip : ips) { |
| 2466 | + if (ip.isOneToOneNat()) { |
| 2467 | + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + |
| 2468 | + " as ip " + ip + " belonging to the range is used for static nat purposes. Cleanup the rules first"); |
| 2469 | + } |
| 2470 | + |
| 2471 | + if (ip.isSourceNat() && _nicDao.findByIp4AddressAndNetworkId(ip.getAddress().addr(), ip.getSourceNetworkId()) != null) { |
| 2472 | + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + |
| 2473 | + " as ip " + ip + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId() + |
| 2474 | + ". Either delete the network, or Virtual Router instance using this ip address"); |
| 2475 | + } |
| 2476 | + |
| 2477 | + if (_firewallDao.countRulesByIpId(ip.getId()) > 0) { |
| 2478 | + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + |
| 2479 | + " as ip " + ip + " belonging to the range has firewall rules applied. Cleanup the rules first"); |
| 2480 | + } |
| 2481 | + //release public ip address here |
| 2482 | + success = success && _networkMgr.releasePublicIpAddress(ip.getId(), userId, caller); |
| 2483 | + } |
| 2484 | + if (!success) { |
| 2485 | + s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal"); |
| 2486 | + } |
| 2487 | + } finally { |
| 2488 | + _vlanDao.releaseFromLockTable(vlanDbId); |
| 2489 | + } |
| 2490 | + } else { |
| 2491 | + throw new InvalidParameterValueException("The IP range can't be deleted because it has allocated public IP addresses."); |
| 2492 | + } |
2437 | 2493 | }
|
2438 | 2494 |
|
2439 |
| - // Delete all public IPs in the VLAN |
2440 |
| - if (!deletePublicIPRange(vlanDbId)) { |
| 2495 | + if (success) { |
| 2496 | + // Delete all public IPs in the VLAN |
| 2497 | + if (!deletePublicIPRange(vlanDbId)) { |
| 2498 | + return false; |
| 2499 | + } |
| 2500 | + |
| 2501 | + // Delete the VLAN |
| 2502 | + return _vlanDao.expunge(vlanDbId); |
| 2503 | + } else { |
2441 | 2504 | return false;
|
2442 | 2505 | }
|
2443 |
| - |
2444 |
| - // Delete the VLAN |
2445 |
| - return _vlanDao.expunge(vlanDbId); |
2446 | 2506 | }
|
2447 | 2507 |
|
2448 | 2508 | @Override
|
@@ -2766,8 +2826,7 @@ public boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd) {
|
2766 | 2826 | throw new InvalidParameterValueException("Please specify a valid IP range id.");
|
2767 | 2827 | }
|
2768 | 2828 |
|
2769 |
| - return deleteVlanAndPublicIpRange(UserContext.current().getCallerUserId(), vlanDbId); |
2770 |
| - |
| 2829 | + return deleteVlanAndPublicIpRange(UserContext.current().getCallerUserId(), vlanDbId, UserContext.current().getCaller()); |
2771 | 2830 | }
|
2772 | 2831 |
|
2773 | 2832 | @Override
|
@@ -3620,7 +3679,8 @@ public boolean deleteAccountSpecificVirtualRanges(long accountId) {
|
3620 | 3679 | Transaction txn = Transaction.currentTxn();
|
3621 | 3680 | txn.start();
|
3622 | 3681 | for (AccountVlanMapVO map : maps) {
|
3623 |
| - if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId())) { |
| 3682 | + if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId(), |
| 3683 | + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) { |
3624 | 3684 | result = false;
|
3625 | 3685 | }
|
3626 | 3686 | }
|
|
0 commit comments