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'],