Skip to content

Commit 28a6acf

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Implement trust in identity v3 api"
2 parents 3946bf0 + cf23fd5 commit 28a6acf

5 files changed

Lines changed: 582 additions & 1 deletion

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
=====
2+
trust
3+
=====
4+
5+
Identity v3
6+
7+
trust create
8+
------------
9+
10+
Create new trust
11+
12+
.. program:: trust create
13+
.. code:: bash
14+
15+
os trust create
16+
--project <project>
17+
--role <role>
18+
[--impersonate]
19+
[--expiration <expiration>]
20+
[--project-domain <domain>]
21+
[--trustor-domain <domain>]
22+
[--trustee-domain <domain>]
23+
<trustor>
24+
<trustee>
25+
26+
.. option:: --project <project>
27+
28+
Project being delegated (name or ID) (required)
29+
30+
.. option:: --role <role>
31+
32+
Roles to authorize (name or ID) (repeat to set multiple values) (required)
33+
34+
.. option:: --impersonate
35+
36+
Tokens generated from the trust will represent <trustor> (defaults to False)
37+
38+
.. option:: --expiration <expiration>
39+
40+
Sets an expiration date for the trust (format of YYYY-mm-ddTHH:MM:SS)
41+
42+
.. option:: --project-domain <domain>
43+
44+
Domain that contains <project> (name or ID)
45+
46+
.. option:: --trustor-domain <domain>
47+
48+
Domain that contains <trustor> (name or ID)
49+
50+
.. option:: --trustee-domain <domain>
51+
52+
Domain that contains <trustee> (name or ID)
53+
54+
.. describe:: <trustor-user>
55+
56+
User that is delegating authorization (name or ID)
57+
58+
.. describe:: <trustee-user>
59+
60+
User that is assuming authorization (name or ID)
61+
62+
63+
trust delete
64+
------------
65+
66+
Delete trust(s)
67+
68+
.. program:: trust delete
69+
.. code:: bash
70+
71+
os trust delete
72+
<trust> [<trust> ...]
73+
74+
.. describe:: <trust>
75+
76+
Trust(s) to delete
77+
78+
trust list
79+
----------
80+
81+
List trusts
82+
83+
.. program:: trust list
84+
.. code:: bash
85+
86+
os trust list
87+
88+
trust show
89+
----------
90+
91+
Display trust details
92+
93+
.. program:: trust show
94+
.. code:: bash
95+
96+
os trust show
97+
<trust>
98+
99+
.. describe:: <trust>
100+
101+
Trust to display
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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+
14+
"""Identity v3 Trust action implementations"""
15+
16+
import datetime
17+
import logging
18+
import six
19+
20+
from cliff import command
21+
from cliff import lister
22+
from cliff import show
23+
24+
from openstackclient.common import utils
25+
from openstackclient.identity import common
26+
27+
28+
class CreateTrust(show.ShowOne):
29+
"""Create new trust"""
30+
31+
log = logging.getLogger(__name__ + '.CreateTrust')
32+
33+
def get_parser(self, prog_name):
34+
parser = super(CreateTrust, self).get_parser(prog_name)
35+
parser.add_argument(
36+
'trustor',
37+
metavar='<trustor-user>',
38+
help='User that is delegating authorization (name or ID)',
39+
)
40+
parser.add_argument(
41+
'trustee',
42+
metavar='<trustee-user>',
43+
help='User that is assuming authorization (name or ID)',
44+
)
45+
parser.add_argument(
46+
'--project',
47+
metavar='<project>',
48+
required=True,
49+
help='Project being delegated (name or ID) (required)',
50+
)
51+
parser.add_argument(
52+
'--role',
53+
metavar='<role>',
54+
action='append',
55+
default=[],
56+
help='Roles to authorize (name or ID) '
57+
'(repeat to set multiple values) (required)',
58+
required=True
59+
)
60+
parser.add_argument(
61+
'--impersonate',
62+
dest='impersonate',
63+
action='store_true',
64+
default=False,
65+
help='Tokens generated from the trust will represent <trustor>'
66+
' (defaults to False)',
67+
)
68+
parser.add_argument(
69+
'--expiration',
70+
metavar='<expiration>',
71+
help='Sets an expiration date for the trust'
72+
' (format of YYYY-mm-ddTHH:MM:SS)',
73+
)
74+
parser.add_argument(
75+
'--project-domain',
76+
metavar='<domain>',
77+
help='Domain that contains <project> (name or ID)',
78+
)
79+
parser.add_argument(
80+
'--trustor-domain',
81+
metavar='<domain>',
82+
help='Domain that contains <trustor> (name or ID)',
83+
)
84+
parser.add_argument(
85+
'--trustee-domain',
86+
metavar='<domain>',
87+
help='Domain that contains <trustee> (name or ID)',
88+
)
89+
return parser
90+
91+
def take_action(self, parsed_args):
92+
self.log.debug('take_action(%s)' % parsed_args)
93+
identity_client = self.app.client_manager.identity
94+
95+
if parsed_args.project_domain:
96+
project_domain = common.find_domain(identity_client,
97+
parsed_args.project_domain).id
98+
else:
99+
project_domain = None
100+
101+
if parsed_args.trustor_domain:
102+
trustor_domain = common.find_domain(identity_client,
103+
parsed_args.trustor_domain).id
104+
else:
105+
trustor_domain = None
106+
107+
if parsed_args.trustee_domain:
108+
trustee_domain = common.find_domain(identity_client,
109+
parsed_args.trustee_domain).id
110+
else:
111+
trustee_domain = None
112+
113+
# NOTE(stevemar): Find the two users, project and roles that
114+
# are necessary for making a trust usable, the API dictates that
115+
# trustee, project and role are optional, but that makes the trust
116+
# pointless, and trusts are immutable, so let's enforce it at the
117+
# client level.
118+
trustor_id = utils.find_resource(identity_client.users,
119+
parsed_args.trustor,
120+
domain_id=trustor_domain).id
121+
trustee_id = utils.find_resource(identity_client.users,
122+
parsed_args.trustee,
123+
domain_id=trustee_domain).id
124+
project_id = utils.find_resource(identity_client.projects,
125+
parsed_args.project,
126+
domain_id=project_domain).id
127+
128+
role_names = []
129+
for role in parsed_args.role:
130+
role_name = utils.find_resource(
131+
identity_client.roles,
132+
role,
133+
).name
134+
role_names.append(role_name)
135+
136+
expires_at = None
137+
if parsed_args.expiration:
138+
expires_at = datetime.datetime.strptime(parsed_args.expiration,
139+
'%Y-%m-%dT%H:%M:%S')
140+
141+
trust = identity_client.trusts.create(
142+
trustee_id, trustor_id,
143+
impersonation=parsed_args.impersonate,
144+
project=project_id,
145+
role_names=role_names,
146+
expires_at=expires_at,
147+
)
148+
149+
trust._info.pop('roles_links', None)
150+
trust._info.pop('links', None)
151+
152+
# Format roles into something sensible
153+
roles = trust._info.pop('roles')
154+
msg = ''.join([r['name'] + ' ' for r in roles])
155+
trust._info['roles'] = msg
156+
157+
return zip(*sorted(six.iteritems(trust._info)))
158+
159+
160+
class DeleteTrust(command.Command):
161+
"""Delete trust(s)"""
162+
163+
log = logging.getLogger(__name__ + '.DeleteTrust')
164+
165+
def get_parser(self, prog_name):
166+
parser = super(DeleteTrust, self).get_parser(prog_name)
167+
parser.add_argument(
168+
'trust',
169+
metavar='<trust>',
170+
help='Trust(s) to delete',
171+
nargs="+",
172+
)
173+
return parser
174+
175+
def take_action(self, parsed_args):
176+
self.log.debug('take_action(%s)' % parsed_args)
177+
identity_client = self.app.client_manager.identity
178+
for t in parsed_args.trust:
179+
trust_obj = utils.find_resource(identity_client.trusts, t)
180+
identity_client.trusts.delete(trust_obj.id)
181+
182+
183+
class ListTrust(lister.Lister):
184+
"""List trusts"""
185+
186+
log = logging.getLogger(__name__ + '.ListTrust')
187+
188+
def take_action(self, parsed_args):
189+
self.log.debug('take_action(%s)' % parsed_args)
190+
columns = ('ID', 'Expires At', 'Impersonation', 'Project ID',
191+
'Trustee User ID', 'Trustor User ID')
192+
data = self.app.client_manager.identity.trusts.list()
193+
return (columns,
194+
(utils.get_item_properties(
195+
s, columns,
196+
formatters={},
197+
) for s in data))
198+
199+
200+
class ShowTrust(show.ShowOne):
201+
"""Display trust details"""
202+
203+
log = logging.getLogger(__name__ + '.ShowTrust')
204+
205+
def get_parser(self, prog_name):
206+
parser = super(ShowTrust, self).get_parser(prog_name)
207+
parser.add_argument(
208+
'trust',
209+
metavar='<trust>',
210+
help='Trust to display',
211+
)
212+
return parser
213+
214+
def take_action(self, parsed_args):
215+
self.log.debug('take_action(%s)' % parsed_args)
216+
identity_client = self.app.client_manager.identity
217+
trust = utils.find_resource(identity_client.trusts,
218+
parsed_args.trust)
219+
220+
trust._info.pop('roles_links', None)
221+
trust._info.pop('links', None)
222+
223+
# Format roles into something sensible
224+
roles = trust._info.pop('roles')
225+
msg = ''.join([r['name'] + ' ' for r in roles])
226+
trust._info['roles'] = msg
227+
228+
return zip(*sorted(six.iteritems(trust._info)))

‎openstackclient/tests/identity/v3/fakes.py‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@
181181
'links': base_url + 'endpoints/' + endpoint_id,
182182
}
183183

184-
user_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
184+
user_id = 'bbbbbbb-aaaa-aaaa-aaaa-bbbbbbbaaaa'
185185
user_name = 'paul'
186186
user_description = 'Sir Paul'
187187
user_email = 'paul@applecorps.com'
@@ -196,6 +196,22 @@
196196
'links': base_url + 'users/' + user_id,
197197
}
198198

199+
trust_id = 't-456'
200+
trust_expires = None
201+
trust_impersonation = False
202+
trust_roles = {"id": role_id, "name": role_name},
203+
204+
TRUST = {
205+
'expires_at': trust_expires,
206+
'id': trust_id,
207+
'impersonation': trust_impersonation,
208+
'links': base_url + 'trusts/' + trust_id,
209+
'project_id': project_id,
210+
'roles': trust_roles,
211+
'trustee_user_id': user_id,
212+
'trustor_user_id': user_id,
213+
}
214+
199215
token_expires = '2014-01-01T00:00:00Z'
200216
token_id = 'tttttttt-tttt-tttt-tttt-tttttttttttt'
201217

@@ -342,6 +358,8 @@ def __init__(self, **kwargs):
342358
self.session = mock.Mock()
343359
self.session.auth.auth_ref.service_catalog.resource_class = \
344360
fakes.FakeResource(None, {})
361+
self.trusts = mock.Mock()
362+
self.trusts.resource_class = fakes.FakeResource(None, {})
345363
self.users = mock.Mock()
346364
self.users.resource_class = fakes.FakeResource(None, {})
347365
self.role_assignments = mock.Mock()

0 commit comments

Comments
 (0)