遍历ansible字典以获得特定值

时间:2019-08-14 18:41:25

标签: loops dictionary ansible

使用ansible,循环访问返回带有列出值的dict(?)的项目列表。

基本上,我想检查软件包的字典,以查看是否已安装(以及稍后返回任何丢失的软件包的消息)。

到目前为止尝试的任何loop / with_dict组合都返回各种错误,无法找到特定的变量。

查询状态本身(yum模块)时,确实会将每个包的完整输出放入{{pkg}} var中。

---
- name: Ansible tests playbook
  hosts: vms
  remote_user: root
  vars:
    pkgs:
      - yum-utils
      - mariadb-libs
  tasks:
    - name: Check packages
      yum:
        list: "{{ item }}"
        disablerepo: '*'
      register: pkg
      loop: "{{ pkgs }}"

如果我然后简单地使用以下命令输出{{pkg.results}}的内容:

    - name: list
      debug:
        msg: "{{ item }}"
      loop: "{{ pkg.results }}"

我明白了:

root@vm011:~/ovirt# ansible-playbook check.yml

PLAY [Ansible tests playbook] **************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************
ok: [vm017.warp]

TASK [Check paclages] **********************************************************************************************************************************************************************
ok: [vm017.warp] => (item=yum-utils)
ok: [vm017.warp] => (item=mariadb-libs)

TASK [list] ********************************************************************************************************************************************************************************
ok: [vm017.warp] => (item=None) =>
  msg:
    changed: false
    failed: false
    invocation:
      module_args:
        allow_downgrade: false
        conf_file: null
        disable_gpg_check: false
        disable_plugin: []
        disablerepo: '*'
        enable_plugin: []
        enablerepo: null
        exclude: null
        install_repoquery: true
        installroot: /
        list: yum-utils
        name: null
        security: false
        skip_broken: false
        state: installed
        update_cache: false
        update_only: false
        validate_certs: true
    item: yum-utils
    results:
    - arch: noarch
      envra: 0:yum-utils-1.1.31-50.el7.noarch
      epoch: '0'
      name: yum-utils
      release: 50.el7
      repo: installed
      version: 1.1.31
      yumstate: installed
ok: [vm017.warp] => (item=None) =>
  msg:
    changed: false
    failed: false
    invocation:
      module_args:
        allow_downgrade: false
        conf_file: null
        disable_gpg_check: false
        disable_plugin: []
        disablerepo: '*'
        enable_plugin: []
        enablerepo: null
        exclude: null
        install_repoquery: true
        installroot: /
        list: mariadb-libs
        name: null
        security: false
        skip_broken: false
        state: installed
        update_cache: false
        update_only: false
        validate_certs: true
    item: mariadb-libs
    results:
    - arch: x86_64
      envra: 1:mariadb-libs-5.5.60-1.el7_5.x86_64
      epoch: '1'
      name: mariadb-libs
      release: 1.el7_5
      repo: installed
      version: 5.5.60
      yumstate: installed

如何才能将每个软件包的yumstate值(已安装或以其他方式安装)放入单独的变量中?

例如,如果我尝试使用以下命令调试味精

    - name: list
      debug:
        msg: "{{ item.yumstate }}"
      loop: "{{ pkg.results }}"

我得到:

fatal: [vm017.warp]: FAILED! =>
  msg: |-
    The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'yumstate'

3 个答案:

答案 0 :(得分:1)

您在pkg.results中正确循环,但是在每个项目中,yumstate在另一个results键下面。您应该使用:

- name: list
  debug:
    msg: "{{ item.results.yumstate }}"
  loop: "{{ pkg.results }}"

我在我的fedora上尝试了您的代码,并且两个软件包之一的results具有一个列表值,因此item.results.yumstate不起作用:yum utils的Fedora响应:

"item.results": [
    {
        "arch": "noarch",
        "epoch": "0",
        "name": "yum-utils",
        "nevra": "0:yum-utils-1.1.31-517.fc29.noarch",
        "release": "517.fc29",
        "repo": "fedora",
        "version": "1.1.31",
        "yumstate": "available"
    },
    {
        "arch": "noarch",
        "epoch": "0",
        "name": "yum-utils",
        "nevra": "0:yum-utils-1.1.31-518.fc29.noarch",
        "release": "518.fc29",
        "repo": "updates",
        "version": "1.1.31",
        "yumstate": "available"
    }
]

对于mariadb-libs,未找到任何包,响应为:

"item.results": []

希望有帮助

答案 1 :(得分:0)

您确实以正确的方式指出了我。

- name: list 
debug: 
  msg: "Package {{ item.results[0].name }} is {{ item.results[0].yumstate }}"
loop: "{{ pkg.results }}"

做到了这一点,仅使用“ {{item.results.yumstate}}”,它仍然返回错误

TASK [list] ********************************************************************************************************************************************************************************
fatal: [vm017.warp]: FAILED! =>
  msg: |-
    The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'yumstate'

添加[0]得到了我

TASK [list] ********************************************************************************************************************************************************************************
ok: [vm017.warp] => (item=None) =>
  msg: Package yum-utils is installed
ok: [vm017.warp] => (item=None) =>
  msg: Package mariadb-libs is installed

答案 2 :(得分:0)

如果您想尝试精美的事物,则可能要考虑嵌套循环,也称为“循环并包含”。

https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#defining-inner-and-outer-variable-names-with-loop-var