Merge "Add iptables-based active/standby scenario test"
diff --git a/.gitreview b/.gitreview
index a22fc23..9832cf7 100644
--- a/.gitreview
+++ b/.gitreview
@@ -1,4 +1,4 @@
 [gerrit]
-host=review.openstack.org
+host=review.opendev.org
 port=29418
 project=openstack/octavia-tempest-plugin.git
diff --git a/README.rst b/README.rst
index f2b51a7..b2c74ee 100644
--- a/README.rst
+++ b/README.rst
@@ -22,7 +22,7 @@
 
 * Free software: Apache license
 * Documentation: https://docs.openstack.org/octavia-tempest-plugin/latest/
-* Source: https://git.openstack.org/cgit/openstack/octavia-tempest-plugin
+* Source: https://opendev.org/openstack/octavia-tempest-plugin
 * Bugs: https://storyboard.openstack.org/#!/project/openstack/octavia-tempest-plugin
 
 Installing
diff --git a/octavia_tempest_plugin/clients.py b/octavia_tempest_plugin/clients.py
index c1894e3..8409093 100644
--- a/octavia_tempest_plugin/clients.py
+++ b/octavia_tempest_plugin/clients.py
@@ -18,6 +18,8 @@
 from octavia_tempest_plugin.services.load_balancer.v2 import (
     amphora_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)
@@ -69,3 +71,6 @@
             self.auth_provider, SERVICE_TYPE, CONF.identity.region)
         self.provider_client = provider_client.ProviderClient(
             self.auth_provider, SERVICE_TYPE, CONF.identity.region)
+        self.flavor_capabilities_client = (
+            flavor_capabilities_client.FlavorCapabilitiesClient(
+                self.auth_provider, SERVICE_TYPE, CONF.identity.region))
diff --git a/octavia_tempest_plugin/common/constants.py b/octavia_tempest_plugin/common/constants.py
index 54b23d1..7ddcb7a 100644
--- a/octavia_tempest_plugin/common/constants.py
+++ b/octavia_tempest_plugin/common/constants.py
@@ -102,6 +102,7 @@
 HTTP = 'HTTP'
 HTTPS = 'HTTPS'
 TCP = 'TCP'
+TERMINATED_HTTPS = 'TERMINATED_HTTPS'
 
 # HTTP Methods
 GET = 'GET'
diff --git a/octavia_tempest_plugin/config.py b/octavia_tempest_plugin/config.py
index cd8012e..026e941 100644
--- a/octavia_tempest_plugin/config.py
+++ b/octavia_tempest_plugin/config.py
@@ -174,18 +174,22 @@
 LBFeatureEnabledGroup = [
     cfg.BoolOpt('health_monitor_enabled',
                 default=True,
-                help="Whether Health Monitor is available with provider"
-                     " driver or not."),
+                help="Whether Health Monitor is available with provider "
+                     "driver or not."),
     cfg.BoolOpt('terminated_tls_enabled',
                 default=True,
                 help="Whether TLS termination is available with provider "
                      "driver or not."),
     cfg.BoolOpt('l7_protocol_enabled',
                 default=True,
-                help="Whether L7 Protocols are available with the provider"
-                     " driver or not."),
+                help="Whether L7 Protocols are available with the provider "
+                     "driver or not."),
+    cfg.BoolOpt('pool_algorithms_enabled',
+                default=True,
+                help="Whether pool algorithms are available with provider"
+                     "driver or not."),
     cfg.StrOpt('l4_protocol',
                default="TCP",
-               help="The type of L4 Protocol which is supported with the"
-                    " provider driver."),
+               help="The type of L4 Protocol which is supported with the "
+                    "provider driver."),
 ]
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py b/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py
new file mode 100644
index 0000000..4c23042
--- /dev/null
+++ b/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py
@@ -0,0 +1,76 @@
+#   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 octavia_tempest_plugin.services.load_balancer.v2 import base_client
+from octavia_tempest_plugin.services.load_balancer.v2 import provider_client
+
+Unset = base_client.Unset
+
+
+class FlavorCapabilitiesClient(base_client.BaseLBaaSClient):
+
+    list_root_tag = 'flavor_capabilities'
+
+    def __init__(self, *args, **kwargs):
+        super(FlavorCapabilitiesClient, self).__init__(*args, **kwargs)
+        providers_list_root_tag = provider_client.ProviderClient.list_root_tag
+        # /v2.0/lbaas/providers/<PROVIDER_UUID>/flavor_capabilities
+        self.uri = "{provider_base_uri}/{parent}/{object}".format(
+            provider_base_uri=self.base_uri.format(
+                object=providers_list_root_tag),
+            parent="{parent}",
+            object=self.list_root_tag
+        )
+
+    def list_flavor_capabilities(self, provider, query_params=None,
+                                 return_object_only=True):
+        """Get a list of provider flavor capability objects.
+
+        :param provider: The provider to query for flavor capabilities.
+        :param query_params: The optional query parameters to append to the
+                             request. Ex. fields=id&fields=name
+        :param return_object_only: If True, the response returns the object
+                                   inside the root tag. False returns the full
+                                   response from the API.
+        :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: A list of flavor capability objects.
+        """
+        return self._list_objects(parent_id=provider,
+                                  query_params=query_params,
+                                  return_object_only=return_object_only)
diff --git a/octavia_tempest_plugin/tests/api/v2/test_listener.py b/octavia_tempest_plugin/tests/api/v2/test_listener.py
index 599305a..691c61c 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_listener.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_listener.py
@@ -178,7 +178,7 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb2_listener-list")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name,
+            name=lb_name, provider=CONF.load_balancer.provider,
             vip_network_id=self.lb_member_vip_net[const.ID])
         lb_id = lb[const.ID]
         self.addCleanup(
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 4990c79..555d34e 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
@@ -149,7 +149,8 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb1-delete")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name, vip_network_id=self.lb_member_vip_net[const.ID])
+            name=lb_name, provider=CONF.load_balancer.provider,
+            vip_network_id=self.lb_member_vip_net[const.ID])
         self.addClassResourceCleanup(
             self.mem_lb_client.cleanup_loadbalancer,
             lb[const.ID])
@@ -195,7 +196,8 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb1-cascade_delete")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name, vip_network_id=self.lb_member_vip_net[const.ID])
+            name=lb_name, provider=CONF.load_balancer.provider,
+            vip_network_id=self.lb_member_vip_net[const.ID])
         self.addClassResourceCleanup(
             self.mem_lb_client.cleanup_loadbalancer,
             lb[const.ID])
@@ -299,6 +301,7 @@
         lb = self.mem_lb_client.create_loadbalancer(
             admin_state_up=True,
             description=lb_description,
+            provider=CONF.load_balancer.provider,
             name=lb_name,
             vip_network_id=self.lb_member_vip_net[const.ID])
         self.addCleanup(
@@ -329,6 +332,7 @@
         lb = self.mem_lb_client.create_loadbalancer(
             admin_state_up=False,
             description=lb_description,
+            provider=CONF.load_balancer.provider,
             name=lb_name,
             vip_network_id=self.lb_member_vip_net[const.ID])
         self.addCleanup(
@@ -663,7 +667,8 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb1-show_stats")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name, vip_network_id=self.lb_member_vip_net[const.ID])
+            name=lb_name, provider=CONF.load_balancer.provider,
+            vip_network_id=self.lb_member_vip_net[const.ID])
         self.addClassResourceCleanup(
             self.mem_lb_client.cleanup_loadbalancer,
             lb[const.ID])
@@ -724,7 +729,8 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb1-status")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name, vip_network_id=self.lb_member_vip_net[const.ID])
+            name=lb_name, provider=CONF.load_balancer.provider,
+            vip_network_id=self.lb_member_vip_net[const.ID])
         self.addClassResourceCleanup(
             self.mem_lb_client.cleanup_loadbalancer,
             lb[const.ID])
@@ -797,7 +803,8 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb1-failover")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name, vip_network_id=self.lb_member_vip_net[const.ID])
+            name=lb_name, provider=CONF.load_balancer.provider,
+            vip_network_id=self.lb_member_vip_net[const.ID])
         self.addClassResourceCleanup(
             self.mem_lb_client.cleanup_loadbalancer,
             lb[const.ID])
diff --git a/octavia_tempest_plugin/tests/api/v2/test_pool.py b/octavia_tempest_plugin/tests/api/v2/test_pool.py
index 63d9e46..a63bddb 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_pool.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_pool.py
@@ -193,7 +193,7 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb2_pool-list")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name,
+            name=lb_name, provider=CONF.load_balancer.provider,
             vip_network_id=self.lb_member_vip_net[const.ID])
         lb_id = lb[const.ID]
         self.addCleanup(
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 27663b2..25f741a 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
@@ -25,8 +25,6 @@
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 
-from octavia_lib.common import constants as lib_consts
-
 from octavia_tempest_plugin.common import barbican_client_mgr
 from octavia_tempest_plugin.common import cert_utils
 from octavia_tempest_plugin.common import constants as const
@@ -222,7 +220,7 @@
         listener_name = data_utils.rand_name("lb_member_listener1-tls")
         listener_kwargs = {
             const.NAME: listener_name,
-            const.PROTOCOL: lib_consts.PROTOCOL_TERMINATED_HTTPS,
+            const.PROTOCOL: const.TERMINATED_HTTPS,
             const.PROTOCOL_PORT: '443',
             const.LOADBALANCER_ID: self.lb_id,
             const.DEFAULT_POOL_ID: self.pool_id,
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py b/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
index 165424b..b91a368 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_amphora.py
@@ -78,7 +78,7 @@
         """
         lb_name = data_utils.rand_name("lb_member_lb2_amphora-list")
         lb = self.mem_lb_client.create_loadbalancer(
-            name=lb_name,
+            name=lb_name, provider=CONF.load_balancer.provider,
             vip_network_id=self.lb_member_vip_net[const.ID])
         lb_id = lb[const.ID]
         self.addCleanup(
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_pool.py b/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
index 1cdd727..d1090c7 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_pool.py
@@ -51,9 +51,9 @@
                                 CONF.load_balancer.lb_build_interval,
                                 CONF.load_balancer.lb_build_timeout)
         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
 
         listener_name = data_utils.rand_name("lb_member_listener1_pool")
         listener_kwargs = {
@@ -161,8 +161,12 @@
             const.NAME: new_name,
             const.DESCRIPTION: new_description,
             const.ADMIN_STATE_UP: True,
-            const.LB_ALGORITHM: const.LB_ALGORITHM_LEAST_CONNECTIONS,
         }
+
+        if self.lb_feature_enabled.pool_algorithms_enabled:
+            pool_update_kwargs[const.LB_ALGORITHM] = \
+                const.LB_ALGORITHM_LEAST_CONNECTIONS
+
         if self.protocol == const.HTTP:
             pool_update_kwargs[const.SESSION_PERSISTENCE] = {
                 const.TYPE: const.SESSION_PERSISTENCE_HTTP_COOKIE}
@@ -184,8 +188,9 @@
         self.assertEqual(new_name, pool[const.NAME])
         self.assertEqual(new_description, pool[const.DESCRIPTION])
         self.assertTrue(pool[const.ADMIN_STATE_UP])
-        self.assertEqual(const.LB_ALGORITHM_LEAST_CONNECTIONS,
-                         pool[const.LB_ALGORITHM])
+        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:
             self.assertEqual(const.SESSION_PERSISTENCE_HTTP_COOKIE,
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py b/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
index edc2cbc..eba7e38 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
@@ -73,10 +73,15 @@
                                 CONF.load_balancer.lb_build_interval,
                                 CONF.load_balancer.lb_build_timeout)
 
+        protocol = const.HTTP
+        lb_feature_enabled = CONF.loadbalancer_feature_enabled
+        if not lb_feature_enabled.l7_protocol_enabled:
+            protocol = lb_feature_enabled.l4_protocol
+
         listener_name = data_utils.rand_name("lb_member_listener1_operations")
         listener_kwargs = {
             const.NAME: listener_name,
-            const.PROTOCOL: const.HTTP,
+            const.PROTOCOL: protocol,
             const.PROTOCOL_PORT: '80',
             const.LOADBALANCER_ID: cls.lb_id,
         }
@@ -96,7 +101,7 @@
         pool_name = data_utils.rand_name("lb_member_pool1_operations")
         pool_kwargs = {
             const.NAME: pool_name,
-            const.PROTOCOL: const.HTTP,
+            const.PROTOCOL: protocol,
             const.LB_ALGORITHM: const.LB_ALGORITHM_ROUND_ROBIN,
             const.LISTENER_ID: cls.listener_id,
         }
@@ -173,6 +178,9 @@
         # Send some traffic
         self.check_members_balanced(self.lb_vip_address)
 
+    @testtools.skipUnless(
+        CONF.loadbalancer_feature_enabled.health_monitor_enabled,
+        'Health monitor testing is disabled')
     @decorators.idempotent_id('a16f8eb4-a77c-4b0e-8b1b-91c237039713')
     def test_healthmonitor_traffic(self):
         """Tests traffic is correctly routed based on healthmonitor status
@@ -385,6 +393,9 @@
         # Send some traffic and verify it is balanced again
         self.check_members_balanced(self.lb_vip_address)
 
+    @testtools.skipUnless(
+        CONF.loadbalancer_feature_enabled.l7_protocol_enabled,
+        'L7 protocol testing is disabled')
     @decorators.idempotent_id('3558186d-6dcd-4d9d-b7f7-adc190b66149')
     def test_l7policies_and_l7rules(self):
         """Tests sending traffic through a loadbalancer with l7rules
diff --git a/octavia_tempest_plugin/tests/test_base.py b/octavia_tempest_plugin/tests/test_base.py
index 6a9c12b..a4775da 100644
--- a/octavia_tempest_plugin/tests/test_base.py
+++ b/octavia_tempest_plugin/tests/test_base.py
@@ -299,14 +299,14 @@
 
         # Create tenant VIP IPv6 subnet
         if CONF.load_balancer.test_with_ipv6:
-            # See if ipv6-public-subnet exists and use it if so.
-            pub_ipv6_subnet = cls.os_admin.subnets_client.list_subnets(
-                name='ipv6-public-subnet')['subnets']
+            # See if ipv6-private-subnet exists and use it if so.
+            priv_ipv6_subnet = cls.os_admin.subnets_client.list_subnets(
+                name='ipv6-private-subnet')['subnets']
 
-            if len(pub_ipv6_subnet) == 1:
-                cls.lb_member_vip_ipv6_subnet = pub_ipv6_subnet[0]
+            if len(priv_ipv6_subnet) == 1:
+                cls.lb_member_vip_ipv6_subnet = priv_ipv6_subnet[0]
                 cls.lb_member_vip_ipv6_net = {
-                    'id': pub_ipv6_subnet[0]['network_id']}
+                    'id': priv_ipv6_subnet[0]['network_id']}
             else:
                 subnet_kwargs = {
                     'name': data_utils.rand_name("lb_member_vip_ipv6_subnet"),
@@ -315,6 +315,7 @@
                     'ip_version': 6}
                 result = cls.lb_mem_subnet_client.create_subnet(
                     **subnet_kwargs)
+                cls.lb_member_vip_ipv6_net = cls.lb_member_vip_net
                 cls.lb_member_vip_ipv6_subnet = result['subnet']
                 cls.addClassResourceCleanup(
                     waiters.wait_for_not_found,
diff --git a/requirements.txt b/requirements.txt
index c9f839c..3b78bc3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,7 +6,6 @@
 python-dateutil>=2.5.3 # BSD
 ipaddress>=1.0.17;python_version<'3.3' # PSF
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
-octavia-lib>=1.0.0 # Apache-2.0
 oslo.config>=5.2.0 # Apache-2.0
 oslo.log>=3.36.0  # Apache-2.0
 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 64afde0..f27ed30 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,7 +5,7 @@
 
 [testenv]
 usedevelop = True
-install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
+install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt} {opts} {packages}
 setenv =
    VIRTUAL_ENV={envdir}
    PYTHONWARNINGS=default::DeprecationWarning
@@ -40,7 +40,7 @@
 [testenv:docs]
 basepython = python3
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt}
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/doc/requirements.txt
 whitelist_externals = rm
@@ -51,7 +51,7 @@
 [testenv:releasenotes]
 basepython = python3
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt}
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/doc/requirements.txt
 commands =
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 7548504..b27da71 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -81,7 +81,7 @@
         s-proxy: false
         tempest: true
       devstack_plugins:
-        octavia: https://git.openstack.org/openstack/octavia.git
+        octavia: https://opendev.org/openstack/octavia.git
 
 - job:
     name: octavia-dsvm-live-base
@@ -102,7 +102,7 @@
       devstack_services:
         neutron-qos: true
       devstack_plugins:
-        neutron: https://git.openstack.org/openstack/neutron.git
+        neutron: https://opendev.org/openstack/neutron.git
       zuul_copy_output:
         '/var/log/dib-build' : logs
 
@@ -145,8 +145,8 @@
           OCTAVIA_NODES: "main:{{ hostvars['controller']['nodepool']['private_ipv4'] }},second:{{ hostvars['controller2']['nodepool']['private_ipv4'] }}"
           OCTAVIA_USE_PREGENERATED_CERTS: true
         devstack_plugins:
-          neutron: https://git.openstack.org/openstack/neutron.git
-          octavia: https://git.openstack.org/openstack/octavia.git
+          neutron: https://opendev.org/openstack/neutron.git
+          octavia: https://opendev.org/openstack/octavia.git
       controller2:
         devstack_localrc:
           # From devstack "vars:"
@@ -180,7 +180,7 @@
           OCTAVIA_USE_PREGENERATED_CERTS: true
           OCTAVIA_MGMT_PORT_IP: 192.168.0.4
         devstack_plugins:
-          octavia: https://git.openstack.org/openstack/octavia.git
+          octavia: https://opendev.org/openstack/octavia.git
     group-vars:
       controller:
         devstack_local_conf:
@@ -287,6 +287,11 @@
         USE_PYTHON3: False
 
 - job:
+    name: octavia-v2-dsvm-noop-api-stable-stein
+    parent: octavia-v2-dsvm-noop-api
+    override-checkout: stable/stein
+
+- job:
     name: octavia-v2-dsvm-noop-py2-api-stable-rocky
     parent: octavia-v2-dsvm-noop-py2-api
     override-checkout: stable/rocky
@@ -317,6 +322,11 @@
         USE_PYTHON3: False
 
 - job:
+    name: octavia-v2-dsvm-scenario-stable-stein
+    parent: octavia-v2-dsvm-scenario
+    override-checkout: stable/stein
+
+- job:
     name: octavia-v2-dsvm-py2-scenario-stable-rocky
     parent: octavia-v2-dsvm-py2-scenario
     override-checkout: stable/rocky
@@ -376,10 +386,25 @@
       devstack_services:
         barbican: true
       devstack_plugins:
-        barbican: https://git.openstack.org/openstack/barbican.git
+        barbican: https://opendev.org/openstack/barbican.git
       devstack_localrc:
         TEMPEST_PLUGINS: '"/opt/stack/octavia-tempest-plugin /opt/stack/barbican-tempest-plugin"'
 
+- job:
+    name: octavia-v2-dsvm-tls-barbican-stable-stein
+    parent: octavia-v2-dsvm-tls-barbican
+    override-checkout: stable/stein
+
+- job:
+    name: octavia-v2-dsvm-tls-barbican-stable-rocky
+    parent: octavia-v2-dsvm-tls-barbican
+    override-checkout: stable/rocky
+
+- job:
+    name: octavia-v2-dsvm-tls-barbican-stable-queens
+    parent: octavia-v2-dsvm-tls-barbican
+    override-checkout: stable/queens
+
 # Temporary transitional aliases for gates used in other repos
 # Remove once octavia has transitioned job names
 - job:
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index beb4b93..4325958 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -9,10 +9,12 @@
       jobs:
         - octavia-v2-dsvm-noop-api
         - octavia-v2-dsvm-noop-py2-api
+        - octavia-v2-dsvm-noop-api-stable-stein
         - octavia-v2-dsvm-noop-py2-api-stable-rocky
         - octavia-v2-dsvm-noop-py2-api-stable-queens
         - octavia-v2-dsvm-scenario
         - octavia-v2-dsvm-py2-scenario
+        - octavia-v2-dsvm-scenario-stable-stein
         - octavia-v2-dsvm-py2-scenario-stable-rocky
         - octavia-v2-dsvm-py2-scenario-stable-queens
         - octavia-v2-dsvm-scenario-centos-7:
@@ -37,14 +39,22 @@
             voting: false
         - octavia-v2-dsvm-tls-barbican:
             voting: false
+        - octavia-v2-dsvm-tls-barbican-stable-stein:
+            voting: false
+        - octavia-v2-dsvm-tls-barbican-stable-rocky:
+            voting: false
+        - octavia-v2-dsvm-tls-barbican-stable-queens:
+            voting: false
     gate:
       queue: octavia
       jobs:
         - octavia-v2-dsvm-noop-api
         - octavia-v2-dsvm-noop-py2-api
+        - octavia-v2-dsvm-noop-api-stable-stein
         - octavia-v2-dsvm-noop-py2-api-stable-rocky
         - octavia-v2-dsvm-noop-py2-api-stable-queens
         - octavia-v2-dsvm-scenario
         - octavia-v2-dsvm-py2-scenario
+        - octavia-v2-dsvm-scenario-stable-stein
         - octavia-v2-dsvm-py2-scenario-stable-rocky
         - octavia-v2-dsvm-py2-scenario-stable-queens