Improve Router callback system's publish events
When I writing 'ndp_proxy' service plugin, I found I couldn't get enough informations about router from the callback system (Such as: the origin request body of user send). So, for write service plugin that related router plugin more concisely I commit this patch. This patch proposal two changes about router callback publish events: 1. Add 'request_body' parameter to some event's payload 2. add 'BEFORE_UPDATE' event for router gateway Related-bug: #1877301 Change-Id: I5f6a4e6f0b7c5feb794ddb7efbd07d01bad91af8
This commit is contained in:
parent
8123cc6ee3
commit
e4c168b1fc
@ -47,6 +47,7 @@ from neutron.common import ipv6_utils
|
||||
from neutron.common import utils
|
||||
from neutron.db import _utils as db_utils
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db.models import l3_attrs as l3_attrs_models
|
||||
from neutron.db import models_v2
|
||||
from neutron.db import standardattrdescription_db as st_attr
|
||||
from neutron.extensions import l3
|
||||
@ -254,26 +255,36 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
states=(router,)))
|
||||
return router_db
|
||||
|
||||
def _update_gw_for_create_router(self, context, gw_info, router_id):
|
||||
def _update_gw_for_create_router(self, context, gw_info,
|
||||
request_body, router_id):
|
||||
if gw_info:
|
||||
with db_utils.context_if_transaction(
|
||||
context, not context.session.is_active, writer=False):
|
||||
router_db = self._get_router(context, router_id)
|
||||
self._update_router_gw_info(context, router_id,
|
||||
gw_info, router=router_db)
|
||||
gw_info, request_body,
|
||||
router=router_db)
|
||||
|
||||
return self._get_router(context, router_id), None
|
||||
return None, None
|
||||
|
||||
def _get_stripped_router(self, router_body):
|
||||
stripped_router = {}
|
||||
for key in router_body:
|
||||
if getattr(l3_models.Router, key, None) or getattr(
|
||||
l3_attrs_models.RouterExtraAttributes, key, None):
|
||||
stripped_router[key] = router_body[key]
|
||||
return stripped_router
|
||||
|
||||
@db_api.retry_if_session_inactive()
|
||||
def create_router(self, context, router):
|
||||
r = router['router']
|
||||
gw_info = r.pop(EXTERNAL_GW_INFO, None)
|
||||
gw_info = r.get(EXTERNAL_GW_INFO, None)
|
||||
create = functools.partial(self._create_router_db, context, r,
|
||||
r['tenant_id'])
|
||||
delete = functools.partial(self.delete_router, context)
|
||||
update_gw = functools.partial(self._update_gw_for_create_router,
|
||||
context, gw_info)
|
||||
context, gw_info, r)
|
||||
router_db, _unused = db_utils.safe_creation(context, create,
|
||||
delete, update_gw,
|
||||
transaction=False)
|
||||
@ -294,7 +305,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
router_db = self._get_router(context, router_id)
|
||||
old_router = self._make_router_dict(router_db)
|
||||
if data:
|
||||
router_db.update(data)
|
||||
router_db.update(self._get_stripped_router(data))
|
||||
registry.publish(resources.ROUTER, events.PRECOMMIT_UPDATE, self,
|
||||
payload=events.DBEventPayload(
|
||||
context, request_body=data,
|
||||
@ -305,10 +316,10 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
@db_api.retry_if_session_inactive()
|
||||
def update_router(self, context, id, router):
|
||||
r = router['router']
|
||||
gw_info = r.pop(EXTERNAL_GW_INFO, constants.ATTR_NOT_SPECIFIED)
|
||||
gw_info = r.get(EXTERNAL_GW_INFO, constants.ATTR_NOT_SPECIFIED)
|
||||
original = self.get_router(context, id)
|
||||
if gw_info != constants.ATTR_NOT_SPECIFIED:
|
||||
self._update_router_gw_info(context, id, gw_info)
|
||||
self._update_router_gw_info(context, id, gw_info, r)
|
||||
router_db = self._update_router_db(context, id, r)
|
||||
updated = self._make_router_dict(router_db)
|
||||
|
||||
@ -409,7 +420,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
{'router_id': [router_id]}))
|
||||
|
||||
def _delete_current_gw_port(self, context, router_id, router,
|
||||
new_network_id):
|
||||
new_network_id, request_body=None):
|
||||
"""Delete gw port if attached to an old network."""
|
||||
port_requires_deletion = (
|
||||
router.gw_port and router.gw_port['network_id'] != new_network_id)
|
||||
@ -423,7 +434,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
router_id=router_id, net_id=router.gw_port['network_id'])
|
||||
gw_ips = [x['ip_address'] for x in router.gw_port['fixed_ips']]
|
||||
gw_port_id = router.gw_port['id']
|
||||
self._delete_router_gw_port_db(context, router)
|
||||
self._delete_router_gw_port_db(context, router, request_body)
|
||||
if admin_ctx.session.is_active:
|
||||
# TODO(ralonsoh): ML2 plugin "delete_port" should be called outside
|
||||
# a DB transaction. In this case an exception is made but in order
|
||||
@ -443,7 +454,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
metadata=metadata,
|
||||
resource_id=router_id))
|
||||
|
||||
def _delete_router_gw_port_db(self, context, router):
|
||||
def _delete_router_gw_port_db(self, context, router, request_body):
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
router.gw_port = None
|
||||
if router not in context.session:
|
||||
@ -453,6 +464,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
events.BEFORE_DELETE, self,
|
||||
payload=events.DBEventPayload(
|
||||
context, states=(router,),
|
||||
request_body=request_body,
|
||||
resource_id=router.id))
|
||||
except exceptions.CallbackFailure as e:
|
||||
# NOTE(armax): preserve old check's behavior
|
||||
@ -475,7 +487,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
registry.publish(
|
||||
resources.ROUTER_GATEWAY, events.BEFORE_CREATE, self,
|
||||
payload=events.DBEventPayload(
|
||||
context, request_body=router,
|
||||
context,
|
||||
metadata={
|
||||
'network_id': new_network_id,
|
||||
'subnets': subnets},
|
||||
@ -503,11 +515,17 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
'network_id': new_network_id},
|
||||
resource_id=router_id))
|
||||
|
||||
def _update_current_gw_port(self, context, router_id, router, ext_ips):
|
||||
def _update_current_gw_port(self, context, router_id, router,
|
||||
ext_ips, request_body):
|
||||
registry.publish(resources.ROUTER_GATEWAY, events.BEFORE_UPDATE, self,
|
||||
payload=events.DBEventPayload(
|
||||
context, request_body=request_body,
|
||||
states=(router,)))
|
||||
self._core_plugin.update_port(context.elevated(), router.gw_port['id'],
|
||||
{'port': {'fixed_ips': ext_ips}})
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info, router=None):
|
||||
def _update_router_gw_info(self, context, router_id, info,
|
||||
request_body, router=None):
|
||||
router = router or self._get_router(context, router_id)
|
||||
gw_port = router.gw_port
|
||||
ext_ips = info.get('external_fixed_ips', []) if info else []
|
||||
@ -516,10 +534,10 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||
network_id = self._validate_gw_info(context, info, ext_ips, router)
|
||||
if gw_port and ext_ip_change and gw_port['network_id'] == network_id:
|
||||
self._update_current_gw_port(context, router_id, router,
|
||||
ext_ips)
|
||||
ext_ips, request_body)
|
||||
else:
|
||||
self._delete_current_gw_port(context, router_id, router,
|
||||
network_id)
|
||||
network_id, request_body)
|
||||
self._create_gw_port(context, router_id, router, network_id,
|
||||
ext_ips)
|
||||
|
||||
|
@ -60,11 +60,12 @@ class L3_gw_ip_qos_dbonly_mixin(l3_gwmode_db.L3_NAT_dbonly_mixin):
|
||||
policy = policy_object.QosPolicy.get_policy_obj(context, policy_id)
|
||||
policy.detach_router(router_id)
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info, router=None):
|
||||
def _update_router_gw_info(self, context, router_id, info,
|
||||
request_body, router=None):
|
||||
# Calls superclass, pass router db object for avoiding re-loading
|
||||
router = super(L3_gw_ip_qos_dbonly_mixin,
|
||||
self)._update_router_gw_info(
|
||||
context, router_id, info, router)
|
||||
context, router_id, info, request_body, router)
|
||||
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
if self._is_gw_ip_qos_supported and router.gw_port:
|
||||
|
@ -56,24 +56,23 @@ class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
|
||||
]
|
||||
})
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info, router=None):
|
||||
def _update_router_gw_info(self, context, router_id, info,
|
||||
request_body, router=None):
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
# Always load the router inside the DB context.
|
||||
router = self._get_router(context, router_id)
|
||||
old_router = self._make_router_dict(router)
|
||||
router.enable_snat = self._get_enable_snat(info)
|
||||
router_body = {l3_apidef.ROUTER:
|
||||
{l3_apidef.EXTERNAL_GW_INFO: info}}
|
||||
registry.publish(resources.ROUTER_GATEWAY,
|
||||
events.PRECOMMIT_UPDATE, self,
|
||||
payload=events.DBEventPayload(
|
||||
context, request_body=router_body,
|
||||
context, request_body=request_body,
|
||||
states=(old_router,), resource_id=router_id,
|
||||
desired_state=router))
|
||||
|
||||
# Calls superclass, pass router db object for avoiding re-loading
|
||||
super(L3_NAT_dbonly_mixin, self)._update_router_gw_info(
|
||||
context, router_id, info, router=router)
|
||||
context, router_id, info, request_body, router=router)
|
||||
# Returning the router might come back useful if this
|
||||
# method is overridden in child classes
|
||||
return self._get_router(context, router_id)
|
||||
|
@ -119,9 +119,13 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
ext_net_id = ext_net['network']['id']
|
||||
net1_id = net1['network']['id']
|
||||
# Set gateway to router
|
||||
|
||||
gw_info = {'network_id': ext_net_id}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router1['id'],
|
||||
{'network_id': ext_net_id})
|
||||
gw_info, request_body)
|
||||
# Now add router interface (subnet1) from net1 to router
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router1['id'],
|
||||
@ -292,18 +296,24 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.context, router1['id'],
|
||||
{'subnet_id': subnet1['subnet']['id']})
|
||||
# Set gateway to first router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router1['id'],
|
||||
{'network_id': ext_net_id})
|
||||
gw_info, request_body)
|
||||
# Create second router and add an interface
|
||||
router2 = self._create_router()
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router2['id'],
|
||||
{'subnet_id': subnet2['subnet']['id']})
|
||||
# Set gateway to second router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router2['id'],
|
||||
{'network_id': ext_net_id})
|
||||
gw_info, request_body)
|
||||
# Create an agent gateway port for the external network
|
||||
net_id, agent_gw_port = (
|
||||
self.setup_create_agent_gw_port_for_network(network=ext_net))
|
||||
@ -312,13 +322,15 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.l3_plugin._get_agent_gw_ports_exist_for_network(
|
||||
self.context, ext_net_id, "", self.l3_agent['id']))
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router1['id'], {})
|
||||
self.context, router1['id'], {},
|
||||
{l3_apidef.EXTERNAL_GW_INFO: {}})
|
||||
# Check for agent gateway port after deleting one of the gw
|
||||
self.assertIsNotNone(
|
||||
self.l3_plugin._get_agent_gw_ports_exist_for_network(
|
||||
self.context, ext_net_id, "", self.l3_agent['id']))
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router2['id'], {})
|
||||
self.context, router2['id'], {},
|
||||
{l3_apidef.EXTERNAL_GW_INFO: {}})
|
||||
# Check for agent gateway port after deleting last gw
|
||||
self.assertIsNone(
|
||||
self.l3_plugin._get_agent_gw_ports_exist_for_network(
|
||||
@ -631,9 +643,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.fmt, ext_net, '2001:db8::1', '2001:db8::/64',
|
||||
ip_version=constants.IP_VERSION_6, enable_dhcp=True)
|
||||
router1 = self._create_router()
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router1['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
snat_router_intfs = self.l3_plugin._get_snat_sync_interfaces(
|
||||
self.context, [router1['id']])
|
||||
self.assertEqual(0, len(snat_router_intfs[router1['id']]))
|
||||
@ -703,9 +718,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
candidates=[self.l3_agent])
|
||||
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -811,9 +829,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
candidates=[self.l3_agent])
|
||||
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -891,9 +912,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
candidates=[self.l3_agent])
|
||||
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -966,9 +990,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
candidates=[self.l3_agent])
|
||||
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -1048,9 +1075,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
candidates=[self.l3_agent])
|
||||
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -1177,9 +1207,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
router['id'],
|
||||
candidates=[self.l3_agent])
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -1217,9 +1250,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
router['id'],
|
||||
candidates=[self.l3_agent])
|
||||
# Set gateway to router
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
private_subnet1 = self._make_subnet(
|
||||
self.fmt,
|
||||
private_net1,
|
||||
@ -1349,9 +1385,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.subnet(network=ext_net),\
|
||||
self.subnet(cidr='20.0.0.0/24') as subnet,\
|
||||
self.port(subnet=subnet):
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': subnet['subnet']['id']})
|
||||
@ -1380,9 +1419,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.core_plugin.update_port(
|
||||
self.context, port['port']['id'],
|
||||
{'port': {'binding:host_id': self.l3_agent['host']}})
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': subnet['subnet']['id']})
|
||||
@ -1620,9 +1662,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
with self.subnet() as subnet,\
|
||||
self.network(**kwargs) as ext_net,\
|
||||
self.subnet(network=ext_net, cidr='20.0.0.0/24'):
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': subnet['subnet']['id']})
|
||||
@ -1655,9 +1700,12 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
||||
self.core_plugin.update_port(
|
||||
self.context, port['port']['id'],
|
||||
{'port': {'binding:host_id': self.l3_agent['host']}})
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': subnet['subnet']['id']})
|
||||
@ -2036,9 +2084,12 @@ class L3DvrTestCaseMigration(L3DvrTestCaseBase):
|
||||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': subnet1['subnet']['id']})
|
||||
gw_info = {'network_id': ext_net['network']['id']}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.l3_plugin._update_router_gw_info(
|
||||
self.context, router['id'],
|
||||
{'network_id': ext_net['network']['id']})
|
||||
gw_info, request_body)
|
||||
self.assertEqual(
|
||||
0, len(self.l3_plugin._get_snat_sync_interfaces(
|
||||
self.context, [router['id']])))
|
||||
|
@ -17,6 +17,8 @@ from unittest import mock
|
||||
|
||||
import ddt
|
||||
import netaddr
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||
from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
from neutron_lib.callbacks import resources
|
||||
@ -30,6 +32,7 @@ from neutron_lib.plugins import directory
|
||||
from neutron_lib.plugins import utils as plugin_utils
|
||||
from oslo_utils import uuidutils
|
||||
import testtools
|
||||
import webob.exc
|
||||
|
||||
from neutron.db import extraroute_db
|
||||
from neutron.db import l3_db
|
||||
@ -606,6 +609,10 @@ class L3TestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
||||
self.ctx, network_id=self.network['network']['id'])
|
||||
network_obj.Network.get_object(
|
||||
self.ctx, id=self.network['network']['id']).delete()
|
||||
router_ports = l3_obj.RouterPort.get_objects(
|
||||
self.ctx, **{'router_id': self.router['id']})
|
||||
for router_port in router_ports:
|
||||
router_port.delete()
|
||||
l3_obj.Router.get_object(self.ctx, id=self.router['id']).delete()
|
||||
|
||||
def create_router(self, router):
|
||||
@ -708,3 +715,104 @@ class L3TestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
||||
mock_log.warning.assert_called_once_with(self.GET_PORTS_BY_ROUTER_MSG,
|
||||
msg_vars)
|
||||
self._check_routerports((False, True))
|
||||
|
||||
def test_create_router_notify(self):
|
||||
with mock.patch.object(l3_db.registry, 'publish') as mock_publish:
|
||||
router = {'router': {'name': 'foo_router',
|
||||
'admin_state_up': True,
|
||||
'tenant_id': 'foo_tenant'}}
|
||||
self.create_router(router)
|
||||
expected_calls = [
|
||||
mock.call(resources.ROUTER, events.BEFORE_CREATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.PRECOMMIT_CREATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.AFTER_CREATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
]
|
||||
mock_publish.assert_has_calls(expected_calls)
|
||||
|
||||
def test_update_router_notify(self):
|
||||
with mock.patch.object(l3_db.registry, 'publish') as mock_publish:
|
||||
self.mixin.update_router(self.ctx, self.router['id'],
|
||||
{'router': {'name': 'test1'}})
|
||||
expected_calls = [
|
||||
mock.call(resources.ROUTER, events.PRECOMMIT_UPDATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.AFTER_UPDATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
]
|
||||
mock_publish.assert_has_calls(expected_calls)
|
||||
|
||||
def _create_external_network(self, name=None, **kwargs):
|
||||
name = name or 'network1'
|
||||
kwargs[extnet_apidef.EXTERNAL] = True
|
||||
with db_api.CONTEXT_WRITER.using(self.ctx):
|
||||
res = self._create_network(
|
||||
self.fmt, name, True,
|
||||
arg_list=(extnet_apidef.EXTERNAL,), **kwargs)
|
||||
if res.status_int >= webob.exc.HTTPClientError.code:
|
||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||
return self.deserialize(self.fmt, res)
|
||||
|
||||
def test_update_router_gw_notify(self):
|
||||
with mock.patch.object(l3_db.registry, 'publish') as mock_publish:
|
||||
ext_net = self._create_external_network()
|
||||
self.create_subnet(ext_net, '1.1.2.1', '1.1.2.0/24')
|
||||
update_data = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: {
|
||||
'network_id': ext_net['network']['id']}}
|
||||
self.mixin.update_router(
|
||||
self.ctx, self.router['id'], {'router': update_data})
|
||||
expected_calls = [
|
||||
mock.call(resources.NETWORK, events.BEFORE_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.SEGMENT, events.PRECOMMIT_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.NETWORK, events.PRECOMMIT_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.NETWORK, events.AFTER_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.NETWORK, events.BEFORE_RESPONSE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.SUBNET, events.BEFORE_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.SUBNET, events.AFTER_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.SUBNET, events.BEFORE_RESPONSE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER_GATEWAY, events.BEFORE_CREATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.BEFORE_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.PRECOMMIT_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.AFTER_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER_GATEWAY, events.AFTER_CREATE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.PRECOMMIT_UPDATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.AFTER_UPDATE,
|
||||
self.mixin, payload=mock.ANY)]
|
||||
mock_publish.assert_has_calls(expected_calls)
|
||||
mock_publish.reset_mock()
|
||||
update_data = {l3_apidef.EXTERNAL_GW_INFO: {}}
|
||||
self.mixin.update_router(
|
||||
self.ctx, self.router['id'], {'router': update_data})
|
||||
expected_calls = [
|
||||
mock.call(resources.ROUTER_GATEWAY, events.BEFORE_DELETE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.BEFORE_DELETE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.PRECOMMIT_DELETE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.PORT, events.AFTER_DELETE,
|
||||
mock.ANY, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER_GATEWAY, events.AFTER_DELETE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.PRECOMMIT_UPDATE,
|
||||
self.mixin, payload=mock.ANY),
|
||||
mock.call(resources.ROUTER, events.AFTER_UPDATE,
|
||||
self.mixin, payload=mock.ANY)]
|
||||
mock_publish.assert_has_calls(expected_calls)
|
||||
|
@ -389,7 +389,7 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
||||
'_create_snat_intf_ports_if_not_exists') as cs:
|
||||
self.mixin._create_gw_port(
|
||||
self.ctx, router_id, router_db, mock.ANY,
|
||||
mock.ANY)
|
||||
mock.ANY, mock.ANY)
|
||||
self.assertFalse(cs.call_count)
|
||||
|
||||
def test_build_routers_list_with_gw_port_mismatch(self):
|
||||
|
@ -16,6 +16,7 @@ from unittest import mock
|
||||
|
||||
from neutron_lib.api.definitions import dvr as dvr_apidef
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||
from neutron_lib.api.definitions import l3_ext_ha_mode
|
||||
from neutron_lib.api.definitions import port as port_def
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
@ -1093,8 +1094,11 @@ class L3HAModeDbTestCase(L3HATestFramework):
|
||||
interface_info = {'subnet_id': subnet['id']}
|
||||
|
||||
router = self._create_router()
|
||||
gw_info = {'network_id': ext_net}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.plugin._update_router_gw_info(self.admin_ctx, router['id'],
|
||||
{'network_id': ext_net})
|
||||
gw_info, request_body)
|
||||
self.plugin.add_router_interface(self.admin_ctx,
|
||||
router['id'],
|
||||
interface_info)
|
||||
@ -1119,8 +1123,11 @@ class L3HAModeDbTestCase(L3HATestFramework):
|
||||
interface_info = {'subnet_id': subnet['id']}
|
||||
|
||||
router = self._create_router()
|
||||
gw_info = {'network_id': ext_net}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.plugin._update_router_gw_info(self.admin_ctx, router['id'],
|
||||
{'network_id': ext_net})
|
||||
gw_info, request_body)
|
||||
iface = self.plugin.add_router_interface(self.admin_ctx,
|
||||
router['id'],
|
||||
interface_info)
|
||||
@ -1177,8 +1184,11 @@ class L3HAModeDbTestCase(L3HATestFramework):
|
||||
int_net)
|
||||
interface_info = {'subnet_id': subnet['id']}
|
||||
router = self._create_router(ha=True, distributed=True)
|
||||
gw_info = {'network_id': ext_net}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.plugin._update_router_gw_info(self.admin_ctx, router['id'],
|
||||
{'network_id': ext_net})
|
||||
gw_info, request_body)
|
||||
self.plugin.add_router_interface(self.admin_ctx,
|
||||
router['id'],
|
||||
interface_info)
|
||||
@ -1310,8 +1320,11 @@ class L3HAModeDbTestCase(L3HATestFramework):
|
||||
interface_info = {'subnet_id': subnet['id']}
|
||||
|
||||
router = self._create_router()
|
||||
gw_info = {'network_id': ext_net}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.plugin._update_router_gw_info(self.admin_ctx, router['id'],
|
||||
{'network_id': ext_net})
|
||||
gw_info, request_body)
|
||||
self.plugin.add_router_interface(self.admin_ctx,
|
||||
router['id'],
|
||||
interface_info)
|
||||
|
@ -256,11 +256,15 @@ class TestL3GwModeMixin(testlib_api.SqlTestCase):
|
||||
if not current_enable_snat:
|
||||
previous_gw_info = {'network_id': self.ext_net_id,
|
||||
'enable_snat': current_enable_snat}
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: previous_gw_info}
|
||||
self.target_object._update_router_gw_info(
|
||||
self.context, self.router.id, previous_gw_info)
|
||||
self.context, self.router.id, previous_gw_info, request_body)
|
||||
|
||||
request_body = {
|
||||
l3_apidef.EXTERNAL_GW_INFO: gw_info}
|
||||
self.target_object._update_router_gw_info(
|
||||
self.context, self.router.id, gw_info)
|
||||
self.context, self.router.id, gw_info, request_body)
|
||||
router = self.target_object._get_router(
|
||||
self.context, self.router.id)
|
||||
try:
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add ``request_body`` field to router callback event payloads. The field
|
||||
record the origin request body from user.
|
||||
- |
|
||||
Add ``BEFORE_UPDATE`` callback event for router gateway.
|
Loading…
Reference in New Issue
Block a user