From 57d5f945402681e5f7d62b9ca99fc229927cc784 Mon Sep 17 00:00:00 2001
From: Huanxuan Ao <huanxuan.ao@easystack.cn>
Date: Thu, 20 Oct 2016 10:55:50 +0800
Subject: [PATCH] Allow input the QoS policy name in network rbac create
 command

We could input a QoS policy ID for the "rbac_object"
parameter in "network rbac create" command but not
name before. After this change, "rbac_object" parameter
can be both QoS policy name or ID.

Change-Id: I0fd6b5b5ae410074d85475ef49e5a0a9a52bf86f
---
 doc/source/command-objects/network-rbac.rst   |  2 +-
 openstackclient/network/v2/network_rbac.py    |  9 ++---
 .../unit/network/v2/test_network_rbac.py      | 40 +++++++++++++++++++
 ...-network-rbac-create-d1f4de77ad2dd421.yaml |  4 ++
 4 files changed, 49 insertions(+), 6 deletions(-)
 create mode 100644 releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml

diff --git a/doc/source/command-objects/network-rbac.rst b/doc/source/command-objects/network-rbac.rst
index 8acf097964..113242f471 100644
--- a/doc/source/command-objects/network-rbac.rst
+++ b/doc/source/command-objects/network-rbac.rst
@@ -52,7 +52,7 @@ Create network RBAC policy
 .. _network_rbac_create-rbac-policy:
 .. describe:: <rbac-object>
 
-    The object to which this RBAC policy affects (name or ID for network objects, ID only for QoS policy objects)
+    The object to which this RBAC policy affects (name or ID)
 
 network rbac delete
 -------------------
diff --git a/openstackclient/network/v2/network_rbac.py b/openstackclient/network/v2/network_rbac.py
index bb29579f95..b1e0413f71 100644
--- a/openstackclient/network/v2/network_rbac.py
+++ b/openstackclient/network/v2/network_rbac.py
@@ -47,9 +47,9 @@ def _get_attrs(client_manager, parsed_args):
         object_id = network_client.find_network(
             parsed_args.rbac_object, ignore_missing=False).id
     if parsed_args.type == 'qos_policy':
-        # TODO(Huanxuan Ao): Support finding a object ID by obejct name
-        # after qos policy finding supported in SDK.
-        object_id = parsed_args.rbac_object
+        object_id = network_client.find_qos_policy(
+            parsed_args.rbac_object,
+            ignore_missing=False).id
     attrs['object_id'] = object_id
 
     identity_client = client_manager.identity
@@ -78,8 +78,7 @@ class CreateNetworkRBAC(command.ShowOne):
         parser.add_argument(
             'rbac_object',
             metavar="<rbac-object>",
-            help=_("The object to which this RBAC policy affects (name or "
-                   "ID for network objects, ID only for QoS policy objects)")
+            help=_("The object to which this RBAC policy affects (name or ID)")
         )
         parser.add_argument(
             '--type',
diff --git a/openstackclient/tests/unit/network/v2/test_network_rbac.py b/openstackclient/tests/unit/network/v2/test_network_rbac.py
index c526ae4e4b..b884dbc02d 100644
--- a/openstackclient/tests/unit/network/v2/test_network_rbac.py
+++ b/openstackclient/tests/unit/network/v2/test_network_rbac.py
@@ -36,6 +36,7 @@ class TestNetworkRBAC(network_fakes.TestNetworkV2):
 class TestCreateNetworkRBAC(TestNetworkRBAC):
 
     network_object = network_fakes.FakeNetwork.create_one_network()
+    qos_object = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
     project = identity_fakes_v3.FakeProject.create_one_project()
     rbac_policy = network_fakes.FakeNetworkRBAC.create_one_network_rbac(
         attrs={'tenant_id': project.id,
@@ -71,6 +72,8 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
             return_value=self.rbac_policy)
         self.network.find_network = mock.Mock(
             return_value=self.network_object)
+        self.network.find_qos_policy = mock.Mock(
+            return_value=self.qos_object)
         self.projects_mock.get.return_value = self.project
 
     def test_network_rbac_create_no_type(self):
@@ -194,6 +197,43 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
+    def test_network_rbac_create_qos_object(self):
+        self.rbac_policy.object_type = 'qos_policy'
+        self.rbac_policy.object_id = self.qos_object.id
+        arglist = [
+            '--type', 'qos_policy',
+            '--action', self.rbac_policy.action,
+            '--target-project', self.rbac_policy.target_tenant,
+            self.qos_object.name,
+        ]
+        verifylist = [
+            ('type', 'qos_policy'),
+            ('action', self.rbac_policy.action),
+            ('target_project', self.rbac_policy.target_tenant),
+            ('rbac_object', self.qos_object.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # DisplayCommandBase.take_action() returns two tuples
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.create_rbac_policy.assert_called_with(**{
+            'object_id': self.qos_object.id,
+            'object_type': 'qos_policy',
+            'action': self.rbac_policy.action,
+            'target_tenant': self.rbac_policy.target_tenant,
+        })
+        self.data = [
+            self.rbac_policy.action,
+            self.rbac_policy.id,
+            self.qos_object.id,
+            'qos_policy',
+            self.rbac_policy.tenant_id,
+            self.rbac_policy.target_tenant,
+        ]
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
 
 class TestDeleteNetworkRBAC(TestNetworkRBAC):
 
diff --git a/releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml b/releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
new file mode 100644
index 0000000000..964828ca19
--- /dev/null
+++ b/releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    ``rbac_object`` parameter in ``network rbac create`` command now can be a QoS policy name.