Fix using subnets with host_routes in amphorav2 driver
When using subnets with host_routes in amphorav2, the host_routes attribute in the Subnet data structure was not correctly converted to a HostRoute data structure. It triggered exceptions and failed to provision the load balancer. Story 2008738 Task 42092 Change-Id: I39391070cea170a6039f901093f09fc89ba06123
This commit is contained in:
parent
6c54eab5b5
commit
d0ec3aaf23
@ -266,9 +266,17 @@ class AmphoraPostNetworkPlug(BaseAmphoraTask):
|
||||
for port in ports:
|
||||
net = data_models.Network(**port.pop(constants.NETWORK))
|
||||
ips = port.pop(constants.FIXED_IPS)
|
||||
fixed_ips = [data_models.FixedIP(
|
||||
subnet=data_models.Subnet(**ip.pop(constants.SUBNET)), **ip)
|
||||
for ip in ips]
|
||||
fixed_ips = []
|
||||
for ip in ips:
|
||||
subnet_arg = ip.pop(constants.SUBNET)
|
||||
host_routes = subnet_arg.get('host_routes')
|
||||
if host_routes:
|
||||
subnet_arg['host_routes'] = [
|
||||
data_models.HostRoute(**hr)
|
||||
for hr in host_routes
|
||||
]
|
||||
fixed_ips.append(data_models.FixedIP(
|
||||
subnet=data_models.Subnet(**subnet_arg), **ip))
|
||||
self.amphora_driver.post_network_plug(
|
||||
db_amp, data_models.Port(network=net, fixed_ips=fixed_ips,
|
||||
**port))
|
||||
@ -329,6 +337,12 @@ class AmphoraPostVIPPlug(BaseAmphoraTask):
|
||||
vip_arg = amphorae_network_config[amphora.get(
|
||||
constants.ID)][constants.VIP_SUBNET]
|
||||
if vip_arg:
|
||||
host_routes = vip_arg.get('host_routes')
|
||||
if host_routes:
|
||||
vip_arg['host_routes'] = [
|
||||
data_models.HostRoute(**hr)
|
||||
for hr in host_routes
|
||||
]
|
||||
vip_subnet = data_models.Subnet(**vip_arg)
|
||||
else:
|
||||
vip_subnet = data_models.Subnet()
|
||||
|
@ -381,8 +381,9 @@ class TestAmphoraDriverTasks(base.TestCase):
|
||||
amphora_post_network_plug_obj = (amphora_driver_tasks.
|
||||
AmphoraPostNetworkPlug())
|
||||
mock_amphora_repo_get.return_value = _db_amphora_mock
|
||||
fixed_ips = [{constants.SUBNET: {}}]
|
||||
port_mock = {constants.NETWORK: mock.MagicMock(),
|
||||
constants.FIXED_IPS: [mock.MagicMock()],
|
||||
constants.FIXED_IPS: fixed_ips,
|
||||
constants.ID: uuidutils.generate_uuid()}
|
||||
amphora_post_network_plug_obj.execute(_amphora_mock, [port_mock])
|
||||
|
||||
@ -416,6 +417,37 @@ class TestAmphoraDriverTasks(base.TestCase):
|
||||
failure.Failure.from_exception(Exception('boom')), _amphora_mock)
|
||||
repo.AmphoraRepository.update.assert_not_called()
|
||||
|
||||
def test_amphora_post_network_plug_with_host_routes(
|
||||
self, mock_driver, mock_generate_uuid, mock_log, mock_get_session,
|
||||
mock_listener_repo_get, mock_listener_repo_update,
|
||||
mock_amphora_repo_get, mock_amphora_repo_update):
|
||||
|
||||
amphora_post_network_plug_obj = (amphora_driver_tasks.
|
||||
AmphoraPostNetworkPlug())
|
||||
mock_amphora_repo_get.return_value = _db_amphora_mock
|
||||
host_routes = [{'destination': '10.0.0.0/16',
|
||||
'nexthop': '192.168.10.3'},
|
||||
{'destination': '10.2.0.0/16',
|
||||
'nexthop': '192.168.10.5'}]
|
||||
fixed_ips = [{constants.SUBNET: {'host_routes': host_routes}}]
|
||||
|
||||
port_mock = {constants.NETWORK: mock.MagicMock(),
|
||||
constants.FIXED_IPS: fixed_ips,
|
||||
constants.ID: uuidutils.generate_uuid()}
|
||||
amphora_post_network_plug_obj.execute(_amphora_mock, [port_mock])
|
||||
|
||||
(mock_driver.post_network_plug.
|
||||
assert_called_once_with)(_db_amphora_mock,
|
||||
network_data_models.Port(**port_mock))
|
||||
|
||||
call_args = mock_driver.post_network_plug.call_args[0]
|
||||
port_arg = call_args[1]
|
||||
subnet_arg = port_arg.fixed_ips[0].subnet
|
||||
self.assertEqual(2, len(subnet_arg.host_routes))
|
||||
for hr1, hr2 in zip(host_routes, subnet_arg.host_routes):
|
||||
self.assertEqual(hr1['destination'], hr2.destination)
|
||||
self.assertEqual(hr1['nexthop'], hr2.nexthop)
|
||||
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
||||
def test_amphorae_post_network_plug(self, mock_lb_get,
|
||||
mock_driver,
|
||||
@ -496,7 +528,14 @@ class TestAmphoraDriverTasks(base.TestCase):
|
||||
mock_amphora_repo_get,
|
||||
mock_amphora_repo_update):
|
||||
|
||||
amphorae_net_config_mock = mock.MagicMock()
|
||||
amphorae_net_config_mock = {
|
||||
AMP_ID: {
|
||||
constants.VIP_SUBNET: {
|
||||
'host_routes': []
|
||||
},
|
||||
constants.VRRP_PORT: mock.MagicMock(),
|
||||
}
|
||||
}
|
||||
mock_amphora_repo_get.return_value = _db_amphora_mock
|
||||
mock_lb_get.return_value = _db_load_balancer_mock
|
||||
amphora_post_vip_plug_obj = amphora_driver_tasks.AmphoraPostVIPPlug()
|
||||
@ -549,6 +588,48 @@ class TestAmphoraDriverTasks(base.TestCase):
|
||||
None)
|
||||
repo.AmphoraRepository.update.assert_not_called()
|
||||
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
||||
def test_amphora_post_vip_plug_with_host_routes(
|
||||
self, mock_lb_get, mock_loadbalancer_repo_update, mock_driver,
|
||||
mock_generate_uuid, mock_log, mock_get_session,
|
||||
mock_listener_repo_get, mock_listener_repo_update,
|
||||
mock_amphora_repo_get, mock_amphora_repo_update):
|
||||
|
||||
host_routes = [{'destination': '10.0.0.0/16',
|
||||
'nexthop': '192.168.10.3'},
|
||||
{'destination': '10.2.0.0/16',
|
||||
'nexthop': '192.168.10.5'}]
|
||||
amphorae_net_config_mock = {
|
||||
AMP_ID: {
|
||||
constants.VIP_SUBNET: {
|
||||
'host_routes': host_routes
|
||||
},
|
||||
constants.VRRP_PORT: mock.MagicMock(),
|
||||
}
|
||||
}
|
||||
mock_amphora_repo_get.return_value = _db_amphora_mock
|
||||
mock_lb_get.return_value = _db_load_balancer_mock
|
||||
amphora_post_vip_plug_obj = amphora_driver_tasks.AmphoraPostVIPPlug()
|
||||
amphora_post_vip_plug_obj.execute(_amphora_mock,
|
||||
_LB_mock,
|
||||
amphorae_net_config_mock)
|
||||
vip_subnet = network_data_models.Subnet(
|
||||
**amphorae_net_config_mock[AMP_ID]['vip_subnet'])
|
||||
vrrp_port = network_data_models.Port(
|
||||
**amphorae_net_config_mock[AMP_ID]['vrrp_port'])
|
||||
|
||||
mock_driver.post_vip_plug.assert_called_once_with(
|
||||
_db_amphora_mock, _db_load_balancer_mock, amphorae_net_config_mock,
|
||||
vip_subnet=vip_subnet, vrrp_port=vrrp_port)
|
||||
|
||||
call_kwargs = mock_driver.post_vip_plug.call_args[1]
|
||||
vip_subnet_arg = call_kwargs.get(constants.VIP_SUBNET)
|
||||
self.assertEqual(2, len(vip_subnet_arg.host_routes))
|
||||
for hr1, hr2 in zip(host_routes, vip_subnet_arg.host_routes):
|
||||
self.assertEqual(hr1['destination'], hr2.destination)
|
||||
self.assertEqual(hr1['nexthop'], hr2.nexthop)
|
||||
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
||||
def test_amphorae_post_vip_plug(self, mock_lb_get,
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fix load balancers that use customized host_routes in the VIP or the member
|
||||
subnets in amphorav2.
|
Loading…
Reference in New Issue
Block a user