From 63fc967a8f7a1b6d3f7c99369decbd9e934877b4 Mon Sep 17 00:00:00 2001 From: tonytan4ever Date: Fri, 10 Jun 2016 14:32:35 -0400 Subject: [PATCH] Refactor NetworkDhcpAgentBinding This patch set is for breaking the circular dependency between Agent/NetworkDhcpAgentBinding. The goal of this is to implement Agent OVO Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Change-Id: I3f2a8bcc6f8644e94e377dc916fba6743cb230bc --- neutron/db/agentschedulers_db.py | 47 ++++++++----------- neutron/db/models_v2.py | 4 +- .../db/network_dhcp_agent_binding/__init__.py | 0 .../db/network_dhcp_agent_binding/models.py | 30 ++++++++++++ neutron/scheduler/dhcp_agent_scheduler.py | 4 +- .../scheduler/test_dhcp_agent_scheduler.py | 5 +- .../scheduler/test_dhcp_agent_scheduler.py | 23 ++++----- 7 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 neutron/db/network_dhcp_agent_binding/__init__.py create mode 100644 neutron/db/network_dhcp_agent_binding/models.py diff --git a/neutron/db/agentschedulers_db.py b/neutron/db/agentschedulers_db.py index 4438ebdc59f..0e26dc1edbd 100644 --- a/neutron/db/agentschedulers_db.py +++ b/neutron/db/agentschedulers_db.py @@ -34,6 +34,7 @@ from neutron.common import utils from neutron import context as ncontext from neutron.db import agents_db from neutron.db.availability_zone import network as network_az +from neutron.db.network_dhcp_agent_binding import models as ndab_model from neutron.db import model_base from neutron.extensions import agent as ext_agent from neutron.extensions import dhcpagentscheduler @@ -72,19 +73,6 @@ AGENTS_SCHEDULER_OPTS = [ cfg.CONF.register_opts(AGENTS_SCHEDULER_OPTS) -class NetworkDhcpAgentBinding(model_base.BASEV2): - """Represents binding between neutron networks and DHCP agents.""" - - network_id = sa.Column(sa.String(36), - sa.ForeignKey("networks.id", ondelete='CASCADE'), - primary_key=True) - dhcp_agent = orm.relation(agents_db.Agent) - dhcp_agent_id = sa.Column(sa.String(36), - sa.ForeignKey("agents.id", - ondelete='CASCADE'), - primary_key=True) - - class AgentStatusCheckWorker(neutron_worker.NeutronWorker): def __init__(self, check_func, interval, initial_delay): @@ -311,7 +299,8 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler """ agent_dead_limit = datetime.timedelta( seconds=self.agent_dead_limit_seconds()) - network_count = (context.session.query(NetworkDhcpAgentBinding). + network_count = (context.session.query(ndab_model. + NetworkDhcpAgentBinding). filter_by(dhcp_agent_id=agent['id']).count()) # amount of networks assigned to agent affect amount of time we give # it so startup. Tests show that it's more or less sage to assume @@ -393,7 +382,7 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler context = ncontext.get_admin_context() try: down_bindings = ( - context.session.query(NetworkDhcpAgentBinding). + context.session.query(ndab_model.NetworkDhcpAgentBinding). join(agents_db.Agent). filter(agents_db.Agent.heartbeat_timestamp < cutoff, agents_db.Agent.admin_state_up)) @@ -453,13 +442,13 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler self, context, network_ids, active=None, admin_state_up=None): if not network_ids: return [] - query = context.session.query(NetworkDhcpAgentBinding) + query = context.session.query(ndab_model.NetworkDhcpAgentBinding) query = query.options(orm.contains_eager( - NetworkDhcpAgentBinding.dhcp_agent)) - query = query.join(NetworkDhcpAgentBinding.dhcp_agent) + ndab_model.NetworkDhcpAgentBinding.dhcp_agent)) + query = query.join(ndab_model.NetworkDhcpAgentBinding.dhcp_agent) if network_ids: query = query.filter( - NetworkDhcpAgentBinding.network_id.in_(network_ids)) + ndab_model.NetworkDhcpAgentBinding.network_id.in_(network_ids)) if admin_state_up is not None: query = query.filter(agents_db.Agent.admin_state_up == admin_state_up) @@ -482,7 +471,7 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler if id == dhcp_agent.id: raise dhcpagentscheduler.NetworkHostedByDHCPAgent( network_id=network_id, agent_id=id) - binding = NetworkDhcpAgentBinding() + binding = ndab_model.NetworkDhcpAgentBinding() binding.dhcp_agent_id = id binding.network_id = network_id context.session.add(binding) @@ -495,10 +484,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler notify=True): agent = self._get_agent(context, id) try: - query = context.session.query(NetworkDhcpAgentBinding) + query = context.session.query(ndab_model.NetworkDhcpAgentBinding) binding = query.filter( - NetworkDhcpAgentBinding.network_id == network_id, - NetworkDhcpAgentBinding.dhcp_agent_id == id).one() + ndab_model.NetworkDhcpAgentBinding.network_id == network_id, + ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id).one() except exc.NoResultFound: raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent( network_id=network_id, agent_id=id) @@ -525,8 +514,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler 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) + query = context.session.query( + ndab_model.NetworkDhcpAgentBinding.network_id) + query = query.filter( + ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id) net_ids = [item[0] for item in query] if net_ids: @@ -547,8 +538,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler if not services_available(agent.admin_state_up): return [] - query = context.session.query(NetworkDhcpAgentBinding.network_id) - query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == agent.id) + query = context.session.query( + ndab_model.NetworkDhcpAgentBinding.network_id) + query = query.filter( + ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == agent.id) net_ids = [item[0] for item in query] if net_ids: diff --git a/neutron/db/models_v2.py b/neutron/db/models_v2.py index f5b39dbe55d..e4c1c74420d 100644 --- a/neutron/db/models_v2.py +++ b/neutron/db/models_v2.py @@ -19,7 +19,7 @@ from sqlalchemy import sql from neutron.api.v2 import attributes as attr from neutron.common import constants -from neutron.db import agentschedulers_db as agt +from neutron.db.network_dhcp_agent_binding import models as ndab_model from neutron.db import model_base from neutron.db import rbac_db_models @@ -283,4 +283,4 @@ class Network(model_base.HasStandardAttributes, model_base.BASEV2, availability_zone_hints = sa.Column(sa.String(255)) dhcp_agents = orm.relationship( 'Agent', lazy='joined', viewonly=True, - secondary=agt.NetworkDhcpAgentBinding.__table__) + secondary=ndab_model.NetworkDhcpAgentBinding.__table__) diff --git a/neutron/db/network_dhcp_agent_binding/__init__.py b/neutron/db/network_dhcp_agent_binding/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/neutron/db/network_dhcp_agent_binding/models.py b/neutron/db/network_dhcp_agent_binding/models.py new file mode 100644 index 00000000000..9f3b3c17158 --- /dev/null +++ b/neutron/db/network_dhcp_agent_binding/models.py @@ -0,0 +1,30 @@ +# 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. + +import sqlalchemy as sa +from sqlalchemy import orm + +from neutron.db import model_base +from neutron.db import agents_db + + +class NetworkDhcpAgentBinding(model_base.BASEV2): + """Represents binding between neutron networks and DHCP agents.""" + + network_id = sa.Column(sa.String(36), + sa.ForeignKey("networks.id", ondelete='CASCADE'), + primary_key=True) + dhcp_agent = orm.relation(agents_db.Agent) + dhcp_agent_id = sa.Column(sa.String(36), + sa.ForeignKey("agents.id", + ondelete='CASCADE'), + primary_key=True) diff --git a/neutron/scheduler/dhcp_agent_scheduler.py b/neutron/scheduler/dhcp_agent_scheduler.py index 416f0b79473..79b8bff83c9 100644 --- a/neutron/scheduler/dhcp_agent_scheduler.py +++ b/neutron/scheduler/dhcp_agent_scheduler.py @@ -24,8 +24,8 @@ from oslo_log import log as logging from sqlalchemy import sql from neutron._i18n import _LI, _LW +from neutron.db.network_dhcp_agent_binding import models as ndab_model from neutron.db import agents_db -from neutron.db import agentschedulers_db from neutron.db import api as db_api from neutron.extensions import availability_zone as az_ext from neutron.scheduler import base_resource_filter @@ -164,7 +164,7 @@ class DhcpFilter(base_resource_filter.BaseResourceFilter): # saving agent_id to use it after rollback to avoid # DetachedInstanceError agent_id = agent.id - binding = agentschedulers_db.NetworkDhcpAgentBinding() + binding = ndab_model.NetworkDhcpAgentBinding() binding.dhcp_agent_id = agent_id binding.network_id = network_id try: diff --git a/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py b/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py index 784d8c08f16..5ac109a51a6 100644 --- a/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py +++ b/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py @@ -21,6 +21,7 @@ import six import testscenarios from neutron import context +from neutron.db.network_dhcp_agent_binding import models as ndab_model from neutron.db import agents_db from neutron.db import agentschedulers_db from neutron.db import common_db_mixin @@ -374,9 +375,9 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase, def _get_hosted_networks_on_dhcp_agent(self, agent_id): query = self.ctx.session.query( - agentschedulers_db.NetworkDhcpAgentBinding.network_id) + ndab_model.NetworkDhcpAgentBinding.network_id) query = query.filter( - agentschedulers_db.NetworkDhcpAgentBinding.dhcp_agent_id == + ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == agent_id) return [item[0] for item in query] diff --git a/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py b/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py index 27468bfb1d6..4cca0a67cdc 100644 --- a/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py +++ b/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py @@ -22,6 +22,7 @@ from oslo_utils import importutils import testscenarios from neutron import context +from neutron.db.network_dhcp_agent_binding import models as ndab_model from neutron.db import agentschedulers_db as sched_db from neutron.db import common_db_mixin from neutron.db import models_v2 @@ -69,7 +70,7 @@ class TestDhcpSchedulerBaseTestCase(testlib_api.SqlTestCase): scheduler = dhcp_agent_scheduler.ChanceScheduler() scheduler.resource_filter.bind(self.ctx, agents, network_id) results = self.ctx.session.query( - sched_db.NetworkDhcpAgentBinding).filter_by( + ndab_model.NetworkDhcpAgentBinding).filter_by( network_id=network_id).all() self.assertEqual(len(agents), len(results)) for result in results: @@ -132,7 +133,7 @@ class TestDhcpScheduler(TestDhcpSchedulerBaseTestCase): def _get_agent_binding_from_db(self, agent): return self.ctx.session.query( - sched_db.NetworkDhcpAgentBinding + ndab_model.NetworkDhcpAgentBinding ).filter_by(dhcp_agent_id=agent[0].id).all() def _test_auto_reschedule_vs_network_on_dead_agent(self, @@ -285,7 +286,7 @@ class TestAutoScheduleNetworks(TestDhcpSchedulerBaseTestCase): plugin, self.ctx, host) self.assertEqual(expected_result, observed_ret_value) hosted_agents = self.ctx.session.query( - sched_db.NetworkDhcpAgentBinding).all() + ndab_model.NetworkDhcpAgentBinding).all() self.assertEqual(expected_hosted_agents, len(hosted_agents)) @@ -345,14 +346,14 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase, def test_filter_bindings(self): bindings = [ - sched_db.NetworkDhcpAgentBinding(network_id='foo1', - dhcp_agent={'id': 'id1'}), - sched_db.NetworkDhcpAgentBinding(network_id='foo2', - dhcp_agent={'id': 'id1'}), - sched_db.NetworkDhcpAgentBinding(network_id='foo3', - dhcp_agent={'id': 'id2'}), - sched_db.NetworkDhcpAgentBinding(network_id='foo4', - dhcp_agent={'id': 'id2'})] + ndab_model.NetworkDhcpAgentBinding(network_id='foo1', + dhcp_agent={'id': 'id1'}), + ndab_model.NetworkDhcpAgentBinding(network_id='foo2', + dhcp_agent={'id': 'id1'}), + ndab_model.NetworkDhcpAgentBinding(network_id='foo3', + dhcp_agent={'id': 'id2'}), + ndab_model.NetworkDhcpAgentBinding(network_id='foo4', + dhcp_agent={'id': 'id2'})] with mock.patch.object(self, 'agent_starting_up', side_effect=[True, False]): res = [b for b in self._filter_bindings(None, bindings)]