From: Oleg Bondarev Date: Tue, 2 Jul 2013 08:08:52 +0000 (+0400) Subject: Divide dhcp and l3 agent scheduling into separate extensions X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=0471248b97cd2b743d80701038e43aed9ab8b35d;p=openstack-build%2Fneutron-build.git 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 --- diff --git a/neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py b/neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py index 6c7a531f4..1086a9e58 100644 --- a/neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py +++ b/neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py @@ -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 diff --git a/neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py b/neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py index 557cffeea..28fea4c24 100644 --- a/neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py +++ b/neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py @@ -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) diff --git a/neutron/common/constants.py b/neutron/common/constants.py index 06b0c53d2..a6a5e99e4 100644 --- a/neutron/common/constants.py +++ b/neutron/common/constants.py @@ -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' diff --git a/neutron/db/agentschedulers_db.py b/neutron/db/agentschedulers_db.py index f20e4c956..964b1d20a 100644 --- a/neutron/db/agentschedulers_db.py +++ b/neutron/db/agentschedulers_db.py @@ -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)) - - 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) - - 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 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 - 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 [] +class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase, + AgentSchedulerDbMixin): + """Mixin class to add l3 agent scheduler extension to db_plugin_base_v2.""" - 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) diff --git a/neutron/db/dhcp_rpc_base.py b/neutron/db/dhcp_rpc_base.py index 353f09f31..60858328f 100644 --- a/neutron/db/dhcp_rpc_base.py +++ b/neutron/db/dhcp_rpc_base.py @@ -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( diff --git a/neutron/db/l3_rpc_base.py b/neutron/db/l3_rpc_base.py index 193681990..4b1387187 100644 --- a/neutron/db/l3_rpc_base.py +++ b/neutron/db/l3_rpc_base.py @@ -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( diff --git a/neutron/extensions/dhcpagentscheduler.py b/neutron/extensions/dhcpagentscheduler.py new file mode 100644 index 000000000..994ad8eb1 --- /dev/null +++ b/neutron/extensions/dhcpagentscheduler.py @@ -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 diff --git a/neutron/extensions/agentscheduler.py b/neutron/extensions/l3agentscheduler.py similarity index 57% rename from neutron/extensions/agentscheduler.py rename to neutron/extensions/l3agentscheduler.py index f30156cc8..d851cb0e2 100644 --- a/neutron/extensions/agentscheduler.py +++ b/neutron/extensions/l3agentscheduler.py @@ -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 diff --git a/neutron/plugins/brocade/NeutronPlugin.py b/neutron/plugins/brocade/NeutronPlugin.py index 04ed7fb29..137fb979e 100644 --- a/neutron/plugins/brocade/NeutronPlugin.py +++ b/neutron/plugins/brocade/NeutronPlugin.py @@ -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) diff --git a/neutron/plugins/linuxbridge/lb_neutron_plugin.py b/neutron/plugins/linuxbridge/lb_neutron_plugin.py index 4d7c5cd8e..db9e8c88e 100644 --- a/neutron/plugins/linuxbridge/lb_neutron_plugin.py +++ b/neutron/plugins/linuxbridge/lb_neutron_plugin.py @@ -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): diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index c30dbff63..942b09523 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -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): diff --git a/neutron/plugins/nec/nec_plugin.py b/neutron/plugins/nec/nec_plugin.py index d3444e4e2..144f6da67 100644 --- a/neutron/plugins/nec/nec_plugin.py +++ b/neutron/plugins/nec/nec_plugin.py @@ -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): diff --git a/neutron/plugins/nicira/NeutronPlugin.py b/neutron/plugins/nicira/NeutronPlugin.py index acb933e04..eeebb24bc 100644 --- a/neutron/plugins/nicira/NeutronPlugin.py +++ b/neutron/plugins/nicira/NeutronPlugin.py @@ -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 diff --git a/neutron/plugins/openvswitch/ovs_neutron_plugin.py b/neutron/plugins/openvswitch/ovs_neutron_plugin.py index b98892966..14194e974 100644 --- a/neutron/plugins/openvswitch/ovs_neutron_plugin.py +++ b/neutron/plugins/openvswitch/ovs_neutron_plugin.py @@ -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): diff --git a/neutron/tests/unit/openvswitch/test_agent_scheduler.py b/neutron/tests/unit/openvswitch/test_agent_scheduler.py index 8dbe0c1d3..c4c7ac3cb 100644 --- a/neutron/tests/unit/openvswitch/test_agent_scheduler.py +++ b/neutron/tests/unit/openvswitch/test_agent_scheduler.py @@ -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)