From 162b02195c41d93f3ef8af77dafd460877d1bb2c Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Mon, 20 Dec 2021 14:14:20 +0000 Subject: [PATCH] [OVN] Accept OVS system-id as non UUID formatted string Accept OVS system-id non UUID formatted strings. The OVN metadata agent will generate a unique UUID from the OVS system-id. If this string is a UUID, this value will be used. If not, the OVN metadata agent will generate a UUID based on the provided string. This patch amends [1]. [1]https://review.opendev.org/c/openstack/neutron/+/819634 Closes-Bug: #1952550 Conflicts: neutron/agent/ovn/metadata/agent.py neutron/tests/unit/agent/ovn/metadata/test_agent.py Change-Id: I42a8a767a6ef9454419b26f80339394759644faf (cherry picked from commit 79037c951637dc06d47b6d354776d116a1d2a9ad) (cherry picked from commit 6da4432fed255f3bcf3831f5d0520ab389ce36e5) (cherry picked from commit b07eeb2789abc79c0fa86db0bdf7bc111ea725ac) (cherry picked from commit 4bf531448eac151b53b05cae0a5ca51060ca38c3) --- neutron/agent/ovn/metadata/agent.py | 20 ++++++++++++---- .../unit/agent/ovn/metadata/test_agent.py | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/neutron/agent/ovn/metadata/agent.py b/neutron/agent/ovn/metadata/agent.py index 0dda32309d0..0e9b470d085 100644 --- a/neutron/agent/ovn/metadata/agent.py +++ b/neutron/agent/ovn/metadata/agent.py @@ -14,12 +14,12 @@ import collections import re +import uuid from neutron_lib import constants as n_const from oslo_concurrency import lockutils from oslo_log import log from oslo_utils import netutils -from oslo_utils import uuidutils from ovsdbapp.backend.ovs_idl import event as row_event from ovsdbapp.backend.ovs_idl import vlog import six @@ -48,6 +48,8 @@ OVN_VIF_PORT_TYPES = ("", "external", ) MetadataPortInfo = collections.namedtuple('MetadataPortInfo', ['mac', 'ip_addresses']) +OVN_METADATA_UUID_NAMESPACE = uuid.UUID('d34bf9f6-da32-4871-9af8-15a4626b41ab') + def _sync_lock(f): """Decorator to block all operations for a global sync call.""" @@ -185,9 +187,16 @@ class MetadataAgent(object): def _load_config(self): self.chassis = self._get_own_chassis_name() + try: + self.chassis_id = uuid.UUID(self.chassis) + except ValueError: + # OVS system-id could be a non UUID formatted string. + self.chassis_id = uuid.uuid5(OVN_METADATA_UUID_NAMESPACE, + self.chassis) + self.ovn_bridge = self._get_ovn_bridge() - LOG.debug("Loaded chassis %s and ovn bridge %s.", - self.chassis, self.ovn_bridge) + LOG.info("Loaded chassis name %s (UUID: %s) and ovn bridge %s.", + self.chassis, self.chassis_id, self.ovn_bridge) @_sync_lock def resync(self): @@ -245,8 +254,9 @@ class MetadataAgent(object): # NOTE(lucasagomes): db_add() will not overwrite the UUID if # it's already set. table = ('Chassis_Private' if self.has_chassis_private else 'Chassis') - ext_ids = { - ovn_const.OVN_AGENT_METADATA_ID_KEY: uuidutils.generate_uuid()} + # Generate unique, but consistent metadata id for chassis name + agent_id = uuid.uuid5(self.chassis_id, 'metadata_agent') + ext_ids = {ovn_const.OVN_AGENT_METADATA_ID_KEY: str(agent_id)} self.sb_idl.db_add(table, self.chassis, 'external_ids', ext_ids).execute(check_error=True) diff --git a/neutron/tests/unit/agent/ovn/metadata/test_agent.py b/neutron/tests/unit/agent/ovn/metadata/test_agent.py index fa86f9554fc..40a0cdd2845 100644 --- a/neutron/tests/unit/agent/ovn/metadata/test_agent.py +++ b/neutron/tests/unit/agent/ovn/metadata/test_agent.py @@ -13,10 +13,12 @@ # limitations under the License. import collections +import uuid import mock from oslo_config import cfg from oslo_config import fixture as config_fixture +from oslo_utils import uuidutils from neutron.agent.linux import ip_lib from neutron.agent.linux.ip_lib import IpAddrCommand as ip_addr @@ -322,3 +324,24 @@ class TestMetadataAgent(base.BaseTestCase): expected_dps = ['0', '1', '2'] self._test_update_chassis_metadata_networks_helper( dp, remove, expected_dps, txn_called=False) + + def test__load_config(self): + # Chassis name UUID formatted string. OVN bridge "br-ovn". + valid_uuid_str = uuidutils.generate_uuid() + self.agent.ovs_idl.db_get.return_value.execute.side_effect = [ + {'system-id': valid_uuid_str}, {'ovn-bridge': 'br-ovn'}] + self.agent._load_config() + self.assertEqual(valid_uuid_str, self.agent.chassis) + self.assertEqual(uuid.UUID(valid_uuid_str), self.agent.chassis_id) + self.assertEqual('br-ovn', self.agent.ovn_bridge) + + # Chassis name non UUID formatted string. OVN bridge not defined, + # "br-int" assigned by default. + self.agent.ovs_idl.db_get.return_value.execute.side_effect = [ + {'system-id': 'RandomName1'}, {}] + self.agent._load_config() + generated_uuid = uuid.uuid5(agent.OVN_METADATA_UUID_NAMESPACE, + 'RandomName1') + self.assertEqual('RandomName1', self.agent.chassis) + self.assertEqual(generated_uuid, self.agent.chassis_id) + self.assertEqual('br-int', self.agent.ovn_bridge)