diff --git a/.project b/.project
deleted file mode 100644
index 183860bd142..00000000000
--- a/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
- mgit
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
-
- src
- 2
- /Users/john1/mgit/cloudbridge/src
-
-
-
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index 7b0f264f46b..eda69df3ed6 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -1,4 +1,5 @@
#new labels (begin) **********************************************************************************************
+label.network.rate.megabytes=Network Rate (MB/s)
label.action.enable.physical.network=Enable physical network
label.action.disable.physical.network=Disable physical network
message.action.enable.physical.network=Please confirm that you want to enable this physical network.
diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
index 9c0d189046f..19f87c23e04 100755
--- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config
+++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
@@ -696,11 +696,8 @@ setup_elbvm() {
setup_default() {
cat > /etc/network/interfaces << EOF
-auto lo eth0
+auto lo
iface lo inet loopback
-
-iface eth0 inet static
-
EOF
}
@@ -895,7 +892,9 @@ start)
;;
stop)
- log_action_begin_msg "Stopping cloud-early-config (noop)"
+ log_action_begin_msg "Stopping cloud-early-config"
+ #Override old system's interface setting
+ setup_default;
log_action_end_msg 0
;;
diff --git a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ
index 8be4265efb9..32604954990 100644
--- a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ
+++ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ
@@ -5,8 +5,8 @@ set -e
ip link|grep BROADCAST|grep -v eth0|grep -v eth1|cut -d ":" -f 2 > /tmp/iflist
while read i
do
- ifconfig $i down
- ifconfig $i up
+ ifdown $i
+ ifup $i
done < /tmp/iflist
ip route add default via [GATEWAY] dev eth2 && \
service dnsmasq restart
diff --git a/server/src/com/cloud/cluster/ClusterManagerImpl.java b/server/src/com/cloud/cluster/ClusterManagerImpl.java
index 56e9bccf9f4..4c7d4f28c1e 100755
--- a/server/src/com/cloud/cluster/ClusterManagerImpl.java
+++ b/server/src/com/cloud/cluster/ClusterManagerImpl.java
@@ -399,6 +399,23 @@ public class ClusterManagerImpl implements ClusterManager {
s_logger.warn("Operation timed out", e);
return null;
}
+ Answer[] answers = new Answer[1];
+ answers[0] = new Answer(cmd, result, null);
+ return _gson.toJson(answers);
+ } else if (cmds.length == 1 && cmds[0] instanceof PropagateResourceEventCommand) {
+ PropagateResourceEventCommand cmd = (PropagateResourceEventCommand) cmds[0];
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Intercepting resource manager command: " + _gson.toJson(cmd));
+ }
+
+ boolean result = false;
+ try {
+ result = _resourceMgr.executeUserRequest(cmd.getHostId(), cmd.getEvent());
+ } catch (Exception e) {
+ s_logger.warn("Exception happened while exceuting command from resource manager in other mgmt server", e);
+ return null;
+ }
+
Answer[] answers = new Answer[1];
answers[0] = new Answer(cmd, result, null);
return _gson.toJson(answers);
diff --git a/server/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java b/server/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
index 67c50b609be..9951188036b 100755
--- a/server/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
+++ b/server/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
@@ -76,6 +76,7 @@ public class ClusterBasedAgentLoadBalancerPlanner implements AgentLoadBalancerPl
}
sc = SearchCriteria2.create(HostVO.class);
+ sc.addAnd(sc.getEntity().getResource(), Op.NNULL);
sc.addAnd(sc.getEntity().getManagementServerId(), Op.EQ, msId);
sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up);
List directHosts = sc.list();
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index c85b3c7ca31..d044d4f3525 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -1936,19 +1936,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
result = false;
}
if (result == false) {
- return false;
+ return result;
}
answer = cmds.getAnswer("getDomRVersion");
if (answer != null && answer instanceof GetDomRVersionAnswer) {
GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer;
if (answer == null || !answer.getResult()) {
- /* Try to push on because it's not a critical error */
- s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + " due to: " + versionAnswer.getDetails() + ", but we would continue");
+ s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + " due to: " + versionAnswer.getDetails());
+ result = false;
} else {
router.setTemplateVersion(versionAnswer.getTemplateVersion());
router.setScriptsVersion(versionAnswer.getScriptsVersion());
router = _routerDao.persist(router);
}
+ } else {
+ result = false;
}
return result;
diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java b/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java
index 14fab7dd83b..9a478d20088 100755
--- a/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java
+++ b/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java
@@ -22,6 +22,7 @@ import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import org.apache.log4j.Logger;
@@ -29,7 +30,6 @@ import org.apache.log4j.Logger;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
-
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
@@ -82,8 +82,10 @@ public class Upgrade2214to30 implements DbUpgrade {
updateReduntantRouters(conn);
// update networks that have to switch from Shared to Isolated network offerings
switchAccountSpecificNetworksToIsolated(conn);
+ // update networks to external network offerings if needed
+ String externalOfferingName = fixNetworksWithExternalDevices(conn);
// create service/provider map for network offerings
- createNetworkOfferingServices(conn);
+ createNetworkOfferingServices(conn, externalOfferingName);
// create service/provider map for networks
createNetworkServices(conn);
//migrate user concentrated deployment planner choice to new global setting
@@ -854,67 +856,97 @@ public class Upgrade2214to30 implements DbUpgrade {
}
}
- private void createNetworkOfferingServices(Connection conn) {
+ private void createNetworkOfferingServices(Connection conn, String externalOfferingName) {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn
- .prepareStatement("select id, dns_service, gateway_service, firewall_service, lb_service, userdata_service, vpn_service, dhcp_service, unique_name from `cloud`.`network_offerings` where traffic_type='Guest'");
+ .prepareStatement("select id, dns_service, gateway_service, firewall_service, lb_service, userdata_service," +
+ " vpn_service, dhcp_service, unique_name from `cloud`.`network_offerings` where traffic_type='Guest'");
rs = pstmt.executeQuery();
while (rs.next()) {
+ boolean sharedSourceNat = false;
+ boolean dedicatedLb = true;
long id = rs.getLong(1);
String uniqueName = rs.getString(9);
- ArrayList services = new ArrayList();
+ Map services = new HashMap();
if (rs.getLong(2) != 0) {
- services.add("Dns");
+ services.put("Dns", "VirtualRouter");
}
if (rs.getLong(3) != 0) {
- services.add("Gateway");
+ if (externalOfferingName != null && uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ services.put("Gateway", "JuniperSRX");
+ } else {
+ services.put("Gateway", "VirtualRouter");
+ }
}
if (rs.getLong(4) != 0) {
- services.add("Firewall");
+ if (externalOfferingName != null && uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ services.put("Firewall", "JuniperSRX");
+ } else {
+ services.put("Firewall", "VirtualRouter");
+ }
}
if (rs.getLong(5) != 0) {
- services.add("Lb");
+ if (externalOfferingName != null && uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ services.put("Lb", "F5BigIp");
+ dedicatedLb = false;
+ } else {
+ services.put("Lb", "VirtualRouter");
+ }
}
if (rs.getLong(6) != 0) {
- services.add("UserData");
+ services.put("UserData", "VirtualRouter");
}
if (rs.getLong(7) != 0) {
- services.add("Vpn");
+ if (externalOfferingName == null || !uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ services.put("Vpn", "VirtualRouter");
+ }
}
if (rs.getLong(8) != 0) {
- services.add("Dhcp");
+ services.put("Dhcp", "VirtualRouter");
}
if (uniqueName.equalsIgnoreCase(NetworkOffering.DefaultSharedNetworkOfferingWithSGService.toString())) {
- services.add("SecurityGroup");
+ services.put("SecurityGroup", "SecurityGroupProvider");
}
- if (uniqueName.equals(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService.toString())) {
- services.add("SourceNat");
- services.add("PortForwarding");
- services.add("StaticNat");
+ if (uniqueName.equals(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService.toString()) || uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ if (externalOfferingName != null && uniqueName.equalsIgnoreCase(externalOfferingName)) {
+ services.put("SourceNat", "JuniperSRX");
+ services.put("PortForwarding", "JuniperSRX");
+ services.put("StaticNat", "JuniperSRX");
+ sharedSourceNat = true;
+ } else {
+ services.put("SourceNat", "VirtualRouter");
+ services.put("PortForwarding", "VirtualRouter");
+ services.put("StaticNat", "VirtualRouter");
+ }
}
- for (String service : services) {
- pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ntwk_offering_service_map` (`network_offering_id`, `service`, `provider`, `created`) values (?,?,?, now())");
+ for (String service : services.keySet()) {
+ pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ntwk_offering_service_map` (`network_offering_id`," +
+ " `service`, `provider`, `created`) values (?,?,?, now())");
pstmt.setLong(1, id);
pstmt.setString(2, service);
- if (service.equalsIgnoreCase("SecurityGroup")) {
- pstmt.setString(3, "SecurityGroupProvider");
- } else {
- pstmt.setString(3, "VirtualRouter");
- }
+ pstmt.setString(3, services.get(service));
pstmt.executeUpdate();
}
+
+ //update shared source nat and dedicated lb
+ pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings` set shared_source_nat_service=?, dedicated_lb_service=? where id=?");
+ pstmt.setBoolean(1, sharedSourceNat);
+ pstmt.setBoolean(2, dedicatedLb);
+ pstmt.setLong(3, id);
+ pstmt.executeUpdate();
+
}
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to create service/provider map for network offerings", e);
@@ -1175,7 +1207,7 @@ public class Upgrade2214to30 implements DbUpgrade {
return ;
}
- // get all networks that need to be updated to the redundant network offerings
+ // get all networks that need to be updated to the isolated network offering
pstmt = conn
.prepareStatement("select id, network_offering_id from `cloud`.`networks` where switch_to_isolated=1");
rs = pstmt.executeQuery();
@@ -1310,4 +1342,107 @@ public class Upgrade2214to30 implements DbUpgrade {
}
}
}
+
+ protected String fixNetworksWithExternalDevices(Connection conn) {
+ PreparedStatement pstmt = null;
+ ResultSet rs = null;
+ ResultSet rs1 = null;
+
+ //Get zones to upgrade
+ List zoneIds = new ArrayList();
+ try {
+ pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where lb_provider='F5BigIp' or firewall_provider='JuniperSRX' or gateway_provider='JuniperSRX'");
+ rs = pstmt.executeQuery();
+ while (rs.next()) {
+ zoneIds.add(rs.getLong(1));
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable to switch networks to the new network offering", e);
+ }
+
+
+ String uniqueName = null;
+ HashMap newNetworkOfferingMap = new HashMap();
+
+ for (Long zoneId : zoneIds) {
+ try {
+ // Find the correct network offering
+ pstmt = conn
+ .prepareStatement("select id, network_offering_id from `cloud`.`networks` where guest_type='Virtual' and data_center_id=?");
+ pstmt.setLong(1, zoneId);
+ rs = pstmt.executeQuery();
+ pstmt = conn.prepareStatement("select count(*) from `cloud`.`network_offerings`");
+ rs1 = pstmt.executeQuery();
+ long ntwkOffCount = 0;
+ while (rs1.next()) {
+ ntwkOffCount = rs1.getLong(1);
+ }
+
+ pstmt = conn.prepareStatement("CREATE TEMPORARY TABLE `cloud`.`network_offerings2` ENGINE=MEMORY SELECT * FROM `cloud`.`network_offerings` WHERE id=1");
+ pstmt.executeUpdate();
+
+
+ while (rs.next()) {
+ long networkId = rs.getLong(1);
+ long networkOfferingId = rs.getLong(2);
+ s_logger.debug("Updating network offering for the network id=" + networkId + " as it has switch_to_isolated=1");
+ Long newNetworkOfferingId = null;
+ if (!newNetworkOfferingMap.containsKey(networkOfferingId)) {
+ uniqueName = "Isolated with external providers";
+ // clone the record to
+ pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings2` SELECT * FROM `cloud`.`network_offerings` WHERE id=?");
+ pstmt.setLong(1, networkOfferingId);
+ pstmt.executeUpdate();
+
+ //set the new unique name
+ pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings2` SET id=?, unique_name=?, name=? WHERE id=?");
+ ntwkOffCount = ntwkOffCount + 1;
+ newNetworkOfferingId = ntwkOffCount;
+ pstmt.setLong(1, newNetworkOfferingId);
+ pstmt.setString(2, uniqueName);
+ pstmt.setString(3, uniqueName);
+ pstmt.setLong(4, networkOfferingId);
+ pstmt.executeUpdate();
+
+ pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings` SELECT * from " +
+ "`cloud`.`network_offerings2` WHERE id=" + newNetworkOfferingId);
+ pstmt.executeUpdate();
+
+ pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
+ pstmt.setLong(1, newNetworkOfferingId);
+ pstmt.setLong(2, networkId);
+ pstmt.executeUpdate();
+
+ newNetworkOfferingMap.put(networkOfferingId, ntwkOffCount);
+ } else {
+ pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
+ newNetworkOfferingId = newNetworkOfferingMap.get(networkOfferingId);
+ pstmt.setLong(1, newNetworkOfferingId);
+ pstmt.setLong(2, networkId);
+ pstmt.executeUpdate();
+ }
+
+ s_logger.debug("Successfully updated network id=" + networkId + " with new network offering id " + newNetworkOfferingId);
+ }
+
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable to switch networks to the new network offering", e);
+ } finally {
+ try {
+ pstmt = conn.prepareStatement("DROP TABLE `cloud`.`network_offerings2`");
+ pstmt.executeUpdate();
+ if (rs != null) {
+ rs.close();
+ }
+
+ if (pstmt != null) {
+ pstmt.close();
+ }
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ return uniqueName;
+ }
}
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index d2f01b109d6..b2b4ce04ccc 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -768,14 +768,6 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
}
- @Override
- public IpAddress allocateIP(long networkId, Account ipOwner,
- boolean isSystem) throws ResourceAllocationException,
- InsufficientAddressCapacityException, ConcurrentOperationException {
- // TODO Auto-generated method stub
- return null;
- }
-
@Override
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner,
VlanType type, Long networkId, String requestedIp, boolean isSystem)
@@ -880,4 +872,13 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
// TODO Auto-generated method stub
return null;
}
+
+ /* (non-Javadoc)
+ * @see com.cloud.network.NetworkService#allocateIP(long, com.cloud.user.Account)
+ */
+ @Override
+ public IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/server/test/com/cloud/upgrade/AdvanceZone223To224UpgradeTest.java b/server/test/com/cloud/upgrade/AdvanceZone223To224UpgradeTest.java
index 5ddb19079c4..ce47449ef0f 100644
--- a/server/test/com/cloud/upgrade/AdvanceZone223To224UpgradeTest.java
+++ b/server/test/com/cloud/upgrade/AdvanceZone223To224UpgradeTest.java
@@ -40,8 +40,8 @@ public class AdvanceZone223To224UpgradeTest extends TestCase {
}
public void test217to22Upgrade() throws SQLException {
- s_logger.debug("Finding sample data from 2.2.8");
-// DbTestUtils.executeScript("PreviousDatabaseSchema/2.2.8/dave-sample.sql", false, true);
+ s_logger.debug("Finding sample data from 2.2.14");
+// DbTestUtils.executeScript("PreviousDatabaseSchema/2.2.14/dave-sample.sql", false, true);
Connection conn;
PreparedStatement pstmt;
@@ -50,9 +50,9 @@ public class AdvanceZone223To224UpgradeTest extends TestCase {
DatabaseUpgradeChecker checker = ComponentLocator.inject(DatabaseUpgradeChecker.class);
String version = dao.getCurrentVersion();
- assert version.equals("2.2.8") : "Version returned is not 2.2.8 but " + version;
+ assert version.equals("2.2.14") : "Version returned is not 2.2.14 but " + version;
- checker.upgrade("2.2.8", "2.2.12");
+ checker.upgrade("2.2.14", "3.0.3");
}
}
diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
index ea4950ba2b0..5a65a6d13f9 100755
--- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
@@ -217,4 +217,22 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager {
return null;
}
+ /* (non-Javadoc)
+ * @see com.cloud.vm.VirtualMachineManager#checkIfCanUpgrade(com.cloud.vm.VirtualMachine, long)
+ */
+ @Override
+ public void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.cloud.vm.VirtualMachineManager#upgradeVmDb(long, long)
+ */
+ @Override
+ public boolean upgradeVmDb(long vmId, long serviceOfferingId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
}
diff --git a/setup/db/db/schema-302to303.sql b/setup/db/db/schema-302to303.sql
index ffb0d96da7b..30f53b2fb1e 100755
--- a/setup/db/db/schema-302to303.sql
+++ b/setup/db/db/schema-302to303.sql
@@ -168,3 +168,5 @@ CREATE TABLE `cloud`.`port_profile` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELETE FROM `cloud`.`storage_pool_host_ref` WHERE pool_id IN (SELECT id FROM storage_pool WHERE removed IS NOT NULL);
+
+ALTER TABLE `cloud`.`service_offering` MODIFY `nw_rate` smallint(5) unsigned DEFAULT '200' COMMENT 'network rate throttle mbits/s';
diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py
index c8a7a234bc4..19f6914229f 100644
--- a/test/integration/component/test_accounts.py
+++ b/test/integration/component/test_accounts.py
@@ -19,7 +19,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py
index 5da10b70b75..4155a41aa13 100644
--- a/test/integration/component/test_blocker_bugs.py
+++ b/test/integration/component/test_blocker_bugs.py
@@ -21,7 +21,7 @@ from integration.lib.common import *
#Import Local Modules
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
class Services:
"""Test Services
diff --git a/test/integration/component/test_egress_rules.py b/test/integration/component/test_egress_rules.py
index 751a595bd77..aa301dad3cb 100644
--- a/test/integration/component/test_egress_rules.py
+++ b/test/integration/component/test_egress_rules.py
@@ -18,7 +18,7 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
diff --git a/test/integration/component/test_high_availability.py b/test/integration/component/test_high_availability.py
index 9d1ac019f4f..10281615cc3 100644
--- a/test/integration/component/test_high_availability.py
+++ b/test/integration/component/test_high_availability.py
@@ -21,7 +21,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
@@ -168,7 +168,7 @@ class TestHighAvailability(cloudstackTestCase):
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
- @unittest.skip("skipped")
+
def test_01_host_maintenance_mode(self):
"""Test host maintenance mode
"""
diff --git a/test/integration/component/test_netscaler_configs.py b/test/integration/component/test_netscaler_configs.py
new file mode 100644
index 00000000000..a76a19b8b2e
--- /dev/null
+++ b/test/integration/component/test_netscaler_configs.py
@@ -0,0 +1,2965 @@
+# -*- encoding: utf-8 -*-
+# 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.
+#
+# Automatically generated by addcopyright.py at 04/03/2012
+
+""" P1 tests for netscaler configurations
+"""
+#Import Local Modules
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from integration.lib.utils import *
+from integration.lib.base import *
+from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
+import datetime
+
+
+class Services:
+ """Test netscaler Services
+ """
+
+ def __init__(self):
+ self.services = {
+ "account": {
+ "email": "test@test.com",
+ "firstname": "Test",
+ "lastname": "User",
+ "username": "test",
+ # Random characters are appended for unique
+ # username
+ "password": "fr3sca",
+ },
+ "service_offering": {
+ "name": "Tiny Instance",
+ "displaytext": "Tiny Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100, # in MHz
+ "memory": 128, # In MBs
+ },
+ "virtual_machine": {
+ "displayname": "TestVM",
+ "username": "root",
+ "password": "password",
+ "ssh_port": 22,
+ "hypervisor": 'XenServer',
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": 'TCP',
+ },
+ "netscaler": {
+ "ipaddress": '192.168.100.213',
+ "username": 'nsroot',
+ "password": 'nsroot',
+ "networkdevicetype": 'NetscalerVPXLoadBalancer',
+ "publicinterface": '1/1',
+ "privateinterface": '0/1',
+ "numretries": 2,
+ "lbdevicededicated": False,
+ "lbdevicecapacity": 50,
+ "port": 22,
+ },
+ "network_offering_dedicated": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "specifyVlan": False,
+ "specifyIpRanges": False,
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ "servicecapabilitylist": {
+ "SourceNat": {
+ "SupportedSourceNatTypes": "peraccount"
+ },
+ "lb": {
+ "SupportedLbIsolation": "dedicated"
+ },
+ },
+ },
+ "network_offering": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ },
+ "network": {
+ "name": "Netscaler",
+ "displaytext": "Netscaler",
+ },
+ "lbrule": {
+ "name": "SSH",
+ "alg": "roundrobin",
+ # Algorithm used for load balancing
+ "privateport": 22,
+ "publicport": 22,
+ "openfirewall": False,
+ },
+ "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f',
+ # Cent OS 5.3 (64 bit)
+ "sleep": 60,
+ "timeout": 10,
+ "mode":'advanced'
+ }
+
+
+class TestAddNetScaler(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestAddNetScaler,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls._cleanup = []
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_add_netscaler_device(self):
+ """Test add netscaler device
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device into a Zone by providing valid log in
+ # credentials , public , private interface and enabling Load
+ # Balancing feature.
+ # 2. Netscaler should be configured successfully.
+
+ physical_networks = PhysicalNetwork.list(
+ self.apiclient,
+ zoneid=self.zone.id
+ )
+ self.assertEqual(
+ isinstance(physical_networks, list),
+ True,
+ "There should be atleast one physical network for advanced zone"
+ )
+ physical_network = physical_networks[0]
+ self.debug("Adding netscaler device: %s" %
+ self.services["netscaler"]["ipaddress"])
+ netscaler = NetScaler.add(
+ self.apiclient,
+ self.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+ self.cleanup.append(netscaler)
+ self.debug("Checking if Netscaler network service provider is enabled?")
+
+ nw_service_providers = NetworkServiceProvider.list(
+ self.apiclient,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ self.assertEqual(
+ isinstance(nw_service_providers, list),
+ True,
+ "Network service providers list should not be empty"
+ )
+ netscaler_provider = nw_service_providers[0]
+ if netscaler_provider.state != 'Enabled':
+ self.debug("Netscaler provider is not enabled. Enabling it..")
+ response = NetworkServiceProvider.update(
+ self.apiclient,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ self.assertEqual(
+ response.state,
+ "Enabled",
+ "Network service provider should be in enabled state"
+ )
+ else:
+ self.debug("Netscaler service provider is already enabled.")
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ self.assertEqual(
+ ns.physicalnetworkid,
+ physical_network.id,
+ "Physical network id should match with the network in which device is configured"
+ )
+ return
+
+
+class TestInvalidParametersNetscaler(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestInvalidParametersNetscaler,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls._cleanup = []
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_invalid_cred(self):
+ """Test add netscaler device with invalid credential
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device into a Zone by providing invalid log in
+ # credentials , but valid public, private interface
+ # 2. Netscaler API should throw error
+
+ physical_networks = PhysicalNetwork.list(
+ self.apiclient,
+ zoneid=self.zone.id
+ )
+ self.assertEqual(
+ isinstance(physical_networks, list),
+ True,
+ "There should be atleast one physical network for advanced zone"
+ )
+ physical_network = physical_networks[0]
+
+ self.debug("Checking if Netscaler network service provider is enabled?")
+
+ nw_service_providers = NetworkServiceProvider.list(
+ self.apiclient,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ self.assertEqual(
+ isinstance(nw_service_providers, list),
+ True,
+ "Network service providers list should not be empty"
+ )
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ self.debug("Netscaler provider is not enabled. Enabling it..")
+ response = NetworkServiceProvider.update(
+ self.apiclient,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ self.assertEqual(
+ response.state,
+ "Enabled",
+ "Network service provider should be in enabled state"
+ )
+ else:
+ self.debug("NetScaler service provider is already enabled.")
+
+ self.debug("Passing invalid credential for NetScaler")
+ self.services["netscaler"]["username"] = random_gen()
+ self.services["netscaler"]["password"] = random_gen()
+ self.debug("Adding netscaler device: %s" %
+ self.services["netscaler"]["ipaddress"])
+
+ self.debug("Username: %s, password: %s" % (
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"]
+ ))
+
+ with self.assertRaises(Exception):
+ NetScaler.add(
+ self.apiclient,
+ self.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+ return
+
+ def test_invalid_public_interface(self):
+ """Test add netscaler device with invalid public interface
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device into a Zone by providing valid log in
+ # credentials , private interface and invalid public interface
+ # 2. Netscaler API should throw error
+
+ physical_networks = PhysicalNetwork.list(
+ self.apiclient,
+ zoneid=self.zone.id
+ )
+ self.assertEqual(
+ isinstance(physical_networks, list),
+ True,
+ "There should be atleast one physical network for advanced zone"
+ )
+ physical_network = physical_networks[0]
+
+ self.debug("Checking if Netscaler network service provider is enabled?")
+
+ nw_service_providers = NetworkServiceProvider.list(
+ self.apiclient,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ self.assertEqual(
+ isinstance(nw_service_providers, list),
+ True,
+ "Network service providers list should not be empty"
+ )
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ self.debug("Netscaler provider is not enabled. Enabling it..")
+ response = NetworkServiceProvider.update(
+ self.apiclient,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ self.assertEqual(
+ response.state,
+ "Enabled",
+ "Network service provider should be in enabled state"
+ )
+ else:
+ self.debug("NetScaler service provider is already enabled.")
+
+ self.debug("Passing invalid public interface for NetScaler")
+ self.services["netscaler"]["publicinterface"] = random_gen()
+
+ self.debug("Adding netscaler device: %s" %
+ self.services["netscaler"]["ipaddress"])
+
+ self.debug("Public interface: %s" %
+ self.services["netscaler"]["publicinterface"])
+
+ with self.assertRaises(Exception):
+ NetScaler.add(
+ self.apiclient,
+ self.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+ return
+
+ def test_invalid_private_interface(self):
+ """Test add netscaler device with invalid private interface
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device into a Zone by providing valid log in
+ # credentials , public interface and invalid private interface
+ # 2. Netscaler API should throw error
+
+ physical_networks = PhysicalNetwork.list(
+ self.apiclient,
+ zoneid=self.zone.id
+ )
+ self.assertEqual(
+ isinstance(physical_networks, list),
+ True,
+ "There should be atleast one physical network for advanced zone"
+ )
+ physical_network = physical_networks[0]
+
+ self.debug("Checking if Netscaler network service provider is enabled?")
+
+ nw_service_providers = NetworkServiceProvider.list(
+ self.apiclient,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ self.assertEqual(
+ isinstance(nw_service_providers, list),
+ True,
+ "Network service providers list should not be empty"
+ )
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ self.debug("Netscaler provider is not enabled. Enabling it..")
+ response = NetworkServiceProvider.update(
+ self.apiclient,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ self.assertEqual(
+ response.state,
+ "Enabled",
+ "Network service provider should be in enabled state"
+ )
+ else:
+ self.debug("NetScaler service provider is already enabled.")
+
+ self.debug("Passing invalid private interface for NetScaler")
+ self.services["netscaler"]["privateinterface"] = random_gen()
+
+ self.debug("Adding netscaler device: %s" %
+ self.services["netscaler"]["ipaddress"])
+
+ self.debug("Private interface: %s" %
+ self.services["netscaler"]["privateinterface"])
+
+ with self.assertRaises(Exception):
+ NetScaler.add(
+ self.apiclient,
+ self.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+ return
+
+@unittest.skip("Issue- Unable to validate user credentials while creating nw offering")
+class TestNetScalerDedicated(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestNetScalerDedicated,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.services["netscaler"]["lbdevicededicated"] = True
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering_dedicated"],
+ conservemode=False,
+ state="Creating",
+ status="Creating",
+ allocationstate="Creating",
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_netscaler_dedicated_mode(self):
+ """Test netscaler device in dedicated mode
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device in dedicated mode.
+ # 2. Netscaler should be configured successfully.It should be able to
+ # service only 1 account.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ True,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ with self.assertRaises(Exception):
+ Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ return
+
+
+class TestNetScalerShared(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestNetScalerShared,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_netscaler_dedicated_mode(self):
+ """Test netscaler device in dedicated mode
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device in dedicated mode.
+ # 2. Netscaler should be configured successfully.It should be able to
+ # service only 1 account.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ self.network_2 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_2.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_2.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_2.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ return
+
+
+class TestNetScalerCustomCapacity(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestNetScalerCustomCapacity,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+ cls.services["netscaler"]["lbdevicecapacity"] = 2
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_3 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2, self.account_3]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_netscaler_dedicated_mode(self):
+ """Test netscaler device in dedicated mode
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device in dedicated mode.
+ # 2. Netscaler should be configured successfully.It should be able to
+ # service only 1 account.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ self.network_2 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_2.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_2.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_2.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_2.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ self.network_3 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_3.account.name,
+ domainid=self.account_3.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_3.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_3.account.name)
+ with self.assertRaises(Exception):
+ # Spawn an instance in that network
+ virtual_machine_3 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_3.account.name,
+ domainid=self.account_3.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_3.id)]
+ )
+ return
+
+
+class TestNetScalerNoCapacity(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestNetScalerNoCapacity,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_3 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2, self.account_3]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_netscaler_dedicated_mode(self):
+ """Test netscaler device in dedicated mode
+ """
+
+ # Validate the following
+ # 1. Add Netscaler device in dedicated mode.
+ # 2. Netscaler should be configured successfully.It should be able to
+ # service only 1 account.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ self.network_2 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_2.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_2.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_2.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_2.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ # Creating network using the network offering created
+ self.debug("Trying to create network with network offering: %s" %
+ self.network_offering.id)
+ self.network_3 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_3.account.name,
+ domainid=self.account_3.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_3.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_3.account.name)
+ with self.assertRaises(Exception):
+ # Spawn an instance in that network
+ virtual_machine_3 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_3.account.name,
+ domainid=self.account_3.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_3.id)]
+ )
+ return
+
+
+class TestGuestNetworkWithNetScaler(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestGuestNetworkWithNetScaler,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_guest_network(self):
+ """Implementing Guest Network when first VM gets deployed using the network having Netscaler as LB
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3.Create a new account/user.
+ # 4. Deploy the first VM using a network from the above created
+ # Network offering.
+ # In Netscaler:
+ # 1. Private interface of Netscaler device will be configured to make
+ # it part of the virtual guest network by binding the interface to
+ # the VLAN and subnet allocated for the virtual guest network
+ # 2. Private interface should be associated with a self-ip (second IP
+ # in the subnet) from the guest subnet.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network_1.id,
+ listall=True
+ )
+ nw = network_list[0]
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource "),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_02_guest_network_multiple(self):
+ """Implementing Guest Network when multiple VMs gets deployed using the network having Netscaler as LB
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3.Create a new account/user.
+ # 4. Deploy the first VM using a network from the above created
+ # Network offering.
+ # In Netscaler:
+ # 1. Private interface of Netscaler device will be configured to make
+ # it part of the virtual guest network by binding the interface to
+ # the VLAN and subnet allocated for the virtual guest network
+ # 2. Private interface should be associated with a self-ip (second IP
+ # in the subnet) from the guest subnet.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_2 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_2.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_2.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_2.account.name,
+ domainid=self.account_2.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_2.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_2.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network_1.id,
+ listall=True
+ )
+ nw = network_list[0]
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource "),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network_2.id,
+ listall=True
+ )
+ nw = network_list[0]
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_03_delete_account(self):
+ """Delete an account that has LB rules
+ """
+
+ # Validate the following
+ # 1. Acquire an ipaddress. Create multiple Lb rules on this ip address
+ # 2. Delete this account that has LB rules
+ # In Netscaler:
+ # 1. Private interface on the netscaler LB device will be unbound to
+ # vlan and subnet
+ # 2. All the service instance and the servers that are part of this
+ # vlan, that were created on the Netscaler device as part of
+ # applying LB rules will be destroyed.
+ # 3. Any lb virtual server that is created using this public IP
+ # allocated for the account will be destroyed
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Assigning public IP for the account: %s" %
+ self.account_1.account.name)
+ public_ip = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account_1.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account_1.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ public_ip.ipaddress.ipaddress)
+
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip.ipaddress.id,
+ accountid=self.account_1.account.name,
+ networkid=self.network.id
+ )
+ self.debug("Created the load balancing rule for public IP: %s" %
+ public_ip.ipaddress.ipaddress)
+ self.debug("Assigning VMs to LB rule")
+ lb_rule.assign(self.apiclient, [virtual_machine])
+
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network.id,
+ listall=True
+ )
+ nw = network_list[0]
+
+ self.debug("Deleting account: %s" % self.account_1.account.name)
+ # This is a hack. Delete first account from cleanup list
+ self.cleanup.pop(0).delete(self.apiclient)
+ self.debug("Account: %s is deleted!" % self.account_1.account.name)
+
+ self.debug("Waiting for network.gc.interval & network.gc.wait..")
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+
+class TestGuestNetworkShutDown(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestGuestNetworkShutDown,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+
+ # Creating network using the network offering created
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn few instances in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls.lb_rule = LoadBalancerRule.create(
+ cls.api_client,
+ cls.services["lbrule"],
+ ipaddressid=cls.public_ip.ipaddress.id,
+ accountid=cls.account.account.name,
+ networkid=cls.network.id
+ )
+ cls.lb_rule.assign(cls.api_client, [cls.vm_1, cls.vm_2])
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_stop_all_vms(self):
+ """Test Stopping all the Vms for any account that has LB rules.
+ """
+
+ # Validate the following
+ # 1. Acquire IP address and create a load balancer rule
+ # 2. Stop all VMs in the account that has LB rules
+ # 3. This will result in the network being shutdown. As part of this,
+ # this account and the all the Lb rules for this account should get
+ # removed from the Netscaler
+
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network.id,
+ listall=True
+ )
+ nw = network_list[0]
+ self.debug("Network vlan used is: %s" % nw.vlan)
+
+ self.debug(
+ "Stopping all the VM instances for the account: %s" %
+ self.account.account.name)
+
+ self.vm_1.stop(self.apiclient)
+ self.vm_2.stop(self.apiclient)
+
+ self.debug("Sleep for network.gc.interval + network.gc.wait")
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep((int(interval[0].value) + int(wait[0].value))*2)
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should not have vlan configured for the network"
+ )
+
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ self.lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should not have vserver configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_02_start_one_vm(self):
+ """Test LB rules on Netscaler after starting one Vm in account
+ """
+
+ # Validate the following
+ # 1. Acquire IP address and create a load balancer rule
+ # 2. Stop all VMs in the account that has LB rules
+ # 3. This will result in the network being shutdown. As part of this,
+ # this account and the all the Lb rules for this account should get
+ # removed from the Netscaler
+ # 3. Start one of the VMs. LB rules should get reconfigured on
+ # Netscaler
+
+ self.debug(
+ "starting one VM instances for the account: %s" %
+ self.account.account.name)
+ self.vm_1.start(self.apiclient)
+
+ vms = VirtualMachine.list(
+ self.apiclient,
+ id=self.vm_1.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(vms, list),
+ True,
+ "List VMs should return a valid list"
+ )
+
+ for vm in vms:
+ self.assertEqual(
+ vm.state,
+ "Running",
+ "VM instance should be Up and running after start"
+ )
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network.id,
+ listall=True
+ )
+ nw = network_list[0]
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource "),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ self.lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_03_network_restart_without_cleanup(self):
+ """Test LB rules on Netscaler after network restart without cleanup
+ """
+
+ # Validate the following
+ # 1. Acquire IP address and create a load balancer rule
+ # 2. Restart network->without cleanup option enabled
+ # 3. All existing Lb rules get added again to the netscaler. All the
+ # existing LB rules should continue to work.
+
+ self.debug("Restarting the network: %s" % self.network.id)
+ self.network.restart(self.apiclient, cleanup=False)
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network.id,
+ listall=True
+ )
+ nw = network_list[0]
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource "),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ self.lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_04_network_restart_with_cleanup(self):
+ """Test LB rules on Netscaler after network restart with cleanup
+ """
+
+ # Validate the following
+ # 1. Acquire IP address and create a load balancer rule
+ # 2. Restart network->with cleanup option enabled
+ # 3. All existing Lb rules get deleted and reconfigured again to the
+ # netscaler. All the existing LB rules should continue to work.
+
+ self.debug("Restarting the network: %s" % self.network.id)
+ self.network.restart(self.apiclient, cleanup=True)
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ # Find Network vlan used
+ network_list = Network.list(
+ self.apiclient,
+ id=self.network.id,
+ listall=True
+ )
+ nw = network_list[0]
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show vlan %s" % (nw.vlan)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource "),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ self.lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+ # Output: ERROR: No such resource [id, 123]
+
+ self.assertNotEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Netscaler should have vlan configured for the network"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+
+class TestServiceProvider(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestServiceProvider,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ cls.netscaler_provider = nw_service_providers[0]
+
+ if cls.netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=cls.netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Enable the service provider
+ NetworkServiceProvider.update(
+ cls.api_client,
+ id=cls.netscaler_provider.id,
+ state='Enabled'
+ )
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_create_nw_off_disabled(self):
+ """Test create network with network offering disabled
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering. Do not enable the network offering
+ # 3. Try to create a network with this network offering.
+ # 4. Network creation should fail
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ with self.assertRaises(Exception):
+ Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ return
+
+ def test_02_create_nw_sp_disabled(self):
+ """Test create network when service provider is disabled
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Disable the service provider. Create a Network offering.
+ # 3. Try to create a network. Network creation should fail
+
+ # Enable Network offering
+ self.network_offering.update(self.apiclient, state='Enabled')
+
+ # Disable the service provider
+ NetworkServiceProvider.update(
+ self.apiclient,
+ id=self.netscaler_provider.id,
+ state='Disabled'
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ with self.assertRaises(Exception):
+ Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ return
+
+ def test_03_create_lb_sp_disabled(self):
+ """Test create LB rules when service provider is disabled
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering. Create instances and acquire public Ip
+ # 3. Disabled service provider and again try to create LB rules
+ # 4.Deploy VM should fail
+
+ # Enable the service provider
+ NetworkServiceProvider.update(
+ self.apiclient,
+ id=self.netscaler_provider.id,
+ state='Enabled'
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Acquiring a public IP for Network: %s" % self.network.name)
+ public_ip = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ public_ip.ipaddress.ipaddress)
+
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.debug("Created the load balancing rule for public IP: %s" %
+ public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug("Disabling Netscaler service provider")
+
+ # Disable the service provider
+ NetworkServiceProvider.update(
+ self.apiclient,
+ id=self.netscaler_provider.id,
+ state='Disabled'
+ )
+ self.debug("Deploying VM in the network: %s" % self.network.id)
+ with self.assertRaises(Exception):
+ VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ return
+
+
+class TestDeleteNetscaler(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestDeleteNetscaler,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ physical_networks = PhysicalNetwork.list(
+ cls.api_client,
+ zoneid=cls.zone.id
+ )
+ if isinstance(physical_networks, list):
+ physical_network = physical_networks[0]
+
+ cls.netscaler = NetScaler.add(
+ cls.api_client,
+ cls.services["netscaler"],
+ physicalnetworkid=physical_network.id
+ )
+
+ nw_service_providers = NetworkServiceProvider.list(
+ cls.api_client,
+ name='Netscaler',
+ physicalnetworkid=physical_network.id
+ )
+ if isinstance(nw_service_providers, list):
+ netscaler_provider = nw_service_providers[0]
+
+ if netscaler_provider.state != 'Enabled':
+ response = NetworkServiceProvider.update(
+ cls.api_client,
+ id=netscaler_provider.id,
+ state='Enabled'
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ cls.netscaler,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account_1 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.account_2 = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account_1, self.account_2]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_delete_netscaler_with_lb(self):
+ """Test delete Netscaler when active LB rules are present
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3.Create a new account/user.
+ # 4. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 5. Attempt to delete Netscaler load balancer from zone.
+ # Deletion should NOT be allowed.
+
+ ns_list = NetScaler.list(
+ self.apiclient,
+ lbdeviceid=self.netscaler.lbdeviceid
+ )
+ self.assertEqual(
+ isinstance(ns_list, list),
+ True,
+ "NetScaler list should not be empty"
+ )
+ ns = ns_list[0]
+
+ self.assertEqual(
+ ns.lbdevicededicated,
+ False,
+ "NetScaler device is configured in shared mode"
+ )
+ self.assertEqual(
+ ns.lbdevicestate,
+ "Enabled",
+ "NetScaler device state should be enabled"
+ )
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network_1 = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network_1.id)
+
+ self.debug("Deploying VM in account: %s" % self.account_1.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account_1.account.name,
+ domainid=self.account_1.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network_1.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network_1.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Attempt to delete netscaler load balancer device")
+ with self.assertRaises(Exception):
+ self.netscaler.delete(self.apiclient)
+ self.debug("Attempt to delete Netscaler device failed!")
+ return
diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py
new file mode 100644
index 00000000000..6b1e517df98
--- /dev/null
+++ b/test/integration/component/test_netscaler_lb.py
@@ -0,0 +1,2924 @@
+# -*- encoding: utf-8 -*-
+# 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.
+#
+# Automatically generated by addcopyright.py at 04/03/2012
+
+""" P1 tests for netscaler load balancing
+"""
+#Import Local Modules
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from integration.lib.utils import *
+from integration.lib.base import *
+from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
+import datetime
+
+
+class Services:
+ """Test netscaler services
+ """
+
+ def __init__(self):
+ self.services = {
+ "account": {
+ "email": "test@test.com",
+ "firstname": "Test",
+ "lastname": "User",
+ "username": "test",
+ # Random characters are appended for unique
+ # username
+ "password": "password",
+ },
+ "service_offering": {
+ "name": "Tiny Instance",
+ "displaytext": "Tiny Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100, # in MHz
+ "memory": 64, # In MBs
+ },
+ "virtual_machine": {
+ "displayname": "TestVM",
+ "username": "root",
+ "password": "password",
+ "ssh_port": 22,
+ "hypervisor": 'XenServer',
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": 'TCP',
+ },
+ "netscaler": {
+ "ipaddress": '10.147.40.100',
+ "username": 'nsroot',
+ "password": 'nsroot',
+ "networkdevicetype": 'NetscalerVPXLoadBalancer',
+ "publicinterface": '1/1',
+ "privateinterface": '1/1',
+ "numretries": 2,
+ "lbdevicededicated": False,
+ "lbdevicecapacity": 50,
+ "port": 22,
+ },
+ "network_offering_dedicated": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "specifyVlan": False,
+ "specifyIpRanges": False,
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ "servicecapabilitylist": {
+ "SourceNat": {
+ "SupportedSourceNatTypes": "peraccount"
+ },
+ "lb": {
+ "SupportedLbIsolation": "dedicated"
+ },
+ },
+ },
+ "network_offering": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ },
+ "network": {
+ "name": "Netscaler",
+ "displaytext": "Netscaler",
+ },
+ "lbrule": {
+ "name": "SSH",
+ "alg": "roundrobin",
+ # Algorithm used for load balancing
+ "privateport": 22,
+ "publicport": 22,
+ "openfirewall": False,
+ },
+ "natrule": {
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": "TCP"
+ },
+ "ostypeid": '2b58909b-7d9e-45d9-80d8-e58d0bbcbf07',
+ # Cent OS 5.3 (64 bit)
+ "sleep": 60,
+ "timeout": 10,
+ "mode":'advanced'
+ }
+
+
+class TestLbSourceNat(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbSourceNat,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_add_lb_on_source_nat(self):
+ """Test Create LB rule for sourceNat IP address
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Create LB rule for the sourceNat IP address. User should NOT be
+ # allowed to create an LB rule on source NAT
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ src_nat_list = PublicIPAddress.list(
+ self.apiclient,
+ associatednetworkid=self.network.id,
+ account=self.account.account.name,
+ domainid=self.account.account.domainid,
+ listall=True,
+ issourcenat=True,
+ )
+ self.assertEqual(
+ isinstance(src_nat_list, list),
+ True,
+ "List Public IP should return a valid source NAT"
+ )
+ self.assertNotEqual(
+ len(src_nat_list),
+ 0,
+ "Length of response from listPublicIp should not be 0"
+ )
+
+ src_nat = src_nat_list[0]
+
+ self.debug("Trying to create LB rule on source NAT IP: %s" %
+ src_nat.ipaddress)
+ # Create Load Balancer rule with source NAT
+ with self.assertRaises(Exception):
+ LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=src_nat.id,
+ accountid=self.account.account.name
+ )
+ return
+
+
+class TestLbOnIpWithPf(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbOnIpWithPf,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_on_ip_with_pf(self):
+ """Test Create LB rule for sourceNat IP address
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Create LB rule on Ip with PF rule. User should NOT be
+ # allowed to create an LB rule on Ip with PF
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+ ip_with_nat_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+
+ self.debug("Associated %s with network %s" % (
+ ip_with_nat_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug("Creating PF rule for IP address: %s" %
+ ip_with_nat_rule.ipaddress.ipaddress)
+ NATRule.create(
+ self.apiclient,
+ virtual_machine_1,
+ self.services["natrule"],
+ ipaddressid=ip_with_nat_rule.ipaddress.id
+ )
+
+ self.debug("Trying to create LB rule on IP with NAT: %s" %
+ ip_with_nat_rule.ipaddress.ipaddress)
+
+ # Create Load Balancer rule on IP already having NAT rule
+ with self.assertRaises(Exception):
+ LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_nat_rule.ipaddress.id,
+ accountid=self.account.account.name
+ )
+ return
+
+
+class TestPfOnIpWithLb(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestPfOnIpWithLb,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_pf_on_ip_with_lb(self):
+ """Test Create a port forwarding rule on an Ip address that already has a LB rule.
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Create PF rule on Ip with LB rule. User should NOT be
+ # allowed to create an LB rule on Ip with LB
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug("Creating LB rule for IP address: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ with self.assertRaises(Exception):
+ NATRule.create(
+ self.apiclient,
+ virtual_machine,
+ self.services["natrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id
+ )
+ return
+
+
+class TestLbOnNonSourceNat(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbOnNonSourceNat,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=False
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_on_non_source_nat(self):
+ """Test Create LB rule for non-sourceNat IP address
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create LB rule on it. LB rule should be
+ # created successfully
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug("Creating LB rule for IP address: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ return
+
+
+class TestAddMultipleVmsLb(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestAddMultipleVmsLb,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_add_multiple_vms_lb(self):
+ """Test Add multiple Vms to an existing LB rule.
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create LB rule on it. Add multiple VMs to
+ # this rule. LB rule should be
+ # In Netscaler: For every Vm added to the LB rule:
+ # 1. A server and service instance is created using guest VM’s IP and
+ # port number on the Netscaler LB device,
+ # 2. This service is bound to lb virtual server corresponding to lb
+ # rule.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug("Creating LB rule for IP address: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Assigning virtual machines to LB rule")
+ lb_rule.assign(self.apiclient, [virtual_machine_1, virtual_machine_2])
+
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ 22,
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ self.debug("command: show server")
+ res = ssh_client.execute("show server")
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(virtual_machine_1.ipaddress),
+ 2,
+ "Server must be configured for virtual machines"
+ )
+ self.assertEqual(
+ result.count(virtual_machine_2.ipaddress),
+ 2,
+ "Server must be configured for virtual machines"
+ )
+
+ self.debug("Command:show service")
+ res = ssh_client.execute("show service")
+
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(virtual_machine_1.ipaddress),
+ 3,
+ "Service must be configured for virtual machines"
+ )
+ self.assertEqual(
+ result.count(virtual_machine_2.ipaddress),
+ 3,
+ "Service must be configured for virtual machines"
+ )
+ self.debug("Command:show lb vserver")
+ res = ssh_client.execute("show lb vserver")
+
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(ip_with_lb_rule.ipaddress.ipaddress),
+ 2,
+ "virtual server must be configured for public IP address"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+
+class TestMultipleLbRules(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestMultipleLbRules,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_multiple_lb_publicip(self):
+ """Test Create multiple LB rules using different public Ips acquired
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy few more VMs.
+ # 3. Acquire an Ipaddress and create an LB rule for multiple Vms.
+ # Repeat step2 for few times Requests to all these LB rules should
+ # be serviced correctly.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug(
+ "Associating first public IP for network: %s" %
+ self.network.id)
+
+ public_ip_1 = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ public_ip_1.ipaddress.ipaddress,
+ self.network.id
+ ))
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ public_ip_1.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip_1.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ virtual_machine_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_1, virtual_machine_2])
+
+ self.debug(
+ "Associating second public IP for network: %s" %
+ self.network.id)
+
+ public_ip_2 = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ public_ip_2.ipaddress.ipaddress,
+ self.network.id
+ ))
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ public_ip_2.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip_2.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ public_ip_2.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ virtual_machine_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_1, virtual_machine_2])
+
+ try:
+ self.debug(
+ "Verifying VMs are accessible with different public Ips")
+ hostnames = []
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=public_ip_1.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result[0])
+ self.assertIn(
+ res,
+ [virtual_machine_1.name, virtual_machine_2.name],
+ "The hostname should match with atleast one of instance name"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ public_ip_1.ipaddress.ipaddress,
+ e))
+ try:
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=public_ip_2.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result[0])
+ self.assertIn(
+ res,
+ [virtual_machine_1.name, virtual_machine_2.name],
+ "The hostname should match with atleast one of instance name"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ public_ip_2.ipaddress.ipaddress,
+ e))
+ return
+
+
+
+class TestMultipleLbRulesSameIp(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestMultipleLbRulesSameIp,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_multiple_lb_same_publicip(self):
+ """Test Create multiple LB rules using same public Ips on diff ports
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy few more VMs.
+ # 3. Acquire an Ipaddress and create an LB rule for multiple Vms.
+ # Create another Lb rule on the same Ipaddress pointing to
+ # different public port. Requests to all these LB rules should be
+ # serviced correctly.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug(
+ "Associating first public IP for network: %s" %
+ self.network.id)
+
+ public_ip = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ public_ip.ipaddress.ipaddress,
+ self.network.id
+ ))
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule_1 = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ public_ip.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule_1.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ virtual_machine_2.name,
+ lb_rule_1.name
+ ))
+ lb_rule_1.assign(self.apiclient, [
+ virtual_machine_1,
+ virtual_machine_2
+ ])
+ self.debug(
+ "Trying to create LB rule on IP: %s with on same ports" %
+ public_ip.ipaddress.ipaddress)
+ with self.assertRaises(Exception):
+ LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.debug("Create LB rule on same port failed!")
+ self.debug("Creating LB rule on IP: %s & public port: %s" % (
+ public_ip.ipaddress.ipaddress,
+ str(2222)))
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ self.services["lbrule"]["publicport"] = 2222
+ self.services["lbrule"]["name"] = 'SSH2'
+ lb_rule_2 = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule_2.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ virtual_machine_2.name,
+ lb_rule_2.name
+ ))
+ lb_rule_2.assign(self.apiclient, [
+ virtual_machine_1,
+ virtual_machine_2
+ ])
+
+ try:
+ self.debug("Verifying VMs are accessible on all LB rules")
+ hostnames = []
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result[0])
+ self.assertIn(
+ res,
+ [virtual_machine_1.name, virtual_machine_2.name],
+ "The hostname should match with atleast one of instance name"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ public_ip.ipaddress.ipaddress,
+ e))
+ try:
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=public_ip.ipaddress.ipaddress,
+ reconnect=True,
+ port=self.services["lbrule"]["publicport"]
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result[0])
+ self.assertIn(
+ res,
+ [virtual_machine_1.name, virtual_machine_2.name],
+ "The hostname should match with atleast one of instance name"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLoadBalancingRule(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLoadBalancingRule,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+
+ # Creating network using the network offering created
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.virtual_machine = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls.lb_rule = LoadBalancerRule.create(
+ cls.api_client,
+ cls.services["lbrule"],
+ ipaddressid=cls.public_ip.ipaddress.id,
+ accountid=cls.account.account.name,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_edit_name_lb_rule(self):
+ """Test edit name of LB rule
+ """
+
+ # Validate the following
+ # 1. Create an Lb rule for couple of Vms .
+ # 2. Edit the name of the existing LB rule. When all the existing
+ # Lbrules are listed , we should see the edited name.
+
+ self.debug("Assigning VMs to LB rule: %s" % self.lb_rule.name)
+ self.lb_rule.assign(self.apiclient, [self.virtual_machine])
+
+ self.debug("Editing name of the LB rule: %s" % self.lb_rule.name)
+ new_name = random_gen()
+ self.lb_rule.update(self.apiclient, name=new_name)
+
+ self.debug("Verifing the name change in list Lb rules call")
+ lb_rules = LoadBalancerRule.list(self.apiclient, id=self.lb_rule.id)
+
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB call should return a valid list"
+ )
+ lb = lb_rules[0]
+ self.assertEqual(
+ lb.name,
+ new_name,
+ "LB name should be updated with the new name"
+ )
+ return
+
+ def test_02_edit_lb_ports(self):
+ """Test edit public port of LB rule
+ """
+
+ # Validate the following
+ # 1. Create an Lb rule for couple of Vms .
+ # 2. Edit the public/private of the existing LB rule. When all the
+ # existing Lbrules are listed, this should not be allowed.
+
+ self.debug("Editing public port of the LB rule: %s" % self.lb_rule.name)
+ port = 8888
+ with self.assertRaises(Exception):
+ self.lb_rule.update(self.apiclient, publicport=port)
+
+ self.debug("Editing private port of the LB rule: %s" % self.lb_rule.name)
+ with self.assertRaises(Exception):
+ self.lb_rule.update(self.apiclient, privateport=port)
+
+ return
+
+ def test_03_delete_lb_rule(self):
+ """Test delete LB rule
+ """
+
+ # Validate the following
+ # 1. Delete existing load balancing rule
+ # 2. In netscaler service and port corresponding to LB rule should get
+ # deleted. Any request to IP should error out.
+
+ self.debug("Deleting existing load balancing rule")
+ self.lb_rule.delete(self.apiclient)
+
+ self.debug("SSH into Netscaler to verify other resources are deleted")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ self.lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Virtual server should get deleted after removing LB rule"
+ )
+
+ cmd = "show ip"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(self.public_ip.ipaddress.ipaddress),
+ 0,
+ "Virtual server should get deleted after removing LB rule"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+@unittest.skip("Questions - How to verify after changing public/private ports?")
+class TestDeleteCreateLBRule(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestDeleteCreateLBRule,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+
+ # Creating network using the network offering created
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.virtual_machine = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_create_with_same_public_port(self):
+ """Test create LB rule with same public port after deleting rule"""
+
+ # Validate the following
+ # 1. Delete existing rule and create exactly same rule with different
+ # public port
+ # 2. Requests should be served correctly
+
+ self.debug("Delete the existing LB rule: %s" % self.lb_rule.name)
+ self.lb_rule.delete(self.apiclient)
+ self.debug("LB rule deleted")
+
+ self.debug("Create a new LB rule with different public port")
+ self.services["lbrule"]["publicport"] = 23
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+
+class TestVmWithLb(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestVmWithLb,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+
+ # Creating network using the network offering created
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip_1 = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls.lb_rule_1 = LoadBalancerRule.create(
+ cls.api_client,
+ cls.services["lbrule"],
+ ipaddressid=cls.public_ip_1.ipaddress.id,
+ accountid=cls.account.account.name,
+ networkid=cls.network.id
+ )
+ cls.public_ip_2 = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls.lb_rule_2 = LoadBalancerRule.create(
+ cls.api_client,
+ cls.services["lbrule"],
+ ipaddressid=cls.public_ip_2.ipaddress.id,
+ accountid=cls.account.account.name,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_delete_public_ip(self):
+ """Test delete one public Ip with LB rules"""
+
+ # Validate the following
+ # 1. Associate 2 public Ips and create load balancing rules in it
+ # 2. Delete one of the public Ip
+ # 3. All the LB rules should be removed from that public Ip
+ # 4. In netscaler, make sure that all LB rules associated with that
+ # public Ip should get removed.
+ # 5. All servers and services service to that public Ip get deleted
+
+ self.debug("Deleting public IP: %s from network: %s" % (
+ self.public_ip_2.ipaddress.ipaddress,
+ self.network.name
+ ))
+ self.public_ip_2.delete(self.apiclient)
+ self.debug(
+ "Public Ip: %s is deleted!" %
+ self.public_ip_2.ipaddress.ipaddress)
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ publicipid=self.public_ip_2.ipaddress.id,
+ listall=True,
+ )
+ self.assertEqual(
+ lb_rules,
+ None,
+ "LB rules associated with the public Ip should get deleted"
+ )
+ self.debug("SSH into Netscaler to verify other resources are deleted")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip_2.ipaddress.ipaddress,
+ self.lb_rule_2.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Virtual server should get deleted after removing LB rule"
+ )
+
+ cmd = "show ip"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(self.public_ip_2.ipaddress.ipaddress),
+ 0,
+ "Virtual server should get deleted after removing LB rule"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_02_stop_user_vm(self):
+ """Test stop user VM with LB"""
+
+ # Validate the following
+ # 1. Create 2 instances and add these two for load balancing
+ # 2. Stop one of the user VM
+ # 3. Test whether the request are not sent to stopped user VM
+ # 4. In netscaler, LB rules for this VM still remain configured.But
+ # it will be marked as being down
+
+ self.debug("Adding instances: %s, %s to LB rule: %s" % (
+ self.vm_1.name,
+ self.vm_2.name,
+ self.lb_rule_1.name))
+ self.lb_rule_1.assign(self.apiclient, [self.vm_1, self.vm_2])
+ self.debug("Assigned instances: %s, %s to LB rule: %s" % (
+ self.vm_1.name,
+ self.vm_2.name,
+ self.lb_rule_1.name))
+ self.debug("Stopping VM instance: %s" % self.vm_2.name)
+ self.vm_2.stop(self.apiclient)
+ self.debug("Stopped VM: %s" % self.vm_2.name)
+
+ try:
+ self.debug(
+ "Verifying request served by only running instances")
+ hostnames = []
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must be same as another VM is stopped"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ e))
+ self.debug("SSH into Netscaler to rules still persist")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+
+ cmd = "show server"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertNotEqual(
+ result.count(self.vm_2.ipaddress),
+ 0,
+ "The server should be present in netscaler after VM stop"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_03_start_user_vm(self):
+ """Test start user VM with LB"""
+
+ # Validate the following
+ # 1. Create 2 instances and add these two for load balancing
+ # 2. Stop one of the user VM
+ # 3. Test whether the request are not sent to stopped user VM
+ # 4. In netscaler, LB rules for this VM still remain configured.But
+ # it will be marked as being down
+
+ self.debug("Starting VM instance: %s" % self.vm_2.name)
+ self.vm_2.start(self.apiclient)
+ self.debug("Starting VM: %s" % self.vm_2.name)
+
+ try:
+ self.debug(
+ "Verifying request served by only running instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Both request should be served by different instances"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ e))
+ self.debug("SSH into Netscaler to rules still persist")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+
+ cmd = "show server"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertNotEqual(
+ result.count(self.vm_2.ipaddress),
+ 0,
+ "The server should be present in netscaler after VM stop"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_04_migrate_user_vm(self):
+ """Test migrate user VM with LB"""
+
+ # Validate the following
+ # 1. Create 2 instances and add these two for load balancing
+ # 2. migrate one Vm to another host.
+ # 3. Test whether the request are sent to stopped user VM after migrate
+ # 4. In netscaler, the LB rules are still configured.
+
+ hosts = Host.list(
+ self.apiclient,
+ zoneid=self.vm_2.zoneid,
+ type='Routing'
+ )
+
+ self.assertEqual(
+ isinstance(hosts, list),
+ True,
+ "Check the number of hosts in the zone"
+ )
+ self.assertGreaterEqual(
+ len(hosts),
+ 2,
+ "Atleast 2 hosts should be present in a zone for VM migration"
+ )
+
+ # Remove the host of current VM from the hosts list
+ hosts[:] = [host for host in hosts if host.id != self.vm_2.hostid]
+
+ host = hosts[0]
+ self.debug("Migrating VM-ID: %s to Host: %s" % (self.vm_2.id, host.id))
+
+ cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
+ cmd.hostid = host.id
+ cmd.virtualmachineid = self.medium_virtual_machine.id
+ self.apiclient.migrateVirtualMachine(cmd)
+
+ list_vm_response = list_virtual_machines(
+ self.apiclient,
+ id=self.vm_2.id
+ )
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.hostid,
+ host.id,
+ "Check destination hostID of migrated VM"
+ )
+ self.debug("Migrated VM-ID: %s to Host: %s" % (self.vm_2.id, host.id))
+ try:
+ self.debug(
+ "Verifying request served by only running instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Both request should be served by different instances"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ e))
+ self.debug("SSH into Netscaler to rules still persist")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+
+ cmd = "show server"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertNotEqual(
+ result.count(self.vm_2.ipaddress),
+ 0,
+ "The server should be present in netscaler after migrate"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_05_reboot_user_vm(self):
+ """Test reboot user VM with LB"""
+
+ # Validate the following
+ # 1. Create 2 instances and add these two for load balancing
+ # 2. Reboot one of the user VM
+ # 3. Test whether the request are sent to both VMs after reboot
+ # 4. In netscaler, LB rules for this VM still remain configured.
+
+ self.debug("Rebooting VM instance: %s" % self.vm_2.name)
+ self.vm_2.reboot(self.apiclient)
+ self.debug("Rebooting VM: %s" % self.vm_2.name)
+
+ try:
+ self.debug(
+ "Verifying request served by only running instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Both request should be served by different instances"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ e))
+ self.debug("SSH into Netscaler to rules still persist")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+
+ cmd = "show server"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertNotEqual(
+ result.count(self.vm_2.ipaddress),
+ 0,
+ "The server should be present in netscaler after reboot"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_06_destroy_user_vm(self):
+ """Test destroy user VM with LB"""
+
+ # Validate the following
+ # 1. Create 2 instances and add these two for load balancing
+ # 2. Destroy one of the user VM
+ # 3. Until the time the Vm is in "Destroyed" state, the servies
+ # relating to this Vm will be marked as "Down".
+ # 4. Once the Vm gets expunged, then the servers and services
+ # associated with this VM should get deleted and the LB rules
+ # should not be pointing to this Vm anymore.
+
+ self.debug("Destroying VM instance: %s" % self.vm_2.name)
+ self.vm_2.delete(self.apiclient)
+ self.debug("Destroying VM: %s" % self.vm_2.name)
+
+ try:
+ self.debug(
+ "Verifying request served by only running instances")
+ hostnames = []
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip_1.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[1],
+ "Both request should be served by same instance"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ e))
+ delay = list_configurations(
+ self.apiclient,
+ name='expunge.delay'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='expunge.interval'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(delay[0].value) + int(wait[0].value))
+ self.debug("SSH into Netscaler to rules still persist")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+
+ cmd = "show server"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(self.vm_2.ipaddress),
+ 0,
+ "The server should not be present in netscaler after destroy"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_07_delete_all_public_ip(self):
+ """Test delete all public Ip with LB rules"""
+
+ # Validate the following
+ # 1. Associate 2 public Ips and create load balancing rules in it
+ # 2. Delete all of the public Ip
+ # 3. All the LB rules should be removed from that public Ip
+ # 4. In netscaler, make sure that all LB rules associated with that
+ # public Ip should get removed.
+ # 5. All servers and services service to that public Ip get deleted
+
+ self.debug("Deleting public IP: %s from network: %s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ self.network.name
+ ))
+ self.public_ip_1.delete(self.apiclient)
+ self.debug(
+ "Public Ip: %s is deleted!" %
+ self.public_ip_1.ipaddress.ipaddress)
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ publicipid=self.public_ip_1.ipaddress.id,
+ listall=True,
+ )
+ self.assertEqual(
+ lb_rules,
+ None,
+ "LB rules associated with the public Ip should get deleted"
+ )
+ self.debug("SSH into Netscaler to verify other resources are deleted")
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip_1.ipaddress.ipaddress,
+ self.lb_rule_1.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("ERROR: No such resource"),
+ 1,
+ "Virtual server should get deleted after removing LB rule"
+ )
+
+ cmd = "show ip"
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count(self.public_ip_1.ipaddress.ipaddress),
+ 0,
+ "Virtual server should get deleted after removing LB rule"
+ )
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
diff --git a/test/integration/component/test_netscaler_lb_algo.py b/test/integration/component/test_netscaler_lb_algo.py
new file mode 100644
index 00000000000..7248405001b
--- /dev/null
+++ b/test/integration/component/test_netscaler_lb_algo.py
@@ -0,0 +1,2601 @@
+# -*- encoding: utf-8 -*-
+# 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.
+#
+# Automatically generated by addcopyright.py at 04/03/2012
+
+""" P1 tests for netscaler load balancing
+"""
+#Import Local Modules
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from integration.lib.utils import *
+from integration.lib.base import *
+from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
+import datetime
+
+
+class Services:
+ """Test netscaler services
+ """
+
+ def __init__(self):
+ self.services = {
+ "account": {
+ "email": "test@test.com",
+ "firstname": "Test",
+ "lastname": "User",
+ "username": "test",
+ # Random characters are appended for unique
+ # username
+ "password": "password",
+ },
+ "service_offering": {
+ "name": "Tiny Instance",
+ "displaytext": "Tiny Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100, # in MHz
+ "memory": 64, # In MBs
+ },
+ "virtual_machine": {
+ "displayname": "TestVM",
+ "username": "root",
+ "password": "password",
+ "ssh_port": 22,
+ "hypervisor": 'XenServer',
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": 'TCP',
+ },
+ "netscaler": {
+ "ipaddress": '10.147.40.100',
+ "username": 'nsroot',
+ "password": 'nsroot',
+ "networkdevicetype": 'NetscalerVPXLoadBalancer',
+ "publicinterface": '1/1',
+ "privateinterface": '1/1',
+ "numretries": 2,
+ "lbdevicededicated": False,
+ "lbdevicecapacity": 50,
+ },
+ "network_offering_dedicated": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "specifyVlan": False,
+ "specifyIpRanges": False,
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ "servicecapabilitylist": {
+ "SourceNat": {
+ "SupportedSourceNatTypes": "peraccount"
+ },
+ "lb": {
+ "SupportedLbIsolation": "dedicated"
+ },
+ },
+ },
+ "network_offering": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ },
+ "network": {
+ "name": "Netscaler",
+ "displaytext": "Netscaler",
+ },
+ "lbrule": {
+ "name": "SSH",
+ "alg": "leastconn",
+ # Algorithm used for load balancing
+ "privateport": 22,
+ "publicport": 22,
+ "openfirewall": False,
+ },
+ "natrule": {
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": "TCP"
+ },
+ "ostypeid": '2b58909b-7d9e-45d9-80d8-e58d0bbcbf07',
+ # Cent OS 5.3 (64 bit)
+ "sleep": 60,
+ "timeout": 10,
+ "mode":'advanced'
+ }
+
+
+class TestLbWithRoundRobin(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbWithRoundRobin,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_with_round_robin(self):
+ """Test Create LB rule with round robin algorithm
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create LB rule with round robin algorithm
+ # on it. Verify that "Roundrobin" algorithm is applied when using
+ # this load balancing rule.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ virtual_machine_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_1, virtual_machine_2])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh = virtual_machine_2.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must not be same if round robin algo is used"
+ )
+
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[2],
+ "Alternate Hostnames must be same if roundrobin algo is used"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ e))
+ return
+
+
+
+class TestLbWithLeastConn(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbWithLeastConn,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_with_least_conn(self):
+ """Test Create LB rule with least connection algorithm
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create LB rule with round robin algorithm
+ # on it. Verify that "leastconn" algorithm is applied when using
+ # this load balancing rule.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_1])
+ self.debug("Creating a firewall rule to open up SSH ports..")
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.debug("Adding %s to the LB rule %s" % (
+ virtual_machine_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_2])
+
+ ssh = virtual_machine_2.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+ self.assertNotEqual(
+ res.count(virtual_machine_2.name),
+ 1,
+ "SSH request should go to second VM(having least connections)"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbWithSourceIp(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbWithSourceIp,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.network_offering,
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.account = Account.create(
+ self.apiclient,
+ self.services["account"],
+ admin=True,
+ domainid=self.domain.id
+ )
+ self.cleanup = [self.account]
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ interval = list_configurations(
+ self.apiclient,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ self.apiclient,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_with_source_ip(self):
+ """Test Create LB rule with source Ip algorithm
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create LB rule with round robin algorithm
+ # on it. Verify that "sourceIp" algorithm is applied when using
+ # this load balancing rule.
+
+ # Creating network using the network offering created
+ self.debug("Creating network with network offering: %s" %
+ self.network_offering.id)
+ self.network = Network.create(
+ self.apiclient,
+ self.services["network"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ networkofferingid=self.network_offering.id,
+ zoneid=self.zone.id
+ )
+ self.debug("Created network with ID: %s" % self.network.id)
+
+ self.debug("Deploying VM in account: %s" % self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_1.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_1.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+
+ self.debug("Deploying another VM in account: %s" %
+ self.account.account.name)
+
+ # Spawn an instance in that network
+ virtual_machine_2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ accountid=self.account.account.name,
+ domainid=self.account.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ networkids=[str(self.network.id)]
+ )
+ self.debug("Deployed VM in network: %s" % self.network.id)
+ list_vm_response = VirtualMachine.list(
+ self.apiclient,
+ id=virtual_machine_2.id
+ )
+
+ self.debug(
+ "Verify listVirtualMachines response for virtual machine: %s" \
+ % virtual_machine_2.id
+ )
+
+ self.assertEqual(
+ isinstance(list_vm_response, list),
+ True,
+ "Check list response returns a valid list"
+ )
+ vm_response = list_vm_response[0]
+
+ self.assertEqual(
+ vm_response.state,
+ "Running",
+ "VM state should be running after deployment"
+ )
+ self.debug("Associating public IP for network: %s" % self.network.id)
+
+ ip_with_lb_rule = PublicIPAddress.create(
+ self.apiclient,
+ accountid=self.account.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.account.domainid,
+ networkid=self.network.id
+ )
+ self.debug("Associated %s with network %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ self.network.id
+ ))
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=ip_with_lb_rule.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ ip_with_lb_rule.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ virtual_machine_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_1])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ res = str(result)
+
+ self.assertEqual(
+ res.count(virtual_machine_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ self.debug("Adding %s to the LB rule %s" % (
+ virtual_machine_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [virtual_machine_2])
+
+ ssh = virtual_machine_1.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(virtual_machine_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ ssh = virtual_machine_2.get_ssh_client(
+ ipaddress=ip_with_lb_rule.ipaddress.ipaddress
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(virtual_machine_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ ip_with_lb_rule.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoRrLc(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoRrLc,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_round_robin_to_least_conn(self):
+ """Test edit LB rule from round robin to least connection algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "RounbRobin" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "Round robin" algorithm to
+ # "LeastConn" After the update, Verify that "least Connection"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ self.vm_1.name,
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2])
+
+ try:
+ self.debug(
+ "Verifying the roundrobin algo used by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must not be same if round robin algo is used"
+ )
+
+ ssh_3 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[2],
+ "Alternate Hostnames must be same if roundrobin algo is used"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'leastconn'))
+ lb_rule.update(self.apiclient, algorithm='leastconn')
+
+ self.debug(
+ "Removing virtual machine: %s to test least connection algo" %
+ self.vm_2.name)
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_4 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_5 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+ self.assertNotEqual(
+ res.count(self.vm_2.name),
+ 1,
+ "SSH request should go to second VM(having least connections)"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoLcRr(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoLcRr,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_least_conn_to_round_robin(self):
+ """Test edit LB rule from least conn to round robin algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "Leastconn" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "Least conn" algorithm to
+ # "roundrobin" After the update, Verify that "round robin"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with least conn algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1])
+
+ try:
+ self.debug(
+ "Verifying the leastconn algo used by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_3 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+ self.assertNotEqual(
+ res.count(self.vm_2.name),
+ 1,
+ "SSH request should go to second VM(having least connections)"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'roundrobin'))
+ lb_rule.update(self.apiclient, algorithm='roundrobin')
+ try:
+ self.debug(
+ "Verifying the roundrobin algo used by SSHing into instances")
+ hostnames = []
+ ssh_4 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True)
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_5 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must not be same if round robin algo is used"
+ )
+
+ ssh_6 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_6.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[2],
+ "Alternate Hostnames must be same if roundrobin algo is used"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoRrSb(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoRrSb,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_round_robin_to_source(self):
+ """Test edit LB rule from round robin to source algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "RounbRobin" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "Round robin" algorithm to
+ # "Source" After the update, Verify that "Source"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Trying to create PF rule on IP with LB rule: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s, %s to the LB rule %s" % (
+ self.vm_1.name,
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2])
+
+ try:
+ self.debug(
+ "Verifying the roundrobin algo used by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True)
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must not be same if round robin algo is used"
+ )
+
+ ssh_3 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[2],
+ "Alternate Hostnames must be same if roundrobin algo is used"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'source'))
+ lb_rule.update(self.apiclient, algorithm='source')
+
+ self.debug(
+ "Removing virtual machine: %s to test source algo" %
+ self.vm_2.name)
+ lb_rule.remove(self.apiclient, [self.vm_2])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_4 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_5 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ ssh_6 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_6.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoSbRr(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoSbRr,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_source_to_round_robin(self):
+ """Test edit LB rule from source to round robin algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "source" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "source" algorithm to
+ # "roundrobin" After the update, Verify that "round robin"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with source algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_2 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ ssh_3 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'roundrobin'))
+ lb_rule.update(self.apiclient, algorithm='roundrobin')
+
+ try:
+ self.debug(
+ "Verifying the roundrobin algo used by SSHing into instances")
+ hostnames = []
+ ssh = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_4 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.assertNotEqual(
+ hostnames[0],
+ hostnames[1],
+ "Hostnames must not be same if round robin algo is used"
+ )
+
+ ssh_5 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ self.assertEqual(
+ hostnames[0],
+ hostnames[2],
+ "Alternate Hostnames must be same if roundrobin algo is used"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoSbLc(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoSbLc,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_source_to_least_conn(self):
+ """Test edit LB rule from source to least conn algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "source" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "source" algorithm to
+ # "leastconn" After the update, Verify that "leastconn"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with source algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True)
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_2 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ ssh_3 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'leastconn'))
+ lb_rule.update(self.apiclient, algorithm='leastconn')
+
+ self.debug(
+ "Removing virtual machine: %s to test least connection algo" %
+ self.vm_2.name)
+ lb_rule.remove(self.apiclient, [self.vm_2])
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_4 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_5 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_6 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_6.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+ self.assertNotEqual(
+ res.count(self.vm_2.name),
+ 1,
+ "SSH request should go to second VM(having least connections)"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
+
+
+class TestLbAlgoLcSb(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbAlgoLcSb,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.vm_1 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.vm_2 = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ # Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_lb_leastconn_to_source(self):
+ """Test edit LB rule from round robin to source algo
+ """
+
+ # Validate the following
+ # 1. Deploy the first VM using a network from the above created
+ # Network offering.
+ # 2. Deploy another VM.
+ # 3. Acquire Ip address and create an Lb rule for couple of Vms using
+ # "leastconn" algorithm. Make sure this algorithm is respected.
+ # 4. Edit this existing LB rule with "leastconn" algorithm to
+ # "Source" After the update, Verify that "Source"
+ # algorithm is applied when using this load balancing rule.
+
+ self.debug(
+ "Creating LB rule for IP address: %s with leastconn algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+
+ lb_rules = LoadBalancerRule.list(
+ self.apiclient,
+ id=lb_rule.id,
+ listall=True
+ )
+ self.assertEqual(
+ isinstance(lb_rules, list),
+ True,
+ "List LB rules should return a newly created LB rule"
+ )
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_1.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_1])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_1 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_1.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ ssh_2 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_2.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_3 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_3.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+ self.assertNotEqual(
+ res.count(self.vm_2.name),
+ 1,
+ "SSH request should go to second VM(having least connections)"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ self.debug(
+ "Updating LB rule: %s with new algorithm: %s" % (
+ lb_rule.name,
+ 'source'))
+ lb_rule.update(self.apiclient, algorithm='source')
+
+ self.debug(
+ "Removing virtual machine: %s to test source algo" %
+ self.vm_2.name)
+ lb_rule.remove(self.apiclient, [self.vm_2])
+
+ try:
+ self.debug(
+ "Verifying the algorithm used for LB by SSHing into instances")
+ hostnames = []
+ ssh_4 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress)
+ self.debug("Command: hostname")
+ result = ssh_4.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ self.debug("Adding %s to the LB rule %s" % (
+ self.vm_2.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.vm_2])
+
+ ssh_5 = self.vm_1.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_5.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+ self.debug("Hostnames: %s" % str(hostnames))
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+
+ ssh_6 = self.vm_2.get_ssh_client(
+ ipaddress=self.public_ip.ipaddress.ipaddress,
+ reconnect=True
+ )
+ self.debug("Command: hostname")
+ result = ssh_6.execute("hostname")
+ self.debug("Output: %s" % result)
+ hostnames.append(result)
+
+ res = str(result)
+
+ self.assertEqual(
+ res.count(self.vm_1.name),
+ 1,
+ "Request should be sent only to the first VM"
+ )
+ except Exception as e:
+ self.fail("Exception occured during SSH: %s - %s" % (
+ self.public_ip.ipaddress.ipaddress,
+ e))
+ return
diff --git a/test/integration/component/test_netscaler_lb_sticky.py b/test/integration/component/test_netscaler_lb_sticky.py
new file mode 100644
index 00000000000..75647951c8c
--- /dev/null
+++ b/test/integration/component/test_netscaler_lb_sticky.py
@@ -0,0 +1,1019 @@
+# -*- encoding: utf-8 -*-
+# 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.
+#
+# Automatically generated by addcopyright.py at 04/03/2012
+
+""" P1 tests for netscaler load balancing sticky policy
+"""
+#Import Local Modules
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from integration.lib.utils import *
+from integration.lib.base import *
+from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
+import datetime
+
+
+class Services:
+ """Test netscaler services
+ """
+
+ def __init__(self):
+ self.services = {
+ "account": {
+ "email": "test@test.com",
+ "firstname": "Test",
+ "lastname": "User",
+ "username": "test",
+ # Random characters are appended for unique
+ # username
+ "password": "password",
+ },
+ "service_offering": {
+ "name": "Tiny Instance",
+ "displaytext": "Tiny Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100, # in MHz
+ "memory": 64, # In MBs
+ },
+ "virtual_machine": {
+ "displayname": "TestVM",
+ "username": "root",
+ "password": "password",
+ "ssh_port": 22,
+ "hypervisor": 'XenServer',
+ "privateport": 22,
+ "publicport": 22,
+ "protocol": 'TCP',
+ },
+ "netscaler": {
+ "ipaddress": '10.147.40.100',
+ "username": 'nsroot',
+ "password": 'nsroot',
+ "networkdevicetype": 'NetscalerVPXLoadBalancer',
+ "publicinterface": '1/1',
+ "privateinterface": '1/1',
+ "numretries": 2,
+ "lbdevicededicated": False,
+ "lbdevicecapacity": 50,
+ "port": 22,
+ },
+ "network_offering": {
+ "name": 'Netscaler',
+ "displaytext": 'Netscaler',
+ "guestiptype": 'Isolated',
+ "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
+ "traffictype": 'GUEST',
+ "availability": 'Optional',
+ "serviceProviderList" : {
+ "Dhcp": 'VirtualRouter',
+ "Dns": 'VirtualRouter',
+ "SourceNat": 'VirtualRouter',
+ "PortForwarding": 'VirtualRouter',
+ "Vpn": 'VirtualRouter',
+ "Firewall": 'VirtualRouter',
+ "Lb": 'Netscaler',
+ "UserData": 'VirtualRouter',
+ "StaticNat": 'VirtualRouter',
+ },
+ },
+ "network": {
+ "name": "Netscaler",
+ "displaytext": "Netscaler",
+ },
+ "lbrule": {
+ "name": "SSH",
+ "alg": "roundrobin",
+ # Algorithm used for load balancing
+ "privateport": 22,
+ "publicport": 22,
+ "openfirewall": False,
+ },
+ "ostypeid": '2b58909b-7d9e-45d9-80d8-e58d0bbcbf07',
+ # Cent OS 5.3 (64 bit)
+ "sleep": 60,
+ "timeout": 10,
+ "mode":'advanced'
+ }
+
+
+class TestLbStickyPolicy(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.api_client = super(
+ TestLbStickyPolicy,
+ cls
+ ).getClsTestClient().getApiClient()
+ cls.services = Services().services
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.api_client, cls.services)
+ cls.zone = get_zone(cls.api_client, cls.services)
+ cls.template = get_template(
+ cls.api_client,
+ cls.zone.id,
+ cls.services["ostypeid"]
+ )
+
+ cls.network_offering = NetworkOffering.create(
+ cls.api_client,
+ cls.services["network_offering"],
+ conservemode=True
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.api_client, state='Enabled')
+ cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+ cls.services["virtual_machine"]["template"] = cls.template.id
+
+ cls.service_offering = ServiceOffering.create(
+ cls.api_client,
+ cls.services["service_offering"]
+ )
+ cls.account = Account.create(
+ cls.api_client,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+
+ # Creating network using the network offering created
+ cls.network = Network.create(
+ cls.api_client,
+ cls.services["network"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ networkofferingid=cls.network_offering.id,
+ zoneid=cls.zone.id
+ )
+
+ # Spawn an instance in that network
+ cls.virtual_machine = VirtualMachine.create(
+ cls.api_client,
+ cls.services["virtual_machine"],
+ accountid=cls.account.account.name,
+ domainid=cls.account.account.domainid,
+ serviceofferingid=cls.service_offering.id,
+ networkids=[str(cls.network.id)]
+ )
+ cls.public_ip = PublicIPAddress.create(
+ cls.api_client,
+ accountid=cls.account.account.name,
+ zoneid=cls.zone.id,
+ domainid=cls.account.account.domainid,
+ networkid=cls.network.id
+ )
+ cls._cleanup = [
+ cls.service_offering,
+ cls.account
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ #Cleanup resources used
+ cleanup_resources(cls.api_client, cls._cleanup)
+ interval = list_configurations(
+ cls.api_client,
+ name='network.gc.interval'
+ )
+ wait = list_configurations(
+ cls.api_client,
+ name='network.gc.wait'
+ )
+ # Sleep to ensure that all resources are deleted
+ time.sleep(int(interval[0].value) + int(wait[0].value))
+ cls.network_offering.delete(cls.api_client)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.dbclient = self.testClient.getDbConnection()
+ self.cleanup = []
+ return
+
+ def tearDown(self):
+ try:
+ self.debug("Cleaning up the resources")
+ #Clean up, terminate the created network offerings
+ cleanup_resources(self.apiclient, self.cleanup)
+ self.debug("Cleanup complete!")
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ def test_01_source_based_roundrobin(self):
+ """Test Create a "SourceBased" stick policy for a Lb rule with "RoundRobin" algorithm
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "SourceBased" stick policy for a Lb rule with
+ # "RoundRobin" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with round robin algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='SourceBased',
+ name='SourceBasedRR',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: SOURCEIP"),
+ 1,
+ "'SourceBased' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: ROUNDROBIN"),
+ 1,
+ "'ROUNDROBIN' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_02_source_based_source_algo(self):
+ """Test Create a "SourceBased" stick policy for a Lb rule with "Source" algorithm
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "SourceBased" stick policy for a Lb rule with
+ # "Source" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with source algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='SourceBased',
+ name='SourceBasedSource',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: SOURCEIP"),
+ 1,
+ "'SourceBased' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: SOURCEIPHASH"),
+ 1,
+ "'SOURCE' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_03_source_based_leastconn(self):
+ """Test Create a "SourceBased" stick policy for a Lb rule with leastconn algo
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "SourceBased" stick policy for a Lb rule with
+ # "leastconn" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with leastconn algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='SourceBased',
+ name='SourceBasedLeast',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: SOURCEIP"),
+ 1,
+ "'SourceBased' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: LEASTCONNECTION"),
+ 1,
+ "'leastconn' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_04_lbcookie_based_roundrobin(self):
+ """Test Create a "LBCookie" stick policy for a Lb rule with roundrobin algo
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "LBCookie" stick policy for a Lb rule with
+ # "roundrobin" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with roundrobin algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='LbCookie',
+ name='LbCookieRR',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: COOKIEINSERT"),
+ 1,
+ "'LBCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: ROUNDROBIN"),
+ 1,
+ "'ROUNDROBIN' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_05_lbcookie_source_algo(self):
+ """Test Create a "LBCookie" stick policy for a Lb rule with "Source" algorithm
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "LBCookie" stick policy for a Lb rule with
+ # "Source" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with source algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='LbCookie',
+ name='LbCookieSource',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: COOKIEINSERT"),
+ 1,
+ "'LbCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: SOURCEIPHASH"),
+ 1,
+ "'SOURCE' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_06_lbcookie_leastconn(self):
+ """Test Create a "LBCookie" stick policy for a Lb rule with leastconn algo
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "LBCookie" stick policy for a Lb rule with
+ # "leastconn" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with leastconn algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='LBCookie',
+ name='LbcookieLeastConn',
+ param={"holdtime": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: COOKIEINSERT"),
+ 1,
+ "'LbCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: LEASTCONNECTION"),
+ 1,
+ "'leastconn' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_07_appcookie_based_roundrobin(self):
+ """Test Create a "AppCookie" stick policy for a Lb rule with roundrobin algo
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "AppCookie" stick policy for a Lb rule with
+ # "roundrobin" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with roundrobin algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'roundrobin'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='AppCookie',
+ name='AppCookieRR',
+ param={"name": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: RULE"),
+ 1,
+ "'AppCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: ROUNDROBIN"),
+ 1,
+ "'ROUNDROBIN' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_08_appcookie_source_algo(self):
+ """Test Create a "AppCookie" stick policy for a Lb rule with "Source"
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "AppCookie" stick policy for a Lb rule with
+ # "Source" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with source algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'source'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='AppCookie',
+ name='AppCookieSource',
+ param={"name": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: RULE"),
+ 1,
+ "'AppCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: SOURCEIPHASH"),
+ 1,
+ "'SOURCE' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
+
+ def test_09_appcookie_leastconn(self):
+ """Test Create a "AppCookie" stick policy for a Lb rule with leastconn
+ """
+
+ # Validate the following
+ # 1. Configure Netscaler for load balancing.
+ # 2. Create a Network offering with LB services provided by Netscaler
+ # and all other services by VR.
+ # 3. Create a new account/user.
+ # 4. Deploy few VMs using a network from the above created Network
+ # offering.
+ # 5. Create a "AppCookie" stick policy for a Lb rule with
+ # "leastconn" algorithm
+
+ self.debug(
+ "Creating LB rule for IP address: %s with leastconn algo" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.services["lbrule"]["alg"] = 'leastconn'
+ self.services["lbrule"]["publicport"] = 80
+ self.services["lbrule"]["privateport"] = 80
+ lb_rule = LoadBalancerRule.create(
+ self.apiclient,
+ self.services["lbrule"],
+ ipaddressid=self.public_ip.ipaddress.id,
+ accountid=self.account.account.name,
+ networkid=self.network.id
+ )
+ self.cleanup.append(lb_rule)
+ self.debug("Created the load balancing rule for public IP: %s" %
+ self.public_ip.ipaddress.ipaddress)
+
+ self.debug("Assigning VM instance: %s to LB rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ lb_rule.assign(self.apiclient, [self.virtual_machine])
+ self.debug("Assigned VM instance: %s to lb rule: %s" % (
+ self.virtual_machine.name,
+ lb_rule.name
+ ))
+ self.debug(
+ "Configuring 'SourceBased' Sticky policy on lb rule: %s" %
+ lb_rule.name)
+ try:
+ result = lb_rule.createSticky(
+ self.apiclient,
+ methodname='AppCookie',
+ name='AppCookieLeastConn',
+ param={"name": 20}
+ )
+ self.debug("Response: %s" % result)
+ except Exception as e:
+ self.fail("Configure sticky policy failed with exception: %s" % e)
+
+ self.debug("SSH into Netscaler to check whether sticky policy configured properly or not?")
+ self.debug("SSH into netscaler: %s" %
+ self.services["netscaler"]["ipaddress"])
+ try:
+ ssh_client = remoteSSHClient(
+ self.services["netscaler"]["ipaddress"],
+ self.services["netscaler"]["port"],
+ self.services["netscaler"]["username"],
+ self.services["netscaler"]["password"],
+ )
+ cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % (
+ self.public_ip.ipaddress.ipaddress,
+ lb_rule.publicport)
+ self.debug("command: %s" % cmd)
+ res = ssh_client.execute(cmd)
+ result = str(res)
+ self.debug("Output: %s" % result)
+
+ self.assertEqual(
+ result.count("Persistence: RULE"),
+ 1,
+ "'AppCookie' sticky policy should be configured on NS"
+ )
+
+ self.assertEqual(
+ result.count("Configured Method: LEASTCONNECTION"),
+ 1,
+ "'leastconn' algorithm should be configured on NS"
+ )
+
+ except Exception as e:
+ self.fail("SSH Access failed for %s: %s" % \
+ (self.services["netscaler"]["ipaddress"], e))
+ return
diff --git a/test/integration/component/test_network_offering.py b/test/integration/component/test_network_offering.py
index 24e388c899e..50f17577871 100644
--- a/test/integration/component/test_network_offering.py
+++ b/test/integration/component/test_network_offering.py
@@ -21,7 +21,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
@@ -1576,7 +1576,7 @@ class TestNetworkUpgrade(cloudstackTestCase):
vpns = Vpn.list(
self.apiclient,
publicipid=src_nat.id,
- listall=True,
+ listall=True,
)
self.assertEqual(
diff --git a/test/integration/component/test_project_configs.py b/test/integration/component/test_project_configs.py
index d397d9d2a48..20e2f8af1ed 100644
--- a/test/integration/component/test_project_configs.py
+++ b/test/integration/component/test_project_configs.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py
index 5ecaa83accd..bbf6205c3a2 100644
--- a/test/integration/component/test_project_usage.py
+++ b/test/integration/component/test_project_usage.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
class Services:
diff --git a/test/integration/component/test_projects.py b/test/integration/component/test_projects.py
index e2167326db6..fd195436905 100644
--- a/test/integration/component/test_projects.py
+++ b/test/integration/component/test_projects.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
diff --git a/test/integration/component/test_routers.py b/test/integration/component/test_routers.py
index 7671e80f814..2b0ca7309e6 100644
--- a/test/integration/component/test_routers.py
+++ b/test/integration/component/test_routers.py
@@ -17,10 +17,10 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
#Import System modules
import time
@@ -77,6 +77,7 @@ class Services:
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
+ "protocol": 'TCP',
},
"fw_rule":{
"startport": 1,
diff --git a/test/integration/component/test_security_groups.py b/test/integration/component/test_security_groups.py
index 7e49d20446a..68074536f9e 100644
--- a/test/integration/component/test_security_groups.py
+++ b/test/integration/component/test_security_groups.py
@@ -18,10 +18,10 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
+from marvin.remoteSSHClient import remoteSSHClient
#Import System modules
import time
diff --git a/test/integration/component/test_snapshots.py b/test/integration/component/test_snapshots.py
index 8ab7ff7281e..05585b5ae68 100644
--- a/test/integration/component/test_snapshots.py
+++ b/test/integration/component/test_snapshots.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
class Services:
"""Test Snapshots Services
diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py
index ff41baecd77..1e37abda194 100644
--- a/test/integration/component/test_usage.py
+++ b/test/integration/component/test_usage.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
import datetime
class Services:
diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py
index a20770b2851..4caee7d170f 100644
--- a/test/integration/component/test_volumes.py
+++ b/test/integration/component/test_volumes.py
@@ -20,7 +20,7 @@ from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
#Import System modules
import os
import urllib
diff --git a/test/integration/lib/base.py b/test/integration/lib/base.py
index 1f8a2f851c0..04adbc9a030 100644
--- a/test/integration/lib/base.py
+++ b/test/integration/lib/base.py
@@ -598,7 +598,9 @@ class Template:
time.sleep(interval)
elif 'Installing' not in template.status:
- raise Exception("ErrorInDownload")
+ raise Exception(
+ "Error in downloading template: status - %s" %
+ template.status)
elif timeout == 0:
break
@@ -690,10 +692,12 @@ class Iso:
return
elif 'Downloaded' not in response.status and \
'Installing' not in response.status:
- raise Exception("ErrorInDownload")
+ raise Exception(
+ "Error In Downloading ISO: ISO Status - %s" %
+ response.status)
elif timeout == 0:
- raise Exception("TimeoutException")
+ raise Exception("ISO download Timeout Exception")
else:
timeout = timeout - 1
return
@@ -725,12 +729,12 @@ class PublicIPAddress:
if zoneid:
cmd.zoneid = zoneid
elif "zoneid" in services:
- services["zoneid"]
+ cmd.zoneid = services["zoneid"]
if domainid:
cmd.domainid = domainid
elif "domainid" in services:
- services["domainid"]
+ cmd.domainid = services["domainid"]
if networkid:
cmd.networkid = networkid
@@ -1140,7 +1144,7 @@ class LoadBalancerRule:
apiclient.removeFromLoadBalancerRule(cmd)
return
- def update(self, apiclient, algorithm=None, description=None, name=None):
+ def update(self, apiclient, algorithm=None, description=None, name=None, **kwargs):
"""Updates the load balancing rule"""
cmd = updateLoadBalancerRule.updateLoadBalancerRuleCmd()
cmd.id = self.id
@@ -1151,8 +1155,40 @@ class LoadBalancerRule:
if name:
cmd.name = name
+ [setattr(cmd, k, v) for k, v in kwargs.items()]
return apiclient.updateLoadBalancerRule(cmd)
+ def createSticky(self, apiclient, methodname, name, description=None, param=None):
+ """Creates a sticky policy for the LB rule"""
+
+ cmd = createLBStickinessPolicy.createLBStickinessPolicyCmd()
+ cmd.lbruleid = self.id
+ cmd.methodname = methodname
+ cmd.name = name
+ if description:
+ cmd.description = description
+ if param:
+ cmd.param = []
+ for name, value in param.items():
+ cmd.param.append({'name': name, 'value': value})
+ return apiclient.createLBStickinessPolicy(cmd)
+
+ def deleteSticky(self, apiclient, id):
+ """Deletes stickyness policy"""
+
+ cmd = deleteLBStickinessPolicy.deleteLBStickinessPolicyCmd()
+ cmd.id = id
+ return apiclient.deleteLBStickinessPolicy(cmd)
+
+ @classmethod
+ def listStickyPolicies(cls, apiclient, lbruleid, **kwargs):
+ """Lists stickiness policies for load balancing rule"""
+
+ cmd= listLBStickinessPolicies.listLBStickinessPoliciesCmd()
+ cmd.lbruleid = lbruleid
+ [setattr(cmd, k, v) for k, v in kwargs.items()]
+ return apiclient.listLBStickinessPolicies(cmd)
+
@classmethod
def list(cls, apiclient, **kwargs):
"""List all Load balancing rules matching criteria"""
@@ -1401,6 +1437,15 @@ class Network:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.updateNetwork(cmd))
+ def restart(self, apiclient, cleanup=None):
+ """Restarts the network"""
+
+ cmd = restartNetwork.restartNetworkCmd()
+ cmd.id = self.id
+ if cleanup:
+ cmd.cleanup = cleanup
+ return(apiclient.restartNetwork(cmd))
+
@classmethod
def list(cls, apiclient, **kwargs):
"""List all Networks matching criteria"""
diff --git a/test/integration/lib/common.py b/test/integration/lib/common.py
index 7740a2873d3..5a644aaf16a 100644
--- a/test/integration/lib/common.py
+++ b/test/integration/lib/common.py
@@ -18,7 +18,7 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
from utils import *
from base import *
@@ -103,12 +103,12 @@ def download_systemplates_sec_storage(server, services):
try:
# Login to management server
- ssh = remoteSSHClient.remoteSSHClient(
+ ssh = remoteSSHClient(
server["ipaddress"],
server["port"],
server["username"],
server["password"]
- )
+ )
except Exception:
raise Exception("SSH access failted for server with IP address: %s" %
server["ipaddess"])
diff --git a/test/integration/lib/utils.py b/test/integration/lib/utils.py
index 15e63e285ad..b623f6b503d 100644
--- a/test/integration/lib/utils.py
+++ b/test/integration/lib/utils.py
@@ -16,7 +16,7 @@
import marvin
import time
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
from marvin.cloudstackAPI import *
from marvin import cloudstackConnection
#from cloudstackConnection import cloudConnection
@@ -111,12 +111,7 @@ def is_server_ssh_ready(ipaddress, port, username, password, retries=50):
loop_cnt = retries
while True:
try:
- ssh = remoteSSHClient.remoteSSHClient(
- ipaddress,
- port,
- username,
- password
- )
+ ssh = remoteSSHClient(ipaddress, port, username, password)
except Exception as e:
if loop_cnt == 0:
raise e
@@ -158,12 +153,7 @@ def get_process_status(hostip, port, username, password, linklocalip, process):
"""Double hop and returns a process status"""
#SSH to the machine
- ssh = remoteSSHClient.remoteSSHClient(
- hostip,
- port,
- username,
- password
- )
+ ssh = remoteSSHClient(hostip, port, username, password)
ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
ssh_command = ssh_command + \
"-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % (
diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py
index 5938094884f..d61bbe1d69b 100644
--- a/test/integration/smoke/test_network.py
+++ b/test/integration/smoke/test_network.py
@@ -31,7 +31,7 @@ class Services:
def __init__(self):
self.services = {
- "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
+ "ostypeid": '1a568aed-db2d-41ca-b644-416b0bdc067e',
# Cent OS 5.3 (64 bit)
"mode": 'advanced',
# Networking mode: Basic or advanced
@@ -457,7 +457,7 @@ class TestPortForwarding(cloudstackTestCase):
"SSHing into VM with IP address %s after NAT rule deletion" %
self.virtual_machine.ipaddress)
- remoteSSHClient.remoteSSHClient(
+ remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.virtual_machine.ssh_port,
self.virtual_machine.username,
@@ -573,7 +573,7 @@ class TestPortForwarding(cloudstackTestCase):
"SSHing into VM with IP address %s after NAT rule deletion" %
self.virtual_machine.ipaddress)
- remoteSSHClient.remoteSSHClient(
+ remoteSSHClient(
ip_address.ipaddress.ipaddress,
self.virtual_machine.ssh_port,
self.virtual_machine.username,
@@ -778,7 +778,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
(self.vm_1.ipaddress, src_nat_ip_addr.ipaddress)
)
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -803,7 +803,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.vm_2.id
))
- ssh_2 = remoteSSHClient.remoteSSHClient(
+ ssh_2 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -836,7 +836,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.vm_2.id
))
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -859,7 +859,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
with self.assertRaises(Exception):
self.debug("Removed all VMs, trying to SSH")
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -969,7 +969,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.vm_1.id,
self.vm_2.id
))
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -988,7 +988,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.vm_1.id,
self.vm_2.id
))
- ssh_2 = remoteSSHClient.remoteSSHClient(
+ ssh_2 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -1016,7 +1016,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.non_src_nat_ip.ipaddress.ipaddress,
self.vm_2.id
))
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -1042,7 +1042,7 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.non_src_nat_ip.ipaddress.ipaddress,
self.vm_1.id
))
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
@@ -1195,7 +1195,7 @@ class TestRebootRouter(cloudstackTestCase):
try:
self.debug("SSH into VM (ID : %s ) after reboot" % self.vm_1.id)
- remoteSSHClient.remoteSSHClient(
+ remoteSSHClient(
self.nat_rule.ipaddress,
self.services["natrule"]["publicport"],
self.vm_1.username,
@@ -1273,7 +1273,7 @@ class TestAssignRemoveLB(cloudstackTestCase):
]
return
- def test_assign_and_removal_elb(self):
+ def test_assign_and_removal_lb(self):
"""Test for assign & removing load balancing rule"""
# Validate:
@@ -1347,7 +1347,7 @@ class TestAssignRemoveLB(cloudstackTestCase):
self.vm_2.id
))
#Create SSH client for each VM
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
@@ -1364,7 +1364,7 @@ class TestAssignRemoveLB(cloudstackTestCase):
self.vm_1.id,
self.vm_2.id
))
- ssh_2 = remoteSSHClient.remoteSSHClient(
+ ssh_2 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_2.username,
@@ -1406,7 +1406,7 @@ class TestAssignRemoveLB(cloudstackTestCase):
self.vm_1.id,
))
# Again make a SSH connection, as previous is not used after LB remove
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
@@ -1428,13 +1428,13 @@ class TestAssignRemoveLB(cloudstackTestCase):
lb_rule.assign(self.apiclient, [self.vm_3])
try:
- ssh_1 = remoteSSHClient.remoteSSHClient(
+ ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
self.vm_1.password
)
- ssh_3 = remoteSSHClient.remoteSSHClient(
+ ssh_3 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_3.username,
@@ -1599,7 +1599,7 @@ class TestReleaseIP(cloudstackTestCase):
# SSH Attempt though public IP should fail
with self.assertRaises(Exception):
- ssh_2 = remoteSSHClient.remoteSSHClient(
+ ssh_2 = remoteSSHClient(
self.ip_addr.ipaddress,
self.services["natrule"]["publicport"],
self.virtual_machine.username,
diff --git a/test/integration/smoke/test_routers.py b/test/integration/smoke/test_routers.py
index 603ca672571..8b60933cfe6 100644
--- a/test/integration/smoke/test_routers.py
+++ b/test/integration/smoke/test_routers.py
@@ -42,7 +42,7 @@ class Services:
{
"displayname": "Test VM",
"username": "root",
- "password": "fr3sca",
+ "password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
"privateport": 22,
@@ -54,9 +54,9 @@ class Services:
"firstname": "Test",
"lastname": "User",
"username": "testuser",
- "password": "fr3sca",
+ "password": "password",
},
- "ostypeid":'946b031b-0e10-4f4a-a3fc-d212ae2ea07f',
+ "ostypeid":'1a568aed-db2d-41ca-b644-416b0bdc067e',
"sleep": 60,
"timeout": 10,
"mode": 'advanced', #Networking mode: Basic, Advanced
@@ -152,7 +152,7 @@ class TestRouterServices(cloudstackTestCase):
zoneid=router.zoneid,
type='Routing',
state='Up',
- virtualmachineid=self.vm_1.id
+ id=router.hostid
)
self.assertEqual(
isinstance(hosts, list),
@@ -214,7 +214,7 @@ class TestRouterServices(cloudstackTestCase):
zoneid=router.zoneid,
type='Routing',
state='Up',
- virtualmachineid=self.vm_1.id
+ id=router.hostid
)
self.assertEqual(
isinstance(hosts, list),
@@ -400,7 +400,7 @@ class TestRouterServices(cloudstackTestCase):
zoneid=router.zoneid,
type='Routing',
state='Up',
- virtualmachineid=self.vm_1.id
+ id=router.hostid
)
self.assertEqual(
isinstance(hosts, list),
diff --git a/test/integration/smoke/test_secondary_storage.py b/test/integration/smoke/test_secondary_storage.py
index 9f60593aa9b..120c4fa0a8f 100644
--- a/test/integration/smoke/test_secondary_storage.py
+++ b/test/integration/smoke/test_secondary_storage.py
@@ -39,14 +39,6 @@ class Services:
"hypervisor": "XenServer",
"templatefilter": "self",
},
- 1: {
- "hypervisor": "KVM",
- "templatefilter": "self",
- },
- 2: {
- "hypervisor": "VMWare",
- "templatefilter": "self",
- },
},
"sleep": 60,
"timeout": 5,
@@ -89,6 +81,7 @@ class TestSecStorageServices(cloudstackTestCase):
raise Exception("Warning: Exception during cleanup : %s" % e)
return
+ @unittest.skip("do not add secondary storage")
def test_01_add_sec_storage(self):
"""Test secondary storage
"""
@@ -377,4 +370,4 @@ class TestSecStorageServices(cloudstackTestCase):
True,
"Check whether state of template is ready or not"
)
- return
\ No newline at end of file
+ return
diff --git a/test/integration/smoke/test_snapshots.py b/test/integration/smoke/test_snapshots.py
index 694e60e2b8f..91e65a41a0d 100644
--- a/test/integration/smoke/test_snapshots.py
+++ b/test/integration/smoke/test_snapshots.py
@@ -17,10 +17,10 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
+from marvin.remoteSSHClient import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
class Services:
diff --git a/test/integration/smoke/test_ssvm.py b/test/integration/smoke/test_ssvm.py
index f67d918f91f..0e341d5a74a 100644
--- a/test/integration/smoke/test_ssvm.py
+++ b/test/integration/smoke/test_ssvm.py
@@ -34,7 +34,7 @@ class Services:
self.services = {
"host": {
"username": 'root', # Credentials for SSH
- "password": 'fr3sca',
+ "password": 'password',
"publicport": 22,
},
"sleep": 60,
@@ -78,7 +78,6 @@ class TestSSVMs(cloudstackTestCase):
self.apiclient,
systemvmtype='secondarystoragevm',
state='Running',
- zoneid=self.zone.id
)
self.assertEqual(
isinstance(list_ssvm_response, list),
@@ -196,7 +195,6 @@ class TestSSVMs(cloudstackTestCase):
self.apiclient,
systemvmtype='consoleproxy',
state='Running',
- zoneid=self.zone.id
)
self.assertEqual(
isinstance(list_cpvm_response, list),
diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py
index 40d17665900..b125aa5c768 100644
--- a/test/integration/smoke/test_vm_life_cycle.py
+++ b/test/integration/smoke/test_vm_life_cycle.py
@@ -17,7 +17,7 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
-from marvin import remoteSSHClient
+from marvin.remoteSSHClient import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
@@ -42,7 +42,7 @@ class Services:
"username": "test",
# Random characters are appended in create account to
# ensure unique username generated each time
- "password": "fr3sca",
+ "password": "password",
},
"small":
# Create a small virtual machine instance with disk offering
@@ -84,7 +84,7 @@ class Services:
"name": "Small Instance",
"displaytext": "Small Instance",
"cpunumber": 1,
- "cpuspeed": 500,
+ "cpuspeed": 100,
"memory": 256
},
"medium":
@@ -94,17 +94,17 @@ class Services:
"name": "Medium Instance",
"displaytext": "Medium Instance",
"cpunumber": 1,
- "cpuspeed": 1000,
- "memory": 1024
+ "cpuspeed": 100,
+ "memory": 256
}
},
"iso": # ISO settings for Attach/Detach ISO tests
{
"displaytext": "Test ISO",
"name": "testISO",
- "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
+ "url": "http://nfs1.lab.vmops.com/isos_32bit/dsl-4.4.10.iso",
# Source URL where ISO is located
- "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
+ "ostypeid": '1a568aed-db2d-41ca-b644-416b0bdc067e',
"mode": 'HTTP_DOWNLOAD', # Downloading existing ISO
},
"template": {
@@ -118,7 +118,7 @@ class Services:
"sleep": 60,
"timeout": 10,
#Migrate VM to hostid
- "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
+ "ostypeid": '1a568aed-db2d-41ca-b644-416b0bdc067e',
# CentOS 5.3 (64-bit)
"mode":'advanced',
}
@@ -751,18 +751,15 @@ class TestVMLifeCycle(cloudstackTestCase):
True,
"Check the number of hosts in the zone"
)
- self.assertEqual(
+ self.assertGreaterEqual(
len(hosts),
2,
"Atleast 2 hosts should be present in a zone for VM migration"
)
+ # Remove the host of current VM from the hosts list
+ hosts[:] = [host for host in hosts if host.id != self.medium_virtual_machine.hostid]
- # Find the host of VM and also the new host to migrate VM.
- if self.medium_virtual_machine.hostid == hosts[0].id:
- host = hosts[1]
- else:
- host = hosts[0]
-
+ host = hosts[0]
self.debug("Migrating VM-ID: %s to Host: %s" % (
self.medium_virtual_machine.id,
host.id
diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py
index 7ea16837c26..f6b5e79db90 100644
--- a/test/integration/smoke/test_volumes.py
+++ b/test/integration/smoke/test_volumes.py
@@ -17,10 +17,10 @@
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
+from marvin.remoteSSHClient import remoteSSHClient
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
-from marvin import remoteSSHClient
#Import System modules
import os
import urllib
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index c365684a4bb..5e2c640de06 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -3024,7 +3024,7 @@ Dialogs*/
display: block;
width: 119px;
text-align: right;
- font-size: 13px;
+ font-size: 12px;
margin-top: 2px;
}
diff --git a/ui/index.jsp b/ui/index.jsp
index 3414a8699d6..d36b019c922 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1583,7 +1583,6 @@
-
@@ -1652,6 +1651,7 @@