Merge "Show floating IP associated with Load Balancer VIP"

This commit is contained in:
Jenkins 2014-09-18 22:40:52 +00:00 committed by Gerrit Code Review
commit f2026086ff
4 changed files with 83 additions and 27 deletions

View File

@ -302,7 +302,8 @@ class SecurityGroupManager(network_base.SecurityGroupManager):
class FloatingIp(base.APIDictWrapper): class FloatingIp(base.APIDictWrapper):
_attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id', 'pool'] _attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id',
'instance_type', 'pool']
def __init__(self, fip): def __init__(self, fip):
fip['ip'] = fip['floating_ip_address'] fip['ip'] = fip['floating_ip_address']
@ -320,6 +321,12 @@ class FloatingIpTarget(base.APIDictWrapper):
class FloatingIpManager(network_base.FloatingIpManager): class FloatingIpManager(network_base.FloatingIpManager):
device_owner_map = {
'compute:': 'compute',
'neutron:LOADBALANCER': 'loadbalancer',
}
def __init__(self, request): def __init__(self, request):
self.request = request self.request = request
self.client = neutronclient(request) self.client = neutronclient(request)
@ -329,6 +336,23 @@ class FloatingIpManager(network_base.FloatingIpManager):
return [FloatingIpPool(pool) for pool return [FloatingIpPool(pool) for pool
in self.client.list_networks(**search_opts).get('networks')] in self.client.list_networks(**search_opts).get('networks')]
def _get_instance_type_from_device_owner(self, device_owner):
for key, value in self.device_owner_map.items():
if device_owner.startswith(key):
return value
return device_owner
def _set_instance_info(self, fip, port=None):
if fip['port_id']:
if not port:
port = port_get(self.request, fip['port_id'])
fip['instance_id'] = port.device_id
fip['instance_type'] = self._get_instance_type_from_device_owner(
port.device_owner)
else:
fip['instance_id'] = None
fip['instance_type'] = None
def list(self, all_tenants=False, **search_opts): def list(self, all_tenants=False, **search_opts):
if not all_tenants: if not all_tenants:
tenant_id = self.request.user.tenant_id tenant_id = self.request.user.tenant_id
@ -344,27 +368,20 @@ class FloatingIpManager(network_base.FloatingIpManager):
# Get port list to add instance_id to floating IP list # Get port list to add instance_id to floating IP list
# instance_id is stored in device_id attribute # instance_id is stored in device_id attribute
ports = port_list(self.request, **port_search_opts) ports = port_list(self.request, **port_search_opts)
device_id_dict = SortedDict([(p['id'], p['device_id']) for p in ports]) port_dict = SortedDict([(p['id'], p) for p in ports])
for fip in fips: for fip in fips:
if fip['port_id']: self._set_instance_info(fip, port_dict.get(fip['port_id']))
fip['instance_id'] = device_id_dict[fip['port_id']]
else:
fip['instance_id'] = None
return [FloatingIp(fip) for fip in fips] return [FloatingIp(fip) for fip in fips]
def get(self, floating_ip_id): def get(self, floating_ip_id):
fip = self.client.show_floatingip(floating_ip_id).get('floatingip') fip = self.client.show_floatingip(floating_ip_id).get('floatingip')
if fip['port_id']: self._set_instance_info(fip)
fip['instance_id'] = port_get(self.request,
fip['port_id']).device_id
else:
fip['instance_id'] = None
return FloatingIp(fip) return FloatingIp(fip)
def allocate(self, pool): def allocate(self, pool):
body = {'floatingip': {'floating_network_id': pool}} body = {'floatingip': {'floating_network_id': pool}}
fip = self.client.create_floatingip(body).get('floatingip') fip = self.client.create_floatingip(body).get('floatingip')
fip['instance_id'] = None self._set_instance_info(fip)
return FloatingIp(fip) return FloatingIp(fip)
def release(self, floating_ip_id): def release(self, floating_ip_id):

View File

@ -342,10 +342,13 @@ class FlavorExtraSpec(object):
class FloatingIp(base.APIResourceWrapper): class FloatingIp(base.APIResourceWrapper):
_attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id', 'pool'] _attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id',
'instance_type', 'pool']
def __init__(self, fip): def __init__(self, fip):
fip.__setattr__('port_id', fip.instance_id) fip.__setattr__('port_id', fip.instance_id)
fip.__setattr__('instance_type',
'compute' if fip.instance_id else None)
super(FloatingIp, self).__init__(fip) super(FloatingIp, self).__init__(fip)

View File

@ -16,7 +16,7 @@
import logging import logging
from django.conf import settings from django.conf import settings
from django.core import urlresolvers from django.core.urlresolvers import reverse
from django import shortcuts from django import shortcuts
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.translation import string_concat # noqa from django.utils.translation import string_concat # noqa
@ -119,7 +119,7 @@ class AssociateIP(tables.LinkAction):
return not fip.port_id and POLICY_CHECK(policy, request) return not fip.port_id and POLICY_CHECK(policy, request)
def get_link_url(self, datum): def get_link_url(self, datum):
base_url = urlresolvers.reverse(self.url) base_url = reverse(self.url)
params = urlencode({"ip_id": self.table.get_object_id(datum)}) params = urlencode({"ip_id": self.table.get_object_id(datum)})
return "?".join([base_url, params]) return "?".join([base_url, params])
@ -153,14 +153,23 @@ class DisassociateIP(tables.Action):
return shortcuts.redirect('horizon:project:access_and_security:index') return shortcuts.redirect('horizon:project:access_and_security:index')
def get_instance_info(instance): def get_instance_info(fip):
return getattr(instance, "instance_name", None) if fip.instance_type == 'compute':
return (_("%(instance_name)s %(fixed_ip)s")
% {'instance_name': getattr(fip, "instance_name", ''),
'fixed_ip': fip.fixed_ip})
elif fip.instance_type == 'loadbalancer':
return _("Load Balancer VIP %s") % fip.fixed_ip
elif fip.instance_type:
return fip.fixed_ip
else:
return None
def get_instance_link(datum): def get_instance_link(datum):
view = "horizon:project:instances:detail" if datum.instance_type == 'compute':
if datum.instance_id: return reverse("horizon:project:instances:detail",
return urlresolvers.reverse(view, args=(datum.instance_id,)) args=(datum.instance_id,))
else: else:
return None return None
@ -169,9 +178,9 @@ class FloatingIPsTable(tables.DataTable):
ip = tables.Column("ip", ip = tables.Column("ip",
verbose_name=_("IP Address"), verbose_name=_("IP Address"),
attrs={'data-type': "ip"}) attrs={'data-type': "ip"})
instance = tables.Column(get_instance_info, fixed_ip = tables.Column(get_instance_info,
link=get_instance_link, link=get_instance_link,
verbose_name=_("Instance"), verbose_name=_("Mapped Fixed IP Address"),
empty_value="-") empty_value="-")
pool = tables.Column("pool_name", pool = tables.Column("pool_name",
verbose_name=_("Floating IP Pool"), verbose_name=_("Floating IP Pool"),

View File

@ -124,6 +124,8 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
self.assertEqual(getattr(e, attr), getattr(r, attr)) self.assertEqual(getattr(e, attr), getattr(r, attr))
self.assertEqual(e.instance_id, r.port_id) self.assertEqual(e.instance_id, r.port_id)
exp_instance_type = 'compute' if e.instance_id else None
self.assertEqual(exp_instance_type, r.instance_type)
def test_floating_ip_get(self): def test_floating_ip_get(self):
fip = self.api_floating_ips.first() fip = self.api_floating_ips.first()
@ -136,10 +138,13 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
self.assertEqual(getattr(fip, attr), getattr(ret, attr)) self.assertEqual(getattr(fip, attr), getattr(ret, attr))
self.assertEqual(fip.instance_id, ret.port_id) self.assertEqual(fip.instance_id, ret.port_id)
self.assertEqual(fip.instance_id, ret.instance_id)
self.assertEqual('compute', ret.instance_type)
def test_floating_ip_allocate(self): def test_floating_ip_allocate(self):
pool_name = 'fip_pool' pool_name = 'fip_pool'
fip = self.api_floating_ips.first() fip = [fip for fip in self.api_floating_ips.list()
if not fip.instance_id][0]
novaclient = self.stub_novaclient() novaclient = self.stub_novaclient()
novaclient.floating_ips = self.mox.CreateMockAnything() novaclient.floating_ips = self.mox.CreateMockAnything()
novaclient.floating_ips.create(pool=pool_name).AndReturn(fip) novaclient.floating_ips.create(pool=pool_name).AndReturn(fip)
@ -148,7 +153,8 @@ class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
ret = api.network.tenant_floating_ip_allocate(self.request, pool_name) ret = api.network.tenant_floating_ip_allocate(self.request, pool_name)
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
self.assertEqual(getattr(fip, attr), getattr(ret, attr)) self.assertEqual(getattr(fip, attr), getattr(ret, attr))
self.assertEqual(fip.instance_id, ret.port_id) self.assertIsNone(ret.port_id)
self.assertIsNone(ret.instance_type)
def test_floating_ip_release(self): def test_floating_ip_release(self):
fip = self.api_floating_ips.first() fip = self.api_floating_ips.first()
@ -557,6 +563,10 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
if exp['port_id']: if exp['port_id']:
dev_id = assoc_port['device_id'] if exp['port_id'] else None dev_id = assoc_port['device_id'] if exp['port_id'] else None
self.assertEqual(dev_id, ret.instance_id) self.assertEqual(dev_id, ret.instance_id)
self.assertEqual('compute', ret.instance_type)
else:
self.assertIsNone(ret.instance_id)
self.assertIsNone(ret.instance_type)
def test_floating_ip_list_all_tenants(self): def test_floating_ip_list_all_tenants(self):
fips = self.api_q_floating_ips.list() fips = self.api_q_floating_ips.list()
@ -581,11 +591,14 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
self.assertEqual(getattr(ret, attr), exp[attr]) self.assertEqual(getattr(ret, attr), exp[attr])
if exp['port_id']: if exp['port_id']:
dev_id = assoc_port['device_id'] if exp['port_id'] else None dev_id = assoc_port['device_id'] if exp['port_id'] else None
self.assertEqual(ret.instance_id, dev_id) self.assertEqual(dev_id, ret.instance_id)
self.assertEqual('compute', ret.instance_type)
else:
self.assertIsNone(ret.instance_id)
self.assertIsNone(ret.instance_type)
def test_floating_ip_get_associated(self): def _test_floating_ip_get_associated(self, assoc_port, exp_instance_type):
fip = self.api_q_floating_ips.list()[1] fip = self.api_q_floating_ips.list()[1]
assoc_port = self.api_ports.list()[1]
self.qclient.show_floatingip(fip['id']).AndReturn({'floatingip': fip}) self.qclient.show_floatingip(fip['id']).AndReturn({'floatingip': fip})
self.qclient.show_port(assoc_port['id']) \ self.qclient.show_port(assoc_port['id']) \
.AndReturn({'port': assoc_port}) .AndReturn({'port': assoc_port})
@ -595,6 +608,18 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
self.assertEqual(fip[attr], getattr(ret, attr)) self.assertEqual(fip[attr], getattr(ret, attr))
self.assertEqual(assoc_port['device_id'], ret.instance_id) self.assertEqual(assoc_port['device_id'], ret.instance_id)
self.assertEqual(exp_instance_type, ret.instance_type)
def test_floating_ip_get_associated(self):
assoc_port = self.api_ports.list()[1]
self._test_floating_ip_get_associated(assoc_port, 'compute')
def test_floating_ip_get_associated_with_loadbalancer_vip(self):
assoc_port = copy.deepcopy(self.api_ports.list()[1])
assoc_port['device_owner'] = 'neutron:LOADBALANCER'
assoc_port['device_id'] = str(uuid.uuid4())
assoc_port['name'] = 'vip-' + str(uuid.uuid4())
self._test_floating_ip_get_associated(assoc_port, 'loadbalancer')
def test_floating_ip_get_unassociated(self): def test_floating_ip_get_unassociated(self):
fip = self.api_q_floating_ips.list()[0] fip = self.api_q_floating_ips.list()[0]
@ -605,6 +630,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
self.assertEqual(fip[attr], getattr(ret, attr)) self.assertEqual(fip[attr], getattr(ret, attr))
self.assertIsNone(ret.instance_id) self.assertIsNone(ret.instance_id)
self.assertIsNone(ret.instance_type)
def test_floating_ip_allocate(self): def test_floating_ip_allocate(self):
ext_nets = [n for n in self.api_networks.list() ext_nets = [n for n in self.api_networks.list()
@ -621,6 +647,7 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']: for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
self.assertEqual(fip[attr], getattr(ret, attr)) self.assertEqual(fip[attr], getattr(ret, attr))
self.assertIsNone(ret.instance_id) self.assertIsNone(ret.instance_id)
self.assertIsNone(ret.instance_type)
def test_floating_ip_release(self): def test_floating_ip_release(self):
fip = self.api_q_floating_ips.first() fip = self.api_q_floating_ips.first()