diff --git a/releasenotes/notes/router_ext_gw-b86582317bca8b39.yaml b/releasenotes/notes/router_ext_gw-b86582317bca8b39.yaml new file mode 100644 index 000000000..84d9a1ac0 --- /dev/null +++ b/releasenotes/notes/router_ext_gw-b86582317bca8b39.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - No longer fail in list_router_interfaces() if a router does + not have the external_gateway_info key. diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index eabc9f35f..6deb6b388 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -1854,9 +1854,12 @@ class OpenStackCloud(object): if interface_type: filtered_ports = [] - ext_fixed = (router['external_gateway_info']['external_fixed_ips'] - if router['external_gateway_info'] - else []) + if ('external_gateway_info' in router and + 'external_fixed_ips' in router['external_gateway_info']): + ext_fixed = \ + router['external_gateway_info']['external_fixed_ips'] + else: + ext_fixed = [] # Compare the subnets (subnet_id, ip_address) on the ports with # the subnets making up the router external gateway. Those ports diff --git a/shade/tests/unit/test_shade.py b/shade/tests/unit/test_shade.py index eeff62e27..f66b82976 100644 --- a/shade/tests/unit/test_shade.py +++ b/shade/tests/unit/test_shade.py @@ -250,6 +250,28 @@ class TestShade(base.TestCase): self.cloud.delete_router('123') self.assertTrue(mock_client.delete_router.called) + @mock.patch.object(shade.OpenStackCloud, 'search_ports') + @mock.patch.object(shade.OpenStackCloud, 'neutron_client') + def test_list_router_interfaces_no_gw(self, mock_client, mock_search): + """ + If a router does not have external_gateway_info, do not fail. + """ + external_port = {'id': 'external_port_id', + 'fixed_ips': [ + ('external_subnet_id', 'ip_address'), + ]} + port_list = [external_port] + router = { + 'id': 'router_id', + } + mock_search.return_value = port_list + ret = self.cloud.list_router_interfaces(router, + interface_type='external') + mock_search.assert_called_once_with( + filters={'device_id': router['id']} + ) + self.assertEqual([], ret) + @mock.patch.object(shade.OpenStackCloud, 'search_ports') @mock.patch.object(shade.OpenStackCloud, 'neutron_client') def test_list_router_interfaces_all(self, mock_client, mock_search):