Fix NVP plugin to send notifications for gateway-less subnets

It was noted that an update notification should be sent
regardless; this patch addresses that. Since there is
no longer the need to distinguish on whether to send
the RPC message or not, the operation has been factored
out to avoid code duplication.

Closes-Bug: 1220881

Change-Id: If553a84b7221f8c98d758654d317217a909c43dc
This commit is contained in:
armando-migliaccio 2013-09-04 13:11:43 -07:00
parent f9e80c2c38
commit caa43768e5
3 changed files with 44 additions and 19 deletions

View File

@ -77,11 +77,7 @@ def handle_port_dhcp_access(plugin, context, port_data, action):
if active_port: if active_port:
subnet_id = port_data['fixed_ips'][0]['subnet_id'] subnet_id = port_data['fixed_ips'][0]['subnet_id']
subnet = plugin.get_subnet(context, subnet_id) subnet = plugin.get_subnet(context, subnet_id)
if (cfg.CONF.dhcp_agent_notification and subnet.get('gateway_ip') _notify_rpc_agent(context, {'subnet': subnet}, 'subnet.update.end')
or action == 'delete_port'):
dhcp_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
dhcp_notifier.notify(
context, {'subnet': subnet}, 'subnet.update.end')
def handle_port_metadata_access(context, port, is_delete=False): def handle_port_metadata_access(context, port, is_delete=False):
@ -207,12 +203,8 @@ def _create_metadata_access_network(plugin, context, router_id):
# as it will be removed with the network # as it will be removed with the network
plugin.delete_network(context, meta_net['id']) plugin.delete_network(context, meta_net['id'])
if cfg.CONF.dhcp_agent_notification: # Tell to start the metadata agent proxy
# We need to send a notification to the dhcp agent in _notify_rpc_agent(context, {'network': meta_net}, 'network.create.end')
# order to start the metadata agent proxy
dhcp_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
dhcp_notifier.notify(context, {'network': meta_net},
'network.create.end')
def _destroy_metadata_access_network(plugin, context, router_id, ports): def _destroy_metadata_access_network(plugin, context, router_id, ports):
@ -235,11 +227,12 @@ def _destroy_metadata_access_network(plugin, context, router_id, ports):
# must re-add the router interface # must re-add the router interface
plugin.add_router_interface(context, router_id, plugin.add_router_interface(context, router_id,
{'subnet_id': meta_sub_id}) {'subnet_id': meta_sub_id})
# Tell to stop the metadata agent proxy
_notify_rpc_agent(
context, {'network': {'id': meta_net_id}}, 'network.delete.end')
def _notify_rpc_agent(context, payload, event):
if cfg.CONF.dhcp_agent_notification: if cfg.CONF.dhcp_agent_notification:
# We need to send a notification to the dhcp agent in
# order to stop the metadata agent proxy
dhcp_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() dhcp_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
dhcp_notifier.notify(context, dhcp_notifier.notify(context, payload, event)
{'network': {'id': meta_net_id}},
'network.delete.end')

View File

@ -14,7 +14,9 @@
# under the License. # under the License.
import mock import mock
from oslo.config import cfg
from neutron.common import constants
from neutron.common.test_lib import test_config from neutron.common.test_lib import test_config
from neutron.plugins.nicira.common import sync from neutron.plugins.nicira.common import sync
from neutron.tests.unit.nicira import fake_nvpapiclient from neutron.tests.unit.nicira import fake_nvpapiclient
@ -50,6 +52,7 @@ class NVPDhcpAgentNotifierTestCase(test_base.OvsDhcpAgentNotifierTestCase):
self.addCleanup(self.fc.reset_all) self.addCleanup(self.fc.reset_all)
self.addCleanup(patch_sync.stop) self.addCleanup(patch_sync.stop)
self.addCleanup(self.mock_nvpapi.stop) self.addCleanup(self.mock_nvpapi.stop)
self.addCleanup(cfg.CONF.reset)
def _notification_mocks(self, hosts, mock_dhcp, net, subnet, port): def _notification_mocks(self, hosts, mock_dhcp, net, subnet, port):
host_calls = {} host_calls = {}
@ -75,3 +78,23 @@ class NVPDhcpAgentNotifierTestCase(test_base.OvsDhcpAgentNotifierTestCase):
topic='dhcp_agent.' + host)] topic='dhcp_agent.' + host)]
host_calls[host] = expected_calls host_calls[host] = expected_calls
return host_calls return host_calls
def _test_gateway_subnet_notification(self, gateway='10.0.0.1'):
cfg.CONF.set_override('metadata_mode', 'dhcp_host_route', 'NVP')
hosts = ['hosta']
[mock_dhcp, net, subnet, port] = self._network_port_create(
hosts, gateway=gateway, owner=constants.DEVICE_OWNER_DHCP)
found = False
for call, topic in mock_dhcp.call_args_list:
method = call[1]['method']
if method == 'subnet_update_end':
found = True
break
self.assertTrue(found)
self.assertEqual(subnet['subnet']['gateway_ip'], gateway)
def test_gatewayless_subnet_notification(self):
self._test_gateway_subnet_notification(gateway=None)
def test_subnet_with_gateway_notification(self):
self._test_gateway_subnet_notification()

View File

@ -1018,7 +1018,8 @@ class OvsDhcpAgentNotifierTestCase(OvsAgentSchedulerTestCaseBase):
payload={'admin_state_up': False}), payload={'admin_state_up': False}),
topic='dhcp_agent.' + DHCP_HOSTA) topic='dhcp_agent.' + DHCP_HOSTA)
def _network_port_create(self, hosts): def _network_port_create(
self, hosts, gateway=attributes.ATTR_NOT_SPECIFIED, owner=None):
for host in hosts: for host in hosts:
self._register_one_agent_state( self._register_one_agent_state(
{'binary': 'neutron-dhcp-agent', {'binary': 'neutron-dhcp-agent',
@ -1030,9 +1031,17 @@ class OvsDhcpAgentNotifierTestCase(OvsAgentSchedulerTestCaseBase):
with mock.patch.object(self.dhcp_notifier, 'cast') as mock_dhcp: with mock.patch.object(self.dhcp_notifier, 'cast') as mock_dhcp:
with self.network(do_delete=False) as net1: with self.network(do_delete=False) as net1:
with self.subnet(network=net1, with self.subnet(network=net1,
gateway_ip=gateway,
do_delete=False) as subnet1: do_delete=False) as subnet1:
with self.port(subnet=subnet1, no_delete=True) as port: if owner:
return [mock_dhcp, net1, subnet1, port] with self.port(subnet=subnet1,
no_delete=True,
device_owner=owner) as port:
return [mock_dhcp, net1, subnet1, port]
else:
with self.port(subnet=subnet1,
no_delete=True) as port:
return [mock_dhcp, net1, subnet1, port]
def _notification_mocks(self, hosts, mock_dhcp, net, subnet, port): def _notification_mocks(self, hosts, mock_dhcp, net, subnet, port):
host_calls = {} host_calls = {}