首页 > 解决方案 > 如何在ansible playbook中仅注册和捕获满足失败条件标准的输出?

问题描述

我正在尝试按如下方式设置一个剧本,当我的任务失败时我需要发送电子邮件通知。带有电子邮件通知的警报按预期工作,但是我无法仅针对失败的条件捕获输出,并且目前我注册的方式为我提供了所有结果,包括条件不存在的变量(本示例中的文件路径)失败。

---

- hosts: test-box

  tasks:
    - name: alert on failure
      block:
          - name: generate a list of desired file paths 
            find:
                    paths: /base/sdir
                    recurse: yes
                    file_type: file
                    patterns: "abrn.*.dat"
                    use_regex: yes
            register: file_paths

 
          - name: check if file stopped updating 
            vars:
                  msg: |
                          "{{ item }}"
                          "{{ ansible_date_time.epoch }}"
                          "{{ item.stat.mtime|int }}" 
                          "{{ ( (ansible_date_time.epoch|int - item.stat.mtime|int) / 60 ) | int }} min"
            with_items: "{{ ts.results }}"

            fail:
                  msg: | 
                          "{{ msg.split('\n') }}" 
            register: failed_items    ### -> HOW TO REGISTER ONLY THE FILE PATHS (RESULTS) WHERE THIS FAIL CONDITION IS MET?? 
            when: ( (ansible_date_time.epoch|int - item.stat.mtime|int) / 60 ) | int > 2 


      rescue:
          - name: email notification  
            mail:
              host: localhost
              port: 25
              from: A
              to: B
              subject: TASK FAILED
              body: |
                   Failed subdirs: {{ failed_items }}  ## This gives me all results including those where the failed condition is not met
            delegate_to: localhost

...

在电子邮件的正文中,我只想捕获满足 mtime 条件的文件路径,但目前我获得了所有文件路径。

关于如何过滤以仅捕获匹配条件的输出的任何建议?

谢谢。

标签: ansibleansible-2.x

解决方案


您应该使用set_fact,只有当您的when条件为真时,您才会分配一个列表变量。

---
- hosts: localhost
  become: false
  vars:
    path: "{{ '%s/bin' | format(lookup('env', 'HOME')) }}"
    time: "{{ 2 * 60 }}" # 2 mins
  tasks:
    - name: Find files in a defined path
      find:
        paths: "{{ path }}"
      register: _result
    - name: Add files not modified for longer time than defined to list
      set_fact:
        stale_files: "{{ stale_files | default([]) + [item.path] }}"
      loop: "{{ _result.files }}"
      when: ((ansible_date_time.epoch | float) - item.mtime) > (time | float)
    - name: Show stale files
      debug:
        msg: "{{ stale_files }}"

那么你也可以使用另一种方法,即。使用过滤进行循环(对我来说,selectattr过滤器不适用于lt测试,因此json_query过滤器应该可以工作,请参阅无法将属性与数字进行比较。错误:“在 'AnsibleUnsafeText' 和 'int' 的实例之间不受支持”)。


推荐阅读