Merge "Add octavia_client with openstacksdk"

This commit is contained in:
Zuul 2025-01-09 16:44:49 +00:00 committed by Gerrit Code Review
commit 3549fa9bfd
4 changed files with 117 additions and 2 deletions

View File

@ -139,3 +139,37 @@ def get_neutron_client():
'in Octavia API configuration.') % e
raise driver_exceptions.DriverError(
operator_fault_string=msg)
class OctaviaAuth(metaclass=Singleton):
def __init__(self):
"""Create Octavia client object."""
try:
ksession = KeystoneSession()
kwargs = {'region_name': CONF.service_auth.region_name}
# TODO(ricolin) `interface` option don't take list as option yet.
# We can move away from this when openstacksdk no longer depends
# on `interface`.
try:
interface = CONF.service_auth.valid_interfaces[0]
except (TypeError, LookupError):
interface = CONF.service_auth.valid_interfaces
if interface:
kwargs['interface'] = interface
self.loadbalancer_proxy = openstack.connection.Connection(
session=ksession.session, **kwargs).load_balancer
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception("Error creating Octavia client.")
def get_octavia_client():
try:
return OctaviaAuth().loadbalancer_proxy
except Exception as e:
msg = _('Cannot initialize OpenStackSDK. Exception: %s. '
'Please verify service_auth configuration '
'in Octavia API configuration.') % e
raise driver_exceptions.DriverError(
operator_fault_string=msg)

View File

@ -21,6 +21,7 @@ from octavia_lib.api.drivers import provider_base as driver_base
from octavia_lib.common import constants
from oslo_log import log as logging
from ovn_octavia_provider.common import clients
from ovn_octavia_provider.common import config as ovn_conf
# TODO(mjozefcz): Start consuming const and utils
# from neutron-lib once released.
@ -588,5 +589,8 @@ class OvnProviderDriver(driver_base.ProviderDriver):
def do_sync(self, **lb_filters):
LOG.info(f"Starting sync OVN DB with Loadbalancer filter {lb_filters}")
# TODO(froyo): get LBs from Octavia DB through openstack sdk client and
# call to helper methods to sync
octavia_client = clients.get_octavia_client()
# We can add project_id to lb_filters for lbs to limit the scope.
lbs = self._ovn_helper.get_octavia_lbs(octavia_client, **lb_filters)
for lb in lbs:
LOG.info(f"Starting sync OVN DB with Loadbalancer {lb.id}")

View File

@ -452,6 +452,15 @@ class OvnProviderHelper():
def _neutron_find_port(self, neutron_client, **params):
return neutron_client.find_port(**params)
@tenacity.retry(
retry=tenacity.retry_if_exception_type(
openstack.exceptions.HttpException),
wait=tenacity.wait_exponential(),
stop=tenacity.stop_after_delay(10),
reraise=True)
def get_octavia_lbs(self, octavia_client, **params):
return octavia_client.load_balancers(**params)
def _find_ovn_lbs(self, lb_id, protocol=None):
"""Find the Loadbalancers in OVN with the given lb_id as its name

View File

@ -14,6 +14,7 @@
from unittest import mock
from keystoneauth1 import exceptions as ks_exceptions
from octavia_lib.api.drivers import exceptions as driver_exceptions
from oslo_config import cfg
from oslo_config import fixture as oslo_fixture
from oslotest import base
@ -127,3 +128,70 @@ class TestNeutronAuth(base.BaseTestCase):
c3 = clients.NeutronAuth()
self.assertIs(c2, c3)
self.assertEqual(os_sdk._mock_call_count, 2)
@mock.patch.object(clients, 'KeystoneSession')
def test_get_client(self, mock_ks):
clients.get_neutron_client()
self.mock_client.assert_called_once_with(
session=mock_ks().session)
@mock.patch.object(clients, 'NeutronAuth', side_effect=[RuntimeError])
def test_get_client_error(self, mock_ks):
msg = self.assertRaises(
driver_exceptions.DriverError,
clients.get_neutron_client)
self.assertEqual("An unknown driver error occurred.", str(msg))
class TestOctaviaAuth(base.BaseTestCase):
def setUp(self):
super().setUp()
config.register_opts()
self.mock_client = mock.patch(
'openstack.connection.Connection').start()
clients.Singleton._instances = {}
@mock.patch.object(clients, 'KeystoneSession')
@mock.patch('openstack.connection.Connection')
def test_init(self, mock_conn, mock_ks):
clients.OctaviaAuth()
mock_conn.assert_called_once_with(
session=mock_ks().session,
region_name=mock.ANY
)
def test_singleton(self):
c1 = clients.OctaviaAuth()
c2 = clients.OctaviaAuth()
self.assertIs(c1, c2)
def test_singleton_exception(self):
mock_client = mock.Mock()
mock_client.lbaas_proxy = 'foo'
with mock.patch(
'openstack.connection.Connection',
side_effect=[RuntimeError,
mock_client, mock_client]) as os_sdk:
self.assertRaises(
RuntimeError,
clients.OctaviaAuth)
c2 = clients.OctaviaAuth()
c3 = clients.OctaviaAuth()
self.assertIs(c2, c3)
self.assertEqual(os_sdk._mock_call_count, 2)
@mock.patch.object(clients, 'KeystoneSession')
@mock.patch('openstack.connection.Connection')
def test_get_client(self, mock_conn, mock_ks):
clients.get_octavia_client()
mock_conn.assert_called_once_with(
session=mock_ks().session,
region_name=mock.ANY
)
@mock.patch.object(clients, 'OctaviaAuth', side_effect=[RuntimeError])
def test_get_client_error(self, mock_ks):
msg = self.assertRaises(
driver_exceptions.DriverError,
clients.get_octavia_client)
self.assertEqual("An unknown driver error occurred.", str(msg))