Skip to content

Commit b779757

Browse files
authored
Add groups, roles, and resource_roles to iam_user_info module (#163)
Signed-off-by: rsuplina <rsuplina@cloudera.com>
1 parent 64f8d9c commit b779757

File tree

2 files changed

+141
-30
lines changed

2 files changed

+141
-30
lines changed

plugins/modules/iam_user_info.py

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4-
# Copyright 2023 Cloudera, Inc. All Rights Reserved.
4+
# Copyright 2024 Cloudera, Inc. All Rights Reserved.
55
#
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
@@ -34,12 +34,13 @@
3434
author:
3535
- "Webster Mudge (@wmudge)"
3636
- "Dan Chaffelson (@chaffelson)"
37+
- "Ronald Suplina (@rsuplina)"
3738
options:
3839
name:
3940
description:
40-
- A list of user names or CRNs or a single user name/CRN.
41-
- If no user name or CRN is provided, all users are returned.
42-
- Mutually exclusive with C(current_user).
41+
- A list of user names or a single user name.
42+
- If no user name is provided, all users are returned.
43+
- Mutually exclusive with C(current_user) and C(user_id).
4344
type: list
4445
elements: str
4546
required: False
@@ -48,10 +49,17 @@
4849
current_user:
4950
description:
5051
- Flag to use the current user login.
51-
- Mutually exclusive with C(name).
52+
- Mutually exclusive with C(name) and C(user_id).
5253
type: bool
5354
required: False
5455
default: False
56+
user_id:
57+
description:
58+
- A list of user Ids or a single user Id name/CRN.
59+
- Mutually exclusive with C(current_user) and C(name).
60+
type: list
61+
elements: str
62+
required: False
5563
filter:
5664
description:
5765
- Key value pair where the key is the field to compare and the value is a regex statement. If there is a match in the regex statment, the user will return.
@@ -68,11 +76,20 @@
6876
6977
# List basic information about all Users
7078
- cloudera.cloud.iam_user_info:
79+
view: summary
7180
7281
# Gather detailed information about a named User
7382
- cloudera.cloud.iam_info:
7483
name: Example
7584
85+
# Gather detailed information specific user Id
86+
- cloudera.cloud.iam_info:
87+
user_id: "11a111a-91f0-4ca2-9262-111aa1111"
88+
89+
# Gather detailed information about more users
90+
- cloudera.cloud.iam_info:
91+
name: ["user1", "user2"]
92+
7693
# Gather detailed information about a named User
7794
- cloudera.cdp.iam_info:
7895
filter:
@@ -134,6 +151,18 @@
134151
returned: when supported
135152
type: str
136153
sample: u_023
154+
groups:
155+
description: List of groups that user is assigned.
156+
returned: when supported
157+
type: list
158+
roles:
159+
description: List of user assigned roles.
160+
returned: when supported
161+
type: list
162+
resource_roles:
163+
description: List of user assigned resource roles.
164+
returned: when supported
165+
type: list
137166
sdk_out:
138167
description: Returns the captured CDP SDK log.
139168
returned: when supported
@@ -154,6 +183,8 @@ def __init__(self, module):
154183
self.name = self._get_param("name")
155184
self.current = self._get_param("current_user", False)
156185
self.filter = self._get_param("filter")
186+
self.user_id = self._get_param("user_id")
187+
self.view = self._get_param("view")
157188

158189
# Initialize filter if set
159190
self.compiled_filter = self.compile_filters()
@@ -177,47 +208,72 @@ def compile_filters(self):
177208

178209
return compiled_filters
179210

211+
def get_detailed_user_info(self, user):
212+
user["groups"] = self.cdpy.iam.list_groups_for_user(user["userId"])
213+
user["roles"] = self.cdpy.iam.list_user_assigned_roles(user["userId"])
214+
user["resource_roles"] = self.cdpy.iam.list_user_assigned_resource_roles(
215+
user["userId"]
216+
)
217+
return user
218+
219+
def apply_filters(self):
220+
filtered_users = []
221+
# Iterate users
222+
for userData in self.cdpy.iam.list_users():
223+
# Iterate Filters. Must match all
224+
for filter_key, regx_expr in self.compiled_filter.items():
225+
key_val = userData.get(filter_key)
226+
if key_val and re.search(regx_expr, key_val):
227+
continue # Filter matches, continue to next filter
228+
else:
229+
break # No match, skip to next user
230+
else:
231+
# All filters matched, add user to filtered_users
232+
filtered_users.append(userData)
233+
return filtered_users
234+
180235
def process(self):
236+
181237
if self.current:
182238
self.info = [self.cdpy.iam.get_user()]
239+
240+
elif self.user_id:
241+
self.info = self.cdpy.iam.list_users(self.user_id)
242+
243+
elif self.name:
244+
user_list = self.cdpy.iam.list_users()
245+
for user in user_list:
246+
if user["workloadUsername"] in self.name:
247+
self.info.append(user)
248+
183249
elif self.filter is not None:
184-
filtered_users = []
185-
186-
# Iterate users
187-
for userData in self.cdpy.iam.list_users(): # self.name
188-
# Iterate Filters. Must match all
189-
for filter_key in self.compiled_filter:
190-
key_val = filter_key
191-
regx_expr = self.compiled_filter[filter_key]
192-
193-
key_val = userData[filter_key] if filter_key in userData else None
194-
if key_val is not None:
195-
regx_result = re.search(regx_expr, key_val)
196-
if regx_result is not None:
197-
filtered_users.append(userData)
198-
else:
199-
break # go to next user
200-
else:
201-
break # go to next user
202-
203-
self.info = filtered_users
204-
else:
205-
self.info = self.cdpy.iam.list_users(self.name)
250+
self.info = self.apply_filters()
251+
252+
if self.view == "full":
253+
for user in self.info:
254+
self.get_detailed_user_info(user)
206255

207256

208257
def main():
209258
module = AnsibleModule(
210259
argument_spec=CdpModule.argument_spec(
211-
name=dict(
212-
required=False, type="list", elements="str", aliases=["user_name"]
213-
),
260+
name=dict(required=False, type="list", aliases=["user_name"]),
261+
user_id=dict(required=False, type="list", aliases=["id"]),
214262
current_user=dict(required=False, type="bool"),
215263
filter=dict(required=False, type="dict"),
264+
view=dict(
265+
required=False,
266+
type="str",
267+
choices=["summary", "full"],
268+
default="full",
269+
),
216270
),
217271
mutually_exclusive=[
218272
["name", "current_user"],
219273
["filter", "current_user"],
220274
["filter", "name"],
275+
["user_id", "name"],
276+
["user_id", "current_user"],
221277
],
222278
supports_check_mode=True,
223279
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright 2024 Cloudera, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from __future__ import absolute_import, division, print_function
16+
17+
__metaclass__ = type
18+
19+
import pytest
20+
from plugins.modules import iam_user_info
21+
22+
from ansible_collections.cloudera.cloud.tests.unit.plugins.modules.utils import (
23+
AnsibleExitJson,
24+
setup_module_args,
25+
)
26+
27+
28+
def test_user_info_username():
29+
setup_module_args({"user_name": "mike01"})
30+
with pytest.raises(AnsibleExitJson) as e:
31+
iam_user_info.main()
32+
33+
34+
def test_user_info_get_multiple_usernames():
35+
setup_module_args({"user_name": ["mike01", "john01"]})
36+
with pytest.raises(AnsibleExitJson) as e:
37+
iam_user_info.main()
38+
39+
40+
def test_get_user_with_filter_by_first_name():
41+
setup_module_args({"filter": {"firstName": "Mike"}})
42+
with pytest.raises(AnsibleExitJson) as e:
43+
iam_user_info.main()
44+
45+
46+
def test_get_user_filter_by_email():
47+
setup_module_args({"filter": {"email": "mike"}})
48+
with pytest.raises(AnsibleExitJson) as e:
49+
iam_user_info.main()
50+
51+
52+
def test_get_all_users():
53+
setup_module_args({})
54+
with pytest.raises(AnsibleExitJson) as e:
55+
iam_user_info.main()

0 commit comments

Comments
 (0)