Divide dhcp and l3 agent scheduling into separate extensions

Rationale behind this is that some plugins may support only dhcp or l3 agent scheduling.
The patch is nothing more than refactoring. Functionality was not changed.

Fixes bug 1196806

Change-Id: Ie174059adfaed3028bbf65de7bde3497dd9bc664
This commit is contained in:
Oleg Bondarev 2013-07-02 12:08:52 +04:00
parent 5be7739099
commit 0471248b97
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.""" """Notify all the agents that are hosting the network."""
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
if (method != 'network_delete_end' and utils.is_extension_supported( 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': if method == 'port_create_end':
# we don't schedule when we create network # we don't schedule when we create network
# because we want to give admin a chance to # 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.""" """Notify all the agents that are hosting the routers."""
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported( if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS): plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
adminContext = (context.is_admin and adminContext = (context.is_admin and
context or context.elevated()) context or context.elevated())
plugin.schedule_routers(adminContext, routers) plugin.schedule_routers(adminContext, routers)

View File

@ -71,4 +71,5 @@ PAGINATION_INFINITE = 'infinite'
SORT_DIRECTION_ASC = 'asc' SORT_DIRECTION_ASC = 'asc'
SORT_DIRECTION_DESC = 'desc' 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 agents_db
from neutron.db import model_base from neutron.db import model_base
from neutron.db import models_v2 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 from neutron.openstack.common import log as logging
@ -55,14 +56,11 @@ class RouterL3AgentBinding(model_base.BASEV2, models_v2.HasId):
ondelete='CASCADE')) ondelete='CASCADE'))
class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase, class AgentSchedulerDbMixin(agents_db.AgentDbMixin):
agents_db.AgentDbMixin): """Common class for agent scheduler mixins."""
"""Mixin class to add agent scheduler extension to db_plugin_base_v2."""
dhcp_agent_notifier = None dhcp_agent_notifier = None
l3_agent_notifier = None l3_agent_notifier = None
network_scheduler = None
router_scheduler = None
@staticmethod @staticmethod
def is_eligible_agent(active, agent): def is_eligible_agent(active, agent):
@ -77,101 +75,31 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
return not agents_db.AgentDbMixin.is_agent_down( return not agents_db.AgentDbMixin.is_agent_down(
agent['heartbeat_timestamp']) agent['heartbeat_timestamp'])
def get_dhcp_agents_hosting_networks( def update_agent(self, context, id, agent):
self, context, network_ids, active=None): original_agent = self.get_agent(context, id)
if not network_ids: result = super(AgentSchedulerDbMixin, self).update_agent(
return [] context, id, agent)
query = context.session.query(NetworkDhcpAgentBinding) agent_data = agent['agent']
query = query.options(joinedload('dhcp_agent')) if ('admin_state_up' in agent_data and
if len(network_ids) == 1: original_agent['admin_state_up'] != agent_data['admin_state_up']):
query = query.filter( if (original_agent['agent_type'] == constants.AGENT_TYPE_DHCP and
NetworkDhcpAgentBinding.network_id == network_ids[0]) self.dhcp_agent_notifier):
elif network_ids: self.dhcp_agent_notifier.agent_updated(
query = query.filter( context, agent_data['admin_state_up'],
NetworkDhcpAgentBinding.network_id in network_ids) original_agent['host'])
if active is not None: elif (original_agent['agent_type'] == constants.AGENT_TYPE_L3 and
query = (query.filter(agents_db.Agent.admin_state_up == active)) 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): class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
self._get_network(context, network_id) AgentSchedulerDbMixin):
with context.session.begin(subtransactions=True): """Mixin class to add l3 agent scheduler extension to db_plugin_base_v2."""
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)
def remove_network_from_dhcp_agent(self, context, id, network_id): router_scheduler = None
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': []}
def add_router_to_l3_agent(self, context, id, router_id): def add_router_to_l3_agent(self, context, id, router_id):
"""Add a l3 agent to host a router.""" """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 if (agent_db['agent_type'] != constants.AGENT_TYPE_L3 or
not agent_db['admin_state_up'] or not agent_db['admin_state_up'] or
not self.get_l3_agent_candidates(router, [agent_db])): not self.get_l3_agent_candidates(router, [agent_db])):
raise agentscheduler.InvalidL3Agent(id=id) raise l3agentscheduler.InvalidL3Agent(id=id)
query = context.session.query(RouterL3AgentBinding) query = context.session.query(RouterL3AgentBinding)
try: try:
binding = query.filter( binding = query.filter(
RouterL3AgentBinding.l3_agent_id == agent_db.id, RouterL3AgentBinding.l3_agent_id == agent_db.id,
RouterL3AgentBinding.router_id == router_id).one() RouterL3AgentBinding.router_id == router_id).one()
if binding: if binding:
raise agentscheduler.RouterHostedByL3Agent( raise l3agentscheduler.RouterHostedByL3Agent(
router_id=router_id, agent_id=id) router_id=router_id, agent_id=id)
except exc.NoResultFound: except exc.NoResultFound:
pass pass
@ -197,7 +125,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
agent_db.host, agent_db.host,
router_id) router_id)
if not result: if not result:
raise agentscheduler.RouterSchedulingFailed( raise l3agentscheduler.RouterSchedulingFailed(
router_id=router_id, agent_id=id) router_id=router_id, agent_id=id)
if self.l3_agent_notifier: if self.l3_agent_notifier:
@ -220,7 +148,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
try: try:
binding = query.one() binding = query.one()
except exc.NoResultFound: except exc.NoResultFound:
raise agentscheduler.RouterNotHostedByL3Agent( raise l3agentscheduler.RouterNotHostedByL3Agent(
router_id=router_id, agent_id=id) router_id=router_id, agent_id=id)
context.session.delete(binding) context.session.delete(binding)
if self.l3_agent_notifier: if self.l3_agent_notifier:
@ -305,18 +233,6 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
else: else:
return {'agents': []} 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): def get_l3_agents(self, context, active=None, filters=None):
query = context.session.query(agents_db.Agent) query = context.session.query(agents_db.Agent)
query = query.filter( query = query.filter(
@ -372,21 +288,118 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
for router in routers: for router in routers:
self.schedule_router(context, router) self.schedule_router(context, router)
def update_agent(self, context, id, agent):
original_agent = self.get_agent(context, id) class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
result = super(AgentSchedulerDbMixin, self).update_agent( .DhcpAgentSchedulerPluginBase,
context, id, agent) AgentSchedulerDbMixin):
agent_data = agent['agent'] """Mixin class to add DHCP agent scheduler extension to db_plugin_base_v2.
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 network_scheduler = None
self.dhcp_agent_notifier):
self.dhcp_agent_notifier.agent_updated( def get_dhcp_agents_hosting_networks(
context, agent_data['admin_state_up'], self, context, network_ids, active=None):
original_agent['host']) if not network_ids:
elif (original_agent['agent_type'] == constants.AGENT_TYPE_L3 and return []
self.l3_agent_notifier): query = context.session.query(NetworkDhcpAgentBinding)
self.l3_agent_notifier.agent_updated( query = query.options(joinedload('dhcp_agent'))
context, agent_data['admin_state_up'], if len(network_ids) == 1:
original_agent['host']) query = query.filter(
return result 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) LOG.debug(_('Network list requested from %s'), host)
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported( if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS): plugin, constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS):
if cfg.CONF.network_auto_schedule: if cfg.CONF.network_auto_schedule:
plugin.auto_schedule_networks(context, host) plugin.auto_schedule_networks(context, host)
nets = plugin.list_active_networks_on_active_dhcp_agent( nets = plugin.list_active_networks_on_active_dhcp_agent(

View File

@ -42,7 +42,7 @@ class L3RpcCallbackMixin(object):
context = neutron_context.get_admin_context() context = neutron_context.get_admin_context()
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported( if utils.is_extension_supported(
plugin, constants.AGENT_SCHEDULER_EXT_ALIAS): plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
if cfg.CONF.router_auto_schedule: if cfg.CONF.router_auto_schedule:
plugin.auto_schedule_routers(context, host, router_id) plugin.auto_schedule_routers(context, host, router_id)
routers = plugin.list_active_sync_routers_on_active_l3_agent( 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 policy
from neutron import wsgi 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_ROUTER = 'l3-router'
L3_ROUTERS = L3_ROUTER + 's' L3_ROUTERS = L3_ROUTER + 's'
L3_AGENT = 'l3-agent' L3_AGENT = 'l3-agent'
L3_AGENTS = L3_AGENT + 's' 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): class RouterSchedulerController(wsgi.Controller):
def index(self, request, **kwargs): def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
@ -91,16 +61,6 @@ class RouterSchedulerController(wsgi.Controller):
request.context, kwargs['agent_id'], id) 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): class L3AgentsHostingRouterController(wsgi.Controller):
def index(self, request, **kwargs): def index(self, request, **kwargs):
plugin = manager.NeutronManager.get_plugin() plugin = manager.NeutronManager.get_plugin()
@ -111,29 +71,29 @@ class L3AgentsHostingRouterController(wsgi.Controller):
request.context, kwargs['router_id']) request.context, kwargs['router_id'])
class Agentscheduler(extensions.ExtensionDescriptor): class L3agentscheduler(extensions.ExtensionDescriptor):
"""Extension class supporting agent scheduler. """Extension class supporting l3 agent scheduler.
""" """
@classmethod @classmethod
def get_name(cls): def get_name(cls):
return "Agent Schedulers" return "L3 Agent Scheduler"
@classmethod @classmethod
def get_alias(cls): def get_alias(cls):
return constants.AGENT_SCHEDULER_EXT_ALIAS return constants.L3_AGENT_SCHEDULER_EXT_ALIAS
@classmethod @classmethod
def get_description(cls): def get_description(cls):
return "Schedule resources among agents" return "Schedule routers among l3 agents"
@classmethod @classmethod
def get_namespace(cls): 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 @classmethod
def get_updated(cls): def get_updated(cls):
return "2013-02-03T10:00:00-00:00" return "2013-02-07T10:00:00-00:00"
@classmethod @classmethod
def get_resources(cls): def get_resources(cls):
@ -141,24 +101,12 @@ class Agentscheduler(extensions.ExtensionDescriptor):
exts = [] exts = []
parent = dict(member_name="agent", parent = dict(member_name="agent",
collection_name="agents") collection_name="agents")
controller = resource.Resource(NetworkSchedulerController(),
base.FAULT_MAP)
exts.append(extensions.ResourceExtension(
DHCP_NETS, controller, parent))
controller = resource.Resource(RouterSchedulerController(), controller = resource.Resource(RouterSchedulerController(),
base.FAULT_MAP) base.FAULT_MAP)
exts.append(extensions.ResourceExtension( exts.append(extensions.ResourceExtension(
L3_ROUTERS, controller, parent)) 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", parent = dict(member_name="router",
collection_name="routers") collection_name="routers")
@ -172,20 +120,6 @@ class Agentscheduler(extensions.ExtensionDescriptor):
return {} 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): class InvalidL3Agent(agent.AgentNotFound):
message = _("Agent %(id)s is not a L3 Agent or has been disabled") 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.") " by L3 agent %(agent_id)s.")
class AgentSchedulerPluginBase(object): class L3AgentSchedulerPluginBase(object):
"""REST API to operate the agent scheduler. """REST API to operate the l3 agent scheduler.
All of method must be in an admin context. 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 @abstractmethod
def add_router_to_l3_agent(self, context, id, router_id): def add_router_to_l3_agent(self, context, id, router_id):
pass pass

View File

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

View File

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

View File

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

View File

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

View File

@ -132,7 +132,7 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
qos_db.NVPQoSDbMixin, qos_db.NVPQoSDbMixin,
nvp_sec.NVPSecurityGroups, nvp_sec.NVPSecurityGroups,
nvp_meta.NvpMetadataAccess, nvp_meta.NvpMetadataAccess,
agentschedulers_db.AgentSchedulerDbMixin): agentschedulers_db.DhcpAgentSchedulerDbMixin):
"""L2 Virtual network plugin. """L2 Virtual network plugin.
NvpPluginV2 is a Neutron plugin that provides L2 Virtual Network 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, extraroute_db.ExtraRoute_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin, l3_gwmode_db.L3_NAT_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin, sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.AgentSchedulerDbMixin, agentschedulers_db.L3AgentSchedulerDbMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
portbindings_db.PortBindingMixin): portbindings_db.PortBindingMixin):
"""Implement the Neutron abstractions using Open vSwitch. """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", _supported_extension_aliases = ["provider", "router", "ext-gw-mode",
"binding", "quotas", "security-group", "binding", "quotas", "security-group",
"agent", "extraroute", "agent_scheduler"] "agent", "extraroute",
"l3_agent_scheduler",
"dhcp_agent_scheduler"]
@property @property
def supported_extension_aliases(self): 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 dhcp_rpc_base
from neutron.db import l3_rpc_base from neutron.db import l3_rpc_base
from neutron.extensions import agent 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 import manager
from neutron.openstack.common import timeutils from neutron.openstack.common import timeutils
from neutron.openstack.common import uuidutils from neutron.openstack.common import uuidutils
@ -89,7 +90,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code, expected_code=exc.HTTPOk.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s.%s" % (agent_id, path = "/agents/%s/%s.%s" % (agent_id,
agentscheduler.L3_ROUTERS, l3agentscheduler.L3_ROUTERS,
self.fmt) self.fmt)
return self._request_list(path, expected_code=expected_code, return self._request_list(path, expected_code=expected_code,
admin_context=admin_context) admin_context=admin_context)
@ -98,7 +99,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code, expected_code=exc.HTTPOk.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s.%s" % (agent_id, path = "/agents/%s/%s.%s" % (agent_id,
agentscheduler.DHCP_NETS, dhcpagentscheduler.DHCP_NETS,
self.fmt) self.fmt)
return self._request_list(path, expected_code=expected_code, return self._request_list(path, expected_code=expected_code,
admin_context=admin_context) admin_context=admin_context)
@ -107,7 +108,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code, expected_code=exc.HTTPOk.code,
admin_context=True): admin_context=True):
path = "/routers/%s/%s.%s" % (router_id, path = "/routers/%s/%s.%s" % (router_id,
agentscheduler.L3_AGENTS, l3agentscheduler.L3_AGENTS,
self.fmt) self.fmt)
return self._request_list(path, expected_code=expected_code, return self._request_list(path, expected_code=expected_code,
admin_context=admin_context) admin_context=admin_context)
@ -116,7 +117,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPOk.code, expected_code=exc.HTTPOk.code,
admin_context=True): admin_context=True):
path = "/networks/%s/%s.%s" % (network_id, path = "/networks/%s/%s.%s" % (network_id,
agentscheduler.DHCP_AGENTS, dhcpagentscheduler.DHCP_AGENTS,
self.fmt) self.fmt)
return self._request_list(path, expected_code=expected_code, return self._request_list(path, expected_code=expected_code,
admin_context=admin_context) admin_context=admin_context)
@ -125,7 +126,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPCreated.code, expected_code=exc.HTTPCreated.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s.%s" % (id, path = "/agents/%s/%s.%s" % (id,
agentscheduler.L3_ROUTERS, l3agentscheduler.L3_ROUTERS,
self.fmt) self.fmt)
req = self._path_create_request(path, req = self._path_create_request(path,
{'router_id': router_id}, {'router_id': router_id},
@ -137,7 +138,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPCreated.code, expected_code=exc.HTTPCreated.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s.%s" % (id, path = "/agents/%s/%s.%s" % (id,
agentscheduler.DHCP_NETS, dhcpagentscheduler.DHCP_NETS,
self.fmt) self.fmt)
req = self._path_create_request(path, req = self._path_create_request(path,
{'network_id': network_id}, {'network_id': network_id},
@ -149,7 +150,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPNoContent.code, expected_code=exc.HTTPNoContent.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s/%s.%s" % (id, path = "/agents/%s/%s/%s.%s" % (id,
agentscheduler.DHCP_NETS, dhcpagentscheduler.DHCP_NETS,
network_id, network_id,
self.fmt) self.fmt)
req = self._path_delete_request(path, req = self._path_delete_request(path,
@ -161,7 +162,7 @@ class AgentSchedulerTestMixIn(object):
expected_code=exc.HTTPNoContent.code, expected_code=exc.HTTPNoContent.code,
admin_context=True): admin_context=True):
path = "/agents/%s/%s/%s.%s" % (id, path = "/agents/%s/%s/%s.%s" % (id,
agentscheduler.L3_ROUTERS, l3agentscheduler.L3_ROUTERS,
router_id, router_id,
self.fmt) self.fmt)
req = self._path_delete_request(path, admin_context=admin_context) req = self._path_delete_request(path, admin_context=admin_context)