Skip to content

Commit 97f8ee9

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] Expose chassis hosting information in LSP" into stable/2023.1
2 parents 5dde1b0 + 82e9420 commit 97f8ee9

File tree

5 files changed

+76
-3
lines changed

5 files changed

+76
-3
lines changed

neutron/common/ovn/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
OVN_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:liveness_check_at'
5656
METADATA_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:metadata_liveness_check_at'
5757
OVN_PORT_BINDING_PROFILE = portbindings.PROFILE
58+
OVN_HOST_ID_EXT_ID_KEY = 'neutron:host_id'
5859

5960
MIGRATING_ATTR = 'migrating_to'
6061
OVN_ROUTER_PORT_OPTION_KEYS = ['router-port', 'nat-addresses',

neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,8 @@ def set_port_status_up(self, port_id):
11301130
const.PORT_STATUS_ACTIVE)
11311131
elif self._should_notify_nova(db_port):
11321132
self._plugin.nova_notifier.notify_port_active_direct(db_port)
1133+
1134+
self._ovn_client.update_lsp_host_info(admin_context, db_port)
11331135
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11341136
LOG.debug('Port not found during OVN status up report: %s',
11351137
port_id)
@@ -1158,6 +1160,9 @@ def set_port_status_down(self, port_id):
11581160
None)
11591161
self._plugin.nova_notifier.send_port_status(
11601162
None, None, db_port)
1163+
1164+
self._ovn_client.update_lsp_host_info(
1165+
admin_context, db_port, up=False)
11611166
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11621167
LOG.debug("Port not found during OVN status down report: %s",
11631168
port_id)

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,36 @@ def determine_bind_host(self, port, port_context=None):
274274
ovn_const.VIF_DETAILS_CARD_SERIAL_NUMBER]).hostname
275275
return ''
276276

277+
def update_lsp_host_info(self, context, db_port, up=True):
278+
"""Update the binding hosting information for the LSP.
279+
280+
Update the binding hosting information in the Logical_Switch_Port
281+
external_ids column. See LP #2020058 for more information.
282+
283+
:param context: Neutron API context.
284+
:param db_port: The Neutron port.
285+
:param up: If True add the host information, if False remove it.
286+
Defaults to True.
287+
"""
288+
cmd = []
289+
if up:
290+
if not db_port.port_bindings:
291+
return
292+
host = db_port.port_bindings[0].host
293+
294+
ext_ids = ('external_ids',
295+
{ovn_const.OVN_HOST_ID_EXT_ID_KEY: host})
296+
cmd.append(
297+
self._nb_idl.db_set(
298+
'Logical_Switch_Port', db_port.id, ext_ids))
299+
else:
300+
cmd.append(
301+
self._nb_idl.db_remove(
302+
'Logical_Switch_Port', db_port.id, 'external_ids',
303+
ovn_const.OVN_HOST_ID_EXT_ID_KEY, if_exists=True))
304+
305+
self._transaction(cmd)
306+
277307
def _get_port_options(self, port):
278308
context = n_context.get_admin_context()
279309
bp_info = utils.validate_and_get_data_from_binding_profile(port)
@@ -428,7 +458,12 @@ def _get_port_options(self, port):
428458
# a RARP packet from it to inform network about the new
429459
# location of the port
430460
options['activation-strategy'] = 'rarp'
431-
options[ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY] = chassis
461+
462+
# Virtual ports can not be bound by using the
463+
# requested-chassis mechanism, ovn-controller will create the
464+
# Port_Binding entry when it sees an ARP coming from the VIP
465+
if port_type != ovn_const.LSP_TYPE_VIRTUAL:
466+
options[ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY] = chassis
432467

433468
# TODO(lucasagomes): Enable the mcast_flood_reports by default,
434469
# according to core OVN developers it shouldn't cause any harm

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ def test__add_router_ext_gw_no_default_route(self):
103103
self.ovn_client._add_router_ext_gw(router, networks, txn))
104104
self.nb_idl.add_static_route.assert_not_called()
105105

106+
def test_update_lsp_host_info_up(self):
107+
context = mock.MagicMock()
108+
host_id = 'fake-binding-host-id'
109+
port_id = 'fake-port-id'
110+
db_port = mock.Mock(
111+
id=port_id, port_bindings=[mock.Mock(host=host_id)])
112+
113+
self.ovn_client.update_lsp_host_info(context, db_port)
114+
115+
self.nb_idl.db_set.assert_called_once_with(
116+
'Logical_Switch_Port', port_id,
117+
('external_ids', {constants.OVN_HOST_ID_EXT_ID_KEY: host_id}))
118+
119+
def test_update_lsp_host_info_down(self):
120+
context = mock.MagicMock()
121+
port_id = 'fake-port-id'
122+
db_port = mock.Mock(id=port_id)
123+
124+
self.ovn_client.update_lsp_host_info(context, db_port, up=False)
125+
126+
self.nb_idl.db_remove.assert_called_once_with(
127+
'Logical_Switch_Port', port_id, 'external_ids',
128+
constants.OVN_HOST_ID_EXT_ID_KEY, if_exists=True)
129+
106130

107131
class TestOVNClientDetermineBindHost(TestOVNClientBase):
108132

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,9 @@ def _test_set_port_status_up(self, is_compute_port=False):
10771077
mock.patch.object(self.mech_driver,
10781078
'_update_dnat_entry_if_needed') as ude, \
10791079
mock.patch.object(self.mech_driver, '_should_notify_nova',
1080-
return_value=is_compute_port):
1080+
return_value=is_compute_port), \
1081+
mock.patch.object(self.mech_driver._ovn_client,
1082+
'update_lsp_host_info') as ulsp:
10811083
self.mech_driver.set_port_status_up(port1['port']['id'])
10821084
pc.assert_called_once_with(
10831085
mock.ANY,
@@ -1097,6 +1099,8 @@ def _test_set_port_status_up(self, is_compute_port=False):
10971099
notify_port_active_direct.assert_called_once_with(
10981100
mock.ANY)
10991101

1102+
ulsp.assert_called_once_with(mock.ANY, mock.ANY)
1103+
11001104
def test_set_port_status_up(self):
11011105
self._test_set_port_status_up(is_compute_port=False)
11021106

@@ -1116,7 +1120,9 @@ def _test_set_port_status_down(self, is_compute_port=False):
11161120
mock.patch.object(self.mech_driver,
11171121
'_update_dnat_entry_if_needed') as ude, \
11181122
mock.patch.object(self.mech_driver, '_should_notify_nova',
1119-
return_value=is_compute_port):
1123+
return_value=is_compute_port), \
1124+
mock.patch.object(self.mech_driver._ovn_client,
1125+
'update_lsp_host_info') as ulsp:
11201126
self.mech_driver.set_port_status_down(port1['port']['id'])
11211127
apc.assert_called_once_with(
11221128
mock.ANY,
@@ -1142,6 +1148,8 @@ def _test_set_port_status_down(self, is_compute_port=False):
11421148
send_port_status.assert_called_once_with(
11431149
None, None, mock.ANY)
11441150

1151+
ulsp.assert_called_once_with(mock.ANY, mock.ANY, up=False)
1152+
11451153
def test_set_port_status_down(self):
11461154
self._test_set_port_status_down(is_compute_port=False)
11471155

0 commit comments

Comments
 (0)