Merge "Fix VIP IPv6 subnet discovery order"
diff --git a/doc/requirements.txt b/doc/requirements.txt
index d2e8cfc..ddf8411 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -3,7 +3,8 @@
 # process, which may cause wedges in the gate later.
 
 sphinxcontrib-apidoc>=0.2.0 # BSD
-sphinx>=1.6.2,!=1.6.6,!=1.6.7 # BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7'  # BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2,!=2.1.0;python_version>='3.4'  # BSD
 openstackdocstheme>=1.18.1 # Apache-2.0
 
 # releasenotes
diff --git a/octavia_tempest_plugin/clients.py b/octavia_tempest_plugin/clients.py
index 8409093..f85404c 100644
--- a/octavia_tempest_plugin/clients.py
+++ b/octavia_tempest_plugin/clients.py
@@ -41,7 +41,6 @@
     provider_client)
 
 CONF = config.CONF
-SERVICE_TYPE = 'load-balancer'
 
 
 class ManagerV2(clients.Manager):
@@ -49,28 +48,29 @@
     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,
+            '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(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.listener_client = listener_client.ListenerClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.pool_client = pool_client.PoolClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.member_client = member_client.MemberClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
+            **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(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.l7policy_client = l7policy_client.L7PolicyClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.l7rule_client = l7rule_client.L7RuleClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.amphora_client = amphora_client.AmphoraClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
+            **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(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.flavor_client = flavor_client.FlavorClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
-        self.provider_client = provider_client.ProviderClient(
-            self.auth_provider, SERVICE_TYPE, CONF.identity.region)
+            **params)
+        self.flavor_client = flavor_client.FlavorClient(**params)
+        self.provider_client = provider_client.ProviderClient(**params)
         self.flavor_capabilities_client = (
-            flavor_capabilities_client.FlavorCapabilitiesClient(
-                self.auth_provider, SERVICE_TYPE, CONF.identity.region))
+            flavor_capabilities_client.FlavorCapabilitiesClient(**params))
diff --git a/octavia_tempest_plugin/common/constants.py b/octavia_tempest_plugin/common/constants.py
index 7ddcb7a..e767298 100644
--- a/octavia_tempest_plugin/common/constants.py
+++ b/octavia_tempest_plugin/common/constants.py
@@ -97,6 +97,7 @@
 SORT = 'sort'
 SINGLE = 'SINGLE'
 ACTIVE_STANDBY = 'ACTIVE_STANDBY'
+SUPPORTED_LB_TOPOLOGIES = (SINGLE, ACTIVE_STANDBY)
 
 # Protocols
 HTTP = 'HTTP'
diff --git a/octavia_tempest_plugin/config.py b/octavia_tempest_plugin/config.py
index 11dc59f..7c4ed2f 100644
--- a/octavia_tempest_plugin/config.py
+++ b/octavia_tempest_plugin/config.py
@@ -102,15 +102,32 @@
                     'default RBAC tests. "owner_or_admin" runs the legacy '
                     'owner or admin tests. "none" disables the RBAC tests.'),
     cfg.DictOpt('enabled_provider_drivers',
-                help=('List of enabled provider drivers and description '
-                      'dictionaries. Must match the driver name in the '
+                help=('A comma separated list of dictionaries of the '
+                      'enabled provider driver names and descriptions. '
+                      'Must match the driver name in the '
                       'octavia.api.drivers entrypoint. Example: '
-                      '{\'amphora\': \'The Octavia Amphora driver.\', '
-                      '\'octavia\': \'Deprecated alias of the Octavia '
-                      'Amphora driver.\'}'),
+                      'amphora:The Octavia Amphora driver.,'
+                      'octavia:Deprecated alias of the Octavia '
+                      'Amphora driver.'),
                 default={'amphora': 'The Octavia Amphora driver.',
                          'octavia': 'Deprecated alias of the Octavia Amphora '
                          'driver.'}),
+    cfg.StrOpt('loadbalancer_topology',
+               default=const.SINGLE,
+               choices=const.SUPPORTED_LB_TOPOLOGIES,
+               help='Load balancer topology configuration.'),
+    cfg.DictOpt('expected_flavor_capability',
+                help=('Defines a provider flavor capability that is expected '
+                      'to be present in the selected provider under test. '
+                      'It is specified in a "name": "description" dict. '
+                      'Example: {"loadbalancer_topology": "The load balancer '
+                      'topology. One of: SINGLE - One amphora per load '
+                      'balancer. ACTIVE_STANDBY - Two amphora per load '
+                      'balancer."}'),
+                default={'loadbalancer_topology': 'The load balancer '
+                         'topology. One of: SINGLE - One amphora per load '
+                         'balancer. ACTIVE_STANDBY - Two amphora per load '
+                         'balancer.'}),
     # Networking
     cfg.BoolOpt('test_with_ipv6',
                 default=True,
@@ -196,4 +213,8 @@
                default=False,
                help="Wether spare pool is available with amphora provider "
                     "driver or not."),
+    cfg.BoolOpt('session_persistence_enabled',
+                default=True,
+                help="Whether session persistence is supported with the "
+                     "provider driver."),
 ]
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py b/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
index ce324cb..4094515 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
@@ -157,3 +157,73 @@
             return jsonutils.loads(body.decode('utf-8'))[self.stats_root_tag]
         else:
             return jsonutils.loads(body.decode('utf-8'))
+
+    def update_amphora_config(self, amphora_id):
+        """Update the amphora agent configuration.
+
+        :param amphora_id: The ID of the amphora to update.
+        :raises AssertionError: if the expected_code isn't a valid http success
+                                response code
+        :raises BadRequest: If a 400 response code is received
+        :raises Conflict: If a 409 response code is received
+        :raises Forbidden: If a 403 response code is received
+        :raises Gone: If a 410 response code is received
+        :raises InvalidContentType: If a 415 response code is received
+        :raises InvalidHTTPResponseBody: The response body wasn't valid JSON
+        :raises InvalidHttpSuccessCode: if the read code isn't an expected
+                                        http success code
+        :raises NotFound: If a 404 response code is received
+        :raises NotImplemented: If a 501 response code is received
+        :raises OverLimit: If a 413 response code is received and over_limit is
+                           not in the response body
+        :raises RateLimitExceeded: If a 413 response code is received and
+                                   over_limit is in the response body
+        :raises ServerFault: If a 500 response code is received
+        :raises Unauthorized: If a 401 response code is received
+        :raises UnexpectedContentType: If the content-type of the response
+                                       isn't an expect type
+        :raises UnexpectedResponseCode: If a response code above 400 is
+                                        received and it doesn't fall into any
+                                        of the handled checks
+        :raises UnprocessableEntity: If a 422 response code is received and
+                                     couldn't be parsed
+        :returns: None
+        """
+        uri = '{0}/{1}/config'.format(self.uri, amphora_id)
+        response, body = self.put(uri, '')
+        self.expected_success(202, response.status)
+
+    def amphora_failover(self, amphora_id):
+        """Failover an amphora.
+
+        :param amphora_id: The ID of the amphora to failover.
+        :raises AssertionError: if the expected_code isn't a valid http success
+                                response code
+        :raises BadRequest: If a 400 response code is received
+        :raises Conflict: If a 409 response code is received
+        :raises Forbidden: If a 403 response code is received
+        :raises Gone: If a 410 response code is received
+        :raises InvalidContentType: If a 415 response code is received
+        :raises InvalidHTTPResponseBody: The response body wasn't valid JSON
+        :raises InvalidHttpSuccessCode: if the read code isn't an expected
+                                        http success code
+        :raises NotFound: If a 404 response code is received
+        :raises NotImplemented: If a 501 response code is received
+        :raises OverLimit: If a 413 response code is received and over_limit is
+                           not in the response body
+        :raises RateLimitExceeded: If a 413 response code is received and
+                                   over_limit is in the response body
+        :raises ServerFault: If a 500 response code is received
+        :raises Unauthorized: If a 401 response code is received
+        :raises UnexpectedContentType: If the content-type of the response
+                                       isn't an expect type
+        :raises UnexpectedResponseCode: If a response code above 400 is
+                                        received and it doesn't fall into any
+                                        of the handled checks
+        :raises UnprocessableEntity: If a 422 response code is received and
+                                     couldn't be parsed
+        :returns: None
+        """
+        uri = '{0}/{1}/failover'.format(self.uri, amphora_id)
+        response, body = self.put(uri, '')
+        self.expected_success(202, response.status)
diff --git a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
index 40418a2..97886b5 100644
--- a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
+++ b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
@@ -46,6 +46,10 @@
                                     "or 'octavia' (alias to 'amphora', "
                                     "deprecated) set.")
 
+        if CONF.load_balancer.loadbalancer_topology != const.ACTIVE_STANDBY:
+            raise cls.skipException("Configured load balancer topology is not "
+                                    "%s." % const.ACTIVE_STANDBY)
+
     @classmethod
     def resource_setup(cls):
         """Setup resources needed by the tests."""
diff --git a/octavia_tempest_plugin/tests/api/v2/test_amphora.py b/octavia_tempest_plugin/tests/api/v2/test_amphora.py
new file mode 100644
index 0000000..7873679
--- /dev/null
+++ b/octavia_tempest_plugin/tests/api/v2/test_amphora.py
@@ -0,0 +1,134 @@
+#    Copyright 2019 Rackspace US Inc.  All rights reserved.
+#
+#    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 config
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+from tempest.lib import exceptions
+
+from octavia_tempest_plugin.common import constants as const
+from octavia_tempest_plugin.tests import test_base
+from octavia_tempest_plugin.tests import waiters
+
+CONF = config.CONF
+
+
+class AmphoraAPITest(test_base.LoadBalancerBaseTest):
+    """Test the amphora object API."""
+
+    @classmethod
+    def skip_checks(cls):
+        super(AmphoraAPITest, cls).skip_checks()
+        if CONF.load_balancer.provider not in ['amphora', 'octavia']:
+            raise cls.skipException('Amphora tests only run with the amphora '
+                                    'provider enabled.')
+
+    @classmethod
+    def resource_setup(cls):
+        """Setup resources needed by the tests."""
+        super(AmphoraAPITest, cls).resource_setup()
+
+        lb_name = data_utils.rand_name("lb_member_lb1-amphora-api")
+        lb_kwargs = {const.PROVIDER: CONF.load_balancer.provider,
+                     const.NAME: lb_name}
+
+        cls._setup_lb_network_kwargs(lb_kwargs)
+
+        lb = cls.mem_lb_client.create_loadbalancer(**lb_kwargs)
+        cls.lb_id = lb[const.ID]
+        cls.addClassResourceCleanup(
+            cls.mem_lb_client.cleanup_loadbalancer,
+            cls.lb_id)
+
+        waiters.wait_for_status(cls.mem_lb_client.show_loadbalancer,
+                                cls.lb_id, const.PROVISIONING_STATUS,
+                                const.ACTIVE,
+                                CONF.load_balancer.lb_build_interval,
+                                CONF.load_balancer.lb_build_timeout)
+
+    @decorators.idempotent_id('b7fc231b-dcfa-47a5-99f3-ec5ddcc48f30')
+    def test_amphora_update(self):
+        """Tests the amphora agent configuration update API
+
+        * Tests that users without the loadbalancer admin role cannot
+          update an amphora.
+        * Update the amphora.
+        """
+
+        # 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.lb_admin_amphora_client.is_version_supported(
+                self.api_version, '2.7'):
+            raise self.skipException('Amphora update is only available on '
+                                     'Octavia API version 2.7 or newer.')
+
+        amphorae = self.lb_admin_amphora_client.list_amphorae(
+            query_params='{loadbalancer_id}={lb_id}'.format(
+                loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
+        amphora_1 = amphorae[0]
+
+        # Test that a user without the load balancer admin role cannot
+        # create a flavor
+        if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
+            self.assertRaises(
+                exceptions.Forbidden,
+                self.os_primary.amphora_client.update_amphora_config,
+                amphora_1[const.ID])
+
+        self.lb_admin_amphora_client.update_amphora_config(amphora_1[const.ID])
+
+        # TODO(johnsom) Assert that an amphora config setting updated
+        #               when we have a setting to check.
+
+        amp = self.lb_admin_amphora_client.show_amphora(amphora_1[const.ID])
+
+        self.assertEqual(const.STATUS_ALLOCATED, amp[const.STATUS])
+
+    @decorators.idempotent_id('fb772680-b2ba-4fc3-989b-95ad8492ccaf')
+    def test_amphora_failover(self):
+        """Tests the amphora failover API.
+
+        * Validates that non-admin accounts cannot failover amphora
+        * Fails over an amphora
+        * Validates that a new amphora is built
+        """
+        amphorae = self.lb_admin_amphora_client.list_amphorae(
+            query_params='{loadbalancer_id}={lb_id}'.format(
+                loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
+        amphora_1 = amphorae[0]
+
+        # Test RBAC not authorized for non-admin role
+        if not CONF.load_balancer.RBAC_test_type == const.NONE:
+            self.assertRaises(exceptions.Forbidden,
+                              self.os_primary.amphora_client.amphora_failover,
+                              amphora_1[const.ID])
+            self.assertRaises(
+                exceptions.Forbidden,
+                self.os_roles_lb_member.amphora_client.amphora_failover,
+                amphora_1[const.ID])
+
+        self.lb_admin_amphora_client.amphora_failover(amphora_1[const.ID])
+
+        waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
+                                self.lb_id, const.PROVISIONING_STATUS,
+                                const.ACTIVE,
+                                CONF.load_balancer.lb_build_interval,
+                                CONF.load_balancer.lb_build_timeout)
+
+        after_amphorae = self.lb_admin_amphora_client.list_amphorae(
+            query_params='{loadbalancer_id}={lb_id}'.format(
+                loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
+
+        for new_amp in after_amphorae:
+            self.assertNotEqual(amphora_1[const.ID], new_amp[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py b/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
new file mode 100644
index 0000000..924c044
--- /dev/null
+++ b/octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
@@ -0,0 +1,83 @@
+#    Copyright 2019 Rackspace US Inc.  All rights reserved.
+#
+#    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 config
+from tempest.lib import decorators
+from tempest.lib import exceptions
+
+from octavia_tempest_plugin.common import constants as const
+from octavia_tempest_plugin.tests import test_base
+
+CONF = config.CONF
+
+
+class FlavorCapabilitiesAPITest(test_base.LoadBalancerBaseTest):
+    """Test the provider flavor capabilities API."""
+
+    @decorators.idempotent_id('df837ee3-ca4b-4a4d-a7a3-27fa57cf3a33')
+    def test_flavor_capabilities_list(self):
+        """Tests provider flavor capabilities list API and field filtering.
+
+        * Validates that non-lb admin accounts cannot list the capabilities.
+        * List the flavor capablilities.
+        * Validate that the "loadbalancer_topology" capablility is present.
+        * List the providers returning one field at a time.
+        """
+        # 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_provider_client.is_version_supported(
+                self.api_version, '2.6'):
+            raise self.skipException('Flavor capabilities are only available '
+                                     'on Octavia API version 2.6 or newer.')
+
+        # Test that a user without the load balancer admin role cannot
+        # list provider flavor capabilities.
+        if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
+            os_primary_capabilities_client = (
+                self.os_primary.flavor_capabilities_client)
+            self.assertRaises(
+                exceptions.Forbidden,
+                os_primary_capabilities_client.list_flavor_capabilities,
+                CONF.load_balancer.provider)
+
+        # Check for an expected flavor capability for the configured provider
+        admin_capabilities_client = self.lb_admin_capabilities_client
+        capabilities = admin_capabilities_client.list_flavor_capabilities(
+            CONF.load_balancer.provider)
+
+        expected_name = list(
+            CONF.load_balancer.expected_flavor_capability.keys())[0]
+        expected_description = (
+            CONF.load_balancer.expected_flavor_capability[expected_name])
+        for capability in capabilities:
+            if capability[const.NAME] == expected_name:
+                self.assertEqual(expected_description,
+                                 capability[const.DESCRIPTION])
+
+        # Test fields
+        capabilities = admin_capabilities_client.list_flavor_capabilities(
+            CONF.load_balancer.provider,
+            query_params='{fields}={field}&{field}={exp_name}'.format(
+                fields=const.FIELDS, field=const.NAME, exp_name=expected_name))
+        self.assertEqual(1, len(capabilities[0]))
+        self.assertEqual(expected_name, capabilities[0][const.NAME])
+
+        capabilities = admin_capabilities_client.list_flavor_capabilities(
+            CONF.load_balancer.provider,
+            query_params='{fields}={field}&{name}={exp_name}'.format(
+                fields=const.FIELDS, field=const.DESCRIPTION, name=const.NAME,
+                exp_name=expected_name))
+        self.assertEqual(1, len(capabilities[0]))
+        self.assertEqual(expected_description,
+                         capabilities[0][const.DESCRIPTION])
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 66d26cf..10ae85d 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
@@ -826,6 +826,11 @@
         lb = self.mem_lb_client.show_loadbalancer(lb[const.ID])
         self.assertEqual(const.ACTIVE, lb[const.PROVISIONING_STATUS])
 
+        if CONF.load_balancer.provider in ['amphora', 'octavia']:
+            before_amphorae = self.lb_admin_amphora_client.list_amphorae(
+                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])
 
@@ -834,8 +839,17 @@
                                      const.ACTIVE,
                                      CONF.load_balancer.lb_build_interval,
                                      CONF.load_balancer.lb_build_timeout)
-        # TODO(johnsom) Assert the amphora ID has changed when amp client
-        #               is available.
+
+        if CONF.load_balancer.provider in ['amphora', 'octavia']:
+            after_amphorae = self.lb_admin_amphora_client.list_amphorae(
+                query_params='{loadbalancer_id}={lb_id}'.format(
+                    loadbalancer_id=const.LOADBALANCER_ID, lb_id=lb[const.ID]))
+
+            # Make sure all of the amphora on the load balancer have
+            # failed over
+            for amphora in before_amphorae:
+                for new_amp in after_amphorae:
+                    self.assertNotEqual(amphora[const.ID], new_amp[const.ID])
 
         # Attempt to clean up so that one full test run doesn't start 10+
         # amps before the cleanup phase fires
diff --git a/octavia_tempest_plugin/tests/api/v2/test_pool.py b/octavia_tempest_plugin/tests/api/v2/test_pool.py
index a63bddb..8273b48 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_pool.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_pool.py
@@ -41,9 +41,9 @@
                      const.NAME: lb_name}
         cls._setup_lb_network_kwargs(lb_kwargs)
         cls.protocol = const.HTTP
-        lb_feature_enabled = CONF.loadbalancer_feature_enabled
-        if not lb_feature_enabled.l7_protocol_enabled:
-            cls.protocol = lb_feature_enabled.l4_protocol
+        cls.lb_feature_enabled = CONF.loadbalancer_feature_enabled
+        if not cls.lb_feature_enabled.l7_protocol_enabled:
+            cls.protocol = cls.lb_feature_enabled.l4_protocol
 
         lb = cls.mem_lb_client.create_loadbalancer(**lb_kwargs)
         cls.lb_id = lb[const.ID]
@@ -103,11 +103,13 @@
             const.ADMIN_STATE_UP: True,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
+        }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_kwargs[const.SESSION_PERSISTENCE] = {
                 const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
                 const.COOKIE_NAME: pool_sp_cookie_name,
-            },
-        }
+            }
+
         if has_listener:
             pool_kwargs[const.LISTENER_ID] = self.listener_id
         else:
@@ -170,11 +172,13 @@
             self.assertEmpty(pool[const.LISTENERS])
         self.assertEqual(const.LB_ALGORITHM_ROUND_ROBIN,
                          pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
-                         pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertEqual(pool_sp_cookie_name,
-                         pool[const.SESSION_PERSISTENCE][const.COOKIE_NAME])
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
+            self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
+                             pool[const.SESSION_PERSISTENCE][const.TYPE])
+            self.assertEqual(pool_sp_cookie_name,
+                             pool[const.SESSION_PERSISTENCE][
+                                 const.COOKIE_NAME])
 
     @decorators.idempotent_id('6959a32e-fb34-4f3e-be68-8880c6450016')
     def test_pool_list(self):
@@ -216,12 +220,13 @@
             const.ADMIN_STATE_UP: True,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
-                const.COOKIE_NAME: pool1_sp_cookie_name,
-            },
             const.LOADBALANCER_ID: lb_id,
         }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool1_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
+                const.COOKIE_NAME: pool1_sp_cookie_name,
+            }
         pool1 = self.mem_pool_client.create_pool(
             **pool1_kwargs)
         self.addCleanup(
@@ -253,12 +258,13 @@
             const.ADMIN_STATE_UP: True,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
-                const.COOKIE_NAME: pool2_sp_cookie_name,
-            },
             const.LOADBALANCER_ID: lb_id,
         }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool2_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
+                const.COOKIE_NAME: pool2_sp_cookie_name,
+            }
         pool2 = self.mem_pool_client.create_pool(
             **pool2_kwargs)
         self.addCleanup(
@@ -430,12 +436,13 @@
             const.ADMIN_STATE_UP: True,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
-                const.COOKIE_NAME: pool_sp_cookie_name,
-            },
             const.LOADBALANCER_ID: self.lb_id,
         }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
+                const.COOKIE_NAME: pool_sp_cookie_name,
+            }
 
         pool = self.mem_pool_client.create_pool(**pool_kwargs)
         self.addClassResourceCleanup(
@@ -469,11 +476,13 @@
         self.assertEmpty(pool[const.LISTENERS])
         self.assertEqual(const.LB_ALGORITHM_ROUND_ROBIN,
                          pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
-                         pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertEqual(pool_sp_cookie_name,
-                         pool[const.SESSION_PERSISTENCE][const.COOKIE_NAME])
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
+            self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
+                             pool[const.SESSION_PERSISTENCE][const.TYPE])
+            self.assertEqual(pool_sp_cookie_name,
+                             pool[const.SESSION_PERSISTENCE][
+                                 const.COOKIE_NAME])
 
         # Test that a user with lb_admin role can see the pool
         if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
@@ -524,13 +533,13 @@
             const.ADMIN_STATE_UP: False,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
-                const.COOKIE_NAME: pool_sp_cookie_name,
-            },
             const.LOADBALANCER_ID: self.lb_id,
         }
-
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
+                const.COOKIE_NAME: pool_sp_cookie_name,
+            }
         pool = self.mem_pool_client.create_pool(**pool_kwargs)
         self.addClassResourceCleanup(
             self.mem_pool_client.cleanup_pool,
@@ -563,11 +572,13 @@
         self.assertEmpty(pool[const.LISTENERS])
         self.assertEqual(const.LB_ALGORITHM_ROUND_ROBIN,
                          pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
-                         pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertEqual(pool_sp_cookie_name,
-                         pool[const.SESSION_PERSISTENCE][const.COOKIE_NAME])
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
+            self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
+                             pool[const.SESSION_PERSISTENCE][const.TYPE])
+            self.assertEqual(pool_sp_cookie_name,
+                             pool[const.SESSION_PERSISTENCE][
+                                 const.COOKIE_NAME])
 
         # Test that a user, without the load balancer member role, cannot
         # use this command
@@ -607,10 +618,11 @@
             const.DESCRIPTION: new_description,
             const.ADMIN_STATE_UP: True,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_HTTP_COOKIE,
-            },
         }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_update_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_HTTP_COOKIE,
+            }
         pool = self.mem_pool_client.update_pool(
             pool[const.ID], **pool_update_kwargs)
 
@@ -631,16 +643,18 @@
         self.assertTrue(pool[const.ADMIN_STATE_UP])
         self.assertEqual(const.LB_ALGORITHM_ROUND_ROBIN,
                          pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        self.assertEqual(const.SESSION_PERSISTENCE_HTTP_COOKIE,
-                         pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertIsNone(
-            pool[const.SESSION_PERSISTENCE].get(const.COOKIE_NAME))
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
+            self.assertEqual(const.SESSION_PERSISTENCE_HTTP_COOKIE,
+                             pool[const.SESSION_PERSISTENCE][const.TYPE])
+            self.assertIsNone(
+                pool[const.SESSION_PERSISTENCE].get(const.COOKIE_NAME))
 
         # Also test removing a Session Persistence
-        pool_update_kwargs = {
-            const.SESSION_PERSISTENCE: None,
-        }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_update_kwargs = {
+                const.SESSION_PERSISTENCE: None,
+            }
         pool = self.mem_pool_client.update_pool(
             pool[const.ID], **pool_update_kwargs)
 
@@ -655,7 +669,8 @@
             const.ACTIVE,
             CONF.load_balancer.build_interval,
             CONF.load_balancer.build_timeout)
-        self.assertIsNone(pool.get(const.SESSION_PERSISTENCE))
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNone(pool.get(const.SESSION_PERSISTENCE))
 
     @decorators.idempotent_id('35ed3800-7a4a-47a6-9b94-c1033fff1112')
     def test_pool_delete(self):
@@ -672,12 +687,13 @@
             const.NAME: pool_name,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
-                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
-                const.COOKIE_NAME: pool_sp_cookie_name,
-            },
             const.LOADBALANCER_ID: self.lb_id,
         }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_kwargs[const.SESSION_PERSISTENCE] = {
+                const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
+                const.COOKIE_NAME: pool_sp_cookie_name,
+            }
         pool = self.mem_pool_client.create_pool(**pool_kwargs)
         self.addClassResourceCleanup(
             self.mem_pool_client.cleanup_pool,
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py b/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
index b91a368..30a116c 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
@@ -115,11 +115,11 @@
 
         # Test that a user with cloud admin role can list the amphorae
         if not CONF.load_balancer.RBAC_test_type == const.NONE:
-            adm = self.os_admin.amphora_client.list_amphorae()
+            adm = self.lb_admin_amphora_client.list_amphorae()
             self.assertTrue(len(adm) >= 2 * self._expected_amp_count(adm))
 
         # Get an actual list of the amphorae
-        amphorae = self.os_admin.amphora_client.list_amphorae()
+        amphorae = self.lb_admin_amphora_client.list_amphorae()
 
         # There should be AT LEAST 2, there may be more depending on the
         # configured topology, or if there are other LBs created besides ours
@@ -127,7 +127,7 @@
             len(amphorae) >= 2 * self._expected_amp_count(amphorae))
 
         show_amphora_response_fields = const.SHOW_AMPHORA_RESPONSE_FIELDS
-        if self.mem_amphora_client.is_version_supported(
+        if self.lb_admin_amphora_client.is_version_supported(
                 self.api_version, '2.1'):
             show_amphora_response_fields.append('created_at')
             show_amphora_response_fields.append('updated_at')
@@ -140,7 +140,7 @@
                 self.assertIn(field, amp)
 
             amp_id = amp[const.ID]
-            amp_obj = self.os_admin.amphora_client.show_amphora(
+            amp_obj = self.lb_admin_amphora_client.show_amphora(
                 amphora_id=amp_id)
 
             # Make sure all of the fields exist on the amp show record
@@ -148,7 +148,7 @@
                 self.assertIn(field, amp_obj)
 
             # Verify a few of the fields are the right type
-            if self.mem_amphora_client.is_version_supported(
+            if self.lb_admin_amphora_client.is_version_supported(
                     self.api_version, '2.1'):
                 parser.parse(amp_obj[const.CREATED_AT])
                 parser.parse(amp_obj[const.UPDATED_AT])
@@ -175,13 +175,13 @@
                 self.assertEqual(amp[field], amp_obj[field])
 
         # Test filtering by loadbalancer_id
-        amphorae = self.os_admin.amphora_client.list_amphorae(
+        amphorae = self.lb_admin_amphora_client.list_amphorae(
             query_params='{loadbalancer_id}={lb_id}'.format(
                 loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
         self.assertEqual(self._expected_amp_count(amphorae), len(amphorae))
         self.assertEqual(self.lb_id, amphorae[0][const.LOADBALANCER_ID])
 
-        amphorae = self.os_admin.amphora_client.list_amphorae(
+        amphorae = self.lb_admin_amphora_client.list_amphorae(
             query_params='{loadbalancer_id}={lb_id}'.format(
                 loadbalancer_id=const.LOADBALANCER_ID, lb_id=lb_id))
         self.assertEqual(self._expected_amp_count(amphorae), len(amphorae))
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_load_balancer.py b/octavia_tempest_plugin/tests/scenario/v2/test_load_balancer.py
index 79f1876..3d79173 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_load_balancer.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_load_balancer.py
@@ -17,6 +17,7 @@
 
 from dateutil import parser
 
+from oslo_serialization import jsonutils
 from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
@@ -30,6 +31,49 @@
 
 class LoadBalancerScenarioTest(test_base.LoadBalancerBaseTest):
 
+    @classmethod
+    def resource_setup(cls):
+        """Setup resources needed by the tests."""
+        super(LoadBalancerScenarioTest, cls).resource_setup()
+
+        if cls.lb_admin_flavor_profile_client.is_version_supported(
+                cls.api_version, '2.6'):
+
+            # Create a shared flavor profile
+            flavor_profile_name = data_utils.rand_name("lb_scenario-setup")
+            flavor_data = {const.LOADBALANCER_TOPOLOGY:
+                           CONF.load_balancer.loadbalancer_topology}
+            flavor_data_json = jsonutils.dumps(flavor_data)
+
+            flavor_profile_kwargs = {
+                const.NAME: flavor_profile_name,
+                const.PROVIDER_NAME: CONF.load_balancer.provider,
+                const.FLAVOR_DATA: flavor_data_json
+            }
+
+            cls.flavor_profile = (
+                cls.lb_admin_flavor_profile_client.create_flavor_profile(
+                    **flavor_profile_kwargs))
+            cls.addClassResourceCleanup(
+                cls.lb_admin_flavor_profile_client.cleanup_flavor_profile,
+                cls.flavor_profile[const.ID])
+
+            flavor_name = data_utils.rand_name("lb_scenario-setup")
+            flavor_description = data_utils.arbitrary_string(size=255)
+
+            flavor_kwargs = {
+                const.NAME: flavor_name,
+                const.DESCRIPTION: flavor_description,
+                const.ENABLED: True,
+                const.FLAVOR_PROFILE_ID: cls.flavor_profile[const.ID]}
+
+            cls.flavor = cls.lb_admin_flavor_client.create_flavor(
+                **flavor_kwargs)
+            cls.addClassResourceCleanup(
+                cls.lb_admin_flavor_client.cleanup_a_flavor,
+                cls.flavor[const.ID])
+            cls.flavor_id = cls.flavor[const.ID]
+
     @decorators.idempotent_id('a5e2e120-4f7e-4c8b-8aac-cf09cb56711c')
     def test_load_balancer_ipv4_CRUD(self):
         self._test_load_balancer_CRUD(4)
@@ -56,6 +100,10 @@
                      const.PROVIDER: CONF.load_balancer.provider,
                      const.NAME: lb_name}
 
+        if self.lb_admin_flavor_profile_client.is_version_supported(
+                self.api_version, '2.6'):
+            lb_kwargs[const.FLAVOR_ID] = self.flavor_id
+
         self._setup_lb_network_kwargs(lb_kwargs, ip_version)
 
         lb = self.mem_lb_client.create_loadbalancer(**lb_kwargs)
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_pool.py b/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
index d1090c7..e6cd8c1 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
@@ -101,11 +101,12 @@
             const.ADMIN_STATE_UP: False,
             const.PROTOCOL: self.protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
-            const.SESSION_PERSISTENCE: {
+        }
+        if self.lb_feature_enabled.session_persistence_enabled:
+            pool_kwargs[const.SESSION_PERSISTENCE] = {
                 const.TYPE: const.SESSION_PERSISTENCE_APP_COOKIE,
                 const.COOKIE_NAME: pool_sp_cookie_name,
-            },
-        }
+            }
         if has_listener:
             pool_kwargs[const.LISTENER_ID] = self.listener_id
         else:
@@ -147,11 +148,13 @@
             self.assertEmpty(pool[const.LISTENERS])
         self.assertEqual(const.LB_ALGORITHM_ROUND_ROBIN,
                          pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
-                         pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertEqual(pool_sp_cookie_name,
-                         pool[const.SESSION_PERSISTENCE][const.COOKIE_NAME])
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
+            self.assertEqual(const.SESSION_PERSISTENCE_APP_COOKIE,
+                             pool[const.SESSION_PERSISTENCE][const.TYPE])
+            self.assertEqual(pool_sp_cookie_name,
+                             pool[const.SESSION_PERSISTENCE][
+                                 const.COOKIE_NAME])
 
         # Pool update
         new_name = data_utils.rand_name("lb_member_pool1-update")
@@ -167,7 +170,8 @@
             pool_update_kwargs[const.LB_ALGORITHM] = \
                 const.LB_ALGORITHM_LEAST_CONNECTIONS
 
-        if self.protocol == const.HTTP:
+        if self.protocol == const.HTTP and (
+            self.lb_feature_enabled.session_persistence_enabled):
             pool_update_kwargs[const.SESSION_PERSISTENCE] = {
                 const.TYPE: const.SESSION_PERSISTENCE_HTTP_COOKIE}
         pool = self.mem_pool_client.update_pool(
@@ -191,12 +195,12 @@
         if self.lb_feature_enabled.pool_algorithms_enabled:
             self.assertEqual(const.LB_ALGORITHM_LEAST_CONNECTIONS,
                              pool[const.LB_ALGORITHM])
-        self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
-        if self.protocol == const.HTTP:
+        if self.lb_feature_enabled.session_persistence_enabled:
+            self.assertIsNotNone(pool.get(const.SESSION_PERSISTENCE))
             self.assertEqual(const.SESSION_PERSISTENCE_HTTP_COOKIE,
                              pool[const.SESSION_PERSISTENCE][const.TYPE])
-        self.assertIsNone(
-            pool[const.SESSION_PERSISTENCE].get(const.COOKIE_NAME))
+            self.assertIsNone(
+                pool[const.SESSION_PERSISTENCE].get(const.COOKIE_NAME))
 
         # Pool delete
         waiters.wait_for_status(
diff --git a/octavia_tempest_plugin/tests/test_base.py b/octavia_tempest_plugin/tests/test_base.py
index ddc953d..c26b675 100644
--- a/octavia_tempest_plugin/tests/test_base.py
+++ b/octavia_tempest_plugin/tests/test_base.py
@@ -121,13 +121,15 @@
             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.mem_amphora_client = cls.os_roles_lb_member.amphora_client
+        cls.lb_admin_amphora_client = cls.os_roles_lb_admin.amphora_client
         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
         cls.os_admin_servers_client = cls.os_admin.servers_client
+        cls.lb_admin_capabilities_client = (
+            cls.os_roles_lb_admin.flavor_capabilities_client)
 
     @classmethod
     def resource_setup(cls):
diff --git a/releasenotes/notes/Fix-service-client-params-41a0f7c9c6b53aac.yaml b/releasenotes/notes/Fix-service-client-params-41a0f7c9c6b53aac.yaml
new file mode 100644
index 0000000..16c04da
--- /dev/null
+++ b/releasenotes/notes/Fix-service-client-params-41a0f7c9c6b53aac.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Fixed the service clients to use the tempest default service client
+    configuration settings.
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 1788b85..0766931 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -1,6 +1,6 @@
-============================================
- octavia_tempest_plugin Release Notes
-============================================
+====================================
+octavia_tempest_plugin Release Notes
+====================================
 
 .. toctree::
    :maxdepth: 1
diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst
index cd22aab..875030f 100644
--- a/releasenotes/source/unreleased.rst
+++ b/releasenotes/source/unreleased.rst
@@ -1,5 +1,5 @@
-==============================
- Current Series Release Notes
-==============================
+============================
+Current Series Release Notes
+============================
 
 .. release-notes::
diff --git a/requirements.txt b/requirements.txt
index 3b78bc3..8020630 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,3 +17,4 @@
 six>=1.10.0 # MIT
 tempest>=17.1.0 # Apache-2.0
 tenacity>=4.4.0 # Apache-2.0
+keystoneauth1>=3.3.0 # Apache-2.0
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 5c89676..d342aff 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -293,6 +293,13 @@
       tempest_concurrency: 2
       tempest_test_regex: ^octavia_tempest_plugin.tests.api.v2
       tox_envlist: all
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^api-ref/.*$
+      - ^doc/.*$
+      - ^etc/.*$
+      - ^releasenotes/.*$
+      - ^octavia_tempest_plugin/tests/(?!api/|\w+\.py).*
 
 - job:
     name: octavia-v2-dsvm-noop-py2-api
@@ -328,6 +335,13 @@
       tempest_concurrency: 2
       tempest_test_regex: ^octavia_tempest_plugin.tests.scenario.v2
       tox_envlist: all
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^api-ref/.*$
+      - ^doc/.*$
+      - ^etc/.*$
+      - ^releasenotes/.*$
+      - ^octavia_tempest_plugin/tests/(?!scenario/|\w+\.py).*
 
 - job:
     name: octavia-v2-dsvm-py2-scenario
@@ -351,6 +365,7 @@
     parent: octavia-v2-dsvm-py2-scenario
     override-checkout: stable/queens
 
+# Legacy jobs for the transition to the act-stdby two node jobs
 - job:
     name: octavia-v2-dsvm-scenario-two-node
     parent: octavia-dsvm-live-two-node-base
@@ -358,6 +373,13 @@
       tempest_concurrency: 2
       tempest_test_regex: ^octavia_tempest_plugin.tests.scenario.v2
       tox_envlist: all
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^api-ref/.*$
+      - ^doc/.*$
+      - ^etc/.*$
+      - ^releasenotes/.*$
+      - ^octavia_tempest_plugin/tests/(?!scenario/|\w+\.py).*
 
 - job:
     name: octavia-v2-dsvm-py2-scenario-two-node
@@ -371,6 +393,30 @@
           USE_PYTHON3: False
 
 - 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:
+        test-config:
+          "$TEMPEST_CONFIG":
+            load_balancer:
+              loadbalancer_topology: ACTIVE_STANDBY
+
+- job:
+    name: octavia-v2-act-stdby-dsvm-py2-scenario-two-node
+    parent: octavia-v2-act-stdby-dsvm-scenario-two-node
+    host-vars:
+      controller:
+        devstack_localrc:
+          USE_PYTHON3: False
+      controller2:
+        devstack_localrc:
+          USE_PYTHON3: False
+
+- job:
     name: octavia-v2-dsvm-py2-scenario-centos-7
     parent: octavia-v2-dsvm-py2-scenario
     nodeset: devstack-single-node-centos-7
@@ -379,6 +425,12 @@
         OCTAVIA_AMP_BASE_OS: centos
         OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID: 7
         OCTAVIA_AMP_IMAGE_SIZE: 3
+      devstack_local_conf:
+        post-config:
+          $OCTAVIA_CONF:
+            haproxy_amphora:
+              # Set these higher for non-nested virt nodepool instances
+              connection_max_retries: 480
 
 - job:
     name: octavia-v2-dsvm-scenario-ubuntu-bionic
@@ -413,6 +465,13 @@
         barbican: https://opendev.org/openstack/barbican.git
       devstack_localrc:
         TEMPEST_PLUGINS: '"/opt/stack/octavia-tempest-plugin /opt/stack/barbican-tempest-plugin"'
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^api-ref/.*$
+      - ^doc/.*$
+      - ^etc/.*$
+      - ^releasenotes/.*$
+      - ^octavia_tempest_plugin/tests/(?!barbican_scenario/|\w+\.py).*
 
 - job:
     name: octavia-v2-dsvm-tls-barbican-stable-stein
@@ -502,9 +561,11 @@
           "$TEMPEST_CONFIG":
             load_balancer:
               check_timeout: 180
+              loadbalancer_topology: 'ACTIVE_STANDBY'
       tempest_test_regex: ^octavia_tempest_plugin.tests.act_stdby_scenario.v2.test_active_standby_iptables
       tox_envlist: all
 
+
 - job:
     name: octavia-v2-act-stdby-iptables-dsvm-py2-scenario
     parent: octavia-v2-act-stdby-iptables-dsvm-scenario
@@ -523,6 +584,11 @@
         OCTAVIA_AMP_DISTRIBUTION_RELEASE_ID: 7
         OCTAVIA_AMP_IMAGE_SIZE: 3
       devstack_local_conf:
+        post-config:
+          $OCTAVIA_CONF:
+            haproxy_amphora:
+              # Set these higher for non-nested virt nodepool instances
+              connection_max_retries: 480
         test-config:
           "$TEMPEST_CONFIG":
             load_balancer:
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index 2bb813e..490d68b 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -22,9 +22,9 @@
             voting: false
         - octavia-v2-dsvm-scenario-ubuntu-bionic:
             voting: false
-        - octavia-v2-dsvm-scenario-two-node:
+        - octavia-v2-act-stdby-dsvm-scenario-two-node:
             voting: false
-        - octavia-v2-dsvm-py2-scenario-two-node:
+        - octavia-v2-act-stdby-dsvm-py2-scenario-two-node:
             voting: false
         - octavia-v2-act-stdby-iptables-dsvm-scenario:
             voting: false