diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index e732f0b44c7..87d69bfaef6 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -170,6 +170,7 @@ import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; @@ -1928,7 +1929,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InvalidParameterValueException("Ip address id=" + ipAddressId + " belongs to Account wide IP pool and cannot be disassociated"); } - return releasePublicIpAddress(ipAddressId, userId, caller); + boolean success = releasePublicIpAddress(ipAddressId, userId, caller); + if (success) { + Long vmId = ipVO.getAssociatedWithVmId(); + UserVm vm = null; + if (vmId != null) { + vm = _userVmDao.findById(vmId); + } + return _rulesMgr.enableElasticIpAndStaticNatForVm(vm, true); + } else { + s_logger.warn("Failed to release public ip address id=" + ipAddressId); + return false; + } } @Deprecated // No one is using this method. diff --git a/server/src/com/cloud/network/rules/FirewallManager.java b/server/src/com/cloud/network/rules/FirewallManager.java index 50171ce0125..bdc5500aa88 100644 --- a/server/src/com/cloud/network/rules/FirewallManager.java +++ b/server/src/com/cloud/network/rules/FirewallManager.java @@ -24,8 +24,8 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; import com.cloud.network.firewall.FirewallService; -import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.FirewallRuleType; +import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.user.Account; public interface FirewallManager extends FirewallService{ @@ -77,5 +77,4 @@ public interface FirewallManager extends FirewallService{ boolean revokeFirewallRulesForVm(long vmId); boolean addSystemFirewallRules(IPAddressVO ip, Account acct); - } diff --git a/server/src/com/cloud/network/rules/RulesManager.java b/server/src/com/cloud/network/rules/RulesManager.java index 2edcbbe8278..3f36dc2fb30 100644 --- a/server/src/com/cloud/network/rules/RulesManager.java +++ b/server/src/com/cloud/network/rules/RulesManager.java @@ -71,4 +71,6 @@ public interface RulesManager extends RulesService { boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller); + boolean enableElasticIpAndStaticNatForVm(UserVm vm, boolean stopOnError); + } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 88fe2a0bf0a..f0e8a013f2c 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.api.commands.ListPortForwardingRulesCmd; +import com.cloud.configuration.ConfigurationManager; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -49,6 +50,7 @@ import com.cloud.network.dao.IPAddressDao; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -70,6 +72,7 @@ import com.cloud.utils.net.Ip; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; @Local(value = { RulesManager.class, RulesService.class }) @@ -101,6 +104,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { FirewallManager _firewallMgr; @Inject DomainManager _domainMgr; + @Inject + ConfigurationManager _configMgr; + @Inject + NicDao _nicDao; @Override public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) { @@ -1025,6 +1032,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { ipAddress.setOneToOneNat(false); ipAddress.setAssociatedWithVmId(null); _ipAddressDao.update(ipAddress.getId(), ipAddress); + if (!handleElasticIpRelease(ipAddress)) { + s_logger.warn("Failed to release elastic ip address " + ipAddress); + return false; + } return true; } else { s_logger.warn("Failed to disable one to one nat for the ip address id" + ipId); @@ -1106,4 +1117,68 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { return true; } + + + @Override + public boolean enableElasticIpAndStaticNatForVm(UserVm vm, boolean stopOnError) { + boolean success = true; + + //enable static nat if eIp capability is supported + List nics = _nicDao.listByVmId(vm.getId()); + for (Nic nic : nics) { + Network guestNetwork = _networkMgr.getNetwork(nic.getNetworkId()); + NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); + if (offering.getElasticIp()) { + try { + //check if there is already static nat enabled + if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null) { + s_logger.debug("Vm " + vm + " already has elastic ip associated with it in guest network " + guestNetwork); + continue; + } + + s_logger.debug("Allocating elastic ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork); + IpAddress ip = _networkMgr.assignElasticIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true); + if (ip == null) { + s_logger.warn("Failed to allocate elastic ip for vm " + vm + " in guest network " + guestNetwork); + return false; + } + s_logger.debug("Allocated elastic ip " + ip + ", now enabling static nat on it for vm " + vm); + success = success && enableStaticNat(ip.getId(), vm.getId()); + if (!success) { + s_logger.warn("Failed to enable static nat on elastic ip " + ip + " for the vm " + vm + ", releasing the ip..."); + handleElasticIpRelease(ip); + } else { + s_logger.warn("Succesfully enabled static nat on elastic ip " + ip + " for the vm " + vm); + } + } catch (Exception ex) { + s_logger.warn("Failed to acquire elastic ip and enable static nat for vm " + vm + " on the network " + guestNetwork + " due to exception ", ex); + } finally { + if (!success && stopOnError) { + return false; + } + } + } + } + + return success; + } + + protected boolean handleElasticIpRelease(IpAddress ip) { + boolean success = true; + Long networkId = ip.getAssociatedWithNetworkId(); + if (networkId != null) { + Network guestNetwork = _networkMgr.getNetwork(networkId); + NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); + if (offering.getElasticIp()) { + UserContext ctx = UserContext.current(); + if (!_networkMgr.releasePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { + s_logger.warn("Unable to release elastic ip address id=" + ip.getId()); + success = false; + } else { + s_logger.warn("Successfully released elastic ip address id=" + ip.getId()); + } + } + } + return success; + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 161e982b374..9dcb9e0df0c 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -119,7 +119,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -1271,21 +1270,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge"); success = false; } - - Long networkId = ip.getAssociatedWithNetworkId(); - if (networkId != null) { - Network guestNetwork = _networkMgr.getNetwork(networkId); - NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); - if (offering.getElasticIp()) { - UserContext ctx = UserContext.current(); - if (!_networkMgr.releasePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { - s_logger.warn("Unable to release elastic ip address id=" + ip.getId() + " as a part of vm id=" + vmId + " cleanup"); - success = false; - } else { - s_logger.warn("Successfully released elastic ip address id=" + ip.getId() + " as a part of vm id=" + vmId + " cleanup"); - } - } - } } } catch (ResourceUnavailableException e) { success = false; @@ -2746,8 +2730,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } //enable elastic ip for vm - boolean success = enableElasticIpAndStaticNatForVm(profile.getVirtualMachine(), true); - return success; + return _rulesMgr.enableElasticIpAndStaticNatForVm(profile.getVirtualMachine(), true); } @Override @@ -3604,46 +3587,5 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return vm; } - protected boolean enableElasticIpAndStaticNatForVm(UserVm vm, boolean stopOnError) { - boolean success = true; - Account vmOwner = _accountMgr.getAccount(vm.getAccountId()); - - //enable static nat if eIp capability is supported - List nics = _nicDao.listByVmId(vm.getId()); - for (Nic nic : nics) { - Network guestNetwork = _networkMgr.getNetwork(nic.getNetworkId()); - NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); - if (offering.getElasticIp()) { - try { - //check if there is already static nat enabled - if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null) { - s_logger.debug("Vm " + vm + " already has elastic ip associated with it in guest network " + guestNetwork); - continue; - } - - s_logger.debug("Allocating elastic ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork); - IpAddress ip = _networkMgr.assignElasticIp(guestNetwork.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), false, true); - if (ip == null) { - s_logger.warn("Failed to allocate elastic ip as a part of vm deployment for vm " + vm); - return false; - } - s_logger.debug("Allocated elastic ip " + ip + ", now enabling static nat on it for vm " + vm); - success = success && _rulesMgr.enableStaticNat(ip.getId(), vm.getId()); - if (!success) { - s_logger.warn("Failed to enable static nat on elastic ip " + ip + " for the vm " + vm); - } else { - s_logger.warn("Succesfully enabled static nat on elastic ip " + ip + " for the vm " + vm); - } - } catch (Exception ex) { - s_logger.warn("Failed to finalize vm deployment for vm " + vm + " on the network " + guestNetwork + " due to exception ", ex); - } finally { - if (!success && stopOnError) { - return false; - } - } - } - } - - return success; - } + }