Merge "[OVN] Identify the LR GW port with "external_ids:neutron:is_ext_gw""

This commit is contained in:
Zuul 2024-03-01 07:53:15 +00:00 committed by Gerrit Code Review
commit 44159ca659
3 changed files with 72 additions and 24 deletions

View File

@ -19,6 +19,7 @@ from neutron_lib import constants
from neutron_lib import exceptions as n_exc
from neutron_lib.utils import helpers
from oslo_log import log
from oslo_utils import strutils
from oslo_utils import uuidutils
from ovs import socket_util
from ovs import stream
@ -775,19 +776,18 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
return result[0] if result else None
def get_lrouter_gw_ports(self, lrouter_name):
r_name = ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY
is_gw = ovn_const.OVN_ROUTER_IS_EXT_GW
lr = self.get_lrouter(lrouter_name)
gw_ports = []
for lrp in getattr(lr, 'ports', []):
lrp_ext_ids = getattr(lrp, 'external_ids', {})
if (ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY not in lrp_ext_ids or
utils.ovn_name(lrp_ext_ids[
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY]) != lr.name):
if (r_name not in lrp_ext_ids or
utils.ovn_name(lrp_ext_ids[r_name]) != lr.name or
not strutils.bool_from_string(lrp_ext_ids.get(is_gw))):
continue
lrp_ha_cfg = (getattr(lrp, 'gateway_chassis', None) or
getattr(lrp, 'options', {}).get(
ovn_const.OVN_GATEWAY_CHASSIS_KEY))
if lrp_ha_cfg:
gw_ports.append(lrp)
gw_ports.append(lrp)
return gw_ports
def get_lrouter_by_lrouter_port(self, lrp_name):

View File

@ -1269,17 +1269,12 @@ class TestAgentApi(base.TestOVNFunctionalBase):
self.context, metadata_id)
class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
class _TestRouter(base.TestOVNFunctionalBase):
def setUp(self):
super().setUp()
def setUp(self, **kwargs):
super().setUp(**kwargs)
self._ovn_client = self.mech_driver._ovn_client
def deserialize(self, content_type, response):
ctype = 'application/%s' % content_type
data = self._deserializers[ctype].deserialize(response.body)['body']
return data
def _create_router(self, name, external_gateway_info=None):
data = {'router': {'name': name, 'tenant_id': self._tenant_id,
'external_gateway_info': external_gateway_info}}
@ -1289,6 +1284,20 @@ class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
res = req.get_response(self.api)
return self.deserialize(self.fmt, res)['router']
def _update_router(self, router_id, router_dict):
data = {'router': router_dict}
req = self.new_update_request('routers', data, router_id, self.fmt)
res = req.get_response(self.api)
return self.deserialize(self.fmt, res)['router']
class TestNATRuleGatewayPort(_TestRouter):
def deserialize(self, content_type, response):
ctype = 'application/%s' % content_type
data = self._deserializers[ctype].deserialize(response.body)['body']
return data
def _process_router_interface(self, action, router_id, subnet_id):
req = self.new_action_request(
'routers', {'subnet_id': subnet_id}, router_id,
@ -1369,3 +1378,42 @@ class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
self.assertNotEqual([], fip_rule['gateway_port'])
else:
self.assertNotIn('gateway_port', fip_rule)
class TestRouterGWPort(_TestRouter):
def test_create_and_delete_router_gw_port(self):
ext_net = self._make_network(
self.fmt, 'ext_networktest', True, as_admin=True,
arg_list=('router:external',
'provider:network_type',
'provider:physical_network'),
**{'router:external': True,
'provider:network_type': 'flat',
'provider:physical_network': 'public'})['network']
res = self._create_subnet(self.fmt, ext_net['id'], '100.0.0.0/24')
ext_subnet = self.deserialize(self.fmt, res)['subnet']
external_gateway_info = {
'enable_snat': True,
'network_id': ext_net['id'],
'external_fixed_ips': [
{'ip_address': '100.0.0.2', 'subnet_id': ext_subnet['id']}]}
router = self._create_router(
uuidutils.generate_uuid(),
external_gateway_info=external_gateway_info)
# Check GW LRP.
lr = self._ovn_client._nb_idl.lookup('Logical_Router',
utils.ovn_name(router['id']))
for lrp in lr.ports:
if lrp.external_ids[ovn_const.OVN_ROUTER_IS_EXT_GW] == str(True):
break
else:
self.fail('Logical Router %s does not have a gateway port' %
utils.ovn_name(router['id']))
# Remove LR GW port and check.
self._update_router(router['id'], {'external_gateway_info': {}})
lr = self._ovn_client._nb_idl.lookup('Logical_Router',
utils.ovn_name(router['id']))
self.assertEqual([], lr.ports)

View File

@ -168,18 +168,18 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
'lr-name-f'}}],
'lrouter_ports': [
{'name': utils.ovn_lrouter_port_name('orp-id-a1'),
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
'lr-id-a'},
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
'networks': ['10.0.1.0/24'],
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
{'name': utils.ovn_lrouter_port_name('orp-id-a2'),
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
'lr-id-a'},
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
'networks': ['10.0.2.0/24'],
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
{'name': utils.ovn_lrouter_port_name('orp-id-a3'),
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
'lr-id-a'},
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
'networks': ['10.0.3.0/24'],
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY:
ovn_const.OVN_GATEWAY_INVALID_CHASSIS}},
@ -192,8 +192,8 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
'external_ids': {}, 'networks': ['20.0.3.0/24'],
'options': {}},
{'name': utils.ovn_lrouter_port_name('gwc'),
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
'lr-id-f'},
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-f',
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
'networks': ['10.0.4.0/24'],
'options': {}}],
'gateway_chassis': [