如何使用另一个包含字典的列表循环遍历一个列表

问题描述 投票:0回答:1

我在使用正在开发的 Ansible Playbook 时遇到了一些问题。我使用 vm_hardware_disk_module 来在特定 vCenter 中的特定虚拟机上创建多个虚拟磁盘。

这是我编写的 .yml,用于循环虚拟机和 vCenter。

server_list:
- cpu_count: 6
  memory_size: 12288
  name: nodeA
  vcenter: vCenterA
  vdisks:
    - capacity: 107374182400
    - capacity: 214748364800

最终目标应该与此类似,即按索引遍历 .yml 文件并动态更改 CPU/内存并根据需要添加虚拟磁盘:

server_list:
- cpu_count: 6
  memory_size: 12288
  name: nodeA
  vcenter: vCenterA
  vdisks:
    - capacity: 107374182400
    - capacity: 214748364800

- cpu_count: 2
  memory_size: 2048
  name: nodeB
  vcenter: vCenterB
  vdisks:
    - capacity: 123415414552
    - capacity: 436345634633

作为我最近创建的剧本的参考,这就是我循环遍历虚拟机和 vCenter 的方式,以便让我获取所需的信息并动态升级 CPU/内存。

- name: Gather current VM information
  vmware.vmware_rest.vcenter_vm_info:
    vcenter_username: "{{ SECRET.USER }}"
    vcenter_password: "{{ SECRET.PASS }}"
    vcenter_hostname: "{{ item.vcenter }}"
    names: "{{ item.name }}"
  loop: "{{ server_list }}"
  register: vm_info

- name: Upgrade CPU
  vmware.vmware_rest.vcenter_vm_hardware_cpu:
    vcenter_username: "{{ SECRET.USER }}"
    vcenter_password: "{{ SECRET.PASS }}"
    vcenter_hostname: "{{ item.vcenter }}"
    vm: "{{ vm_info.results[item_index]['value'][0]['vm'] }}"
    count: "{{ item.cpu_count }}"
  when: vm_info.results[item_index]['value'][0]['cpu_count'] != item.cpu_count
  loop: "{{ server_list }}"
  loop_control:
    index_var: item_index`

这使我能够跨不同的 vCenter 循环并动态升级多个虚拟机。这是我正在从事的工作的第一部分,现在我正在尝试实现第二部分,其中添加虚拟磁盘(如果指定)。

这是创建虚拟磁盘的模块

`- name: Create a new Disk
  vmware.vmware_rest.vcenter_vm_hardware_disk:
   vcenter_username: <username>
   vcenter_password: <password>
   vcenter_hostname: "{{ item.vcenter }}"
   vm: "{{ vm_info.results[item_index]['value'][0]['vm'] }}"
   new_vmdk:
     capacity: "{{ }}" <-- What I need to loop through
     type: SCSI
  loop: "{{ server_list }}"
  loop_control:
     index_var: item_index`

我尝试过多种选择,例如

item.vdisks | map(attribute='capacity')
item | json_query('[].vdisks[].capacity)
item.vdisks.capacity
- name: Debug
  ansible.builtin.debug:
   msg: <The Integer Loop I want>
  loop: "{{ server_list }}"

这就是我循环“{{ server_list }}”时的输出:

{
  "item": {
    "cpu_count": 6,
    "memory_size": 12288,
    "name": "nodeA",
    "vcenter": "vCenterA",
    "vdisks": [
      {
        "capacity": 107374182400
      },
      {
        "capacity": 214748364800
      }
    ]
  }
}

我看到的最终输出是它创建第一个虚拟磁盘,然后再次循环执行任务并创建第二个虚拟磁盘。该任务完成后,它将继续执行服务器列表的下一个索引,即另一个虚拟机和 vCenter。

我需要将 server_list 保留为循环,因为这允许我在“创建新磁盘”任务中循环访问 vCenter(除非可能有其他方法),因为我试图保持所有内容动态而不是硬编码。 (.yml 文件是动态的,通过自动化创建)

ansible ansible-2.x ansible-template
1个回答
0
投票

使用

subelement
过滤器:

---
- hosts: localhost
  gather_facts: false

  vars:
    server_list:
      - cpu_count: 6
        memory_size: 12288
        name: nodeA
        vcenter: vCenterA
        vdisks:
          - capacity: 107374182400
          - capacity: 214748364800
      - cpu_count: 2
        memory_size: 2048
        name: nodeB
        vcenter: vCenterB
        vdisks:
          - capacity: 123415414552
          - capacity: 436345634633

  tasks:
    - name: debug task to illustrate the use of the `subelements` filter
      ansible.builtin.debug:
        msg:
          - name is {{ item.0.name }}
          - memory is {{ item.0.memory_size }}
          - cpu count is {{ item.0.cpu_count }}
          - vcenter is {{ item.0.vcenter }}
          - disks capacities for this node are {{ item.0.vdisks }} ...
          - ... but current disk capacity we loop on is {{ item.1.capacity | int }}
      loop: "{{ server_list | subelements('vdisks') }}"

剧本结果:

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

TASK [debug task to illustrate the use of the `subelements` filter] ********************************************************************************************************************************************************************
ok: [localhost] => (item=[{'cpu_count': 6, 'memory_size': 12288, 'name': 'nodeA', 'vcenter': 'vCenterA', 'vdisks': [{'capacity': 107374182400}, {'capacity': 214748364800}]}, {'capacity': 107374182400}]) => {
    "msg": [
        "name is nodeA",
        "memory is 12288",
        "cpu count is 6",
        "vcenter is vCenterA",
        "disks for this node are [{'capacity': 107374182400}, {'capacity': 214748364800}] ...",
        "... but current disk we loop on is {'capacity': 107374182400}"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 6, 'memory_size': 12288, 'name': 'nodeA', 'vcenter': 'vCenterA', 'vdisks': [{'capacity': 107374182400}, {'capacity': 214748364800}]}, {'capacity': 214748364800}]) => {
    "msg": [
        "name is nodeA",
        "memory is 12288",
        "cpu count is 6",
        "vcenter is vCenterA",
        "disks for this node are [{'capacity': 107374182400}, {'capacity': 214748364800}] ...",
        "... but current disk we loop on is {'capacity': 214748364800}"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 2, 'memory_size': 2048, 'name': 'nodeB', 'vcenter': 'vCenterB', 'vdisks': [{'capacity': 123415414552}, {'capacity': 436345634633}]}, {'capacity': 123415414552}]) => {
    "msg": [
        "name is nodeB",
        "memory is 2048",
        "cpu count is 2",
        "vcenter is vCenterB",
        "disks for this node are [{'capacity': 123415414552}, {'capacity': 436345634633}] ...",
        "... but current disk we loop on is {'capacity': 123415414552}"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 2, 'memory_size': 2048, 'name': 'nodeB', 'vcenter': 'vCenterB', 'vdisks': [{'capacity': 123415414552}, {'capacity': 436345634633}]}, {'capacity': 436345634633}]) => {
    "msg": [
        "name is nodeB",
        "memory is 2048",
        "cpu count is 2",
        "vcenter is vCenterB",
        "disks for this node are [{'capacity': 123415414552}, {'capacity': 436345634633}] ...",
        "... but current disk we loop on is {'capacity': 436345634633}"
    ]
}

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

olcla@annapurna:/tmp/toto$ ansible-playbook bla.yml 

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

TASK [debug task to illustrate the use of the `subelements` filter] ********************************************************************************************************************************************************************
ok: [localhost] => (item=[{'cpu_count': 6, 'memory_size': 12288, 'name': 'nodeA', 'vcenter': 'vCenterA', 'vdisks': [{'capacity': 107374182400}, {'capacity': 214748364800}]}, {'capacity': 107374182400}]) => {
    "msg": [
        "name is nodeA",
        "memory is 12288",
        "cpu count is 6",
        "vcenter is vCenterA",
        "disks capacities for this node are [{'capacity': 107374182400}, {'capacity': 214748364800}] ...",
        "... but current disk capacity we loop on is 107374182400"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 6, 'memory_size': 12288, 'name': 'nodeA', 'vcenter': 'vCenterA', 'vdisks': [{'capacity': 107374182400}, {'capacity': 214748364800}]}, {'capacity': 214748364800}]) => {
    "msg": [
        "name is nodeA",
        "memory is 12288",
        "cpu count is 6",
        "vcenter is vCenterA",
        "disks capacities for this node are [{'capacity': 107374182400}, {'capacity': 214748364800}] ...",
        "... but current disk capacity we loop on is 214748364800"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 2, 'memory_size': 2048, 'name': 'nodeB', 'vcenter': 'vCenterB', 'vdisks': [{'capacity': 123415414552}, {'capacity': 436345634633}]}, {'capacity': 123415414552}]) => {
    "msg": [
        "name is nodeB",
        "memory is 2048",
        "cpu count is 2",
        "vcenter is vCenterB",
        "disks capacities for this node are [{'capacity': 123415414552}, {'capacity': 436345634633}] ...",
        "... but current disk capacity we loop on is 123415414552"
    ]
}
ok: [localhost] => (item=[{'cpu_count': 2, 'memory_size': 2048, 'name': 'nodeB', 'vcenter': 'vCenterB', 'vdisks': [{'capacity': 123415414552}, {'capacity': 436345634633}]}, {'capacity': 436345634633}]) => {
    "msg": [
        "name is nodeB",
        "memory is 2048",
        "cpu count is 2",
        "vcenter is vCenterB",
        "disks capacities for this node are [{'capacity': 123415414552}, {'capacity': 436345634633}] ...",
        "... but current disk capacity we loop on is 436345634633"
    ]
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
© www.soinside.com 2019 - 2024. All rights reserved.