From f0c57e17c9a4b5bbe2f072a4eacefce3bcf30d45 Mon Sep 17 00:00:00 2001
From: Nathan Kinder <nkinder@redhat.com>
Date: Tue, 7 Oct 2014 16:30:56 -0700
Subject: [PATCH] Allow --domain to be used for identity commands without
 lookup

Performing create, list, or set operations for users, groups, and projects
with the --domain option attempts to look up the domain for name to ID
conversion.  In the case of an environment using Keystone domains, it is
desired to allow a domain admin to perform these operations for objects in
their domain without allowing them to list or show domains. The current
behavior prevents the domain admin from performing these operations since
they will be forbidden to perform the underlying list_domains operation.

This patch makes the domain lookup error a soft failure, and falls back
to using the passed in domain argument directly as a domain ID in the
request that it sends to Keystone.

Change-Id: I5139097f8cedc53693f6f71297518917ac72e50a
Closes-Bug: #1378565
---
 openstackclient/identity/v3/group.py   | 18 +++++++-----------
 openstackclient/identity/v3/project.py | 13 +++++++------
 openstackclient/identity/v3/user.py    | 17 +++++++----------
 3 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/openstackclient/identity/v3/group.py b/openstackclient/identity/v3/group.py
index fdb9501ad6..bdb4e02980 100644
--- a/openstackclient/identity/v3/group.py
+++ b/openstackclient/identity/v3/group.py
@@ -129,8 +129,8 @@ class CreateGroup(show.ShowOne):
         self.log.debug('take_action(%s)', parsed_args)
         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
         group = identity_client.groups.create(
@@ -174,7 +174,7 @@ class ListGroup(lister.Lister):
         parser.add_argument(
             '--domain',
             metavar='<domain>',
-            help='Filter group list by <domain>',
+            help='Filter group list by <domain> (name or ID)',
         )
         parser.add_argument(
             '--user',
@@ -194,10 +194,8 @@ class ListGroup(lister.Lister):
         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
 
@@ -301,10 +299,8 @@ class SetGroup(command.Command):
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
         if parsed_args.domain:
-            domain = utils.find_resource(
-                identity_client.domains, parsed_args.domain).id
-            kwargs['domain'] = domain
-
+            kwargs['domain'] = common.find_domain(identity_client,
+                                                  parsed_args.domain).id
         if not len(kwargs):
             sys.stderr.write("Group not updated, no arguments present")
             return
diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index ec8e5a3b1a..7b3c281cf9 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -74,7 +74,8 @@ class CreateProject(show.ShowOne):
         identity_client = self.app.client_manager.identity
 
         if parsed_args.domain:
-            domain = common.find_domain(identity_client, parsed_args.domain).id
+            domain = common.find_domain(identity_client,
+                                        parsed_args.domain).id
         else:
             domain = None
 
@@ -141,7 +142,7 @@ class ListProject(lister.Lister):
         parser.add_argument(
             '--domain',
             metavar='<project-domain>',
-            help='Filter by a specific domain',
+            help='Filter by a specific domain (name or ID)',
         )
         return parser
 
@@ -154,8 +155,8 @@ class ListProject(lister.Lister):
             columns = ('ID', 'Name')
         kwargs = {}
         if parsed_args.domain:
-            domain = common.find_domain(identity_client, parsed_args.domain)
-            kwargs['domain'] = domain.id
+            kwargs['domain'] = common.find_domain(identity_client,
+                                                  parsed_args.domain).id
         data = identity_client.projects.list(**kwargs)
         return (columns,
                 (utils.get_item_properties(
@@ -232,8 +233,8 @@ class SetProject(command.Command):
         if parsed_args.name:
             kwargs['name'] = parsed_args.name
         if parsed_args.domain:
-            domain = common.find_domain(identity_client, parsed_args.domain)
-            kwargs['domain'] = domain.id
+            kwargs['domain'] = common.find_domain(identity_client,
+                                                  parsed_args.domain).id
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
         if parsed_args.enable:
diff --git a/openstackclient/identity/v3/user.py b/openstackclient/identity/v3/user.py
index 73bb7f1308..10921219d6 100644
--- a/openstackclient/identity/v3/user.py
+++ b/openstackclient/identity/v3/user.py
@@ -95,8 +95,8 @@ class CreateUser(show.ShowOne):
             project_id = None
 
         if parsed_args.domain:
-            domain_id = utils.find_resource(
-                identity_client.domains, parsed_args.domain).id
+            domain_id = common.find_domain(identity_client,
+                                           parsed_args.domain).id
         else:
             domain_id = None
 
@@ -158,7 +158,7 @@ class ListUser(lister.Lister):
         parser.add_argument(
             '--domain',
             metavar='<domain>',
-            help='Filter group list by <domain>',
+            help='Filter user list by <domain> (name or ID)',
         )
         parser.add_argument(
             '--group',
@@ -178,10 +178,8 @@ class ListUser(lister.Lister):
         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
 
@@ -311,9 +309,8 @@ class SetUser(command.Command):
                 identity_client.projects, parsed_args.project).id
             kwargs['project'] = project_id
         if parsed_args.domain:
-            domain_id = utils.find_resource(
-                identity_client.domains, parsed_args.domain).id
-            kwargs['domain'] = domain_id
+            kwargs['domain'] = common.find_domain(identity_client,
+                                                  parsed_args.domain).id
         kwargs['enabled'] = user.enabled
         if parsed_args.enable:
             kwargs['enabled'] = True