Search code examples
postgresqlansiblevault

Combining two dictionaries and creating a list of dictionaries with updated credentials


I would like a helping hand to create a new data structure, which compares the two dictionaries,

then create a list with dictionaries. The idea being that in case of change to keep the old versions and add the modified usernames/password.

Goal:

list: [{"username": "a1", "password": "apass1"}, {"username": "a2", "password": "apass2"}, {"username": "b1", "password": "bpass1"}, {"username": "c1", "password": "cpass1"}, {"c_username": "c1", "c_password" : "cpass1"} , {"c_username": "c2", "c2_password" : "cpass1"}]
---
name: "Username/Password version 1"
set_fact:
  dict1: {"a_username": "a1", "a_password" : "apass1", "b_username": "b1", "b_password" : "bpass1", "c_username": "c1", "c_password" : "cpass1"}

name: "Username/Password version 2"
set_fact:
  dict2: {"a_username": "a2", "a_password" : "apass2", "b_username": "b1", "b_password" : "bpass1", "c_username": "c2", "c2_password" : "cpass1"}

I would like this to be useful for managing service interruptions in my PostgreSQL database. I also retrieve the username/password data from vault


Solution

  • Given the dictionaries

        dict1:
          a_username: a1
          a_password: apass1
          b_username: b1
          b_password: bpass1
          c_username: c1
          c_password: cpass1
          
        dict2:
          a_username: a2
          a_password: apass2
          b_username: b1
          b_password: bpass1
          c_username: c2
          c_password: cpass1
    

    Q: "Keep the old versions and add the modified usernames/password."

    A: The template below

        list1: |
          {% filter from_yaml %}
          {% for i in dict1.keys()|batch(2) %}
          - {username: {{ dict1[i.0] }}, password: {{ dict1[i.1] }}}
          {% if dict1[i.0] != dict2[i.0] or dict1[i.1] != dict2[i.1] %}
          - {username: {{ dict2[i.0] }}, password: {{ dict2[i.1] }}}
          {% endif %}
          {% endfor %}
          {% endfilter %}
    

    gives

        list1:
          - {password: apass1, username: a1}
          - {password: apass2, username: a2}
          - {password: bpass1, username: b1}
          - {password: cpass1, username: c1}
          - {password: cpass1, username: c2}
    

    The next option is getting the unique username/password pairs and creating a dictionary

        dict3: "{{ dict((dict1.values()|list + dict2.values()|list)|
                        batch(2)|unique) }}"
    

    gives

        dict3:
          a1: apass1
          a2: apass2
          b1: bpass1
          c1: cpass1
          c2: cpass1
    

    Convert the dictionary to a list and you get the same result

        list1: "{{ dict3|
                   dict2items(key_name='username', value_name='password')|
                   sort(attribute='username') }}"