diff --git a/test/integration/smoke/test_internal_lb.py b/test/integration/smoke/test_internal_lb.py index 174782f5a766..da845ea767f6 100644 --- a/test/integration/smoke/test_internal_lb.py +++ b/test/integration/smoke/test_internal_lb.py @@ -16,63 +16,303 @@ # under the License. """ Tests for configuring Internal Load Balancing Rules. """ -#Import Local Modules -from marvin.codes import FAILED -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.lib.utils import * -from marvin.lib.base import * -from marvin.lib.common import * +# Import Local Modules +from marvin.codes import PASS, FAILED +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import (cleanup_resources, + get_process_status) +from marvin.lib.base import (Domain, + Account, + Configurations, + VPC, + VpcOffering, + ServiceOffering, + NetworkOffering, + Network, + PublicIPAddress, + NATRule, + NetworkACL, + LoadBalancerRule, + ApplicationLoadBalancer, + VirtualMachine, + Template, + FireWallRule, + StaticNATRule, + NetworkACLList + ) + +from marvin.sshClient import SshClient + + +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_network_offerings) + from nose.plugins.attrib import attr +import logging +import time +import math + + +class Services: + + """Test VPC network services - Port Forwarding Rules Test Data Class. + """ + + 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", + }, + "host1": None, + "host2": None, + "default_hypervisor": "kvm", + "compute_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "network_offering": { + "name": 'VPC Network offering', + "displaytext": 'VPC Network', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,Lb,PortForwarding,UserData,StaticNat,NetworkACL', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' + }, + }, + "network_offering_internal_lb": { + "name": 'VPC Network Internal Lb offering', + "displaytext": 'VPC Network internal lb', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL,Lb', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "serviceCapabilityList": { + "Lb": { + "SupportedLbIsolation": 'dedicated', + "lbSchemes": 'internal' + } + }, + "serviceProviderList": { + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter', + "Lb": 'InternalLbVm' + }, + "egress_policy": "true", + }, + "vpc_offering": { + "name": 'Redundant VPC off', + "displaytext": 'Redundant VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' + }, + "serviceCapabilityList": { + "SourceNat": { + "RedundantRouter": 'true' + } + }, + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.1.0.0/16' + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0' + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 2222, + "openfirewall": False, + "startport": 22, + "endport": 2222, + "protocol": "TCP", + "cidrlist": '0.0.0.0/0', + }, + "lbrule_http": { + "name": "HTTP", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 80, + "publicport": 80, + "openfirewall": False, + "startport": 80, + "endport": 80, + "protocol": "TCP", + "cidrlist": '0.0.0.0/0', + }, + "natrule": { + "protocol": "TCP", + "cidrlist": '0.0.0.0/0', + }, + "http_rule": { + "privateport": 80, + "publicport": 80, + "startport": 80, + "endport": 80, + "cidrlist": '0.0.0.0/0', + "protocol": "TCP" + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "template_kvm": { + "name": "tiny-kvm", + "displaytext": "macchinina kvm", + "format": "qcow2", + "hypervisor": "kvm", + "ostype": "Other PV (64-bit)", + "url": "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-kvm.qcow2.bz2", + "requireshvm": "True", + }, + "template_xen": { + "name": "tiny-xen", + "displaytext": "macchinina xen", + "format": "vhd", + "hypervisor": "xen", + "ostype": "Other (64-bit)", + "url": "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-xen.vhd.bz2", + "requireshvm": "True", + }, + } + + class TestInternalLb(cloudstackTestCase): + """Test Internal LB """ @classmethod def setUpClass(cls): + + cls.logger = logging.getLogger('TestInternalLb') + cls.stream_handler = logging.StreamHandler() + cls.logger.setLevel(logging.DEBUG) + cls.logger.addHandler(cls.stream_handler) + testClient = super(TestInternalLb, cls).getClsTestClient() cls.apiclient = testClient.getApiClient() - cls.services = testClient.getParsedTestDataConfig() + cls.services = Services().services cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.domain = get_domain(cls.apiclient) - cls.service_offering = ServiceOffering.create( + cls.compute_offering = ServiceOffering.create( cls.apiclient, - cls.services["service_offerings"]["tiny"] - ) - cls.account = Account.create(cls.apiclient, services=cls.services["account"]) - cls.template = get_template( - cls.apiclient, - cls.zone.id, - cls.services["ostype"] + cls.services["compute_offering"] ) + cls.account = Account.create( + cls.apiclient, services=cls.services["account"]) + + if cls.services["default_hypervisor"] == "kvm": + cls.template = Template.register(cls.apiclient, cls.services["template_kvm"], cls.zone.id, hypervisor=cls.services[ + "template_kvm"]["hypervisor"], account=cls.account.name, domainid=cls.domain.id) + else: + cls.template = Template.register(cls.apiclient, cls.services["template_xen"], cls.zone.id, hypervisor=cls.services[ + "template_xen"]["hypervisor"], account=cls.account.name, domainid=cls.domain.id) + if cls.template == FAILED: - assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] + assert False, "get_template() failed to return template" - cls.debug("Successfully created account: %s, id: \ - %s" % (cls.account.name,\ + cls.logger.debug("Successfully created account: %s, id: \ + %s" % (cls.account.name, cls.account.id)) + cls.cleanup = [cls.account] + return - @attr(tags=["smoke", "advanced"], required_hardware="true") - def test_internallb(self): - """Test create, delete, assign, remove of internal loadbalancer - """ - #1) Create and enable network offering with Internal Lb vm service - self.networkOffering = NetworkOffering.create(self.apiclient, self.services["network_offering_internal_lb"], conservemode=False) - #TODO: SIMENH:modify this test to verify lb rules by sending request from another tier - self.networkOffering.update(self.apiclient, state="Enabled") - - #2) Create VPC and network in it - vpcOffering = VpcOffering.list(self.apiclient,isdefault=True) - self.assert_(vpcOffering is not None and len(vpcOffering)>0, "No VPC offerings found") - self.services["vpc"] = {} - self.services["vpc"]["name"] = "vpc-internallb" - self.services["vpc"]["displaytext"] = "vpc-internallb" - self.services["vpc"]["cidr"] = "10.1.1.0/24" - vpc = VPC.create( + def get_networkoffering_state(self, offering): + result = list_network_offerings(self.apiclient, id=offering.id) + if result: + offering = result[0] + return offering.state + else: + return None + + def create_and_enable_network_serviceoffering(self, services): + + try: + # Create offering + offering = NetworkOffering.create( + self.apiclient, services, conservemode=False) + + self.assertIsNotNone(offering, "Failed to create network offering") + self.logger.debug("Created network offering: %s" % offering.id) + + if offering: + # Enable offeringq + offering.update(self.apiclient, state="Enabled") + self.assertEqual(self.get_networkoffering_state( + offering), "Enabled", "Failed to enable network offering") + + self.logger.debug("Enabled network offering: %s" % offering.id) + return offering + + except Exception as e: + self.fail("Failed to create and enable network offering: %s because of %s" % ( + offering_name, e)) + + def create_vpc(self, name, cidr): + print name, cidr + try: + vpcOffering = VpcOffering.list(self.apiclient, isdefault=True) + self.assert_(vpcOffering is not None and len( + vpcOffering) > 0, "No VPC offerings found") + + self.services["vpc"] = {} + self.services["vpc"]["name"] = name + self.services["vpc"]["displaytext"] = name + self.services["vpc"]["cidr"] = cidr + + vpc = VPC.create( apiclient=self.apiclient, services=self.services["vpc"], networkDomain="vpc.internallb", @@ -80,61 +320,425 @@ def test_internallb(self): zoneid=self.zone.id, account=self.account.name, domainid=self.domain.id - ) - self.assert_(vpc is not None, "VPC creation failed") - self.services["vpcnetwork"] = {} - self.services["vpcnetwork"]["name"] = "vpcntwk" - self.services["vpcnetwork"]["displaytext"] = "vpcntwk" - ntwk = Network.create( - apiclient=self.apiclient, - services=self.services["vpcnetwork"], + ) + self.assertIsNotNone(vpc, "VPC creation failed") + self.logger.debug("Created VPC %s" % vpc.id) + return vpc + + except Exception as e: + self.fail("Failed to create VPC: %s due to %s" % (name, e)) + + def create_network_tier(self, name, vpcid, gateway, network_offering): + self.services["network"]["name"] = name + self.services["network"]["displaytext"] = name + + default_acl = NetworkACLList.list(self.apiclient, name="default_allow")[0] + + try: + network = Network.create( + apiclient=self.apiclient, + services=self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offering.id, + zoneid=self.zone.id, + vpcid=vpcid, + gateway=gateway, + netmask=self.services["network"]["netmask"], + aclid=default_acl.id + ) + self.assertIsNotNone(network, "Network failed to create") + self.logger.debug( + "Created network %s in VPC %s" % (network.id, vpcid)) + + return network + + except Exception as e: + raise Exception("Create network failed: %s" % e) + + def deployvm_in_network(self, vpc, networkid): + + try: + self.services["virtual_machine"]["networkids"] = networkid + vm = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"], + templateid=self.template.id, + zoneid=self.zone.id, + accountid=self.account.name, + domainid=self.domain.id, + serviceofferingid=self.compute_offering.id, + hypervisor=self.services[ + "template_kvm"]["hypervisor"] + ) + self.assertIsNotNone( + vm, "Failed to deploy vm in network: %s" % networkid) + self.assert_(vm.state == 'Running', "VM is not running") + self.logger.debug("Deployed VM id: %s in VPC %s" % (vm.id, vpc.id)) + + return vm + + except Exception as e: + raise Exception("Deployment failed of VM: %s" % e) + + def create_internal_loadbalancer(self, intport, sport, algorithm, networkid): + try: + # 5) Create an Internal Load Balancer + applb = ApplicationLoadBalancer.create(self.apiclient, services=self.services, + name="lbrule", + sourceport=sport, + instanceport=intport, + algorithm=algorithm, + scheme="Internal", + sourcenetworkid=networkid, + networkid=networkid + ) + + self.assertIsNotNone(applb, "Failed to create loadbalancer") + self.logger.debug("Created LB %s in VPC" % applb.id) + + return applb + + except Exception as e: + self.fail(e) + + def acquire_publicip(self, vpc, network): + self.logger.debug( + "Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, accountid=self.account.name, - domainid=self.domain.id, - networkofferingid=self.networkOffering.id, zoneid=self.zone.id, - vpcid=vpc.id, - gateway="10.1.1.1", - netmask="255.255.255.192" + domainid=self.account.domainid, + networkid=network.id, + vpcid=vpc.id ) - self.assertIsNotNone(ntwk, "Network failed to create") - self.debug("Network %s created in VPC %s" %(ntwk.id, vpc.id)) + self.assertIsNotNone(public_ip, "Failed to acquire public IP") + self.logger.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + return public_ip - #3) Deploy a vm - self.services["virtual_machine"]["networkids"] = ntwk.id - vm = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"], - templateid=self.template.id, - zoneid=self.zone.id, - accountid=self.account.name, - domainid= self.domain.id, - serviceofferingid=self.service_offering.id, + def create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None): + self.logger.debug("Creating NAT rule in network for vm with public IP") + if not services: + self.services["natrule"]["privateport"] = private_port + self.services["natrule"]["publicport"] = public_port + self.services["natrule"]["startport"] = public_port + self.services["natrule"]["endport"] = public_port + services = self.services["natrule"] + + nat_rule = NATRule.create( + apiclient=self.apiclient, + services=services, + ipaddressid=public_ip.ipaddress.id, + virtual_machine=vm, + networkid=network.id ) - self.assert_(vm is not None, "VM failed to deploy") - self.assert_(vm.state == 'Running', "VM is not running") - self.debug("VM %s deployed in VPC %s" %(vm.id, vpc.id)) - - #4) Create an Internal Load Balancer - applb = ApplicationLoadBalancer.create(self.apiclient, services=self.services, - name="lbrule", - sourceport=22, - instanceport=22, - algorithm="roundrobin", - scheme="internal", - sourcenetworkid=ntwk.id, - networkid=ntwk.id) - - #5) Assign the VM to the Internal Load Balancer - applb.assign(self.apiclient, vms=[vm]) - - #6) Remove the vm from the Interanl Load Balancer - applb.remove(self.apiclient, vms=[vm]) - - #7) Delete the Load Balancer + self.assertIsNotNone( + nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress) + self.logger.debug( + "Adding NetworkACL rules to make NAT rule accessible") + + vm.ssh_ip = nat_rule.ipaddress + vm.public_ip = nat_rule.ipaddress + vm.public_port = int(public_port) + return nat_rule + + def get_ssh_client(self, vm, retries): + """ Setup ssh client connection and return connection + vm requires attributes public_ip, public_port, username, password """ + + try: + ssh_client = SshClient( + vm.public_ip, + vm.public_port, + vm.username, + vm.password, + retries + ) + except Exception as e: + self.fail("Unable to create ssh connection: " % e) + + self.assertIsNotNone( + ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (vm.name, vm.public_ip)) + return ssh_client + + def setup_http_daemon(self, vm): + """ Creates a index.html in /tmp with private ip as content and + starts httpd daemon on all interfaces port 80 serving /tmp/ + (only tested on the busybox based tiny vm) + vm requires attributes public_ip, public_port, username, password + """ + commands = [ + # using ip address instead of hostname + "/sbin/ip addr show eth0 |grep 'inet '| cut -f6 -d' ' > /tmp/index.html", + "/usr/sbin/httpd -v -p 0.0.0.0:80 -h /tmp/" + ] + try: + ssh_client = self.get_ssh_client(vm, 8) + for cmd in commands: + ssh_client.execute(cmd) + except Exception as e: + self.fail("Failed to ssh into vm: %s due to %s" % (vm, e)) + + def run_ssh_test_accross_hosts(self, clienthost, lb_address, max_requests=30): + """ Uses clienthost to run wgets on hosts port 80 expects a unique output from url. + returns a list of outputs to evaluate. + """ + # Setup ssh connection + ssh_client = self.get_ssh_client(clienthost, 8) + self.logger.debug(ssh_client) + results = [] + + try: + for x in range(0, max_requests): + cmd_test_http = "/usr/bin/wget -T2 -qO- http://" + \ + lb_address + "/ 2>/dev/null" + # self.debug( "SSH into VM public address: %s and port: %s" + # %(.public_ip, vm.public_port)) + results.append(ssh_client.execute(cmd_test_http)[0]) + self.logger.debug(results) + + except Exception as e: + self.fail("%s: SSH failed for VM with IP Address: %s" % + (e, clienthost.public_ip)) + + return results + + def get_std_deviation(self, data): + """ Calculates and outputs a mean, variance and standard deviation from an input list of values """ + num_val = len(data) + mean = sum(data) / num_val + sqrt = map(lambda x: math.pow(abs(x - mean), 2), data) + variance = (sum(sqrt) / num_val - 1) + stddev = math.sqrt(variance) + return (mean, variance, stddev) + + def evaluate_http_responses(self, responses, algorithm): + """ Evaluates response values from http test and verifies algorithm used""" + if algorithm == 'roundrobin': + # get a list of unique values + unique_values = set(responses) + # count the occurence of each value in the responses + dataset = [responses.count(value) for value in unique_values] + + if len(set(dataset)) == 1: + # all values in dataset are equal, perfect result distribution + # woohoo! + self.logger.debug( + "HTTP responses are evenly distributed! SUCCESS!") + return True + else: + # calculate mean, var, stddev on dataset + mean, variance, stddev = self.get_std_deviation(dataset) + for value in dataset: + # determine how much value difference is there from the + # mean + difference = abs(value - mean) + # difference between response count of a host and the mean + # should be less than the standard deviation + self.assertLess( + difference, stddev, "Internal LB RoundRobin test Failed because http responsest are not evenly distributed") + self.logger.debug( + "Response distribution count: %d difference to mean: %d within standard deviation: %d" % (value, mean, stddev)) + return True + + @attr(tags=["smoke", "advanced"], required_hardware="true") + def test_01_internallb_roundrobin_1VPC_3VM_HTTP_port80(self): + """Test create, assign, remove of an Internal LB with roundrobin http traffic to 3 vm's + """ + max_http_requests = 30 + algorithm = "roundrobin" + public_lb_port = 80 + private_http_port = 80 + public_ssh_start_port = 2000 + num_app_vms = 3 + + self.logger.debug("Starting test_01_internallb_roundrobin_1VPC_3VM_HTTP_port80") + # Create and enable network offerings + network_offering_guestnet = self.create_and_enable_network_serviceoffering( + self.services["network_offering"]) + network_offering_intlb = self.create_and_enable_network_serviceoffering( + self.services["network_offering_internal_lb"]) + + # Create VPC + vpc = self.create_vpc("vpc_intlb_test01", "10.1.0.0/16") + + # Create network tiers + network_guestnet = self.create_network_tier( + "guestnet_test01", vpc.id, "10.1.1.1", network_offering_guestnet) + network_internal_lb = self.create_network_tier( + "intlb_test01", vpc.id, "10.1.2.1", network_offering_intlb) + + # Create 1 lb client vm in guestnet network tier + client_vm = self.deployvm_in_network(vpc, network_guestnet.id) + + # Create X app vm's in internal lb network tier + app_vms = [] + for x in range(0, num_app_vms): + vm = None + vm = self.deployvm_in_network(vpc, network_internal_lb.id) + app_vms.append(vm) + + # Acquire public ip to access guestnet app vms + guestnet_public_ip = self.acquire_publicip(vpc, network_guestnet) + intlb_public_ip = self.acquire_publicip(vpc, network_internal_lb) + + # Create nat rule to access client vm + self.create_natrule(vpc, client_vm, public_ssh_start_port, 22, guestnet_public_ip, network_guestnet) + + # Create nat rule to access app vms directly and start a http daemon on + # the vm + public_port = public_ssh_start_port + 1 + for vm in app_vms: + self.create_natrule(vpc, vm, public_port, 22, intlb_public_ip, network_internal_lb) + public_port += 1 + time.sleep(10) + # start http daemon on vm's + self.setup_http_daemon(vm) + + # Create a internal loadbalancer in the internal lb network tier + applb = self.create_internal_loadbalancer( private_http_port, public_lb_port, algorithm, network_internal_lb.id) + # wait for the loadbalancer to boot and be configured + time.sleep(10) + # Assign the 2 VMs to the Internal Load Balancer + self.logger.debug("Assigning virtual machines to LB: %s" % applb.id) + try: + applb.assign(self.apiclient, vms=app_vms) + except Exception as e: + self.fail( + "Failed to assign virtual machine(s) to loadbalancer: %s" % e) + + time.sleep(120) + # self.logger.debug(dir(applb)) + results = self.run_ssh_test_accross_hosts( + client_vm, applb.sourceipaddress, max_http_requests) + success = self.evaluate_http_responses(results, algorithm) + self.assertTrue(success, "Test failed on algorithm: %s" % algorithm) + + self.logger.debug( + "Removing virtual machines and networks for test_01_internallb_roundrobin_2VM_port80") + + # Remove the virtual machines from the Internal LoadBalancer + self.logger.debug("Remove virtual machines from LB: %s" % applb.id) + applb.remove(self.apiclient, vms=app_vms) + + # Remove the Load Balancer + self.logger.debug("Deleting LB: %s" % applb.id) applb.delete(self.apiclient) + def get_lb_stats_settings(self): + self.logger.debug("Retrieving haproxy stats settings") + settings = {} + try: + settings["stats_port"] = Configurations.list( + self.apiclient, name="network.loadbalancer.haproxy.stats.port")[0].value + settings["stats_uri"] = Configurations.list( + self.apiclient, name="network.loadbalancer.haproxy.stats.uri")[0].value + settings["username"], settings["password"] = Configurations.list( + self.apiclient, name="network.loadbalancer.haproxy.stats.auth")[0].value.split(":") + settings["visibility"] = Configurations.list( + self.apiclient, name="network.loadbalancer.haproxy.stats.visibility")[0].value + self.logger.debug(settings) + except Exception as e: + self.fail("Failed to retrieve stats settings " % e) + + return settings + + def verify_lb_stats(self, stats_ip, ssh_client, settings): + + word_to_verify = "uptime" + + url = "http://" + stats_ip + ":" + \ + settings["stats_port"] + settings["stats_uri"] + get_contents = "/usr/bin/wget -T3 -qO- --user=" + \ + settings["username"] + " --password=" + \ + settings["password"] + " " + url + try: + self.logger.debug( + "Trying to connect to the haproxy stats url %s" % url) + result = ssh_client.execute(get_contents) + except Exception as e: + self.fail("Failed to verify admin stats url %s from: %s" % + (url, ssh_client)) + finally: + del ssh_client + + found = any(word_to_verify in word for word in result) + + if found: + return True + else: + return False + + @attr(tags=["smoke", "advanced"], required_hardware="true") + def test02_internallb_haproxy_stats_on_all_interfaces(self): + """ Test to verify access to loadbalancer haproxy admin stats page + when global setting network.loadbalancer.haproxy.stats.visibility is set to 'all' + with credentials from global setting network.loadbalancer.haproxy.stats.auth + using the uri from global setting network.loadbalancer.haproxy.stats.uri""" + + self.logger.debug( + "Starting test_02_internallb_haproxy_stats_on_all_interfaces") + + settings = self.get_lb_stats_settings() + + dummy_port = 90 + network_gw = "10.1.2.1" + default_visibility = "global" + + # Update global setting if it is not set to our test default + if settings["visibility"] != default_visibility: + config_update = Configurations.update( + self.apiclient, "network.loadbalancer.haproxy.stats.visibility", default_visibility) + self.logger.debug( + "Updated global setting stats haproxy.stats.visibility to %s" % (default_visibility)) + settings = self.get_lb_stats_settings() + + # Create and enable network offering + network_offering_intlb = self.create_and_enable_network_serviceoffering( + self.services["network_offering_internal_lb"]) + + # Create VPC + vpc = self.create_vpc("vpc_intlb_test_02", "10.1.0.0/16") + + # Create network tier with internal lb service enabled + network_internal_lb = self.create_network_tier( + "intlb_test02", vpc.id, network_gw, network_offering_intlb) + + # Create 1 lb vm in internal lb network tier + vm = self.deployvm_in_network(vpc, network_internal_lb.id) + + # Acquire 1 public ip and attach to the internal lb network tier + public_ip = self.acquire_publicip(vpc, network_internal_lb) + + # Create an internal loadbalancer in the internal lb network tier + applb = self.create_internal_loadbalancer( + dummy_port, dummy_port, "leastconn", network_internal_lb.id) + + # Assign the 1 VM to the Internal Load Balancer + self.logger.debug("Assigning virtual machines to LB: %s" % applb.id) + try: + applb.assign(self.apiclient, vms=[vm]) + except Exception as e: + self.fail( + "Failed to assign virtual machine(s) to loadbalancer: %s" % e) + + # Create nat rule to access client vm + self.create_natrule( + vpc, vm, "22", "22", public_ip, network_internal_lb) + + # Verify access to and the contents of the admin stats page on the + # private address via a vm in the internal lb tier + stats = self.verify_lb_stats( + applb.sourceipaddress, self.get_ssh_client(vm, 4), settings) + self.assertTrue(stats, "Failed to verify LB HAProxy stats") + @classmethod def tearDownClass(cls): try: + cls.logger.debug("Cleaning up testcase resources") cleanup_resources(cls.apiclient, cls.cleanup) - except Exception, e: - raise Exception("Cleanup failed with %s" % e) + except Exception as e: + raise Exception("Cleanup failed with %s" % e)