Home > database >  Combining 2 dictionairies: looping with ansible and jinja2
Combining 2 dictionairies: looping with ansible and jinja2

Time:03-11

I'm trying to loop through a dictionairy of teams which contain a permission_type, and loop through a second dictionairy to retrieve the values of that permission_type

List with teams:

teams:
  - name: "A"
    permission_type: admin_permissions
  - name: "B"
    permission_type: user_permissions
  - name: "C"
    permission_type: user_permissions

Dictionary with permissions:

permission_list:
  - admin_permissions:
    - Scope: permission1
      Rights: write
    - Scope: permission2
      Rights: write
  - user_permissions:
    - Scope: permission1
      Rights: read
    - Scope: permission2
      Rights: read

With the following role ansible task:

- name: Define role permissions
  command:
    chdir: "{{ bin_dir }}"
    cmd: |
      ./myscript.sh -modify_role -name "{{ item.name }}-access-role"  -add_permission
      {% for permissions in permission_list if item.permission_type == permissions %} -auth_resource "{{ permissions.Scope }}" -operation "{{ permissions.Rights }}" {% endfor %}
  loop: "{{ teams }}"

The error I get is that the if statement does not match, meaning everything after -add_permission is empty

Result should be:

./myscript.sh -modify_role -name "A-access-role"  -add_permission -auth_resource permission1 -operation write -auth_resource permission2 -operation write 

./myscript.sh -modify_role -name "B-access-role"  -add_permission -auth_resource permission1 -operation read -auth_resource permission2 -operation read 

./myscript.sh -modify_role -name "C-access-role"  -add_permission -auth_resource permission1 -operation read -auth_resource permission2 -operation read 

How can I achieve this?

CodePudding user response:

You could change your permission list so that you can lookup the rights for each type. So instead of using a list, use a dictionary where the type is the key:

permission_list:
  admin_permissions:
    - Scope: permission1
      Rights: write
    - Scope: permission2
      Rights: write
  user_permissions:
    - Scope: permission1
      Rights: read
    - Scope: permission2
      Rights: read

Then use with_items to go over your teams:

- name: Test
debug:
    msg: "{% for p in  permission_list[item.permission_type]%} scope: {{ p.Scope }} rights: {{ p.Rights }} {% endfor %}"
with_items: "{{ teams }}"

The result is:

    TASK [stack_overflow_1 : Test] *************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item={u'name': u'A', u'permission_type': u'admin_permissions'}) => {
    "msg": " scope: permission1 rights: write  scope: permission2 rights: write "
}
ok: [localhost] => (item={u'name': u'B', u'permission_type': u'user_permissions'}) => {
    "msg": " scope: permission1 rights: read  scope: permission2 rights: read "
}
ok: [localhost] => (item={u'name': u'C', u'permission_type': u'user_permissions'}) => {
    "msg": " scope: permission1 rights: read  scope: permission2 rights: read "
}

CodePudding user response:

Convert the list to a dictionary first. For example

    - set_fact:
        permission_dict: "{{ permission_dict|d({})|
                             combine({permission_type: auth_resource}) }}"
      loop: "{{ permission_list }}"
      vars:
        permission_type: "{{ item.keys()|first }}"
        auth_resource: |-
          {% for p in item|json_query('*')|flatten %}
           -auth_resource {{ p.Scope }} -operation {{ p.Rights }}
          {%- endfor %}

gives

  permission_dict:
    admin_permissions: " -auth_resource permission1 -operation write -auth_resource permission2 -operation write"
    user_permissions: " -auth_resource permission1 -operation read -auth_resource permission2 -operation read"

Use this dictionary to create the commands

    - debug:
        var: cmd
      loop: "{{ teams }}"
      vars:
        cmd: >-
          ./myscript.sh -modify_role -name {{ item.name }}-access-role
          -add_permission{{ permission_dict[item.permission_type] }}

gives (abridged)

  cmd: ./myscript.sh -modify_role -name A-access-role -add_permission -auth_resource permission1 -operation write -auth_resource permission2 -operation write
  cmd: ./myscript.sh -modify_role -name B-access-role -add_permission -auth_resource permission1 -operation read -auth_resource permission2 -operation read
  cmd: ./myscript.sh -modify_role -name C-access-role -add_permission -auth_resource permission1 -operation read -auth_resource permission2 -operation read
  • Related