Merge "OVO for NetworkDhcpAgentBinding"
This commit is contained in:
commit
e03744c335
@ -23,7 +23,6 @@ from oslo_config import cfg
|
|||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
import oslo_messaging
|
import oslo_messaging
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
from sqlalchemy import orm
|
|
||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from neutron._i18n import _
|
from neutron._i18n import _
|
||||||
@ -32,10 +31,9 @@ from neutron.common import constants as n_const
|
|||||||
from neutron.common import utils
|
from neutron.common import utils
|
||||||
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.models import agent as agent_model
|
|
||||||
from neutron.db.network_dhcp_agent_binding import models as ndab_model
|
|
||||||
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
|
||||||
|
from neutron.objects import network
|
||||||
from neutron import worker as neutron_worker
|
from neutron import worker as neutron_worker
|
||||||
|
|
||||||
|
|
||||||
@ -234,9 +232,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(ndab_model.
|
network_count = network.NetworkDhcpAgentBinding.count(
|
||||||
NetworkDhcpAgentBinding).
|
context, dhcp_agent_id=agent['id'])
|
||||||
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
|
||||||
# that DHCP agent processes each network in less than 2 seconds.
|
# that DHCP agent processes each network in less than 2 seconds.
|
||||||
@ -285,9 +282,10 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
|||||||
checked_agents = {}
|
checked_agents = {}
|
||||||
for binding in bindings:
|
for binding in bindings:
|
||||||
try:
|
try:
|
||||||
agent_id = binding.dhcp_agent['id']
|
agent_id = binding.db_obj.dhcp_agent['id']
|
||||||
if agent_id not in checked_agents:
|
if agent_id not in checked_agents:
|
||||||
if self.agent_starting_up(context, binding.dhcp_agent):
|
if self.agent_starting_up(context,
|
||||||
|
binding.db_obj.dhcp_agent):
|
||||||
# When agent starts and it has many networks to process
|
# When agent starts and it has many networks to process
|
||||||
# it may fail to send state reports in defined interval
|
# it may fail to send state reports in defined interval
|
||||||
# The server will consider it dead and try to remove
|
# The server will consider it dead and try to remove
|
||||||
@ -316,11 +314,8 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
|||||||
|
|
||||||
context = ncontext.get_admin_context()
|
context = ncontext.get_admin_context()
|
||||||
try:
|
try:
|
||||||
down_bindings = (
|
down_bindings = network.NetworkDhcpAgentBinding.get_down_bindings(
|
||||||
context.session.query(ndab_model.NetworkDhcpAgentBinding).
|
context, cutoff)
|
||||||
join(agent_model.Agent).
|
|
||||||
filter(agent_model.Agent.heartbeat_timestamp < cutoff,
|
|
||||||
agent_model.Agent.admin_state_up))
|
|
||||||
dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP)
|
dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP)
|
||||||
dead_bindings = [b for b in
|
dead_bindings = [b for b in
|
||||||
self._filter_bindings(context, down_bindings)]
|
self._filter_bindings(context, down_bindings)]
|
||||||
@ -381,23 +376,23 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
|||||||
hosts=None):
|
hosts=None):
|
||||||
if not network_ids:
|
if not network_ids:
|
||||||
return []
|
return []
|
||||||
query = context.session.query(ndab_model.NetworkDhcpAgentBinding)
|
# get all the NDAB objects, which will also fetch (from DB)
|
||||||
query = query.options(orm.contains_eager(
|
# the related dhcp_agent objects because of the synthetic field
|
||||||
ndab_model.NetworkDhcpAgentBinding.dhcp_agent))
|
bindings = network.NetworkDhcpAgentBinding.get_objects(
|
||||||
query = query.join(ndab_model.NetworkDhcpAgentBinding.dhcp_agent)
|
context, network_id=network_ids)
|
||||||
if network_ids:
|
# get the already fetched dhcp_agent objects
|
||||||
query = query.filter(
|
agent_objs = [binding.db_obj.dhcp_agent for binding in bindings]
|
||||||
ndab_model.NetworkDhcpAgentBinding.network_id.in_(network_ids))
|
# filter the dhcp_agent objects on admin_state_up
|
||||||
if hosts:
|
|
||||||
query = query.filter(agent_model.Agent.host.in_(hosts))
|
|
||||||
if admin_state_up is not None:
|
if admin_state_up is not None:
|
||||||
query = query.filter(agent_model.Agent.admin_state_up ==
|
agent_objs = [agent for agent in agent_objs
|
||||||
admin_state_up)
|
if agent.admin_state_up == admin_state_up]
|
||||||
|
# filter the dhcp_agent objects on hosts
|
||||||
return [binding.dhcp_agent
|
if hosts:
|
||||||
for binding in query
|
agent_objs = [agent for agent in agent_objs
|
||||||
if self.is_eligible_agent(context, active,
|
if agent.host in hosts]
|
||||||
binding.dhcp_agent)]
|
# finally filter if the agents are eligible
|
||||||
|
return [agent for agent in agent_objs
|
||||||
|
if self.is_eligible_agent(context, active, agent)]
|
||||||
|
|
||||||
def add_network_to_dhcp_agent(self, context, id, network_id):
|
def add_network_to_dhcp_agent(self, context, id, network_id):
|
||||||
self._get_network(context, network_id)
|
self._get_network(context, network_id)
|
||||||
@ -412,10 +407,8 @@ 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 = ndab_model.NetworkDhcpAgentBinding()
|
network.NetworkDhcpAgentBinding(context, dhcp_agent_id=id,
|
||||||
binding.dhcp_agent_id = id
|
network_id=network_id).create()
|
||||||
binding.network_id = network_id
|
|
||||||
context.session.add(binding)
|
|
||||||
dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP)
|
dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP)
|
||||||
if dhcp_notifier:
|
if dhcp_notifier:
|
||||||
dhcp_notifier.network_added_to_agent(
|
dhcp_notifier.network_added_to_agent(
|
||||||
@ -424,12 +417,9 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
|||||||
def remove_network_from_dhcp_agent(self, context, id, network_id,
|
def remove_network_from_dhcp_agent(self, context, id, network_id,
|
||||||
notify=True):
|
notify=True):
|
||||||
agent = self._get_agent(context, id)
|
agent = self._get_agent(context, id)
|
||||||
try:
|
binding_obj = network.NetworkDhcpAgentBinding.get_object(
|
||||||
query = context.session.query(ndab_model.NetworkDhcpAgentBinding)
|
context, network_id=network_id, dhcp_agent_id=id)
|
||||||
binding = query.filter(
|
if not binding_obj:
|
||||||
ndab_model.NetworkDhcpAgentBinding.network_id == network_id,
|
|
||||||
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id).one()
|
|
||||||
except exc.NoResultFound:
|
|
||||||
raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
raise dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
||||||
network_id=network_id, agent_id=id)
|
network_id=network_id, agent_id=id)
|
||||||
|
|
||||||
@ -444,8 +434,7 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler
|
|||||||
for port in ports:
|
for port in ports:
|
||||||
port['device_id'] = n_const.DEVICE_ID_RESERVED_DHCP_PORT
|
port['device_id'] = n_const.DEVICE_ID_RESERVED_DHCP_PORT
|
||||||
self.update_port(context, port['id'], dict(port=port))
|
self.update_port(context, port['id'], dict(port=port))
|
||||||
with context.session.begin():
|
binding_obj.delete()
|
||||||
context.session.delete(binding)
|
|
||||||
|
|
||||||
if not notify:
|
if not notify:
|
||||||
return
|
return
|
||||||
@ -455,12 +444,9 @@ 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(
|
objs = network.NetworkDhcpAgentBinding.get_objects(context,
|
||||||
ndab_model.NetworkDhcpAgentBinding.network_id)
|
dhcp_agent_id=id)
|
||||||
query = query.filter(
|
net_ids = [item.network_id for item in objs]
|
||||||
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == id)
|
|
||||||
|
|
||||||
net_ids = [item[0] for item in query]
|
|
||||||
if net_ids:
|
if net_ids:
|
||||||
return {'networks':
|
return {'networks':
|
||||||
self.get_networks(context, filters={'id': net_ids})}
|
self.get_networks(context, filters={'id': net_ids})}
|
||||||
@ -479,12 +465,11 @@ 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(
|
|
||||||
ndab_model.NetworkDhcpAgentBinding.network_id)
|
|
||||||
query = query.filter(
|
|
||||||
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id == agent.id)
|
|
||||||
|
|
||||||
net_ids = [item[0] for item in query]
|
query = network.NetworkDhcpAgentBinding.get_objects(
|
||||||
|
context, dhcp_agent_id=agent.id)
|
||||||
|
|
||||||
|
net_ids = [item.network_id for item in query]
|
||||||
if net_ids:
|
if net_ids:
|
||||||
return self.get_networks(
|
return self.get_networks(
|
||||||
context,
|
context,
|
||||||
|
@ -23,7 +23,7 @@ class NetworkDhcpAgentBinding(model_base.BASEV2):
|
|||||||
network_id = sa.Column(sa.String(36),
|
network_id = sa.Column(sa.String(36),
|
||||||
sa.ForeignKey("networks.id", ondelete='CASCADE'),
|
sa.ForeignKey("networks.id", ondelete='CASCADE'),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
dhcp_agent = orm.relation(agent_model.Agent)
|
dhcp_agent = orm.relation(agent_model.Agent, lazy='subquery')
|
||||||
dhcp_agent_id = sa.Column(sa.String(36),
|
dhcp_agent_id = sa.Column(sa.String(36),
|
||||||
sa.ForeignKey("agents.id",
|
sa.ForeignKey("agents.id",
|
||||||
ondelete='CASCADE'),
|
ondelete='CASCADE'),
|
||||||
|
@ -20,9 +20,11 @@ from neutron.db.models import dns as dns_models
|
|||||||
from neutron.db.models import external_net as ext_net_model
|
from neutron.db.models import external_net as ext_net_model
|
||||||
from neutron.db.models import segment as segment_model
|
from neutron.db.models import segment as segment_model
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
|
from neutron.db.network_dhcp_agent_binding import models as ndab_models
|
||||||
from neutron.db.port_security import models as ps_models
|
from neutron.db.port_security import models as ps_models
|
||||||
from neutron.db import rbac_db_models
|
from neutron.db import rbac_db_models
|
||||||
from neutron.extensions import availability_zone as az_ext
|
from neutron.extensions import availability_zone as az_ext
|
||||||
|
from neutron.objects import agent as agent_obj
|
||||||
from neutron.objects import base
|
from neutron.objects import base
|
||||||
from neutron.objects import common_types
|
from neutron.objects import common_types
|
||||||
from neutron.objects.extensions import port_security as base_ps
|
from neutron.objects.extensions import port_security as base_ps
|
||||||
@ -30,6 +32,30 @@ from neutron.objects.qos import binding
|
|||||||
from neutron.objects import rbac_db
|
from neutron.objects import rbac_db
|
||||||
|
|
||||||
|
|
||||||
|
@obj_base.VersionedObjectRegistry.register
|
||||||
|
class NetworkDhcpAgentBinding(base.NeutronDbObject):
|
||||||
|
# Version 1.0: Initial version
|
||||||
|
VERSION = '1.0'
|
||||||
|
|
||||||
|
db_model = ndab_models.NetworkDhcpAgentBinding
|
||||||
|
|
||||||
|
primary_keys = ['network_id', 'dhcp_agent_id']
|
||||||
|
|
||||||
|
fields = {
|
||||||
|
'network_id': common_types.UUIDField(),
|
||||||
|
'dhcp_agent_id': common_types.UUIDField(),
|
||||||
|
}
|
||||||
|
|
||||||
|
# NOTE(ndahiwade): The join was implemented this way as get_objects
|
||||||
|
# currently doesn't support operators like '<' or '>'
|
||||||
|
@classmethod
|
||||||
|
def get_down_bindings(cls, context, cutoff):
|
||||||
|
agent_objs = agent_obj.Agent.get_objects(context)
|
||||||
|
dhcp_agent_ids = [obj.id for obj in agent_objs
|
||||||
|
if obj.heartbeat_timestamp < cutoff]
|
||||||
|
return cls.get_objects(context, dhcp_agent_id=dhcp_agent_ids)
|
||||||
|
|
||||||
|
|
||||||
@obj_base.VersionedObjectRegistry.register
|
@obj_base.VersionedObjectRegistry.register
|
||||||
class NetworkSegment(base.NeutronDbObject):
|
class NetworkSegment(base.NeutronDbObject):
|
||||||
# Version 1.0: Initial version
|
# Version 1.0: Initial version
|
||||||
|
@ -18,15 +18,13 @@ import collections
|
|||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
from neutron_lib.objects import exceptions
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_db import exception as db_exc
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from sqlalchemy import sql
|
from sqlalchemy import sql
|
||||||
|
|
||||||
from neutron.agent.common import utils as agent_utils
|
from neutron.agent.common import utils as agent_utils
|
||||||
from neutron.db import api as db_api
|
|
||||||
from neutron.db.models import agent as agent_model
|
from neutron.db.models import agent as agent_model
|
||||||
from neutron.db.network_dhcp_agent_binding import models as ndab_model
|
|
||||||
from neutron.extensions import availability_zone as az_ext
|
from neutron.extensions import availability_zone as az_ext
|
||||||
from neutron.objects import network
|
from neutron.objects import network
|
||||||
from neutron.scheduler import base_resource_filter
|
from neutron.scheduler import base_resource_filter
|
||||||
@ -181,15 +179,10 @@ 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 = ndab_model.NetworkDhcpAgentBinding()
|
|
||||||
binding.dhcp_agent_id = agent_id
|
|
||||||
binding.network_id = network_id
|
|
||||||
try:
|
try:
|
||||||
with db_api.autonested_transaction(context.session):
|
network.NetworkDhcpAgentBinding(context,
|
||||||
context.session.add(binding)
|
dhcp_agent_id=agent_id, network_id=network_id).create()
|
||||||
# try to actually write the changes and catch integrity
|
except exceptions.NeutronDbObjectDuplicateEntry:
|
||||||
# DBDuplicateEntry
|
|
||||||
except db_exc.DBDuplicateEntry:
|
|
||||||
# it's totally ok, someone just did our job!
|
# it's totally ok, someone just did our job!
|
||||||
bound_agents.remove(agent)
|
bound_agents.remove(agent)
|
||||||
LOG.info('Agent %s already present', agent_id)
|
LOG.info('Agent %s already present', agent_id)
|
||||||
@ -273,15 +266,14 @@ class DhcpFilter(base_resource_filter.BaseResourceFilter):
|
|||||||
az_hints = (network.get(az_ext.AZ_HINTS) or
|
az_hints = (network.get(az_ext.AZ_HINTS) or
|
||||||
cfg.CONF.default_availability_zones)
|
cfg.CONF.default_availability_zones)
|
||||||
active_dhcp_agents = self._get_active_agents(plugin, context, az_hints)
|
active_dhcp_agents = self._get_active_agents(plugin, context, az_hints)
|
||||||
|
hosted_agent_ids = [agent['id'] for agent in hosted_agents]
|
||||||
if not active_dhcp_agents:
|
if not active_dhcp_agents:
|
||||||
return {'n_agents': 0, 'hostable_agents': [],
|
return {'n_agents': 0, 'hostable_agents': [],
|
||||||
'hosted_agents': hosted_agents}
|
'hosted_agents': hosted_agents}
|
||||||
hostable_dhcp_agents = [
|
hostable_dhcp_agents = [
|
||||||
agent for agent in set(active_dhcp_agents)
|
agent for agent in active_dhcp_agents
|
||||||
if agent not in hosted_agents and plugin.is_eligible_agent(
|
if agent.id not in hosted_agent_ids and plugin.is_eligible_agent(
|
||||||
context, True, agent)
|
context, True, agent)]
|
||||||
]
|
|
||||||
|
|
||||||
hostable_dhcp_agents = self._filter_agents_with_network_access(
|
hostable_dhcp_agents = self._filter_agents_with_network_access(
|
||||||
plugin, context, network, hostable_dhcp_agents)
|
plugin, context, network, hostable_dhcp_agents)
|
||||||
|
|
||||||
|
@ -19,12 +19,13 @@ from operator import attrgetter
|
|||||||
from neutron_lib.api.definitions import provider_net as providernet
|
from neutron_lib.api.definitions import provider_net as providernet
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
from neutron_lib import context
|
from neutron_lib import context
|
||||||
|
from oslo_utils import uuidutils
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
|
||||||
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
|
||||||
from neutron.db.network_dhcp_agent_binding import models as ndab_model
|
from neutron.objects import network
|
||||||
from neutron.scheduler import dhcp_agent_scheduler
|
from neutron.scheduler import dhcp_agent_scheduler
|
||||||
from neutron.tests.common import helpers
|
from neutron.tests.common import helpers
|
||||||
from neutron.tests.unit.plugins.ml2 import test_plugin
|
from neutron.tests.unit.plugins.ml2 import test_plugin
|
||||||
@ -359,10 +360,10 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase,
|
|||||||
|
|
||||||
def get_subnets(self, context, fields=None):
|
def get_subnets(self, context, fields=None):
|
||||||
subnets = []
|
subnets = []
|
||||||
for net_id in self._networks:
|
for net in self._networks:
|
||||||
enable_dhcp = (not self._strip_host_index(net_id) in
|
enable_dhcp = (self._strip_host_index(net['name']) not in
|
||||||
self.networks_with_dhcp_disabled)
|
self.networks_with_dhcp_disabled)
|
||||||
subnets.append({'network_id': net_id,
|
subnets.append({'network_id': net.id,
|
||||||
'enable_dhcp': enable_dhcp,
|
'enable_dhcp': enable_dhcp,
|
||||||
'segment_id': None})
|
'segment_id': None})
|
||||||
return subnets
|
return subnets
|
||||||
@ -374,13 +375,9 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase,
|
|||||||
return {'availability_zone_hints': az_hints}
|
return {'availability_zone_hints': az_hints}
|
||||||
|
|
||||||
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(
|
binding_objs = network.NetworkDhcpAgentBinding.get_objects(
|
||||||
ndab_model.NetworkDhcpAgentBinding.network_id)
|
self.ctx, dhcp_agent_id=agent_id)
|
||||||
query = query.filter(
|
return [item.network_id for item in binding_objs]
|
||||||
ndab_model.NetworkDhcpAgentBinding.dhcp_agent_id ==
|
|
||||||
agent_id)
|
|
||||||
|
|
||||||
return [item[0] for item in query]
|
|
||||||
|
|
||||||
def _test_auto_schedule(self, host_index):
|
def _test_auto_schedule(self, host_index):
|
||||||
self.config(dhcp_agents_per_network=self.max_agents_per_network)
|
self.config(dhcp_agents_per_network=self.max_agents_per_network)
|
||||||
@ -394,9 +391,16 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase,
|
|||||||
dhcp_agents = self._create_and_set_agents_down(hosts)
|
dhcp_agents = self._create_and_set_agents_down(hosts)
|
||||||
|
|
||||||
# create networks
|
# create networks
|
||||||
self._networks = ['%s-network-%s' % (host_index, i)
|
self._networks = [
|
||||||
for i in range(self.network_count)]
|
network.Network(
|
||||||
self._save_networks(self._networks)
|
self.ctx,
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
name='%s-network-%s' % (host_index, i))
|
||||||
|
for i in range(self.network_count)
|
||||||
|
]
|
||||||
|
for i in range(len(self._networks)):
|
||||||
|
self._networks[i].create()
|
||||||
|
network_ids = [net.id for net in self._networks]
|
||||||
|
|
||||||
# pre schedule the networks to the agents defined in
|
# pre schedule the networks to the agents defined in
|
||||||
# self.hosted_networks before calling auto_schedule_network
|
# self.hosted_networks before calling auto_schedule_network
|
||||||
@ -406,7 +410,7 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase,
|
|||||||
net_index = self._extract_index(net)
|
net_index = self._extract_index(net)
|
||||||
scheduler.resource_filter.bind(self.ctx,
|
scheduler.resource_filter.bind(self.ctx,
|
||||||
[dhcp_agents[agent_index]],
|
[dhcp_agents[agent_index]],
|
||||||
self._networks[net_index])
|
network_ids[net_index])
|
||||||
|
|
||||||
retval = scheduler.auto_schedule_networks(self, self.ctx,
|
retval = scheduler.auto_schedule_networks(self, self.ctx,
|
||||||
hosts[host_index])
|
hosts[host_index])
|
||||||
@ -415,11 +419,14 @@ class TestAutoSchedule(test_dhcp_sch.TestDhcpSchedulerBaseTestCase,
|
|||||||
|
|
||||||
agent_id = dhcp_agents[host_index].id
|
agent_id = dhcp_agents[host_index].id
|
||||||
hosted_networks = self._get_hosted_networks_on_dhcp_agent(agent_id)
|
hosted_networks = self._get_hosted_networks_on_dhcp_agent(agent_id)
|
||||||
hosted_net_ids = [self._strip_host_index(net)
|
hosted_net_names = [
|
||||||
for net in hosted_networks]
|
self._strip_host_index(net['name'])
|
||||||
|
for net in network.Network.get_objects(
|
||||||
|
self.ctx, id=hosted_networks)
|
||||||
|
]
|
||||||
expected_hosted_networks = self.expected_hosted_networks['agent-%s' %
|
expected_hosted_networks = self.expected_hosted_networks['agent-%s' %
|
||||||
host_index]
|
host_index]
|
||||||
self.assertItemsEqual(hosted_net_ids, expected_hosted_networks, msg)
|
self.assertItemsEqual(hosted_net_names, expected_hosted_networks, msg)
|
||||||
|
|
||||||
def test_auto_schedule(self):
|
def test_auto_schedule(self):
|
||||||
for i in range(self.agent_count):
|
for i in range(self.agent_count):
|
||||||
|
@ -1716,7 +1716,17 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
|
|||||||
# check that the stored database model does not have non-empty
|
# check that the stored database model does not have non-empty
|
||||||
# relationships
|
# relationships
|
||||||
dbattr = obj.fields_need_translation.get(field, field)
|
dbattr = obj.fields_need_translation.get(field, field)
|
||||||
self.assertFalse(getattr(obj.db_obj, dbattr, None))
|
# Skipping empty relationships for the following reasons:
|
||||||
|
# 1) db_obj have the related object loaded - In this case we do not
|
||||||
|
# have to create the related objects and the loop can continue.
|
||||||
|
# 2) when the related objects are not loaded - In this
|
||||||
|
# case they need to be created because of the foreign key
|
||||||
|
# relationships. But we still need to check whether the
|
||||||
|
# relationships are loaded or not. That is achieved by the
|
||||||
|
# assertTrue statement after retrieving the dbattr in
|
||||||
|
# this method.
|
||||||
|
if getattr(obj.db_obj, dbattr, None):
|
||||||
|
continue
|
||||||
|
|
||||||
if isinstance(cls_.fields[field], obj_fields.ObjectField):
|
if isinstance(cls_.fields[field], obj_fields.ObjectField):
|
||||||
objclass_fields = self._get_non_synth_fields(objclass,
|
objclass_fields = self._get_non_synth_fields(objclass,
|
||||||
|
@ -20,6 +20,26 @@ from neutron.tests.unit.objects import test_base as obj_test_base
|
|||||||
from neutron.tests.unit import testlib_api
|
from neutron.tests.unit import testlib_api
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkDhcpAgentBindingObjectIfaceTestCase(
|
||||||
|
obj_test_base.BaseObjectIfaceTestCase):
|
||||||
|
|
||||||
|
_test_class = network.NetworkDhcpAgentBinding
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkDhcpAgentBindingDbObjectTestCase(
|
||||||
|
obj_test_base.BaseDbObjectTestCase, testlib_api.SqlTestCase):
|
||||||
|
|
||||||
|
_test_class = network.NetworkDhcpAgentBinding
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(NetworkDhcpAgentBindingDbObjectTestCase, self).setUp()
|
||||||
|
self._network = self._create_test_network()
|
||||||
|
|
||||||
|
self.update_obj_fields(
|
||||||
|
{'network_id': self._network.id,
|
||||||
|
'dhcp_agent_id': lambda: self._create_test_agent_id()})
|
||||||
|
|
||||||
|
|
||||||
class NetworkPortSecurityIfaceObjTestCase(
|
class NetworkPortSecurityIfaceObjTestCase(
|
||||||
obj_test_base.BaseObjectIfaceTestCase):
|
obj_test_base.BaseObjectIfaceTestCase):
|
||||||
_test_class = network.NetworkPortSecurity
|
_test_class = network.NetworkPortSecurity
|
||||||
|
@ -57,6 +57,7 @@ object_data = {
|
|||||||
'MeteringLabelRule': '1.0-b5c5717e7bab8d1af1623156012a5842',
|
'MeteringLabelRule': '1.0-b5c5717e7bab8d1af1623156012a5842',
|
||||||
'Log': '1.0-6391351c0f34ed34375a19202f361d24',
|
'Log': '1.0-6391351c0f34ed34375a19202f361d24',
|
||||||
'Network': '1.0-f2f6308f79731a767b92b26b0f4f3849',
|
'Network': '1.0-f2f6308f79731a767b92b26b0f4f3849',
|
||||||
|
'NetworkDhcpAgentBinding': '1.0-6eeceb5fb4335cd65a305016deb41c68',
|
||||||
'NetworkDNSDomain': '1.0-420db7910294608534c1e2e30d6d8319',
|
'NetworkDNSDomain': '1.0-420db7910294608534c1e2e30d6d8319',
|
||||||
'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',
|
'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',
|
||||||
'NetworkSegment': '1.0-57b7f2960971e3b95ded20cbc59244a8',
|
'NetworkSegment': '1.0-57b7f2960971e3b95ded20cbc59244a8',
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
@ -20,13 +21,15 @@ from neutron_lib import constants
|
|||||||
from neutron_lib import context
|
from neutron_lib import context
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_utils import importutils
|
from oslo_utils import importutils
|
||||||
|
from oslo_utils import uuidutils
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
|
||||||
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
|
||||||
from neutron.db.network_dhcp_agent_binding import models as ndab_model
|
|
||||||
from neutron.extensions import dhcpagentscheduler
|
from neutron.extensions import dhcpagentscheduler
|
||||||
|
from neutron.objects import agent
|
||||||
|
from neutron.objects import network as network_obj
|
||||||
from neutron.scheduler import dhcp_agent_scheduler
|
from neutron.scheduler import dhcp_agent_scheduler
|
||||||
from neutron.services.segments import db as segments_service_db
|
from neutron.services.segments import db as segments_service_db
|
||||||
from neutron.tests.common import helpers
|
from neutron.tests.common import helpers
|
||||||
@ -47,8 +50,8 @@ class TestDhcpSchedulerBaseTestCase(testlib_api.SqlTestCase):
|
|||||||
super(TestDhcpSchedulerBaseTestCase, self).setUp()
|
super(TestDhcpSchedulerBaseTestCase, self).setUp()
|
||||||
self.setup_coreplugin(self.CORE_PLUGIN)
|
self.setup_coreplugin(self.CORE_PLUGIN)
|
||||||
self.ctx = context.get_admin_context()
|
self.ctx = context.get_admin_context()
|
||||||
self.network = {'id': 'foo_network_id'}
|
self.network = {'id': uuidutils.generate_uuid()}
|
||||||
self.network_id = 'foo_network_id'
|
self.network_id = self.network['id']
|
||||||
self._save_networks([self.network_id])
|
self._save_networks([self.network_id])
|
||||||
|
|
||||||
def _create_and_set_agents_down(self, hosts, down_agent_count=0,
|
def _create_and_set_agents_down(self, hosts, down_agent_count=0,
|
||||||
@ -72,11 +75,10 @@ class TestDhcpSchedulerBaseTestCase(testlib_api.SqlTestCase):
|
|||||||
def _test_schedule_bind_network(self, agents, network_id):
|
def _test_schedule_bind_network(self, agents, network_id):
|
||||||
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(
|
binding_objs = network_obj.NetworkDhcpAgentBinding.get_objects(
|
||||||
ndab_model.NetworkDhcpAgentBinding).filter_by(
|
self.ctx, network_id=network_id)
|
||||||
network_id=network_id).all()
|
self.assertEqual(len(agents), len(binding_objs))
|
||||||
self.assertEqual(len(agents), len(results))
|
for result in binding_objs:
|
||||||
for result in results:
|
|
||||||
self.assertEqual(network_id, result.network_id)
|
self.assertEqual(network_id, result.network_id)
|
||||||
|
|
||||||
|
|
||||||
@ -135,9 +137,8 @@ class TestDhcpScheduler(TestDhcpSchedulerBaseTestCase):
|
|||||||
self._test_reschedule_vs_network_on_dead_agent(False)
|
self._test_reschedule_vs_network_on_dead_agent(False)
|
||||||
|
|
||||||
def _get_agent_binding_from_db(self, agent):
|
def _get_agent_binding_from_db(self, agent):
|
||||||
return self.ctx.session.query(
|
return network_obj.NetworkDhcpAgentBinding.get_objects(
|
||||||
ndab_model.NetworkDhcpAgentBinding
|
self.ctx, dhcp_agent_id=agent[0].id)
|
||||||
).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,
|
||||||
active_hosts_only):
|
active_hosts_only):
|
||||||
@ -289,9 +290,9 @@ class TestAutoScheduleNetworks(TestDhcpSchedulerBaseTestCase):
|
|||||||
observed_ret_value = scheduler.auto_schedule_networks(
|
observed_ret_value = scheduler.auto_schedule_networks(
|
||||||
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(
|
count_hosted_agents = network_obj.NetworkDhcpAgentBinding.count(
|
||||||
ndab_model.NetworkDhcpAgentBinding).all()
|
self.ctx)
|
||||||
self.assertEqual(expected_hosted_agents, len(hosted_agents))
|
self.assertEqual(expected_hosted_agents, count_hosted_agents)
|
||||||
|
|
||||||
|
|
||||||
class TestAutoScheduleSegments(test_plugin.Ml2PluginV2TestCase,
|
class TestAutoScheduleSegments(test_plugin.Ml2PluginV2TestCase,
|
||||||
@ -409,10 +410,11 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase,
|
|||||||
sched_db.DhcpAgentSchedulerDbMixin,
|
sched_db.DhcpAgentSchedulerDbMixin,
|
||||||
common_db_mixin.CommonDbMixin):
|
common_db_mixin.CommonDbMixin):
|
||||||
def test_reschedule_network_from_down_agent(self):
|
def test_reschedule_network_from_down_agent(self):
|
||||||
|
net_id = uuidutils.generate_uuid()
|
||||||
agents = self._create_and_set_agents_down(['host-a', 'host-b'], 1)
|
agents = self._create_and_set_agents_down(['host-a', 'host-b'], 1)
|
||||||
self._test_schedule_bind_network([agents[0]], self.network_id)
|
self._test_schedule_bind_network([agents[0]], self.network_id)
|
||||||
self._save_networks(["foo-network-2"])
|
self._save_networks([net_id])
|
||||||
self._test_schedule_bind_network([agents[1]], "foo-network-2")
|
self._test_schedule_bind_network([agents[1]], net_id)
|
||||||
with mock.patch.object(self, 'remove_network_from_dhcp_agent') as rn,\
|
with mock.patch.object(self, 'remove_network_from_dhcp_agent') as rn,\
|
||||||
mock.patch.object(self,
|
mock.patch.object(self,
|
||||||
'schedule_network',
|
'schedule_network',
|
||||||
@ -459,24 +461,70 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase,
|
|||||||
rn_side_effect=dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
rn_side_effect=dhcpagentscheduler.NetworkNotHostedByDhcpAgent(
|
||||||
network_id='foo', agent_id='bar'))
|
network_id='foo', agent_id='bar'))
|
||||||
|
|
||||||
|
def _create_test_networks(self, num_net=0):
|
||||||
|
networks = [network_obj.Network(
|
||||||
|
self.ctx,
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
name='network-%s' % (i))
|
||||||
|
for i in range(num_net)]
|
||||||
|
for net in networks:
|
||||||
|
net.create()
|
||||||
|
return [net.id for net in networks]
|
||||||
|
|
||||||
|
def _create_dhcp_agents(self):
|
||||||
|
timestamp = datetime.datetime.now()
|
||||||
|
dhcp_agent_ids = [uuidutils.generate_uuid() for x in range(2)]
|
||||||
|
dhcp_agent_1 = agent.Agent(self.ctx, id=dhcp_agent_ids[0],
|
||||||
|
agent_type='DHCP Agent',
|
||||||
|
topic='fake_topic',
|
||||||
|
host='fake_host',
|
||||||
|
binary='fake_binary',
|
||||||
|
created_at=timestamp,
|
||||||
|
started_at=timestamp,
|
||||||
|
heartbeat_timestamp=timestamp,
|
||||||
|
configurations={},
|
||||||
|
load=0)
|
||||||
|
dhcp_agent_1.create()
|
||||||
|
|
||||||
|
dhcp_agent_2 = agent.Agent(self.ctx, id=dhcp_agent_ids[1],
|
||||||
|
agent_type='DHCP Agent',
|
||||||
|
topic='fake_topic',
|
||||||
|
host='fake_host_1',
|
||||||
|
binary='fake_binary',
|
||||||
|
created_at=timestamp,
|
||||||
|
started_at=timestamp,
|
||||||
|
heartbeat_timestamp=timestamp,
|
||||||
|
configurations={},
|
||||||
|
load=0)
|
||||||
|
dhcp_agent_2.create()
|
||||||
|
return [dhcp_agent_1.id, dhcp_agent_2.id]
|
||||||
|
|
||||||
def test_filter_bindings(self):
|
def test_filter_bindings(self):
|
||||||
bindings = [
|
self.ctx = context.get_admin_context()
|
||||||
ndab_model.NetworkDhcpAgentBinding(network_id='foo1',
|
dhcp_agt_ids = self._create_dhcp_agents()
|
||||||
dhcp_agent={'id': 'id1'}),
|
network_ids = self._create_test_networks(num_net=4)
|
||||||
ndab_model.NetworkDhcpAgentBinding(network_id='foo2',
|
ndab_obj1 = network_obj.NetworkDhcpAgentBinding(self.ctx,
|
||||||
dhcp_agent={'id': 'id1'}),
|
network_id=network_ids[0], dhcp_agent_id=dhcp_agt_ids[0])
|
||||||
ndab_model.NetworkDhcpAgentBinding(network_id='foo3',
|
ndab_obj1.create()
|
||||||
dhcp_agent={'id': 'id2'}),
|
ndab_obj2 = network_obj.NetworkDhcpAgentBinding(self.ctx,
|
||||||
ndab_model.NetworkDhcpAgentBinding(network_id='foo4',
|
network_id=network_ids[1], dhcp_agent_id=dhcp_agt_ids[0])
|
||||||
dhcp_agent={'id': 'id2'})]
|
ndab_obj2.create()
|
||||||
|
ndab_obj3 = network_obj.NetworkDhcpAgentBinding(self.ctx,
|
||||||
|
network_id=network_ids[2], dhcp_agent_id=dhcp_agt_ids[1])
|
||||||
|
ndab_obj3.create()
|
||||||
|
ndab_obj4 = network_obj.NetworkDhcpAgentBinding(self.ctx,
|
||||||
|
network_id=network_ids[3], dhcp_agent_id=dhcp_agt_ids[1])
|
||||||
|
ndab_obj4.create()
|
||||||
|
bindings_objs = network_obj.NetworkDhcpAgentBinding.get_objects(
|
||||||
|
self.ctx)
|
||||||
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_objs)]
|
||||||
# once per each agent id1 and id2
|
# once per each agent id1 and id2
|
||||||
self.assertEqual(2, len(res))
|
self.assertEqual(2, len(res))
|
||||||
res_ids = [b.network_id for b in res]
|
res_ids = [b.network_id for b in res]
|
||||||
self.assertIn('foo3', res_ids)
|
self.assertIn(network_ids[2], res_ids)
|
||||||
self.assertIn('foo4', res_ids)
|
self.assertIn(network_ids[3], res_ids)
|
||||||
|
|
||||||
def test_reschedule_network_from_down_agent_failed_on_unexpected(self):
|
def test_reschedule_network_from_down_agent_failed_on_unexpected(self):
|
||||||
agents = self._create_and_set_agents_down(['host-a'], 1)
|
agents = self._create_and_set_agents_down(['host-a'], 1)
|
||||||
@ -717,7 +765,7 @@ class TestDhcpSchedulerFilter(TestDhcpSchedulerBaseTestCase,
|
|||||||
admin_state_up=False)
|
admin_state_up=False)
|
||||||
|
|
||||||
def test_get_dhcp_agents_hosting_many_networks(self):
|
def test_get_dhcp_agents_hosting_many_networks(self):
|
||||||
net_id = 'another-net-id'
|
net_id = uuidutils.generate_uuid()
|
||||||
self._save_networks([net_id])
|
self._save_networks([net_id])
|
||||||
networks = [net_id, self.network_id]
|
networks = [net_id, self.network_id]
|
||||||
self._test_get_dhcp_agents_hosting_networks({'host-a', 'host-b',
|
self._test_get_dhcp_agents_hosting_networks({'host-a', 'host-b',
|
||||||
@ -745,35 +793,38 @@ class DHCPAgentAZAwareWeightSchedulerTestCase(TestDhcpSchedulerBaseTestCase):
|
|||||||
cfg.CONF.set_override("dhcp_load_type", "networks")
|
cfg.CONF.set_override("dhcp_load_type", "networks")
|
||||||
|
|
||||||
def test_az_scheduler_one_az_hints(self):
|
def test_az_scheduler_one_az_hints(self):
|
||||||
self._save_networks(['1111'])
|
net_id = uuidutils.generate_uuid()
|
||||||
|
self._save_networks([net_id])
|
||||||
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
||||||
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
||||||
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
||||||
helpers.register_dhcp_agent('az2-host2', networks=4, az='az2')
|
helpers.register_dhcp_agent('az2-host2', networks=4, az='az2')
|
||||||
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
||||||
{'id': '1111', 'availability_zone_hints': ['az2']})
|
{'id': net_id, 'availability_zone_hints': ['az2']})
|
||||||
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
||||||
['1111'])
|
[net_id])
|
||||||
self.assertEqual(1, len(agents))
|
self.assertEqual(1, len(agents))
|
||||||
self.assertEqual('az2-host1', agents[0]['host'])
|
self.assertEqual('az2-host1', agents[0]['host'])
|
||||||
|
|
||||||
def test_az_scheduler_default_az_hints(self):
|
def test_az_scheduler_default_az_hints(self):
|
||||||
|
net_id = uuidutils.generate_uuid()
|
||||||
cfg.CONF.set_override('default_availability_zones', ['az1'])
|
cfg.CONF.set_override('default_availability_zones', ['az1'])
|
||||||
self._save_networks(['1111'])
|
self._save_networks([net_id])
|
||||||
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
||||||
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
||||||
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
||||||
helpers.register_dhcp_agent('az2-host2', networks=4, az='az2')
|
helpers.register_dhcp_agent('az2-host2', networks=4, az='az2')
|
||||||
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
||||||
{'id': '1111', 'availability_zone_hints': []})
|
{'id': net_id, 'availability_zone_hints': []})
|
||||||
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
||||||
['1111'])
|
[net_id])
|
||||||
self.assertEqual(1, len(agents))
|
self.assertEqual(1, len(agents))
|
||||||
self.assertEqual('az1-host1', agents[0]['host'])
|
self.assertEqual('az1-host1', agents[0]['host'])
|
||||||
|
|
||||||
def test_az_scheduler_two_az_hints(self):
|
def test_az_scheduler_two_az_hints(self):
|
||||||
|
net_id = uuidutils.generate_uuid()
|
||||||
cfg.CONF.set_override('dhcp_agents_per_network', 2)
|
cfg.CONF.set_override('dhcp_agents_per_network', 2)
|
||||||
self._save_networks(['1111'])
|
self._save_networks([net_id])
|
||||||
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
||||||
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
||||||
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
helpers.register_dhcp_agent('az2-host1', networks=3, az='az2')
|
||||||
@ -781,17 +832,18 @@ class DHCPAgentAZAwareWeightSchedulerTestCase(TestDhcpSchedulerBaseTestCase):
|
|||||||
helpers.register_dhcp_agent('az3-host1', networks=5, az='az3')
|
helpers.register_dhcp_agent('az3-host1', networks=5, az='az3')
|
||||||
helpers.register_dhcp_agent('az3-host2', networks=6, az='az3')
|
helpers.register_dhcp_agent('az3-host2', networks=6, az='az3')
|
||||||
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
||||||
{'id': '1111', 'availability_zone_hints': ['az1', 'az3']})
|
{'id': net_id, 'availability_zone_hints': ['az1', 'az3']})
|
||||||
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
||||||
['1111'])
|
[net_id])
|
||||||
self.assertEqual(2, len(agents))
|
self.assertEqual(2, len(agents))
|
||||||
expected_hosts = set(['az1-host1', 'az3-host1'])
|
expected_hosts = set(['az1-host1', 'az3-host1'])
|
||||||
hosts = set([a['host'] for a in agents])
|
hosts = set([a['host'] for a in agents])
|
||||||
self.assertEqual(expected_hosts, hosts)
|
self.assertEqual(expected_hosts, hosts)
|
||||||
|
|
||||||
def test_az_scheduler_two_az_hints_one_available_az(self):
|
def test_az_scheduler_two_az_hints_one_available_az(self):
|
||||||
|
net_id = uuidutils.generate_uuid()
|
||||||
cfg.CONF.set_override('dhcp_agents_per_network', 2)
|
cfg.CONF.set_override('dhcp_agents_per_network', 2)
|
||||||
self._save_networks(['1111'])
|
self._save_networks([net_id])
|
||||||
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
helpers.register_dhcp_agent('az1-host1', networks=1, az='az1')
|
||||||
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
helpers.register_dhcp_agent('az1-host2', networks=2, az='az1')
|
||||||
helpers.register_dhcp_agent('az2-host1', networks=3, alive=False,
|
helpers.register_dhcp_agent('az2-host1', networks=3, alive=False,
|
||||||
@ -799,26 +851,27 @@ class DHCPAgentAZAwareWeightSchedulerTestCase(TestDhcpSchedulerBaseTestCase):
|
|||||||
helpers.register_dhcp_agent('az2-host2', networks=4,
|
helpers.register_dhcp_agent('az2-host2', networks=4,
|
||||||
admin_state_up=False, az='az2')
|
admin_state_up=False, az='az2')
|
||||||
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
||||||
{'id': '1111', 'availability_zone_hints': ['az1', 'az2']})
|
{'id': net_id, 'availability_zone_hints': ['az1', 'az2']})
|
||||||
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
||||||
['1111'])
|
[net_id])
|
||||||
self.assertEqual(2, len(agents))
|
self.assertEqual(2, len(agents))
|
||||||
expected_hosts = set(['az1-host1', 'az1-host2'])
|
expected_hosts = set(['az1-host1', 'az1-host2'])
|
||||||
hosts = set([a['host'] for a in agents])
|
hosts = set([a['host'] for a in agents])
|
||||||
self.assertEqual(expected_hosts, hosts)
|
self.assertEqual(expected_hosts, hosts)
|
||||||
|
|
||||||
def _test_az_scheduler_no_az_hints(self, multiple_agent=False):
|
def _test_az_scheduler_no_az_hints(self, multiple_agent=False):
|
||||||
|
net_id = uuidutils.generate_uuid()
|
||||||
num_agent = 2 if multiple_agent else 1
|
num_agent = 2 if multiple_agent else 1
|
||||||
cfg.CONF.set_override('dhcp_agents_per_network', num_agent)
|
cfg.CONF.set_override('dhcp_agents_per_network', num_agent)
|
||||||
self._save_networks(['1111'])
|
self._save_networks([net_id])
|
||||||
helpers.register_dhcp_agent('az1-host1', networks=2, az='az1')
|
helpers.register_dhcp_agent('az1-host1', networks=2, az='az1')
|
||||||
helpers.register_dhcp_agent('az1-host2', networks=3, az='az1')
|
helpers.register_dhcp_agent('az1-host2', networks=3, az='az1')
|
||||||
helpers.register_dhcp_agent('az2-host1', networks=2, az='az2')
|
helpers.register_dhcp_agent('az2-host1', networks=2, az='az2')
|
||||||
helpers.register_dhcp_agent('az2-host2', networks=1, az='az2')
|
helpers.register_dhcp_agent('az2-host2', networks=1, az='az2')
|
||||||
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
self.plugin.network_scheduler.schedule(self.plugin, self.ctx,
|
||||||
{'id': '1111', 'availability_zone_hints': []})
|
{'id': net_id, 'availability_zone_hints': []})
|
||||||
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
agents = self.plugin.get_dhcp_agents_hosting_networks(self.ctx,
|
||||||
['1111'])
|
[net_id])
|
||||||
self.assertEqual(num_agent, len(agents))
|
self.assertEqual(num_agent, len(agents))
|
||||||
if multiple_agent:
|
if multiple_agent:
|
||||||
expected_hosts = set(['az1-host1', 'az2-host2'])
|
expected_hosts = set(['az1-host1', 'az2-host2'])
|
||||||
@ -834,7 +887,7 @@ class DHCPAgentAZAwareWeightSchedulerTestCase(TestDhcpSchedulerBaseTestCase):
|
|||||||
self._test_az_scheduler_no_az_hints()
|
self._test_az_scheduler_no_az_hints()
|
||||||
|
|
||||||
def test_az_scheduler_select_az_with_least_weight(self):
|
def test_az_scheduler_select_az_with_least_weight(self):
|
||||||
self._save_networks(['1111'])
|
self._save_networks([uuidutils.generate_uuid()])
|
||||||
dhcp_agents = []
|
dhcp_agents = []
|
||||||
# Register 6 dhcp agents in 3 AZs, every AZ will have 2 agents.
|
# Register 6 dhcp agents in 3 AZs, every AZ will have 2 agents.
|
||||||
dhcp_agents.append(
|
dhcp_agents.append(
|
||||||
|
Loading…
Reference in New Issue
Block a user