Elastic IP - when deployVm, get ip address and enable static nat on it. On vm destroy release the Ip

This commit is contained in:
Alena Prokharchyk 2012-01-12 16:56:54 -08:00
parent 630cbb2243
commit 0f6f231ee6
5 changed files with 100 additions and 31 deletions

View File

@ -278,4 +278,8 @@ public interface NetworkManager extends NetworkService {
Capability cap, String capValue);
Provider getDefaultUniqueProviderForService(String serviceName);
IpAddress assignElasticIp(long networkId, Account owner,
boolean forElasticLb, boolean forElasticIp)
throws InsufficientAddressCapacityException;
}

View File

@ -5838,4 +5838,33 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
}
public IpAddress assignElasticIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException{
Network guestNetwork = getNetwork(networkId);
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
IpAddress ip = null;
if ((off.getElasticLb() && forElasticLb) || (off.getElasticIp() && forElasticIp)) {
try {
s_logger.debug("Allocating elastic IP address for load balancer rule...");
//allocate ip
ip = allocateIP(networkId, owner);
//apply ip associations
ip = associateIP(ip.getId());
} catch (ResourceAllocationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic ip due to ", ex);
} catch (ConcurrentOperationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
} catch (ResourceUnavailableException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
}
if (ip == null) {
throw new CloudRuntimeException("Failed to allocate elastic ip");
}
}
return ip;
}
}

View File

@ -47,12 +47,10 @@ import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddress;
@ -627,37 +625,18 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
_networkMgr.checkIpForService(ipAddressVo, Service.Lb);
}
Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId());
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
if (ipAddressVo != null) {
throw new InvalidParameterValueException("Can't specify ipAddressId when create LB in the network with LB capability " + Capability.ElasticLb.getName());
}
LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId());
if (result == null){
Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId());
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
if (off.getElasticLb()) {
if (ipAddressVo != null) {
throw new InvalidParameterValueException("Can't specify ipAddressId when create LB in the network with LB capability " + Capability.ElasticLb.getName());
}
IpAddress ip = null;
try {
s_logger.debug("Allocating elastic IP address for load balancer rule...");
//allocate ip
ip = _networkMgr.allocateIP(lb.getNetworkId(), lbOwner);
//apply ip associations
ip = _networkMgr.associateIP(ip.getId());
} catch (ResourceAllocationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
} catch (ConcurrentOperationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
} catch (ResourceUnavailableException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
}
if (ip == null) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip");
}
IpAddress ip = _networkMgr.assignElasticIp(lb.getNetworkId(), lbOwner, true, false);
lb.setSourceIpAddressId(ip.getId());
}
result = createLoadBalancer(lb, openFirewall);
}

View File

@ -953,7 +953,7 @@ public class ConfigurationServerImpl implements ConfigurationServer {
NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
"Offering for Shared networks with Elastic IP and Elastic LB capabilities",
TrafficType.Guest,
true, true, null, null, true, Availability.Optional,
false, true, null, null, true, Availability.Optional,
null, Network.GuestType.Shared, true, false, false, false, true, true);
defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled);

View File

@ -119,6 +119,7 @@ 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;
@ -1260,7 +1261,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
s_logger.warn("Fail to remove vm id=" + vmId + " from load balancers as a part of expunge process");
}
// If vm is assigned to static nat, disable static nat for the ip address
// If vm is assigned to static nat, disable static nat for the ip address and disassociate ip if elasticIP is enabled
IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(vmId);
try {
if (ip != null) {
@ -1270,6 +1271,21 @@ 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;
@ -2591,9 +2607,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
} finally {
updateVmStateForFailedVmCreation(vm.getId());
}
if (!finalizeDeploy(vm, true)) {
//FIXME alena - if fails, expunge the vm
}
if (template.getEnablePassword()) {
// this value is not being sent to the backend; need only for api dispaly purposes
// this value is not being sent to the backend; need only for api display purposes
vm.setPassword(password);
}
@ -3586,4 +3606,41 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
s_logger.debug("Restore VM " + vmId + " with template " + root.getTemplateId() + " successfully");
return vm;
}
protected boolean finalizeDeploy(UserVm vm, boolean stopOnError) {
boolean success = true;
Account vmOwner = _accountMgr.getAccount(vm.getAccountId());
//enable static nat if eIp capability is supported
List<? extends Nic> 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 {
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(), vmOwner, 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;
}
}