字典列表中的ansible更改值

ansible change value inside dictonary list

我想禁用一些服务器,我需要在字典列表中更改状态。

这里是例子

{
    "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
        }
    ]
}

如果服务器IP是10.50.100.48,我需要更改"adminState": "disable" 我已经试过了,但没有用。

- 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'

结果应该是这样

[
        {
            "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
        }
    ]

这个剧本可以完成工作:

  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

结果:

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
        }
    ]
}

您可以建立您的 ipstodisabled 列表...

如果 ip 不在 ipstodisabled 中,我会保留该值

给定数据

    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_update: "{{ pm_dict|combine(pm_dict_disable, recursive=True) }}"

词典pm_dict_update将在每次引用时更新。例如,声明禁用服务器列表pm_ip_disable并引用变量

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

给予

  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

使用这本词典更新列表。例如

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

给予

  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

在禁用服务器列表旁边,您可能想要维护一个启用服务器列表。声明变量

    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) }}"

然后,例如

    - 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

给予

  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

将所有内容放在一起,就是下面的剧本

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

给予

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