首页 > 解决方案 > Ansible:使用公共键将值分组在同一行

问题描述

我正在努力使用 ansible 将一些常见值分组在同一行上。
我在每一行都有 vg 名称和磁盘,如下所示:

ok: [localhost] => {
    "msg": [
        "vg01  /dev/xvdk",
        "vg01 /dev/xvdj",
        "vg02  /dev/xvdi",
        "vg02  /dev/xvdh",
        "vg03  /dev/xvdg",
        "vg03  /dev/xvdf"
    ]
}

现在,我想要 vg 及其所有磁盘,在同一行,每个 vg 一个,如下所示:

"vg01 /dev/xvdk, /dev/xvdj",
"vg02 /dev/xvdi, /dev/xvdh",
"vg03 /dev/xvdg, /dev/xvdf",

仍然无法做到这一点;有人可以帮忙吗?
谢谢你。

标签: ansible

解决方案


创建字典列表。例如,假设数据存储在可变磁盘中

    - set_fact:
        l1: "{{ l1|default([]) + [{'dsk': item.split(' ')|first,
                                   'dev': item.split(' ')|last}] }}"
      loop: "{{ disks }}"

  l1:
  - dev: /dev/xvdk
    dsk: vg01
  - dev: /dev/xvdj
    dsk: vg01
  - dev: /dev/xvdi
    dsk: vg02
  - dev: /dev/xvdh
    dsk: vg02
  - dev: /dev/xvdg
    dsk: vg03
  - dev: /dev/xvdf
    dsk: vg03

使用groupby过滤器并格式化循环中的行,例如

    - debug:
        msg: "{{ item.0 }} {{ item.1|flatten|map(attribute='dev')|join(', ') }}"
      loop: "{{ l1|groupby('dsk') }}"

  msg: vg01 /dev/xvdk, /dev/xvdj
  msg: vg02 /dev/xvdi, /dev/xvdh
  msg: vg03 /dev/xvdg, /dev/xvdf

使用regex_replace/from_yaml的更强大的选项可能能够处理一些格式错误的数据,其中简单的split/first/last会失败,例如

    - set_fact:
        l1: "{{ l1|default([]) + [item.0|combine(item.1)] }}"
      with_together:
        - "{{ disks|map('regex_replace', '^(.*?) (.*)$', 'dsk: \\1')|
                    map('from_yaml')|list }}"
        - "{{ disks|map('regex_replace', '^(.*?) (.*)$', 'dev: \\2')|
                    map('from_yaml')|list }}"

推荐阅读