Skip to content

Commit 1ce56d3

Browse files
committed
Get users and groups from distinct API requests
An API request to retrieve a list of all users and groups is subject to pagination, which can break assumptions if your object exists but is not returned in the first page results. Query each user and group from the API directly, and then parse the result to distinguish between objects that are present or absent.
1 parent f3debaa commit 1ce56d3

File tree

4 files changed

+102
-132
lines changed

4 files changed

+102
-132
lines changed

roles/pulp_group/tasks/main.yml

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,45 @@
11
---
22

3-
- name: Get group list
3+
- name: Get information for each group
44
uri:
5-
url: "{{ pulp_group_url }}"
5+
url: "{{ pulp_group_url }}?name={{ item.name }}"
66
user: "{{ pulp_username }}"
77
password: "{{ pulp_password }}"
88
method: GET
99
status_code: 200
1010
force_basic_auth: true
11-
register: groups_list_result
11+
loop: "{{ pulp_groups }}"
12+
register: groups_get_result
13+
14+
- name: Reset groups facts
15+
set_fact:
16+
remove_groups: []
17+
create_groups: []
18+
19+
- name: Set groups to remove fact
20+
set_fact:
21+
remove_groups: "{{ remove_groups + [group.json.results[0]] }}"
22+
loop: "{{ groups_get_result.results }}"
23+
loop_control:
24+
loop_var: "group"
25+
label: "{{ group.item.name }}"
26+
when:
27+
- group.json.count == 1
28+
- group.item.state is defined
29+
- group.item.state == "absent"
1230

13-
- name: Set fact remove_groups
31+
- name: Set groups to create fact
1432
set_fact:
15-
remove_groups: "{{ (remove_groups | default([])) + [item.name] }}"
16-
when: item.state is defined and item.state == 'absent'
17-
with_items: "{{ pulp_groups }}"
33+
create_groups: "{{ create_groups + [group.item] }}"
34+
loop: "{{ groups_get_result.results }}"
35+
loop_control:
36+
loop_var: "group"
37+
label: "{{ group.item.name }}"
38+
when:
39+
- group.json.count == 0
40+
- group.item.state is not defined or group.item.state != "absent"
1841

1942
- name: Create groups
20-
vars:
21-
groupnames: "{{ groups_list_result.json.results | map(attribute='name') | list }}"
2243
uri:
2344
url: "{{ pulp_group_url }}"
2445
user: "{{ pulp_username }}"
@@ -29,32 +50,21 @@
2950
body:
3051
name: "{{ item.name }}"
3152
body_format: form-urlencoded
32-
loop: "{{ pulp_groups }}"
33-
register: result
34-
when:
35-
- item.name not in groupnames
36-
- item.state is not defined or item.state != 'absent'
37-
changed_when: result.status == 201
38-
39-
- name: Initialise hrefs
40-
set_fact:
41-
hrefs: []
42-
43-
- name: Set fact hrefs
44-
set_fact:
45-
hrefs: "{{ (hrefs | default([])) + [item.pulp_href] }}"
46-
when: item.name in (remove_groups | default([]))
47-
with_items: "{{ groups_list_result.json.results }}"
53+
loop: "{{ create_groups }}"
54+
loop_control:
55+
label: "{{ item.name }}"
56+
changed_when: true
4857

4958
- name: Remove groups
5059
uri:
51-
url: "{{ pulp_url }}{{ item }}"
60+
url: "{{ pulp_url }}{{ item.pulp_href }}"
5261
user: "{{ pulp_username }}"
5362
password: "{{ pulp_password }}"
5463
force_basic_auth: true
5564
method: DELETE
5665
status_code: 204
5766
body_format: form-urlencoded
58-
loop: "{{ hrefs }}"
59-
register: result
60-
changed_when: result.status == 204
67+
loop: "{{ remove_groups }}"
68+
loop_control:
69+
label: "{{ item.name }}"
70+
changed_when: true

roles/pulp_user/tasks/main.yml

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,56 @@
11
---
2-
3-
- name: Get user list
2+
- name: Get information for each user
43
uri:
5-
url: "{{ pulp_user_url }}"
4+
url: "{{ pulp_user_url }}?username={{ item.username }}"
65
user: "{{ pulp_username }}"
76
password: "{{ pulp_password }}"
87
method: GET
98
status_code: 200
109
force_basic_auth: true
11-
register: users_list_result
10+
loop: "{{ pulp_users }}"
11+
register: users_get_result
12+
13+
- name: Reset users facts
14+
set_fact:
15+
remove_users: []
16+
create_users: []
17+
update_users: []
18+
19+
- name: Set users to delete fact
20+
set_fact:
21+
remove_users: "{{ remove_users + [user.json.results[0]] }}"
22+
loop: "{{ users_get_result.results }}"
23+
loop_control:
24+
loop_var: "user"
25+
label: "{{ user.item.username }}"
26+
when:
27+
- user.json.count == 1
28+
- user.item.state is defined
29+
- user.item.state == "absent"
1230

13-
- name: Set fact remove_users
31+
- name: Set users to create fact
1432
set_fact:
15-
remove_users: "{{ (remove_users | default([])) + [item.username] }}"
16-
when: item.state is defined and item.state == 'absent'
17-
with_items: "{{ pulp_users }}"
33+
create_users: "{{ create_users + [user.item] }}"
34+
loop: "{{ users_get_result.results }}"
35+
loop_control:
36+
loop_var: "user"
37+
label: "{{ user.item.username }}"
38+
when:
39+
- user.json.count == 0
40+
- user.item.state is not defined or user.item.state != "absent"
41+
42+
- name: Set users to update fact
43+
set_fact:
44+
update_users: "{{ update_users + [user.json.results[0] | combine(user.item) | combine({'existing_groups': user.json.results[0]['groups']}) ] }}"
45+
loop: "{{ users_get_result.results }}"
46+
loop_control:
47+
loop_var: "user"
48+
label: "{{ user.item.username }}"
49+
when:
50+
- user.json.count == 1
51+
- user.item.state is not defined or user.item.state != "absent"
1852

1953
- name: Create users
20-
vars:
21-
usernames: "{{ users_list_result.json.results | map(attribute='username') | list }}"
2254
uri:
2355
url: "{{ pulp_user_url }}"
2456
user: "{{ pulp_username }}"
@@ -35,21 +67,14 @@
3567
is_staff: "{{ item.is_staff | default(None) }}"
3668
is_active: "{{ item.is_active | default(None) }}"
3769
body_format: form-urlencoded
38-
loop: "{{ pulp_users }}"
70+
loop: "{{ create_users }}"
3971
loop_control:
4072
label: "{{ item.username }}"
41-
register: result
42-
when:
43-
- item.username not in usernames
44-
- item.state is not defined or item.state != 'absent'
45-
changed_when: result.status == 201
73+
changed_when: true
4674

4775
- name: Update existing users
48-
vars:
49-
usernames: "{{ users_list_result.json.results | map(attribute='username') | list }}"
50-
url_query: "[?username=='{{ item.username }}'].pulp_href"
5176
uri:
52-
url: "{{ pulp_url }}{{ users_list_result.json.results | json_query(url_query) | first }}"
77+
url: "{{ pulp_url }}{{ item.pulp_href }}"
5378
user: "{{ pulp_username }}"
5479
password: "{{ pulp_password }}"
5580
force_basic_auth: true
@@ -63,46 +88,30 @@
6388
is_staff: "{{ item.is_staff | default(None) }}"
6489
is_active: "{{ item.is_active | default(None) }}"
6590
body_format: form-urlencoded
66-
loop: "{{ pulp_users }}"
91+
loop: "{{ update_users }}"
6792
loop_control:
6893
label: "{{ item.username }}"
6994
register: result
70-
when:
71-
- item.username in usernames
72-
- item.state is not defined or item.state != 'absent'
73-
changed_when:
74-
# The pulp API currently does not report when a change is made, so we must
75-
# manually check
76-
- result.json not in users_list_result.json.results
77-
- result.status == 200
95+
changed_when: true
7896

7997
- name: Add or remove user from group(s)
8098
include_tasks: user_groups/add_or_remove_users.yml
81-
# Noop if pulp_users is defined but empty
82-
loop: "{{ pulp_users }}"
83-
when: item.state is not defined or item.state != 'absent'
99+
# All users that aren't state: absent are in play here
100+
loop: "{{ create_users + update_users }}"
84101
loop_control:
85102
loop_var: user
86-
87-
- name: Initialise hrefs
88-
set_fact:
89-
hrefs: []
90-
91-
- name: Set fact hrefs
92-
set_fact:
93-
hrefs: "{{ (hrefs | default([])) + [item.pulp_href] }}"
94-
when: item.username in (remove_users | default([]))
95-
with_items: "{{ users_list_result.json.results }}"
103+
label: "{{ user.username }}"
96104

97105
- name: Delete users
98106
uri:
99-
url: "{{ pulp_url }}{{ item }}"
107+
url: "{{ pulp_url }}{{ item.pulp_href }}"
100108
user: "{{ pulp_username }}"
101109
password: "{{ pulp_password }}"
102110
force_basic_auth: true
103111
method: DELETE
104112
status_code: 204
105113
body_format: form-urlencoded
106-
loop: "{{ hrefs }}"
107-
register: result
108-
changed_when: result.status == 204
114+
loop: "{{ remove_users }}"
115+
loop_control:
116+
label: "{{ item.username }}"
117+
changed_when: true
Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
11
---
22

3-
- name: Get all groups that user belongs to
4-
uri:
5-
url: "{{ pulp_user_url }}?username={{ user.username }}"
6-
user: "{{ pulp_username }}"
7-
password: "{{ pulp_password }}"
8-
method: GET
9-
status_code: 200
10-
force_basic_auth: true
11-
register: user_group_result
12-
13-
- name: Set current_group_membership fact
14-
set_fact:
15-
current_group_membership: "{{ user_group_result | json_query('json.results[*].groups') | flatten | map(attribute='name') | list }}"
16-
173
- name: Remove user from groups not defined in pulp_users
184
include_tasks: remove_user_from_groups.yml
19-
loop: "{{ current_group_membership | difference(user.groups | default([], true)) }}"
5+
loop: "{{ user.existing_groups | map(attribute='name') | difference(user.groups | default([], true)) }}"
206
loop_control:
217
loop_var: remove_group
8+
when: user.existing_groups is defined
229

2310
- name: Add user to groups defined in pulp_users
2411
include_tasks: add_user_to_groups.yml
25-
loop: "{{ user.groups | default([], true) | difference(current_group_membership) }}"
12+
loop: "{{ user.groups | default([], true) | difference(user.existing_groups | default([]) | map(attribute='name') ) }}"
2613
loop_control:
2714
loop_var: add_group
Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,11 @@
11
---
22
# These user/group combinations definitely DO exist on pulp server
33

4-
- name: Get group href from Pulp API
5-
uri:
6-
url: "{{ pulp_add_group_user_url }}?name={{ remove_group }}"
7-
user: "{{ pulp_username }}"
8-
password: "{{ pulp_password }}"
9-
method: GET
10-
status_code: 200
11-
force_basic_auth: true
12-
register: group_href_result
13-
14-
# We should only return a single group here because we've just queried
15-
# from pulp API
16-
- name: Fail when group cannot be unambiguosly returned from Pulp API
17-
fail:
18-
msg: >
19-
"Pulp API query: GET '{{ group_href_result.url }}' did not return
20-
exactly one group. Groupname '{{ remove_group }}' was found
21-
'{{ group_href_result.json.count }}' times.
22-
Groupnames should be unique and exist before associating users
23-
with them"
24-
when: group_href_result.json.count != 1
25-
26-
- name: Get user id from Pulp API
27-
uri:
28-
url: "{{ pulp_user_url }}?username={{ user.username }}"
29-
user: "{{ pulp_username }}"
30-
password: "{{ pulp_password }}"
31-
method: GET
32-
status_code: 200
33-
force_basic_auth: true
34-
register: user_list_result
35-
36-
- name: Fail when user id cannot be unambiguosly returned from Pulp API
37-
fail:
38-
msg: >
39-
"Pulp API query: GET '{{ user_list_result.url }}' did not return
40-
exactly one user id. User '{{ user.username }}' was found
41-
'{{ user_list_result.json.count }}' times."
42-
when: user_list_result.json.count != 1
43-
444
# Will fail before we get here if the group/user doesn't exist
455
- name: Remove user from group
466
# DELETE {{ pulp_url }}/pulp/api/v3/groups/880/users/11/
477
uri:
48-
url: "{{ pulp_url }}{{ group_href_result.json.results[0].pulp_href }}users/{{ user_list_result.json.results[0].id }}/"
8+
url: "{{ pulp_url }}{{ user_group.pulp_href }}users/{{ user.id }}/"
499
user: "{{ pulp_username }}"
5010
password: "{{ pulp_password }}"
5111
method: DELETE
@@ -54,3 +14,7 @@
5414
force_basic_auth: true
5515
# If we get here, we're always changing something
5616
changed_when: true
17+
loop: "{{ user.existing_groups | selectattr('name', 'equalto', remove_group) }}"
18+
loop_control:
19+
loop_var: user_group
20+
label: "{{ user.username }} {{ user_group.name }}"

0 commit comments

Comments
 (0)