Merge "Get instance networking information from Neutron"

This commit is contained in:
Jenkins
2014-02-17 16:33:55 +00:00
committed by Gerrit Code Review
6 changed files with 273 additions and 69 deletions

View File

@@ -130,3 +130,15 @@ def server_update_security_groups(request, instance_id,
def security_group_backend(request):
return NetworkClient(request).secgroups.backend
def servers_update_addresses(request, servers):
"""Retrieve servers networking information from Neutron if enabled.
Should be used when up to date networking information is required,
and Nova's networking info caching mechanism is not fast enough.
"""
neutron_enabled = base.is_service_enabled(request, 'network')
if neutron_enabled:
neutron.servers_update_addresses(request, servers)

View File

@@ -21,12 +21,15 @@
from __future__ import absolute_import
import collections
import logging
import netaddr
from django.conf import settings
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
from horizon import messages
from horizon.utils.memoized import memoized # noqa
from openstack_dashboard.api import base
@@ -321,12 +324,12 @@ class FloatingIpManager(network_base.FloatingIpManager):
return [FloatingIpPool(pool) for pool
in self.client.list_networks(**search_opts).get('networks')]
def list(self):
def list(self, **search_opts):
tenant_id = self.request.user.tenant_id
# In Neutron, list_floatingips returns Floating IPs from all tenants
# when the API is called with admin role, so we need to filter them
# with tenant_id.
fips = self.client.list_floatingips(tenant_id=tenant_id)
fips = self.client.list_floatingips(tenant_id=tenant_id, **search_opts)
fips = fips.get('floatingips')
# Get port list to add instance_id to floating IP list
# instance_id is stored in device_id attribute
@@ -732,6 +735,88 @@ def provider_list(request):
return providers['service_providers']
def servers_update_addresses(request, servers):
"""Retrieve servers networking information from Neutron if enabled.
Should be used when up to date networking information is required,
and Nova's networking info caching mechanism is not fast enough.
"""
# Get all (filtered for relevant servers) information from Neutron
try:
ports = port_list(request,
device_id=[instance.id for instance in servers])
floating_ips = FloatingIpManager(request).list(
port_id=[port.id for port in ports])
networks = network_list(request,
id=[port.network_id for port in ports])
except Exception:
error_message = _('Unable to connect to Neutron.')
LOG.error(error_message)
messages.error(request, error_message)
return
# Map instance to its ports
instances_ports = collections.defaultdict(list)
for port in ports:
instances_ports[port.device_id].append(port)
# Map port to its floating ips
ports_floating_ips = collections.defaultdict(list)
for fip in floating_ips:
ports_floating_ips[fip.port_id].append(fip)
# Map network id to its name
network_names = dict(((network.id, network.name) for network in networks))
for server in servers:
try:
addresses = _server_get_addresses(
request,
server,
instances_ports,
ports_floating_ips,
network_names)
except Exception as e:
LOG.error(e)
else:
server.addresses = addresses
def _server_get_addresses(request, server, ports, floating_ips, network_names):
def _format_address(mac, ip, type):
try:
version = netaddr.IPAddress(ip).version
except Exception as e:
error_message = _('Unable to parse IP address %s.') % ip
LOG.error(error_message)
messages.error(request, error_message)
raise e
return {u'OS-EXT-IPS-MAC:mac_addr': mac,
u'version': version,
u'addr': ip,
u'OS-EXT-IPS:type': type}
addresses = collections.defaultdict(list)
instance_ports = ports.get(server.id, [])
for port in instance_ports:
network_name = network_names.get(port.network_id)
if network_name is not None:
for fixed_ip in port.fixed_ips:
addresses[network_name].append(
_format_address(port.mac_address,
fixed_ip['ip_address'],
u'fixed'))
port_fips = floating_ips.get(port.id, [])
for fip in port_fips:
addresses[network_name].append(
_format_address(port.mac_address,
fip.floating_ip_address,
u'floating'))
return dict(addresses)
@memoized
def list_extensions(request):
extensions_list = neutronclient(request).list_extensions()

View File

@@ -20,6 +20,7 @@ from django.core.urlresolvers import reverse
from django import http
from django.utils.datastructures import SortedDict
from mox import IgnoreArg # noqa
from mox import IsA # noqa
from openstack_dashboard import api
@@ -32,7 +33,8 @@ INDEX_URL = reverse('horizon:admin:instances:index')
class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported',),
api.keystone: ('tenant_list',)})
api.keystone: ('tenant_list',),
api.network: ('servers_update_addresses',)})
def test_index(self):
servers = self.servers.list()
flavors = self.flavors.list()
@@ -45,6 +47,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
self.mox.ReplayAll()
@@ -55,7 +58,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list', 'extension_supported',),
api.keystone: ('tenant_list',)})
api.keystone: ('tenant_list',),
api.network: ('servers_update_addresses',)})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
tenants = self.tenants.list()
@@ -66,6 +70,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)). \
@@ -85,7 +90,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list', 'extension_supported', ),
api.keystone: ('tenant_list',)})
api.keystone: ('tenant_list',),
api.network: ('servers_update_addresses',)})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
@@ -99,6 +105,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)). \
@@ -164,14 +171,17 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported', ),
api.keystone: ('tenant_list',)})
api.keystone: ('tenant_list',),
api.network: ('servers_update_addresses',)})
def test_index_options_before_migrate(self):
servers = self.servers.list()
api.keystone.tenant_list(IsA(http.HttpRequest)).\
AndReturn([self.tenants.list(), False])
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)).\
@@ -185,7 +195,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported', ),
api.keystone: ('tenant_list',)})
api.keystone: ('tenant_list',),
api.network: ('servers_update_addresses',)})
def test_index_options_after_migrate(self):
servers = self.servers.list()
server1 = servers[0]
@@ -199,7 +210,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
.MultipleTimes().AndReturn(True)
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IsA(http.HttpRequest)).\
AndReturn(self.flavors.list())
self.mox.ReplayAll()

View File

@@ -80,6 +80,14 @@ class AdminIndexView(tables.DataTableView):
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))
if instances:
try:
api.network.servers_update_addresses(self.request, instances)
except Exception:
exceptions.handle(
self.request,
message=_('Unable to retrieve IP addresses from Neutron.'),
ignore=True)
# Gather our flavors to correlate against IDs
try:
flavors = api.nova.flavor_list(self.request)

View File

@@ -54,9 +54,11 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_index(self):
servers = self.servers.list()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
@@ -66,7 +68,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
api.network.floating_ip_simple_associate_supported(
@@ -106,7 +109,8 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
@@ -118,6 +122,7 @@ class InstanceTests(test.TestCase):
.MultipleTimes().AndReturn(True)
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndRaise(self.exceptions.nova)
api.glance.image_list_detailed(IgnoreArg()) \
@@ -146,7 +151,8 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
@@ -162,6 +168,7 @@ class InstanceTests(test.TestCase):
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
@@ -189,7 +196,8 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_index_with_instance_booted_from_volume(self):
volume_server = self.servers.first()
@@ -208,6 +216,7 @@ class InstanceTests(test.TestCase):
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
api.network.floating_ip_simple_associate_supported(
@@ -225,18 +234,20 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_list',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_terminate_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
api.nova.server_delete(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
formData = {'action': 'instances__terminate__%s' % server.id}
@@ -247,13 +258,16 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_list',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_terminate_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
@@ -271,9 +285,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_pause_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
@@ -284,7 +300,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_pause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@@ -298,9 +315,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_pause_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
@@ -311,7 +330,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_pause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@@ -326,9 +346,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_unpause_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
server.status = "PAUSED"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
@@ -339,7 +361,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_unpause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@@ -353,9 +376,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_unpause_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
server.status = "PAUSED"
api.nova.extension_supported('AdminActions',
@@ -367,7 +392,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_unpause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@@ -381,16 +407,19 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_reboot',
'server_list',
'flavor_list',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_reboot_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
soft_reboot=False)
@@ -404,9 +433,11 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_reboot',
'server_list',
'flavor_list',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_reboot_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
@@ -414,7 +445,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
soft_reboot=False) \
.AndRaise(self.exceptions.nova)
@@ -429,9 +461,11 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_reboot',
'server_list',
'flavor_list',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_soft_reboot_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
@@ -439,7 +473,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
soft_reboot=True)
@@ -454,9 +489,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_suspend_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
@@ -467,7 +504,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@@ -481,9 +519,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_suspend_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
@@ -494,7 +534,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@@ -509,9 +550,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_resume_instance(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
server.status = "SUSPENDED"
api.nova.extension_supported('AdminActions',
@@ -523,7 +566,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_resume(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@@ -537,9 +581,11 @@ class InstanceTests(test.TestCase):
'server_list',
'flavor_list',
'extension_supported',),
api.glance: ('image_list_detailed',)})
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_resume_instance_exception(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
server.status = "SUSPENDED"
api.nova.extension_supported('AdminActions',
@@ -551,7 +597,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.server_resume(IsA(http.HttpRequest),
unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@@ -566,12 +613,15 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ("server_get",
"instance_volumes_list",
"flavor_get"),
api.network: ("server_security_groups",)})
api.network: ("server_security_groups",
"servers_update_addresses")})
def test_instance_details_volumes(self):
server = self.servers.first()
volumes = [self.volumes.list()[1]]
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.network.servers_update_addresses(IsA(http.HttpRequest),
IgnoreArg())
api.nova.instance_volumes_list(IsA(http.HttpRequest),
server.id).AndReturn(volumes)
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
@@ -590,12 +640,15 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ("server_get",
"instance_volumes_list",
"flavor_get"),
api.network: ("server_security_groups",)})
api.network: ("server_security_groups",
"servers_update_addresses")})
def test_instance_details_volume_sorting(self):
server = self.servers.first()
volumes = self.volumes.list()[1:3]
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.network.servers_update_addresses(IsA(http.HttpRequest),
IgnoreArg())
api.nova.instance_volumes_list(IsA(http.HttpRequest),
server.id).AndReturn(volumes)
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
@@ -618,11 +671,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ("server_get",
"instance_volumes_list",
"flavor_get"),
api.network: ("server_security_groups",)})
api.network: ("server_security_groups",
"servers_update_addresses")})
def test_instance_details_metadata(self):
server = self.servers.first()
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.network.servers_update_addresses(IsA(http.HttpRequest),
IgnoreArg())
api.nova.instance_volumes_list(IsA(http.HttpRequest),
server.id).AndReturn([])
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
@@ -650,7 +706,8 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ("server_get",
"instance_volumes_list",
"flavor_get"),
api.network: ("server_security_groups",)})
api.network: ("server_security_groups",
"servers_update_addresses")})
def test_instance_details_fault(self):
server = self.servers.first()
@@ -666,6 +723,8 @@ class InstanceTests(test.TestCase):
"created": "2013-10-07T00:08:32Z"}
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.network.servers_update_addresses(IsA(http.HttpRequest),
IgnoreArg())
api.nova.instance_volumes_list(IsA(http.HttpRequest),
server.id).AndReturn([])
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
@@ -1892,9 +1951,11 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_launch_button_disabled_when_quota_exceeded(self):
servers = self.servers.list()
limits = self.limits['absolute']
limits['totalInstancesUsed'] = limits['maxTotalInstances']
@@ -1907,7 +1968,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(limits)
api.network.floating_ip_simple_associate_supported(
@@ -1933,9 +1995,11 @@ class InstanceTests(test.TestCase):
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network:
('floating_ip_simple_associate_supported',),
('floating_ip_simple_associate_supported',
'servers_update_addresses',),
})
def test_index_options_after_migrate(self):
servers = self.servers.list()
server = self.servers.first()
server.status = "VERIFY_RESIZE"
api.nova.extension_supported('AdminActions',
@@ -1947,7 +2011,8 @@ class InstanceTests(test.TestCase):
.AndReturn((self.images.list(), False))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
api.network.floating_ip_simple_associate_supported(
@@ -2027,17 +2092,20 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
'tenant_floating_ip_allocate',
'floating_ip_associate'),
'floating_ip_associate',
'servers_update_addresses',),
api.glance: ('image_list_detailed',),
api.nova: ('server_list',
'flavor_list')})
def test_associate_floating_ip(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
fip = self.q_floating_ips.first()
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
@@ -2058,18 +2126,21 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
'tenant_floating_ip_list',
'floating_ip_disassociate',),
'floating_ip_disassociate',
'servers_update_addresses',),
api.glance: ('image_list_detailed',),
api.nova: ('server_list',
'flavor_list')})
def test_disassociate_floating_ip(self):
server = self.servers.first()
servers = self.servers.list()
server = servers[0]
fip = self.q_floating_ips.first()
fip.port_id = server.id
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
.AndReturn([servers, False])
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))

View File

@@ -67,8 +67,17 @@ class IndexView(tables.DataTableView):
instances = []
exceptions.handle(self.request,
_('Unable to retrieve instances.'))
# Gather our flavors and images and correlate our instances to them
if instances:
try:
api.network.servers_update_addresses(self.request, instances)
except Exception:
exceptions.handle(
self.request,
message=_('Unable to retrieve IP addresses from Neutron.'),
ignore=True)
# Gather our flavors and images and correlate our instances to them
try:
flavors = api.nova.flavor_list(self.request)
except Exception:
@@ -233,6 +242,13 @@ class DetailView(tabs.TabView):
_('Unable to retrieve details for '
'instance "%s".') % instance_id,
redirect=redirect)
try:
api.network.servers_update_addresses(self.request, [instance])
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve IP addresses from Neutron for instance '
'"%s".') % instance_id, ignore=True)
return instance
def get_tabs(self, request, *args, **kwargs):