Add constant to identify OVN LB HM ports
OVN metadata and OVN LB HM port (used for health checks) are both using network:distributed in the device_owner field. Some tasks in Neutron search by that value, considering just one port will exist per network with that value. This patch adds a new constant to differentiate OVN metadata ports from the OVN LB HM ones. The latter will use a device_owner of ovn-lb-hm:distributed to be different but will still receive the treatment of a localport in the OVN NB DB. Related-Bug: 2038091 Change-Id: I70de163fad34371de10fec28c51959384900ebc8
This commit is contained in:
parent
0e17bd15eb
commit
b2e14b23f3
@ -70,6 +70,10 @@ OVN_ROUTER_PORT_GW_MTU_OPTION = 'gateway_mtu'
|
||||
OVN_PROVNET_PORT_NAME_PREFIX = 'provnet-'
|
||||
OVN_NAME_PREFIX = 'neutron-'
|
||||
|
||||
# TODO(froyo): Move this to neutron-lib as soon as possible, and when a new
|
||||
# release is created and pointed to in the requirements remove this code
|
||||
OVN_LB_HM_PORT_DISTRIBUTED = 'ovn-lb-hm:distributed'
|
||||
|
||||
# Agent extension constants
|
||||
OVN_AGENT_DESC_KEY = 'neutron:description'
|
||||
OVN_AGENT_METADATA_SB_CFG_KEY = 'neutron:ovn-metadata-sb-cfg'
|
||||
|
@ -608,6 +608,11 @@ def is_ovn_metadata_port(port):
|
||||
port['device_id'].startswith('ovnmeta'))
|
||||
|
||||
|
||||
def is_ovn_lb_hm_port(port):
|
||||
return (port['device_owner'] == constants.OVN_LB_HM_PORT_DISTRIBUTED and
|
||||
port['device_id'].startswith('ovn-lb-hm'))
|
||||
|
||||
|
||||
def is_gateway_chassis_invalid(chassis_name, gw_chassis,
|
||||
physnet, chassis_physnets,
|
||||
az_hints, chassis_with_azs):
|
||||
|
@ -15,6 +15,7 @@ import functools
|
||||
import socket
|
||||
import uuid
|
||||
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.utils import helpers
|
||||
from oslo_log import log
|
||||
@ -929,7 +930,10 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
||||
except idlutils.RowNotFound:
|
||||
return None
|
||||
cmd = self.db_find_rows('Port_Binding', ('datapath', '=', dp),
|
||||
('type', '=', ovn_const.LSP_TYPE_LOCALPORT))
|
||||
('type', '=', ovn_const.LSP_TYPE_LOCALPORT),
|
||||
('external_ids', '=', {
|
||||
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
constants.DEVICE_OWNER_DISTRIBUTED}))
|
||||
return next(iter(cmd.execute(check_error=True)), None)
|
||||
|
||||
def set_chassis_neutron_description(self, chassis, description,
|
||||
|
@ -379,8 +379,9 @@ class OVNClient(object):
|
||||
cidrs += ' {}/{}'.format(ip['ip_address'],
|
||||
subnet['cidr'].split('/')[1])
|
||||
|
||||
# Metadata port.
|
||||
if utils.is_ovn_metadata_port(port):
|
||||
# Metadata or OVN LB HM port.
|
||||
if (utils.is_ovn_metadata_port(port) or
|
||||
utils.is_ovn_lb_hm_port(port)):
|
||||
port_type = ovn_const.LSP_TYPE_LOCALPORT
|
||||
|
||||
if utils.is_port_external(port):
|
||||
|
@ -16,6 +16,7 @@
|
||||
import re
|
||||
from unittest import mock
|
||||
|
||||
from neutron_lib import constants
|
||||
from oslo_config import fixture as fixture_config
|
||||
from oslo_utils import uuidutils
|
||||
from ovsdbapp.backend.ovs_idl import event
|
||||
@ -154,7 +155,9 @@ class TestMetadataAgent(base.TestOVNFunctionalBase):
|
||||
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_DEVID_EXT_ID_KEY: 'ovnmeta-' + lswitch_name
|
||||
ovn_const.OVN_DEVID_EXT_ID_KEY: 'ovnmeta-' + lswitch_name,
|
||||
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
constants.DEVICE_OWNER_DISTRIBUTED
|
||||
}))
|
||||
|
||||
def _update_metadata_port_ip(self, metadata_port_name):
|
||||
|
@ -15,6 +15,7 @@
|
||||
import copy
|
||||
import uuid
|
||||
|
||||
from neutron_lib import constants
|
||||
from oslo_utils import uuidutils
|
||||
from ovsdbapp.backend.ovs_idl import connection
|
||||
from ovsdbapp import constants as const
|
||||
@ -104,34 +105,62 @@ class TestSbApi(BaseOvnIdlTest):
|
||||
self.load_test_data()
|
||||
self.assertRaises(ValueError, self.api.get_chassis_and_physnets)
|
||||
|
||||
def _add_switch_port(self, chassis_name,
|
||||
type=ovn_const.LSP_TYPE_LOCALPORT):
|
||||
sname, pname = (utils.get_rand_device_name(prefix=p)
|
||||
for p in ('switch', 'port'))
|
||||
def _add_switch(self, chassis_name):
|
||||
sname = utils.get_rand_device_name(prefix='switch')
|
||||
chassis = self.api.lookup('Chassis', chassis_name)
|
||||
with self.nbapi.transaction(check_error=True) as txn:
|
||||
switch = txn.add(self.nbapi.ls_add(sname))
|
||||
return chassis, switch.result
|
||||
|
||||
def _add_port_to_switch(
|
||||
self, switch, type=ovn_const.LSP_TYPE_LOCALPORT,
|
||||
device_owner=constants.DEVICE_OWNER_DISTRIBUTED):
|
||||
pname = utils.get_rand_device_name(prefix='port')
|
||||
row_event = events.WaitForCreatePortBindingEvent(pname)
|
||||
self.handler.watch_event(row_event)
|
||||
with self.nbapi.transaction(check_error=True) as txn:
|
||||
switch = txn.add(self.nbapi.ls_add(sname))
|
||||
port = txn.add(self.nbapi.lsp_add(sname, pname, type=type))
|
||||
port = txn.add(self.nbapi.lsp_add(
|
||||
switch.uuid, pname, type=type,
|
||||
external_ids={
|
||||
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: device_owner}))
|
||||
row_event.wait()
|
||||
return chassis, switch.result, port.result, row_event.row
|
||||
return port.result, row_event.row
|
||||
|
||||
def test_get_metadata_port_network(self):
|
||||
chassis, switch, port, binding = self._add_switch_port(
|
||||
self.data['chassis'][0]['name'])
|
||||
chassis, switch = self._add_switch(self.data['chassis'][0]['name'])
|
||||
port, binding = self._add_port_to_switch(switch)
|
||||
result = self.api.get_metadata_port_network(str(binding.datapath.uuid))
|
||||
self.assertEqual(binding, result)
|
||||
self.assertEqual(binding.datapath.external_ids['logical-switch'],
|
||||
str(switch.uuid))
|
||||
self.assertEqual(
|
||||
port.external_ids[ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY],
|
||||
constants.DEVICE_OWNER_DISTRIBUTED)
|
||||
|
||||
def test_get_metadata_port_network_other_non_metadata_port(self):
|
||||
chassis, switch = self._add_switch(self.data['chassis'][0]['name'])
|
||||
port, binding = self._add_port_to_switch(switch)
|
||||
port_lbhm, binding_port_lbhm = self._add_port_to_switch(
|
||||
switch, device_owner=ovn_const.OVN_LB_HM_PORT_DISTRIBUTED)
|
||||
result = self.api.get_metadata_port_network(str(binding.datapath.uuid))
|
||||
self.assertEqual(binding, result)
|
||||
self.assertEqual(binding.datapath.external_ids['logical-switch'],
|
||||
str(switch.uuid))
|
||||
self.assertEqual(
|
||||
binding_port_lbhm.datapath.external_ids['logical-switch'],
|
||||
str(switch.uuid))
|
||||
self.assertEqual(
|
||||
port_lbhm.external_ids[ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY],
|
||||
ovn_const.OVN_LB_HM_PORT_DISTRIBUTED)
|
||||
|
||||
def test_get_metadata_port_network_missing(self):
|
||||
val = str(uuid.uuid4())
|
||||
self.assertIsNone(self.api.get_metadata_port_network(val))
|
||||
|
||||
def _create_bound_port_with_ip(self):
|
||||
chassis, switch, port, binding = self._add_switch_port(
|
||||
chassis, switch = self._add_switch(
|
||||
self.data['chassis'][0]['name'])
|
||||
port, binding = self._add_port_to_switch(switch)
|
||||
mac = 'de:ad:be:ef:4d:ad'
|
||||
ipaddr = '192.0.2.1'
|
||||
mac_ip = '%s %s' % (mac, ipaddr)
|
||||
@ -165,8 +194,9 @@ class TestSbApi(BaseOvnIdlTest):
|
||||
self.assertEqual(1, len(result))
|
||||
|
||||
def test_get_ports_on_chassis(self):
|
||||
chassis, switch, port, binding = self._add_switch_port(
|
||||
chassis, switch = self._add_switch(
|
||||
self.data['chassis'][0]['name'])
|
||||
port, binding = self._add_port_to_switch(switch)
|
||||
self.api.lsp_bind(port.name, chassis.name).execute(check_error=True)
|
||||
self.assertEqual([binding],
|
||||
self.api.get_ports_on_chassis(chassis.name))
|
||||
|
@ -217,6 +217,21 @@ class TestUtils(base.BaseTestCase):
|
||||
self.assertFalse(utils.is_ovn_metadata_port(non_meta_port_0))
|
||||
self.assertFalse(utils.is_ovn_metadata_port(non_meta_port_1))
|
||||
|
||||
def test_is_ovn_lb_hm_port(self):
|
||||
ovn_lb_hm_port = {
|
||||
'device_owner': constants.OVN_LB_HM_PORT_DISTRIBUTED,
|
||||
'device_id': 'ovn-lb-hm-12345'}
|
||||
non_ovn_lb_hm_port_0 = {
|
||||
'device_owner': n_const.DEVICE_OWNER_DISTRIBUTED,
|
||||
'device_id': 'ovnmeta-12345'}
|
||||
non_ovn_lb_hm_port_1 = {
|
||||
'device_owner': n_const.DEVICE_OWNER_DHCP,
|
||||
'device_id': 'dhcp-12345'}
|
||||
|
||||
self.assertTrue(utils.is_ovn_lb_hm_port(ovn_lb_hm_port))
|
||||
self.assertFalse(utils.is_ovn_lb_hm_port(non_ovn_lb_hm_port_0))
|
||||
self.assertFalse(utils.is_ovn_lb_hm_port(non_ovn_lb_hm_port_1))
|
||||
|
||||
|
||||
class TestGateWayChassisValidity(base.BaseTestCase):
|
||||
|
||||
|
@ -1913,6 +1913,22 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
|
||||
self.assertEqual("address_scope_v4", options.address4_scope_id)
|
||||
self.assertEqual("address_scope_v6", options.address6_scope_id)
|
||||
|
||||
def test__get_port_options_with_ovn_lb_hm_port(self):
|
||||
port = {
|
||||
'id': 'ovn-lb-hm-port',
|
||||
'mac_address': '00:00:00:00:00:00',
|
||||
'device_owner': ovn_const.OVN_LB_HM_PORT_DISTRIBUTED,
|
||||
'device_id': 'ovn-lb-hm-foo',
|
||||
'network_id': 'foo',
|
||||
'fixed_ips': [],
|
||||
portbindings.HOST_ID: 'fake-src',
|
||||
portbindings.PROFILE: {
|
||||
ovn_const.MIGRATING_ATTR: 'fake-dest',
|
||||
}
|
||||
}
|
||||
options = self.mech_driver._ovn_client._get_port_options(port)
|
||||
self.assertEqual('fake-src', options.options['requested-chassis'])
|
||||
|
||||
def test__get_port_options_migrating_additional_chassis_missing(self):
|
||||
port = {
|
||||
'id': 'virt-port',
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
other:
|
||||
- |
|
||||
The new value for 'device_owner' for OVN loadbalancer health monitor ports
|
||||
(ovn-lb-hm:distributed) is now supported by Neutron, providing a LOCALPORT
|
||||
behavior to these ports. The responsibility to define these ports with the
|
||||
new value instead of the old one (network:distributed) is under the
|
||||
OVN-Octavia Provider driver, which will take care of database conversion
|
||||
for these ports.
|
Loading…
Reference in New Issue
Block a user