redhat_cloudforms_azure_arm.../ansible-netapp-qtree-provison/group_lookup.yml

191 lines
8.3 KiB
YAML
Executable File

---
- name: nested groups loop
block:
- name: Reset loop variables # without unsetting infinte loops will occur
set_fact:
group_present: false
find_groups: []
#find_users: [] # we dont want to reset this var, this will append on each loop until exit (unexpected behaviour but works)
find_group_members_tidy: []
group_members: []
samaccountname_tidy: []
samaccountname_group_members: []
member_type: []
member_attributes: []
# - name: Inspect dummy host object_attributes
# debug:
# msg: "{{ hostvars['DUMMY_HOST']['object_attributes'] }}"
- name: Filter groups into a list - CHANGED
set_fact:
find_groups: "{{ find_groups | default([]) + [dict(name=item.name, role=item.role, type=item.type)] }}"
with_items: "{{ hostvars['DUMMY_HOST']['object_attributes'] }}"
when: item.type == 'Group'
- name: Append users to list - CHANGED
set_fact:
find_users: "{{ find_users | default([]) + [dict(name=item.name, role=item.role, type=item.type)] }}"
with_items: "{{ hostvars['DUMMY_HOST']['object_attributes'] }}"
when: item.type == 'Person'
# - debug:
# msg:
# - "{{ find_groups }}"
# - "{{ find_users }}"
# when: find_groups is defined
- name: Query group members
win_shell: ([ADSISearcher] "(sAMAccountName={{ item.name }})").FindOne().Properties.member
register: find_group_members_result
with_items: "{{ find_groups }}"
when: find_groups is defined
# - debug:
# msg: "{{ find_group_members_result }}"
# when: find_group_members_result is defined
- name: Tidy group members into dict of names and role
set_fact:
find_group_members_tidy: '{{ find_group_members_tidy | default([]) + [dict(name=item.name, role=item.role)] }}'
with_items: "{{ find_group_members_result | json_query(jmesquery) }}"
vars:
jmesquery: "results[].{role: @.item.role, name: @.stdout_lines}"
when: find_groups is defined # new - did i miss this in the demo
- name: Tidy group members into dict of name and role
set_fact:
group_members: "{{ group_members | default([]) + [dict(name=item.1.split(',')[0].split('CN=')[1], role=item.0.role)] }}"
with_subelements:
- "{{ find_group_members_tidy }}"
- name
when: find_groups is defined # new - did i miss this in the demo
# - debug:
# msg: "{{ group_members }}"
# when: group_members is defined
# the UoN account field distinguishedname uses the short account name the same as samaccountname - this is helpful when looking up group members
# distinguishedname {CN=tseed,CN=Users,DC=netappsim,DC=local}
# samaccountname {tseed}
#
# out of the box AD will have the full name of the user in the distinguishedname field
# distinguishedname {CN=Toby Seed,CN=Users,DC=netappsim,DC=local}
# samaccountname {tseed}
#
# an additional check follows to lookup a samaccountname using the distinguishedname, this maintains compatibility with non UoN AD
- name: Find group members sAMAccountName
win_shell: ([ADSISearcher] "(cn={{ item.name }})").FindOne().Properties.samaccountname
register: samaccountname_result
with_items: "{{ group_members }}"
when: group_members is defined
- name: Tidy group members sAMAccountName into list
set_fact:
samaccountname_tidy: "{{ samaccountname_tidy | default([]) + [(item.stdout_lines)[0]] }}"
with_items: "{{ samaccountname_result.results }}"
when: group_members is defined
- name: Rebuild group_members dict with sAMAccountName
set_fact:
samaccountname_group_members: "{{ samaccountname_group_members | default([]) + [ dict(name=item[1], role=item[0].role) ] }}"
loop: "{{ group_members|zip(samaccountname_tidy)|list }}"
when: group_members is defined
# - debug:
# msg: "{{ samaccountname_group_members }}"
# when: group_members is defined
- name: copy samaccountname_group_members to group_members
set_fact:
group_members: "{{ samaccountname_group_members }}"
when: samaccountname_group_members is defined
# - debug:
# msg: "{{ group_members }}"
# when: group_members is defined
- name: Check AD object is user or group
win_shell: ([ADSISearcher] "(sAMAccountName={{ item.name }})").FindOne().Properties.objectcategory
register: member_type_result
with_items: "{{ group_members }}"
when: group_members is defined
# - debug:
# msg: "{{ member_type_result }}"
# when: group_members is defined
- name: Build list of AD object type
set_fact:
member_type: "{{ member_type | default([]) + [(item.stdout.split(',')[0].split('CN=')[1])] }}"
with_items: "{{ member_type_result.results }}"
when: group_members is defined
# - debug:
# msg: "{{ member_type }}"
# when: group_members is defined
- name: Build dict of object names and types
set_fact:
member_attributes: "{{ member_attributes | default([]) + [ dict(name=item[0].name, role=item[0].role, type=item[1]) ] }}" # effectively adding a new positional field from the list to the dict
loop: "{{ group_members|zip(member_type)|list }}"
when: group_members is defined
# - debug:
# msg: "{{ member_attributes }}"
# when: group_members is defined
- name: Reset/Add variable object_attributes to dummy host for next loop
add_host:
name: "DUMMY_HOST"
object_attributes: "{{ member_attributes }}"
when: member_attributes is defined
- name: Set flag to notify there are nested groups
set_fact:
group_present: true
with_items: "{{ member_attributes }}"
when: member_attributes is defined and item.type == 'Group'
#when: member_attributes is defined and item.type == 'GroupA' # used to break loop with test for no group_present
- name: Nested group present?
fail:
msg: Nested group detected, loop will run again
when: group_present
# the following tasks only run on the last run of the loop where there are no more groups detected
# append the users from the last run of the loop to find_users
# set find_users as a DUMMY_HOST variable to be retrieved from the calling script - this is how you pass variables back from different plays also works for include_tasks
- name: Append users to list
set_fact:
find_users: "{{ find_users | default([]) + [dict(name=item.name, type=item.type, role=item.role)] }}"
with_items: "{{ member_attributes }}"
when: item.type == 'Person'
# if the script was passed the members parameter containing only a group and the requester_user_ad is a member of this group
# there wont be an entry in the find_users dict as this wont have been caught and assigned the role='requestor' in the calling script
# all requester flag logic could be moved here, the calling script wouldnt need to pass the role key, we keep it for illustration as
# this script was origionally designed to assign roles for different RWX permissions on GPFS
# we add the user to the dict with role='requester'
- name: Check if requestor was nested in group and not passed in the members parameter
set_fact:
requester_found: "{{ item.name }}"
with_items: "{{ find_users }}"
when: item.name == requester_user_ad
- name: Add requestor if it was nested in group and not passed in the members parameter
set_fact:
find_users: "{{ find_users + [dict(name=requester_found, type='Person', role='requester')] }}"
when: requester_found is defined
- name: Add users to variable find_users for dummy host on final loop
add_host:
name: "DUMMY_HOST"
find_users: "{{ find_users }}"
when: find_users is defined
rescue:
- include_tasks: group_lookup.yml