首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在带有某些条件的Ansible中向字典中添加字符串

如何在带有某些条件的Ansible中向字典中添加字符串
EN

Stack Overflow用户
提问于 2021-09-08 19:44:03
回答 1查看 167关注 0票数 0

我的剧本有问题,实际上我想在一些Windows主机上做一个ping测试,我想通过Slack发送结果。我已经做了所有的这一切,问题是,我想要发出的信息,只是什么是什么是好的,什么不是。

这就是ping的作用:

代码语言:javascript
运行
复制
---
- name: get powershell version
  ignore_unreachable: true
  raw: $PSVersionTable
- name: ping
  ignore_unreachable: true
  win_ping:
  register: ping_results

为了有一个远景,这是ping_results输出:

代码语言:javascript
运行
复制
ok: [frsv000003.local.cloud.com] => {
    "msg": {
        "changed": false, 
        "failed": false, 
        "ping": "pong"
    }
}
ok: [frsv000023.local.cloud.com] => {
    "msg": {
        "changed": false, 
        "failed": false, 
        "ping": "pong"
    }
}
ok: [besv000075.local.cloud.com] => {
    "msg": {
        "changed": false, 
        "msg": "psrp connection failure during runspace open: Received a broken RunspacePoolState message: Requested registry access is not allowed.", 
        "skip_reason": "Host besv000075.local.cloud.com is unreachable", 
        "unreachable": true
    }
}
ok: [frsv000007.local.cloud.com] => {
    "msg": {
        "changed": false, 
        "msg": "psrp connection failure during runspace open: Received a WSManFault message. (Code: 2150858811, Machine: 172.9.1.xxx, Reason: The WS-Management service cannot process the request. The resource URI (http://schemas.microsoft.com/powershell/Microsoft.PowerShell) was not found in the WS-Management catalog. The catalog contains the metadata that describes resources, or logical endpoints.)", 
        "skip_reason": "Host frsv000007.local.cloud.com is unreachable", 
        "unreachable": true
    }
}

现在,对于发送空闲的消息,我已经创建了一个条件,将可以和不确定的主机放在两个不同的列表中。

代码语言:javascript
运行
复制
- name: set fact
  set_fact:
    ok_list: []
- name: set fact2  
  set_fact:
    ok_list: "{{ ok_list + [item.value] }}"
  when: item.value is match('pong')
  with_dict: "{{ ping_results }}"
- name: set fact
  set_fact:
    nok_list: []
- name: set fact2  
  set_fact:
    nok_list: "{{ nok_list + [item.value] }}"
  when:
   - item.value is not match('pong')
  with_items: "{{ ping_results | dict2items }}"

我遇到的问题是:

代码语言:javascript
运行
复制
TASK [Hello-windows : Print variable ok] ***************************************
ok: [frsv000003.local.cloud.com] => {
    "msg": [
        "pong"
    ]
}
ok: [frsv000023.local.cloud.com] => {
    "msg": [
        "pong"
    ]
}
ok: [besv000075.local.cloud.com] => {
    "msg": []
}
ok: [frsv000007.local.cloud.com] => {
    "msg": []
}

我只需要获得主机名就可以在Slack中打印它,问题是如何从一个列表中获取这些主机,而不需要空值。谢谢。

编辑部分:@larsks,我会把这个作为一个答案,库存是基于ansible塔,包含了很多主机,比如第一个例子:

代码语言:javascript
运行
复制
  frsv000003.local.cloud.com
  frsv000004.local.cloud.com
  frsv000005.local.cloud.com
  frsv000006.local.cloud.com
  frsv000007.local.cloud.com
  frsv000008.local.cloud.com
  frsv000009.local.cloud.com
  frsv000010.local.cloud.com
 ...

对于剧本,我使用一个角色,因此该角色的主文件与您的相同

代码语言:javascript
运行
复制
- name: set ok_list
  set_fact:
    ok_list: "{{ ok_list + [item] }}"
  when: hostvars[item].ping_results.ping|default('') == "pong"
  loop: "{{ groups.all }}"

- name: set nok_list
  set_fact:
    nok_list: "{{ nok_list + [item] }}"
  when: hostvars[item].ping_results.ping|default('') != "pong"
  loop: "{{ groups.all }}"

- debug:
    msg:
      - "ok_list: {{ ok_list }}"
      - "nok_list: {{ nok_list }}"

此外,对于主文件(而不是角色),我有以下内容:

代码语言:javascript
运行
复制
- name: Test windows Connectivity
  hosts: all
  gather_facts: no
  vars:
    ping_results:
    slack_msg:
    ok_list: []
    nok_list: []
  roles:
    - Hello-windows

因此,当我使用带有5个主机的作业模板运行作业时,问题是我得到了这样一个列表,这意味着nok列表包含所有主机:

代码语言:javascript
运行
复制
TASK [Hello-windows : debug] ***************************************************
ok: [frsv000003.local.cloud.com] => {
    "msg": [
        "ok_list: [u'frsv000003.local.cloud.com', u'frsv000023.local.cloud.com']", 
        "nok_list: [u'frsv005207.local.cloud.com', u'frsv005336.local.cloud.com', u'uksv000232.local.cloud.com', u'frsv001871.local.cloud.com', u'frsv005090.local.cloud.com', u'frsv005333.local.cloud.com', u'frsv002043.local.cloud.com', u'frsv001811.local.cloud.com', u'frsv005150.local.cloud.com', u'frsv000928.local.cloud.com', u'frsv005529.local.cloud.com', u'frsv001606.local.cloud.com', u'frsv000236.local.cloud.com', u'frsv000929.local.cloud.com', u'frsv000363.local.cloud.com', u'frsv000539.local.cloud.com', u'frsv000653.local.cloud.com', u'frsv000508.local.cloud.com', u'frsv000654.local.cloud.com', u'frsv000205.local.cloud.com', u'frsv000632.local.cloud.com', u'frsv000516.local.cloud.com', u'frsv000427.local.cloud.com', u'frsv000137.local.cloud.com', u'frsv000466.local.cloud.com', u'frsv000324.local.cloud.com', u'frsv000974.local.cloud.com', u'frsv001451.local.cloud.com', u'frsv005432.local.cloud.com', u'besv005627.local.cloud.com',
    ]
}
ok: [frsv000023.local.cloud.com] => {
    "msg": [
        "ok_list: [u'frsv000003.local.cloud.com', u'frsv000023.local.cloud.com']", 
        "nok_list: [u'frsv005207.local.cloud.com', u'frsv005336.local.cloud.com', u'uksv000232.local.cloud.com', u'frsv001871.local.cloud.com', u'frsv005090.local.cloud.com', u'frsv005333.local.cloud.com', u'frsv002043.local.cloud.com', u'frsv001811.local.cloud.com', u'frsv005150.local.cloud.com', u'frsv000928.local.cloud.com', u'frsv005529.local.cloud.com', u'frsv001606.local.cloud.com', u'frsv000236.local.cloud.com', u'frsv000929.local.cloud.com', u'frsv000363.local.cloud.com', u'frsv000539.local.cloud.com', u'frsv000653.local.cloud.com', u'frsv000508.local.cloud.com', u'frsv000654.local.cloud.com', u'frsv000205.local.cloud.com', u'frsv000632.local.cloud.com', u'frsv000516.local.cloud.com', u'frsv000427.local.cloud.com', u'frsv000137.local.cloud.com', u'frsv000466.local.cloud.com', u'frsv000324.local.cloud.com', u'frsv000974.local.cloud.com', u'frsv001451.local.cloud.com', u'frsv005432.local.cloud.com', u'besv005627.local.cloud.com',
    ]
}
ok: [besv000075.local.cloud.com] => {
    "msg": [
        "ok_list: [u'frsv000003.local.cloud.com', u'frsv000023.local.cloud.com']", 
        "nok_list: [u'frsv005207.local.cloud.com', u'frsv005336.local.cloud.com', u'uksv000232.local.cloud.com', u'frsv001871.local.cloud.com', u'frsv005090.local.cloud.com', u'frsv005333.local.cloud.com', u'frsv002043.local.cloud.com', u'frsv001811.local.cloud.com', u'frsv005150.local.cloud.com', u'frsv000928.local.cloud.com', u'frsv005529.local.cloud.com', u'frsv001606.local.cloud.com', u'frsv000236.local.cloud.com', u'frsv000929.local.cloud.com', u'frsv000363.local.cloud.com', u'frsv000539.local.cloud.com', u'frsv000653.local.cloud.com', u'frsv000508.local.cloud.com', u'frsv000654.local.cloud.com', u'frsv000205.local.cloud.com', u'frsv000632.local.cloud.com', u'frsv000516.local.cloud.com', u'frsv000427.local.cloud.com', u'frsv000137.local.cloud.com', u'frsv000466.local.cloud.com', u'frsv000324.local.cloud.com', u'frsv000974.local.cloud.com', u'frsv001451.local.cloud.com', u'frsv005432.local.cloud.com', u'besv005627.local.cloud.com',
    ]
}
ok: [frsv000007.local.cloud.com] => {
    "msg": [
        "ok_list: [u'frsv000003.local.cloud.com', u'frsv000023.local.cloud.com']", 
        "nok_list: [u'frsv005207.local.cloud.com', u'frsv005336.local.cloud.com', u'uksv000232.local.cloud.com', u'frsv001871.local.cloud.com', u'frsv005090.local.cloud.com', u'frsv005333.local.cloud.com', u'frsv002043.local.cloud.com', u'frsv001811.local.cloud.com', u'frsv005150.local.cloud.com', u'frsv000928.local.cloud.com', u'frsv005529.local.cloud.com', u'frsv001606.local.cloud.com', u'frsv000236.local.cloud.com', u'frsv000929.local.cloud.com', u'frsv000363.local.cloud.com', u'frsv000539.local.cloud.com', u'frsv000653.local.cloud.com', u'frsv000508.local.cloud.com', u'frsv000654.local.cloud.com', u'frsv000205.local.cloud.com', u'frsv000632.local.cloud.com', u'frsv000516.local.cloud.com', u'frsv000427.local.cloud.com', u'frsv000137.local.cloud.com', u'frsv000466.local.cloud.com', u'frsv000324.local.cloud.com', u'frsv000974.local.cloud.com', u'frsv001451.local.cloud.com', u'frsv005432.local.cloud.com', u'besv005627.local.cloud.com',
    ]
}

PLAY RECAP *********************************************************************
besv000075.local.cloud.com : ok=3    changed=0    unreachable=1    failed=0    skipped=1    rescued=0    ignored=0   
frsv000003.local.cloud.com : ok=10   changed=1    unreachable=0    failed=0    skipped=10   rescued=0    ignored=0   
frsv000007.local.cloud.com : ok=3    changed=0    unreachable=1    failed=0    skipped=1    rescued=0    ignored=0   
frsv000023.local.cloud.com : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-08 21:06:00

您的问题是,ping_results不是结果列表;它是单个主机的单个结果。当你跑步时:

代码语言:javascript
运行
复制
- name: ping
  ignore_unreachable: true
  win_ping:
  register: ping_results

这在每个主机上运行一次,并为该主机注册一个名为ping_results的变量。您可以在调试输出中看到这一点。

要获得两个列表,一个是可访问的主机,另一个是不可访问的主机,您需要在单个主机(例如localhost)上运行一个play,并在所有目标主机上循环查找ping_results变量。例如:

代码语言:javascript
运行
复制
- hosts: localhost
  gather_facts: false
  tasks:
    - name: set ok_list
      set_fact:
        ok_list: "{{ ok_list + [item] }}"
      when: hostvars[item].ping_results.ping|default('') == "pong"
      vars:
        ok_list: []
      loop: "{{ groups.all }}"

    - name: set nok_list
      set_fact:
        nok_list: "{{ nok_list + [item] }}"
      when: hostvars[item].ping_results.ping|default('') != "pong"
      vars:
        nok_list: []
      loop: "{{ groups.all }}"

    - debug:
        msg:
          - "ok_list: {{ ok_list }}"
          - "nok_list: {{ nok_list }}"

使用示例数据运行此操作将产生以下结果:

代码语言:javascript
运行
复制
PLAY [localhost] ***************************************************************

TASK [set ok_list] *************************************************************
ok: [localhost] => (item=frsv000003.local.cloud.com)
ok: [localhost] => (item=frsv000023.local.cloud.com)
skipping: [localhost] => (item=besv000075.local.cloud.com) 
skipping: [localhost] => (item=frsv000007.local.cloud.com) 

TASK [set nok_list] ************************************************************
skipping: [localhost] => (item=frsv000003.local.cloud.com) 
skipping: [localhost] => (item=frsv000023.local.cloud.com) 
ok: [localhost] => (item=besv000075.local.cloud.com)
ok: [localhost] => (item=frsv000007.local.cloud.com)

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": [
        "ok_list: ['frsv000003.local.cloud.com', 'frsv000023.local.cloud.com']",
        "nok_list: ['besv000075.local.cloud.com', 'frsv000007.local.cloud.com']"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

我想这就是你要找的。

注意:我在hosts.yml中使用这个库存文件测试了上面的剧本

代码语言:javascript
运行
复制
all:
  hosts:
    frsv000003.local.cloud.com:
      ansible_host: localhost
      ping_results:
        changed: false
        failed: false
        ping: pong
    frsv000023.local.cloud.com:
      ansible_host: localhost
      ping_results:
        changed: false
        failed: false
        ping: pong
    besv000075.local.cloud.com:
      ansible_host: localhost
      ping_results:
        changed: false
        msg: "psrp connection failure during runspace open: Received a broken RunspacePoolState message: Requested registry access is not allowed."
        skip_reason: "Host besv000075.local.cloud.com is unreachable"
        unreachable: true
    frsv000007.local.cloud.com:
      ansible_host: localhost
      ping_results:
        changed: false
        msg: "psrp connection failure during runspace open: Received a WSManFault message. (Code: 2150858811, Machine: 172.9.1.xxx, Reason: The WS-Management service cannot process the request. The resource URI (http://schemas.microsoft.com/powershell/Microsoft.PowerShell) was not found in the WS-Management catalog. The catalog contains the metadata that describes resources, or logical endpoints.)"
        skip_reason: "Host frsv000007.local.cloud.com is unreachable"
        unreachable: true

像这样运行:

代码语言:javascript
运行
复制
ansible-playbook -i hosts.yml playbook.yml
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69108843

复制
相关文章

相似问题

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