diff --git a/core/src/com/cloud/network/dao/FirewallRulesDao.java b/core/src/com/cloud/network/dao/FirewallRulesDao.java index 7db42df3bf6..2fab931b7da 100644 --- a/core/src/com/cloud/network/dao/FirewallRulesDao.java +++ b/core/src/com/cloud/network/dao/FirewallRulesDao.java @@ -44,5 +44,6 @@ public interface FirewallRulesDao extends GenericDao { public List listBySecurityGroupId(long securityGroupId); public List listByLoadBalancerId(long loadBalancerId); public List listForwardingByPubAndPrivIp(boolean forwarding, String publicIPAddress, String privateIp); - public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding); + public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding); + public List listByPrivateIp(String privateIp); } diff --git a/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index a73ce47d0f8..655a2d77b36 100644 --- a/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -306,5 +306,12 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i sc.setParameters("forwarding", forwarding); return findOneActiveBy(sc); - } + } + + @Override + public List listByPrivateIp(String privateIp) { + SearchCriteria sc = FWByPrivateIPSearch.create(); + sc.setParameters("privateIpAddress", privateIp); + return listActiveBy(sc); + } } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 9baac17cf86..0e67108301f 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -27,7 +27,9 @@ import com.cloud.dc.HostPodVO; import com.cloud.dc.VlanVO; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InternalErrorException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.network.FirewallRuleVO; @@ -211,4 +213,5 @@ public interface NetworkManager extends Manager { */ List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat); + public void deleteRule(long ruleId, long userId, long accountId) throws InvalidParameterValueException, PermissionDeniedException, InternalErrorException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 1bc28b8b7f2..957cebe0a43 100644 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -184,6 +184,8 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager AsyncJobManager _asyncMgr; StoragePoolDao _storagePoolDao = null; ServiceOfferingDao _serviceOfferingDao = null; + FirewallRulesDao _firewallRulesDao; + IPAddressDao _publicIpAddressDao; long _routerTemplateId = -1; int _routerRamSize; @@ -1731,6 +1733,16 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager throw new ConfigurationException("Unable to get the configuration dao."); } + _firewallRulesDao = locator.getDao(FirewallRulesDao.class); + if (_firewallRulesDao == null) { + throw new ConfigurationException("Unable to get the firewall rules dao."); + } + + _publicIpAddressDao = locator.getDao(IPAddressDao.class); + if (_publicIpAddressDao == null) { + throw new ConfigurationException("Unable to get the ip address dao."); + } + _configMgr = locator.getManager(ConfigurationManager.class); if (_configMgr == null) { throw new ConfigurationException("Unable to get the configuration manager."); @@ -2417,4 +2429,243 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager return _ipAddressDao.search(ipAddressSC, null); } + @Override + public void deleteRule(long ruleId, long userId, long accountId)throws InvalidParameterValueException, PermissionDeniedException,InternalErrorException + { + Exception e = null; + try { + FirewallRuleVO rule = _firewallRulesDao.findById(ruleId); + if (rule != null) { + boolean success = false; + + try { + if (rule.isForwarding()) { + success = deleteIpForwardingRule(userId, accountId, rule.getPublicIpAddress(), rule.getPublicPort(), rule.getPrivateIpAddress(), rule.getPrivatePort(), + rule.getProtocol()); + } else { + success = deleteLoadBalancingRule(userId, accountId, rule.getPublicIpAddress(), rule.getPublicPort(), rule.getPrivateIpAddress(), rule.getPrivatePort(), + rule.getAlgorithm()); + } + } catch (Exception ex) { + e = ex; + } + + String description; + String type = EventTypes.EVENT_NET_RULE_DELETE; + String level = EventVO.LEVEL_INFO; + String ruleName = rule.isForwarding() ? "ip forwarding" : "load balancer"; + + if (success) { + String desc = "deleted " + ruleName + " rule [" + rule.getPublicIpAddress() + ":" + rule.getPublicPort() + "]->[" + rule.getPrivateIpAddress() + ":" + + rule.getPrivatePort() + "] " + rule.getProtocol(); + if (!rule.isForwarding()) { + desc = desc + ", algorithm = " + rule.getAlgorithm(); + } + description = desc; + } else { + level = EventVO.LEVEL_ERROR; + String desc = "deleted " + ruleName + " rule [" + rule.getPublicIpAddress() + ":" + rule.getPublicPort() + "]->[" + rule.getPrivateIpAddress() + ":" + + rule.getPrivatePort() + "] " + rule.getProtocol(); + if (!rule.isForwarding()) { + desc = desc + ", algorithm = " + rule.getAlgorithm(); + } + description = desc; + } + + saveEvent(userId, accountId, level, type, description); + } + } finally { + if (e != null) { + if (e instanceof InvalidParameterValueException) { + throw (InvalidParameterValueException) e; + } else if (e instanceof PermissionDeniedException) { + throw (PermissionDeniedException) e; + } else if (e instanceof InternalErrorException) { + throw (InternalErrorException) e; + } + } + } + } + + @DB + protected boolean deleteIpForwardingRule(long userId, long accountId, String publicIp, String publicPort, String privateIp, String privatePort, String proto) + throws PermissionDeniedException, InvalidParameterValueException, InternalErrorException { + + Transaction txn = Transaction.currentTxn(); + boolean locked = false; + try { + AccountVO accountVO = _accountDao.findById(accountId); + if (accountVO == null) { + // throw this exception because hackers can use the api to probe + // for existing user ids + throw new PermissionDeniedException("Account does not own supplied address"); + } + // although we are not writing these values to the DB, we will check + // them out of an abundance + // of caution (may not be warranted) + if (!NetUtils.isValidPort(publicPort) || !NetUtils.isValidPort(privatePort)) { + throw new InvalidParameterValueException("Invalid value for port"); + } +// if (!NetUtils.isValidPrivateIp(privateIp, _configs.get("guest.ip.network"))) { +// throw new InvalidParameterValueException("Invalid private ip address"); +// } + if (!NetUtils.isValidProto(proto)) { + throw new InvalidParameterValueException("Invalid protocol"); + } + IPAddressVO ipVO = _publicIpAddressDao.acquire(publicIp); + if (ipVO == null) { + // throw this exception because hackers can use the api to probe for allocated ips + throw new PermissionDeniedException("User does not own supplied address"); + } + + locked = true; + if ((ipVO.getAllocated() == null) || (ipVO.getAccountId() == null) || (ipVO.getAccountId().longValue() != accountId)) { + // FIXME: if admin account, make sure the user is visible in the + // admin's domain, or has that checking been done by this point? + if (!BaseCmd.isAdmin(accountVO.getType())) { + throw new PermissionDeniedException("User/account does not own supplied address"); + } + } + + txn.start(); + + List fwdings = _firewallRulesDao.listIPForwardingForUpdate(publicIp, publicPort, proto); + FirewallRuleVO fwRule = null; + if (fwdings.size() == 0) { + throw new InvalidParameterValueException("No such rule"); + } else if (fwdings.size() == 1) { + fwRule = fwdings.get(0); + if (fwRule.getPrivateIpAddress().equalsIgnoreCase(privateIp) && fwRule.getPrivatePort().equals(privatePort)) { + _firewallRulesDao.delete(fwRule.getId()); + } else { + throw new InvalidParameterValueException("No such rule"); + } + } else { + throw new InternalErrorException("Multiple matches. Please contact support"); + } + fwRule.setEnabled(false); + boolean success = updateFirewallRule(fwRule, null, null); + if (!success) { + throw new InternalErrorException("Failed to update router"); + } + txn.commit(); + return success; + } catch (Throwable e) { + if (e instanceof InvalidParameterValueException) { + throw (InvalidParameterValueException) e; + } else if (e instanceof PermissionDeniedException) { + throw (PermissionDeniedException) e; + } else if (e instanceof InternalErrorException) { + s_logger.warn("ManagementServer error", e); + throw (InternalErrorException) e; + } + s_logger.warn("ManagementServer error", e); + } finally { + if (locked) { + _publicIpAddressDao.release(publicIp); + } + } + return false; + } + + @DB + private boolean deleteLoadBalancingRule(long userId, long accountId, String publicIp, String publicPort, String privateIp, String privatePort, String algo) + throws PermissionDeniedException, InvalidParameterValueException, InternalErrorException { + Transaction txn = Transaction.currentTxn(); + boolean locked = false; + try { + AccountVO accountVO = _accountDao.findById(accountId); + if (accountVO == null) { + // throw this exception because hackers can use the api to probe + // for existing user ids + throw new PermissionDeniedException("Account does not own supplied address"); + } + // although we are not writing these values to the DB, we will check + // them out of an abundance + // of caution (may not be warranted) + if (!NetUtils.isValidPort(publicPort) || !NetUtils.isValidPort(privatePort)) { + throw new InvalidParameterValueException("Invalid value for port"); + } +// if (!NetUtils.isValidPrivateIp(privateIp, _configs.get("guest.ip.network"))) { +// throw new InvalidParameterValueException("Invalid private ip address"); +// } + if (!NetUtils.isValidAlgorithm(algo)) { + throw new InvalidParameterValueException("Invalid protocol"); + } + + IPAddressVO ipVO = _publicIpAddressDao.acquire(publicIp); + + if (ipVO == null) { + // throw this exception because hackers can use the api to probe + // for allocated ips + throw new PermissionDeniedException("User does not own supplied address"); + } + + locked = true; + if ((ipVO.getAllocated() == null) || (ipVO.getAccountId() == null) || (ipVO.getAccountId().longValue() != accountId)) { + // FIXME: the user visible from the admin account's domain? has + // that check been done already? + if (!BaseCmd.isAdmin(accountVO.getType())) { + throw new PermissionDeniedException("User does not own supplied address"); + } + } + + List fwdings = _firewallRulesDao.listLoadBalanceRulesForUpdate(publicIp, publicPort, algo); + FirewallRuleVO fwRule = null; + if (fwdings.size() == 0) { + throw new InvalidParameterValueException("No such rule"); + } + for (FirewallRuleVO frv : fwdings) { + if (frv.getPrivateIpAddress().equalsIgnoreCase(privateIp) && frv.getPrivatePort().equals(privatePort)) { + fwRule = frv; + break; + } + } + + if (fwRule == null) { + throw new InvalidParameterValueException("No such rule"); + } + + txn.start(); + + fwRule.setEnabled(false); + _firewallRulesDao.update(fwRule.getId(), fwRule); + + boolean success = updateFirewallRule(fwRule, null, null); + if (!success) { + throw new InternalErrorException("Failed to update router"); + } + _firewallRulesDao.delete(fwRule.getId()); + + txn.commit(); + return success; + } catch (Throwable e) { + if (e instanceof InvalidParameterValueException) { + throw (InvalidParameterValueException) e; + } else if (e instanceof PermissionDeniedException) { + throw (PermissionDeniedException) e; + } else if (e instanceof InternalErrorException) { + s_logger.warn("ManagementServer error", e); + throw (InternalErrorException) e; + } + s_logger.warn("ManagementServer error", e); + } finally { + if (locked) { + _publicIpAddressDao.release(publicIp); + } + } + return false; + } + + private Long saveEvent(Long userId, Long accountId, String level, String type, String description) { + EventVO event = new EventVO(); + event.setUserId(userId); + event.setAccountId(accountId); + event.setType(type); + event.setDescription(description); + event.setLevel(level); + event = _eventDao.persist(event); + return event.getId(); + } + } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c5d8b2eedf7..3e1f0624635 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3643,175 +3643,6 @@ public class ManagementServerImpl implements ManagementServer { return _asyncMgr.submitAsyncJob(job); } - @DB - protected boolean deleteIpForwardingRule(long userId, long accountId, String publicIp, String publicPort, String privateIp, String privatePort, String proto) - throws PermissionDeniedException, InvalidParameterValueException, InternalErrorException { - - Transaction txn = Transaction.currentTxn(); - boolean locked = false; - try { - AccountVO accountVO = _accountDao.findById(accountId); - if (accountVO == null) { - // throw this exception because hackers can use the api to probe - // for existing user ids - throw new PermissionDeniedException("Account does not own supplied address"); - } - // although we are not writing these values to the DB, we will check - // them out of an abundance - // of caution (may not be warranted) - if (!NetUtils.isValidPort(publicPort) || !NetUtils.isValidPort(privatePort)) { - throw new InvalidParameterValueException("Invalid value for port"); - } -// if (!NetUtils.isValidPrivateIp(privateIp, _configs.get("guest.ip.network"))) { -// throw new InvalidParameterValueException("Invalid private ip address"); -// } - if (!NetUtils.isValidProto(proto)) { - throw new InvalidParameterValueException("Invalid protocol"); - } - IPAddressVO ipVO = _publicIpAddressDao.acquire(publicIp); - if (ipVO == null) { - // throw this exception because hackers can use the api to probe for allocated ips - throw new PermissionDeniedException("User does not own supplied address"); - } - - locked = true; - if ((ipVO.getAllocated() == null) || (ipVO.getAccountId() == null) || (ipVO.getAccountId().longValue() != accountId)) { - // FIXME: if admin account, make sure the user is visible in the - // admin's domain, or has that checking been done by this point? - if (!BaseCmd.isAdmin(accountVO.getType())) { - throw new PermissionDeniedException("User/account does not own supplied address"); - } - } - - txn.start(); - - List fwdings = _firewallRulesDao.listIPForwardingForUpdate(publicIp, publicPort, proto); - FirewallRuleVO fwRule = null; - if (fwdings.size() == 0) { - throw new InvalidParameterValueException("No such rule"); - } else if (fwdings.size() == 1) { - fwRule = fwdings.get(0); - if (fwRule.getPrivateIpAddress().equalsIgnoreCase(privateIp) && fwRule.getPrivatePort().equals(privatePort)) { - _firewallRulesDao.delete(fwRule.getId()); - } else { - throw new InvalidParameterValueException("No such rule"); - } - } else { - throw new InternalErrorException("Multiple matches. Please contact support"); - } - fwRule.setEnabled(false); - boolean success = _networkMgr.updateFirewallRule(fwRule, null, null); - if (!success) { - throw new InternalErrorException("Failed to update router"); - } - txn.commit(); - return success; - } catch (Throwable e) { - if (e instanceof InvalidParameterValueException) { - throw (InvalidParameterValueException) e; - } else if (e instanceof PermissionDeniedException) { - throw (PermissionDeniedException) e; - } else if (e instanceof InternalErrorException) { - s_logger.warn("ManagementServer error", e); - throw (InternalErrorException) e; - } - s_logger.warn("ManagementServer error", e); - } finally { - if (locked) { - _publicIpAddressDao.release(publicIp); - } - } - return false; - } - - @DB - private boolean deleteLoadBalancingRule(long userId, long accountId, String publicIp, String publicPort, String privateIp, String privatePort, String algo) - throws PermissionDeniedException, InvalidParameterValueException, InternalErrorException { - Transaction txn = Transaction.currentTxn(); - boolean locked = false; - try { - AccountVO accountVO = _accountDao.findById(accountId); - if (accountVO == null) { - // throw this exception because hackers can use the api to probe - // for existing user ids - throw new PermissionDeniedException("Account does not own supplied address"); - } - // although we are not writing these values to the DB, we will check - // them out of an abundance - // of caution (may not be warranted) - if (!NetUtils.isValidPort(publicPort) || !NetUtils.isValidPort(privatePort)) { - throw new InvalidParameterValueException("Invalid value for port"); - } -// if (!NetUtils.isValidPrivateIp(privateIp, _configs.get("guest.ip.network"))) { -// throw new InvalidParameterValueException("Invalid private ip address"); -// } - if (!NetUtils.isValidAlgorithm(algo)) { - throw new InvalidParameterValueException("Invalid protocol"); - } - - IPAddressVO ipVO = _publicIpAddressDao.acquire(publicIp); - - if (ipVO == null) { - // throw this exception because hackers can use the api to probe - // for allocated ips - throw new PermissionDeniedException("User does not own supplied address"); - } - - locked = true; - if ((ipVO.getAllocated() == null) || (ipVO.getAccountId() == null) || (ipVO.getAccountId().longValue() != accountId)) { - // FIXME: the user visible from the admin account's domain? has - // that check been done already? - if (!BaseCmd.isAdmin(accountVO.getType())) { - throw new PermissionDeniedException("User does not own supplied address"); - } - } - - List fwdings = _firewallRulesDao.listLoadBalanceRulesForUpdate(publicIp, publicPort, algo); - FirewallRuleVO fwRule = null; - if (fwdings.size() == 0) { - throw new InvalidParameterValueException("No such rule"); - } - for (FirewallRuleVO frv : fwdings) { - if (frv.getPrivateIpAddress().equalsIgnoreCase(privateIp) && frv.getPrivatePort().equals(privatePort)) { - fwRule = frv; - break; - } - } - - if (fwRule == null) { - throw new InvalidParameterValueException("No such rule"); - } - - txn.start(); - - fwRule.setEnabled(false); - _firewallRulesDao.update(fwRule.getId(), fwRule); - - boolean success = _networkMgr.updateFirewallRule(fwRule, null, null); - if (!success) { - throw new InternalErrorException("Failed to update router"); - } - _firewallRulesDao.delete(fwRule.getId()); - - txn.commit(); - return success; - } catch (Throwable e) { - if (e instanceof InvalidParameterValueException) { - throw (InvalidParameterValueException) e; - } else if (e instanceof PermissionDeniedException) { - throw (PermissionDeniedException) e; - } else if (e instanceof InternalErrorException) { - s_logger.warn("ManagementServer error", e); - throw (InternalErrorException) e; - } - s_logger.warn("ManagementServer error", e); - } finally { - if (locked) { - _publicIpAddressDao.release(publicIp); - } - } - return false; - } @Override public List getEvents(long userId, long accountId, Long domainId, String type, String level, Date startDate, Date endDate) { @@ -6025,60 +5856,9 @@ public class ManagementServerImpl implements ManagementServer { return _asyncMgr.submitAsyncJob(job); } - public void deleteRule(long ruleId, long userId, long accountId) throws InvalidParameterValueException, PermissionDeniedException, InternalErrorException { - Exception e = null; - try { - FirewallRuleVO rule = _firewallRulesDao.findById(ruleId); - if (rule != null) { - boolean success = false; - - try { - if (rule.isForwarding()) { - success = deleteIpForwardingRule(userId, accountId, rule.getPublicIpAddress(), rule.getPublicPort(), rule.getPrivateIpAddress(), rule.getPrivatePort(), - rule.getProtocol()); - } else { - success = deleteLoadBalancingRule(userId, accountId, rule.getPublicIpAddress(), rule.getPublicPort(), rule.getPrivateIpAddress(), rule.getPrivatePort(), - rule.getAlgorithm()); - } - } catch (Exception ex) { - e = ex; - } - - String description; - String type = EventTypes.EVENT_NET_RULE_DELETE; - String level = EventVO.LEVEL_INFO; - String ruleName = rule.isForwarding() ? "ip forwarding" : "load balancer"; - - if (success) { - String desc = "deleted " + ruleName + " rule [" + rule.getPublicIpAddress() + ":" + rule.getPublicPort() + "]->[" + rule.getPrivateIpAddress() + ":" - + rule.getPrivatePort() + "] " + rule.getProtocol(); - if (!rule.isForwarding()) { - desc = desc + ", algorithm = " + rule.getAlgorithm(); - } - description = desc; - } else { - level = EventVO.LEVEL_ERROR; - String desc = "deleted " + ruleName + " rule [" + rule.getPublicIpAddress() + ":" + rule.getPublicPort() + "]->[" + rule.getPrivateIpAddress() + ":" - + rule.getPrivatePort() + "] " + rule.getProtocol(); - if (!rule.isForwarding()) { - desc = desc + ", algorithm = " + rule.getAlgorithm(); - } - description = desc; - } - - saveEvent(userId, accountId, level, type, description); - } - } finally { - if (e != null) { - if (e instanceof InvalidParameterValueException) { - throw (InvalidParameterValueException) e; - } else if (e instanceof PermissionDeniedException) { - throw (PermissionDeniedException) e; - } else if (e instanceof InternalErrorException) { - throw (InternalErrorException) e; - } - } - } + public void deleteRule(long ruleId, long userId, long accountId) throws InvalidParameterValueException, PermissionDeniedException, InternalErrorException + { + _networkMgr.deleteRule(ruleId, userId, accountId); } public long deleteRuleAsync(long id, long userId, long accountId) { diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 5cd41d342d8..7222e27c5d9 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -119,6 +119,7 @@ import com.cloud.network.dao.SecurityGroupVMMapDao; import com.cloud.network.security.NetworkGroupManager; import com.cloud.network.security.NetworkGroupVO; import com.cloud.pricing.dao.PricingDao; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.ServiceOffering.GuestIpType; @@ -153,6 +154,7 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.User; +import com.cloud.user.UserContext; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; @@ -224,7 +226,6 @@ public class UserVmManagerImpl implements UserVmManager { @Inject NetworkGroupManager _networkGroupManager; @Inject ServiceOfferingDao _serviceOfferingDao; @Inject EventDao _eventDao = null; - private IpAddrAllocator _IpAllocator; ScheduledExecutorService _executor = null; int _expungeInterval; @@ -1938,7 +1939,9 @@ public class UserVmManagerImpl implements UserVmManager { public void expunge() { List vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long)_expungeDelay << 10))); s_logger.info("Found " + vms.size() + " vms to expunge."); - for (UserVmVO vm : vms) { + for (UserVmVO vm : vms) + { + String privateIpAddress = vm.getPrivateIpAddress(); long vmId = vm.getId(); releaseGuestIpAddress(vm); vm.setGuestNetmask(null); @@ -1947,6 +1950,23 @@ public class UserVmManagerImpl implements UserVmManager { s_logger.info("vm " + vmId + " is skipped because it is no longer in Destroyed state"); continue; } + + List forwardingRules = null; + try + { + forwardingRules = _rulesDao.listByPrivateIp(privateIpAddress); + + for(FirewallRuleVO rule: forwardingRules) + { + _networkMgr.deleteRule(rule.getId(), Long.valueOf(User.UID_SYSTEM), vm.getAccountId()); + if(s_logger.isDebugEnabled()) + s_logger.debug("Rule "+rule.getId()+" for vm:"+vm.getId()+" is deleted successfully during expunge operation"); + } + + } catch (Exception e) { + s_logger.info("VM " + vmId +" expunge failed due to " + e.getMessage()); + } + List vols = null; try {