bug 11817: NAAS: device allocation logic

- adding a allocation state to device
 - change device allocation logic based on network offering  and device state
This commit is contained in:
Murali Reddy 2011-11-10 09:55:23 -08:00
parent 4ea3aaeb18
commit 122b62066a
15 changed files with 301 additions and 98 deletions

View File

@ -19,14 +19,8 @@
package com.cloud.network.resource;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
@ -64,8 +58,6 @@ import com.citrix.netscaler.nitro.resource.config.network.*;
import com.citrix.netscaler.nitro.resource.config.ns.*;
import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding;
import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats;
import org.apache.axis.types.*;
import org.apache.log4j.Logger;
class NitroError {
@ -87,6 +79,7 @@ public class NetscalerResource implements ServerResource {
private Integer _numRetries;
private String _guid;
private boolean _inline;
private boolean _isSdx;
private static final Logger s_logger = Logger.getLogger(NetscalerResource.class);
protected Gson _gson;
@ -144,7 +137,12 @@ public class NetscalerResource implements ServerResource {
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
String deviceName = (String) params.get("deviceName");
if (deviceName.equalsIgnoreCase("NetscalerSDXLoadBalancer")) {
_isSdx = true;
}
_inline = Boolean.parseBoolean((String) params.get("inline"));
login();

View File

@ -30,14 +30,14 @@ public class AddNetworkDeviceCmd extends BaseCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@Parameter(name = ApiConstants.NETWORK_DEVICE_TYPE, type = CommandType.STRING, description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall")
@Parameter(name = ApiConstants.NETWORK_DEVICE_TYPE, type = CommandType.STRING, description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerMPXLoadBalancer, NetscalerVPXLoadBalancer, NetscalerSDXLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall")
private String type;
@Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "parameters for network device")
private Map paramList;
public String getType() {
public String getDeviceType() {
return type;
}

View File

@ -34,13 +34,13 @@ public class ListNetworkDeviceCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NETWORK_DEVICE_TYPE, type = CommandType.STRING, description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall")
@Parameter(name = ApiConstants.NETWORK_DEVICE_TYPE, type = CommandType.STRING, description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerMPXLoadBalancer, NetscalerVPXLoadBalancer, NetscalerSDXLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall")
private String type;
@Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "parameters for network device")
private Map paramList;
public String getType() {
public String getDeviceType() {
return type;
}

View File

@ -26,12 +26,10 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.network.PhysicalNetworkServiceProvider.State;
/**
* ExternalFirewallDeviceVO contains information of a external firewall device (Juniper SRX)
* added into a deployment
* ExternalFirewallDeviceVO contains information of a external firewall device (Juniper SRX) added into a deployment
*/
@Entity
@ -61,11 +59,21 @@ public class ExternalFirewallDeviceVO {
@Column(name = "capacity_type")
private String capacity_type;
@Column(name = "allocation_state")
@Enumerated(value=EnumType.STRING)
private AllocationState allocationState;
public enum AllocationState {
Free,
Allocated
}
public ExternalFirewallDeviceVO(long hostId, long physicalNetworkId, String provider_name) {
this.physicalNetworkId = physicalNetworkId;
this.providerName = provider_name;
this.hostId = hostId;
this.state = PhysicalNetworkServiceProvider.State.Disabled;
this.allocationState = AllocationState.Free;
}
public ExternalFirewallDeviceVO() {
@ -103,4 +111,12 @@ public class ExternalFirewallDeviceVO {
public void setState(State state) {
this.state = state;
}
public AllocationState getAllocationState() {
return allocationState;
}
public void setAllocationState(AllocationState allocationState) {
this.allocationState = allocationState;
}
}

View File

@ -27,11 +27,8 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.network.PhysicalNetworkServiceProvider.State;
/**
* ExternalLoadBalancerDeviceVO contains information of a external load balancer device (F5/Netscaler)
* added into a deployment
* ExternalLoadBalancerDeviceVO contains information of a external load balancer devices (F5/Netscaler VPX,MPX,SDX) added into a deployment
*/
@Entity
@ -52,29 +49,63 @@ public class ExternalLoadBalancerDeviceVO {
@Column(name = "provider_name")
private String providerName;
@Column(name = "device_name")
private String deviceName;
@Column(name="state")
@Enumerated(value=EnumType.STRING)
private State state;
private LBDeviceState state;
@Column(name = "allocation_state")
@Enumerated(value=EnumType.STRING)
private LBDeviceAllocationState allocationState;
@Column(name="managed")
boolean managedDevice;
@Column(name = "parent_host_id")
private long parentHostId;
@Column(name = "capacity")
private long capacity;
@Column(name = "capacity_type")
private String capacity_type;
public enum LBDeviceState {
Enabled,
Disabled
}
public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name) {
public enum LBDeviceAllocationState {
Free, // In this state no networks are using this device for load balancing
InSharedUse, // In this state one or more networks will be using this device for load balancing
InDedicatedUse // In this state this device is dedicated for a single network
}
public enum LBDeviceManagedType {
CloudManaged, // Cloudstack managed load balancer (e.g. VPX instances on SDX for now, in future releases load balancer provisioned from template)
ExternalManaged // Externally managed
}
public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, String device_name) {
this.physicalNetworkId = physicalNetworkId;
this.providerName = provider_name;
this.deviceName = device_name;
this.hostId = hostId;
this.state = PhysicalNetworkServiceProvider.State.Disabled;
this.state = LBDeviceState.Disabled;
this.allocationState = LBDeviceAllocationState.Free;
this.managedDevice = false;
}
public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, long capacity, String capacityType) {
this(hostId, physicalNetworkId, provider_name);
this.capacity = capacity;
this.capacity_type = capacityType;
public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, String device_name, boolean managed, long parentHostId) {
this(hostId, physicalNetworkId, provider_name, device_name);
this.managedDevice = managed;
this.parentHostId = parentHostId;
}
public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, String device_name, long capacity) {
this(hostId, physicalNetworkId, provider_name, device_name);
this.capacity = capacity;
}
public ExternalLoadBalancerDeviceVO() {
}
@ -91,24 +122,43 @@ public class ExternalLoadBalancerDeviceVO {
return providerName;
}
public String getDeviceName() {
return deviceName;
}
public long getHostId() {
return hostId;
}
public long getParentHostId() {
return parentHostId;
}
public void setParentHostId(long parentHostId) {
this.parentHostId = parentHostId;
}
public long getCapacity() {
return capacity;
}
public String getCapacityType() {
return capacity_type;
public void setCapacity(long capacity) {
this.capacity = capacity;
}
public State getState() {
public LBDeviceState getState() {
return state;
}
public void setState(State state) {
public void setState(LBDeviceState state) {
this.state = state;
}
public LBDeviceAllocationState getAllocationState() {
return allocationState;
}
public void setAllocationState(LBDeviceAllocationState allocationState) {
this.allocationState = allocationState;
}
}

View File

@ -49,7 +49,9 @@ public interface ExternalNetworkDeviceManager extends Manager {
public static final NetworkDevice ExternalDhcp = new NetworkDevice("ExternalDhcp", null);
public static final NetworkDevice PxeServer = new NetworkDevice("PxeServer", null);
public static final NetworkDevice NetscalerLoadBalancer = new NetworkDevice("NetscalerLoadBalancer", Network.Provider.Netscaler.getName());
public static final NetworkDevice NetscalerMPXLoadBalancer = new NetworkDevice("NetscalerMPXLoadBalancer", Network.Provider.Netscaler.getName());
public static final NetworkDevice NetscalerVPXLoadBalancer = new NetworkDevice("NetscalerVPXLoadBalancer", Network.Provider.Netscaler.getName());
public static final NetworkDevice NetscalerSDXLoadBalancer = new NetworkDevice("NetscalerSDXLoadBalancer", Network.Provider.Netscaler.getName());
public static final NetworkDevice F5BigIpLoadBalancer = new NetworkDevice("F5BigIpLoadBalancer", Network.Provider.F5BigIp.getName());
public static final NetworkDevice JuniperSRXFirewall = new NetworkDevice("JuniperSRXFirewall", Network.Provider.JuniperSRX.getName());

View File

@ -82,7 +82,10 @@ import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.ExternalFirewallDeviceDao;
@ -93,6 +96,7 @@ import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkExternalFirewallDao;
import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
@ -110,8 +114,8 @@ import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.StaticNatRule;
import com.cloud.network.rules.StaticNatRuleImpl;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.resource.ServerResource;
import com.cloud.server.api.response.ExternalFirewallResponse;
import com.cloud.server.api.response.ExternalLoadBalancerResponse;
@ -177,6 +181,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
@Inject ExternalFirewallDeviceDao _externalFirewallDeviceDao;
@Inject NetworkExternalLoadBalancerDao _networkExternalLBDao;
@Inject NetworkExternalFirewallDao _networkExternalFirewallDao;
@Inject NetworkServiceMapDao _ntwkSrvcProviderDao;
ScheduledExecutorService _executor;
int _externalNetworkStatsInterval;
@ -221,7 +226,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
Collection paramsCollection = paramList.values();
HashMap params = (HashMap) (paramsCollection.toArray())[0];
if (cmd.getType().equalsIgnoreCase(NetworkDevice.ExternalDhcp.getName())) {
if (cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.ExternalDhcp.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long podId = Long.parseLong((String)params.get(ApiConstants.POD_ID));
String type = (String) params.get(ApiConstants.DHCP_SERVER_TYPE);
@ -230,7 +235,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
String password = (String) params.get(ApiConstants.PASSWORD);
return _dhcpMgr.addDhcpServer(zoneId, podId, type, url, username, password);
} else if (cmd.getType().equalsIgnoreCase(NetworkDevice.PxeServer.getName())) {
} else if (cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.PxeServer.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long podId = Long.parseLong((String)params.get(ApiConstants.POD_ID));
String type = (String) params.get(ApiConstants.PXE_SERVER_TYPE);
@ -245,20 +250,19 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
PxeServerProfile profile = new PxeServerProfile(zoneId, podId, url, username, password, type, pingStorageServerIp, pingDir, tftpDir,
pingCifsUsername, pingCifsPassword);
return _pxeMgr.addPxeServer(profile);
} else if (cmd.getType().equalsIgnoreCase(NetworkDevice.JuniperSRXFirewall.getName())) {
} else if (cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.JuniperSRXFirewall.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return addExternalFirewall(zoneId, networkId, NetworkDevice.JuniperSRXFirewall.getName(), cmd.getParamList());
} else if (cmd.getType().equalsIgnoreCase(NetworkDevice.NetscalerLoadBalancer.getName())) {
Long physicalNetworkId = (params.get(ApiConstants.PHYSICAL_NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.PHYSICAL_NETWORK_ID)):null;
return addExternalFirewall(zoneId, physicalNetworkId, NetworkDevice.JuniperSRXFirewall.getName(), cmd.getParamList());
} else if (cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.F5BigIpLoadBalancer.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return addExternalLoadBalancer(zoneId, networkId, NetworkDevice.NetscalerLoadBalancer.getName(), cmd.getParamList());
} else if (cmd.getType().equalsIgnoreCase(NetworkDevice.F5BigIpLoadBalancer.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return addExternalLoadBalancer(zoneId, networkId, NetworkDevice.F5BigIpLoadBalancer.getName(), cmd.getParamList());
Long physicalNetworkId = (params.get(ApiConstants.PHYSICAL_NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.PHYSICAL_NETWORK_ID)):null;
return addExternalLoadBalancer(zoneId, physicalNetworkId, cmd.getDeviceType(), cmd.getParamList());
} else {
throw new CloudRuntimeException("Unsupported network device type:" + cmd.getType());
throw new CloudRuntimeException("Unsupported network device type:" + cmd.getDeviceType());
}
}
@ -289,6 +293,10 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
} else {
throw new CloudRuntimeException("Unsupported PXE server type:" + pxeType);
}
} else if (host.getType() == Host.Type.ExternalLoadBalancer) {
response = createExternalLoadBalancerResponse(host);
} else if (host.getType() == Host.Type.ExternalFirewall) {
response = createExternalFirewallResponse(host);
} else {
throw new CloudRuntimeException("Unsupported network device type:" + host.getType());
}
@ -324,34 +332,33 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
List<Host> res;
Collection paramsCollection = paramList.values();
HashMap params = (HashMap) (paramsCollection.toArray())[0];
if (NetworkDevice.ExternalDhcp.getName().equalsIgnoreCase(cmd.getType())) {
if (NetworkDevice.ExternalDhcp.getName().equalsIgnoreCase(cmd.getDeviceType())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long podId = Long.parseLong((String)params.get(ApiConstants.POD_ID));
res = listNetworkDevice(zoneId, null, podId, Host.Type.ExternalDhcp);
} else if (NetworkDevice.PxeServer.getName().equalsIgnoreCase(cmd.getType())) {
} else if (NetworkDevice.PxeServer.getName().equalsIgnoreCase(cmd.getDeviceType())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long podId = Long.parseLong((String)params.get(ApiConstants.POD_ID));
res = listNetworkDevice(zoneId, null, podId, Host.Type.PxeServer);
} else if (NetworkDevice.F5BigIpLoadBalancer.getName().equalsIgnoreCase(cmd.getType())) {
} else if (cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName()) ||
cmd.getDeviceType().equalsIgnoreCase(NetworkDevice.F5BigIpLoadBalancer.getName())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return listExternalLoadBalancers(zoneId, networkId, NetworkDevice.F5BigIpLoadBalancer.getName());
} else if (NetworkDevice.NetscalerLoadBalancer.getName().equalsIgnoreCase(cmd.getType())) {
Long physicalNetworkId = (params.get(ApiConstants.PHYSICAL_NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.PHYSICAL_NETWORK_ID)):null;
return listExternalLoadBalancers(zoneId, physicalNetworkId, cmd.getDeviceType());
} else if (NetworkDevice.JuniperSRXFirewall.getName().equalsIgnoreCase(cmd.getDeviceType())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return listExternalLoadBalancers(zoneId, networkId, NetworkDevice.NetscalerLoadBalancer.getName());
} else if (NetworkDevice.JuniperSRXFirewall.getName().equalsIgnoreCase(cmd.getType())) {
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
return listExternalFirewalls(zoneId, networkId, NetworkDevice.JuniperSRXFirewall.getName());
} else if (cmd.getType() == null){
Long physicalNetworkId = (params.get(ApiConstants.PHYSICAL_NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.PHYSICAL_NETWORK_ID)):null;
return listExternalFirewalls(zoneId, physicalNetworkId, NetworkDevice.JuniperSRXFirewall.getName());
} else if (cmd.getDeviceType() == null){
Long zoneId = Long.parseLong((String) params.get(ApiConstants.ZONE_ID));
Long podId = Long.parseLong((String)params.get(ApiConstants.POD_ID));
Long networkId = (params.get(ApiConstants.NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.NETWORK_ID)):null;
List<Host> res1 = listNetworkDevice(zoneId, networkId, podId, Host.Type.PxeServer);
List<Host> res2 = listNetworkDevice(zoneId, networkId, podId, Host.Type.ExternalDhcp);
List<Host> res3 = listNetworkDevice(zoneId, networkId, podId, Host.Type.ExternalLoadBalancer);
List<Host> res4 = listNetworkDevice(zoneId, networkId, podId, Host.Type.ExternalFirewall);
Long physicalNetworkId = (params.get(ApiConstants.PHYSICAL_NETWORK_ID)==null)?Long.parseLong((String)params.get(ApiConstants.PHYSICAL_NETWORK_ID)):null;
List<Host> res1 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.PxeServer);
List<Host> res2 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalDhcp);
List<Host> res3 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalLoadBalancer);
List<Host> res4 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalFirewall);
List<Host> deviceAll = new ArrayList<Host>();
deviceAll.addAll(res1);
deviceAll.addAll(res2);
@ -359,7 +366,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
deviceAll.addAll(res4);
res = deviceAll;
} else {
throw new CloudRuntimeException("Unknown network device type:" + cmd.getType());
throw new CloudRuntimeException("Unknown network device type:" + cmd.getDeviceType());
}
return res;
@ -412,23 +419,63 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
_networkExternalFirewallDao.persist(fwDeviceForNetwork);
}
protected long findSuitableLBDeviceForNetwork(Network network) throws InsufficientCapacityException {
protected long findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException {
long physicalNetworkId = network.getPhysicalNetworkId();
List<ExternalLoadBalancerDeviceVO> lbDevices = _externalLoadBalancerDeviceDao.listByPhysicalNetwork(physicalNetworkId);
List<ExternalLoadBalancerDeviceVO> lbDevices =null;
String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
assert(provider != null);
// loop through the LB device in the physical network and pick the first-fit
for (ExternalLoadBalancerDeviceVO lbdevice: lbDevices) {
// max number of guest networks that can be mapped to this device
long fullCapacity = lbdevice.getCapacity();
if (dedicatedLb) {
lbDevices = _externalLoadBalancerDeviceDao.listByDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
if (lbDevices != null && !lbDevices.isEmpty()) {
for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
if (lbdevice.getState() == LBDeviceState.Enabled) {
return lbdevice.getId(); //return first device that is free and fully configured
}
}
}
} else {
// get the LB devices that are already allocated for shared use
lbDevices = _externalLoadBalancerDeviceDao.listByDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.InSharedUse);
// get the list of guest networks that are mapped to this load balancer
List<NetworkExternalLoadBalancerVO> mappedNetworks = _networkExternalLBDao.listByLBDeviceId(lbdevice.getId());
if (lbDevices != null) {
// loop through the LB device in the physical network and pick the first-fit
for (ExternalLoadBalancerDeviceVO lbdevice: lbDevices) {
long usedCapacity = (mappedNetworks == null) ? 0 : mappedNetworks.size();
if ((fullCapacity - usedCapacity) > 0) {
return lbdevice.getId();
// skip if device is not enabled
if (lbdevice.getState() != LBDeviceState.Enabled) {
continue;
}
// get max number of guest networks that can be mapped to this device
long fullCapacity = lbdevice.getCapacity();
assert (fullCapacity != 0) : "How did the capacity of device ended up as zero?";
// get the list of guest networks that are mapped to this load balancer
List<NetworkExternalLoadBalancerVO> mappedNetworks = _networkExternalLBDao.listByLBDeviceId(lbdevice.getId());
long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty()))? 0 : mappedNetworks.size();
if ((fullCapacity - usedCapacity) > 0) {
return lbdevice.getId();
}
}
}
// if we are here then there are no existing LB devices in shared use or the devices in shared use has no free capacity
// so allocate a new one from the pool of free LB devices
lbDevices = _externalLoadBalancerDeviceDao.listByDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
if (lbDevices != null && !lbDevices.isEmpty()) {
for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
if (lbdevice.getState() == LBDeviceState.Enabled) {
return lbdevice.getId(); //return first device that is free and fully configured
}
}
}
}
// there are no LB device or there is no free capacity on the devices in the physical network
// FIXME: check if new device from SDX can be provisioned
throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " +
" to implement the network", Network.class, network.getId());
}
@ -550,7 +597,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
if (deviceName.equalsIgnoreCase(NetworkDevice.F5BigIpLoadBalancer.getName())) {
resource = new F5BigIpResource();
guid = getExternalNetworkResourceGuid(zoneId, ExternalNetworkResourceName.F5BigIp, ipAddress);
} else if (deviceName.equalsIgnoreCase(NetworkDevice.NetscalerLoadBalancer.getName())) {
} else if (Provider.Netscaler.getName().equalsIgnoreCase(ntwkDevice.getNetworkServiceProvder())) {
resource = new NetscalerResource();
guid = getExternalNetworkResourceGuid(zoneId, ExternalNetworkResourceName.NetscalerMPX, ipAddress);
} else {
@ -569,6 +616,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
hostDetails.put("guid", guid);
hostDetails.put("name", guid);
hostDetails.put("inline", String.valueOf(inline));
hostDetails.put("deviceName", deviceName);
try {
resource.configure(guid, hostDetails);
@ -580,7 +628,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
if (host != null) {
Transaction txn = Transaction.currentTxn();
txn.start();
ExternalLoadBalancerDeviceVO device = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName());
ExternalLoadBalancerDeviceVO device = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName(), deviceName);
_externalLoadBalancerDeviceDao.persist(device);
txn.commit();
return host;
@ -630,7 +678,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
PhysicalNetworkVO pNetwork=null;
if (((zoneId == null) && (physicalNetworkId == null)) || (lbNetworkDevice == null)) {
throw new InvalidParameterValueException("Atleast one of ther required parameter zone Id, physical networkId, device name is missing or invalid.");
throw new InvalidParameterValueException("Atleast one of the required parameter zone Id, physical networkId, device name is missing or invalid.");
}
if (physicalNetworkId != null) {
@ -649,6 +697,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
if (physicalNetworkId == null) {
return lbHostsInZone;
}
PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(),
lbNetworkDevice.getNetworkServiceProvder());
//if provider not configured in to physical network, then there can be no instances
@ -680,7 +729,7 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
@Override
public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException {
if (guestConfig.getTrafficType() != TrafficType.Guest) {
s_logger.trace("External load balancer can only be user for add/remove guest networks.");
s_logger.trace("External load balancer can only be user for guest networks.");
return false;
}
@ -689,25 +738,47 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
HostVO externalLoadBalancer = null;
if (add) {
GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkLBDeviceMap");
GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
Transaction txn = Transaction.currentTxn();
try {
if (deviceMapLock.lock(120)) {
try {
long externalLoadBalancerId = findSuitableLBDeviceForNetwork(guestConfig);
NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), externalLoadBalancerId);
NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
long lbDeviceId;
txn.start();
// find a load balancer device as per the network offering
boolean dedicatedLB = offering.getDedicatedLB();
lbDeviceId = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB);
// persist the load balancer device id that will be used for this network. Once a network
// is implemented on a LB device then later on all rules will be programmed on to same device
NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId);
_networkExternalLBDao.persist(networkLB);
ExternalLoadBalancerDeviceVO device = _externalLoadBalancerDeviceDao.findById(externalLoadBalancerId);
externalLoadBalancer = _hostDao.findById(device.getHostId());
// mark device to be in use
ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.InDedicatedUse : LBDeviceAllocationState.InSharedUse);
_externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice);
// return the HostVO for the lb device
externalLoadBalancer = _hostDao.findById(lbDevice.getHostId());
txn.commit();
} finally {
deviceMapLock.unlock();
if (externalLoadBalancer == null) {
txn.rollback();
}
}
}
} finally {
deviceMapLock.releaseRef();
}
} else {
// find the load balancer device allocated for the network
externalLoadBalancer = getExternalLoadBalancerForNetwork(guestConfig);
assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??";
}
// Send a command to the external load balancer to implement or shutdown the guest network
@ -736,6 +807,26 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
savePlaceholderNic(guestConfig, selfIp);
}
if (!add) {
Transaction txn = Transaction.currentTxn();
txn.start();
// since network is shutdown remove the network mapping to the load balancer device
NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId());
_networkExternalLBDao.remove(networkLBDevice.getId());
// if this is the last network mapped to the load balancer device then set device allocation state to be free
List<NetworkExternalLoadBalancerVO> ntwksMapped = _networkExternalLBDao.listByLBDeviceId(networkLBDevice.getExternalLBDeviceId());
if (ntwksMapped == null || ntwksMapped.isEmpty()) {
ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(networkLBDevice.getExternalLBDeviceId());
lbDevice.setAllocationState(LBDeviceAllocationState.Free);
_externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice);
//TODO: if device is cloud managed then take action
}
txn.commit();
}
Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId());
String action = add ? "implemented" : "shut down";
s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag);
@ -750,9 +841,9 @@ public class ExternalNetworkDeviceManagerImpl implements ExternalNetworkDeviceMa
DataCenterVO zone = _dcDao.findById(zoneId);
HostVO externalLoadBalancer = getExternalLoadBalancerForNetwork(network);
assert(externalLoadBalancer != null);
assert(externalLoadBalancer != null) : "There is no device assigned to this network how apply rules ended up here??";
// If the load balancer is inline, find the external firewall in this zone
// FIXME: remove this restriction for in-line case firewall provider need not be external firewall
boolean externalLoadBalancerIsInline = externalLoadBalancerIsInline(externalLoadBalancer);
HostVO externalFirewall = null;
if (externalLoadBalancerIsInline) {

View File

@ -25,6 +25,11 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* NetworkExternalFirewallVO contains information on the networks that are using external firewall
*/
@Entity
@Table(name="network_external_firewall_device_map")
public class NetworkExternalFirewallVO {

View File

@ -17,6 +17,8 @@
*/
package com.cloud.network;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@ -24,6 +26,12 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDao;
/**
* NetworkExternalLoadBalancerVO contains information on the networks that are using external load balancers
*/
@Entity
@Table(name="network_external_lb_device_map")
public class NetworkExternalLoadBalancerVO {
@ -42,6 +50,12 @@ public class NetworkExternalLoadBalancerVO {
@Column(name = "subscribed_capacity")
private long subscribedCapacity;
@Column(name=GenericDao.CREATED_COLUMN)
Date created;
@Column(name=GenericDao.REMOVED_COLUMN)
Date removed;
public NetworkExternalLoadBalancerVO(long networkId, long externalLBDeviceID) {
this.networkId = networkId;
this.externalLBDeviceId = externalLBDeviceID;

View File

@ -20,11 +20,13 @@ package com.cloud.network.dao;
import java.util.List;
import com.cloud.network.ExternalLoadBalancerDeviceVO;
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
import com.cloud.utils.db.GenericDao;
public interface ExternalLoadBalancerDeviceDao extends GenericDao<ExternalLoadBalancerDeviceVO, Long> {
List<ExternalLoadBalancerDeviceVO> listByPhysicalNetworkServiceProvider(long physicalNetworkId, String provider_name);
List<ExternalLoadBalancerDeviceVO> listByPhysicalNetwork(long physicalNetworkId);
List<ExternalLoadBalancerDeviceVO> listByDeviceAllocationState(long physicalNetworkId, String provider_name, LBDeviceAllocationState state);
}

View File

@ -21,6 +21,7 @@ package com.cloud.network.dao;
import java.util.List;
import javax.ejb.Local;
import com.cloud.network.ExternalLoadBalancerDeviceVO;
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
@ -31,6 +32,7 @@ import com.cloud.utils.db.SearchCriteria.Op;
public class ExternalLoadBalancerDeviceDaoImpl extends GenericDaoBase<ExternalLoadBalancerDeviceVO, Long> implements ExternalLoadBalancerDeviceDao {
final SearchBuilder<ExternalLoadBalancerDeviceVO> physicalNetworkServiceProviderSearch;
final SearchBuilder<ExternalLoadBalancerDeviceVO> physicalNetworkIdSearch;
final SearchBuilder<ExternalLoadBalancerDeviceVO> allocationStateSearch;
public ExternalLoadBalancerDeviceDaoImpl() {
super();
@ -42,6 +44,11 @@ public class ExternalLoadBalancerDeviceDaoImpl extends GenericDaoBase<ExternalLo
physicalNetworkIdSearch = createSearchBuilder();
physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), Op.EQ);
physicalNetworkIdSearch.done();
allocationStateSearch = createSearchBuilder();
allocationStateSearch.and("physicalNetworkId", allocationStateSearch.entity().getPhysicalNetworkId(), Op.EQ);
allocationStateSearch.and("allocationState", allocationStateSearch.entity().getAllocationState(), Op.EQ);
allocationStateSearch.done();
}
@Override
@ -54,8 +61,17 @@ public class ExternalLoadBalancerDeviceDaoImpl extends GenericDaoBase<ExternalLo
@Override
public List<ExternalLoadBalancerDeviceVO> listByPhysicalNetworkServiceProvider(long physicalNetworkId, String provider_name) {
SearchCriteria<ExternalLoadBalancerDeviceVO> sc = physicalNetworkServiceProviderSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
sc.setParameters("provider_name", provider_name);
return search(sc, null);
}
@Override
public List<ExternalLoadBalancerDeviceVO> listByDeviceAllocationState(long physicalNetworkId, String provider_name, LBDeviceAllocationState state) {
SearchCriteria<ExternalLoadBalancerDeviceVO> sc = allocationStateSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
sc.setParameters("provider_name", provider_name);
sc.setParameters("allocationState", state);
return search(sc, null);
}
}

View File

@ -160,7 +160,7 @@ public class NetscalerExternalLoadBalancerElement extends AdapterBase implements
@Override
public boolean isReady(PhysicalNetworkServiceProvider provider) {
// TODO Auto-generated method stub
// FIXME: return true if atleast one Netscaler device is added in to physical network and is configured (in enabled state)
return true;
}

View File

@ -24,7 +24,7 @@ import com.cloud.api.response.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class ExternalFirewallResponse extends BaseResponse {
public class ExternalFirewallResponse extends NetworkDeviceResponse {
@SerializedName(ApiConstants.ID) @Param(description="the ID of the external firewall")
private Long id;

View File

@ -24,7 +24,7 @@ import com.cloud.api.response.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class ExternalLoadBalancerResponse extends BaseResponse {
public class ExternalLoadBalancerResponse extends NetworkDeviceResponse {
@SerializedName(ApiConstants.ID) @Param(description="the ID of the external load balancer")
private Long id;

View File

@ -1817,23 +1817,28 @@ CREATE TABLE `cloud`.`physical_network_service_providers` (
CREATE TABLE `cloud`.`external_load_balancer_devices` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external load balancer device',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network to which the device is added in to',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which the device is added',
`provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this device',
`device_name` varchar(255) NOT NULL COMMENT 'name of the load balancer device',
`state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device',
`allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state of the device',
`managed` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device is provisioned and its life cycle is managed by by cloudstack',
`host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external load balancer device',
`parent_host_id` bigint unsigned COMMENT 'if cloudstack managed, then host id on which this device is provisioned',
`capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the load balancer device',
`capacity_type` varchar(32) NOT NULL DEFAULT 'Throughput' COMMENT 'Type of the capacity',
PRIMARY KEY (`id`),
CONSTRAINT `fk_external_lb_devices_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_external_lb_devices_parent_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_external_lb_devices_physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`external_firewall_devices` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external firewall device',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network to which the device is added in to',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which the device is added',
`provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this device',
`state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device',
`allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state of the device',
`capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the external firewall device',
`capacity_type` varchar(32) NOT NULL DEFAULT 'Throughput' COMMENT 'Type of the capacity',
PRIMARY KEY (`id`),
@ -1846,6 +1851,8 @@ CREATE TABLE `cloud`.`network_external_lb_device_map` (
`network_id` bigint unsigned NOT NULL COMMENT ' guest network id',
`external_load_balancer_device_id` bigint unsigned NOT NULL COMMENT 'id of external LB device',
`subscribed_capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the device this network is subscrbed to',
`created` datetime COMMENT 'Date from when network started using the device',
`removed` datetime COMMENT 'Date till the network stopped using the device ',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_external_lb_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_network_external_lb_devices_device_id` FOREIGN KEY (`external_load_balancer_device_id`) REFERENCES `external_load_balancer_devices`(`id`) ON DELETE CASCADE
@ -1855,6 +1862,8 @@ CREATE TABLE `cloud`.`network_external_firewall_device_map` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`network_id` bigint unsigned NOT NULL COMMENT ' guest network id',
`external_firewall_device_id` bigint unsigned NOT NULL COMMENT 'id of external firewall device',
`created` datetime COMMENT 'Date from when network started using the device',
`removed` datetime COMMENT 'Date till the network stopped using the device ',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_external_firewall_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_network_external_firewall_devices_device_id` FOREIGN KEY (`external_firewall_device_id`) REFERENCES `external_firewall_devices`(`id`) ON DELETE CASCADE