From 54225ad231c84cad7846bdb73cbd80c7170347ba Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Thu, 4 Feb 2021 15:25:17 +0100 Subject: [PATCH] Fix testing IPv6 VIP network connectivity The IPv6 VIP subnet used in the tests is created using devstack's default IPv6 subnetpool. Devstack ensures that any CIDR from this subnetpool is routable from the devstack node if the subnet is plugged into devstack's router1. Change-Id: Iaf3113087a344787add3405208fb229838a56d0b --- devstack/plugin.sh | 10 +++ octavia_tempest_plugin/config.py | 7 ++ octavia_tempest_plugin/tests/test_base.py | 83 ++++++++++++++++------- 3 files changed, 74 insertions(+), 26 deletions(-) diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 5eac133c..fb4e9325 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -24,6 +24,15 @@ function build_backend_test_server { ${DEST}/octavia-tempest-plugin/octavia_tempest_plugin/contrib/test_server/test_server.go } +function _configure_tempest { + if [ -n "$Q_ROUTER_NAME" ]; then + iniset $TEMPEST_CONFIG load_balancer default_router "$Q_ROUTER_NAME" + fi + if [ -n "$SUBNETPOOL_NAME_V6" ]; then + iniset $TEMPEST_CONFIG load_balancer default_ipv6_subnetpool "$SUBNETPOOL_NAME_V6" + fi +} + if [[ "$1" == "stack" ]]; then case "$2" in install) @@ -40,6 +49,7 @@ if [[ "$1" == "stack" ]]; then test-config) echo_summary "Building backend test server" build_backend_test_server + _configure_tempest ;; esac fi diff --git a/octavia_tempest_plugin/config.py b/octavia_tempest_plugin/config.py index f44bf960..7af7a1fa 100644 --- a/octavia_tempest_plugin/config.py +++ b/octavia_tempest_plugin/config.py @@ -179,6 +179,13 @@ OctaviaGroup = [ cfg.StrOpt('member_2_ipv6_subnet_cidr', default='fd77:1457:4cf0:26a8::/64', help='CIDR format subnet to use for the member 1 ipv6 subnet.'), + cfg.StrOpt('default_router', + default='router1', + help='The default router connected to the public network.'), + cfg.StrOpt('default_ipv6_subnetpool', + default='shared-default-subnetpool-v6', + help='The default IPv6 subnetpool to use when creating the ' + 'IPv6 VIP subnet.'), # Amphora specific options cfg.StrOpt('amphora_ssh_user', default='ubuntu', diff --git a/octavia_tempest_plugin/tests/test_base.py b/octavia_tempest_plugin/tests/test_base.py index 669a33ce..ace65026 100644 --- a/octavia_tempest_plugin/tests/test_base.py +++ b/octavia_tempest_plugin/tests/test_base.py @@ -128,6 +128,8 @@ class LoadBalancerBaseTest(validators.ValidatorsMixin, test.BaseTestCase): cls.mem_flavor_client = cls.os_roles_lb_member.flavor_client cls.mem_provider_client = cls.os_roles_lb_member.provider_client cls.os_admin_servers_client = cls.os_admin.servers_client + cls.os_admin_routers_client = cls.os_admin.routers_client + cls.os_admin_subnetpools_client = cls.os_admin.subnetpools_client cls.lb_admin_flavor_capabilities_client = ( cls.os_roles_lb_admin.flavor_capabilities_client) cls.lb_admin_availability_zone_capabilities_client = ( @@ -324,33 +326,38 @@ class LoadBalancerBaseTest(validators.ValidatorsMixin, test.BaseTestCase): # Create tenant VIP IPv6 subnet if CONF.load_balancer.test_with_ipv6: - # See if ipv6-private-subnet exists and use it if so. - priv_ipv6_subnet = cls.os_admin.subnets_client.list_subnets( - name='ipv6-private-subnet')['subnets'] - cls.lb_member_vip_ipv6_subnet_stateful = False - if len(priv_ipv6_subnet) == 1: - if (priv_ipv6_subnet[0]['ipv6_address_mode'] == - 'dhcpv6-stateful'): - cls.lb_member_vip_ipv6_subnet_stateful = True - cls.lb_member_vip_ipv6_subnet = priv_ipv6_subnet[0] - cls.lb_member_vip_ipv6_net = { - 'id': priv_ipv6_subnet[0]['network_id']} - else: - subnet_kwargs = { - 'name': data_utils.rand_name("lb_member_vip_ipv6_subnet"), - 'network_id': cls.lb_member_vip_net['id'], - 'cidr': CONF.load_balancer.vip_ipv6_subnet_cidr, - 'ip_version': 6} - result = cls.lb_mem_subnet_client.create_subnet( - **subnet_kwargs) - cls.lb_member_vip_ipv6_net = cls.lb_member_vip_net - cls.lb_member_vip_ipv6_subnet = result['subnet'] - cls.addClassResourceCleanup( - waiters.wait_for_not_found, - cls._logging_delete_subnet, - cls.lb_mem_subnet_client.show_subnet, - cls.lb_member_vip_ipv6_subnet['id']) + cls.lb_member_vip_ipv6_subnet_use_subnetpool = False + subnet_kwargs = { + 'name': data_utils.rand_name("lb_member_vip_ipv6_subnet"), + 'network_id': cls.lb_member_vip_net['id'], + 'ip_version': 6} + + # Use a CIDR from devstack's default IPv6 subnetpool if it exists, + # the subnetpool's cidr is routable from the devstack node + # through the default router + subnetpool_name = CONF.load_balancer.default_ipv6_subnetpool + if subnetpool_name: + subnetpool = cls.os_admin_subnetpools_client.list_subnetpools( + name=subnetpool_name)['subnetpools'] + if len(subnetpool) == 1: + subnetpool = subnetpool[0] + subnet_kwargs['subnetpool_id'] = subnetpool['id'] + cls.lb_member_vip_ipv6_subnet_use_subnetpool = True + + if 'subnetpool_id' not in subnet_kwargs: + subnet_kwargs['cidr'] = ( + CONF.load_balancer.vip_ipv6_subnet_cidr) + + result = cls.lb_mem_subnet_client.create_subnet( + **subnet_kwargs) + cls.lb_member_vip_ipv6_net = cls.lb_member_vip_net + cls.lb_member_vip_ipv6_subnet = result['subnet'] + cls.addClassResourceCleanup( + waiters.wait_for_not_found, + cls._logging_delete_subnet, + cls.lb_mem_subnet_client.show_subnet, + cls.lb_member_vip_ipv6_subnet['id']) LOG.info('lb_member_vip_ipv6_subnet: {}'.format( cls.lb_member_vip_ipv6_subnet)) @@ -737,6 +744,30 @@ class LoadBalancerBaseTestWithCompute(LoadBalancerBaseTest): cls.lb_member_router['id'], subnet_id=cls.lb_member_vip_subnet['id']) + if (CONF.load_balancer.test_with_ipv6 and + CONF.load_balancer.default_router and + cls.lb_member_vip_ipv6_subnet_use_subnetpool): + + router_name = CONF.load_balancer.default_router + # if lb_member_vip_ipv6_subnet uses devstack's subnetpool, + # plug the subnet into the default router + router = cls.os_admin.routers_client.list_routers( + name=router_name)['routers'] + + if len(router) == 1: + router = router[0] + + # Add IPv6 VIP subnet to router1 + cls.os_admin_routers_client.add_router_interface( + router['id'], + subnet_id=cls.lb_member_vip_ipv6_subnet['id']) + cls.addClassResourceCleanup( + waiters.wait_for_not_found, + cls.os_admin_routers_client.remove_router_interface, + cls.os_admin_routers_client.remove_router_interface, + router['id'], + subnet_id=cls.lb_member_vip_ipv6_subnet['id']) + # Add member subnet 1 to router cls.lb_mem_routers_client.add_router_interface( cls.lb_member_router['id'],