mirror of https://github.com/apache/cloudstack.git
bug 12911, 12912, 11417: netscaler SDX based dynamiac load balancer provisioning
status 12911, 12912, 11417: resolved fixed
This commit is contained in:
parent
c46591f814
commit
a4cabad669
|
|
@ -256,9 +256,7 @@ public class NetscalerResource implements ServerResource {
|
|||
|
||||
private void validateInterfaces(String publicInterface, String privateInterface) throws ExecutionException {
|
||||
try {
|
||||
if (_isSdx) {
|
||||
return;
|
||||
} else {
|
||||
if (!_isSdx && !_cloudManaged) {
|
||||
Interface publicIf = Interface.get(_netscalerService, publicInterface);
|
||||
Interface privateIf = Interface.get(_netscalerService, privateInterface);
|
||||
if (publicIf != null || privateIf != null) {
|
||||
|
|
@ -266,7 +264,7 @@ public class NetscalerResource implements ServerResource {
|
|||
} else {
|
||||
throw new ExecutionException("Invalid interface name specified for public/private interfaces.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (nitro_exception e) {
|
||||
if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
|
||||
throw new ExecutionException("Invalid interface name specified for public and private interfaces.");
|
||||
|
|
@ -280,7 +278,7 @@ public class NetscalerResource implements ServerResource {
|
|||
|
||||
private void validateDeviceType(String deviceType) throws ExecutionException {
|
||||
try {
|
||||
if (!_isSdx) {
|
||||
if (!_isSdx && !_cloudManaged) {
|
||||
nshardware nsHw = com.citrix.netscaler.nitro.resource.config.ns.nshardware.get(_netscalerService);
|
||||
if (nsHw == null) {
|
||||
throw new ExecutionException("Failed to get the hardware description of the Netscaler device at " + _ip);
|
||||
|
|
@ -291,7 +289,7 @@ public class NetscalerResource implements ServerResource {
|
|||
}
|
||||
throw new ExecutionException("Netscalar device type specified does not match with the actuall device type.");
|
||||
}
|
||||
} else {
|
||||
} else if (_isSdx) {
|
||||
mps serviceVM = mps.get(_netscalerSdxService);
|
||||
if (serviceVM != null) {
|
||||
if (serviceVM.get_platform().contains("SDX") || serviceVM.get_product().contains("SDX")) {
|
||||
|
|
@ -656,10 +654,10 @@ public class NetscalerResource implements ServerResource {
|
|||
|
||||
// wait for VPX instance to start-up
|
||||
long startTick = System.currentTimeMillis();
|
||||
long startWaitMins = 200000;
|
||||
while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMins) {
|
||||
long startWaitMilliSeconds = 600000;
|
||||
while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(10000);
|
||||
} catch(InterruptedException e) {
|
||||
}
|
||||
ns refreshNsObj = new ns();
|
||||
|
|
@ -669,16 +667,36 @@ public class NetscalerResource implements ServerResource {
|
|||
|
||||
// if vpx instance never came up then error out
|
||||
if (!newVpx.get_ns_state().equalsIgnoreCase("up")) {
|
||||
new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip));
|
||||
return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip));
|
||||
}
|
||||
|
||||
// wait till NS service in side VPX is actually ready
|
||||
startTick = System.currentTimeMillis();
|
||||
boolean nsServiceUp = false;
|
||||
long nsServiceWaitMilliSeconds = 60000;
|
||||
while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) {
|
||||
try {
|
||||
nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https");
|
||||
_netscalerService.set_credential(username, password);
|
||||
_netscalerService.set_timeout(_timeout);
|
||||
apiCallResult = _netscalerService.login();
|
||||
if (apiCallResult.errorcode == 0) {
|
||||
nsServiceUp = true;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nsServiceUp) {
|
||||
return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip));
|
||||
}
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip);
|
||||
}
|
||||
|
||||
// FIXME: once VPX comes up there is time lag before we can actually login to VPX, so wait
|
||||
Thread.sleep(20000);
|
||||
|
||||
// physical interfaces on the SDX range from 10/1 to 10/8 of which two different port or same port can be used for public and private interfaces
|
||||
// However the VPX instances created will have interface range start from 10/1 but will only have as many interfaces enabled while creating the VPX instance
|
||||
|
||||
|
|
@ -816,8 +834,6 @@ public class NetscalerResource implements ServerResource {
|
|||
String vlanInterface = guestVlan ? _privateInterface : _publicInterface;
|
||||
throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message);
|
||||
}
|
||||
} else {
|
||||
throw new ExecutionException("Failed to configure Netscaler device for vlan with tag " + vlanTag + " as vlan already exisits");
|
||||
}
|
||||
} catch (nitro_exception e) {
|
||||
throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ import com.cloud.host.Host;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.host.dao.HostDetailsDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
|
||||
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState;
|
||||
import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice;
|
||||
|
|
@ -103,6 +104,7 @@ import com.cloud.resource.ResourceManager;
|
|||
import com.cloud.resource.ResourceStateAdapter;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.UnableDeleteHostException;
|
||||
import com.cloud.resource.ResourceStateAdapter.DeleteHostAnswer;
|
||||
import com.cloud.server.api.response.ExternalLoadBalancerResponse;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
|
|
@ -469,27 +471,44 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
|||
//we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer
|
||||
String dedicatedLb = offering.getDedicatedLB()?"true":"false";
|
||||
|
||||
// acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
|
||||
//acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
|
||||
PublicIp publicIp = _networkMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null);
|
||||
IPAddressVO ipvo = _ipAddressDao.findById(publicIp.getId());
|
||||
String publicIPNetmask = publicIp.getVlanNetmask();
|
||||
String publicIPgateway = publicIp.getVlanGateway();
|
||||
String publicIPVlanTag = publicIp.getVlanTag();
|
||||
String publicIP = publicIp.getAddress().toString();
|
||||
|
||||
|
||||
String url = "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb +
|
||||
"&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&publicipvlan="+ publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
|
||||
ExternalLoadBalancerDeviceVO lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource());
|
||||
"&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&publicipvlan="+ publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
|
||||
ExternalLoadBalancerDeviceVO lbAppliance = null;
|
||||
try {
|
||||
lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource());
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() + ". So provisioned load balancer appliance will be destroyed.");
|
||||
}
|
||||
|
||||
if (lbAppliance != null) {
|
||||
// mark the load balancer as cloudstack managed
|
||||
// mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned
|
||||
ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId());
|
||||
managedLb.setIsManagedDevice(true);
|
||||
// set parent host id on which lb appliance is provisioned
|
||||
managedLb.setParentHostId(lbProviderDevice.getHostId());
|
||||
_externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb);
|
||||
} else {
|
||||
_networkMgr.releasePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
|
||||
// failed to add the provisioned load balancer into cloudstack so destroy the appliance
|
||||
DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
|
||||
DestroyLoadBalancerApplianceAnswer answer = null;
|
||||
try {
|
||||
answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.warn("Failed to destroy load balancer appliance created");
|
||||
} else {
|
||||
// release the public & private IP back to dc pool, as the load balancer appliance is now destroyed
|
||||
_dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null);
|
||||
_networkMgr.releasePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -607,8 +626,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
|||
txn.commit();
|
||||
|
||||
if (!lbInUse && lbCloudManaged) {
|
||||
// send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance
|
||||
// is provisioned as this is the last network using it
|
||||
// send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned
|
||||
Host lbHost = _hostDao.findById(lbDevice.getHostId());
|
||||
String lbIP = lbHost.getPrivateIpAddress();
|
||||
DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
|
||||
|
|
@ -627,10 +645,16 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
|||
}
|
||||
deviceMapLock.unlock();
|
||||
|
||||
// remove the provisioned load balancer appliance from cloudstack
|
||||
deleteExternalLoadBalancer(lbHost.getId());
|
||||
|
||||
// release the private IP back to dc pool, as the load balancer appliance is now destroyed
|
||||
_dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null);
|
||||
|
||||
//FIXME : release the public IP allocated for this LB appliance
|
||||
|
||||
// release the public IP allocated for this LB appliance
|
||||
DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip");
|
||||
IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString());
|
||||
_networkMgr.releasePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
|
||||
} else {
|
||||
deviceMapLock.unlock();
|
||||
}
|
||||
|
|
@ -1213,7 +1237,9 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
|||
|
||||
@Override
|
||||
public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
if (host.getType() != com.cloud.host.Host.Type.ExternalLoadBalancer) {
|
||||
return null;
|
||||
}
|
||||
return new DeleteHostAnswer(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
|
|||
IPAddressVO findByAssociatedVmId(long vmId);
|
||||
|
||||
IPAddressVO findByIpAndSourceNetworkId(long networkId, String ipAddress);
|
||||
|
||||
|
||||
public IPAddressVO findByIpAndDcId(long dcId, String ipAddress);
|
||||
|
||||
List<IPAddressVO> listByPhysicalNetworkId(long physicalNetworkId);
|
||||
|
||||
long countFreeIPs();
|
||||
|
|
|
|||
|
|
@ -208,7 +208,15 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
|
|||
sc.setParameters("ipAddress", ipAddress);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IPAddressVO findByIpAndDcId(long dcId, String ipAddress) {
|
||||
SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("dataCenterId", dcId);
|
||||
sc.setParameters("ipAddress", ipAddress);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IPAddressVO> listByDcId(long dcId) {
|
||||
SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
|
||||
|
|
|
|||
Loading…
Reference in New Issue