从字典格式的事实中获取名称和版本

Get name and version from a dictionary formatted facts

以下ansible任务以字典格式显示pip包。

- name: Ganther pip packages
  pip_package_info:
    clients: pip3
  register: pip_pkgs

输出为:

{
  "packages": {
    pip3: {
      "xxx": [
        {
          name: "xxx"
          source: "pip3"
          version: "1.0.0"
        }
      ],
      "yyy": [
        {
          name: "yyy"
          source: "pip3"
          version: "2.0.0"
        }
      ]
    }
  }
}

我试图遍历已注册的变量,但是,我收到有关未定义变量的错误。如何从上面的字典中获取名称和版本?

您可以使用 Python 词典的 values 方法来获得可以循环的内容:

- debug:
    msg: "{{ item.name }} is in version {{ item.version }}"
  loop: "{{ pip_pkgs.packages.pip3.values() | flatten }}"

或者,它也可以用 dict2items 来实现,但是会使循环语法稍微长一点,因为你必须 map 你感兴趣的属性——这里是值:

- debug:
    msg: "{{ item.name }} is in version {{ item.version }}"
  loop: >-
    {{
      pip_pkgs.packages.pip3
      | dict2items
      | map(attribute='value')
      | flatten
    }}

如果你想创建一个字典,这将是最简单的:

- set_fact:
    pip_packages: >-
      {{
        dict(
          _pip_pkg | map(attribute='name')
          | zip(_pip_pkg | map(attribute='version'))
        )
      }}
  vars:
    _pip_pkg: "{{ pip_pkgs.packages.pip3.values() | flatten }}"

字典看起来像

pip_packages:
  ansible: 5.6.0
  ansible-compat: 2.0.2
  ansible-core: 2.12.4
  ansible-lint: 6.0.2

给定两个任务:

- pip_package_info:
    clients: pip3
  register: pip_pkgs

- debug:
    msg: "{{ item.name }} is in version {{ item.version }}"
  loop: "{{ pip_pkgs.packages.pip3.values() | flatten }}"
  loop_control:
    label: "{{ item.name }}"

这给出:

ok: [localhost] => (item=ansible) => 
  msg: ansible is in version 5.6.0
ok: [localhost] => (item=ansible-compat) => 
  msg: ansible-compat is in version 2.0.2
ok: [localhost] => (item=ansible-core) => 
  msg: ansible-core is in version 2.12.5
ok: [localhost] => (item=ansible-lint) => 
  msg: ansible-lint is in version 6.0.2

... list goes on