Merge "[OVN] Identify the LR GW port with "external_ids:neutron:is_ext_gw""
This commit is contained in:
commit
44159ca659
@ -19,6 +19,7 @@ from neutron_lib import constants
|
|||||||
from neutron_lib import exceptions as n_exc
|
from neutron_lib import exceptions as n_exc
|
||||||
from neutron_lib.utils import helpers
|
from neutron_lib.utils import helpers
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
from oslo_utils import strutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from ovs import socket_util
|
from ovs import socket_util
|
||||||
from ovs import stream
|
from ovs import stream
|
||||||
@ -775,18 +776,17 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
|
|||||||
return result[0] if result else None
|
return result[0] if result else None
|
||||||
|
|
||||||
def get_lrouter_gw_ports(self, lrouter_name):
|
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)
|
lr = self.get_lrouter(lrouter_name)
|
||||||
gw_ports = []
|
gw_ports = []
|
||||||
for lrp in getattr(lr, 'ports', []):
|
for lrp in getattr(lr, 'ports', []):
|
||||||
lrp_ext_ids = getattr(lrp, 'external_ids', {})
|
lrp_ext_ids = getattr(lrp, 'external_ids', {})
|
||||||
if (ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY not in lrp_ext_ids or
|
if (r_name not in lrp_ext_ids or
|
||||||
utils.ovn_name(lrp_ext_ids[
|
utils.ovn_name(lrp_ext_ids[r_name]) != lr.name or
|
||||||
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY]) != lr.name):
|
not strutils.bool_from_string(lrp_ext_ids.get(is_gw))):
|
||||||
continue
|
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
|
return gw_ports
|
||||||
|
|
||||||
|
@ -1269,17 +1269,12 @@ class TestAgentApi(base.TestOVNFunctionalBase):
|
|||||||
self.context, metadata_id)
|
self.context, metadata_id)
|
||||||
|
|
||||||
|
|
||||||
class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
|
class _TestRouter(base.TestOVNFunctionalBase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self, **kwargs):
|
||||||
super().setUp()
|
super().setUp(**kwargs)
|
||||||
self._ovn_client = self.mech_driver._ovn_client
|
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):
|
def _create_router(self, name, external_gateway_info=None):
|
||||||
data = {'router': {'name': name, 'tenant_id': self._tenant_id,
|
data = {'router': {'name': name, 'tenant_id': self._tenant_id,
|
||||||
'external_gateway_info': external_gateway_info}}
|
'external_gateway_info': external_gateway_info}}
|
||||||
@ -1289,6 +1284,20 @@ class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
|
|||||||
res = req.get_response(self.api)
|
res = req.get_response(self.api)
|
||||||
return self.deserialize(self.fmt, res)['router']
|
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):
|
def _process_router_interface(self, action, router_id, subnet_id):
|
||||||
req = self.new_action_request(
|
req = self.new_action_request(
|
||||||
'routers', {'subnet_id': subnet_id}, router_id,
|
'routers', {'subnet_id': subnet_id}, router_id,
|
||||||
@ -1369,3 +1378,42 @@ class TestNATRuleGatewayPort(base.TestOVNFunctionalBase):
|
|||||||
self.assertNotEqual([], fip_rule['gateway_port'])
|
self.assertNotEqual([], fip_rule['gateway_port'])
|
||||||
else:
|
else:
|
||||||
self.assertNotIn('gateway_port', fip_rule)
|
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)
|
||||||
|
@ -168,18 +168,18 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||||||
'lr-name-f'}}],
|
'lr-name-f'}}],
|
||||||
'lrouter_ports': [
|
'lrouter_ports': [
|
||||||
{'name': utils.ovn_lrouter_port_name('orp-id-a1'),
|
{'name': utils.ovn_lrouter_port_name('orp-id-a1'),
|
||||||
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
|
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
|
||||||
'lr-id-a'},
|
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
|
||||||
'networks': ['10.0.1.0/24'],
|
'networks': ['10.0.1.0/24'],
|
||||||
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
|
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
|
||||||
{'name': utils.ovn_lrouter_port_name('orp-id-a2'),
|
{'name': utils.ovn_lrouter_port_name('orp-id-a2'),
|
||||||
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
|
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
|
||||||
'lr-id-a'},
|
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
|
||||||
'networks': ['10.0.2.0/24'],
|
'networks': ['10.0.2.0/24'],
|
||||||
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
|
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY: 'host-1'}},
|
||||||
{'name': utils.ovn_lrouter_port_name('orp-id-a3'),
|
{'name': utils.ovn_lrouter_port_name('orp-id-a3'),
|
||||||
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
|
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-a',
|
||||||
'lr-id-a'},
|
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
|
||||||
'networks': ['10.0.3.0/24'],
|
'networks': ['10.0.3.0/24'],
|
||||||
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY:
|
'options': {ovn_const.OVN_GATEWAY_CHASSIS_KEY:
|
||||||
ovn_const.OVN_GATEWAY_INVALID_CHASSIS}},
|
ovn_const.OVN_GATEWAY_INVALID_CHASSIS}},
|
||||||
@ -192,8 +192,8 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||||||
'external_ids': {}, 'networks': ['20.0.3.0/24'],
|
'external_ids': {}, 'networks': ['20.0.3.0/24'],
|
||||||
'options': {}},
|
'options': {}},
|
||||||
{'name': utils.ovn_lrouter_port_name('gwc'),
|
{'name': utils.ovn_lrouter_port_name('gwc'),
|
||||||
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY:
|
'external_ids': {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'lr-id-f',
|
||||||
'lr-id-f'},
|
ovn_const.OVN_ROUTER_IS_EXT_GW: str(True)},
|
||||||
'networks': ['10.0.4.0/24'],
|
'networks': ['10.0.4.0/24'],
|
||||||
'options': {}}],
|
'options': {}}],
|
||||||
'gateway_chassis': [
|
'gateway_chassis': [
|
||||||
|
Loading…
Reference in New Issue
Block a user