Not creating HA router when not enough l3 agents

Currently a HA router can be successfully created even when
there is not enough active l3 agent. Current code only checks
existing l3 agents but does not check if the agent is already
down.

This patch fixes this problem by checking only active l3 agents
when getting the number of agents for scheduling HA router.

Closes-Bug: 1420117

Change-Id: I6c1d108db1a7c93b61c0dd0b1ffee319a411b17a
This commit is contained in:
Xu Han Peng 2015-04-09 01:46:36 -04:00 committed by Hong Hui Xiao
parent c5188d8bf8
commit c27310638b
3 changed files with 27 additions and 11 deletions

View File

@ -262,13 +262,13 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin):
"""
min_agents = cfg.CONF.min_l3_agents_per_router
num_agents = len(self.get_l3_agents(context,
num_agents = len(self.get_l3_agents(context, active=True,
filters={'agent_modes': [constants.L3_AGENT_MODE_LEGACY,
constants.L3_AGENT_MODE_DVR_SNAT]}))
max_agents = cfg.CONF.max_l3_agents_per_router
if max_agents:
if max_agents > num_agents:
LOG.info(_LI("Number of available agents lower than "
LOG.info(_LI("Number of active agents lower than "
"max_l3_agents_per_router. L3 agents "
"available: %s"), num_agents)
else:

View File

@ -12,8 +12,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import datetime
import mock
from oslo_config import cfg
from oslo_utils import timeutils
from neutron.api.v2 import attributes
from neutron.common import constants
@ -52,22 +54,28 @@ class L3HATestFramework(testlib_api.SqlTestCase):
cfg.CONF.set_override('allow_overlapping_ips', True)
self.plugin = FakeL3PluginWithAgents()
self._register_agents()
self.agent1 = self._register_agent('legacy', 'l3host')
self.agent2 = self._register_agent('dvr_snat', 'l3host_2')
def _register_agents(self):
def _register_agent(self, agent_mode, host):
agent_status = {
'agent_type': constants.AGENT_TYPE_L3,
'binary': 'neutron-l3-agent',
'host': 'l3host',
'host': host,
'topic': 'N/A',
'configurations': {'agent_mode': 'legacy'}
'configurations': {'agent_mode': agent_mode}
}
self.plugin.create_or_update_agent(self.admin_ctx, agent_status)
agent_status['host'] = 'l3host_2'
agent_status['configurations'] = {'agent_mode': 'dvr_snat'}
self.plugin.create_or_update_agent(self.admin_ctx, agent_status)
self.agent1, self.agent2 = self.plugin.get_agents(self.admin_ctx)
return self.plugin.get_agents(
self.admin_ctx, filters={'host': [host]})[0]
def _bring_down_agent(self, agent_id):
update = {
'agent': {
'heartbeat_timestamp':
timeutils.utcnow() - datetime.timedelta(hours=1)}}
self.plugin.update_agent(self.admin_ctx, agent_id, update)
def _create_router(self, ha=True, tenant_id='tenant1', distributed=None,
ctx=None):
@ -478,6 +486,14 @@ class L3HATestCase(L3HATestFramework):
self.admin_ctx)
self.assertEqual(2, num_ha_candidates)
def test_get_number_of_agents_for_scheduling_not_enough_agents(self):
cfg.CONF.set_override('min_l3_agents_per_router', 3)
agent_to_bring_down = self._register_agent('legacy', 'l3host_3')
self._bring_down_agent(agent_to_bring_down['id'])
self.assertRaises(l3_ext_ha_mode.HANotEnoughAvailableAgents,
self.plugin.get_number_of_agents_for_scheduling,
self.admin_ctx)
class L3HAModeDbTestCase(L3HATestFramework):

View File

@ -1641,10 +1641,10 @@ class L3HAChanceSchedulerTestCase(L3HATestCaseMixin):
admin_state_up=True)
self.assertEqual(2, len(agents))
r2 = self._create_ha_router()
self._set_l3_agent_admin_state(self.adminContext,
self.agent_id2, False)
r2 = self._create_ha_router()
self.plugin.schedule_router(self.adminContext, r2['id'])
agents = self.plugin.get_l3_agents_hosting_routers(
self.adminContext, [r2['id']],