Domain administrator cannot do project operations
Domain administrator cannot do project operations because the require access to the domain API (which they don't have). When attempting to find a domain for project operations, ignore errors because the API returns nothing without indicating there is a problem. The domain administrators will have to use a domain id, but they will still be able to do project operations. If the user does not have permission to read the domain table, they cannot use domain names. Change-Id: Ieed5d420022a407c8296a0bb3569d9469c89d752 Closes-Bug: #1317478 Closes-Bug: #1317485
This commit is contained in:
parent
b3736fd9df
commit
b638488697
@ -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})
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user