Merge "Domain administrator cannot do project operations"

This commit is contained in:
Jenkins 2014-07-09 08:18:23 +00:00 committed by Gerrit Code Review
commit 70283744a0
3 changed files with 91 additions and 12 deletions

View File

@ -16,6 +16,7 @@
"""Common identity code"""
from keystoneclient import exceptions as identity_exc
from keystoneclient.v3 import domains
from openstackclient.common import exceptions
from openstackclient.common import utils
@ -36,3 +37,23 @@ def find_service(identity_client, name_type_or_id):
msg = ("No service with a type, name or ID of '%s' exists."
% name_type_or_id)
raise exceptions.CommandError(msg)
def find_domain(identity_client, name_or_id):
"""Find a domain.
If the user does not have permssions to access the v3 domain API,
assume that domain given is the id rather than the name. This
method is used by the project list command, so errors access the
domain will be ignored and if the user has access to the project
API, everything will work fine.
Closes bugs #1317478 and #1317485.
"""
try:
dom = utils.find_resource(identity_client.domains, name_or_id)
if dom is not None:
return dom
except identity_exc.Forbidden:
pass
return domains.Domain(None, {'id': name_or_id})

View File

@ -24,6 +24,7 @@ from cliff import show
from openstackclient.common import parseractions
from openstackclient.common import utils
from openstackclient.identity import common
class CreateProject(show.ShowOne):
@ -73,10 +74,7 @@ class CreateProject(show.ShowOne):
identity_client = self.app.client_manager.identity
if parsed_args.domain:
domain = utils.find_resource(
identity_client.domains,
parsed_args.domain,
).id
domain = common.find_domain(identity_client, parsed_args.domain).id
else:
domain = None
@ -156,10 +154,8 @@ class ListProject(lister.Lister):
columns = ('ID', 'Name')
kwargs = {}
if parsed_args.domain:
kwargs['domain'] = utils.find_resource(
identity_client.domains,
parsed_args.domain,
).id
domain = common.find_domain(identity_client, parsed_args.domain)
kwargs['domain'] = domain.id
data = identity_client.projects.list(**kwargs)
return (columns,
(utils.get_item_properties(
@ -236,10 +232,8 @@ class SetProject(command.Command):
if parsed_args.name:
kwargs['name'] = parsed_args.name
if parsed_args.domain:
kwargs['domain'] = utils.find_resource(
identity_client.domains,
parsed_args.domain,
).id
domain = common.find_domain(identity_client, parsed_args.domain)
kwargs['domain'] = domain.id
if parsed_args.description:
kwargs['description'] = parsed_args.description
if parsed_args.enable:

View File

@ -14,6 +14,7 @@
#
import copy
import mock
from openstackclient.identity.v3 import project
from openstackclient.tests import fakes
@ -172,6 +173,45 @@ class TestProjectCreate(TestProject):
)
self.assertEqual(data, datalist)
def test_project_create_domain_no_perms(self):
arglist = [
'--domain', identity_fakes.domain_id,
identity_fakes.project_name,
]
verifylist = [
('domain', identity_fakes.domain_id),
('enable', False),
('disable', False),
('name', identity_fakes.project_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
mocker = mock.Mock()
mocker.return_value = None
with mock.patch("openstackclient.common.utils.find_resource", mocker):
columns, data = self.cmd.take_action(parsed_args)
# Set expected values
kwargs = {
'name': identity_fakes.project_name,
'domain': identity_fakes.domain_id,
'description': None,
'enabled': True,
}
self.projects_mock.create.assert_called_with(
**kwargs
)
collist = ('description', 'domain_id', 'enabled', 'id', 'name')
self.assertEqual(columns, collist)
datalist = (
identity_fakes.project_description,
identity_fakes.domain_id,
True,
identity_fakes.project_id,
identity_fakes.project_name,
)
self.assertEqual(data, datalist)
def test_project_create_enable(self):
arglist = [
'--enable',
@ -411,6 +451,30 @@ class TestProjectList(TestProject):
), )
self.assertEqual(tuple(data), datalist)
def test_project_list_domain_no_perms(self):
arglist = [
'--domain', identity_fakes.domain_id,
]
verifylist = [
('domain', identity_fakes.domain_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
mocker = mock.Mock()
mocker.return_value = None
with mock.patch("openstackclient.common.utils.find_resource", mocker):
columns, data = self.cmd.take_action(parsed_args)
self.projects_mock.list.assert_called_with(
domain=identity_fakes.domain_id)
collist = ('ID', 'Name')
self.assertEqual(columns, collist)
datalist = ((
identity_fakes.project_id,
identity_fakes.project_name,
), )
self.assertEqual(tuple(data), datalist)
class TestProjectSet(TestProject):