Merge "Divide dhcp and l3 agent scheduling into separate extensions"

This commit is contained in:
Jenkins 2013-07-09 07:26:52 +00:00 committed by Gerrit Code Review
commit f8310ed645
15 changed files with 348 additions and 248 deletions

View File

@ -61,7 +61,7 @@ class DhcpAgentNotifyAPI(proxy.RpcProxy):
"""Notify all the agents that are hosting the network."""
plugin = manager.NeutronManager.get_plugin()
if (method != 'network_delete_end' and utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS)):
plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS)):
if method == 'port_create_end':
# we don't schedule when we create network
# because we want to give admin a chance to

View File

@ -67,7 +67,7 @@ class L3AgentNotifyAPI(proxy.RpcProxy):
"""Notify all the agents that are hosting the routers."""
plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS):
plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
adminContext = (context.is_admin and
context or context.elevated())
plugin.schedule_routers(adminContext, routers)

View File

@ -71,4 +71,5 @@ PAGINATION_INFINITE = 'infinite'
SORT_DIRECTION_ASC = 'asc'
SORT_DIRECTION_DESC = 'desc'
AGENT_SCHEDULER_EXT_ALIAS = 'agent_scheduler'
L3_AGENT_SCHEDULER_EXT_ALIAS = 'l3_agent_scheduler'
DHCP_AGENT_SCHEDULER_EXT_ALIAS = 'dhcp_agent_scheduler'

View File

@ -24,7 +24,8 @@ from neutron.common import constants
from neutron.db import agents_db
from neutron.db import model_base
from neutron.db import models_v2
from neutron.extensions import agentscheduler
from neutron.extensions import dhcpagentscheduler
from neutron.extensions import l3agentscheduler
from neutron.openstack.common import log as logging
@ -55,14 +56,11 @@ class RouterL3AgentBinding(model_base.BASEV2, models_v2.HasId):
ondelete='CASCADE'))
class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
agents_db.AgentDbMixin):
"""Mixin class to add agent scheduler extension to db_plugin_base_v2."""
class AgentSchedulerDbMixin(agents_db.AgentDbMixin):
"""Common class for agent scheduler mixins."""
dhcp_agent_notifier = None
l3_agent_notifier = None
network_scheduler = None
router_scheduler = None
@staticmethod
def is_eligible_agent(active, agent):
@ -77,101 +75,31 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
return not agents_db.AgentDbMixin.is_agent_down(
agent['heartbeat_timestamp'])
def get_dhcp_agents_hosting_networks(
self, context, network_ids, active=None):
if not network_ids:
return []
query = context.session.query(NetworkDhcpAgentBinding)
query = query.options(joinedload('dhcp_agent'))
if len(network_ids) == 1:
query = query.filter(
NetworkDhcpAgentBinding.network_id == network_ids[0])
elif network_ids:
query = query.filter(
NetworkDhcpAgentBinding.network_id in network_ids)
if active is not None:
query = (query.filter(agents_db.Agent.admin_state_up == active))
def update_agent(self, context, id, agent):
original_agent = self.get_agent(context, id)
result = super(AgentSchedulerDbMixin, self).update_agent(
context, id, agent)
agent_data = agent['agent']
if ('admin_state_up' in agent_data and
original_agent['admin_state_up'] != agent_data['admin_state_up']):
if (original_agent['agent_type'] == constants.AGENT_TYPE_DHCP and
self.dhcp_agent_notifier):
self.dhcp_agent_notifier.agent_updated(
context, agent_data['admin_state_up'],
original_agent['host'])
elif (original_agent['agent_type'] == constants.AGENT_TYPE_L3 and
self.l3_agent_notifier):
self.l3_agent_notifier.agent_updated(
context, agent_data['admin_state_up'],
original_agent['host'])
return result
return [binding.dhcp_agent
for binding in query
if AgentSchedulerDbMixin.is_eligible_agent(active,
binding.dhcp_agent)]
def add_network_to_dhcp_agent(self, context, id, network_id):
self._get_network(context, network_id)
with context.session.begin(subtransactions=True):
agent_db = self._get_agent(context, id)
if (agent_db['agent_type'] != constants.AGENT_TYPE_DHCP or
not agent_db['admin_state_up']):
raise agentscheduler.InvalidDHCPAgent(id=id)
dhcp_agents = self.get_dhcp_agents_hosting_networks(
context, [network_id])
for dhcp_agent in dhcp_agents:
if id == dhcp_agent.id:
raise agentscheduler.NetworkHostedByDHCPAgent(
network_id=network_id, agent_id=id)
binding = NetworkDhcpAgentBinding()
binding.dhcp_agent_id = id
binding.network_id = network_id
context.session.add(binding)
if self.dhcp_agent_notifier:
self.dhcp_agent_notifier.network_added_to_agent(
context, network_id, agent_db.host)
class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
AgentSchedulerDbMixin):
"""Mixin class to add l3 agent scheduler extension to db_plugin_base_v2."""
def remove_network_from_dhcp_agent(self, context, id, network_id):
agent = self._get_agent(context, id)
with context.session.begin(subtransactions=True):
try:
query = context.session.query(NetworkDhcpAgentBinding)
binding = query.filter(
NetworkDhcpAgentBinding.network_id == network_id,
NetworkDhcpAgentBinding.dhcp_agent_id == id).one()
except exc.NoResultFound:
raise agentscheduler.NetworkNotHostedByDhcpAgent(
network_id=network_id, agent_id=id)
context.session.delete(binding)
if self.dhcp_agent_notifier:
self.dhcp_agent_notifier.network_removed_from_agent(
context, network_id, agent.host)
def list_networks_on_dhcp_agent(self, context, id):
query = context.session.query(NetworkDhcpAgentBinding.network_id)
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == id)
net_ids = [item[0] for item in query]
if net_ids:
return {'networks':
self.get_networks(context, filters={'id': net_ids})}
else:
return {'networks': []}
def list_active_networks_on_active_dhcp_agent(self, context, host):
agent = self._get_agent_by_type_and_host(
context, constants.AGENT_TYPE_DHCP, host)
if not agent.admin_state_up:
return []
query = context.session.query(NetworkDhcpAgentBinding.network_id)
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == agent.id)
net_ids = [item[0] for item in query]
if net_ids:
return self.get_networks(
context,
filters={'id': net_ids, 'admin_state_up': [True]}
)
else:
return []
def list_dhcp_agents_hosting_network(self, context, network_id):
dhcp_agents = self.get_dhcp_agents_hosting_networks(
context, [network_id])
agent_ids = [dhcp_agent.id for dhcp_agent in dhcp_agents]
if agent_ids:
return {
'agents':
self.get_agents(context, filters={'id': agent_ids})}
else:
return {'agents': []}
router_scheduler = None
def add_router_to_l3_agent(self, context, id, router_id):
"""Add a l3 agent to host a router."""
@ -181,14 +109,14 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
if (agent_db['agent_type'] != constants.AGENT_TYPE_L3 or
not agent_db['admin_state_up'] or
not self.get_l3_agent_candidates(router, [agent_db])):
raise agentscheduler.InvalidL3Agent(id=id)
raise l3agentscheduler.InvalidL3Agent(id=id)
query = context.session.query(RouterL3AgentBinding)
try:
binding = query.filter(
RouterL3AgentBinding.l3_agent_id == agent_db.id,
RouterL3AgentBinding.router_id == router_id).one()
if binding:
raise agentscheduler.RouterHostedByL3Agent(
raise l3agentscheduler.RouterHostedByL3Agent(
router_id=router_id, agent_id=id)
except exc.NoResultFound:
pass
@ -197,7 +125,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
agent_db.host,
router_id)
if not result:
raise agentscheduler.RouterSchedulingFailed(
raise l3agentscheduler.RouterSchedulingFailed(
router_id=router_id, agent_id=id)
if self.l3_agent_notifier:
@ -220,7 +148,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
try:
binding = query.one()
except exc.NoResultFound:
raise agentscheduler.RouterNotHostedByL3Agent(
raise l3agentscheduler.RouterNotHostedByL3Agent(
router_id=router_id, agent_id=id)
context.session.delete(binding)
if self.l3_agent_notifier:
@ -305,18 +233,6 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
else:
return {'agents': []}
def schedule_network(self, context, created_network):
if self.network_scheduler:
chosen_agent = self.network_scheduler.schedule(
self, context, created_network)
if not chosen_agent:
LOG.warn(_('Fail scheduling network %s'), created_network)
return chosen_agent
def auto_schedule_networks(self, context, host):
if self.network_scheduler:
self.network_scheduler.auto_schedule_networks(self, context, host)
def get_l3_agents(self, context, active=None, filters=None):
query = context.session.query(agents_db.Agent)
query = query.filter(
@ -372,21 +288,118 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
for router in routers:
self.schedule_router(context, router)
def update_agent(self, context, id, agent):
original_agent = self.get_agent(context, id)
result = super(AgentSchedulerDbMixin, self).update_agent(
context, id, agent)
agent_data = agent['agent']
if ('admin_state_up' in agent_data and
original_agent['admin_state_up'] != agent_data['admin_state_up']):
if (original_agent['agent_type'] == constants.AGENT_TYPE_DHCP and
self.dhcp_agent_notifier):
self.dhcp_agent_notifier.agent_updated(
context, agent_data['admin_state_up'],
original_agent['host'])
elif (original_agent['agent_type'] == constants.AGENT_TYPE_L3 and
self.l3_agent_notifier):
self.l3_agent_notifier.agent_updated(
context, agent_data['admin_state_up'],
original_agent['host'])
return result
class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
.DhcpAgentSchedulerPluginBase,
AgentSchedulerDbMixin):
"""Mixin class to add DHCP agent scheduler extension to db_plugin_base_v2.
"""
network_scheduler = None
def get_dhcp_agents_hosting_networks(
self, context, network_ids, active=None):
if not network_ids:
return []
query = context.session.query(NetworkDhcpAgentBinding)
query = query.options(joinedload('dhcp_agent'))
if len(network_ids) == 1:
query = query.filter(
NetworkDhcpAgentBinding.network_id == network_ids[0])
elif network_ids:
query = query.filter(
NetworkDhcpAgentBinding.network_id in network_ids)
if active is not None:
query = (query.filter(agents_db.Agent.admin_state_up == active))
return [binding.dhcp_agent
for binding in query
if AgentSchedulerDbMixin.is_eligible_agent(active,
binding.dhcp_agent)]
def add_network_to_dhcp_agent(self, context, id, network_id):
self._get_network(context, network_id)
with context.session.begin(subtransactions=True):
agent_db = self._get_agent(context, id)
if (agent_db['agent_type'] != constants.AGENT_TYPE_DHCP or
not agent_db['admin_state_up']):
raise dhcpagentscheduler.InvalidDHCPAgent(id=id)
dhcp_agents = self.get_dhcp_agents_hosting_networks(
context, [network_id])
for dhcp_agent in dhcp_agents:
if id == dhcp_agent.id:
raise dhcpagentscheduler.NetworkHostedByDHCPAgent(
network_id=network_id, agent_id=id)
binding = NetworkDhcpAgentBinding()
binding.dhcp_agent_id = id
binding.network_id = network_id
context.session.add(binding)
if self.dhcp_agent_notifier:
self.dhcp_agent_notifier.network_added_to_agent(
context, network_id, agent_db.host)
def remove_network_from_dhcp_agent(self, context, id, network_id):
agent = self._get_agent(context, id)
with context.session.begin(subtransactions=True):
try:
query = context.session.query(NetworkDhcpAgentBinding)
binding = query.filter(
NetworkDhcpAgentBinding.network_id == network_id,
NetworkDhcpAgentBinding.dhcp_agent_id == id).one()
except exc.NoResultFound:
raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
network_id=network_id, agent_id=id)
context.session.delete(binding)
if self.dhcp_agent_notifier:
self.dhcp_agent_notifier.network_removed_from_agent(
context, network_id, agent.host)
def list_networks_on_dhcp_agent(self, context, id):
query = context.session.query(NetworkDhcpAgentBinding.network_id)
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == id)
net_ids = [item[0] for item in query]
if net_ids:
return {'networks':
self.get_networks(context, filters={'id': net_ids})}
else:
return {'networks': []}
def list_active_networks_on_active_dhcp_agent(self, context, host):
agent = self._get_agent_by_type_and_host(
context, constants.AGENT_TYPE_DHCP, host)
if not agent.admin_state_up:
return []
query = context.session.query(NetworkDhcpAgentBinding.network_id)
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == agent.id)
net_ids = [item[0] for item in query]
if net_ids:
return self.get_networks(
context,
filters={'id': net_ids, 'admin_state_up': [True]}
)
else:
return []
def list_dhcp_agents_hosting_network(self, context, network_id):
dhcp_agents = self.get_dhcp_agents_hosting_networks(
context, [network_id])
agent_ids = [dhcp_agent.id for dhcp_agent in dhcp_agents]
if agent_ids:
return {
'agents': self.get_agents(context, filters={'id': agent_ids})}
else:
return {'agents': []}
def schedule_network(self, context, created_network):
if self.network_scheduler:
chosen_agent = self.network_scheduler.schedule(
self, context, created_network)
if not chosen_agent:
LOG.warn(_('Fail scheduling network %s'), created_network)
return chosen_agent
def auto_schedule_networks(self, context, host):
if self.network_scheduler:
self.network_scheduler.auto_schedule_networks(self, context, host)

View File

@ -35,7 +35,7 @@ class DhcpRpcCallbackMixin(object):
LOG.debug(_('Network list requested from %s'), host)
plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS):
plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS):
if cfg.CONF.network_auto_schedule:
plugin.auto_schedule_networks(context, host)
nets = plugin.list_active_networks_on_active_dhcp_agent(

View File

@ -42,7 +42,7 @@ class L3RpcCallbackMixin(object):
context = neutron_context.get_admin_context()
plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS):
plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
if cfg.CONF.router_auto_schedule:
plugin.auto_schedule_routers(context, host, router_id)
routers = plugin.list_active_sync_routers_on_active_l3_agent(

View File

@ -0,0 +1,154 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 OpenStack Foundation.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from abc import abstractmethod
from neutron.api import extensions
from neutron.api.v2 import base
from neutron.api.v2 import resource
from neutron.common import constants
from neutron.common import exceptions
from neutron.extensions import agent
from neutron import manager
from neutron import policy
from neutron import wsgi
DHCP_NET = 'dhcp-network'
DHCP_NETS = DHCP_NET + 's'
DHCP_AGENT = 'dhcp-agent'
DHCP_AGENTS = DHCP_AGENT + 's'
class NetworkSchedulerController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"get_%s" % DHCP_NETS,
{})
return plugin.list_networks_on_dhcp_agent(
request.context, kwargs['agent_id'])
def create(self, request, body, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"create_%s" % DHCP_NET,
{})
return plugin.add_network_to_dhcp_agent(
request.context, kwargs['agent_id'], body['network_id'])
def delete(self, request, id, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"delete_%s" % DHCP_NET,
{})
return plugin.remove_network_from_dhcp_agent(
request.context, kwargs['agent_id'], id)
class DhcpAgentsHostingNetworkController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"get_%s" % DHCP_AGENTS,
{})
return plugin.list_dhcp_agents_hosting_network(
request.context, kwargs['network_id'])
class Dhcpagentscheduler(extensions.ExtensionDescriptor):
"""Extension class supporting dhcp agent scheduler.
"""
@classmethod
def get_name(cls):
return "DHCP Agent Scheduler"
@classmethod
def get_alias(cls):
return constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS
@classmethod
def get_description(cls):
return "Schedule networks among dhcp agents"
@classmethod
def get_namespace(cls):
return "http://docs.openstack.org/ext/dhcp_agent_scheduler/api/v1.0"
@classmethod
def get_updated(cls):
return "2013-02-07T10:00:00-00:00"
@classmethod
def get_resources(cls):
"""Returns Ext Resources."""
exts = []
parent = dict(member_name="agent",
collection_name="agents")
controller = resource.Resource(NetworkSchedulerController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
DHCP_NETS, controller, parent))
parent = dict(member_name="network",
collection_name="networks")
controller = resource.Resource(DhcpAgentsHostingNetworkController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
DHCP_AGENTS, controller, parent))
return exts
def get_extended_resources(self, version):
return {}
class InvalidDHCPAgent(agent.AgentNotFound):
message = _("Agent %(id)s is not a valid DHCP Agent or has been disabled")
class NetworkHostedByDHCPAgent(exceptions.Conflict):
message = _("The network %(network_id)s has been already hosted"
" by the DHCP Agent %(agent_id)s.")
class NetworkNotHostedByDhcpAgent(exceptions.Conflict):
message = _("The network %(network_id)s is not hosted"
" by the DHCP agent %(agent_id)s.")
class DhcpAgentSchedulerPluginBase(object):
"""REST API to operate the DHCP agent scheduler.
All of method must be in an admin context.
"""
@abstractmethod
def add_network_to_dhcp_agent(self, context, id, network_id):
pass
@abstractmethod
def remove_network_from_dhcp_agent(self, context, id, network_id):
pass
@abstractmethod
def list_networks_on_dhcp_agent(self, context, id):
pass
@abstractmethod
def list_dhcp_agents_hosting_network(self, context, network_id):
pass

View File

@ -27,42 +27,12 @@ from neutron import manager
from neutron import policy
from neutron import wsgi
DHCP_NET = 'dhcp-network'
DHCP_NETS = DHCP_NET + 's'
DHCP_AGENT = 'dhcp-agent'
DHCP_AGENTS = DHCP_AGENT + 's'
L3_ROUTER = 'l3-router'
L3_ROUTERS = L3_ROUTER + 's'
L3_AGENT = 'l3-agent'
L3_AGENTS = L3_AGENT + 's'
class NetworkSchedulerController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"get_%s" % DHCP_NETS,
{})
return plugin.list_networks_on_dhcp_agent(
request.context, kwargs['agent_id'])
def create(self, request, body, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"create_%s" % DHCP_NET,
{})
return plugin.add_network_to_dhcp_agent(
request.context, kwargs['agent_id'], body['network_id'])
def delete(self, request, id, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"delete_%s" % DHCP_NET,
{})
return plugin.remove_network_from_dhcp_agent(
request.context, kwargs['agent_id'], id)
class RouterSchedulerController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
@ -91,16 +61,6 @@ class RouterSchedulerController(wsgi.Controller):
request.context, kwargs['agent_id'], id)
class DhcpAgentsHostingNetworkController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
policy.enforce(request.context,
"get_%s" % DHCP_AGENTS,
{})
return plugin.list_dhcp_agents_hosting_network(
request.context, kwargs['network_id'])
class L3AgentsHostingRouterController(wsgi.Controller):
def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin()
@ -111,29 +71,29 @@ class L3AgentsHostingRouterController(wsgi.Controller):
request.context, kwargs['router_id'])
class Agentscheduler(extensions.ExtensionDescriptor):
"""Extension class supporting agent scheduler.
class L3agentscheduler(extensions.ExtensionDescriptor):
"""Extension class supporting l3 agent scheduler.
"""
@classmethod
def get_name(cls):
return "Agent Schedulers"
return "L3 Agent Scheduler"
@classmethod
def get_alias(cls):
return constants.AGENT_SCHEDULER_EXT_ALIAS
return constants.L3_AGENT_SCHEDULER_EXT_ALIAS
@classmethod
def get_description(cls):
return "Schedule resources among agents"
return "Schedule routers among l3 agents"
@classmethod
def get_namespace(cls):
return "http://docs.openstack.org/ext/agent_scheduler/api/v1.0"
return "http://docs.openstack.org/ext/l3_agent_scheduler/api/v1.0"
@classmethod
def get_updated(cls):
return "2013-02-03T10:00:00-00:00"
return "2013-02-07T10:00:00-00:00"
@classmethod
def get_resources(cls):
@ -141,24 +101,12 @@ class Agentscheduler(extensions.ExtensionDescriptor):
exts = []
parent = dict(member_name="agent",
collection_name="agents")
controller = resource.Resource(NetworkSchedulerController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
DHCP_NETS, controller, parent))
controller = resource.Resource(RouterSchedulerController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
L3_ROUTERS, controller, parent))
parent = dict(member_name="network",
collection_name="networks")
controller = resource.Resource(DhcpAgentsHostingNetworkController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
DHCP_AGENTS, controller, parent))
parent = dict(member_name="router",
collection_name="routers")
@ -172,20 +120,6 @@ class Agentscheduler(extensions.ExtensionDescriptor):
return {}
class InvalidDHCPAgent(agent.AgentNotFound):
message = _("Agent %(id)s is not a valid DHCP Agent or has been disabled")
class NetworkHostedByDHCPAgent(exceptions.Conflict):
message = _("The network %(network_id)s has been already hosted"
" by the DHCP Agent %(agent_id)s.")
class NetworkNotHostedByDhcpAgent(exceptions.Conflict):
message = _("The network %(network_id)s is not hosted"
" by the DHCP agent %(agent_id)s.")
class InvalidL3Agent(agent.AgentNotFound):
message = _("Agent %(id)s is not a L3 Agent or has been disabled")
@ -205,28 +139,12 @@ class RouterNotHostedByL3Agent(exceptions.Conflict):
" by L3 agent %(agent_id)s.")
class AgentSchedulerPluginBase(object):
"""REST API to operate the agent scheduler.
class L3AgentSchedulerPluginBase(object):
"""REST API to operate the l3 agent scheduler.
All of method must be in an admin context.
"""
@abstractmethod
def add_network_to_dhcp_agent(self, context, id, network_id):
pass
@abstractmethod
def remove_network_from_dhcp_agent(self, context, id, network_id):
pass
@abstractmethod
def list_networks_on_dhcp_agent(self, context, id):
pass
@abstractmethod
def list_dhcp_agents_hosting_network(self, context, network_id):
pass
@abstractmethod
def add_router_to_l3_agent(self, context, id, router_id):
pass

View File

@ -197,7 +197,8 @@ class AgentNotifierApi(proxy.RpcProxy,
class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2,
extraroute_db.ExtraRoute_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin):
agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin):
"""BrocadePluginV2 is a Neutron plugin.
Provides L2 Virtual Network functionality using VDX. Upper
@ -213,7 +214,8 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2,
self.supported_extension_aliases = ["binding", "security-group",
"router", "extraroute",
"agent", "agent_scheduler"]
"agent", "l3_agent_scheduler",
"dhcp_agent_scheduler"]
self.physical_interface = (cfg.CONF.PHYSICAL_INTERFACE.
physical_interface)

View File

@ -188,7 +188,8 @@ class LinuxBridgePluginV2(db_base_plugin_v2.NeutronDbPluginV2,
extraroute_db.ExtraRoute_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin,
agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
portbindings_db.PortBindingMixin):
"""Implement the Neutron abstractions using Linux bridging.
@ -215,7 +216,9 @@ class LinuxBridgePluginV2(db_base_plugin_v2.NeutronDbPluginV2,
_supported_extension_aliases = ["provider", "router", "ext-gw-mode",
"binding", "quotas", "security-group",
"agent", "extraroute", "agent_scheduler"]
"agent", "extraroute",
"l3_agent_scheduler",
"dhcp_agent_scheduler"]
@property
def supported_extension_aliases(self):

View File

@ -49,7 +49,8 @@ TYPE_MULTI_SEGMENT = 'multi-segment'
class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
extraroute_db.ExtraRoute_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin,
agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
portbindings_db.PortBindingMixin):
"""Implement the Neutron L2 abstractions using modules.
@ -70,7 +71,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
# List of supported extensions
_supported_extension_aliases = ["provider", "router", "extraroute",
"binding", "quotas", "security-group",
"agent", "agent_scheduler"]
"agent", "l3_agent_scheduler",
"dhcp_agent_scheduler"]
@property
def supported_extension_aliases(self):

View File

@ -64,7 +64,8 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
extraroute_db.ExtraRoute_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin):
agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin):
"""NECPluginV2 controls an OpenFlow Controller.
The Neutron NECPluginV2 maps L2 logical networks to L2 virtualized networks
@ -79,7 +80,9 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
"""
_supported_extension_aliases = ["router", "ext-gw-mode", "quotas",
"binding", "security-group",
"extraroute", "agent", "agent_scheduler"]
"extraroute", "agent",
"l3_agent_scheduler",
"dhcp_agent_scheduler"]
@property
def supported_extension_aliases(self):

View File

@ -132,7 +132,7 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
qos_db.NVPQoSDbMixin,
nvp_sec.NVPSecurityGroups,
nvp_meta.NvpMetadataAccess,
agentschedulers_db.AgentSchedulerDbMixin):
agentschedulers_db.DhcpAgentSchedulerDbMixin):
"""L2 Virtual network plugin.
NvpPluginV2 is a Neutron plugin that provides L2 Virtual Network

View File

@ -218,7 +218,8 @@ class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
extraroute_db.ExtraRoute_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin,
agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
portbindings_db.PortBindingMixin):
"""Implement the Neutron abstractions using Open vSwitch.
@ -247,7 +248,9 @@ class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
_supported_extension_aliases = ["provider", "router", "ext-gw-mode",
"binding", "quotas", "security-group",
"agent", "extraroute", "agent_scheduler"]
"agent", "extraroute",
"l3_agent_scheduler",
"dhcp_agent_scheduler"]
@property
def supported_extension_aliases(self):

View File

@ -29,7 +29,8 @@ from neutron.db import agents_db
from neutron.db import dhcp_rpc_base
from neutron.db import l3_rpc_base
from neutron.extensions import agent
from neutron.extensions import agentscheduler
from neutron.extensions import dhcpagentscheduler
from neutron.extensions import l3agentscheduler
from neutron import manager
from neutron.openstack.common import timeutils
from neutron.openstack.common import uuidutils
@ -89,7 +90,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code,
admin_context=True):
path = "/agents/%s/%s.%s" % (agent_id,
agentscheduler.L3_ROUTERS,
l3agentscheduler.L3_ROUTERS,
self.fmt)
return self._request_list(path, expected_code=expected_code,
admin_context=admin_context)
@ -98,7 +99,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code,
admin_context=True):
path = "/agents/%s/%s.%s" % (agent_id,
agentscheduler.DHCP_NETS,
dhcpagentscheduler.DHCP_NETS,
self.fmt)
return self._request_list(path, expected_code=expected_code,
admin_context=admin_context)
@ -107,7 +108,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code,
admin_context=True):
path = "/routers/%s/%s.%s" % (router_id,
agentscheduler.L3_AGENTS,
l3agentscheduler.L3_AGENTS,
self.fmt)
return self._request_list(path, expected_code=expected_code,
admin_context=admin_context)
@ -116,7 +117,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code,
admin_context=True):
path = "/networks/%s/%s.%s" % (network_id,
agentscheduler.DHCP_AGENTS,
dhcpagentscheduler.DHCP_AGENTS,
self.fmt)
return self._request_list(path, expected_code=expected_code,
admin_context=admin_context)
@ -125,7 +126,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPCreated.code,
admin_context=True):
path = "/agents/%s/%s.%s" % (id,
agentscheduler.L3_ROUTERS,
l3agentscheduler.L3_ROUTERS,
self.fmt)
req = self._path_create_request(path,
{'router_id': router_id},
@ -137,7 +138,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPCreated.code,
admin_context=True):
path = "/agents/%s/%s.%s" % (id,
agentscheduler.DHCP_NETS,
dhcpagentscheduler.DHCP_NETS,
self.fmt)
req = self._path_create_request(path,
{'network_id': network_id},
@ -149,7 +150,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPNoContent.code,
admin_context=True):
path = "/agents/%s/%s/%s.%s" % (id,
agentscheduler.DHCP_NETS,
dhcpagentscheduler.DHCP_NETS,
network_id,
self.fmt)
req = self._path_delete_request(path,
@ -161,7 +162,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPNoContent.code,
admin_context=True):
path = "/agents/%s/%s/%s.%s" % (id,
agentscheduler.L3_ROUTERS,
l3agentscheduler.L3_ROUTERS,
router_id,
self.fmt)
req = self._path_delete_request(path, admin_context=admin_context)