From 122b62066a69637362fc414dc33dae10afd43929 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Thu, 10 Nov 2011 09:55:23 -0800 Subject: [PATCH] bug 11817: NAAS: device allocation logic - adding a allocation state to device - change device allocation logic based on network offering and device state --- .../network/resource/NetscalerResource.java | 16 +- .../api/commands/AddNetworkDeviceCmd.java | 4 +- .../api/commands/ListNetworkDeviceCmd.java | 4 +- .../network/ExternalFirewallDeviceVO.java | 22 +- .../network/ExternalLoadBalancerDeviceVO.java | 84 ++++++-- .../network/ExternalNetworkDeviceManager.java | 4 +- .../ExternalNetworkDeviceManagerImpl.java | 203 +++++++++++++----- .../network/NetworkExternalFirewallVO.java | 5 + .../NetworkExternalLoadBalancerVO.java | 14 ++ .../dao/ExternalLoadBalancerDeviceDao.java | 2 + .../ExternalLoadBalancerDeviceDaoImpl.java | 18 +- .../NetscalerExternalLoadBalancerElement.java | 2 +- .../response/ExternalFirewallResponse.java | 2 +- .../ExternalLoadBalancerResponse.java | 2 +- setup/db/create-schema.sql | 17 +- 15 files changed, 301 insertions(+), 98 deletions(-) diff --git a/core/src/com/cloud/network/resource/NetscalerResource.java b/core/src/com/cloud/network/resource/NetscalerResource.java index 231e1f29e2c..3eb7f559c0d 100644 --- a/core/src/com/cloud/network/resource/NetscalerResource.java +++ b/core/src/com/cloud/network/resource/NetscalerResource.java @@ -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(); diff --git a/server/src/com/cloud/api/commands/AddNetworkDeviceCmd.java b/server/src/com/cloud/api/commands/AddNetworkDeviceCmd.java index fa0b4756b15..960d70f1d12 100644 --- a/server/src/com/cloud/api/commands/AddNetworkDeviceCmd.java +++ b/server/src/com/cloud/api/commands/AddNetworkDeviceCmd.java @@ -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; } diff --git a/server/src/com/cloud/api/commands/ListNetworkDeviceCmd.java b/server/src/com/cloud/api/commands/ListNetworkDeviceCmd.java index a66ae433d2a..310a096cfeb 100644 --- a/server/src/com/cloud/api/commands/ListNetworkDeviceCmd.java +++ b/server/src/com/cloud/api/commands/ListNetworkDeviceCmd.java @@ -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; } diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceVO.java b/server/src/com/cloud/network/ExternalFirewallDeviceVO.java index 0160c78f4d7..45297e54cb2 100644 --- a/server/src/com/cloud/network/ExternalFirewallDeviceVO.java +++ b/server/src/com/cloud/network/ExternalFirewallDeviceVO.java @@ -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; + } } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java index 0a166489ccb..e8c8f123155 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java @@ -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; + } } diff --git a/server/src/com/cloud/network/ExternalNetworkDeviceManager.java b/server/src/com/cloud/network/ExternalNetworkDeviceManager.java index dc462a30ee9..51d24ab18ac 100644 --- a/server/src/com/cloud/network/ExternalNetworkDeviceManager.java +++ b/server/src/com/cloud/network/ExternalNetworkDeviceManager.java @@ -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()); diff --git a/server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java index b75d1f56525..2c2ad8ed001 100644 --- a/server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java @@ -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 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 res1 = listNetworkDevice(zoneId, networkId, podId, Host.Type.PxeServer); - List res2 = listNetworkDevice(zoneId, networkId, podId, Host.Type.ExternalDhcp); - List res3 = listNetworkDevice(zoneId, networkId, podId, Host.Type.ExternalLoadBalancer); - List 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 res1 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.PxeServer); + List res2 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalDhcp); + List res3 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalLoadBalancer); + List res4 = listNetworkDevice(zoneId, physicalNetworkId, podId, Host.Type.ExternalFirewall); List deviceAll = new ArrayList(); 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 lbDevices = _externalLoadBalancerDeviceDao.listByPhysicalNetwork(physicalNetworkId); + List 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 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 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 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) { diff --git a/server/src/com/cloud/network/NetworkExternalFirewallVO.java b/server/src/com/cloud/network/NetworkExternalFirewallVO.java index a26af04377a..9cba5dc1186 100644 --- a/server/src/com/cloud/network/NetworkExternalFirewallVO.java +++ b/server/src/com/cloud/network/NetworkExternalFirewallVO.java @@ -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 { diff --git a/server/src/com/cloud/network/NetworkExternalLoadBalancerVO.java b/server/src/com/cloud/network/NetworkExternalLoadBalancerVO.java index 2dd5ec5b5df..17ecd3d5de3 100644 --- a/server/src/com/cloud/network/NetworkExternalLoadBalancerVO.java +++ b/server/src/com/cloud/network/NetworkExternalLoadBalancerVO.java @@ -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; diff --git a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java b/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java index 7ab9c3a198a..e7d8b464b54 100644 --- a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java +++ b/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java @@ -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 { List listByPhysicalNetworkServiceProvider(long physicalNetworkId, String provider_name); List listByPhysicalNetwork(long physicalNetworkId); + List listByDeviceAllocationState(long physicalNetworkId, String provider_name, LBDeviceAllocationState state); } diff --git a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java b/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java index 959bdf68fe1..f41510e7fd5 100644 --- a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java +++ b/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java @@ -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 implements ExternalLoadBalancerDeviceDao { final SearchBuilder physicalNetworkServiceProviderSearch; final SearchBuilder physicalNetworkIdSearch; + final SearchBuilder allocationStateSearch; public ExternalLoadBalancerDeviceDaoImpl() { super(); @@ -42,6 +44,11 @@ public class ExternalLoadBalancerDeviceDaoImpl extends GenericDaoBase listByPhysicalNetworkServiceProvider(long physicalNetworkId, String provider_name) { SearchCriteria sc = physicalNetworkServiceProviderSearch.create(); + sc.setParameters("physicalNetworkId", physicalNetworkId); sc.setParameters("provider_name", provider_name); return search(sc, null); } - + + @Override + public List listByDeviceAllocationState(long physicalNetworkId, String provider_name, LBDeviceAllocationState state) { + SearchCriteria sc = allocationStateSearch.create(); + sc.setParameters("physicalNetworkId", physicalNetworkId); + sc.setParameters("provider_name", provider_name); + sc.setParameters("allocationState", state); + return search(sc, null); + } } diff --git a/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java b/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java index 0b925b9d53b..eeda45347cd 100644 --- a/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java +++ b/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java @@ -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; } diff --git a/server/src/com/cloud/server/api/response/ExternalFirewallResponse.java b/server/src/com/cloud/server/api/response/ExternalFirewallResponse.java index b5dad30080c..29428521174 100644 --- a/server/src/com/cloud/server/api/response/ExternalFirewallResponse.java +++ b/server/src/com/cloud/server/api/response/ExternalFirewallResponse.java @@ -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; diff --git a/server/src/com/cloud/server/api/response/ExternalLoadBalancerResponse.java b/server/src/com/cloud/server/api/response/ExternalLoadBalancerResponse.java index 5d5baa68b0c..7f3005f7f09 100644 --- a/server/src/com/cloud/server/api/response/ExternalLoadBalancerResponse.java +++ b/server/src/com/cloud/server/api/response/ExternalLoadBalancerResponse.java @@ -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; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 5c91ea49a55..878d7594e58 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -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