Skip to content

Commit a03e3db

Browse files
committed
Fix "access rule" commands to only use ID
This patch modifies the access rule commands to use only the resource ID. The previous logic incorrectly assumed that access rules have a "name" property, which resulted in unexpected behaviors. For example, "access rule delete {non-existent-id}" now results in a "not found" error instead of sometimes deleting an unrelated rule. Story: 2010775 Task: 48163 Change-Id: Ib5c3b7f86acf1dfe7cc76dfa99fa4c118388bd71 (cherry picked from commit bc60e3b)
1 parent 07c5a26 commit a03e3db

File tree

4 files changed

+39
-17
lines changed

4 files changed

+39
-17
lines changed

openstackclient/identity/common.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ def get_resource(manager, name_type_or_id):
8787
raise exceptions.CommandError(msg % name_type_or_id)
8888

8989

90+
def get_resource_by_id(manager, resource_id):
91+
"""Get resource by ID
92+
93+
Raises CommandError if the resource is not found
94+
"""
95+
try:
96+
return manager.get(resource_id)
97+
except identity_exc.NotFound:
98+
msg = _("Resource with id {} not found")
99+
raise exceptions.CommandError(msg.format(resource_id))
100+
101+
90102
def _get_token_resource(client, resource, parsed_name, parsed_domain=None):
91103
"""Peek into the user's auth token to get resource IDs
92104

openstackclient/identity/v3/access_rule.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def get_parser(self, prog_name):
3737
'access_rule',
3838
metavar='<access-rule>',
3939
nargs="+",
40-
help=_('Access rule(s) to delete (name or ID)'),
40+
help=_('Access rule ID(s) to delete'),
4141
)
4242
return parser
4343

@@ -47,8 +47,9 @@ def take_action(self, parsed_args):
4747
errors = 0
4848
for ac in parsed_args.access_rule:
4949
try:
50-
access_rule = utils.find_resource(
51-
identity_client.access_rules, ac)
50+
access_rule = common.get_resource_by_id(
51+
identity_client.access_rules, ac
52+
)
5253
identity_client.access_rules.delete(access_rule.id)
5354
except Exception as e:
5455
errors += 1
@@ -103,14 +104,15 @@ def get_parser(self, prog_name):
103104
parser.add_argument(
104105
'access_rule',
105106
metavar='<access-rule>',
106-
help=_('Access rule to display (name or ID)'),
107+
help=_('Access rule ID to display'),
107108
)
108109
return parser
109110

110111
def take_action(self, parsed_args):
111112
identity_client = self.app.client_manager.identity
112-
access_rule = utils.find_resource(identity_client.access_rules,
113-
parsed_args.access_rule)
113+
access_rule = common.get_resource_by_id(
114+
identity_client.access_rules, parsed_args.access_rule
115+
)
114116

115117
access_rule._info.pop('links', None)
116118

openstackclient/tests/unit/identity/v3/test_access_rule.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
#
1515

1616
import copy
17-
from unittest import mock
1817

18+
from keystoneclient import exceptions as identity_exc
1919
from osc_lib import exceptions
20-
from osc_lib import utils
2120

2221
from openstackclient.identity.v3 import access_rule
2322
from openstackclient.tests.unit import fakes
@@ -69,10 +68,13 @@ def test_access_rule_delete(self):
6968
)
7069
self.assertIsNone(result)
7170

72-
@mock.patch.object(utils, 'find_resource')
73-
def test_delete_multi_access_rules_with_exception(self, find_mock):
74-
find_mock.side_effect = [self.access_rules_mock.get.return_value,
75-
exceptions.CommandError]
71+
def test_delete_multi_access_rules_with_exception(self):
72+
# mock returns for common.get_resource_by_id
73+
mock_get = self.access_rules_mock.get
74+
mock_get.side_effect = [
75+
mock_get.return_value,
76+
identity_exc.NotFound,
77+
]
7678
arglist = [
7779
identity_fakes.access_rule_id,
7880
'nonexistent_access_rule',
@@ -89,12 +91,10 @@ def test_delete_multi_access_rules_with_exception(self, find_mock):
8991
self.assertEqual('1 of 2 access rules failed to'
9092
' delete.', str(e))
9193

92-
find_mock.assert_any_call(self.access_rules_mock,
93-
identity_fakes.access_rule_id)
94-
find_mock.assert_any_call(self.access_rules_mock,
95-
'nonexistent_access_rule')
94+
mock_get.assert_any_call(identity_fakes.access_rule_id)
95+
mock_get.assert_any_call('nonexistent_access_rule')
9696

97-
self.assertEqual(2, find_mock.call_count)
97+
self.assertEqual(2, mock_get.call_count)
9898
self.access_rules_mock.delete.assert_called_once_with(
9999
identity_fakes.access_rule_id)
100100

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fixes:
3+
- |
4+
Fixed a bug in "access rule" subcommands where the client logic incorrectly
5+
assumed that access rules have a "name" property which resulted in
6+
unpredictable behaviors. e.g. "access rule delete {non-existent-id}" now
7+
results in a not-found error instead of sometimes deleting an unrelated
8+
rule.

0 commit comments

Comments
 (0)