From c2e585ae4cdc90162e0e0e9921731eb9ad7dddb8 Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Mon, 3 Feb 2020 09:34:13 +0100 Subject: [PATCH 1/3] octavia: Move LB creation API calls to helper --- zaza/openstack/charm_tests/octavia/tests.py | 213 ++++++++++---------- 1 file changed, 112 insertions(+), 101 deletions(-) diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index c022b02..c3786f4 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -47,6 +47,115 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): """Run class setup for running LBaaSv2 service tests.""" super(LBAASv2Test, cls).setUpClass() + @staticmethod + @tenacity.retry(wait=tenacity.wait_fixed(1), + reraise=True, stop=tenacity.stop_after_delay(900)) + def wait_for_lb_resource(octavia_show_func, resource_id, + operating_status=None): + """Wait for loadbalancer resource to reach expected status.""" + resp = octavia_show_func(resource_id) + logging.info(resp['provisioning_status']) + assert resp['provisioning_status'] == 'ACTIVE', ( + 'load balancer resource has not reached ' + 'expected provisioning status: {}' + .format(resp)) + if operating_status: + logging.info(resp['operating_status']) + assert resp['operating_status'] == operating_status, ( + 'load balancer resource has not reached ' + 'expected operating status: {}'.format(resp)) + + return resp + + def _create_lb_resources(self, octavia_client, provider, vip_subnet_id, + member_subnet_id, payload_ips): + result = octavia_client.load_balancer_create( + json={ + 'loadbalancer': { + 'description': 'Created by Zaza', + 'admin_state_up': True, + 'vip_subnet_id': vip_subnet_id, + 'name': 'zaza-lb-0', + }}) + lb = result['loadbalancer'] + lb_id = lb['id'] + + logging.info('Awaiting loadbalancer to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource( + octavia_client.load_balancer_show, lb_id) + logging.info(resp) + + result = octavia_client.listener_create( + json={ + 'listener': { + 'loadbalancer_id': lb_id, + 'name': 'listener1', + 'protocol': 'HTTP', + 'protocol_port': 80 + }, + }) + listener_id = result['listener']['id'] + logging.info('Awaiting listener to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource( + octavia_client.listener_show, listener_id) + logging.info(resp) + + result = octavia_client.pool_create( + json={ + 'pool': { + 'listener_id': listener_id, + 'name': 'pool1', + 'lb_algorithm': 'ROUND_ROBIN', + 'protocol': 'HTTP', + }, + }) + pool_id = result['pool']['id'] + logging.info('Awaiting pool to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource(octavia_client.pool_show, pool_id) + logging.info(resp) + + result = octavia_client.health_monitor_create( + json={ + 'healthmonitor': { + 'pool_id': pool_id, + 'delay': 5, + 'max_retries': 4, + 'timeout': 10, + 'type': 'HTTP', + 'url_path': '/', + }, + }) + healthmonitor_id = result['healthmonitor']['id'] + logging.info('Awaiting healthmonitor to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource(octavia_client.health_monitor_show, + healthmonitor_id) + logging.info(resp) + + for ip in payload_ips: + result = octavia_client.member_create( + pool_id=pool_id, + json={ + 'member': { + 'subnet_id': member_subnet_id, + 'address': ip, + 'protocol_port': 80, + }, + }) + member_id = result['member']['id'] + logging.info('Awaiting member to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource( + lambda x: octavia_client.member_show( + pool_id=pool_id, member_id=x), + member_id, + operating_status='ONLINE') + logging.info(resp) + return lb + def test_create_loadbalancer(self): """Create load balancer.""" keystone_session = openstack_utils.get_overcloud_keystone_session() @@ -70,109 +179,11 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): vip_subnet_id = subnet_id octavia_client = openstack_utils.get_octavia_session_client( keystone_session) - result = octavia_client.load_balancer_create( - json={ - 'loadbalancer': { - 'description': 'Created by Zaza', - 'admin_state_up': True, - 'vip_subnet_id': vip_subnet_id, - 'name': 'zaza-lb-0', - }}) - lb_id = result['loadbalancer']['id'] - lb_vip_port_id = result['loadbalancer']['vip_port_id'] - - @tenacity.retry(wait=tenacity.wait_fixed(1), - reraise=True, stop=tenacity.stop_after_delay(900)) - def wait_for_lb_resource(octavia_show_func, resource_id, - operating_status=None): - resp = octavia_show_func(resource_id) - logging.info(resp['provisioning_status']) - assert resp['provisioning_status'] == 'ACTIVE', ( - 'load balancer resource has not reached ' - 'expected provisioning status: {}' - .format(resp)) - if operating_status: - logging.info(resp['operating_status']) - assert resp['operating_status'] == operating_status, ( - 'load balancer resource has not reached ' - 'expected operating status: {}'.format(resp)) - - return resp - logging.info('Awaiting loadbalancer to reach provisioning_status ' - '"ACTIVE"') - resp = wait_for_lb_resource(octavia_client.load_balancer_show, lb_id) - logging.info(resp) - - result = octavia_client.listener_create( - json={ - 'listener': { - 'loadbalancer_id': lb_id, - 'name': 'listener1', - 'protocol': 'HTTP', - 'protocol_port': 80 - }, - }) - listener_id = result['listener']['id'] - logging.info('Awaiting listener to reach provisioning_status ' - '"ACTIVE"') - resp = wait_for_lb_resource(octavia_client.listener_show, listener_id) - logging.info(resp) - - result = octavia_client.pool_create( - json={ - 'pool': { - 'listener_id': listener_id, - 'name': 'pool1', - 'lb_algorithm': 'ROUND_ROBIN', - 'protocol': 'HTTP', - }, - }) - pool_id = result['pool']['id'] - logging.info('Awaiting pool to reach provisioning_status ' - '"ACTIVE"') - resp = wait_for_lb_resource(octavia_client.pool_show, pool_id) - logging.info(resp) - - result = octavia_client.health_monitor_create( - json={ - 'healthmonitor': { - 'pool_id': pool_id, - 'delay': 5, - 'max_retries': 4, - 'timeout': 10, - 'type': 'HTTP', - 'url_path': '/', - }, - }) - healthmonitor_id = result['healthmonitor']['id'] - logging.info('Awaiting healthmonitor to reach provisioning_status ' - '"ACTIVE"') - resp = wait_for_lb_resource(octavia_client.health_monitor_show, - healthmonitor_id) - logging.info(resp) - - for ip in payload_ips: - result = octavia_client.member_create( - pool_id=pool_id, - json={ - 'member': { - 'subnet_id': subnet_id, - 'address': ip, - 'protocol_port': 80, - }, - }) - member_id = result['member']['id'] - logging.info('Awaiting member to reach provisioning_status ' - '"ACTIVE"') - resp = wait_for_lb_resource( - lambda x: octavia_client.member_show( - pool_id=pool_id, member_id=x), - member_id, - operating_status='ONLINE') - logging.info(resp) + lb = self._create_lb_resources(octavia_client, 'amphora', + vip_subnet_id, subnet_id, payload_ips) lb_fp = openstack_utils.create_floating_ip( - neutron_client, 'ext_net', port={'id': lb_vip_port_id}) + neutron_client, 'ext_net', port={'id': lb['vip_port_id']}) @tenacity.retry(wait=tenacity.wait_fixed(1), reraise=True, stop=tenacity.stop_after_delay(900)) From 998a61a6a510ca26eb2d2e892b19657843253ea6 Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Mon, 3 Feb 2020 10:03:49 +0100 Subject: [PATCH 2/3] octavia: Support testing multiple providers --- zaza/openstack/charm_tests/octavia/tests.py | 113 +++++++++++++------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index c3786f4..bd23cc9 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -67,15 +67,43 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): return resp + @staticmethod + def get_lb_providers(octavia_client): + """Retrieve loadbalancer providers. + + :param octavia_client: Octavia client object + :type octavia_client: OctaviaAPI + :returns: Dictionary with provider information, name as keys + :rtype: Dict[str,Dict[str,str]] + """ + providers = { + provider['name']: provider + for provider in octavia_client.provider_list().get('providers', []) + if provider['name'] != 'octavia' # alias for `amphora`, skip + } + return providers + def _create_lb_resources(self, octavia_client, provider, vip_subnet_id, member_subnet_id, payload_ips): + # The `amphora` provider is required for load balancing based on + # higher layer protocols + if provider == 'amphora': + protocol = 'HTTP' + algorithm = 'ROUND_ROBIN' + monitor = True + else: + protocol = 'TCP' + algorithm = 'SOURCE_IP_PORT' + monitor = False + result = octavia_client.load_balancer_create( json={ 'loadbalancer': { 'description': 'Created by Zaza', 'admin_state_up': True, 'vip_subnet_id': vip_subnet_id, - 'name': 'zaza-lb-0', + 'name': 'zaza-{}-0'.format(provider), + 'provider': provider, }}) lb = result['loadbalancer'] lb_id = lb['id'] @@ -91,7 +119,7 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): 'listener': { 'loadbalancer_id': lb_id, 'name': 'listener1', - 'protocol': 'HTTP', + 'protocol': protocol, 'protocol_port': 80 }, }) @@ -107,8 +135,8 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): 'pool': { 'listener_id': listener_id, 'name': 'pool1', - 'lb_algorithm': 'ROUND_ROBIN', - 'protocol': 'HTTP', + 'lb_algorithm': algorithm, + 'protocol': protocol, }, }) pool_id = result['pool']['id'] @@ -117,23 +145,25 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): resp = self.wait_for_lb_resource(octavia_client.pool_show, pool_id) logging.info(resp) - result = octavia_client.health_monitor_create( - json={ - 'healthmonitor': { - 'pool_id': pool_id, - 'delay': 5, - 'max_retries': 4, - 'timeout': 10, - 'type': 'HTTP', - 'url_path': '/', - }, - }) - healthmonitor_id = result['healthmonitor']['id'] - logging.info('Awaiting healthmonitor to reach provisioning_status ' - '"ACTIVE"') - resp = self.wait_for_lb_resource(octavia_client.health_monitor_show, - healthmonitor_id) - logging.info(resp) + if monitor: + result = octavia_client.health_monitor_create( + json={ + 'healthmonitor': { + 'pool_id': pool_id, + 'delay': 5, + 'max_retries': 4, + 'timeout': 10, + 'type': 'HTTP', + 'url_path': '/', + }, + }) + healthmonitor_id = result['healthmonitor']['id'] + logging.info('Awaiting healthmonitor to reach provisioning_status ' + '"ACTIVE"') + resp = self.wait_for_lb_resource( + octavia_client.health_monitor_show, + healthmonitor_id) + logging.info(resp) for ip in payload_ips: result = octavia_client.member_create( @@ -152,10 +182,19 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): lambda x: octavia_client.member_show( pool_id=pool_id, member_id=x), member_id, - operating_status='ONLINE') + operating_status='ONLINE' if monitor else '') logging.info(resp) return lb + @staticmethod + @tenacity.retry(wait=tenacity.wait_fixed(1), + reraise=True, stop=tenacity.stop_after_delay(900)) + def _get_payload(ip): + return subprocess.check_output( + ['wget', '-O', '-', + 'http://{}/'.format(ip)], + universal_newlines=True) + def test_create_loadbalancer(self): """Create load balancer.""" keystone_session = openstack_utils.get_overcloud_keystone_session() @@ -179,21 +218,19 @@ class LBAASv2Test(test_utils.OpenStackBaseTest): vip_subnet_id = subnet_id octavia_client = openstack_utils.get_octavia_session_client( keystone_session) - lb = self._create_lb_resources(octavia_client, 'amphora', - vip_subnet_id, subnet_id, payload_ips) + for provider in self.get_lb_providers(octavia_client).keys(): + logging.info('Creating loadbalancer with provider {}' + .format(provider)) + lb = self._create_lb_resources(octavia_client, provider, + vip_subnet_id, subnet_id, + payload_ips) - lb_fp = openstack_utils.create_floating_ip( - neutron_client, 'ext_net', port={'id': lb['vip_port_id']}) + lb_fp = openstack_utils.create_floating_ip( + neutron_client, 'ext_net', port={'id': lb['vip_port_id']}) - @tenacity.retry(wait=tenacity.wait_fixed(1), - reraise=True, stop=tenacity.stop_after_delay(900)) - def get_payload(): - return subprocess.check_output( - ['wget', '-O', '-', - 'http://{}/'.format(lb_fp['floating_ip_address'])], - universal_newlines=True) - snippet = 'This is the default welcome page' - assert snippet in get_payload() - logging.info('Found "{}" in page retrieved through load balancer at ' - '"http://{}/"' - .format(snippet, lb_fp['floating_ip_address'])) + snippet = 'This is the default welcome page' + assert snippet in self._get_payload(lb_fp['floating_ip_address']) + logging.info('Found "{}" in page retrieved through load balancer ' + ' (provider="{}") at "http://{}/"' + .format(snippet, provider, + lb_fp['floating_ip_address'])) From d66358ce41fc706128573ab464d1a9bd6567c4ea Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Tue, 4 Feb 2020 09:16:44 +0100 Subject: [PATCH 3/3] policyd/octavia: Use correct network for vips Which network to use for vips depend on deployment configuration. --- zaza/openstack/charm_tests/policyd/tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zaza/openstack/charm_tests/policyd/tests.py b/zaza/openstack/charm_tests/policyd/tests.py index 532495f..f332765 100644 --- a/zaza/openstack/charm_tests/policyd/tests.py +++ b/zaza/openstack/charm_tests/policyd/tests.py @@ -679,7 +679,11 @@ class OctaviaTests(BasePolicydSpecialization): octavia_client = openstack_utils.get_octavia_session_client(sess) neutron_client = openstack_utils.get_neutron_session_client(sess) - resp = neutron_client.list_networks(name="private_lb_fip_network") + if openstack_utils.dvr_enabled(): + network_name = 'private_lb_fip_network' + else: + network_name = 'private' + resp = neutron_client.list_networks(name=network_name) vip_subnet_id = resp['networks'][0]['subnets'][0]