【问题标题】:Ansible - Getting List Values from within a Dictionary (Regsiter Variable)Ansible - 从字典中获取列表值(Regsiter 变量)
【发布时间】:2020-10-31 03:26:43
【问题描述】:

因此,我正在为我们支持的许多服务器使用 Ansible 来处理一些审计点。在大多数情况下,我不得不使用 shell 模块来获取我想要的数据,然后根据通过/失败情况编写一些文件。在很多情况下,这是处理输出数据的更简单方法。首先,我意识到这不一定是 Ansible 的强项。我想在某些时候它被公司推销为它可以很容易地做到这一点,我同意 - 在很多方面它比编写自定义 python/BASH 脚本来做同样的事情更容易。所以 - 我确实意识到我在这里稍微改变了 Ansible 的概念来进行报告,而不是配置/状态管理。然而;我喜欢这个工具,并希望向公司展示我们可以从中获得很多价值。

虽然我可以使用 shell 模块轻松完成这一部分,但我想更好地学习 Ansible。所以想我会发布这个问题。

我正在使用 Yum 模块来获取目标主机上的 repolist。但是我一直对如何提取嵌套在输出字典中的列表值感到困惑。我已经对类型进行了一些检查,据我所知 - 'results' 变量是一个字典,输出在一个列表中。我想要做的是从列表中获取键/值,然后根据该输出执行一些其他任务。但是对于我的生活 - 我无法弄清楚如何做到这一点!

理想情况下 - 我想根据输出使用一些“何时”模块语句(例如,当 repo ID 是..这样做..)或者至少能够将它们存储在一个变量中以使用数据。因此,从这个输出中,我只想获取 reoid 以及它是否已启用。如何从嵌套列表中获取这些值?

简单的剧本:

---
- hosts: localhost
  become: yes
  tasks:

  - name: Section 1.1 - Check Yum Repos
    yum:
      list: repos
    register: section1_1

  - name: Debug
    debug:
      var: section1_1

这是我在本剧本中调试任务的输出:

TASK [Debug] ****************************************************************************************************************************************************
ok: [localhost] => {
    "section1_1": {
        "changed": false,
        "failed": false,
        "results": [
            {
                "repoid": "ansible",
                "state": "enabled"
            },
            {
                "repoid": "epel",
                "state": "enabled"
            },
            {
                "repoid": "ol7_UEKR6",
                "state": "enabled"
            },
            {
                "repoid": "ol7_latest",
                "state": "enabled"
            }
        ]
    }
}

我怀疑这对外面的人来说可能很容易。我一直在尝试这个,这已经有一段时间了,终于到了我想我会问的地步:)

【问题讨论】:

    标签: ansible


    【解决方案1】:

    section1_1 中注册的输出是字典列表。我们可以遍历每个项目,以获取字典键。

    例子:

    - name: Get the first repo's repoid and state
      debug:
        msg: "Repo ID: {{ results[0]['repoid'] }}, is {{ results[0]['state'] }}"
    # This will show -- Repo ID: ansible, is enabled
    

    类似地,我们可以通过编号访问其他元素。

    或者我们可以遍历数组的每个元素:

    - name: loop through array and conditionally do something
      debug:
        msg: "Repo ID is {{ item.repoid }}, so I am going to write a playbook."
      when: item.repoid == 'ansible'
      loop: "{{ results }}"
    

    【讨论】:

    • 太棒了,我想这正是我所需要的。我确实发现我可以使用 [index] 访问这些项目 - 现在我可以看到如何在循环中处理它。我确实必须使用寄存器中的“variable.results”才能使其正常工作(section1_1.results)。但这成功了!循环:“{{ section1_1.results }}”我想我现在明白了 - 谢谢! :)
    【解决方案2】:

    问:从列表中获取键/值。

    答:还有更多选择。鉴于下面的简化数据

        section1_1:
          changed: false,
          failed: false,
          results:
            - {repoid: ansible, state: enabled}
            - {repoid: epel, state: enabled}
            - {repoid: test9, state: disabled}
    
    • 使用 map 创建所有存储库的列表。例如
        - set_fact:
            keys_all: "{{ section1_1.results|
                          map(attribute='repoid')|
                          list }}"
        - debug:
            var: keys_all
    

    给予

      keys_all:
      - ansible
      - epel
      - test9
    

    • 使用 mapselectattr 创建已启用的存储库列表。例如
        - set_fact:
            keys_ena: "{{ section1_1.results|
                          selectattr('state', 'eq', 'enabled')|
                          map(attribute='repoid')|
                          list }}"
        - debug:
            var: keys_ena
    

    给予

      keys_ena:
      - ansible
      - epel
    

    使用 items2dict 创建字典。例如

        - set_fact:
            dict: "{{ section1_1.results|
                      items2dict(key_name='repoid', value_name='state') }}"
        - debug:
            var: dict
    

    给予

      dict:
        ansible: enabled
        epel: enabled
        test9: disabled
    

    【讨论】:

    • 我很喜欢有更多的做事方式。现在你给了我几个小时的逻辑。谢谢弗拉达米尔。不用说,我在其他相关主题上遇到了一些你的 cmets(顺便说一句总是有帮助的)。我发现在 Ansible 中,我经常需要改变构建逻辑的方式,而不是 Python,例如。这将是一个巨大的帮助!
    猜你喜欢
    • 2016-08-05
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多