Skip to content

Commit 3549fa9

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Add octavia_client with openstacksdk"
2 parents 29d17aa + 051317e commit 3549fa9

File tree

4 files changed

+117
-2
lines changed

4 files changed

+117
-2
lines changed

ovn_octavia_provider/common/clients.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,37 @@ def get_neutron_client():
139139
'in Octavia API configuration.') % e
140140
raise driver_exceptions.DriverError(
141141
operator_fault_string=msg)
142+
143+
144+
class OctaviaAuth(metaclass=Singleton):
145+
def __init__(self):
146+
"""Create Octavia client object."""
147+
try:
148+
ksession = KeystoneSession()
149+
kwargs = {'region_name': CONF.service_auth.region_name}
150+
# TODO(ricolin) `interface` option don't take list as option yet.
151+
# We can move away from this when openstacksdk no longer depends
152+
# on `interface`.
153+
try:
154+
interface = CONF.service_auth.valid_interfaces[0]
155+
except (TypeError, LookupError):
156+
interface = CONF.service_auth.valid_interfaces
157+
if interface:
158+
kwargs['interface'] = interface
159+
160+
self.loadbalancer_proxy = openstack.connection.Connection(
161+
session=ksession.session, **kwargs).load_balancer
162+
except Exception:
163+
with excutils.save_and_reraise_exception():
164+
LOG.exception("Error creating Octavia client.")
165+
166+
167+
def get_octavia_client():
168+
try:
169+
return OctaviaAuth().loadbalancer_proxy
170+
except Exception as e:
171+
msg = _('Cannot initialize OpenStackSDK. Exception: %s. '
172+
'Please verify service_auth configuration '
173+
'in Octavia API configuration.') % e
174+
raise driver_exceptions.DriverError(
175+
operator_fault_string=msg)

ovn_octavia_provider/driver.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from octavia_lib.common import constants
2222
from oslo_log import log as logging
2323

24+
from ovn_octavia_provider.common import clients
2425
from ovn_octavia_provider.common import config as ovn_conf
2526
# TODO(mjozefcz): Start consuming const and utils
2627
# from neutron-lib once released.
@@ -588,5 +589,8 @@ def health_monitor_delete(self, healthmonitor):
588589

589590
def do_sync(self, **lb_filters):
590591
LOG.info(f"Starting sync OVN DB with Loadbalancer filter {lb_filters}")
591-
# TODO(froyo): get LBs from Octavia DB through openstack sdk client and
592-
# call to helper methods to sync
592+
octavia_client = clients.get_octavia_client()
593+
# We can add project_id to lb_filters for lbs to limit the scope.
594+
lbs = self._ovn_helper.get_octavia_lbs(octavia_client, **lb_filters)
595+
for lb in lbs:
596+
LOG.info(f"Starting sync OVN DB with Loadbalancer {lb.id}")

ovn_octavia_provider/helper.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,15 @@ def _neutron_list_ports(self, neutron_client, **params):
452452
def _neutron_find_port(self, neutron_client, **params):
453453
return neutron_client.find_port(**params)
454454

455+
@tenacity.retry(
456+
retry=tenacity.retry_if_exception_type(
457+
openstack.exceptions.HttpException),
458+
wait=tenacity.wait_exponential(),
459+
stop=tenacity.stop_after_delay(10),
460+
reraise=True)
461+
def get_octavia_lbs(self, octavia_client, **params):
462+
return octavia_client.load_balancers(**params)
463+
455464
def _find_ovn_lbs(self, lb_id, protocol=None):
456465
"""Find the Loadbalancers in OVN with the given lb_id as its name
457466

ovn_octavia_provider/tests/unit/common/test_clients.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from unittest import mock
1515

1616
from keystoneauth1 import exceptions as ks_exceptions
17+
from octavia_lib.api.drivers import exceptions as driver_exceptions
1718
from oslo_config import cfg
1819
from oslo_config import fixture as oslo_fixture
1920
from oslotest import base
@@ -127,3 +128,70 @@ def test_singleton_exception(self):
127128
c3 = clients.NeutronAuth()
128129
self.assertIs(c2, c3)
129130
self.assertEqual(os_sdk._mock_call_count, 2)
131+
132+
@mock.patch.object(clients, 'KeystoneSession')
133+
def test_get_client(self, mock_ks):
134+
clients.get_neutron_client()
135+
self.mock_client.assert_called_once_with(
136+
session=mock_ks().session)
137+
138+
@mock.patch.object(clients, 'NeutronAuth', side_effect=[RuntimeError])
139+
def test_get_client_error(self, mock_ks):
140+
msg = self.assertRaises(
141+
driver_exceptions.DriverError,
142+
clients.get_neutron_client)
143+
self.assertEqual("An unknown driver error occurred.", str(msg))
144+
145+
146+
class TestOctaviaAuth(base.BaseTestCase):
147+
def setUp(self):
148+
super().setUp()
149+
config.register_opts()
150+
self.mock_client = mock.patch(
151+
'openstack.connection.Connection').start()
152+
clients.Singleton._instances = {}
153+
154+
@mock.patch.object(clients, 'KeystoneSession')
155+
@mock.patch('openstack.connection.Connection')
156+
def test_init(self, mock_conn, mock_ks):
157+
clients.OctaviaAuth()
158+
mock_conn.assert_called_once_with(
159+
session=mock_ks().session,
160+
region_name=mock.ANY
161+
)
162+
163+
def test_singleton(self):
164+
c1 = clients.OctaviaAuth()
165+
c2 = clients.OctaviaAuth()
166+
self.assertIs(c1, c2)
167+
168+
def test_singleton_exception(self):
169+
mock_client = mock.Mock()
170+
mock_client.lbaas_proxy = 'foo'
171+
with mock.patch(
172+
'openstack.connection.Connection',
173+
side_effect=[RuntimeError,
174+
mock_client, mock_client]) as os_sdk:
175+
self.assertRaises(
176+
RuntimeError,
177+
clients.OctaviaAuth)
178+
c2 = clients.OctaviaAuth()
179+
c3 = clients.OctaviaAuth()
180+
self.assertIs(c2, c3)
181+
self.assertEqual(os_sdk._mock_call_count, 2)
182+
183+
@mock.patch.object(clients, 'KeystoneSession')
184+
@mock.patch('openstack.connection.Connection')
185+
def test_get_client(self, mock_conn, mock_ks):
186+
clients.get_octavia_client()
187+
mock_conn.assert_called_once_with(
188+
session=mock_ks().session,
189+
region_name=mock.ANY
190+
)
191+
192+
@mock.patch.object(clients, 'OctaviaAuth', side_effect=[RuntimeError])
193+
def test_get_client_error(self, mock_ks):
194+
msg = self.assertRaises(
195+
driver_exceptions.DriverError,
196+
clients.get_octavia_client)
197+
self.assertEqual("An unknown driver error occurred.", str(msg))

0 commit comments

Comments
 (0)