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
This commit is contained in:
parent
77e03443ff
commit
63fc967a8f
|
@ -34,6 +34,7 @@ from neutron.common import utils
|
||||||
from neutron import context as ncontext
|
from neutron import context as ncontext
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
from neutron.db.availability_zone import network as network_az
|
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.db import model_base
|
||||||
from neutron.extensions import agent as ext_agent
|
from neutron.extensions import agent as ext_agent
|
||||||
from neutron.extensions import dhcpagentscheduler
|
from neutron.extensions import dhcpagentscheduler
|
||||||
|
@ -72,19 +73,6 @@ AGENTS_SCHEDULER_OPTS = [
|
||||||
cfg.CONF.register_opts(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):
|
class AgentStatusCheckWorker(neutron_worker.NeutronWorker):
|
||||||
|
|
||||||
def __init__(self, check_func, interval, initial_delay):
|
def __init__(self, check_func, interval, initial_delay):
|
||||||
|
@ -311,7 +299,8 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
"""
|
"""
|
||||||
agent_dead_limit = datetime.timedelta(
|
agent_dead_limit = datetime.timedelta(
|
||||||
seconds=self.agent_dead_limit_seconds())
|
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())
|
filter_by(dhcp_agent_id=agent['id']).count())
|
||||||
# amount of networks assigned to agent affect amount of time we give
|
# 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
|
# 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()
|
context = ncontext.get_admin_context()
|
||||||
try:
|
try:
|
||||||
down_bindings = (
|
down_bindings = (
|
||||||
context.session.query(NetworkDhcpAgentBinding).
|
context.session.query(ndab_model.NetworkDhcpAgentBinding).
|
||||||
join(agents_db.Agent).
|
join(agents_db.Agent).
|
||||||
filter(agents_db.Agent.heartbeat_timestamp < cutoff,
|
filter(agents_db.Agent.heartbeat_timestamp < cutoff,
|
||||||
agents_db.Agent.admin_state_up))
|
agents_db.Agent.admin_state_up))
|
||||||
|
@ -453,13 +442,13 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
self, context, network_ids, active=None, admin_state_up=None):
|
self, context, network_ids, active=None, admin_state_up=None):
|
||||||
if not network_ids:
|
if not network_ids:
|
||||||
return []
|
return []
|
||||||
query = context.session.query(NetworkDhcpAgentBinding)
|
query = context.session.query(ndab_model.NetworkDhcpAgentBinding)
|
||||||
query = query.options(orm.contains_eager(
|
query = query.options(orm.contains_eager(
|
||||||
NetworkDhcpAgentBinding.dhcp_agent))
|
ndab_model.NetworkDhcpAgentBinding.dhcp_agent))
|
||||||
query = query.join(NetworkDhcpAgentBinding.dhcp_agent)
|
query = query.join(ndab_model.NetworkDhcpAgentBinding.dhcp_agent)
|
||||||
if network_ids:
|
if network_ids:
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
NetworkDhcpAgentBinding.network_id.in_(network_ids))
|
ndab_model.NetworkDhcpAgentBinding.network_id.in_(network_ids))
|
||||||
if admin_state_up is not None:
|
if admin_state_up is not None:
|
||||||
query = query.filter(agents_db.Agent.admin_state_up ==
|
query = query.filter(agents_db.Agent.admin_state_up ==
|
||||||
admin_state_up)
|
admin_state_up)
|
||||||
|
@ -482,7 +471,7 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
if id == dhcp_agent.id:
|
if id == dhcp_agent.id:
|
||||||
raise dhcpagentscheduler.NetworkHostedByDHCPAgent(
|
raise dhcpagentscheduler.NetworkHostedByDHCPAgent(
|
||||||
network_id=network_id, agent_id=id)
|
network_id=network_id, agent_id=id)
|
||||||
binding = NetworkDhcpAgentBinding()
|
binding = ndab_model.NetworkDhcpAgentBinding()
|
||||||
binding.dhcp_agent_id = id
|
binding.dhcp_agent_id = id
|
||||||
binding.network_id = network_id
|
binding.network_id = network_id
|
||||||
context.session.add(binding)
|
context.session.add(binding)
|
||||||
|
@ -495,10 +484,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
notify=True):
|
notify=True):
|
||||||
agent = self._get_agent(context, id)
|
agent = self._get_agent(context, id)
|
||||||
try:
|
try:
|
||||||
query = context.session.query(NetworkDhcpAgentBinding)
|
query = context.session.query(ndab_model.NetworkDhcpAgentBinding)
|
||||||
binding = query.filter(
|
binding = query.filter(
|
||||||
NetworkDhcpAgentBinding.network_id == network_id,
|
ndab_model.NetworkDhcpAgentBinding.network_id == network_id,
|
||||||
NetworkDhcpAgentBinding.dhcp_agent_id == id).one()
|
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id).one()
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
||||||
network_id=network_id, agent_id=id)
|
network_id=network_id, agent_id=id)
|
||||||
|
@ -525,8 +514,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
context, network_id, agent.host)
|
context, network_id, agent.host)
|
||||||
|
|
||||||
def list_networks_on_dhcp_agent(self, context, id):
|
def list_networks_on_dhcp_agent(self, context, id):
|
||||||
query = context.session.query(NetworkDhcpAgentBinding.network_id)
|
query = context.session.query(
|
||||||
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == id)
|
ndab_model.NetworkDhcpAgentBinding.network_id)
|
||||||
|
query = query.filter(
|
||||||
|
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id)
|
||||||
|
|
||||||
net_ids = [item[0] for item in query]
|
net_ids = [item[0] for item in query]
|
||||||
if net_ids:
|
if net_ids:
|
||||||
|
@ -547,8 +538,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
||||||
|
|
||||||
if not services_available(agent.admin_state_up):
|
if not services_available(agent.admin_state_up):
|
||||||
return []
|
return []
|
||||||
query = context.session.query(NetworkDhcpAgentBinding.network_id)
|
query = context.session.query(
|
||||||
query = query.filter(NetworkDhcpAgentBinding.dhcp_agent_id == agent.id)
|
ndab_model.NetworkDhcpAgentBinding.network_id)
|
||||||
|
query = query.filter(
|
||||||
|
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == agent.id)
|
||||||
|
|
||||||
net_ids = [item[0] for item in query]
|
net_ids = [item[0] for item in query]
|
||||||
if net_ids:
|
if net_ids:
|
||||||
|
|
|
@ -19,7 +19,7 @@ from sqlalchemy import sql
|
||||||
|
|
||||||
from neutron.api.v2 import attributes as attr
|
from neutron.api.v2 import attributes as attr
|
||||||
from neutron.common import constants
|
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 model_base
|
||||||
from neutron.db import rbac_db_models
|
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))
|
availability_zone_hints = sa.Column(sa.String(255))
|
||||||
dhcp_agents = orm.relationship(
|
dhcp_agents = orm.relationship(
|
||||||
'Agent', lazy='joined', viewonly=True,
|
'Agent', lazy='joined', viewonly=True,
|
||||||
secondary=agt.NetworkDhcpAgentBinding.__table__)
|
secondary=ndab_model.NetworkDhcpAgentBinding.__table__)
|
||||||
|
|
|
@ -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)
|
|
@ -24,8 +24,8 @@ from oslo_log import log as logging
|
||||||
from sqlalchemy import sql
|
from sqlalchemy import sql
|
||||||
|
|
||||||
from neutron._i18n import _LI, _LW
|
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 agents_db
|
||||||
from neutron.db import agentschedulers_db
|
|
||||||
from neutron.db import api as db_api
|
from neutron.db import api as db_api
|
||||||
from neutron.extensions import availability_zone as az_ext
|
from neutron.extensions import availability_zone as az_ext
|
||||||
from neutron.scheduler import base_resource_filter
|
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
|
# saving agent_id to use it after rollback to avoid
|
||||||
# DetachedInstanceError
|
# DetachedInstanceError
|
||||||
agent_id = agent.id
|
agent_id = agent.id
|
||||||
binding = agentschedulers_db.NetworkDhcpAgentBinding()
|
binding = ndab_model.NetworkDhcpAgentBinding()
|
||||||
binding.dhcp_agent_id = agent_id
|
binding.dhcp_agent_id = agent_id
|
||||||
binding.network_id = network_id
|
binding.network_id = network_id
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -21,6 +21,7 @@ import six
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
|
||||||
from neutron import context
|
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 agents_db
|
||||||
from neutron.db import agentschedulers_db
|
from neutron.db import agentschedulers_db
|
||||||
from neutron.db import common_db_mixin
|
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):
|
def _get_hosted_networks_on_dhcp_agent(self, agent_id):
|
||||||
query = self.ctx.session.query(
|
query = self.ctx.session.query(
|
||||||
agentschedulers_db.NetworkDhcpAgentBinding.network_id)
|
ndab_model.NetworkDhcpAgentBinding.network_id)
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
agentschedulers_db.NetworkDhcpAgentBinding.dhcp_agent_id ==
|
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id ==
|
||||||
agent_id)
|
agent_id)
|
||||||
|
|
||||||
return [item[0] for item in query]
|
return [item[0] for item in query]
|
||||||
|
|
|
@ -22,6 +22,7 @@ from oslo_utils import importutils
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
|
||||||
from neutron import context
|
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 agentschedulers_db as sched_db
|
||||||
from neutron.db import common_db_mixin
|
from neutron.db import common_db_mixin
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
|
@ -69,7 +70,7 @@ class TestDhcpSchedulerBaseTestCase(testlib_api.SqlTestCase):
|
||||||
scheduler = dhcp_agent_scheduler.ChanceScheduler()
|
scheduler = dhcp_agent_scheduler.ChanceScheduler()
|
||||||
scheduler.resource_filter.bind(self.ctx, agents, network_id)
|
scheduler.resource_filter.bind(self.ctx, agents, network_id)
|
||||||
results = self.ctx.session.query(
|
results = self.ctx.session.query(
|
||||||
sched_db.NetworkDhcpAgentBinding).filter_by(
|
ndab_model.NetworkDhcpAgentBinding).filter_by(
|
||||||
network_id=network_id).all()
|
network_id=network_id).all()
|
||||||
self.assertEqual(len(agents), len(results))
|
self.assertEqual(len(agents), len(results))
|
||||||
for result in results:
|
for result in results:
|
||||||
|
@ -132,7 +133,7 @@ class TestDhcpScheduler(TestDhcpSchedulerBaseTestCase):
|
||||||
|
|
||||||
def _get_agent_binding_from_db(self, agent):
|
def _get_agent_binding_from_db(self, agent):
|
||||||
return self.ctx.session.query(
|
return self.ctx.session.query(
|
||||||
sched_db.NetworkDhcpAgentBinding
|
ndab_model.NetworkDhcpAgentBinding
|
||||||
).filter_by(dhcp_agent_id=agent[0].id).all()
|
).filter_by(dhcp_agent_id=agent[0].id).all()
|
||||||
|
|
||||||
def _test_auto_reschedule_vs_network_on_dead_agent(self,
|
def _test_auto_reschedule_vs_network_on_dead_agent(self,
|
||||||
|
@ -285,7 +286,7 @@ class TestAutoScheduleNetworks(TestDhcpSchedulerBaseTestCase):
|
||||||
plugin, self.ctx, host)
|
plugin, self.ctx, host)
|
||||||
self.assertEqual(expected_result, observed_ret_value)
|
self.assertEqual(expected_result, observed_ret_value)
|
||||||
hosted_agents = self.ctx.session.query(
|
hosted_agents = self.ctx.session.query(
|
||||||
sched_db.NetworkDhcpAgentBinding).all()
|
ndab_model.NetworkDhcpAgentBinding).all()
|
||||||
self.assertEqual(expected_hosted_agents, len(hosted_agents))
|
self.assertEqual(expected_hosted_agents, len(hosted_agents))
|
||||||
|
|
||||||
|
|
||||||
|
@ -345,14 +346,14 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase,
|
||||||
|
|
||||||
def test_filter_bindings(self):
|
def test_filter_bindings(self):
|
||||||
bindings = [
|
bindings = [
|
||||||
sched_db.NetworkDhcpAgentBinding(network_id='foo1',
|
ndab_model.NetworkDhcpAgentBinding(network_id='foo1',
|
||||||
dhcp_agent={'id': 'id1'}),
|
dhcp_agent={'id': 'id1'}),
|
||||||
sched_db.NetworkDhcpAgentBinding(network_id='foo2',
|
ndab_model.NetworkDhcpAgentBinding(network_id='foo2',
|
||||||
dhcp_agent={'id': 'id1'}),
|
dhcp_agent={'id': 'id1'}),
|
||||||
sched_db.NetworkDhcpAgentBinding(network_id='foo3',
|
ndab_model.NetworkDhcpAgentBinding(network_id='foo3',
|
||||||
dhcp_agent={'id': 'id2'}),
|
dhcp_agent={'id': 'id2'}),
|
||||||
sched_db.NetworkDhcpAgentBinding(network_id='foo4',
|
ndab_model.NetworkDhcpAgentBinding(network_id='foo4',
|
||||||
dhcp_agent={'id': 'id2'})]
|
dhcp_agent={'id': 'id2'})]
|
||||||
with mock.patch.object(self, 'agent_starting_up',
|
with mock.patch.object(self, 'agent_starting_up',
|
||||||
side_effect=[True, False]):
|
side_effect=[True, False]):
|
||||||
res = [b for b in self._filter_bindings(None, bindings)]
|
res = [b for b in self._filter_bindings(None, bindings)]
|
||||||
|
|
Loading…
Reference in New Issue