Skip to content

Commit a521e2a

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] Expose chassis hosting information in LSP" into stable/zed
2 parents 67f3ab4 + 984193b commit a521e2a

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
@@ -53,6 +53,7 @@
5353
OVN_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:liveness_check_at'
5454
METADATA_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:metadata_liveness_check_at'
5555
OVN_PORT_BINDING_PROFILE = portbindings.PROFILE
56+
OVN_HOST_ID_EXT_ID_KEY = 'neutron:host_id'
5657

5758
MIGRATING_ATTR = 'migrating_to'
5859
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
@@ -1126,6 +1126,8 @@ def set_port_status_up(self, port_id):
11261126
const.PORT_STATUS_ACTIVE)
11271127
elif self._should_notify_nova(db_port):
11281128
self._plugin.nova_notifier.notify_port_active_direct(db_port)
1129+
1130+
self._ovn_client.update_lsp_host_info(admin_context, db_port)
11291131
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11301132
LOG.debug('Port not found during OVN status up report: %s',
11311133
port_id)
@@ -1154,6 +1156,9 @@ def set_port_status_down(self, port_id):
11541156
None)
11551157
self._plugin.nova_notifier.send_port_status(
11561158
None, None, db_port)
1159+
1160+
self._ovn_client.update_lsp_host_info(
1161+
admin_context, db_port, up=False)
11571162
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11581163
LOG.debug("Port not found during OVN status down report: %s",
11591164
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
@@ -271,6 +271,36 @@ def determine_bind_host(self, port, port_context=None):
271271
ovn_const.VIF_DETAILS_CARD_SERIAL_NUMBER]).hostname
272272
return ''
273273

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

431466
# TODO(lucasagomes): Enable the mcast_flood_reports by default,
432467
# 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
@@ -126,6 +126,30 @@ def test_vnic_remote_managed_port_context(self):
126126
self.fake_smartnic_hostname,
127127
self.ovn_client.determine_bind_host({}, port_context=context))
128128

129+
def test_update_lsp_host_info_up(self):
130+
context = mock.MagicMock()
131+
host_id = 'fake-binding-host-id'
132+
port_id = 'fake-port-id'
133+
db_port = mock.Mock(
134+
id=port_id, port_bindings=[mock.Mock(host=host_id)])
135+
136+
self.ovn_client.update_lsp_host_info(context, db_port)
137+
138+
self.nb_idl.db_set.assert_called_once_with(
139+
'Logical_Switch_Port', port_id,
140+
('external_ids', {constants.OVN_HOST_ID_EXT_ID_KEY: host_id}))
141+
142+
def test_update_lsp_host_info_down(self):
143+
context = mock.MagicMock()
144+
port_id = 'fake-port-id'
145+
db_port = mock.Mock(id=port_id)
146+
147+
self.ovn_client.update_lsp_host_info(context, db_port, up=False)
148+
149+
self.nb_idl.db_remove.assert_called_once_with(
150+
'Logical_Switch_Port', port_id, 'external_ids',
151+
constants.OVN_HOST_ID_EXT_ID_KEY, if_exists=True)
152+
129153

130154
class TestOVNClientFairMeter(TestOVNClientBase,
131155
test_log_driver.TestOVNDriverBase):

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)