mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 10:32:34 +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 PATH = "path";
|
||||
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 PORT = "port";
|
||||
public static final String PORTAL = "portal";
|
||||
|
||||
@ -12,11 +12,16 @@
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.api.response;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.utils.IdentityProxy;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class NetscalerLoadBalancerResponse extends BaseResponse {
|
||||
|
||||
@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")
|
||||
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) {
|
||||
this.id.setValue(lbDeviceId);
|
||||
}
|
||||
@ -95,4 +105,8 @@ public class NetscalerLoadBalancerResponse extends BaseResponse {
|
||||
public void setIpAddress(String 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
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
@ -22,6 +24,7 @@ import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.PlugService;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.NetscalerLoadBalancerResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
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")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -78,6 +87,10 @@ public class ConfigureNetscalerLoadBalancerCmd extends BaseAsyncCmd {
|
||||
return inline;
|
||||
}
|
||||
|
||||
public List<Long> getPodIds() {
|
||||
return podIds;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// 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),
|
||||
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),
|
||||
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),
|
||||
|
||||
@ -79,6 +79,7 @@ import com.cloud.network.dao.InlineLoadBalancerNicMapDaoImpl;
|
||||
import com.cloud.network.dao.LBStickinessPolicyDaoImpl;
|
||||
import com.cloud.network.dao.LoadBalancerDaoImpl;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapDaoImpl;
|
||||
import com.cloud.network.dao.NetScalerPodDaoImpl;
|
||||
import com.cloud.network.dao.NetworkDaoImpl;
|
||||
import com.cloud.network.dao.NetworkDomainDaoImpl;
|
||||
import com.cloud.network.dao.NetworkExternalFirewallDaoImpl;
|
||||
@ -315,6 +316,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
|
||||
addDao("ExternalFirewallDeviceDao", ExternalFirewallDeviceDaoImpl.class);
|
||||
addDao("NetworkExternalLoadBalancerDao", NetworkExternalLoadBalancerDaoImpl.class);
|
||||
addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class);
|
||||
addDao("NetScalerPodDao", NetScalerPodDaoImpl.class);
|
||||
addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class);
|
||||
addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.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.dao.ConfigurationDao;
|
||||
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.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
@ -59,6 +62,7 @@ import com.cloud.network.ExternalLoadBalancerDeviceVO;
|
||||
import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState;
|
||||
import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.NetScalerPodVO;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
@ -71,6 +75,7 @@ import com.cloud.network.PhysicalNetworkServiceProvider;
|
||||
import com.cloud.network.PhysicalNetworkVO;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
|
||||
import com.cloud.network.dao.NetScalerPodDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
|
||||
import com.cloud.network.dao.NetworkServiceMapDao;
|
||||
@ -129,7 +134,11 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
HostDetailsDao _detailsDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
|
||||
@Inject
|
||||
NetScalerPodDao _netscalerPodDao;
|
||||
@Inject
|
||||
DataCenterIpAddressDao _privateIpAddressDao;
|
||||
|
||||
private boolean canHandle(Network config, Service service) {
|
||||
DataCenter zone = _dcDao.findById(config.getDataCenterId());
|
||||
boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced && config.getGuestType() == Network.GuestType.Isolated && config.getTrafficType() == TrafficType.Guest);
|
||||
@ -324,16 +333,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
Boolean dedicatedUse = cmd.getLoadBalancerDedicated();
|
||||
Boolean inline = cmd.getLoadBalancerInline();
|
||||
Long capacity = cmd.getLoadBalancerCapacity();
|
||||
|
||||
List<Long> podIds = cmd.getPodIds();
|
||||
try {
|
||||
return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse);
|
||||
return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse, podIds);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
if (dedicatedUse != null || capacity != null || inline != null) {
|
||||
if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) ||
|
||||
@ -395,6 +435,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
|
||||
_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
|
||||
_detailsDao.persist(lbDeviceVo.getHostId(), lbDetails);
|
||||
HostVO host = _hostDao.findById(lbDeviceVo.getHostId());
|
||||
@ -485,6 +535,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
response.setProvider(lbDeviceVO.getProviderName());
|
||||
response.setDeviceState(lbDeviceVO.getState().name());
|
||||
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;
|
||||
}
|
||||
|
||||
@ -630,47 +689,96 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
|
||||
return false;
|
||||
}
|
||||
|
||||
String errMsg;
|
||||
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);
|
||||
}
|
||||
}
|
||||
boolean multiNetScalerDeployment = Boolean.valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key()));
|
||||
|
||||
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 {
|
||||
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);
|
||||
if (!multiNetScalerDeployment) {
|
||||
String errMsg;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO);
|
||||
answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd);
|
||||
if (answer == null) {
|
||||
return false;
|
||||
} else {
|
||||
return answer.getResult();
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage());
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user