summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-01-14 16:28:42 +0000
committerGerrit Code Review <review@openstack.org>2021-01-14 16:28:42 +0000
commit13b70f70c7c79f5316d0bd282eea07d8d6506ac7 (patch)
tree5ddb3063568da7e7ae632aa41f5e5d1a8f9a8b7e
parent4a05e657d3b116e978fa415c73892ec9f8f5aaba (diff)
parent02ad1b7909628f435515eca043c5b849d937176c (diff)
downloadneutron-13b70f70c7c79f5316d0bd282eea07d8d6506ac7.tar.gz
Merge "Fix migration from the HA to non-HA routers" into stable/queens
-rw-r--r--neutron/agent/l3/agent.py17
-rw-r--r--neutron/tests/unit/agent/l3/test_agent.py60
2 files changed, 77 insertions, 0 deletions
diff --git a/neutron/agent/l3/agent.py b/neutron/agent/l3/agent.py
index 6fe209ac6f..89e9abb467 100644
--- a/neutron/agent/l3/agent.py
+++ b/neutron/agent/l3/agent.py
@@ -527,6 +527,23 @@ class L3NATAgent(ha.AgentMixin,
def _process_updated_router(self, router):
ri = self.router_info[router['id']]
+
+ router_ha = router.get('ha')
+ router_distributed = router.get('distributed')
+ if ((router_ha is not None and ri.router.get('ha') != router_ha) or
+ (router_distributed is not None and
+ ri.router.get('distributed') != router_distributed)):
+ LOG.warning('Type of the router %(id)s changed. '
+ 'Old type: ha=%(old_ha)s; distributed=%(old_dvr)s; '
+ 'New type: ha=%(new_ha)s; distributed=%(new_dvr)s',
+ {'id': router['id'],
+ 'old_ha': ri.router.get('ha'),
+ 'old_dvr': ri.router.get('distributed'),
+ 'new_ha': router.get('ha'),
+ 'new_dvr': router.get('distributed')})
+ ri = self._create_router(router['id'], router)
+ self.router_info[router['id']] = ri
+
is_dvr_snat_agent = (self.conf.agent_mode ==
lib_const.L3_AGENT_MODE_DVR_SNAT)
is_dvr_only_agent = (self.conf.agent_mode in
diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py
index fa8ee2d0f3..a1e96c386c 100644
--- a/neutron/tests/unit/agent/l3/test_agent.py
+++ b/neutron/tests/unit/agent/l3/test_agent.py
@@ -2820,6 +2820,16 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
router.distributed = True
router.ha = True
router_info = mock.MagicMock()
+
+ def mock_get(name):
+ if name == 'ha':
+ return router.ha
+ if name == 'distributed':
+ return router.distributed
+ return mock.Mock()
+
+ router_info.router.get.side_effect = mock_get
+
agent.router_info[router.id] = router_info
updated_router = {'id': '1234',
'distributed': True,
@@ -2852,6 +2862,16 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
router._ha_interface = True
router.ha = True
router_info = mock.MagicMock()
+
+ def mock_get(name):
+ if name == 'ha':
+ return router.ha
+ if name == 'distributed':
+ return router.distributed
+ return mock.Mock()
+
+ router_info.router.get.side_effect = mock_get
+
agent.router_info[router.id] = router_info
updated_router = {'id': '1234',
'distributed': True, 'ha': True,
@@ -2997,6 +3017,46 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
agent._process_router_if_compatible(router)
self.assertIn(router['id'], agent.router_info)
+ def test_process_router_if_compatible_type_match(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+
+ router = {'id': _uuid(),
+ 'routes': [],
+ 'admin_state_up': True,
+ 'ha': False, 'distributed': False,
+ 'external_gateway_info': {'network_id': 'aaa'}}
+
+ ri = mock.Mock(router=router)
+ agent.router_info[router['id']] = ri
+ with mock.patch.object(agent, "_create_router") as create_router_mock:
+ agent._process_router_if_compatible(router)
+ create_router_mock.assert_not_called()
+ self.assertIn(router['id'], agent.router_info)
+ self.assertFalse(agent.router_info[router['id']].router['ha'])
+ self.assertFalse(agent.router_info[router['id']].router['distributed'])
+
+ def test_process_router_if_compatible_type_changed(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+
+ router = {'id': _uuid(),
+ 'routes': [],
+ 'admin_state_up': True,
+ 'revision_number': 1,
+ 'ha': True, 'distributed': False,
+ 'external_gateway_info': {'network_id': 'aaa'}}
+
+ ri = mock.Mock(router=router)
+ agent.router_info[router['id']] = ri
+ new_router = copy.deepcopy(router)
+ new_router['ha'] = False
+ with mock.patch.object(agent, "_create_router") as create_router_mock:
+ agent._process_router_if_compatible(new_router)
+ create_router_mock.assert_called_once_with(
+ new_router['id'], new_router)
+ self.assertIn(router['id'], agent.router_info)
+ self.assertFalse(agent.router_info[router['id']].router['ha'])
+ self.assertFalse(agent.router_info[router['id']].router['distributed'])
+
def test_nonexistent_interface_driver(self):
self.conf.set_override('interface_driver', None)
self.assertRaises(SystemExit, l3_agent.L3NATAgent,