Ansible package_facts:通过与另一个简单列表进行比较来设置事实

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

由于ansible-cmdb,我目前正在为每个库存主机生成报告。这个工具很棒,但我有一个问题需要修改一些事实:

我使用package_facts模块来注册已安装的软件包。它们会自动在hostvars中注册为这样的dicts列表(ansible_facts.packages):

"packages": {
    "accountsservice": [
        {
            "arch": "amd64",
            "name": "accountsservice",
            "source": "apt",
            "version": "0.6.40-2ubuntu11.3"
        }
    ],
    "acl": [
        {
            "arch": "amd64",
            "name": "acl",
            "source": "apt",
            "version": "2.2.52-3"
        }
    ],
    "acpid": [
        {
            "arch": "amd64",
            "name": "acpid",
            "source": "apt",
            "version": "1:2.0.26-1ubuntu2"
        }
    ]}

另一方面,我有一个远程bash脚本,它输出手动安装在主机上的简单包名列表。对于每个主机,我想比较两个列表,如果包名也在ansible_facts.packages中,那么在包中添加一个键为所需的包“manual”:true。否则,如果可能,添加“manual”:false。因此,经过比较,事实应该像这样设置:

"packages": {
    "accountsservice": [
        {
            "arch": "amd64",
            "name": "accountsservice",
            "source": "apt",
            "version": "0.6.40-2ubuntu11.3",
            "manual": true
        }
    ],
    "acl": [
        {
            "arch": "amd64",
            "name": "acl",
            "source": "apt",
            "version": "2.2.52-3",
            "manual": false
        }
    ],
...}

你认为这是可能的吗?我是一个关于使用Ansible处理JSON数据结构的新手,这就是为什么我会用Python脚本做一个解决方法的原因,因为我工作了几天以正确的方式(没有成功)。

如果我知道如何正确地做这件事,那将是一个很大的帮助/步骤。提前致谢 !

ansible ansible-facts
1个回答
0
投票

是的,Jinja是一种非常强大的模板语言,你可以使用set_facts模块声明新的事实,导致类似这样的事情:

  vars:
    the_list: |
      [
       {"name": "alpha"},
       {"name": "beta"}
      ]
    the_names: |
      ["alpha", "charlie"]
  tasks:
  - set_fact:
     new_list: |
      [
      {% set names_list = (the_names|from_json) %}
      {% for item in (the_list|from_json) %}
      {{ '' if loop.first else ',' }}
      {% set _ = item.update({"manual": item.name in names_list}) %}
      {{ item | to_json }}
      {% endfor %}
      ]
  - debug: var=item.manual verbosity=0
    with_items: '{{ new_list }}'

set _ =部分是因为jinja只有set声明引起副作用,其余只是从文本强制到实际的dict,然后with_items以与--extra-vars相同的方式强制文本重新变成丰富的对象和朋友们这样做:如果它看起来像json-y,他们会这样对待它。我们必须手动执行from_json,因为强制行为是一种安全行为,而不是一种恶行为。

© www.soinside.com 2019 - 2024. All rights reserved.