From 470a1f1acfe261357fc3125b2db3bc6ec10c654e Mon Sep 17 00:00:00 2001
From: zhanghongtao <zhanghongtao0826@126.com>
Date: Tue, 25 Jul 2017 15:48:27 +0800
Subject: [PATCH] Add optional parameter "user_id" and "type" to list
 credentials

In keystone version 3.5, "type" optional attribute has been added
to list credentials. This patch add "user_id" and "type" optional
parameter in openstack client.

Change-Id: Ia09ee7c39204fdff2dfd7b9b606d888d007caac5
---
 doc/source/cli/command-objects/credential.rst | 19 +++++++++-
 openstackclient/identity/v3/credential.py     | 37 +++++++++++++++++--
 .../tests/unit/identity/v3/test_credential.py | 30 ++++++++++++++-
 ...ntial_list_user_type-c809e5b8014d6275.yaml |  5 +++
 4 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml

diff --git a/doc/source/cli/command-objects/credential.rst b/doc/source/cli/command-objects/credential.rst
index 0b835c73f1..47c847c895 100644
--- a/doc/source/cli/command-objects/credential.rst
+++ b/doc/source/cli/command-objects/credential.rst
@@ -19,7 +19,7 @@ Create new credential
 
 .. option:: --type <type>
 
-    New credential type
+    New credential type: cert, ec2
 
 .. option:: --project <project>
 
@@ -59,6 +59,21 @@ List credentials
 .. code:: bash
 
     openstack credential list
+        [--user <user> [--user-domain <user-domain>]]
+        [--type <type>]
+
+.. option:: --user <user>
+
+    Filter credentials by <user> (name or ID)
+
+.. option:: --user-domain <user-domain>
+
+    Domain the user belongs to (name or ID). This can be
+    used in case collisions between user names exist.
+
+.. option:: --type <type>
+
+    Filter credentials by type: cert, ec2
 
 credential set
 --------------
@@ -81,7 +96,7 @@ Set credential properties
 
 .. option:: --type <type>
 
-    New credential type
+    New credential type: cert, ec2
 
 .. option:: --data <data>
 
diff --git a/openstackclient/identity/v3/credential.py b/openstackclient/identity/v3/credential.py
index 2fd0062610..79ef632cc4 100644
--- a/openstackclient/identity/v3/credential.py
+++ b/openstackclient/identity/v3/credential.py
@@ -23,6 +23,7 @@ from osc_lib import utils
 import six
 
 from openstackclient.i18n import _
+from openstackclient.identity import common
 
 
 LOG = logging.getLogger(__name__)
@@ -43,7 +44,7 @@ class CreateCredential(command.ShowOne):
             default="cert",
             metavar='<type>',
             choices=['ec2', 'cert'],
-            help=_('New credential type'),
+            help=_('New credential type: cert, ec2'),
         )
         parser.add_argument(
             'data',
@@ -112,10 +113,40 @@ class DeleteCredential(command.Command):
 class ListCredential(command.Lister):
     _description = _("List credentials")
 
+    def get_parser(self, prog_name):
+        parser = super(ListCredential, self).get_parser(prog_name)
+        parser.add_argument(
+            '--user',
+            metavar='<user>',
+            help=_('Filter credentials by <user> (name or ID)'),
+        )
+        common.add_user_domain_option_to_parser(parser)
+        parser.add_argument(
+            '--type',
+            metavar='<type>',
+            choices=['ec2', 'cert'],
+            help=_('Filter credentials by type: cert, ec2'),
+        )
+        return parser
+
     def take_action(self, parsed_args):
+        identity_client = self.app.client_manager.identity
+
+        kwargs = {}
+        if parsed_args.user:
+            user_id = common.find_user(
+                identity_client,
+                parsed_args.user,
+                parsed_args.user_domain,
+            ).id
+            kwargs["user_id"] = user_id
+
+        if parsed_args.type:
+            kwargs["type"] = parsed_args.type
+
         columns = ('ID', 'Type', 'User ID', 'Blob', 'Project ID')
         column_headers = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
-        data = self.app.client_manager.identity.credentials.list()
+        data = self.app.client_manager.identity.credentials.list(**kwargs)
         return (column_headers,
                 (utils.get_item_properties(
                     s, columns,
@@ -144,7 +175,7 @@ class SetCredential(command.Command):
             metavar='<type>',
             choices=['ec2', 'cert'],
             required=True,
-            help=_('New credential type'),
+            help=_('New credential type: cert, ec2'),
         )
         parser.add_argument(
             '--data',
diff --git a/openstackclient/tests/unit/identity/v3/test_credential.py b/openstackclient/tests/unit/identity/v3/test_credential.py
index ce0fb5ae24..161f048447 100644
--- a/openstackclient/tests/unit/identity/v3/test_credential.py
+++ b/openstackclient/tests/unit/identity/v3/test_credential.py
@@ -225,12 +225,15 @@ class TestCredentialList(TestCredential):
     def setUp(self):
         super(TestCredentialList, self).setUp()
 
+        self.user = identity_fakes.FakeUser.create_one_user()
+        self.users_mock.get.return_value = self.user
+
         self.credentials_mock.list.return_value = [self.credential]
 
         # Get the command object to test
         self.cmd = credential.ListCredential(self.app, None)
 
-    def test_domain_list_no_options(self):
+    def test_credential_list_no_options(self):
         arglist = []
         verifylist = []
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -241,6 +244,31 @@ class TestCredentialList(TestCredential):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
+    def test_credential_list_with_options(self):
+        arglist = [
+            '--user', self.credential.user_id,
+            '--type', self.credential.type,
+        ]
+        verifylist = [
+            ('user', self.credential.user_id),
+            ('type', self.credential.type),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        kwargs = {
+            'user_id': self.user.id,
+            'type': self.credential.type,
+        }
+        self.users_mock.get.assert_called_with(self.credential.user_id)
+        self.credentials_mock.list.assert_called_with(
+            **kwargs
+        )
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, tuple(data))
+
 
 class TestCredentialSet(TestCredential):
 
diff --git a/releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml b/releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml
new file mode 100644
index 0000000000..e6280358a0
--- /dev/null
+++ b/releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add ``--user`` and ``--type`` option to ``credential list`` command
+    to filter list result by different user or type.