Added list_flavor_access.

Change-Id: Ia983486ec4d587dd436e6a9c0b443be8ce1a7102
This commit is contained in:
Roberto Polli 2016-12-23 14:52:20 +01:00
parent 6f78e6860f
commit 9d145e0be2
7 changed files with 83 additions and 0 deletions

View File

@ -87,6 +87,19 @@ A flavor for a Nova Server.
extra_specs=dict(),
properties=dict())
Flavor Access
------
An access entry for a Nova Flavor.
.. code-block:: python
FlavorAccess = dict(
flavor_id=str(),
project_id=str())
Image
-----

View File

@ -0,0 +1,4 @@
---
features:
- Add a list_flavor_access method to list all
the projects/tenants allowed to access a given flavor.

View File

@ -102,6 +102,11 @@ class FlavorGet(task_manager.Task):
return client.nova_client.flavors.get(**self.args)
class FlavorListAccess(task_manager.Task):
def main(self, client):
return client.nova_client.flavor_access.list(**self.args)
class FlavorAddAccess(task_manager.Task):
def main(self, client):
return client.nova_client.flavor_access.add_tenant_access(

View File

@ -303,6 +303,17 @@ def normalize_roles(roles):
return meta.obj_list_to_dict(ret)
def normalize_flavor_accesses(flavor_accesses):
"""Normalize Flavor access list."""
return [munch.Munch(
dict(
flavor_id=acl.get('flavor_id'),
project_id=acl.get('project_id') or acl.get('tenant_id'),
)
) for acl in flavor_accesses
]
def normalize_stacks(stacks):
""" Normalize Stack Object """
for stack in stacks:

View File

@ -1593,6 +1593,23 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
"""
self._mod_flavor_access('remove', flavor_id, project_id)
def list_flavor_access(self, flavor_id):
"""List access from a private flavor for a project/tenant.
:param string flavor_id: ID of the private flavor.
:returns: a list of ``munch.Munch`` containing the access description
:raises: OpenStackCloudException on operation error.
"""
with _utils.shade_exceptions("Error trying to list access from "
"flavor ID {flavor}".format(
flavor=flavor_id)):
projects = self.manager.submit_task(
_tasks.FlavorListAccess(flavor=flavor_id)
)
return _utils.normalize_flavor_accesses(projects)
def create_role(self, name):
"""Create a Keystone role.

View File

@ -129,6 +129,12 @@ class TestFlavor(base.BaseFunctionalTestCase):
self.assertEqual(1, len(flavors))
self.assertEqual(priv_flavor_name, flavors[0]['name'])
# Now see if the 'demo' user has access to it without needing
# the demo_cloud access.
acls = self.operator_cloud.list_flavor_access(new_flavor['id'])
self.assertEqual(1, len(acls))
self.assertEqual(project['id'], acls[0]['project_id'])
# Now revoke the access and make sure we can't find it
self.operator_cloud.remove_flavor_access(new_flavor['id'],
project['id'])

View File

@ -14,6 +14,7 @@
import mock
from shade.tests.fakes import FakeFlavor, FakeProject
import shade
from keystoneauth1.fixture import keystoneauth_betamax
@ -117,9 +118,35 @@ class TestFlavors(base.TestCase):
flavor='flavor_id', tenant='tenant_id'
)
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
def test_add_flavor_access_by_flavor(self, mock_nova):
flavor = FakeFlavor(id='flavor_id', name='flavor_name', ram=None)
tenant = FakeProject('tenant_id')
self.op_cloud.add_flavor_access(flavor, tenant)
mock_nova.flavor_access.add_tenant_access.assert_called_once_with(
flavor=flavor, tenant=tenant
)
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
def test_remove_flavor_access(self, mock_nova):
self.op_cloud.remove_flavor_access('flavor_id', 'tenant_id')
mock_nova.flavor_access.remove_tenant_access.assert_called_once_with(
flavor='flavor_id', tenant='tenant_id'
)
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
def test_list_flavor_access(self, mock_nova):
mock_nova.flavors.list.return_value = [FakeFlavor(
id='flavor_id', name='flavor_name', ram=None)]
self.op_cloud.list_flavor_access('flavor_id')
mock_nova.flavor_access.list.assert_called_once_with(
flavor='flavor_id'
)
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
def test_list_flavor_access_by_flavor(self, mock_nova):
flavor = FakeFlavor(id='flavor_id', name='flavor_name', ram=None)
self.op_cloud.list_flavor_access(flavor)
mock_nova.flavor_access.list.assert_called_once_with(
flavor=flavor
)