ansible change value inside dictonary list

Viewed 145

I would like to disable some server and I need to change status inside dictionary list.

here is example

{
    "pool_members_list": [
        {
            "addressDiscovery": "static",
            "adminState": "enable",
            "serverAddresses": [
                "10.50.100.48"
            ],
            "servicePort": 80,
            "shareNodes": true
        },
        {
            "addressDiscovery": "static",
            "adminState": "enable",
            "serverAddresses": [
                "10.50.100.38"
            ],
            "servicePort": 80,
            "shareNodes": true
        }
    ]
}

I need to change "adminState": "disable" if the server IP is 10.50.100.48 I have tried this but does not work .

- name: disabled pool members
  set_fact:
    pool_members_changed: "{{ item | combine ( {'adminState': 'disabled'} ) }}"
  loop: "{{ pool_members_list }}"
  when: item['serverAddresses'][0] == '10.50.100.48'

The result should be this

[
        {
            "addressDiscovery": "static",
            "adminState": "disabled",
            "serverAddresses": [
                "10.50.100.48"
            ],
            "servicePort": 80,
            "shareNodes": true
        },
        {
            "addressDiscovery": "static",
            "adminState": "enable",
            "serverAddresses": [
                "10.50.100.38"
            ],
            "servicePort": 80,
            "shareNodes": true
        }
    ]
2 Answers

this playbook does the job:

  vars:
    pool_members_list:
    - addressDiscovery: static
      adminState: enable
      serverAddresses:
      - 10.50.100.48
      servicePort: 80
      shareNodes: true
    - addressDiscovery: static
      adminState: enable
      serverAddresses:
      - 10.50.100.38
      servicePort: 80
      shareNodes: true
  tasks:
    - name: disabled pool members
      set_fact:
        pool_members_changed: >-
                {{ pool_members_changed | d([]) + 
                    [ item | combine ( {'adminState': state} )] }}
      loop: "{{ pool_members_list }}"
      vars:
        ipstodisabled: ['10.50.100.48']
        ip: "{{ item['serverAddresses'][0] }}"
        state: "{{ 'disable' if ip in ipstodisabled else item.adminState }}"
      
    - debug:
        var: pool_members_changed

result:

ok: [localhost] => {
    "pool_members_changed": [
        {
            "addressDiscovery": "static",
            "adminState": "disable",
            "serverAddresses": [
                "10.50.100.48"
            ],
            "servicePort": 80,
            "shareNodes": true
        },
        {
            "addressDiscovery": "static",
            "adminState": "enable",
            "serverAddresses": [
                "10.50.100.38"
            ],
            "servicePort": 80,
            "shareNodes": true
        }
    ]
}

you could build your list of ipstodisabled...

i keep the value if ip is not in ipstodisabled

Given the data

    pm_list:
      - addressDiscovery: static
        adminState: enable
        serverAddresses:
          - 10.50.100.48
        servicePort: 80
        shareNodes: true
      - addressDiscovery: static
        adminState: enable
        serverAddresses:
          - 10.50.100.38
        servicePort: 80
        shareNodes: true

Declare the variables below

    pm_ip: "{{ pm_list|
               map(attribute='serverAddresses')|
               map('first')|list }}"
    pm_dict: "{{ dict(pm_ip|zip(pm_list)) }}"
    pm_dict_disable: "{{ dict(pm_ip_disable|d([])|
                              product([{'adminState': 'disable'}])) }}"
    pm_dict_update: "{{ pm_dict|combine(pm_dict_disable, recursive=True) }}"

The dictionary pm_dict_update will be updated whenever referenced. For example, declare the list of disabled servers pm_ip_disable and reference the variable

    - debug:
        var: pm_dict_update
      vars:
        pm_ip_disable:
          - 10.50.100.38

gives

  pm_dict_update:
    10.50.100.38:
      addressDiscovery: static
      adminState: disable
      serverAddresses:
      - 10.50.100.38
      servicePort: 80
      shareNodes: true
    10.50.100.48:
      addressDiscovery: static
      adminState: enable
      serverAddresses:
      - 10.50.100.48
      servicePort: 80
      shareNodes: true

Use this dictionary to update the list. For example

    - set_fact:
        pm_list: "{{ pm_dict_update.values()|list }}"
      vars:
        pm_ip_disable:
          - 10.50.100.38
    - debug:
        var: pm_list

gives

  pm_list:
  - addressDiscovery: static
    adminState: enable
    serverAddresses:
    - 10.50.100.48
    servicePort: 80
    shareNodes: true
  - addressDiscovery: static
    adminState: disable
    serverAddresses:
    - 10.50.100.38
    servicePort: 80
    shareNodes: true

Next to the list of disabled servers, you might want to maintain a list of enabled servers. Declare the variables

    pm_dict_disable: "{{ dict(pm_ip_disable|d([])|
                              product([{'adminState': 'disable'}])) }}"
    pm_dict_enable: "{{ dict(pm_ip_enable|d([])|
                              product([{'adminState': 'enable'}])) }}"
    pm_dict_update: "{{ pm_dict|combine(pm_dict_disable, recursive=True)|
                                combine(pm_dict_enable, recursive=True) }}"

Then, for example

    - set_fact:
        pm_list: "{{ pm_dict_update.values()|list }}"
      vars:
        pm_ip_disable: [10.50.100.48]
        pm_ip_enable: [10.50.100.38]
    - debug:
        var: pm_list

gives

  pm_list:
  - addressDiscovery: static
    adminState: disable
    serverAddresses:
    - 10.50.100.48
    servicePort: 80
    shareNodes: true
  - addressDiscovery: static
    adminState: enable
    serverAddresses:
    - 10.50.100.38
    servicePort: 80
    shareNodes: true

Putting it all together, the playbook below

shell> cat pb.yml
- hosts: localhost
  vars:
    pm_list:
      - addressDiscovery: static
        adminState: enable
        serverAddresses:
          - 10.50.100.48
        servicePort: 80
        shareNodes: true
      - addressDiscovery: static
        adminState: enable
        serverAddresses:
          - 10.50.100.38
        servicePort: 80
        shareNodes: true
    pm_ip: "{{ pm_list|
               map(attribute='serverAddresses')|
               map('first')|list }}"
    pm_dict: "{{ dict(pm_ip|zip(pm_list)) }}"
    pm_dict_disable: "{{ dict(pm_ip_disable|d([])|
                              product([{'adminState': 'disable'}])) }}"
    pm_dict_enable: "{{ dict(pm_ip_enable|d([])|
                              product([{'adminState': 'enable'}])) }}"
    pm_dict_update: "{{ pm_dict|combine(pm_dict_disable, recursive=True)|
                                combine(pm_dict_enable, recursive=True) }}"

  tasks:
    - set_fact:
        pm_list: "{{ pm_dict_update.values()|list }}"
      vars:
        pm_ip_disable:
          - 10.50.100.38
    - debug:
        var: pm_list

    - set_fact:
        pm_list: "{{ pm_dict_update.values()|list }}"
      vars:
        pm_ip_disable: [10.50.100.48]
        pm_ip_enable: [10.50.100.38]
    - debug:
        var: pm_list

gives

shell> ansible-playbook pb.yml 

PLAY [localhost] *****************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [localhost]

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  pm_list:
  - addressDiscovery: static
    adminState: enable
    serverAddresses:
    - 10.50.100.48
    servicePort: 80
    shareNodes: true
  - addressDiscovery: static
    adminState: disable
    serverAddresses:
    - 10.50.100.38
    servicePort: 80
    shareNodes: true

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  pm_list:
  - addressDiscovery: static
    adminState: disable
    serverAddresses:
    - 10.50.100.48
    servicePort: 80
    shareNodes: true
  - addressDiscovery: static
    adminState: enable
    serverAddresses:
    - 10.50.100.38
    servicePort: 80
    shareNodes: true

PLAY RECAP ***********************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Related