首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >所有主机的不可附加dict结果

所有主机的不可附加dict结果
EN

Stack Overflow用户
提问于 2019-12-13 15:24:14
回答 1查看 2.2K关注 0票数 3

我正在尝试使用Ansible将一个命令发送给几个返回一个dict的主机。然后,我希望附加每个主机的dict结果,以累积所有主机的结果。最后,我希望打印累积结果的切分,以便以后处理或写入文件。由于结果显示为string,我似乎无法组合这些数据集。有办法补救吗?此外,是否有更有效的方法来实现这一点?

示例Playbook:

代码语言:javascript
复制
---
  - hosts: myhosts
    gather_facts: False
    vars:
      mydict: {}
    tasks:
    - name: Get dict result
      shell: "cat /path/dict_output"
      register: output
    - set_fact:
       result_dict="{{ output.stdout}}"

    - debug: var=result_dict

调试输出:

代码语言:javascript
复制
TASK [debug] ****************************************************************************************************************************************************************
ok: [host-a] => {
    "result_dict": {
        "host_b": [
            {
                "ip-1": {
                    "port": "22", 
                    "service": "ssh"
                }
            }, 
            {
                "ip-2": {
                    "port": "21", 
                    "service": "ftp"
                }
            }
        ]
    }
}
ok: [host-b] => {
    "result_dict": {
        "host_a": [
            {
                "ip-1": {
                    "port": "22", 
                    "service": "ssh"
                }
            }, 
            {
                "ip-2": {
                    "port": "21", 
                    "service": "ftp"
                }
            }
        ]
    }
}

我试图组合每个主机的结果:

代码语言:javascript
复制
- set_fact:
   mydict: "{{ mydict | combine(output.stdout) }}"
- debug: var=mydict

失败的结果:

代码语言:javascript
复制
TASK [set_fact] *************************************************************************************************************************************************************
    fatal: [host-b]: FAILED! => {"msg": "|combine expects dictionaries, got u\"{'host_b': [{'ip-1': {'service': 'ssh', 'port': '22'}}, {'ip-2': {'service': 'ftp', 'port': '21'}}]}\""}
    fatal: [host-a]: FAILED! => {"msg": "|combine expects dictionaries, got u\"{'host_a': [{'ip-1': {'service': 'ssh', 'port': '22'}}, {'ip-2': {'service': 'ftp', 'port': '21'}}]}\""}

期望的累积结果输出:

代码语言:javascript
复制
{'host_a': [{'ip-1': {'port': '22', 'service': 'ssh'}},
            {'ip-2': {'port': '21', 'service': 'ftp'}}],
 'host_b': [{'ip-1': {'port': '22', 'service': 'ssh'}},
            {'ip-2': {'port': '21', 'service': 'ftp'}}]}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-13 16:11:53

在收集了所有主机上的所有信息之后,可以在本地主机上运行的单个任务中创建hashmap。

您可以从hostvars hashmap中的任何主机浏览事实,并通过groups['name_of_group']访问组中所有机器的列表。

知道了这两个信息,基本的想法是:

  • 提取为您组中的机器提供所有主机,并确保从=> groups["myhosts"] | map("extract", hostvars) | list中获得一个列表
  • 筛选结果,只保留result_dict。我们可以使用过滤器再使用=> map(attribute="result_dict")来完成这个任务。我们已经非常接近您正在寻找的内容,它将是一个哈希映射列表(每个主机一个元素)。但你在找一个单一的hashmap所以..。
  • 循环这个结果,为每个主机创建一个带有条目的hashmap。

下面的游戏是在您的其他任务应该满足您的要求之后运行的:

代码语言:javascript
复制
- name: consolidate and display my result
  hosts: localhost

  tasks:
    - name: Consolidate result in a single hashmap
      set_fact:
        my_final_map: "{{ my_final_map | default({}) | combine(item) }}"
      loop: >-
        {{
          groups["myhosts"]
          | map("extract", hostvars)
          | map(attribute="result_dict")
          | list
        }}

    - name: Display consolidated result
      debug:
        var: my_final_map

注意:如果组中有一些主机没有运行任务(因为无法到达或由于其他原因),则可以使用result_dict排除具有未定义过滤器的主机。

代码语言:javascript
复制
      loop: >-
        {{
          groups["myhosts"]
          | map("extract", hostvars)
          | selectattr("result_dict", "defined") 
          | map(attribute="result_dict")
          | list
        }}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59325431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档