Merge "Switch centos-8 jobs to centos-8-stream"
diff --git a/octavia_tempest_plugin/clients.py b/octavia_tempest_plugin/clients.py
deleted file mode 100644
index 7fe3606..0000000
--- a/octavia_tempest_plugin/clients.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#   Copyright 2017 GoDaddy
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with 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.
-#
-from tempest import clients
-from tempest import config
-
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    amphora_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    availability_zone_capabilities_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    availability_zone_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    availability_zone_profile_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    flavor_capabilities_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    flavor_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    flavor_profile_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    healthmonitor_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    l7policy_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    l7rule_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    listener_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    loadbalancer_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    member_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    pool_client)
-from octavia_tempest_plugin.services.load_balancer.v2 import (
-    provider_client)
-
-CONF = config.CONF
-
-
-class ManagerV2(clients.Manager):
-
-    def __init__(self, credentials):
-        super(ManagerV2, self).__init__(credentials)
-
-        params = dict(self.default_params)
-        params.update({
-            'auth_provider': self.auth_provider,
-            'service': CONF.load_balancer.catalog_type,
-            'region': CONF.load_balancer.region or CONF.identity.region,
-            'endpoint_type': CONF.load_balancer.endpoint_type,
-            'build_interval': CONF.load_balancer.build_interval,
-            'build_timeout': CONF.load_balancer.build_timeout
-        })
-
-        self.loadbalancer_client = loadbalancer_client.LoadbalancerClient(
-            **params)
-        self.listener_client = listener_client.ListenerClient(**params)
-        self.pool_client = pool_client.PoolClient(**params)
-        self.member_client = member_client.MemberClient(**params)
-        self.healthmonitor_client = healthmonitor_client.HealthMonitorClient(
-            **params)
-        self.l7policy_client = l7policy_client.L7PolicyClient(**params)
-        self.l7rule_client = l7rule_client.L7RuleClient(**params)
-        self.amphora_client = amphora_client.AmphoraClient(**params)
-        self.flavor_profile_client = flavor_profile_client.FlavorProfileClient(
-            **params)
-        self.flavor_client = flavor_client.FlavorClient(**params)
-        self.provider_client = provider_client.ProviderClient(**params)
-        self.flavor_capabilities_client = (
-            flavor_capabilities_client.FlavorCapabilitiesClient(**params))
-        self.availability_zone_capabilities_client = (
-            availability_zone_capabilities_client
-            .AvailabilityZoneCapabilitiesClient(**params))
-        self.availability_zone_profile_client = (
-            availability_zone_profile_client.AvailabilityZoneProfileClient(
-                **params))
-        self.availability_zone_client = (
-            availability_zone_client.AvailabilityZoneClient(**params))
diff --git a/octavia_tempest_plugin/common/constants.py b/octavia_tempest_plugin/common/constants.py
index aea476e..174589c 100644
--- a/octavia_tempest_plugin/common/constants.py
+++ b/octavia_tempest_plugin/common/constants.py
@@ -21,6 +21,7 @@
 ADMIN_STATE_UP = 'admin_state_up'
 BYTES_IN = 'bytes_in'
 BYTES_OUT = 'bytes_out'
+CA_TLS_CONTAINER_REF = 'ca_tls_container_ref'
 CLIENT_AUTHENTICATION = 'client_authentication'
 CLIENT_AUTH_NONE = 'NONE'
 CLIENT_AUTH_OPTIONAL = 'OPTIONAL'
@@ -28,6 +29,7 @@
 CLIENT_CA_TLS_CONTAINER_REF = 'client_ca_tls_container_ref'
 CLIENT_CRL_CONTAINER_REF = 'client_crl_container_ref'
 CREATED_AT = 'created_at'
+CRL_CONTAINER_REF = 'crl_container_ref'
 DESCRIPTION = 'description'
 FLAVOR_DATA = 'flavor_data'
 FLAVOR_ID = 'flavor_id'
@@ -63,6 +65,7 @@
 TIMEOUT_MEMBER_CONNECT = 'timeout_member_connect'
 TIMEOUT_MEMBER_DATA = 'timeout_member_data'
 TIMEOUT_TCP_INSPECT = 'timeout_tcp_inspect'
+TLS_ENABLED = 'tls_enabled'
 DEFAULT_TLS_CONTAINER_REF = 'default_tls_container_ref'
 SNI_CONTAINER_REFS = 'sni_container_refs'
 DEFAULT_POOL_ID = 'default_pool_id'
diff --git a/octavia_tempest_plugin/contrib/test_server/test_server.go b/octavia_tempest_plugin/contrib/test_server/test_server.go
index fa8f8d7..1671b5c 100644
--- a/octavia_tempest_plugin/contrib/test_server/test_server.go
+++ b/octavia_tempest_plugin/contrib/test_server/test_server.go
@@ -171,11 +171,14 @@
 				tls.CurveP256},
 			PreferServerCipherSuites: true,
 			CipherSuites: []uint16{
+				tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
 				tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 				tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 				tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
 				tls.TLS_RSA_WITH_AES_256_CBC_SHA,
 			},
+			NextProtos: []string{"h2", "http/1.1", "http/1.0"},
 		}
 	} else {
 		tlsConfig = &tls.Config{
@@ -186,6 +189,8 @@
 				tls.CurveP256},
 			PreferServerCipherSuites: true,
 			CipherSuites: []uint16{
+				tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
 				tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 				tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 				tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
@@ -200,8 +205,6 @@
 		Addr:      portStr,
 		Handler:   mux,
 		TLSConfig: tlsConfig,
-		TLSNextProto: make(map[string]func(*http.Server, *tls.Conn,
-			http.Handler), 0),
 	}
 	log.Fatal(srv.ListenAndServeTLS(serverCertPem, serverKeyPem))
 }
diff --git a/octavia_tempest_plugin/plugin.py b/octavia_tempest_plugin/plugin.py
index 655cdba..ec8e7c5 100644
--- a/octavia_tempest_plugin/plugin.py
+++ b/octavia_tempest_plugin/plugin.py
@@ -19,6 +19,7 @@
 from tempest.test_discover import plugins
 
 from octavia_tempest_plugin import config as project_config
+from octavia_tempest_plugin.services.load_balancer import v2 as lb_v2_services
 
 
 class OctaviaTempestPlugin(plugins.TempestPlugin):
@@ -57,10 +58,10 @@
         )
 
         params = {
-            'name': 'load-balancer_v2',
+            'name': 'load_balancer_v2',
             'service_version': 'load-balancer.v2',
             'module_path': 'octavia_tempest_plugin.services.load_balancer.v2',
-            'client_names': ['LoadbalancerClient'],
+            'client_names': lb_v2_services.__all__,
         }
         params.update(octavia_config)
 
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/__init__.py b/octavia_tempest_plugin/services/load_balancer/v2/__init__.py
index 04cb473..2067372 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/__init__.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/__init__.py
@@ -12,6 +12,35 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from .amphora_client import AmphoraClient
+from .availability_zone_capabilities_client import (
+    AvailabilityZoneCapabilitiesClient)
+from .availability_zone_client import AvailabilityZoneClient
+from .availability_zone_profile_client import AvailabilityZoneProfileClient
+from .flavor_capabilities_client import FlavorCapabilitiesClient
+from .flavor_client import FlavorClient
+from .flavor_profile_client import FlavorProfileClient
+from .healthmonitor_client import HealthMonitorClient
+from .l7policy_client import L7PolicyClient
+from .l7rule_client import L7RuleClient
+from .listener_client import ListenerClient
 from .loadbalancer_client import LoadbalancerClient
+from .member_client import MemberClient
+from .pool_client import PoolClient
+from .provider_client import ProviderClient
 
-__all__ = ['LoadbalancerClient']
+__all__ = ['LoadbalancerClient',
+           'ListenerClient',
+           'PoolClient',
+           'MemberClient',
+           'HealthMonitorClient',
+           'L7PolicyClient',
+           'L7RuleClient',
+           'FlavorClient',
+           'FlavorProfileClient',
+           'FlavorCapabilitiesClient',
+           'AmphoraClient',
+           'ProviderClient',
+           'AvailabilityZoneClient',
+           'AvailabilityZoneProfileClient',
+           'AvailabilityZoneCapabilitiesClient']
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py b/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
index 98f4bfa..c19d97c 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
@@ -32,6 +32,8 @@
                     listener_id=Unset, name=Unset, description=Unset,
                     tags=Unset,
                     admin_state_up=Unset, session_persistence=Unset,
+                    ca_tls_container_ref=Unset, crl_container_ref=Unset,
+                    tls_enabled=Unset, tls_container_ref=Unset,
                     return_object_only=True):
         """Create a pool.
 
@@ -47,6 +49,18 @@
         :param session_persistence: A JSON object specifying the session
                                     persistence for the pool or null for no
                                     session persistence.
+        :param ca_tls_container_ref: The key manager ref for a secret
+                                     containing the PEM encoded CA certificate
+                                     to validate pool members against.
+        :param crl_container_ref: The key manager ref for a secret containing
+                                  the PEM encoded CRL to use when validating
+                                  pool members.
+        :param tls_enabled: A boolean, True when the pool should connect to
+                            members using TLS.
+        :param tls_container_ref: The key manager ref for a secret containing
+                                  a PKCS12 bundle with the client
+                                  authentication certificate and key used
+                                  when connecting to pool members over TLS.
         :param return_object_only: If True, the response returns the object
                                    inside the root tag. False returns the full
                                    response from the API.
@@ -164,7 +178,9 @@
     @skip_if_not_implemented
     def update_pool(self, pool_id, lb_algorithm=Unset, name=Unset,
                     description=Unset, tags=Unset, admin_state_up=Unset,
-                    session_persistence=Unset, return_object_only=True):
+                    session_persistence=Unset, ca_tls_container_ref=Unset,
+                    crl_container_ref=Unset, tls_enabled=Unset,
+                    tls_container_ref=Unset, return_object_only=True):
         """Update a pool.
 
         :param pool_id: The pool ID to update.
@@ -177,6 +193,18 @@
         :param session_persistence: A JSON object specifying the session
                                     persistence for the pool or null for no
                                     session persistence.
+        :param ca_tls_container_ref: The key manager ref for a secret
+                                     containing the PEM encoded CA certificate
+                                     to validate pool members against.
+        :param crl_container_ref: The key manager ref for a secret containing
+                                  the PEM encoded CRL to use when validating
+                                  pool members.
+        :param tls_enabled: A boolean, True when the pool should connect to
+                            members using TLS.
+        :param tls_container_ref: The key manager ref for a secret containing
+                                  a PKCS12 bundle with the client
+                                  authentication certificate and key used
+                                  when connecting to pool members over TLS.
         :param return_object_only: If True, the response returns the object
                                    inside the root tag. False returns the full
                                    response from the API.
diff --git a/octavia_tempest_plugin/tests/RBAC_tests.py b/octavia_tempest_plugin/tests/RBAC_tests.py
index b24e5c4..d31d506 100644
--- a/octavia_tempest_plugin/tests/RBAC_tests.py
+++ b/octavia_tempest_plugin/tests/RBAC_tests.py
@@ -28,12 +28,20 @@
 
 class RBACTestsMixin(test.BaseTestCase):
 
+    def _get_client_method(self, cred_obj, client_str, method_str):
+        """Get requested method from registered clients in Tempest."""
+        lb_clients = getattr(cred_obj, 'load_balancer_v2')
+        client = getattr(lb_clients, client_str)
+        client_obj = client()
+        method = getattr(client_obj, method_str)
+        return method
+
     def _check_allowed(self, client_str, method_str, allowed_list,
                        *args, **kwargs):
         """Test an API call allowed RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param allowed_list: The list of credentials expected to be
@@ -62,8 +70,7 @@
                               'testing was not created by tempest '
                               'credentials setup. This is likely a bug in the '
                               'test.'.format(cred))
-            client = getattr(cred_obj, client_str)
-            method = getattr(client, method_str)
+            method = self._get_client_method(cred_obj, client_str, method_str)
             try:
                 method(*args, **kwargs)
             except exceptions.Forbidden as e:
@@ -76,7 +83,7 @@
         """Test an API call disallowed RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param allowed_list: The list of credentials expected to be
@@ -98,8 +105,7 @@
                                set(allowed_list))
         for cred in expected_disallowed:
             cred_obj = getattr(self, cred)
-            client = getattr(cred_obj, client_str)
-            method = getattr(client, method_str)
+            method = self._get_client_method(cred_obj, client_str, method_str)
 
             # Unfortunately tempest uses testtools assertRaises[1] which means
             # we cannot use the unittest assertRaises context[2] with msg= to
@@ -133,7 +139,7 @@
         """Test an API call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -173,7 +179,7 @@
         """Test an API show call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -195,7 +201,7 @@
         """Test an API list call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -218,7 +224,7 @@
         """Test an API create/update/delete call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -259,7 +265,7 @@
         """Test an API create call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -286,7 +292,7 @@
         """Test an API delete call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -313,7 +319,7 @@
         """Test an API update call RBAC enforcement.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -347,7 +353,7 @@
         will validate that only the expected count of results are returned.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -391,8 +397,7 @@
                               'testing was not created by tempest '
                               'credentials setup. This is likely a bug in the '
                               'test.'.format(cred))
-            client = getattr(cred_obj, client_str)
-            method = getattr(client, method_str)
+            method = self._get_client_method(cred_obj, client_str, method_str)
             try:
                 result = method(*args, **kwargs)
             except exceptions.Forbidden as e:
@@ -416,7 +421,7 @@
         will validate that the expected object Ids in included in the results.
 
         :param client_str: The service client to use for the test, without the
-                           credential.  Example: 'amphora_client'
+                           credential.  Example: 'AmphoraClient'
         :param method_str: The method on the client to call for the test.
                            Example: 'list_amphorae'
         :param expected_allowed: The list of credentials expected to be
@@ -460,8 +465,7 @@
                               'testing was not created by tempest '
                               'credentials setup. This is likely a bug in the '
                               'test.'.format(cred))
-            client = getattr(cred_obj, client_str)
-            method = getattr(client, method_str)
+            method = self._get_client_method(cred_obj, client_str, method_str)
             try:
                 result = method(*args, **kwargs)
             except exceptions.Forbidden as e:
diff --git a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby.py b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby.py
index 5655b3f..11b0cec 100644
--- a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby.py
+++ b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby.py
@@ -183,6 +183,7 @@
         * Sends traffic through the load balancer
         * Validates that the Backup has assumed the Master role
         """
+        amphora_client = self.os_admin.load_balancer_v2.AmphoraClient()
         # We have to do this here as the api_version and clients are not
         # setup in time to use a decorator or the skip_checks mixin
         if not self.mem_listener_client.is_version_supported(
@@ -197,7 +198,7 @@
         self.check_members_balanced(self.lb_vip_address)
 
         # Get the amphorae associated with this load balancer
-        amphorae = self.os_admin.amphora_client.list_amphorae(
+        amphorae = amphora_client.list_amphorae(
             query_params='{loadbalancer_id}={lb_id}'.format(
                 loadbalancer_id=const.LOADBALANCER_ID,
                 lb_id=self.lb_id))
@@ -216,7 +217,7 @@
         start = int(time.time())
         while True:
             for amp in amphorae:
-                amphora_stats = self.os_admin.amphora_client.get_amphora_stats(
+                amphora_stats = amphora_client.get_amphora_stats(
                     amp[const.ID])
                 for listener in amphora_stats:
                     if listener[const.TOTAL_CONNECTIONS] > 0:
@@ -243,7 +244,7 @@
             else:
                 backup_amp = amp
         self.assertIsNotNone(backup_amp)
-        amphora_stats = self.os_admin.amphora_client.get_amphora_stats(
+        amphora_stats = amphora_client.get_amphora_stats(
             backup_amp[const.ID])
         for listener in amphora_stats:
             self.assertEqual(0, listener[const.TOTAL_CONNECTIONS])
@@ -265,7 +266,7 @@
             time.sleep(1)
 
         # Check that the Backup amphora is now Master
-        amphora_stats = self.os_admin.amphora_client.get_amphora_stats(
+        amphora_stats = amphora_client.get_amphora_stats(
             backup_amp[const.ID])
         connections = 0
         for listener in amphora_stats:
diff --git a/octavia_tempest_plugin/tests/api/v2/test_amphora.py b/octavia_tempest_plugin/tests/api/v2/test_amphora.py
index a1a6441..180e4f3 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_amphora.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_amphora.py
@@ -99,7 +99,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'amphora_client', 'list_amphorae', expected_allowed)
+                'AmphoraClient', 'list_amphorae', expected_allowed)
 
         # Get an actual list of the amphorae
         amphorae = self.lb_admin_amphora_client.list_amphorae()
@@ -119,7 +119,7 @@
         # Test RBAC for show amphora
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'amphora_client', 'show_amphora', expected_allowed,
+                'AmphoraClient', 'show_amphora', expected_allowed,
                 amphora_id=amphorae[0][const.ID])
 
         show_amphora_response_fields = const.SHOW_AMPHORA_RESPONSE_FIELDS
@@ -187,7 +187,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'amphora_client', 'update_amphora_config', expected_allowed,
+                'AmphoraClient', 'update_amphora_config', expected_allowed,
                 None, None, amphora_1[const.ID])
 
         self.lb_admin_amphora_client.update_amphora_config(amphora_1[const.ID])
@@ -222,7 +222,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'amphora_client', 'amphora_failover', expected_allowed,
+                'AmphoraClient', 'amphora_failover', expected_allowed,
                 None, None, amphora_1[const.ID])
 
         self.lb_admin_amphora_client.amphora_failover(amphora_1[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_availability_zone.py b/octavia_tempest_plugin/tests/api/v2/test_availability_zone.py
index e18a194..fa7b6a4 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_availability_zone.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_availability_zone.py
@@ -114,7 +114,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'availability_zone_client', 'create_availability_zone',
+                'AvailabilityZoneClient', 'create_availability_zone',
                 expected_allowed, **availability_zone_kwargs)
 
         # Happy path
@@ -243,7 +243,7 @@
                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'availability_zone_client', 'list_availability_zones',
+                'AvailabilityZoneClient', 'list_availability_zones',
                 expected_allowed)
 
         # Check the default sort order (by ID)
@@ -396,7 +396,7 @@
                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'availability_zone_client', 'show_availability_zone',
+                'AvailabilityZoneClient', 'show_availability_zone',
                 expected_allowed, availability_zone[const.NAME])
 
         result = self.mem_availability_zone_client.show_availability_zone(
@@ -463,7 +463,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'availability_zone_client', 'update_availability_zone',
+                'AvailabilityZoneClient', 'update_availability_zone',
                 expected_allowed, None, None, availability_zone[const.NAME],
                 **availability_zone_updated_kwargs)
 
@@ -540,7 +540,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'availability_zone_client', 'delete_availability_zone',
+                'AvailabilityZoneClient', 'delete_availability_zone',
                 expected_allowed, None, None, availability_zone[const.NAME])
 
         # Happy path
diff --git a/octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py b/octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py
index 4831ede..d3833f6 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py
@@ -53,7 +53,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'availability_zone_capabilities_client',
+                'AvailabilityZoneCapabilitiesClient',
                 'list_availability_zone_capabilities', expected_allowed,
                 CONF.load_balancer.provider)
 
diff --git a/octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py b/octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py
index 079d125..456a01e 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py
@@ -85,7 +85,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'availability_zone_profile_client',
+                'AvailabilityZoneProfileClient',
                 'create_availability_zone_profile',
                 expected_allowed, **availability_zone_profile_kwargs)
 
@@ -240,7 +240,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'availability_zone_profile_client',
+                'AvailabilityZoneProfileClient',
                 'list_availability_zone_profiles', expected_allowed)
 
         # Check the default sort order (by ID)
@@ -401,7 +401,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'availability_zone_profile_client',
+                'AvailabilityZoneProfileClient',
                 'show_availability_zone_profile', expected_allowed,
                 availability_zone_profile[const.ID])
 
@@ -503,7 +503,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'availability_zone_profile_client',
+                'AvailabilityZoneProfileClient',
                 'update_availability_zone_profile', expected_allowed,
                 None, None, availability_zone_profile[const.ID],
                 **availability_zone_profile_updated_kwargs)
@@ -585,7 +585,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'availability_zone_profile_client',
+                'AvailabilityZoneProfileClient',
                 'delete_availability_zone_profile', expected_allowed,
                 None, None, availability_zone_profile[const.ID])
 
diff --git a/octavia_tempest_plugin/tests/api/v2/test_flavor.py b/octavia_tempest_plugin/tests/api/v2/test_flavor.py
index 89b36cc..b5b4254 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_flavor.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_flavor.py
@@ -97,7 +97,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'flavor_client', 'create_flavor',
+                'FlavorClient', 'create_flavor',
                 expected_allowed, None, None, **flavor_kwargs)
 
         # Happy path
@@ -209,7 +209,7 @@
                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'flavor_client', 'list_flavors', expected_allowed)
+                'FlavorClient', 'list_flavors', expected_allowed)
 
         # Check the default sort order (by ID)
         flavors = self.mem_flavor_client.list_flavors()
@@ -337,7 +337,7 @@
                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'flavor_client', 'show_flavor', expected_allowed,
+                'FlavorClient', 'show_flavor', expected_allowed,
                 flavor[const.ID])
 
         result = self.mem_flavor_client.show_flavor(flavor[const.ID])
@@ -399,7 +399,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'flavor_client', 'update_flavor', expected_allowed, None, None,
+                'FlavorClient', 'update_flavor', expected_allowed, None, None,
                 flavor[const.ID], **flavor_updated_kwargs)
 
         updated_flavor = self.lb_admin_flavor_client.update_flavor(
@@ -463,7 +463,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'flavor_client', 'delete_flavor', expected_allowed,
+                'FlavorClient', 'delete_flavor', expected_allowed,
                 None, None, flavor[const.ID])
 
         # Happy path
diff --git a/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py b/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
index 5b48833..884f656 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
@@ -51,7 +51,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'flavor_capabilities_client',
+                'FlavorCapabilitiesClient',
                 'list_flavor_capabilities', expected_allowed,
                 CONF.load_balancer.provider)
 
diff --git a/octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py b/octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py
index eec8679..39f3338 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py
@@ -69,7 +69,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'flavor_profile_client', 'create_flavor_profile',
+                'FlavorProfileClient', 'create_flavor_profile',
                 expected_allowed, None, None, **flavor_profile_kwargs)
 
         # Happy path
@@ -189,7 +189,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'flavor_profile_client', 'list_flavor_profiles',
+                'FlavorProfileClient', 'list_flavor_profiles',
                 expected_allowed)
 
         # Check the default sort order (by ID)
@@ -318,7 +318,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'flavor_profile_client', 'show_flavor_profile',
+                'FlavorProfileClient', 'show_flavor_profile',
                 expected_allowed, flavor_profile[const.ID])
 
         result = (
@@ -396,7 +396,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'flavor_profile_client', 'update_flavor_profile',
+                'FlavorProfileClient', 'update_flavor_profile',
                 expected_allowed, None, None, flavor_profile[const.ID],
                 **flavor_profile_updated_kwargs)
 
@@ -463,7 +463,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'flavor_profile_client', 'delete_flavor_profile',
+                'FlavorProfileClient', 'delete_flavor_profile',
                 expected_allowed, None, None, flavor_profile[const.ID])
 
         # Happy path
diff --git a/octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py b/octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py
index a2eec1c..a305ead 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py
@@ -288,7 +288,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'healthmonitor_client', 'create_healthmonitor',
+                'HealthMonitorClient', 'create_healthmonitor',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **hm_kwargs)
@@ -731,7 +731,7 @@
             expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement_count(
-                'healthmonitor_client', 'list_healthmonitors',
+                'HealthMonitorClient', 'list_healthmonitors',
                 expected_allowed, 0)
 
         # Test credentials that should see these healthmonitors can see them.
@@ -747,7 +747,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'healthmonitor_client', 'list_healthmonitors',
+                'HealthMonitorClient', 'list_healthmonitors',
                 expected_allowed, test_ids)
 
         # Test that users without the lb member role cannot list healthmonitors
@@ -774,7 +774,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'healthmonitor_client', 'list_healthmonitors',
+                'HealthMonitorClient', 'list_healthmonitors',
                 expected_allowed)
 
         # Check the default sort order, created_at
@@ -1202,7 +1202,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'healthmonitor_client', 'show_healthmonitor',
+                'HealthMonitorClient', 'show_healthmonitor',
                 expected_allowed, hm[const.ID])
 
     @decorators.idempotent_id('2417164b-ec03-4488-afd2-60b096dc0077')
@@ -1481,7 +1481,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'healthmonitor_client', 'update_healthmonitor',
+                'HealthMonitorClient', 'update_healthmonitor',
                 expected_allowed, None, None, hm[const.ID],
                 admin_state_up=True)
 
@@ -1784,7 +1784,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'healthmonitor_client', 'delete_healthmonitor',
+                'HealthMonitorClient', 'delete_healthmonitor',
                 expected_allowed, None, None, hm[const.ID])
 
         self.mem_healthmonitor_client.delete_healthmonitor(hm[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_l7policy.py b/octavia_tempest_plugin/tests/api/v2/test_l7policy.py
index 05ef55d..e7ed5a6 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_l7policy.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_l7policy.py
@@ -145,7 +145,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'l7policy_client', 'create_l7policy',
+                'L7PolicyClient', 'create_l7policy',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **l7policy_kwargs)
@@ -372,7 +372,7 @@
             expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement_count(
-                'l7policy_client', 'list_l7policies',
+                'L7PolicyClient', 'list_l7policies',
                 expected_allowed, 0)
 
         # Test credentials that should see these l7policies can see them.
@@ -388,7 +388,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'l7policy_client', 'list_l7policies',
+                'L7PolicyClient', 'list_l7policies',
                 expected_allowed, test_ids,
                 query_params='listener_id={listener_id}'.format(
                     listener_id=listener_id))
@@ -417,7 +417,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'l7policy_client', 'list_l7policies',
+                'L7PolicyClient', 'list_l7policies',
                 expected_allowed)
 
         # Check the default sort order, created_at
@@ -661,7 +661,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'l7policy_client', 'show_l7policy',
+                'L7PolicyClient', 'show_l7policy',
                 expected_allowed, l7policy[const.ID])
 
     @decorators.idempotent_id('08f73b22-550b-4e5a-b3d6-2ec03251ca13')
@@ -767,7 +767,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'l7policy_client', 'update_l7policy',
+                'L7PolicyClient', 'update_l7policy',
                 expected_allowed, None, None, l7policy[const.ID],
                 admin_state_up=True)
 
@@ -878,7 +878,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'l7policy_client', 'delete_l7policy',
+                'L7PolicyClient', 'delete_l7policy',
                 expected_allowed, None, None, l7policy[const.ID])
 
         self.mem_l7policy_client.delete_l7policy(l7policy[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_l7rule.py b/octavia_tempest_plugin/tests/api/v2/test_l7rule.py
index adaeaad..5cb85c4 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_l7rule.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_l7rule.py
@@ -153,7 +153,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'l7rule_client', 'create_l7rule',
+                'L7RuleClient', 'create_l7rule',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **l7rule_kwargs)
@@ -365,7 +365,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'l7rule_client', 'list_l7rules', expected_allowed, test_ids,
+                'L7RuleClient', 'list_l7rules', expected_allowed, test_ids,
                 l7policy_id)
 
         # Test that users without the lb member role cannot list L7 rules.
@@ -389,7 +389,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'l7rule_client', 'list_l7rules', expected_allowed, l7policy_id)
+                'L7RuleClient', 'list_l7rules', expected_allowed, l7policy_id)
 
         # Check the default sort order, created_at
         l7rules = self.mem_l7rule_client.list_l7rules(l7policy_id)
@@ -575,7 +575,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'l7rule_client', 'show_l7rule',
+                'L7RuleClient', 'show_l7rule',
                 expected_allowed, l7rule[const.ID],
                 l7policy_id=self.l7policy_id)
 
@@ -660,7 +660,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'l7rule_client', 'update_l7rule',
+                'L7RuleClient', 'update_l7rule',
                 expected_allowed, None, None, l7rule[const.ID],
                 l7policy_id=self.l7policy_id, admin_state_up=True)
 
@@ -762,7 +762,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'l7rule_client', 'delete_l7rule',
+                'L7RuleClient', 'delete_l7rule',
                 expected_allowed, None, None, l7rule[const.ID],
                 l7policy_id=self.l7policy_id)
 
diff --git a/octavia_tempest_plugin/tests/api/v2/test_listener.py b/octavia_tempest_plugin/tests/api/v2/test_listener.py
index bb78aad..152f6ff 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_listener.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_listener.py
@@ -59,6 +59,14 @@
         if CONF.load_balancer.test_with_ipv6:
             cls.allowed_cidrs = ['2001:db8:a0b:12f0::/64']
 
+    @classmethod
+    def setup_clients(cls):
+        """Setup client aliases."""
+        super(ListenerAPITest, cls).setup_clients()
+        cls.listener_client = cls.os_primary.load_balancer_v2.ListenerClient()
+        cls.member2_listener_client = (
+            cls.os_roles_lb_member2.load_balancer_v2.ListenerClient())
+
     @decorators.idempotent_id('88d0ec83-7b08-48d9-96e2-0df1d2f8cd98')
     def test_http_listener_create(self):
         self._test_listener_create(const.HTTP, 8000)
@@ -156,7 +164,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'listener_client', 'create_listener',
+                'ListenerClient', 'create_listener',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **listener_kwargs)
@@ -545,7 +553,7 @@
             expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement_count(
-                'listener_client', 'list_listeners', expected_allowed, 0,
+                'ListenerClient', 'list_listeners', expected_allowed, 0,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
         # Test credentials that should see these listeners can see them.
@@ -561,7 +569,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'listener_client', 'list_listeners', expected_allowed,
+                'ListenerClient', 'list_listeners', expected_allowed,
                 test_ids,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
@@ -589,7 +597,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'listener_client', 'list_listeners', expected_allowed,
+                'ListenerClient', 'list_listeners', expected_allowed,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
         # Check the default sort order, created_at
@@ -864,7 +872,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'listener_client', 'show_listener',
+                'ListenerClient', 'show_listener',
                 expected_allowed, listener[const.ID])
 
     @decorators.idempotent_id('aaae0298-5778-4c7e-a27a-01549a71b319')
@@ -996,7 +1004,7 @@
         if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
             self.assertRaises(
                 exceptions.Forbidden,
-                self.os_primary.listener_client.update_listener,
+                self.listener_client.update_listener,
                 listener[const.ID], admin_state_up=True)
 
         # Assert we didn't go into PENDING_*
@@ -1009,7 +1017,7 @@
         # Test that a user, without the load balancer member role, cannot
         # update this listener
         if not CONF.load_balancer.RBAC_test_type == const.NONE:
-            member2_client = self.os_roles_lb_member2.listener_client
+            member2_client = self.member2_listener_client
             self.assertRaises(exceptions.Forbidden,
                               member2_client.update_listener,
                               listener[const.ID], admin_state_up=True)
@@ -1180,13 +1188,13 @@
         if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
             self.assertRaises(
                 exceptions.Forbidden,
-                self.os_primary.listener_client.delete_listener,
+                self.listener_client.delete_listener,
                 listener[const.ID])
 
         # Test that a different user, with the load balancer member role
         # cannot delete this listener
         if not CONF.load_balancer.RBAC_test_type == const.NONE:
-            member2_client = self.os_roles_lb_member2.listener_client
+            member2_client = self.member2_listener_client
             self.assertRaises(exceptions.Forbidden,
                               member2_client.delete_listener,
                               listener[const.ID])
@@ -1279,13 +1287,13 @@
         if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
             self.assertRaises(
                 exceptions.Forbidden,
-                self.os_primary.listener_client.get_listener_stats,
+                self.listener_client.get_listener_stats,
                 listener[const.ID])
 
         # Test that a different user, with the load balancer role, cannot see
         # the listener stats
         if not CONF.load_balancer.RBAC_test_type == const.NONE:
-            member2_client = self.os_roles_lb_member2.listener_client
+            member2_client = self.member2_listener_client
             self.assertRaises(exceptions.Forbidden,
                               member2_client.get_listener_stats,
                               listener[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py b/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
index 86de17e..7ade642 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
@@ -96,7 +96,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'loadbalancer_client', 'create_loadbalancer',
+                'LoadbalancerClient', 'create_loadbalancer',
                 expected_allowed, None, None, **lb_kwargs_with_project_id)
 
         lb = self.mem_lb_client.create_loadbalancer(**lb_kwargs)
@@ -199,7 +199,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'loadbalancer_client', 'delete_loadbalancer',
+                'LoadbalancerClient', 'delete_loadbalancer',
                 expected_allowed, None, None, lb[const.ID])
 
         self.mem_lb_client.delete_loadbalancer(lb[const.ID])
@@ -248,7 +248,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'loadbalancer_client', 'delete_loadbalancer',
+                'LoadbalancerClient', 'delete_loadbalancer',
                 expected_allowed, None, None, lb[const.ID], cascade=True)
 
         self.mem_lb_client.delete_loadbalancer(lb[const.ID], cascade=True)
@@ -425,7 +425,7 @@
             expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement_count(
-                'loadbalancer_client', 'list_loadbalancers',
+                'LoadbalancerClient', 'list_loadbalancers',
                 expected_allowed, 0)
 
         # Test credentials that should see these load balancers can see them.
@@ -441,7 +441,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'loadbalancer_client', 'list_loadbalancers',
+                'LoadbalancerClient', 'list_loadbalancers',
                 expected_allowed, test_ids)
 
         # Test that users without the lb member role cannot list load balancers
@@ -468,7 +468,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'loadbalancer_client', 'list_loadbalancers', expected_allowed)
+                'LoadbalancerClient', 'list_loadbalancers', expected_allowed)
 
         # Check the default sort order, created_at
         lbs = self.mem_lb_client.list_loadbalancers()
@@ -644,7 +644,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'loadbalancer_client', 'show_loadbalancer',
+                'LoadbalancerClient', 'show_loadbalancer',
                 expected_allowed, lb[const.ID])
 
         # Attempt to clean up so that one full test run doesn't start 10+
@@ -745,7 +745,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'loadbalancer_client', 'update_loadbalancer',
+                'LoadbalancerClient', 'update_loadbalancer',
                 expected_allowed, None, None, lb[const.ID],
                 admin_state_up=True)
 
@@ -840,7 +840,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'loadbalancer_client', 'get_loadbalancer_stats',
+                'LoadbalancerClient', 'get_loadbalancer_stats',
                 expected_allowed, lb[const.ID])
 
         stats = self.mem_lb_client.get_loadbalancer_stats(lb[const.ID])
@@ -911,7 +911,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'loadbalancer_client', 'get_loadbalancer_status',
+                'LoadbalancerClient', 'get_loadbalancer_status',
                 expected_allowed, lb[const.ID])
 
         status = self.mem_lb_client.get_loadbalancer_status(lb[const.ID])
@@ -983,7 +983,7 @@
             expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'loadbalancer_client', 'failover_loadbalancer',
+                'LoadbalancerClient', 'failover_loadbalancer',
                 expected_allowed, None, None, lb[const.ID])
 
         # Assert we didn't go into PENDING_*
@@ -995,8 +995,9 @@
                 query_params='{loadbalancer_id}={lb_id}'.format(
                     loadbalancer_id=const.LOADBALANCER_ID, lb_id=lb[const.ID]))
 
-        self.os_roles_lb_admin.loadbalancer_client.failover_loadbalancer(
-            lb[const.ID])
+        admin_lb_client = (
+            self.os_roles_lb_admin.load_balancer_v2.LoadbalancerClient())
+        admin_lb_client.failover_loadbalancer(lb[const.ID])
 
         lb = waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
                                      lb[const.ID], const.PROVISIONING_STATUS,
diff --git a/octavia_tempest_plugin/tests/api/v2/test_member.py b/octavia_tempest_plugin/tests/api/v2/test_member.py
index a5607da..aa7cf25 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_member.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_member.py
@@ -887,9 +887,10 @@
         # Test that a user without the load balancer role cannot
         # create a member
         if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
+            member_client = self.os_primary.load_balancer_v2.MemberClient()
             self.assertRaises(
                 exceptions.Forbidden,
-                self.os_primary.member_client.create_member,
+                member_client.create_member,
                 **member_kwargs)
 
         # Test that a user without the loadbalancer role cannot
@@ -905,7 +906,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'member_client', 'create_member',
+                'MemberClient', 'create_member',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **member_kwargs)
@@ -1238,7 +1239,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'member_client', 'list_members', expected_allowed,
+                'MemberClient', 'list_members', expected_allowed,
                 test_ids, pool_id)
 
         # Test that users without the lb member role cannot list members
@@ -1261,7 +1262,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'member_client', 'list_members', expected_allowed, pool_id)
+                'MemberClient', 'list_members', expected_allowed, pool_id)
 
         # Check the default sort order, created_at
         members = self.mem_member_client.list_members(pool_id)
@@ -1802,7 +1803,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'member_client', 'show_member',
+                'MemberClient', 'show_member',
                 expected_allowed, member[const.ID],
                 pool_id=pool_id)
 
@@ -2256,7 +2257,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'member_client', 'update_member',
+                'MemberClient', 'update_member',
                 expected_allowed, None, None, member[const.ID],
                 pool_id=pool_id, admin_state_up=True)
 
@@ -2714,7 +2715,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'member_client', 'update_members',
+                'MemberClient', 'update_members',
                 expected_allowed, None, None,
                 pool_id=pool_id, members_list=batch_update_list)
 
@@ -2959,7 +2960,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'member_client', 'delete_member',
+                'MemberClient', 'delete_member',
                 expected_allowed, None, None, member[const.ID],
                 pool_id=pool_id)
 
diff --git a/octavia_tempest_plugin/tests/api/v2/test_pool.py b/octavia_tempest_plugin/tests/api/v2/test_pool.py
index 565812e..ba31a8e 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_pool.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_pool.py
@@ -414,7 +414,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_create_RBAC_enforcement(
-                'pool_client', 'create_pool',
+                'PoolClient', 'create_pool',
                 expected_allowed,
                 status_method=self.mem_lb_client.show_loadbalancer,
                 obj_id=self.lb_id, **pool_kwargs)
@@ -762,7 +762,7 @@
             expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement_count(
-                'pool_client', 'list_pools', expected_allowed, 0,
+                'PoolClient', 'list_pools', expected_allowed, 0,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
         # Test credentials that should see these pools can see them.
@@ -778,7 +778,7 @@
                                 'os_roles_lb_global_observer']
         if expected_allowed:
             self.check_list_IDs_RBAC_enforcement(
-                'pool_client', 'list_pools', expected_allowed, test_ids,
+                'PoolClient', 'list_pools', expected_allowed, test_ids,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
         # Test that users without the lb member role cannot list pools.
@@ -805,7 +805,7 @@
                                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'pool_client', 'list_pools', expected_allowed,
+                'PoolClient', 'list_pools', expected_allowed,
                 query_params='loadbalancer_id={lb_id}'.format(lb_id=lb_id))
 
         # Check the default sort order, created_at
@@ -1020,7 +1020,7 @@
     @decorators.idempotent_id('bd732c36-bdaa-4591-bf4e-28268874d22c')
     def test_UDP_RR_source_IP_pool_show(self):
         self._test_pool_show(
-            const.HTTP, const.LB_ALGORITHM_ROUND_ROBIN,
+            const.UDP, const.LB_ALGORITHM_ROUND_ROBIN,
             session_persistence=const.SESSION_PERSISTENCE_SOURCE_IP)
 
     def _test_pool_show(self, pool_protocol, algorithm,
@@ -1138,7 +1138,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_show_RBAC_enforcement(
-                'pool_client', 'show_pool',
+                'PoolClient', 'show_pool',
                 expected_allowed, pool[const.ID])
 
     @decorators.idempotent_id('d73755fe-ba3a-4248-9543-8e167a5aa7f4')
@@ -1246,7 +1246,7 @@
     @decorators.idempotent_id('28b90650-a612-4b10-981f-d3dd6a366e4f')
     def test_UDP_RR_source_IP_pool_update(self):
         self._test_pool_update(
-            const.HTTP, const.LB_ALGORITHM_ROUND_ROBIN,
+            const.UDP, const.LB_ALGORITHM_ROUND_ROBIN,
             session_persistence=const.SESSION_PERSISTENCE_SOURCE_IP)
 
     def _test_pool_update(self, pool_protocol, algorithm,
@@ -1370,7 +1370,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_update_RBAC_enforcement(
-                'pool_client', 'update_pool',
+                'PoolClient', 'update_pool',
                 expected_allowed, None, None, pool[const.ID],
                 admin_state_up=True)
 
@@ -1590,7 +1590,7 @@
     @decorators.idempotent_id('cc69c0d0-9191-4faf-a154-e33df880f44e')
     def test_UDP_RR_source_IP_pool_delete(self):
         self._test_pool_delete(
-            const.HTTP, const.LB_ALGORITHM_ROUND_ROBIN,
+            const.UDP, const.LB_ALGORITHM_ROUND_ROBIN,
             session_persistence=const.SESSION_PERSISTENCE_SOURCE_IP)
 
     def _test_pool_delete(self, pool_protocol, algorithm,
@@ -1667,7 +1667,7 @@
                                 'os_roles_lb_member']
         if expected_allowed:
             self.check_delete_RBAC_enforcement(
-                'pool_client', 'delete_pool',
+                'PoolClient', 'delete_pool',
                 expected_allowed, None, None, pool[const.ID])
 
         self.mem_pool_client.delete_pool(pool[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_provider.py b/octavia_tempest_plugin/tests/api/v2/test_provider.py
index ae4a08a..9a9dd28 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_provider.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_provider.py
@@ -60,7 +60,7 @@
                 'os_roles_lb_member', 'os_roles_lb_member2']
         if expected_allowed:
             self.check_list_RBAC_enforcement(
-                'provider_client', 'list_providers', expected_allowed)
+                'ProviderClient', 'list_providers', expected_allowed)
 
         providers = self.mem_provider_client.list_providers()
 
diff --git a/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py b/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
index 843388e..3f41892 100644
--- a/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
+++ b/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
@@ -99,6 +99,23 @@
         return new_cert, new_key, new_secret_ref
 
     @classmethod
+    def _load_pool_pki(cls):
+        # Create the pkcs12 bundle
+        pkcs12 = cert_utils.generate_pkcs12_bundle(cls.member_client_cert,
+                                                   cls.member_client_key)
+        LOG.debug('Pool client PKCS12 bundle: %s', base64.b64encode(pkcs12))
+
+        cls.pool_client_ref = cls._store_secret(cls.barbican_mgr, pkcs12)
+
+        cls.pool_CA_ref = cls._store_secret(
+            cls.barbican_mgr,
+            cls.member_ca_cert.public_bytes(serialization.Encoding.PEM))
+
+        cls.pool_CRL_ref = cls._store_secret(
+            cls.barbican_mgr,
+            cls.member_crl.public_bytes(serialization.Encoding.PEM))
+
+    @classmethod
     def resource_setup(cls):
         """Setup resources needed by the tests."""
         super(TLSWithBarbicanTest, cls).resource_setup()
@@ -174,6 +191,8 @@
             cls.barbican_mgr,
             cls.client_crl.public_bytes(serialization.Encoding.PEM))
 
+        cls._load_pool_pki()
+
         # Setup a load balancer for the tests to use
         lb_name = data_utils.rand_name("lb_member_lb1-tls")
         lb_kwargs = {const.PROVIDER: CONF.load_balancer.provider,
@@ -1197,3 +1216,149 @@
     def test_http_1_1_tls_traffic(self):
         self._test_http_versions_tls_traffic(
             'HTTP/1.1', ['http/1.1', 'http/1.0'])
+
+    @decorators.idempotent_id('ee0faf71-d11e-4323-8673-e5e15779749b')
+    def test_pool_reencryption(self):
+        if not self.mem_listener_client.is_version_supported(
+                self.api_version, '2.8'):
+            raise self.skipException('Pool re-encryption is only available on '
+                                     'Octavia API version 2.8 or newer.')
+        pool_name = data_utils.rand_name("lb_member_pool1-tls-reencrypt")
+        pool_kwargs = {
+            const.NAME: pool_name,
+            const.PROTOCOL: const.HTTP,
+            const.LB_ALGORITHM: self.lb_algorithm,
+            const.LOADBALANCER_ID: self.lb_id,
+            const.TLS_ENABLED: True
+        }
+        pool = self.mem_pool_client.create_pool(**pool_kwargs)
+        pool_id = pool[const.ID]
+
+        waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
+                                self.lb_id, const.PROVISIONING_STATUS,
+                                const.ACTIVE,
+                                CONF.load_balancer.build_interval,
+                                CONF.load_balancer.build_timeout)
+
+        # Set up Member 1 for Webserver 1
+        member1_name = data_utils.rand_name("lb_member_member1-tls-reencrypt")
+        member1_kwargs = {
+            const.POOL_ID: pool_id,
+            const.NAME: member1_name,
+            const.ADMIN_STATE_UP: True,
+            const.ADDRESS: self.webserver1_ip,
+            const.PROTOCOL_PORT: 443,
+        }
+        if self.lb_member_1_subnet:
+            member1_kwargs[const.SUBNET_ID] = self.lb_member_1_subnet[const.ID]
+
+        self.mem_member_client.create_member(**member1_kwargs)
+        waiters.wait_for_status(
+            self.mem_lb_client.show_loadbalancer, self.lb_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+
+        # Set up Member 2 for Webserver 2
+        member2_name = data_utils.rand_name("lb_member_member2-tls-reencrypt")
+        member2_kwargs = {
+            const.POOL_ID: pool_id,
+            const.NAME: member2_name,
+            const.ADMIN_STATE_UP: True,
+            const.ADDRESS: self.webserver2_ip,
+            const.PROTOCOL_PORT: 443,
+        }
+        if self.lb_member_2_subnet:
+            member2_kwargs[const.SUBNET_ID] = self.lb_member_2_subnet[const.ID]
+
+        self.mem_member_client.create_member(**member2_kwargs)
+        waiters.wait_for_status(
+            self.mem_lb_client.show_loadbalancer, self.lb_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+
+        listener_name = data_utils.rand_name(
+            "lb_member_listener1-tls-reencrypt")
+        listener_kwargs = {
+            const.NAME: listener_name,
+            const.PROTOCOL: const.HTTP,
+            const.PROTOCOL_PORT: '84',
+            const.LOADBALANCER_ID: self.lb_id,
+            const.DEFAULT_POOL_ID: pool_id,
+        }
+        listener = self.mem_listener_client.create_listener(**listener_kwargs)
+        self.listener_id = listener[const.ID]
+
+        waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
+                                self.lb_id, const.PROVISIONING_STATUS,
+                                const.ACTIVE,
+                                CONF.load_balancer.build_interval,
+                                CONF.load_balancer.build_timeout)
+
+        # Test with no CA validation
+        self.check_members_balanced(self.lb_vip_address, protocol=const.HTTP,
+                                    protocol_port=84)
+
+        # Test with CA validation - invalid CA
+        pool_update_kwargs = {
+            const.CA_TLS_CONTAINER_REF: self.client_ca_cert_ref
+        }
+
+        self.mem_pool_client.update_pool(pool_id, **pool_update_kwargs)
+
+        waiters.wait_for_status(
+            self.mem_lb_client.show_loadbalancer, self.lb_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+        waiters.wait_for_status(
+            self.mem_pool_client.show_pool, pool_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+
+        url = 'http://{0}:84'.format(self.lb_vip_address)
+        self.validate_URL_response(url, expected_status_code=503)
+
+        # Test with CA validation - valid CA
+        pool_update_kwargs = {
+            const.CA_TLS_CONTAINER_REF: self.pool_CA_ref
+        }
+
+        self.mem_pool_client.update_pool(pool_id, **pool_update_kwargs)
+
+        waiters.wait_for_status(
+            self.mem_lb_client.show_loadbalancer, self.lb_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+        waiters.wait_for_status(
+            self.mem_pool_client.show_pool, pool_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+
+        self.check_members_balanced(self.lb_vip_address, protocol=const.HTTP,
+                                    protocol_port=84)
+
+        # Test with CRL including one webserver certificate revoked
+        pool_update_kwargs = {
+            const.CRL_CONTAINER_REF: self.pool_CRL_ref
+        }
+
+        self.mem_pool_client.update_pool(pool_id, **pool_update_kwargs)
+
+        waiters.wait_for_status(
+            self.mem_lb_client.show_loadbalancer, self.lb_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+        waiters.wait_for_status(
+            self.mem_pool_client.show_pool, pool_id,
+            const.PROVISIONING_STATUS, const.ACTIVE,
+            CONF.load_balancer.check_interval,
+            CONF.load_balancer.check_timeout)
+
+        self.check_members_balanced(self.lb_vip_address, protocol=const.HTTP,
+                                    protocol_port=84, traffic_member_count=1)
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_ipv6_traffic_ops.py b/octavia_tempest_plugin/tests/scenario/v2/test_ipv6_traffic_ops.py
index 717ddf9..4efa241 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_ipv6_traffic_ops.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_ipv6_traffic_ops.py
@@ -493,6 +493,8 @@
         # wait until Neutron completes the SG update.
         # See https://bugs.launchpad.net/neutron/+bug/1866353.
         def expect_timeout_error(address, protocol, protocol_port):
+            if protocol != const.UDP:
+                address = "[{}]".format(address)
             try:
                 self.make_request(address, protocol=protocol,
                                   protocol_port=protocol_port)
diff --git a/octavia_tempest_plugin/tests/spare_pool_scenario/v2/test_spare_pool.py b/octavia_tempest_plugin/tests/spare_pool_scenario/v2/test_spare_pool.py
index e641bc4..0ccfe55 100644
--- a/octavia_tempest_plugin/tests/spare_pool_scenario/v2/test_spare_pool.py
+++ b/octavia_tempest_plugin/tests/spare_pool_scenario/v2/test_spare_pool.py
@@ -57,10 +57,10 @@
         * Send traffic through load balancer
         * Validate amphora spare pool size is restored
         """
-
+        amphora_client = self.os_admin.load_balancer_v2.AmphoraClient()
         # Check there is at least one amphora in spare pool
         spare_amps = waiters.wait_for_spare_amps(
-            self.os_admin.amphora_client.list_amphorae,
+            amphora_client.list_amphorae,
             CONF.load_balancer.lb_build_interval,
             CONF.load_balancer.lb_build_timeout)
 
@@ -100,7 +100,7 @@
 
         # Confirm the spare pool has changed since last check
         spare_amps_2 = waiters.wait_for_spare_amps(
-            self.os_admin.amphora_client.list_amphorae,
+            amphora_client.list_amphorae,
             CONF.load_balancer.lb_build_interval,
             CONF.load_balancer.lb_build_timeout)
         self.assertNotEqual(spare_amps, spare_amps_2)
@@ -180,12 +180,12 @@
 
         # Check there is at least one amphora in spare pool
         spare_amps = waiters.wait_for_spare_amps(
-            self.os_admin.amphora_client.list_amphorae,
+            amphora_client.list_amphorae,
             CONF.load_balancer.lb_build_interval,
             CONF.load_balancer.lb_build_timeout)
 
         # Delete amphora compute instance
-        amp = self.os_admin.amphora_client.list_amphorae(
+        amp = amphora_client.list_amphorae(
             query_params='{loadbalancer_id}={lb_id}'.format(
                 loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
 
@@ -211,12 +211,12 @@
 
         # Confirm the spare pool has changed since last check
         spare_amps_2 = waiters.wait_for_spare_amps(
-            self.os_admin.amphora_client.list_amphorae,
+            amphora_client.list_amphorae,
             CONF.load_balancer.lb_build_interval,
             CONF.load_balancer.lb_build_timeout)
         self.assertNotEqual(spare_amps, spare_amps_2)
 
         # Check there is at least one amphora in spare pool
-        waiters.wait_for_spare_amps(self.os_admin.amphora_client.list_amphorae,
+        waiters.wait_for_spare_amps(amphora_client.list_amphorae,
                                     CONF.load_balancer.lb_build_interval,
                                     CONF.load_balancer.lb_build_timeout)
diff --git a/octavia_tempest_plugin/tests/test_base.py b/octavia_tempest_plugin/tests/test_base.py
index b9438e4..e7a344d 100644
--- a/octavia_tempest_plugin/tests/test_base.py
+++ b/octavia_tempest_plugin/tests/test_base.py
@@ -30,7 +30,6 @@
 from tempest import test
 import tenacity
 
-from octavia_tempest_plugin import clients
 from octavia_tempest_plugin.common import cert_utils
 from octavia_tempest_plugin.common import constants as const
 from octavia_tempest_plugin.tests import RBAC_tests
@@ -89,7 +88,6 @@
     # Tests shall not mess with the list of allocated credentials
     allocated_credentials = tuple(allocated_creds)
 
-    client_manager = clients.ManagerV2
     webserver1_response = 1
     webserver2_response = 5
     used_ips = []
@@ -165,6 +163,7 @@
     def setup_clients(cls):
         """Setup client aliases."""
         super(LoadBalancerBaseTest, cls).setup_clients()
+        lb_admin_prefix = cls.os_roles_lb_admin.load_balancer_v2
         cls.lb_mem_float_ip_client = cls.os_roles_lb_member.floating_ips_client
         cls.lb_mem_keypairs_client = cls.os_roles_lb_member.keypairs_client
         cls.lb_mem_net_client = cls.os_roles_lb_member.networks_client
@@ -175,33 +174,41 @@
             cls.os_roles_lb_member.security_group_rules_client)
         cls.lb_mem_servers_client = cls.os_roles_lb_member.servers_client
         cls.lb_mem_subnet_client = cls.os_roles_lb_member.subnets_client
-        cls.mem_lb_client = cls.os_roles_lb_member.loadbalancer_client
-        cls.mem_listener_client = cls.os_roles_lb_member.listener_client
-        cls.mem_pool_client = cls.os_roles_lb_member.pool_client
-        cls.mem_member_client = cls.os_roles_lb_member.member_client
+        cls.mem_lb_client = (
+            cls.os_roles_lb_member.load_balancer_v2.LoadbalancerClient())
+        cls.mem_listener_client = (
+            cls.os_roles_lb_member.load_balancer_v2.ListenerClient())
+        cls.mem_pool_client = (
+            cls.os_roles_lb_member.load_balancer_v2.PoolClient())
+        cls.mem_member_client = (
+            cls.os_roles_lb_member.load_balancer_v2.MemberClient())
         cls.mem_healthmonitor_client = (
-            cls.os_roles_lb_member.healthmonitor_client)
-        cls.mem_l7policy_client = cls.os_roles_lb_member.l7policy_client
-        cls.mem_l7rule_client = cls.os_roles_lb_member.l7rule_client
-        cls.lb_admin_amphora_client = cls.os_roles_lb_admin.amphora_client
+            cls.os_roles_lb_member.load_balancer_v2.HealthMonitorClient())
+        cls.mem_l7policy_client = (
+            cls.os_roles_lb_member.load_balancer_v2.L7PolicyClient())
+        cls.mem_l7rule_client = (
+            cls.os_roles_lb_member.load_balancer_v2.L7RuleClient())
+        cls.lb_admin_amphora_client = lb_admin_prefix.AmphoraClient()
         cls.lb_admin_flavor_profile_client = (
-            cls.os_roles_lb_admin.flavor_profile_client)
-        cls.lb_admin_flavor_client = cls.os_roles_lb_admin.flavor_client
-        cls.mem_flavor_client = cls.os_roles_lb_member.flavor_client
-        cls.mem_provider_client = cls.os_roles_lb_member.provider_client
+            lb_admin_prefix.FlavorProfileClient())
+        cls.lb_admin_flavor_client = lb_admin_prefix.FlavorClient()
+        cls.mem_flavor_client = (
+            cls.os_roles_lb_member.load_balancer_v2.FlavorClient())
+        cls.mem_provider_client = (
+            cls.os_roles_lb_member.load_balancer_v2.ProviderClient())
         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)
+            lb_admin_prefix.FlavorCapabilitiesClient())
         cls.lb_admin_availability_zone_capabilities_client = (
-            cls.os_roles_lb_admin.availability_zone_capabilities_client)
+            lb_admin_prefix.AvailabilityZoneCapabilitiesClient())
         cls.lb_admin_availability_zone_profile_client = (
-            cls.os_roles_lb_admin.availability_zone_profile_client)
+            lb_admin_prefix.AvailabilityZoneProfileClient())
         cls.lb_admin_availability_zone_client = (
-            cls.os_roles_lb_admin.availability_zone_client)
+            lb_admin_prefix.AvailabilityZoneClient())
         cls.mem_availability_zone_client = (
-            cls.os_roles_lb_member.availability_zone_client)
+            cls.os_roles_lb_member.load_balancer_v2.AvailabilityZoneClient())
 
     @classmethod
     def resource_setup(cls):
@@ -633,6 +640,19 @@
                 cls.lb_mem_SGr_client.delete_security_group_rule,
                 cls.lb_mem_SGr_client.show_security_group_rule,
                 SGr['id'])
+            # Create a security group rule to allow 443 (test webservers)
+            SGr = cls.lb_mem_SGr_client.create_security_group_rule(
+                direction='ingress',
+                security_group_id=cls.lb_member_sec_group['id'],
+                protocol='tcp',
+                ethertype='IPv4',
+                port_range_min=443,
+                port_range_max=443)['security_group_rule']
+            cls.addClassResourceCleanup(
+                waiters.wait_for_not_found,
+                cls.lb_mem_SGr_client.delete_security_group_rule,
+                cls.lb_mem_SGr_client.show_security_group_rule,
+                SGr['id'])
             # Create a security group rule to allow UDP 9999 (test webservers)
             # Port 9999 is used to illustrate health monitor ERRORs on closed
             # ports.
@@ -689,6 +709,19 @@
                     cls.lb_mem_SGr_client.delete_security_group_rule,
                     cls.lb_mem_SGr_client.show_security_group_rule,
                     SGr['id'])
+                # Create a security group rule to allow 443 (test webservers)
+                SGr = cls.lb_mem_SGr_client.create_security_group_rule(
+                    direction='ingress',
+                    security_group_id=cls.lb_member_sec_group['id'],
+                    protocol='tcp',
+                    ethertype='IPv6',
+                    port_range_min=443,
+                    port_range_max=443)['security_group_rule']
+                cls.addClassResourceCleanup(
+                    waiters.wait_for_not_found,
+                    cls.lb_mem_SGr_client.delete_security_group_rule,
+                    cls.lb_mem_SGr_client.show_security_group_rule,
+                    SGr['id'])
                 # Create a security group rule to allow 22 (ssh)
                 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
                     direction='ingress',
diff --git a/playbooks/prepare-ovn-multinode.yaml b/playbooks/prepare-ovn-multinode.yaml
new file mode 100644
index 0000000..a653a6c
--- /dev/null
+++ b/playbooks/prepare-ovn-multinode.yaml
@@ -0,0 +1,4 @@
+- hosts: all
+  roles:
+    - multi-node-bridge
+    - multi-node-setup
diff --git a/releasenotes/notes/pool-tls-scenario-test-0eb88e731c595b67.yaml b/releasenotes/notes/pool-tls-scenario-test-0eb88e731c595b67.yaml
new file mode 100644
index 0000000..429874a
--- /dev/null
+++ b/releasenotes/notes/pool-tls-scenario-test-0eb88e731c595b67.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Added scenario test coverage for pool re-encryption.
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 9bf2759..77615e1 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -268,9 +268,17 @@
     name: octavia-dsvm-live-two-node-base
     parent: octavia-dsvm-base
     nodeset: octavia-two-node
-    timeout: 9000
+    timeout: 10800
     required-projects:
       - openstack/diskimage-builder
+    roles:
+      - zuul: openstack/neutron-tempest-plugin
+    pre-run: playbooks/prepare-ovn-multinode.yaml
+    vars:
+      zuul_copy_output:
+        '/var/log/dib-build': logs
+        '/var/log/octavia-amphora.log': logs
+        '/var/log/octavia-tenant-traffic.log': logs
     host-vars:
       controller:
         configure_swap_size: 8192
@@ -310,10 +318,6 @@
           octavia-tempest-plugin: https://opendev.org/openstack/octavia-tempest-plugin.git
         tempest_plugins:
           - octavia-tempest-plugin
-        zuul_copy_output:
-          '/var/log/dib-build' : logs
-          '/var/log/octavia-amphora.log': logs
-          '/var/log/octavia-tenant-traffic.log': logs
       controller2:
         configure_swap_size: 8192
         devstack_localrc:
@@ -350,13 +354,8 @@
           OCTAVIA_USE_PREGENERATED_CERTS: true
           OCTAVIA_MGMT_PORT_IP: 192.168.0.4
         devstack_plugins:
+          neutron: https://opendev.org/openstack/neutron.git
           octavia: https://opendev.org/openstack/octavia.git
-          octavia-tempest-plugin: https://opendev.org/openstack/octavia-tempest-plugin.git
-        tempest_plugins:
-          - octavia-tempest-plugin
-        zuul_copy_output:
-          '/var/log/octavia-amphora.log': logs
-          '/var/log/octavia-tenant-traffic.log': logs
     group-vars:
       controller:
         devstack_local_conf:
@@ -368,6 +367,9 @@
                 api_v1_enabled: False
               amphora_agent:
                 forward_all_logs: True
+            "/$NEUTRON_CORE_PLUGIN_CONF":
+              ovn:
+                enable_distributed_floating_ip: True
         devstack_services:
           base: false
           barbican: false
@@ -391,11 +393,16 @@
           o-cw: true
           o-hm: true
           o-hk: true
+          ovn-controller: true
+          ovn-northd: true
+          ovn-vswitchd: true
+          ovsdb-server: true
           placement-api: true
-          q-agt: true
-          q-dhcp: true
-          q-l3: true
-          q-meta: true
+          q-agt: false
+          q-dhcp: false
+          q-l3: false
+          q-meta: false
+          q-ovn-metadata-agent: true
           q-svc: true
           rabbit: true
           tempest: true
@@ -410,6 +417,9 @@
                 api_v1_enabled: False
               amphora_agent:
                 forward_all_logs: True
+            "/$NEUTRON_CORE_PLUGIN_CONF":
+              ovn:
+                enable_distributed_floating_ip: True
         devstack_services:
           c-vol: false
           c-bak: false
@@ -418,7 +428,16 @@
           o-cw: true
           o-hm: true
           o-hk: true
-          q-agt: true
+          ovn-controller: true
+          ovn-northd: false
+          ovn-vswitchd: true
+          ovsdb-server: true
+          q-fake: true
+          q-agt: false
+          q-dhcp: false
+          q-l3: false
+          q-meta: false
+          q-ovn-metadata-agent: true
 
 - job:
     name: octavia-dsvm-noop-base
@@ -454,6 +473,7 @@
 - job:
     name: octavia-v2-dsvm-noop-api
     parent: octavia-dsvm-noop-base
+    timeout: 10800
     vars:
       devstack_local_conf:
         post-config:
@@ -500,6 +520,11 @@
         USE_PYTHON3: False
 
 - job:
+    name: octavia-v2-dsvm-noop-api-stable-wallaby
+    parent: octavia-v2-dsvm-noop-api
+    override-checkout: stable/wallaby
+
+- job:
     name: octavia-v2-dsvm-noop-api-stable-victoria
     parent: octavia-v2-dsvm-noop-api
     override-checkout: stable/victoria
@@ -571,6 +596,10 @@
         override-checkout: 2.30.0
 
 - job:
+    name: octavia-v2-dsvm-scenario-stable-wallaby
+    parent: octavia-v2-dsvm-scenario
+    override-checkout: stable/wallaby
+- job:
     name: octavia-v2-dsvm-scenario-stable-victoria
     parent: octavia-v2-dsvm-scenario
     override-checkout: stable/victoria
@@ -624,19 +653,30 @@
 - job:
     name: octavia-v2-act-stdby-dsvm-scenario-two-node
     parent: octavia-dsvm-live-two-node-base
-    vars:
-      tempest_concurrency: 2
-      tempest_test_regex: ^octavia_tempest_plugin.tests.scenario.v2
-      tox_envlist: all
-      devstack_local_conf:
-        post-config:
+    group-vars:
+      controller:
+        tempest_concurrency: 2
+        tempest_test_regex: ^octavia_tempest_plugin.tests.scenario.v2
+        tox_envlist: all
+        devstack_local_conf:
+          post-config:
             $OCTAVIA_CONF:
               nova:
                 enable_anti_affinity: True
-        test-config:
-          "$TEMPEST_CONFIG":
-            load_balancer:
-              loadbalancer_topology: ACTIVE_STANDBY
+              controller_worker:
+                loadbalancer_topology: ACTIVE_STANDBY
+          test-config:
+            "$TEMPEST_CONFIG":
+              load_balancer:
+                loadbalancer_topology: ACTIVE_STANDBY
+      subnode:
+        devstack_local_conf:
+          post-config:
+            $OCTAVIA_CONF:
+              nova:
+                enable_anti_affinity: True
+              controller_worker:
+                loadbalancer_topology: ACTIVE_STANDBY
 
 - job:
     name: octavia-v2-dsvm-py2-scenario-centos-7
@@ -702,6 +742,11 @@
       - ^octavia_tempest_plugin/tests/(?!barbican_scenario/|\w+\.py).*
 
 - job:
+    name: octavia-v2-dsvm-tls-barbican-stable-wallaby
+    parent: octavia-v2-dsvm-tls-barbican
+    override-checkout: stable/wallaby
+
+- job:
     name: octavia-v2-dsvm-tls-barbican-stable-victoria
     parent: octavia-v2-dsvm-tls-barbican
     override-checkout: stable/victoria
@@ -756,6 +801,11 @@
         override-checkout: 2.30.0
 
 - job:
+    name: octavia-v2-dsvm-spare-pool-stable-wallaby
+    parent: octavia-v2-dsvm-spare-pool
+    override-checkout: stable/wallaby
+
+- job:
     name: octavia-v2-dsvm-spare-pool-stable-victoria
     parent: octavia-v2-dsvm-spare-pool
     override-checkout: stable/victoria
@@ -902,6 +952,11 @@
       tox_envlist: all
 
 - job:
+    name: octavia-v2-act-stdby-dsvm-scenario-stable-wallaby
+    parent: octavia-v2-act-stdby-dsvm-scenario
+    override-checkout: stable/wallaby
+
+- job:
     name: octavia-v2-act-stdby-dsvm-scenario-stable-victoria
     parent: octavia-v2-act-stdby-dsvm-scenario
     override-checkout: stable/victoria
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index f872c59..6d1b15a 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -9,15 +9,18 @@
     check:
       jobs:
         - octavia-v2-dsvm-noop-api
+        - octavia-v2-dsvm-noop-api-stable-wallaby
         - octavia-v2-dsvm-noop-api-stable-victoria
         - octavia-v2-dsvm-noop-api-stable-ussuri
         - octavia-v2-dsvm-noop-api-stable-train
         - octavia-v2-dsvm-noop-api-scoped-tokens
         - octavia-v2-dsvm-scenario
+        - octavia-v2-dsvm-scenario-stable-wallaby
         - octavia-v2-dsvm-scenario-stable-victoria
         - octavia-v2-dsvm-scenario-stable-ussuri
         - octavia-v2-dsvm-scenario-stable-train
         - octavia-v2-dsvm-tls-barbican
+        - octavia-v2-dsvm-tls-barbican-stable-wallaby
         - octavia-v2-dsvm-tls-barbican-stable-victoria
         - octavia-v2-dsvm-tls-barbican-stable-ussuri
         - octavia-v2-dsvm-tls-barbican-stable-train
@@ -29,6 +32,8 @@
             voting: false
         - octavia-v2-act-stdby-dsvm-scenario:
             voting: false
+        - octavia-v2-act-stdby-dsvm-scenario-stable-wallaby:
+            voting: false
         - octavia-v2-act-stdby-dsvm-scenario-stable-victoria:
             voting: false
         - octavia-v2-act-stdby-dsvm-scenario-stable-ussuri:
@@ -37,6 +42,8 @@
             voting: false
         - octavia-v2-dsvm-spare-pool:
             voting: false
+        - octavia-v2-dsvm-spare-pool-stable-wallaby:
+            voting: false
         - octavia-v2-dsvm-spare-pool-stable-victoria:
             voting: false
         - octavia-v2-dsvm-spare-pool-stable-ussuri:
@@ -55,15 +62,18 @@
       queue: octavia
       jobs:
         - octavia-v2-dsvm-noop-api
+        - octavia-v2-dsvm-noop-api-stable-wallaby
         - octavia-v2-dsvm-noop-api-stable-victoria
         - octavia-v2-dsvm-noop-api-stable-ussuri
         - octavia-v2-dsvm-noop-api-stable-train
         - octavia-v2-dsvm-noop-api-scoped-tokens
         - octavia-v2-dsvm-scenario
+        - octavia-v2-dsvm-scenario-stable-wallaby
         - octavia-v2-dsvm-scenario-stable-victoria
         - octavia-v2-dsvm-scenario-stable-ussuri
         - octavia-v2-dsvm-scenario-stable-train
         - octavia-v2-dsvm-tls-barbican
+        - octavia-v2-dsvm-tls-barbican-stable-wallaby
         - octavia-v2-dsvm-tls-barbican-stable-victoria
         - octavia-v2-dsvm-tls-barbican-stable-ussuri
         - octavia-v2-dsvm-tls-barbican-stable-train