Working on a role for Authentik; as with any IdP, I’m dealing with users and groups. Authentik gives an idempotent API path to use for updating groups, and it uses JSON for the body of its API calls, which is convenient, except in one way. To define which users are in a group, I have to list the users by their “pk” number, which is a random number assigned when the user was created in the system.
user_info_from_api_call:
# A previous task makes an API request for this info that I register to a variable.
- name: Luke
pk: 2843
- name: ObiWan
pk: 4973
- name: Vader
pk: 8693
- name: Palpatine
pk: 6666
desired_groups:
- name: Jedi
is_superuser: true
users:
- Luke
- ObiWan
- name: Sith
is_superuser: false
users:
- Vader
- Palpatine
Given the above variables, I need to transform desired_groups by replacing the user names with their pk numbers to plug into my API request to idempotently update the group:
I tried using items2dict on user_info_from_api_call to make it easier to reference the pk number by the user’s name, then using map() on desired_groups, but couldn’t make it gel. I appreciate any solutions people might have.
I’m sure there’s a clever pipeline that will do this, but if you want me to be able to read it later, you’d better go old school and throw in some loops.
---
# JethCalark_01.yml
- name: Name games
hosts: localhost
gather_facts: false
vars:
user_info_from_api_call:
- name: Luke
pk: 2843
- name: ObiWan
pk: 4973
- name: Vader
pk: 8693
- name: Palpatine
pk: 6666
desired_groups:
- name: Jedi
is_superuser: true
users:
- Luke
- ObiWan
- name: Sith
is_superuser: false
users:
- Vader
- Palpatine
tasks:
- name: Substitute pk for user names
ansible.builtin.set_fact:
new_groups: |
{% set new_groups = [] -%}
{% for group in desired_groups -%}
{% set new_users = [] -%}
{% for user in group.users -%}
{% for uifac in user_info_from_api_call -%}
{% if uifac.name == user -%}
{% set _ = new_users.append(uifac.pk) -%}
{% endif -%}
{% endfor -%}
{% endfor -%}
{% set _ = new_groups.append({"name": group.name,
"is_superuser": group.is_superuser,
"users": new_users}) -%}
{% endfor %}{{ new_groups }}
That Jinja is definitely giving me flashbacks to certain templates…
I do tend to like the clever pipelines, and I also forget that Jinja can be used in Ansible tasks. Definitely going to need a moment to process that, to make sure I understand how it’s working.