Skip to content

Commit 757ecb7

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Identity: Migrate 'policy' commands to SDK"
2 parents 21ff556 + e1f9e82 commit 757ecb7

5 files changed

Lines changed: 493 additions & 25 deletions

File tree

openstackclient/identity/v3/policy.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import logging
2121
from typing import Any
2222

23+
from openstack.identity.v3 import policy as _policy
24+
from openstack import utils as sdk_utils
2325
from osc_lib import exceptions
2426
from osc_lib import utils
2527

@@ -30,6 +32,14 @@
3032
LOG = logging.getLogger(__name__)
3133

3234

35+
def _format_policy(
36+
policy: _policy.Policy,
37+
) -> tuple[tuple[str, ...], tuple[str, ...]]:
38+
columns = ('id', 'blob', 'type')
39+
column_headers = ('id', 'rules', 'type')
40+
return (column_headers, utils.get_item_properties(policy, columns))
41+
42+
3343
class CreatePolicy(command.ShowOne):
3444
_description = _("Create new policy")
3545

@@ -56,15 +66,14 @@ def take_action(
5666
) -> tuple[Sequence[str], Iterable[Any]]:
5767
blob = utils.read_blob_file_contents(parsed_args.rules)
5868

59-
identity_client = self.app.client_manager.identity
60-
policy = identity_client.policies.create(
69+
identity_client = sdk_utils.ensure_service_version(
70+
self.app.client_manager.sdk_connection.identity, '3'
71+
)
72+
policy = identity_client.create_policy(
6173
blob=blob, type=parsed_args.type
6274
)
6375

64-
policy._info.pop('links')
65-
policy._info.update({'rules': policy._info.pop('blob')})
66-
col_headers, col_data = zip(*sorted(policy._info.items()))
67-
return col_headers, col_data
76+
return _format_policy(policy)
6877

6978

7079
class DeletePolicy(command.Command):
@@ -81,11 +90,13 @@ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
8190
return parser
8291

8392
def take_action(self, parsed_args: argparse.Namespace) -> None:
84-
identity_client = self.app.client_manager.identity
93+
identity_client = sdk_utils.ensure_service_version(
94+
self.app.client_manager.sdk_connection.identity, '3'
95+
)
8596
result = 0
8697
for i in parsed_args.policy:
8798
try:
88-
identity_client.policies.delete(i)
99+
identity_client.delete_policy(i, ignore_missing=False)
89100
except Exception as e:
90101
result += 1
91102
LOG.error(
@@ -126,17 +137,20 @@ def take_action(
126137
if parsed_args.long:
127138
columns += ('Blob',)
128139
column_headers += ('Rules',)
129-
data = self.app.client_manager.identity.policies.list()
140+
identity_client = sdk_utils.ensure_service_version(
141+
self.app.client_manager.sdk_connection.identity, '3'
142+
)
143+
data = identity_client.policies()
130144
return (
131145
column_headers,
132-
(
146+
[
133147
utils.get_item_properties(
134148
s,
135149
columns,
136150
formatters={},
137151
)
138152
for s in data
139-
),
153+
],
140154
)
141155

142156

@@ -163,19 +177,19 @@ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
163177
return parser
164178

165179
def take_action(self, parsed_args: argparse.Namespace) -> None:
166-
identity_client = self.app.client_manager.identity
167-
blob = None
180+
identity_client = sdk_utils.ensure_service_version(
181+
self.app.client_manager.sdk_connection.identity, '3'
182+
)
183+
184+
kwargs = {}
168185

169186
if parsed_args.rules:
170-
blob = utils.read_blob_file_contents(parsed_args.rules)
187+
kwargs['blob'] = utils.read_blob_file_contents(parsed_args.rules)
171188

172-
kwargs = {}
173-
if blob:
174-
kwargs['blob'] = blob
175189
if parsed_args.type:
176190
kwargs['type'] = parsed_args.type
177191

178-
identity_client.policies.update(parsed_args.policy, **kwargs)
192+
identity_client.update_policy(parsed_args.policy, **kwargs)
179193

180194

181195
class ShowPolicy(command.ShowOne):
@@ -193,12 +207,9 @@ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
193207
def take_action(
194208
self, parsed_args: argparse.Namespace
195209
) -> tuple[Sequence[str], Iterable[Any]]:
196-
identity_client = self.app.client_manager.identity
197-
policy = utils.find_resource(
198-
identity_client.policies, parsed_args.policy
210+
identity_client = sdk_utils.ensure_service_version(
211+
self.app.client_manager.sdk_connection.identity, '3'
199212
)
213+
policy = identity_client.get_policy(parsed_args.policy)
200214

201-
policy._info.pop('links')
202-
policy._info.update({'rules': policy._info.pop('blob')})
203-
col_headers, col_data = zip(*sorted(policy._info.items()))
204-
return col_headers, col_data
215+
return _format_policy(policy)

openstackclient/tests/functional/identity/v3/common.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ class IdentityTests(base.TestCase):
154154
'Region ID',
155155
]
156156

157+
POLICY_FIELDS = [
158+
'id',
159+
'rules',
160+
'type',
161+
]
162+
POLICY_LIST_HEADERS = [
163+
'ID',
164+
'Type',
165+
]
166+
POLICY_LIST_LONG_HEADERS = [
167+
'ID',
168+
'Type',
169+
'Rules',
170+
]
171+
157172
DOMAIN_NAME: ClassVar[str]
158173
DOMAIN_DESCRIPTION: ClassVar[str]
159174
PROJECT_NAME: ClassVar[str]
@@ -520,3 +535,30 @@ def _create_dummy_limit(self, add_clean_up=True):
520535

521536
self.assert_show_fields(items, self.LIMIT_FIELDS)
522537
return limit_id
538+
539+
def _create_dummy_policy(self, add_clean_up=True):
540+
# Create rules file
541+
with tempfile.NamedTemporaryFile(mode='w+') as f:
542+
RULES = [
543+
{
544+
"local": [{"group": {"id": "85a868"}}],
545+
"remote": [
546+
{"type": "orgPersonType", "any_one_of": ["Employee"]},
547+
{"type": "sn", "any_one_of": ["Young"]},
548+
],
549+
}
550+
]
551+
f.write(json.dumps(RULES))
552+
f.flush()
553+
raw_output = self.openstack(f'policy create {f.name}')
554+
items = self.parse_show(raw_output)
555+
policy_id = self._extract_value_from_items('id', items)
556+
557+
if add_clean_up:
558+
self.addCleanup(
559+
self.openstack,
560+
f'policy delete {policy_id}',
561+
)
562+
items = self.parse_show(raw_output)
563+
self.assert_show_fields(items, self.POLICY_FIELDS)
564+
return policy_id
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import json
14+
import tempfile
15+
16+
from openstackclient.tests.functional.identity.v3 import common
17+
18+
19+
class PolicyTests(common.IdentityTests):
20+
def test_policy_create(self):
21+
self._create_dummy_policy()
22+
23+
def test_policy_delete(self):
24+
policy = self._create_dummy_policy(add_clean_up=False)
25+
raw_output = self.openstack(f'policy delete {policy}')
26+
self.assertEqual(0, len(raw_output))
27+
28+
def test_policy_multi_delete(self):
29+
policy_1 = self._create_dummy_policy(add_clean_up=False)
30+
policy_2 = self._create_dummy_policy(add_clean_up=False)
31+
raw_output = self.openstack(f'policy delete {policy_1} {policy_2}')
32+
self.assertEqual(0, len(raw_output))
33+
34+
def test_policy_show(self):
35+
policy = self._create_dummy_policy(add_clean_up=True)
36+
raw_output = self.openstack(f'policy show {policy}')
37+
items = self.parse_show(raw_output)
38+
self.assert_show_fields(items, self.POLICY_FIELDS)
39+
40+
def test_policy_list(self):
41+
self._create_dummy_policy(add_clean_up=True)
42+
raw_output = self.openstack('policy list')
43+
items = self.parse_listing(raw_output)
44+
self.assert_table_structure(items, self.POLICY_LIST_HEADERS)
45+
46+
def test_policy_list_long(self):
47+
self._create_dummy_policy(add_clean_up=True)
48+
raw_output = self.openstack('policy list --long')
49+
items = self.parse_listing(raw_output)
50+
self.assert_table_structure(items, self.POLICY_LIST_LONG_HEADERS)
51+
52+
def test_policy_set(self):
53+
policy = self._create_dummy_policy(add_clean_up=True)
54+
with tempfile.NamedTemporaryFile(mode='w+') as f:
55+
NEW_RULES = [
56+
{
57+
"local": [{"group": {"id": "85a868"}}],
58+
"remote": [
59+
{"type": "orgPersonType", "any_one_of": ["Employee"]},
60+
{"type": "sn", "any_one_of": ["Young"]},
61+
],
62+
},
63+
{
64+
"local": [
65+
{"group": {"id": "0cd5e9"}},
66+
{"user": {"name": "0cd5e9"}},
67+
],
68+
"remote": [
69+
{"type": "UserName"},
70+
{
71+
"type": "orgPersonType",
72+
"not_any_of": ["Contractor", "SubContractor"],
73+
},
74+
{"type": "LastName", "any_one_of": ["Bo"]},
75+
],
76+
},
77+
]
78+
f.write(json.dumps(NEW_RULES))
79+
f.flush()
80+
raw_output = self.openstack(
81+
f'policy set {policy} --rules {f.name} --type text/json'
82+
)
83+
self.assertEqual(0, len(raw_output))
84+
raw_output = self.openstack(f'policy show {policy}')
85+
updated_value = self.parse_show_as_object(raw_output)
86+
self.assertEqual('text/json', updated_value['type'])

0 commit comments

Comments
 (0)