Browse Source

Merge "Schedule networks to new segments if needed" into stable/stein

changes/22/783922/1
Zuul 2 months ago
committed by Gerrit Code Review
parent
commit
c2f3c69c77
2 changed files with 71 additions and 1 deletions
  1. +28
    -1
      neutron/db/agentschedulers_db.py
  2. +43
    -0
      neutron/tests/unit/db/test_agentschedulers_db.py

+ 28
- 1
neutron/db/agentschedulers_db.py View File

@ -17,11 +17,15 @@ import datetime
import random
import time
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants
from neutron_lib import context as ncontext
from neutron_lib import exceptions as n_exc
from neutron_lib.exceptions import agent as agent_exc
from neutron_lib.exceptions import dhcpagentscheduler as das_exc
from neutron_lib.plugins import directory
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging
@ -35,6 +39,7 @@ from neutron.db import agents_db
from neutron.db.availability_zone import network as network_az
from neutron.extensions import dhcpagentscheduler
from neutron.objects import network
from neutron.objects import subnet as subnet_obj
from neutron import worker as neutron_worker
@ -221,12 +226,15 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
additional_time)
return agent_expected_up > timeutils.utcnow()
def _schedule_network(self, context, network_id, dhcp_notifier):
def _schedule_network(self, context, network_id, dhcp_notifier,
candidate_hosts=None):
LOG.info("Scheduling unhosted network %s", network_id)
try:
# TODO(enikanorov): have to issue redundant db query
# to satisfy scheduling interface
network = self.get_network(context, network_id)
if candidate_hosts:
network['candidate_hosts'] = candidate_hosts
agents = self.schedule_network(context, network)
if not agents:
LOG.info("Failed to schedule network %s, "
@ -477,6 +485,25 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
if self.network_scheduler:
self.network_scheduler.auto_schedule_networks(self, context, host)
@registry.receives(resources.SEGMENT_HOST_MAPPING, [events.AFTER_CREATE])
def auto_schedule_new_network_segments(self, resource, event, trigger,
payload=None):
if not cfg.CONF.network_auto_schedule:
return
segment_plugin = directory.get_plugin('segments')
dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP)
segment_ids = payload.metadata.get('current_segment_ids')
segments = segment_plugin.get_segments(
payload.context, filters={'id': segment_ids})
subnets = subnet_obj.Subnet.get_objects(
payload.context, segment_id=segment_ids)
network_ids = {s.network_id for s in subnets}
for network_id in network_ids:
for segment in segments:
self._schedule_network(
payload.context, network_id, dhcp_notifier,
candidate_hosts=segment['hosts'])
class AZDhcpAgentSchedulerDbMixin(DhcpAgentSchedulerDbMixin,
network_az.NetworkAvailabilityZoneMixin):


+ 43
- 0
neutron/tests/unit/db/test_agentschedulers_db.py View File

@ -18,6 +18,8 @@ import datetime
import mock
from neutron_lib.api.definitions import dhcpagentscheduler as das_apidef
from neutron_lib.api.definitions import portbindings
from neutron_lib.callbacks import events
from neutron_lib.callbacks import resources
from neutron_lib import constants
from neutron_lib import context
from neutron_lib.plugins import constants as plugin_constants
@ -1560,6 +1562,47 @@ class OvsDhcpAgentNotifierTestCase(test_agent.AgentDBTestMixIn,
for expected in low_expecteds:
self.assertIn(expected, self.dhcp_notifier_cast.call_args_list)
def _test_auto_schedule_new_network_segments(self, subnet_on_segment):
ctx = mock.Mock()
payload = events.DBEventPayload(
ctx,
metadata={'host': 'HOST A',
'current_segment_ids': set(['segment-1'])})
segments_plugin = mock.Mock()
segments_plugin.get_segments.return_value = [
{'id': 'segment-1', 'hosts': ['HOST A']}]
dhcp_notifier = mock.Mock()
dhcp_mixin = agentschedulers_db.DhcpAgentSchedulerDbMixin()
with mock.patch(
'neutron_lib.plugins.directory.get_plugin',
return_value=segments_plugin), \
mock.patch(
'neutron.objects.subnet.Subnet.get_objects') as get_subnets, \
mock.patch.object(
dhcp_mixin, '_schedule_network') as schedule_network:
get_subnets.return_value = (
[subnet_on_segment] if subnet_on_segment else [])
dhcp_mixin.agent_notifiers[constants.AGENT_TYPE_DHCP] = (
dhcp_notifier)
dhcp_mixin.auto_schedule_new_network_segments(
resources.SEGMENT_HOST_MAPPING, events.AFTER_CREATE,
ctx, payload)
if subnet_on_segment:
schedule_network.assert_called_once_with(
ctx, subnet_on_segment.network_id,
dhcp_notifier, candidate_hosts=['HOST A'])
else:
schedule_network.assert_not_called()
def test_auto_schedule_new_network_segments(self):
self._test_auto_schedule_new_network_segments(
subnet_on_segment=mock.Mock(network_id='net-1'))
def test_auto_schedule_new_network_segments_no_networks_on_segment(self):
self._test_auto_schedule_new_network_segments(subnet_on_segment=None)
def _is_schedule_network_called(self, device_id):
dhcp_notifier_schedule = mock.patch(
'neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.'


Loading…
Cancel
Save