Allow admin user to get all tenant's floating IPs
When getting floatingips by Nova API, the results will be filtered with the 'tenant_id'. So, we can only get the floatingips belonging the tenant of current context. When ceilometer invokes novaclient to list floatingips, it will get an empty list because the tenant is 'service'. we should allow an admin user to index all tenants's floatingip by adding a parameter 'all_tenants'. Part1: part1 try to implement this and part2 will remove the unused codes. Change-Id: I7ab1d5ff463fc29928f6811f846c9e204390a412 Closes-bug: #1262124
This commit is contained in:
parent
693223e0d4
commit
6478554f53
|
@ -141,6 +141,7 @@
|
|||
"compute_extension:floating_ip_dns": "",
|
||||
"compute_extension:floating_ip_pools": "",
|
||||
"compute_extension:floating_ips": "",
|
||||
"compute_extension:floating_ips:all_tenants": "rule:admin_api",
|
||||
"compute_extension:floating_ips_bulk": "rule:admin_api",
|
||||
"compute_extension:fping": "",
|
||||
"compute_extension:fping:all_tenants": "rule:admin_api",
|
||||
|
@ -292,6 +293,7 @@
|
|||
"network:get_backdoor_port": "",
|
||||
|
||||
"network:get_floating_ip": "",
|
||||
"network:get_floating_ips": "",
|
||||
"network:get_floating_ip_pools": "",
|
||||
"network:get_floating_ip_by_address": "",
|
||||
"network:get_floating_ips_by_project": "",
|
||||
|
|
|
@ -1212,7 +1212,7 @@ class CloudController(object):
|
|||
address)
|
||||
floatings.append(floating)
|
||||
else:
|
||||
floatings = self.network_api.get_floating_ips_by_project(context)
|
||||
floatings = self.network_api.get_floating_ips(context)
|
||||
addresses = [self._format_address(context, f) for f in floatings]
|
||||
return {'addressesSet': addresses}
|
||||
|
||||
|
|
|
@ -27,11 +27,14 @@ from nova import exception
|
|||
from nova import network
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import strutils
|
||||
from nova.openstack.common import uuidutils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
authorize = extensions.extension_authorizer('compute', 'floating_ips')
|
||||
authorize_all_tenants = extensions.extension_authorizer(
|
||||
'compute', 'floating_ips:all_tenants')
|
||||
|
||||
|
||||
def make_float_ip(elem):
|
||||
|
@ -135,11 +138,19 @@ class FloatingIPController(object):
|
|||
|
||||
@wsgi.serializers(xml=FloatingIPsTemplate)
|
||||
def index(self, req):
|
||||
"""Return a list of floating ips allocated to a project."""
|
||||
"""Return a list of floating ips."""
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
all_tenants = False
|
||||
if 'all_tenants' in req.GET:
|
||||
try:
|
||||
if strutils.bool_from_string(req.GET['all_tenants'], True):
|
||||
authorize_all_tenants(context)
|
||||
all_tenants = True
|
||||
except ValueError as err:
|
||||
raise webob.exc.HTTPBadRequest(explanation=str(err))
|
||||
|
||||
floating_ips = self.network_api.get_floating_ips_by_project(context)
|
||||
floating_ips = self.network_api.get_floating_ips(context, all_tenants)
|
||||
|
||||
for floating_ip in floating_ips:
|
||||
self._normalize_ip(floating_ip)
|
||||
|
|
|
@ -128,6 +128,14 @@ class API(base_api.NetworkAPI):
|
|||
return self.db.floating_ip_get_all_by_project(context,
|
||||
context.project_id)
|
||||
|
||||
@wrap_check_policy
|
||||
def get_floating_ips(self, context, all_tenants=False):
|
||||
if all_tenants:
|
||||
return self.db.floating_ip_get_all(context)
|
||||
else:
|
||||
return self.db.floating_ip_get_all_by_project(context,
|
||||
context.project_id)
|
||||
|
||||
@wrap_check_policy
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
floating_ips = self.db.floating_ip_get_by_fixed_address(context,
|
||||
|
|
|
@ -877,6 +877,20 @@ class API(base_api.NetworkAPI):
|
|||
return [self._format_floating_ip_model(fip, pool_dict, port_dict)
|
||||
for fip in fips]
|
||||
|
||||
def get_floating_ips(self, context, all_tenants=False):
|
||||
client = neutronv2.get_client(context)
|
||||
project_id = context.project_id
|
||||
if all_tenants:
|
||||
fips = client.list_floatingips()['floatingips']
|
||||
port_dict = self._setup_ports_dict(client)
|
||||
else:
|
||||
fips = client.list_floatingips(
|
||||
tenant_id=project_id)['floatingips']
|
||||
port_dict = self._setup_ports_dict(client, project_id)
|
||||
pool_dict = self._setup_pools_dict(client)
|
||||
return [self._format_floating_ip_model(fip, pool_dict, port_dict)
|
||||
for fip in fips]
|
||||
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
|
|
@ -42,6 +42,24 @@ def network_api_get_floating_ip(self, context, id):
|
|||
'fixed_ip_id': None}
|
||||
|
||||
|
||||
def network_api_get_floating_ips(self, context, all_tenants=False):
|
||||
ret = [{'id': 1,
|
||||
'address': '10.10.10.10',
|
||||
'pool': 'nova',
|
||||
'fixed_ip': {'address': '10.0.0.1',
|
||||
'instance': {'uuid': FAKE_UUID}}},
|
||||
{'id': 2,
|
||||
'pool': 'nova', 'interface': 'eth0',
|
||||
'address': '10.10.10.11',
|
||||
'fixed_ip': None}]
|
||||
if all_tenants:
|
||||
ret.append({'id': 3,
|
||||
'pool': 'nova', 'interface': 'eth1',
|
||||
'address': '10.10.10.12',
|
||||
'fixed_ip': None})
|
||||
return ret
|
||||
|
||||
|
||||
def network_api_get_floating_ip_by_address(self, context, address):
|
||||
return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova',
|
||||
'fixed_ip_id': 10}
|
||||
|
@ -132,6 +150,8 @@ class FloatingIpTest(test.TestCase):
|
|||
compute_api_get)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip",
|
||||
network_api_get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "get_floating_ips",
|
||||
network_api_get_floating_ips)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_address",
|
||||
network_api_get_floating_ip_by_address)
|
||||
self.stubs.Set(network.api.API, "get_floating_ips_by_project",
|
||||
|
@ -202,6 +222,35 @@ class FloatingIpTest(test.TestCase):
|
|||
'id': 2}]}
|
||||
self.assertEqual(res_dict, response)
|
||||
|
||||
def test_floating_ips_list_all_tenants_admin(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-floating-ips/?all_tenants=1',
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
response = {'floating_ips': [{'instance_id': FAKE_UUID,
|
||||
'ip': '10.10.10.10',
|
||||
'pool': 'nova',
|
||||
'fixed_ip': '10.0.0.1',
|
||||
'id': 1},
|
||||
{'instance_id': None,
|
||||
'ip': '10.10.10.11',
|
||||
'pool': 'nova',
|
||||
'fixed_ip': None,
|
||||
'id': 2},
|
||||
{'instance_id': None,
|
||||
'ip': '10.10.10.12',
|
||||
'pool': 'nova',
|
||||
'fixed_ip': None,
|
||||
'id': 3}]}
|
||||
self.assertEqual(response, res_dict)
|
||||
|
||||
def test_floating_ips_list_all_tenants_not_admin(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-floating-ips/?all_tenants=1',
|
||||
use_admin_context=False)
|
||||
self.assertRaises(exception.Forbidden, self.controller.index, req)
|
||||
|
||||
def test_floating_ip_release_nonexisting(self):
|
||||
def fake_get_floating_ip(*args, **kwargs):
|
||||
raise exception.FloatingIpNotFound(id=id)
|
||||
|
@ -625,6 +674,8 @@ class ExtendedFloatingIpTest(test.TestCase):
|
|||
compute_api_get)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip",
|
||||
network_api_get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "get_floating_ips",
|
||||
network_api_get_floating_ips)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_address",
|
||||
network_api_get_floating_ip_by_address)
|
||||
self.stubs.Set(network.api.API, "get_floating_ips_by_project",
|
||||
|
|
|
@ -199,6 +199,7 @@ policy_data = """
|
|||
"compute_extension:floating_ip_dns": "",
|
||||
"compute_extension:floating_ip_pools": "",
|
||||
"compute_extension:floating_ips": "",
|
||||
"compute_extension:floating_ips:all_tenants": "rule:admin_api",
|
||||
"compute_extension:floating_ips_bulk": "",
|
||||
"compute_extension:fping": "",
|
||||
"compute_extension:fping:all_tenants": "is_admin:True",
|
||||
|
@ -345,6 +346,7 @@ policy_data = """
|
|||
"network:setup_networks_on_host": "",
|
||||
|
||||
"network:get_floating_ip": "",
|
||||
"network:get_floating_ips": "",
|
||||
"network:get_floating_ip_pools": "",
|
||||
"network:get_floating_ip_by_address": "",
|
||||
"network:get_floating_ips_by_project": "",
|
||||
|
|
|
@ -155,6 +155,24 @@ class ApiTestCase(test.TestCase):
|
|||
def test_associate_unassociated_floating_ip(self):
|
||||
self._do_test_associate_floating_ip(None)
|
||||
|
||||
def test_get_floating_ips(self):
|
||||
self.mox.StubOutWithMock(self.network_api.db, 'floating_ip_get_all')
|
||||
self.network_api.db.floating_ip_get_all(self.context).AndReturn(
|
||||
['project1-floating-ip', 'project2-floating-ip'])
|
||||
self.mox.StubOutWithMock(self.network_api.db,
|
||||
'floating_ip_get_all_by_project')
|
||||
self.network_api.db.\
|
||||
floating_ip_get_all_by_project(self.context,
|
||||
self.context.project_id).\
|
||||
AndReturn(['project1-floating-ip'])
|
||||
self.mox.ReplayAll()
|
||||
floating_ips = self.network_api.get_floating_ips(self.context)
|
||||
floating_ips_all = self.network_api.get_floating_ips(self.context,
|
||||
all_tenants=True)
|
||||
self.assertEqual(['project1-floating-ip'], floating_ips)
|
||||
self.assertEqual(['project1-floating-ip', 'project2-floating-ip'],
|
||||
floating_ips_all)
|
||||
|
||||
def test_get_floating_ip_invalid_id(self):
|
||||
self.assertRaises(exception.InvalidID,
|
||||
self.network_api.get_floating_ip,
|
||||
|
|
|
@ -268,6 +268,14 @@ class TestNeutronv2Base(test.TestCase):
|
|||
'port_id': None,
|
||||
'fixed_ip_address': None,
|
||||
'router_id': None}
|
||||
self.fip_unassociated_not_my = {'tenant_id': 'not_my_tenantid',
|
||||
'id': 'fip_id3',
|
||||
'floating_ip_address': '172.24.4.227',
|
||||
'floating_network_id': self.fip_pool[
|
||||
'id'],
|
||||
'port_id': None,
|
||||
'fixed_ip_address': None,
|
||||
'router_id': None}
|
||||
fixed_ip_address = self.port_data2[1]['fixed_ips'][0]['ip_address']
|
||||
self.fip_associated = {'tenant_id': 'my_tenantid',
|
||||
'id': 'fip_id2',
|
||||
|
@ -1615,6 +1623,44 @@ class TestNeutronv2(TestNeutronv2Base):
|
|||
fips = api.get_floating_ips_by_project(self.context)
|
||||
self.assertEqual(expected, fips)
|
||||
|
||||
def test_get_floating_ips(self):
|
||||
api = neutronapi.API()
|
||||
project_id = self.context.project_id
|
||||
self.moxed_client.list_floatingips(tenant_id=project_id).\
|
||||
AndReturn({'floatingips': [self.fip_unassociated,
|
||||
self.fip_associated]})
|
||||
|
||||
self.moxed_client.list_ports(tenant_id=project_id). \
|
||||
AndReturn({'ports': self.port_data2})
|
||||
search_opts = {'router:external': True}
|
||||
self.moxed_client.list_networks(**search_opts). \
|
||||
AndReturn({'networks': [self.fip_pool, self.fip_pool_nova]})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
expected = [self._get_expected_fip_model(self.fip_unassociated),
|
||||
self._get_expected_fip_model(self.fip_associated, idx=1)]
|
||||
fips = api.get_floating_ips(self.context)
|
||||
self.assertEqual(expected, fips)
|
||||
|
||||
def test_get_floating_ips_all_tenants(self):
|
||||
api = neutronapi.API()
|
||||
self.moxed_client.list_floatingips(). \
|
||||
AndReturn({'floatingips': [self.fip_unassociated,
|
||||
self.fip_associated,
|
||||
self.fip_unassociated_not_my]})
|
||||
self.moxed_client.list_ports().AndReturn({'ports': self.port_data2})
|
||||
search_opts = {'router:external': True}
|
||||
self.moxed_client.list_networks(**search_opts). \
|
||||
AndReturn({'networks': [self.fip_pool, self.fip_pool_nova]})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
expected = [self._get_expected_fip_model(self.fip_unassociated),
|
||||
self._get_expected_fip_model(self.fip_associated, idx=1),
|
||||
self._get_expected_fip_model(self.fip_unassociated_not_my,
|
||||
idx=2)]
|
||||
fips = api.get_floating_ips(self.context, all_tenants=True)
|
||||
self.assertEqual(expected, fips)
|
||||
|
||||
def _test_get_instance_id_by_floating_address(self, fip_data,
|
||||
associated=False):
|
||||
api = neutronapi.API()
|
||||
|
|
Loading…
Reference in New Issue