diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 7607f7d56e0..fa6fa4e3c6a 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -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"; diff --git a/api/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java b/api/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java index e9884ad10a3..f0045ab2d52 100644 --- a/api/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java +++ b/api/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java @@ -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 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 pods) { + this.podIds = pods; + } } diff --git a/server/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java b/server/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java index 5d3b407815a..9044079a66a 100644 --- a/server/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java +++ b/server/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java @@ -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 podIds; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -78,6 +87,10 @@ public class ConfigureNetscalerLoadBalancerCmd extends BaseAsyncCmd { return inline; } + public List getPodIds() { + return podIds; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index f69ffccb5bb..f39074e4723 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -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), diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 0fb9bca17fb..3794c713fc3 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -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); diff --git a/server/src/com/cloud/network/NetScalerPodVO.java b/server/src/com/cloud/network/NetScalerPodVO.java new file mode 100644 index 00000000000..9325c1400a9 --- /dev/null +++ b/server/src/com/cloud/network/NetScalerPodVO.java @@ -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; + } +} diff --git a/server/src/com/cloud/network/dao/NetScalerPodDao.java b/server/src/com/cloud/network/dao/NetScalerPodDao.java new file mode 100644 index 00000000000..4a458617ef6 --- /dev/null +++ b/server/src/com/cloud/network/dao/NetScalerPodDao.java @@ -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 findByPodId(long podId); + + List listByNetScalerDeviceId(long netscalerDeviceId); +} \ No newline at end of file diff --git a/server/src/com/cloud/network/dao/NetScalerPodDaoImpl.java b/server/src/com/cloud/network/dao/NetScalerPodDaoImpl.java new file mode 100644 index 00000000000..f4df3130d12 --- /dev/null +++ b/server/src/com/cloud/network/dao/NetScalerPodDaoImpl.java @@ -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 implements NetScalerPodDao { + + final SearchBuilder podIdSearch; + final SearchBuilder 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 sc = podIdSearch.create(); + sc.setParameters("pod_id", podId); + return findOneBy(sc); + } + + @Override + public List listByNetScalerDeviceId(long netscalerDeviceId) { + SearchCriteria sc = deviceIdSearch.create(); + sc.setParameters("netscalerDeviceId", netscalerDeviceId); + return search(sc, null); + } + +} diff --git a/server/src/com/cloud/network/element/NetscalerElement.java b/server/src/com/cloud/network/element/NetscalerElement.java index 81d5424d4ab..7fcb6d07682 100644 --- a/server/src/com/cloud/network/element/NetscalerElement.java +++ b/server/src/com/cloud/network/element/NetscalerElement.java @@ -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 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 newPodsConfig) { ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); Map 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 currentPodsConfig = new ArrayList(); + List currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVo.getId()); + if (currentPodVOs != null && currentPodVOs.size() > 0) { + for (NetScalerPodVO nsPodVo: currentPodVOs) { + currentPodsConfig.add(nsPodVo.getPodId()); + } + } + + List podsToAssociate = new ArrayList(); + 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 podsToDeassociate = new ArrayList(); + 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 associatedPods = new ArrayList(); + List 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 rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - 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 rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + 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 rulesTO = new ArrayList(); + 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 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; + } } \ No newline at end of file diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 397bd655235..94cfafe7e6b 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -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;