Skip to content

Commit 0e7cc8b

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] Expose chassis hosting information in LSP" into stable/yoga
2 parents 3bf5e62 + 3e6b2b7 commit 0e7cc8b

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
@@ -50,6 +50,7 @@
5050
OVN_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:liveness_check_at'
5151
METADATA_LIVENESS_CHECK_EXT_ID_KEY = 'neutron:metadata_liveness_check_at'
5252
OVN_PORT_BINDING_PROFILE = portbindings.PROFILE
53+
OVN_HOST_ID_EXT_ID_KEY = 'neutron:host_id'
5354

5455
MIGRATING_ATTR = 'migrating_to'
5556
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
@@ -1118,6 +1118,8 @@ def set_port_status_up(self, port_id):
11181118
const.PORT_STATUS_ACTIVE)
11191119
elif self._should_notify_nova(db_port):
11201120
self._plugin.nova_notifier.notify_port_active_direct(db_port)
1121+
1122+
self._ovn_client.update_lsp_host_info(admin_context, db_port)
11211123
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11221124
LOG.debug('Port not found during OVN status up report: %s',
11231125
port_id)
@@ -1146,6 +1148,9 @@ def set_port_status_down(self, port_id):
11461148
None)
11471149
self._plugin.nova_notifier.send_port_status(
11481150
None, None, db_port)
1151+
1152+
self._ovn_client.update_lsp_host_info(
1153+
admin_context, db_port, up=False)
11491154
except (os_db_exc.DBReferenceError, n_exc.PortNotFound):
11501155
LOG.debug("Port not found during OVN status down report: %s",
11511156
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
@@ -1059,7 +1059,9 @@ def _test_set_port_status_up(self, is_compute_port=False):
10591059
mock.patch.object(self.mech_driver,
10601060
'_update_dnat_entry_if_needed') as ude, \
10611061
mock.patch.object(self.mech_driver, '_should_notify_nova',
1062-
return_value=is_compute_port):
1062+
return_value=is_compute_port), \
1063+
mock.patch.object(self.mech_driver._ovn_client,
1064+
'update_lsp_host_info') as ulsp:
10631065
self.mech_driver.set_port_status_up(port1['port']['id'])
10641066
pc.assert_called_once_with(
10651067
mock.ANY,
@@ -1079,6 +1081,8 @@ def _test_set_port_status_up(self, is_compute_port=False):
10791081
notify_port_active_direct.assert_called_once_with(
10801082
mock.ANY)
10811083

1084+
ulsp.assert_called_once_with(mock.ANY, mock.ANY)
1085+
10821086
def test_set_port_status_up(self):
10831087
self._test_set_port_status_up(is_compute_port=False)
10841088

@@ -1098,7 +1102,9 @@ def _test_set_port_status_down(self, is_compute_port=False):
10981102
mock.patch.object(self.mech_driver,
10991103
'_update_dnat_entry_if_needed') as ude, \
11001104
mock.patch.object(self.mech_driver, '_should_notify_nova',
1101-
return_value=is_compute_port):
1105+
return_value=is_compute_port), \
1106+
mock.patch.object(self.mech_driver._ovn_client,
1107+
'update_lsp_host_info') as ulsp:
11021108
self.mech_driver.set_port_status_down(port1['port']['id'])
11031109
apc.assert_called_once_with(
11041110
mock.ANY,
@@ -1124,6 +1130,8 @@ def _test_set_port_status_down(self, is_compute_port=False):
11241130
send_port_status.assert_called_once_with(
11251131
None, None, mock.ANY)
11261132

1133+
ulsp.assert_called_once_with(mock.ANY, mock.ANY, up=False)
1134+
11271135
def test_set_port_status_down(self):
11281136
self._test_set_port_status_down(is_compute_port=False)
11291137

0 commit comments

Comments
 (0)