mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-17 02:53:18 +01:00
bug CS-14291: support EIP with multiple NetScalers in basic zone
This fix will enable support for multiple NetScaler devices providing EIP service in same zone.
- Introduced global setting "eip.use.multiple.netscalers" to turn multiple netscaler support
- Enhanced configureNetscalerLoadBalancer API to take the PBR setup between the POD's subnet
and NetScaler device
- logic to pick a NetScaler (based on the guest IP and corresponding pod) while configuring INAT rule
This commit is contained in:
parent
ca5683e29d
commit
3b1aca19b3
@ -127,6 +127,7 @@ public class ApiConstants {
|
|||||||
public static final String SSHKEY_ENABLED = "sshkeyenabled";
|
public static final String SSHKEY_ENABLED = "sshkeyenabled";
|
||||||
public static final String PATH = "path";
|
public static final String PATH = "path";
|
||||||
public static final String POD_ID = "podid";
|
public static final String POD_ID = "podid";
|
||||||
|
public static final String POD_IDS = "podids";
|
||||||
public static final String POLICY_ID = "policyid";
|
public static final String POLICY_ID = "policyid";
|
||||||
public static final String PORT = "port";
|
public static final String PORT = "port";
|
||||||
public static final String PORTAL = "portal";
|
public static final String PORTAL = "portal";
|
||||||
|
|||||||
@ -12,11 +12,16 @@
|
|||||||
// Automatically generated by addcopyright.py at 04/03/2012
|
// Automatically generated by addcopyright.py at 04/03/2012
|
||||||
package com.cloud.api.response;
|
package com.cloud.api.response;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.cloud.api.ApiConstants;
|
import com.cloud.api.ApiConstants;
|
||||||
|
import com.cloud.api.Parameter;
|
||||||
|
import com.cloud.api.BaseCmd.CommandType;
|
||||||
import com.cloud.utils.IdentityProxy;
|
import com.cloud.utils.IdentityProxy;
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class NetscalerLoadBalancerResponse extends BaseResponse {
|
public class NetscalerLoadBalancerResponse extends BaseResponse {
|
||||||
|
|
||||||
@SerializedName(ApiConstants.LOAD_BALANCER_DEVICE_ID) @Param(description="device id of the netscaler load balancer")
|
@SerializedName(ApiConstants.LOAD_BALANCER_DEVICE_ID) @Param(description="device id of the netscaler load balancer")
|
||||||
@ -52,6 +57,11 @@ public class NetscalerLoadBalancerResponse extends BaseResponse {
|
|||||||
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the management IP address of the external load balancer")
|
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the management IP address of the external load balancer")
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.POD_IDS) @Param(description="Used when NetScaler device is provider of EIP service." +
|
||||||
|
" This parameter represents the list of pod's, for which there exists a policy based route on datacenter L3 router to " +
|
||||||
|
"route pod's subnet IP to a NetScaler device.")
|
||||||
|
private List<Long> podIds;
|
||||||
|
|
||||||
public void setId(long lbDeviceId) {
|
public void setId(long lbDeviceId) {
|
||||||
this.id.setValue(lbDeviceId);
|
this.id.setValue(lbDeviceId);
|
||||||
}
|
}
|
||||||
@ -95,4 +105,8 @@ public class NetscalerLoadBalancerResponse extends BaseResponse {
|
|||||||
public void setIpAddress(String ipAddress) {
|
public void setIpAddress(String ipAddress) {
|
||||||
this.ipAddress = ipAddress;
|
this.ipAddress = ipAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAssociatedPods(List<Long> pods) {
|
||||||
|
this.podIds = pods;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
// Automatically generated by addcopyright.py at 04/03/2012
|
// Automatically generated by addcopyright.py at 04/03/2012
|
||||||
package com.cloud.api.commands;
|
package com.cloud.api.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.api.ApiConstants;
|
import com.cloud.api.ApiConstants;
|
||||||
@ -22,6 +24,7 @@ import com.cloud.api.Implementation;
|
|||||||
import com.cloud.api.Parameter;
|
import com.cloud.api.Parameter;
|
||||||
import com.cloud.api.PlugService;
|
import com.cloud.api.PlugService;
|
||||||
import com.cloud.api.ServerApiException;
|
import com.cloud.api.ServerApiException;
|
||||||
|
import com.cloud.api.BaseCmd.CommandType;
|
||||||
import com.cloud.api.response.NetscalerLoadBalancerResponse;
|
import com.cloud.api.response.NetscalerLoadBalancerResponse;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
@ -58,6 +61,12 @@ public class ConfigureNetscalerLoadBalancerCmd extends BaseAsyncCmd {
|
|||||||
@Parameter (name=ApiConstants.INLINE, type=CommandType.BOOLEAN, required=false, description="true if netscaler load balancer is intended to be used in in-line with firewall, false if netscaler load balancer will side-by-side with firewall")
|
@Parameter (name=ApiConstants.INLINE, type=CommandType.BOOLEAN, required=false, description="true if netscaler load balancer is intended to be used in in-line with firewall, false if netscaler load balancer will side-by-side with firewall")
|
||||||
private Boolean inline;
|
private Boolean inline;
|
||||||
|
|
||||||
|
@IdentityMapper(entityTableName="host_pod_ref")
|
||||||
|
@Parameter(name=ApiConstants.POD_IDS, type=CommandType.LIST, required=false, description="Used when NetScaler device is provider of EIP service." +
|
||||||
|
" This parameter represents the list of pod's, for which there exists a policy based route on datacenter L3 router to " +
|
||||||
|
"route pod's subnet IP to a NetScaler device.")
|
||||||
|
private List<Long> podIds;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -78,6 +87,10 @@ public class ConfigureNetscalerLoadBalancerCmd extends BaseAsyncCmd {
|
|||||||
return inline;
|
return inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Long> getPodIds() {
|
||||||
|
return podIds;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -328,6 +328,7 @@ public enum Config {
|
|||||||
|
|
||||||
DefaultExternalLoadBalancerCapacity("Advanced", ManagementServer.class, String.class, "external.lb.default.capacity", "50", "default number of networks permitted per external load balancer device", null),
|
DefaultExternalLoadBalancerCapacity("Advanced", ManagementServer.class, String.class, "external.lb.default.capacity", "50", "default number of networks permitted per external load balancer device", null),
|
||||||
DefaultExternalFirewallCapacity("Advanced", ManagementServer.class, String.class, "external.firewall.default.capacity", "50", "default number of networks permitted per external load firewall device", null),
|
DefaultExternalFirewallCapacity("Advanced", ManagementServer.class, String.class, "external.firewall.default.capacity", "50", "default number of networks permitted per external load firewall device", null),
|
||||||
|
EIPWithMultipleNetScalersEnabled("Advanced", ManagementServer.class, Boolean.class, "eip.use.multiple.netscalers", "false", "Should be set to true, if there will be multiple NetScaler devices providing EIP service in a zone", null),
|
||||||
CustomDiskOfferingMinSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.min", "1", "Minimum size in GB for custom disk offering", null),
|
CustomDiskOfferingMinSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.min", "1", "Minimum size in GB for custom disk offering", null),
|
||||||
CustomDiskOfferingMaxSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering", null),
|
CustomDiskOfferingMaxSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering", null),
|
||||||
ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Service offering used by console proxy; if NULL - system offering will be used", null),
|
ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Service offering used by console proxy; if NULL - system offering will be used", null),
|
||||||
|
|||||||
@ -79,6 +79,7 @@ import com.cloud.network.dao.InlineLoadBalancerNicMapDaoImpl;
|
|||||||
import com.cloud.network.dao.LBStickinessPolicyDaoImpl;
|
import com.cloud.network.dao.LBStickinessPolicyDaoImpl;
|
||||||
import com.cloud.network.dao.LoadBalancerDaoImpl;
|
import com.cloud.network.dao.LoadBalancerDaoImpl;
|
||||||
import com.cloud.network.dao.LoadBalancerVMMapDaoImpl;
|
import com.cloud.network.dao.LoadBalancerVMMapDaoImpl;
|
||||||
|
import com.cloud.network.dao.NetScalerPodDaoImpl;
|
||||||
import com.cloud.network.dao.NetworkDaoImpl;
|
import com.cloud.network.dao.NetworkDaoImpl;
|
||||||
import com.cloud.network.dao.NetworkDomainDaoImpl;
|
import com.cloud.network.dao.NetworkDomainDaoImpl;
|
||||||
import com.cloud.network.dao.NetworkExternalFirewallDaoImpl;
|
import com.cloud.network.dao.NetworkExternalFirewallDaoImpl;
|
||||||
@ -315,6 +316,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
|
|||||||
addDao("ExternalFirewallDeviceDao", ExternalFirewallDeviceDaoImpl.class);
|
addDao("ExternalFirewallDeviceDao", ExternalFirewallDeviceDaoImpl.class);
|
||||||
addDao("NetworkExternalLoadBalancerDao", NetworkExternalLoadBalancerDaoImpl.class);
|
addDao("NetworkExternalLoadBalancerDao", NetworkExternalLoadBalancerDaoImpl.class);
|
||||||
addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class);
|
addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class);
|
||||||
|
addDao("NetScalerPodDao", NetScalerPodDaoImpl.class);
|
||||||
addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class);
|
addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class);
|
||||||
addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class);
|
addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class);
|
||||||
addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class);
|
addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class);
|
||||||
|
|||||||
61
server/src/com/cloud/network/NetScalerPodVO.java
Normal file
61
server/src/com/cloud/network/NetScalerPodVO.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||||
|
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||||
|
// file except in compliance with the License. Citrix Systems, Inc.
|
||||||
|
// reserves all rights not expressly granted by the License.
|
||||||
|
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.cloud.network;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NetScalerPodVO contains information about a EIP deployment where on datacenter L3 router a PBR (policy
|
||||||
|
* based routing) is setup between a POD's subnet IP range to a NetScaler device. This VO object
|
||||||
|
* represents a mapping between a POD and NetScaler device where PBR is setup.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name="netscaler_pod_ref")
|
||||||
|
public class NetScalerPodVO {
|
||||||
|
|
||||||
|
@Column(name="external_load_balancer_device_id")
|
||||||
|
private long netscalerDeviceId;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name="id")
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@Column(name="pod_id")
|
||||||
|
private long podId;
|
||||||
|
|
||||||
|
public NetScalerPodVO() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetScalerPodVO(long netscalerDeviceId, long podId) {
|
||||||
|
this.netscalerDeviceId = netscalerDeviceId;
|
||||||
|
this.podId = podId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPodId() {
|
||||||
|
return podId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getNetscalerDeviceId() {
|
||||||
|
return netscalerDeviceId;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
server/src/com/cloud/network/dao/NetScalerPodDao.java
Normal file
24
server/src/com/cloud/network/dao/NetScalerPodDao.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||||
|
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||||
|
// file except in compliance with the License. Citrix Systems, Inc.
|
||||||
|
// reserves all rights not expressly granted by the License.
|
||||||
|
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.cloud.network.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.cloud.network.NetScalerPodVO;
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
|
public interface NetScalerPodDao extends GenericDao<NetScalerPodVO, Long> {
|
||||||
|
|
||||||
|
NetScalerPodVO findByPodId(long podId);
|
||||||
|
|
||||||
|
List<NetScalerPodVO> listByNetScalerDeviceId(long netscalerDeviceId);
|
||||||
|
}
|
||||||
57
server/src/com/cloud/network/dao/NetScalerPodDaoImpl.java
Normal file
57
server/src/com/cloud/network/dao/NetScalerPodDaoImpl.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||||
|
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||||
|
// file except in compliance with the License. Citrix Systems, Inc.
|
||||||
|
// reserves all rights not expressly granted by the License.
|
||||||
|
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.cloud.network.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ejb.Local;
|
||||||
|
|
||||||
|
import com.cloud.network.NetScalerPodVO;
|
||||||
|
import com.cloud.utils.db.DB;
|
||||||
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
|
|
||||||
|
@Local(value=NetScalerPodDao.class) @DB(txn=false)
|
||||||
|
public class NetScalerPodDaoImpl extends GenericDaoBase<NetScalerPodVO, Long> implements NetScalerPodDao {
|
||||||
|
|
||||||
|
final SearchBuilder<NetScalerPodVO> podIdSearch;
|
||||||
|
final SearchBuilder<NetScalerPodVO> deviceIdSearch;
|
||||||
|
|
||||||
|
protected NetScalerPodDaoImpl() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
podIdSearch = createSearchBuilder();
|
||||||
|
podIdSearch.and("pod_id", podIdSearch.entity().getPodId(), Op.EQ);
|
||||||
|
podIdSearch.done();
|
||||||
|
|
||||||
|
deviceIdSearch = createSearchBuilder();
|
||||||
|
deviceIdSearch.and("netscalerDeviceId", deviceIdSearch.entity().getNetscalerDeviceId(), Op.EQ);
|
||||||
|
deviceIdSearch.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetScalerPodVO findByPodId(long podId) {
|
||||||
|
SearchCriteria<NetScalerPodVO> sc = podIdSearch.create();
|
||||||
|
sc.setParameters("pod_id", podId);
|
||||||
|
return findOneBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NetScalerPodVO> listByNetScalerDeviceId(long netscalerDeviceId) {
|
||||||
|
SearchCriteria<NetScalerPodVO> sc = deviceIdSearch.create();
|
||||||
|
sc.setParameters("netscalerDeviceId", netscalerDeviceId);
|
||||||
|
return search(sc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -41,8 +41,11 @@ import com.cloud.configuration.Config;
|
|||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.configuration.dao.ConfigurationDao;
|
import com.cloud.configuration.dao.ConfigurationDao;
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
|
import com.cloud.dc.DataCenterIpAddressVO;
|
||||||
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.dc.DataCenter.NetworkType;
|
import com.cloud.dc.DataCenter.NetworkType;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
|
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
||||||
import com.cloud.deploy.DeployDestination;
|
import com.cloud.deploy.DeployDestination;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
@ -59,6 +62,7 @@ import com.cloud.network.ExternalLoadBalancerDeviceVO;
|
|||||||
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState;
|
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState;
|
||||||
import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice;
|
import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice;
|
||||||
import com.cloud.network.IpAddress;
|
import com.cloud.network.IpAddress;
|
||||||
|
import com.cloud.network.NetScalerPodVO;
|
||||||
import com.cloud.network.Network;
|
import com.cloud.network.Network;
|
||||||
import com.cloud.network.Network.Capability;
|
import com.cloud.network.Network.Capability;
|
||||||
import com.cloud.network.Network.Provider;
|
import com.cloud.network.Network.Provider;
|
||||||
@ -71,6 +75,7 @@ import com.cloud.network.PhysicalNetworkServiceProvider;
|
|||||||
import com.cloud.network.PhysicalNetworkVO;
|
import com.cloud.network.PhysicalNetworkVO;
|
||||||
import com.cloud.network.PublicIpAddress;
|
import com.cloud.network.PublicIpAddress;
|
||||||
import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
|
import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
|
||||||
|
import com.cloud.network.dao.NetScalerPodDao;
|
||||||
import com.cloud.network.dao.NetworkDao;
|
import com.cloud.network.dao.NetworkDao;
|
||||||
import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
|
import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
|
||||||
import com.cloud.network.dao.NetworkServiceMapDao;
|
import com.cloud.network.dao.NetworkServiceMapDao;
|
||||||
@ -129,6 +134,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
HostDetailsDao _detailsDao;
|
HostDetailsDao _detailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
ConfigurationDao _configDao;
|
ConfigurationDao _configDao;
|
||||||
|
@Inject
|
||||||
|
NetScalerPodDao _netscalerPodDao;
|
||||||
|
@Inject
|
||||||
|
DataCenterIpAddressDao _privateIpAddressDao;
|
||||||
|
|
||||||
private boolean canHandle(Network config, Service service) {
|
private boolean canHandle(Network config, Service service) {
|
||||||
DataCenter zone = _dcDao.findById(config.getDataCenterId());
|
DataCenter zone = _dcDao.findById(config.getDataCenterId());
|
||||||
@ -324,16 +333,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
Boolean dedicatedUse = cmd.getLoadBalancerDedicated();
|
Boolean dedicatedUse = cmd.getLoadBalancerDedicated();
|
||||||
Boolean inline = cmd.getLoadBalancerInline();
|
Boolean inline = cmd.getLoadBalancerInline();
|
||||||
Long capacity = cmd.getLoadBalancerCapacity();
|
Long capacity = cmd.getLoadBalancerCapacity();
|
||||||
|
List<Long> podIds = cmd.getPodIds();
|
||||||
try {
|
try {
|
||||||
return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse);
|
return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse, podIds);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage());
|
throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean inline, Boolean dedicatedUse) {
|
private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean inline, Boolean dedicatedUse, List<Long> newPodsConfig) {
|
||||||
ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
|
ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
|
||||||
Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId());
|
Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId());
|
||||||
|
|
||||||
@ -341,6 +350,37 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
|
throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Long> currentPodsConfig = new ArrayList<Long>();
|
||||||
|
List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVo.getId());
|
||||||
|
if (currentPodVOs != null && currentPodVOs.size() > 0) {
|
||||||
|
for (NetScalerPodVO nsPodVo: currentPodVOs) {
|
||||||
|
currentPodsConfig.add(nsPodVo.getPodId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> podsToAssociate = new ArrayList<Long>();
|
||||||
|
if (newPodsConfig != null && newPodsConfig.size() > 0) {
|
||||||
|
for (Long podId: newPodsConfig) {
|
||||||
|
HostPodVO pod = _podDao.findById(podId);
|
||||||
|
if (pod == null) {
|
||||||
|
throw new InvalidParameterValueException("Can't find pod by id " + podId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Long podId: newPodsConfig) {
|
||||||
|
if (!currentPodsConfig.contains(podId)) {
|
||||||
|
podsToAssociate.add(podId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> podsToDeassociate = new ArrayList<Long>();
|
||||||
|
for (Long podId: currentPodsConfig) {
|
||||||
|
if (!newPodsConfig.contains(podId)) {
|
||||||
|
podsToDeassociate.add(podId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String deviceName = lbDeviceVo.getDeviceName();
|
String deviceName = lbDeviceVo.getDeviceName();
|
||||||
if (dedicatedUse != null || capacity != null || inline != null) {
|
if (dedicatedUse != null || capacity != null || inline != null) {
|
||||||
if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) ||
|
if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) ||
|
||||||
@ -395,6 +435,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
|
|
||||||
_lbDeviceDao.update(lbDeviceId, lbDeviceVo);
|
_lbDeviceDao.update(lbDeviceId, lbDeviceVo);
|
||||||
|
|
||||||
|
for (Long podId: podsToAssociate) {
|
||||||
|
NetScalerPodVO nsPodVo = new NetScalerPodVO(lbDeviceId, podId);
|
||||||
|
_netscalerPodDao.persist(nsPodVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Long podId: podsToDeassociate) {
|
||||||
|
NetScalerPodVO nsPodVo = _netscalerPodDao.findByPodId(podId);
|
||||||
|
_netscalerPodDao.remove(nsPodVo.getId());
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME get the row lock to avoid race condition
|
// FIXME get the row lock to avoid race condition
|
||||||
_detailsDao.persist(lbDeviceVo.getHostId(), lbDetails);
|
_detailsDao.persist(lbDeviceVo.getHostId(), lbDetails);
|
||||||
HostVO host = _hostDao.findById(lbDeviceVo.getHostId());
|
HostVO host = _hostDao.findById(lbDeviceVo.getHostId());
|
||||||
@ -485,6 +535,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
response.setProvider(lbDeviceVO.getProviderName());
|
response.setProvider(lbDeviceVO.getProviderName());
|
||||||
response.setDeviceState(lbDeviceVO.getState().name());
|
response.setDeviceState(lbDeviceVO.getState().name());
|
||||||
response.setObjectName("netscalerloadbalancer");
|
response.setObjectName("netscalerloadbalancer");
|
||||||
|
|
||||||
|
List<Long> associatedPods = new ArrayList<Long>();
|
||||||
|
List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVO.getId());
|
||||||
|
if (currentPodVOs != null && currentPodVOs.size() > 0) {
|
||||||
|
for (NetScalerPodVO nsPodVo: currentPodVOs) {
|
||||||
|
associatedPods.add(nsPodVo.getPodId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response.setAssociatedPods(associatedPods);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,47 +689,96 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String errMsg;
|
boolean multiNetScalerDeployment = Boolean.valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key()));
|
||||||
ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config);
|
|
||||||
if (lbDevice == null) {
|
|
||||||
try {
|
|
||||||
lbDevice = allocateLoadBalancerForNetwork(config);
|
|
||||||
} catch (Exception e) {
|
|
||||||
errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage();
|
|
||||||
s_logger.error(errMsg);
|
|
||||||
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNetscalerDevice(lbDevice.getDeviceName())) {
|
|
||||||
errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules.";
|
|
||||||
s_logger.error(errMsg);
|
|
||||||
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetStaticNatRulesAnswer answer = null;
|
|
||||||
try {
|
try {
|
||||||
List<StaticNatRuleTO> rulesTO = null;
|
if (!multiNetScalerDeployment) {
|
||||||
if (rules != null) {
|
String errMsg;
|
||||||
rulesTO = new ArrayList<StaticNatRuleTO>();
|
ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config);
|
||||||
for (StaticNat rule : rules) {
|
if (lbDevice == null) {
|
||||||
IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
|
try {
|
||||||
StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
|
lbDevice = allocateLoadBalancerForNetwork(config);
|
||||||
rulesTO.add(ruleTO);
|
} catch (Exception e) {
|
||||||
|
errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage();
|
||||||
|
s_logger.error(errMsg);
|
||||||
|
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNetscalerDevice(lbDevice.getDeviceName())) {
|
||||||
|
errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules.";
|
||||||
|
s_logger.error(errMsg);
|
||||||
|
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
||||||
|
}
|
||||||
|
SetStaticNatRulesAnswer answer = null;
|
||||||
|
List<StaticNatRuleTO> rulesTO = null;
|
||||||
|
if (rules != null) {
|
||||||
|
rulesTO = new ArrayList<StaticNatRuleTO>();
|
||||||
|
for (StaticNat rule : rules) {
|
||||||
|
IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
|
||||||
|
StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
|
||||||
|
rulesTO.add(ruleTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO);
|
||||||
|
answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd);
|
||||||
|
if (answer == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return answer.getResult();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rules != null) {
|
||||||
|
for (StaticNat rule : rules) {
|
||||||
|
// validate if EIP rule can be configured.
|
||||||
|
ExternalLoadBalancerDeviceVO lbDevice = getNetScalerForEIP(rule);
|
||||||
|
if (lbDevice == null) {
|
||||||
|
String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: " + rule.getDestIpAddress();
|
||||||
|
s_logger.error(errMsg);
|
||||||
|
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
|
||||||
|
IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
|
||||||
|
StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
|
||||||
|
rulesTO.add(ruleTO);
|
||||||
|
SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO);
|
||||||
|
|
||||||
|
// send commands to configure INAT rule on the NetScaler device
|
||||||
|
SetStaticNatRulesAnswer answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd);
|
||||||
|
if (answer == null) {
|
||||||
|
String errMsg = "Failed to configure INAT rule on NetScaler device " + lbDevice.getHostId();
|
||||||
|
s_logger.error(errMsg);
|
||||||
|
throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO);
|
|
||||||
answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd);
|
|
||||||
if (answer == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return answer.getResult();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage());
|
s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns configured NetScaler device that is associated with the pod that owns guest IP
|
||||||
|
private ExternalLoadBalancerDeviceVO getNetScalerForEIP(StaticNat rule) {
|
||||||
|
String guestIP = rule.getDestIpAddress();
|
||||||
|
List <DataCenterIpAddressVO> dcGuestIps = _privateIpAddressDao.listAll();
|
||||||
|
if (dcGuestIps != null) {
|
||||||
|
for (DataCenterIpAddressVO dcGuestIp: dcGuestIps) {
|
||||||
|
if (dcGuestIp.getIpAddress().equalsIgnoreCase(guestIP)) {
|
||||||
|
long podId = dcGuestIp.getPodId();
|
||||||
|
NetScalerPodVO nsPodVO = _netscalerPodDao.findByPodId(podId);
|
||||||
|
if (nsPodVO != null) {
|
||||||
|
ExternalLoadBalancerDeviceVO lbDeviceVO = _lbDeviceDao.findById(nsPodVO.getNetscalerDeviceId());
|
||||||
|
return lbDeviceVO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2079,4 +2079,13 @@ CREATE TABLE `cloud`.`op_user_stats_log` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE `cloud`.`netscaler_pod_ref` (
|
||||||
|
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
|
||||||
|
`external_load_balancer_device_id` bigint unsigned NOT NULL COMMENT 'id of external load balancer device',
|
||||||
|
`pod_id` bigint unsigned NOT NULL COMMENT 'pod id',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
CONSTRAINT `fk_ns_pod_ref__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT `fk_ns_pod_ref__device_id` FOREIGN KEY (`external_load_balancer_device_id`) REFERENCES `external_load_balancer_devices`(`id`) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
SET foreign_key_checks = 1;
|
SET foreign_key_checks = 1;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user