Update tap ip in metadata agent when metadata port ip updated
Update neutron-ovn-metadata-agent, catch port_binding update event of monitoring localport type, and judge if the neutron:cidrs field in the external_ids of port_binding table has changed, then update_datapath. Closes-Bug: #1996677 Change-Id: Ibdc1b385b07a2ab1ca8e4b6278f6d39fb5839509
This commit is contained in:
parent
a358bb802b
commit
686698284b
@ -43,7 +43,7 @@ CHASSIS_METADATA_LOCK = 'chassis_metadata_lock'
|
||||
|
||||
NS_PREFIX = 'ovnmeta-'
|
||||
MAC_PATTERN = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
|
||||
OVN_VIF_PORT_TYPES = ("", "external", )
|
||||
OVN_VIF_PORT_TYPES = ("", "external", ovn_const.LSP_TYPE_LOCALPORT, )
|
||||
|
||||
MetadataPortInfo = collections.namedtuple('MetadataPortInfo', ['mac',
|
||||
'ip_addresses'])
|
||||
@ -82,6 +82,20 @@ class PortBindingChassisEvent(row_event.RowEvent):
|
||||
resync = False
|
||||
if row.type not in OVN_VIF_PORT_TYPES:
|
||||
return
|
||||
if row.type == ovn_const.LSP_TYPE_LOCALPORT:
|
||||
new_ext_ids = row.external_ids
|
||||
old_ext_ids = old.external_ids
|
||||
device_id = row.external_ids.get(
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
|
||||
if not device_id.startswith(NS_PREFIX):
|
||||
return
|
||||
new_cidrs = new_ext_ids.get(ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
|
||||
old_cidrs = old_ext_ids.get(ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
|
||||
# If old_cidrs is "", it is create event,
|
||||
# nothing needs to be done.
|
||||
# If old_cidrs equals new_cidrs, the ip does not change.
|
||||
if old_cidrs in ("", new_cidrs, ):
|
||||
return
|
||||
with _SYNC_STATE_LOCK.read_lock():
|
||||
try:
|
||||
net_name = ovn_utils.get_network_name_from_datapath(
|
||||
@ -96,6 +110,24 @@ class PortBindingChassisEvent(row_event.RowEvent):
|
||||
self.agent.resync()
|
||||
|
||||
|
||||
class PortBindingMetaPortUpdatedEvent(PortBindingChassisEvent):
|
||||
LOG_MSG = "Metadata Port %s in datapath %s updated."
|
||||
|
||||
def __init__(self, metadata_agent):
|
||||
events = (self.ROW_UPDATE,)
|
||||
super(PortBindingMetaPortUpdatedEvent, self).__init__(
|
||||
metadata_agent, events)
|
||||
|
||||
def match_fn(self, event, row, old):
|
||||
if row.type == ovn_const.LSP_TYPE_LOCALPORT:
|
||||
if hasattr(row, 'external_ids') and hasattr(old, 'external_ids'):
|
||||
device_id = row.external_ids.get(
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
|
||||
if device_id.startswith(NS_PREFIX):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class PortBindingChassisCreatedEvent(PortBindingChassisEvent):
|
||||
LOG_MSG = "Port %s in datapath %s bound to our chassis"
|
||||
|
||||
@ -245,7 +277,8 @@ class MetadataAgent(object):
|
||||
'Chassis')
|
||||
events = (PortBindingChassisCreatedEvent(self),
|
||||
PortBindingChassisDeletedEvent(self),
|
||||
SbGlobalUpdateEvent(self))
|
||||
SbGlobalUpdateEvent(self),
|
||||
PortBindingMetaPortUpdatedEvent(self))
|
||||
|
||||
# TODO(lucasagomes): Remove this in the future. Try to register
|
||||
# the Chassis_Private table, if not present, fallback to the normal
|
||||
|
@ -141,7 +141,19 @@ class TestMetadataAgent(base.TestOVNFunctionalBase):
|
||||
type=ovn_const.LSP_TYPE_LOCALPORT,
|
||||
addresses='AA:AA:AA:AA:AA:AA 192.168.122.123',
|
||||
external_ids={
|
||||
ovn_const.OVN_CIDRS_EXT_ID_KEY: '192.168.122.123/24'}))
|
||||
ovn_const.OVN_CIDRS_EXT_ID_KEY: '192.168.122.123/24',
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY: 'ovnmeta-' + lswitch_name
|
||||
}))
|
||||
return mdt_port_name
|
||||
|
||||
def _update_metadata_port_ip(self, metadata_port_name):
|
||||
external_ids = {
|
||||
ovn_const.OVN_CIDRS_EXT_ID_KEY: "192.168.122.2/24",
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY:
|
||||
'ovnmeta-' + uuidutils.generate_uuid()
|
||||
}
|
||||
self.nb_api.set_lswitch_port(lport_name=metadata_port_name,
|
||||
external_ids=external_ids).execute()
|
||||
|
||||
def _create_logical_switch_port(self, type_=None):
|
||||
lswitch_name = 'ovn-' + uuidutils.generate_uuid()
|
||||
@ -192,16 +204,25 @@ class TestMetadataAgent(base.TestOVNFunctionalBase):
|
||||
|
||||
n_utils.wait_until_true(check_mock_pbinding, timeout=10, exception=exc)
|
||||
|
||||
def _test_agent_events(self, delete, type_=None):
|
||||
def _test_agent_events(self, delete, type_=None, update=False):
|
||||
m_pb_created = mock.patch.object(
|
||||
agent.PortBindingChassisCreatedEvent, 'run').start()
|
||||
m_pb_deleted = mock.patch.object(
|
||||
agent.PortBindingChassisDeletedEvent, 'run').start()
|
||||
m_pb_updated = mock.patch.object(
|
||||
agent.PortBindingMetaPortUpdatedEvent, 'run').start()
|
||||
|
||||
lswitchport_name, lswitch_name = self._create_logical_switch_port(
|
||||
type_)
|
||||
self.sb_api.lsp_bind(lswitchport_name, self.chassis_name).execute(
|
||||
check_error=True, log_errors=True)
|
||||
if update and type_ == ovn_const.LSP_TYPE_LOCALPORT:
|
||||
with self.nb_api.transaction(
|
||||
check_error=True, log_errors=True) as txn:
|
||||
mdt_port_name = self._create_metadata_port(txn, lswitch_name)
|
||||
self.sb_api.lsp_bind(mdt_port_name, self.chassis_name).execute(
|
||||
check_error=True, log_errors=True)
|
||||
self._update_metadata_port_ip(mdt_port_name)
|
||||
|
||||
def pb_created():
|
||||
if m_pb_created.call_count < 1:
|
||||
@ -219,6 +240,31 @@ class TestMetadataAgent(base.TestOVNFunctionalBase):
|
||||
"PortBindingChassisCreatedEvent didn't happen on port "
|
||||
"binding."))
|
||||
|
||||
def pb_updated():
|
||||
if m_pb_updated.call_count < 1:
|
||||
return False
|
||||
args = m_pb_updated.call_args[0]
|
||||
self.assertEqual('update', args[0])
|
||||
self.assertTrue(args[1].external_ids)
|
||||
self.assertTrue(args[2].external_ids)
|
||||
device_id = args[1].external_ids.get(
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
|
||||
self.assertTrue(device_id.startswith("ovnmeta-"))
|
||||
new_cidrs = args[1].external_ids.get(
|
||||
ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
|
||||
old_cidrs = args[2].external_ids.get(
|
||||
ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
|
||||
self.assertNotEqual(new_cidrs, old_cidrs)
|
||||
self.assertNotEqual(old_cidrs, "")
|
||||
return True
|
||||
if update and type_ == ovn_const.LSP_TYPE_LOCALPORT:
|
||||
n_utils.wait_until_true(
|
||||
pb_updated,
|
||||
timeout=10,
|
||||
exception=Exception(
|
||||
"PortBindingMetaPortUpdatedEvent didn't happen on "
|
||||
"metadata port ip address updated."))
|
||||
|
||||
if delete:
|
||||
self.nb_api.delete_lswitch_port(
|
||||
lswitchport_name, lswitch_name).execute(
|
||||
@ -290,6 +336,10 @@ class TestMetadataAgent(base.TestOVNFunctionalBase):
|
||||
timeout=10,
|
||||
exception=exc)
|
||||
|
||||
def test_agent_metadata_port_ip_update_event(self):
|
||||
self._test_agent_events(
|
||||
delete=False, type_=ovn_const.LSP_TYPE_LOCALPORT, update=True)
|
||||
|
||||
def test_metadata_agent_only_monitors_own_chassis(self):
|
||||
# We already have the fake chassis which we should be monitoring, so
|
||||
# create an event looking for a change to another chassis
|
||||
|
6
releasenotes/notes/bug-1996677-64851b476a0c5a37.yaml
Normal file
6
releasenotes/notes/bug-1996677-64851b476a0c5a37.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
`1996677 <https://bugs.launchpad.net/neutron/+bug/1996677>`_
|
||||
When the fixed_ips of metadata port is modified, the ip address of
|
||||
tap device in metadata agent is modified.
|
Loading…
Reference in New Issue
Block a user