]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Divide dhcp and l3 agent scheduling into separate extensions
authorOleg Bondarev <obondarev@mirantis.com>
Tue, 2 Jul 2013 08:08:52 +0000 (12:08 +0400)
committerOleg Bondarev <obondarev@mirantis.com>
Mon, 8 Jul 2013 08:29:02 +0000 (12:29 +0400)
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

15 files changed:
neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py
neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py
neutron/common/constants.py
neutron/db/agentschedulers_db.py
neutron/db/dhcp_rpc_base.py
neutron/db/l3_rpc_base.py
neutron/extensions/dhcpagentscheduler.py [new file with mode: 0644]
neutron/extensions/l3agentscheduler.py [moved from neutron/extensions/agentscheduler.py with 57% similarity]
neutron/plugins/brocade/NeutronPlugin.py
neutron/plugins/linuxbridge/lb_neutron_plugin.py
neutron/plugins/ml2/plugin.py
neutron/plugins/nec/nec_plugin.py
neutron/plugins/nicira/NeutronPlugin.py
neutron/plugins/openvswitch/ovs_neutron_plugin.py
neutron/tests/unit/openvswitch/test_agent_scheduler.py

index 6c7a531f409e9fe62e1414c9ab60ae465bc056c1..1086a9e58b6e57739db45daee8bdaefaded12770 100644 (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
index 557cffeea5ee61a995a98b596acf4de10182a8f1..28fea4c2401cc77d7b9ac975d45552ec70ebe93b 100644 (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)
index 06b0c53d2c3aa44abb9fb9e11d0030e3e4feabb1..a6a5e99e42d38291ee948061302b83f73914d4cc 100644 (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'
index f20e4c9563a84b095cdddf8ed2e8066d0ba49091..964b1d20af5937a53966a8a269312ba933537742 100644 (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))
-
-        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)
index 353f09f3100cfe6f0d65ba2465ceee87ea4becff..60858328f561dca23af2ea43004e763b2faffcb9 100644 (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(
index 193681990a252ba3d24ecf5e663f0aaeb23b1b96..4b1387187860d4abb52569a3cc3f2127f64161fb 100644 (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(
diff --git a/neutron/extensions/dhcpagentscheduler.py b/neutron/extensions/dhcpagentscheduler.py
new file mode 100644 (file)
index 0000000..994ad8e
--- /dev/null
@@ -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
similarity index 57%
rename from neutron/extensions/agentscheduler.py
rename to neutron/extensions/l3agentscheduler.py
index f30156cc86bedc3d120fbf97e991056e56925ec2..d851cb0e2b5231d9a2045e40b4de57d8c4cdbae2 100644 (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
index 04ed7fb29d08d270a903eca0d17d580cacbe4074..137fb979eef714af656de1c6d088acc3af9da034 100644 (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)
index 4d7c5cd8ec67c9631a0903ced0cc20833cf45bae..db9e8c88efcbae507b7206008b10d0112f65f5d0 100644 (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):
index c30dbff63f8af7460a7dc870daf173f0f4c7acf7..942b0952361817f208bd71db1626ccc2f57bc2c8 100644 (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):
index d3444e4e28936ad2c0f701d08f43f384ef51aadf..144f6da67e4aae851e049f4482b17b0970566a04 100644 (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):
index acb933e047374d534e83906226431a27775fe1ba..eeebb24bc335490a5436651ccae8fec3287e011a 100644 (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
index b98892966d746d102748ffe7a5d842ddc61e43c7..14194e974b5eaba256dbabf6a336601b3fac5437 100644 (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):
index 8dbe0c1d31fdb1bf25fd9e6aadecb73a677150cf..c4c7ac3cbbd18d52698e9c62f3bf6e0c9f199e25 100644 (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)