diff --git a/shade/meta.py b/shade/meta.py index cf978ccf1..158750bb2 100644 --- a/shade/meta.py +++ b/shade/meta.py @@ -277,6 +277,32 @@ def expand_server_vars(cloud, server): return add_server_interfaces(cloud, server) +def _make_address_dict(fip): + address = dict(version=4, addr=fip['floating_ip_address']) + address['OS-EXT-IPS:type'] = 'floating' + # MAC address comes from the port, not the FIP. It also doesn't matter + # to anyone at the moment, so just make a fake one + address['OS-EXT-IPS-MAC:mac_addr'] = 'de:ad:be:ef:be:ef' + return address + + +def _get_suplemental_addresses(cloud, server): + fixed_ip_mapping = {} + for name, network in server['addresses'].items(): + for address in network: + if address['version'] == 6: + continue + if address['OS-EXT-IPS:type'] == 'floating': + # We have a floating IP that nova knows about, do nothing + return server['addresses'] + fixed_ip_mapping[address['addr']] = name + for fip in cloud.list_floating_ips(): + if fip['fixed_ip_address'] in fixed_ip_mapping: + fixed_net = fixed_ip_mapping[fip['fixed_ip_address']] + server['addresses'][fixed_net].append(_make_address_dict(fip)) + return server['addresses'] + + def add_server_interfaces(cloud, server): """Add network interface information to server. @@ -288,6 +314,7 @@ def add_server_interfaces(cloud, server): """ # First, add an IP address. Set it to '' rather than None if it does # not exist to remain consistent with the pre-existing missing values + server['addresses'] = _get_suplemental_addresses(cloud, server) server['public_v4'] = get_server_external_ipv4(cloud, server) or '' server['public_v6'] = get_server_external_ipv6(server) or '' server['private_v4'] = get_server_private_ip(server, cloud) or '' diff --git a/shade/tests/unit/test_create_server.py b/shade/tests/unit/test_create_server.py index c03382f91..5c8a79bd2 100644 --- a/shade/tests/unit/test_create_server.py +++ b/shade/tests/unit/test_create_server.py @@ -92,11 +92,15 @@ class TestCreateServer(base.TestCase): with patch("shade.OpenStackCloud"): build_server = fakes.FakeServer('1234', '', 'BUILD') error_server = fakes.FakeServer('1234', '', 'ERROR') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.create.return_value": build_server, "servers.get.return_value": build_server, "servers.list.side_effect": [ - [build_server], [error_server]] + [build_server], [error_server]], + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.assertRaises( @@ -129,9 +133,13 @@ class TestCreateServer(base.TestCase): """ with patch("shade.OpenStackCloud"): fake_server = fakes.FakeServer('1234', '', 'BUILD') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.create.return_value": fake_server, - "servers.get.return_value": fake_server + "servers.get.return_value": fake_server, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.assertEqual( @@ -151,9 +159,13 @@ class TestCreateServer(base.TestCase): fake_server = fakes.FakeServer('1234', '', 'BUILD') fake_create_server = fakes.FakeServer('1234', '', 'BUILD', adminPass='ooBootheiX0edoh') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.create.return_value": fake_create_server, - "servers.get.return_value": fake_server + "servers.get.return_value": fake_server, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.assertEqual( @@ -256,12 +268,16 @@ class TestCreateServer(base.TestCase): with patch("shade.OpenStackCloud"): build_server = fakes.FakeServer('1234', '', 'BUILD') fake_server = fakes.FakeServer('1234', '', 'ACTIVE') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.create.return_value": build_server, "servers.get.return_value": [build_server, None], "servers.list.side_effect": [ [build_server], [fake_server]], "servers.delete.return_value": None, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.client._SERVER_AGE = 0 diff --git a/shade/tests/unit/test_meta.py b/shade/tests/unit/test_meta.py index 66f64f85a..406903bf5 100644 --- a/shade/tests/unit/test_meta.py +++ b/shade/tests/unit/test_meta.py @@ -182,6 +182,7 @@ class TestMeta(base.TestCase): mock_has_service.assert_called_with('network') mock_list_networks.assert_called_once_with() + @mock.patch.object(shade.OpenStackCloud, 'list_floating_ips') @mock.patch.object(shade.OpenStackCloud, 'list_subnets') @mock.patch.object(shade.OpenStackCloud, 'list_server_security_groups') @mock.patch.object(shade.OpenStackCloud, 'get_volumes') @@ -194,7 +195,8 @@ class TestMeta(base.TestCase): mock_get_flavor_name, mock_get_image_name, mock_get_volumes, mock_list_server_security_groups, - mock_list_subnets): + mock_list_subnets, + mock_list_floating_ips): mock_get_image_name.return_value = 'cirros-0.3.4-x86_64-uec' mock_get_flavor_name.return_value = 'm1.tiny' mock_has_service.return_value = True @@ -211,6 +213,7 @@ class TestMeta(base.TestCase): 'name': 'private', }, ] + mock_list_floating_ips.return_value = [] srv = self.cloud.get_openstack_vars(meta.obj_to_dict(fakes.FakeServer( id='test-id', name='test-name', status='ACTIVE', @@ -230,6 +233,7 @@ class TestMeta(base.TestCase): self.assertEqual(PRIVATE_V4, srv['private_v4']) mock_has_service.assert_called_with('volume') mock_list_networks.assert_called_once_with() + mock_list_floating_ips.assert_called_once_with() @mock.patch.object(shade.OpenStackCloud, 'has_service') @mock.patch.object(shade.OpenStackCloud, 'list_subnets') diff --git a/shade/tests/unit/test_rebuild_server.py b/shade/tests/unit/test_rebuild_server.py index b87a4da75..8156e57e4 100644 --- a/shade/tests/unit/test_rebuild_server.py +++ b/shade/tests/unit/test_rebuild_server.py @@ -56,10 +56,14 @@ class TestRebuildServer(base.TestCase): """ rebuild_server = fakes.FakeServer('1234', '', 'REBUILD') error_server = fakes.FakeServer('1234', '', 'ERROR') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') with patch("shade.OpenStackCloud"): config = { "servers.rebuild.return_value": rebuild_server, "servers.get.return_value": error_server, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.assertRaises( @@ -122,9 +126,13 @@ class TestRebuildServer(base.TestCase): active_server = fakes.FakeServer('1234', '', 'ACTIVE') ret_active_server = fakes.FakeServer('1234', '', 'ACTIVE', adminPass='ooBootheiX0edoh') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.rebuild.return_value": rebuild_server, "servers.get.return_value": active_server, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.client.name = 'cloud-name' @@ -143,9 +151,13 @@ class TestRebuildServer(base.TestCase): with patch("shade.OpenStackCloud"): rebuild_server = fakes.FakeServer('1234', '', 'REBUILD') active_server = fakes.FakeServer('1234', '', 'ACTIVE') + fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool', + '1.1.1.1', '2.2.2.2', + '5678') config = { "servers.rebuild.return_value": rebuild_server, - "servers.get.return_value": active_server + "servers.get.return_value": active_server, + "floating_ips.list.return_value": [fake_floating_ip] } OpenStackCloud.nova_client = Mock(**config) self.client.name = 'cloud-name'