Don't send malformed status update to Octavia

In some corner cases while updating a member, OVN
Provider Driver sends a malformed status update
to Octavia that breaks the update operation and
resources stuck in PENDING_UPDATE state.

In OVN while resource is administratively disabled
we suffix its ID with string ':D'.
This patch filters this string from resources ID
before sending Octavia a status update.

Because for now we don't have running master branch
for OVN provider driver this change will be applied
first on stable/train and then cherry-picked.

Change-Id: Ib2ce04625faddd6ed263678bad2f4eb10929a520
Closes-Bug: #1860140
This commit is contained in:
Maciej Józefczyk 2020-01-17 14:38:26 +00:00
parent df5c32dc86
commit 439fc8f4b0
2 changed files with 32 additions and 0 deletions

View File

@ -14,6 +14,7 @@
import atexit
import copy
import re
import threading
import netaddr
@ -243,6 +244,14 @@ class OvnProviderHelper(object):
return not any([k.startswith('listener') or k.startswith('pool')
for k in external_ids])
@staticmethod
def _delete_disabled_from_status(status):
d_regex = ':%s$' % DISABLED_RESOURCE_SUFFIX
return {
k: [{c: re.sub(d_regex, '', d) for c, d in i.items()}
for i in v]
for k, v in status.items()}
def _check_and_set_ssl_files(self):
# TODO(reedip): Make ovsdb_monitor's _check_and_set_ssl_files() public
# This is a copy of ovsdb_monitor._check_and_set_ssl_files
@ -473,6 +482,8 @@ class OvnProviderHelper(object):
def _update_status_to_octavia(self, status):
try:
status = OvnProviderHelper._delete_disabled_from_status(status)
LOG.debug('Updating status to octavia: %s', status)
self._octavia_driver_lib.update_loadbalancer_status(status)
except driver_exceptions.UpdateStatusError as e:
msg = ("Error while updating the load balancer "

View File

@ -763,6 +763,27 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
self.ovn_lb.external_ids.pop('pool_%s' % self.pool_id)
self.assertTrue(f(self.ovn_lb.external_ids))
def test__delete_disabled_from_status(self):
f = self.helper._delete_disabled_from_status
status = {
'pools': [
{'id': 'f:D', 'provisioning_status': 'ACTIVE',
'operating_status': 'ONLINE'}],
'members': [
{'id': 'foo:D',
'provisioning_status': 'ACTIVE'}]}
expected = {
'pools': [
{'id': 'f', 'provisioning_status': 'ACTIVE',
'operating_status': 'ONLINE'}],
'members': [
{'id': 'foo',
'provisioning_status': 'ACTIVE'}]}
self.assertEqual(f(status), expected)
self.assertEqual(f(expected), expected)
status = {}
self.assertEqual(f(status), {})
def test__find_ovn_lbs(self):
self.mock_find_ovn_lbs.stop()
f = self.helper._find_ovn_lbs