summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-07-09 08:18:23 +0000
committerGerrit Code Review <review@openstack.org>2014-07-09 08:18:23 +0000
commit70283744a04f868072edc0a31fe49a3122c4bc6e (patch)
treeaf2ae769198fb329fee2582197d84b54172cbddb /openstackclient
parente8f058775eb3dbb9a159218c427d439b3dcc6012 (diff)
parentb6384886973c652c0161a9caeac6f31066edace1 (diff)
downloadpython-openstackclient-70283744a04f868072edc0a31fe49a3122c4bc6e.tar.gz
Merge "Domain administrator cannot do project operations"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/identity/common.py21
-rw-r--r--openstackclient/identity/v3/project.py18
-rw-r--r--openstackclient/tests/identity/v3/test_project.py64
3 files changed, 91 insertions, 12 deletions
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index 6aeaa3c3..48dc0c89 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -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})
diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index 00a98d19..fa935f0b 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -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:
diff --git a/openstackclient/tests/identity/v3/test_project.py b/openstackclient/tests/identity/v3/test_project.py
index e0420a1e..2e7bc54b 100644
--- a/openstackclient/tests/identity/v3/test_project.py
+++ b/openstackclient/tests/identity/v3/test_project.py
@@ -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):