Browse Source

Improve error handling for ChassisMetadataAgentEvent

The ChassisMetadataAgentEvent class is suppose to handle events which
are triggered when a Chassis entry is created or updated in the OVSDB.
Prior to this patch, it was assumed that the external_ids column of that
entry would contain the "neutron:ovn-metadata-sb-cfg" key in it which is
not always true.

This patch is fixing the problem by handling the case which that key is
not yet present in the Chassis external_ids column.

The patch also prevent the ChassisMetadataAgentEvent from running by
not adding it to the list of events to watch in case the OVN metadata
is not enabled.

Change-Id: Ie7f348a70a6f0c67f1822f73e0c559eac46b18bb
Closes-Bug: #1816033
Signed-off-by: Lucas Alvares Gomes <lucasagomes@gmail.com>
tags/6.0.0.0b1
Lucas Alvares Gomes 3 months ago
parent
commit
39fe6c7f34

+ 13
- 5
networking_ovn/ovsdb/ovsdb_monitor.py View File

@@ -94,8 +94,15 @@ class ChassisMetadataAgentEvent(BaseEvent):
94 94
             return False
95 95
 
96 96
     def run(self, event, row, old):
97
-        stats.AgentStats.add_stat(utils.ovn_metadata_name(row.uuid),
98
-                                  self._metadata_nb_cfg(row))
97
+        try:
98
+            stats.AgentStats.add_stat(utils.ovn_metadata_name(row.uuid),
99
+                                      self._metadata_nb_cfg(row))
100
+        except (AttributeError, KeyError):
101
+            LOG.warning('No "%(key)s" key found for the metadata agent at '
102
+                        'Chassis %(chassis)s',
103
+                        {'key': ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY,
104
+                         'chassis': row.uuid})
105
+            return
99 106
 
100 107
 
101 108
 class ChassisEvent(row_event.RowEvent):
@@ -275,9 +282,10 @@ class BaseOvnSbIdl(connection.OvsdbIdl):
275 282
     def __init__(self, remote, schema):
276 283
         super(BaseOvnSbIdl, self).__init__(remote, schema)
277 284
         self.notify_handler = event.RowEventHandler()
278
-        self.notify_handler.watch_events([
279
-            ChassisAgentDeleteEvent(), ChassisMetadataAgentEvent(),
280
-            ChassisGatewayAgentEvent()])
285
+        events = [ChassisAgentDeleteEvent(), ChassisGatewayAgentEvent()]
286
+        if ovn_config.is_ovn_metadata_enabled():
287
+            events.append(ChassisMetadataAgentEvent())
288
+        self.notify_handler.watch_events(events)
281 289
 
282 290
     @classmethod
283 291
     def from_server(cls, connection_string, schema_name):

+ 62
- 0
networking_ovn/tests/unit/ovsdb/test_ovsdb_monitor.py View File

@@ -26,8 +26,11 @@ from ovsdbapp.backend.ovs_idl import connection
26 26
 from ovsdbapp.backend.ovs_idl import idlutils
27 27
 
28 28
 from networking_ovn.common import config as ovn_config
29
+from networking_ovn.common import constants as ovn_const
30
+from networking_ovn.common import utils
29 31
 from networking_ovn.ovsdb import ovsdb_monitor
30 32
 from networking_ovn.tests import base
33
+from networking_ovn.tests.unit import fakes
31 34
 from networking_ovn.tests.unit.ml2 import test_mech_driver
32 35
 
33 36
 basedir = os.path.dirname(os.path.abspath(__file__))
@@ -79,6 +82,10 @@ OVN_SB_SCHEMA = {
79 82
 }
80 83
 
81 84
 
85
+ROW_CREATE = ovsdb_monitor.BaseEvent.ROW_CREATE
86
+ROW_UPDATE = ovsdb_monitor.BaseEvent.ROW_UPDATE
87
+
88
+
82 89
 class TestOvnNbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
83 90
 
84 91
     def setUp(self):
@@ -367,3 +374,58 @@ class TestOvnConnection(base.TestCase):
367 374
     def test_connection_sb_start(self):
368 375
         self._test_connection_start(idl_class=ovsdb_monitor.OvnSbIdl,
369 376
                                     schema='OVN_Southbound')
377
+
378
+
379
+class TestChassisMetadataAgentEvent(base.TestCase):
380
+
381
+    def setUp(self):
382
+        super(TestChassisMetadataAgentEvent, self).setUp()
383
+        self.event = ovsdb_monitor.ChassisMetadataAgentEvent()
384
+
385
+        patcher = mock.patch.object(ovsdb_monitor.stats, 'AgentStats')
386
+        self.agent_stats = patcher.start()
387
+        self.addCleanup(patcher.stop)
388
+
389
+    def test_run(self):
390
+        row = fakes.FakeOvsdbRow.create_one_ovsdb_row(
391
+            attrs={'external_ids': {
392
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '1'}})
393
+
394
+        self.event.run(mock.ANY, row, mock.ANY)
395
+        self.agent_stats.add_stat.assert_called_once_with(
396
+            utils.ovn_metadata_name(row.uuid), 1)
397
+
398
+    def test_run_no_metadata_cfg(self):
399
+        row = fakes.FakeOvsdbRow.create_one_ovsdb_row()
400
+        self.assertIsNone(self.event.run(mock.ANY, row, mock.ANY))
401
+
402
+    def test_match_fn_event_create(self):
403
+        self.assertTrue(self.event.match_fn(ROW_CREATE, mock.ANY))
404
+
405
+    def test_match_fn_missing_metadata_key(self):
406
+        row = fakes.FakeOvsdbRow.create_one_ovsdb_row(
407
+            attrs={'external_ids': {
408
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '1'}})
409
+        old = fakes.FakeOvsdbRow.create_one_ovsdb_row()
410
+
411
+        self.assertFalse(self.event.match_fn(ROW_UPDATE, row, old=old))
412
+
413
+    def test_match_fn_nb_cfg_match(self):
414
+        row = fakes.FakeOvsdbRow.create_one_ovsdb_row(
415
+            attrs={'external_ids': {
416
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '1'}})
417
+        old = fakes.FakeOvsdbRow.create_one_ovsdb_row(
418
+            attrs={'external_ids': {
419
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '1'}})
420
+
421
+        self.assertFalse(self.event.match_fn(ROW_UPDATE, row, old=old))
422
+
423
+    def test_match_fn_nb_cfg_doesnt_match(self):
424
+        row = fakes.FakeOvsdbRow.create_one_ovsdb_row(
425
+            attrs={'external_ids': {
426
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '2'}})
427
+        old = fakes.FakeOvsdbRow.create_one_ovsdb_row(
428
+            attrs={'external_ids': {
429
+                ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: '1'}})
430
+
431
+        self.assertTrue(self.event.match_fn(ROW_UPDATE, row, old=old))

Loading…
Cancel
Save