为什么此ansible的条件检查一直失败?

时间:2018-08-28 07:52:35

标签: ansible

为什么条件检查在这里失败了?

  tasks:
  - name:
    command: dig @{{ item }} -t NS google.com
    with_items:
      - 4.5.6.7  # some server that fails
    register: dig_output

  - meta: end_play
    when: (dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))

我得到的错误是:

  

错误!条件检查'(dig_output | d('')=='')或   ((dig_output | d('')!='')和('NOERROR'不在   dig_output.results.0.stdout))失败。错误是:错误而   评估条件((dig_output | d('')=='')或((dig_output | d('')   !='')和('NOERROR'不在dig_output.results.0.stdout))):无法   在模板字符串中查找名称或访问属性({%,如果   (dig_output | d('')=='')或((dig_output | d('')!='')和('NOERROR'   不在dig_output.results.0.stdout中))%}正确{%else%}错误{%endif   %})。确保您的变量名称不包含无效字符   像“-”一样:“ StrictUndefined”类型的参数不可迭代

如果我只有以下内容,则可以通过以帮助进行故障排除

  when: (dig_output|d('') == '') or ('NOERROR' not in dig_output.results.0.stdout)

想知道我的初始条件出了什么问题,因为整体的各个部分似乎都起作用了。

1 个答案:

答案 0 :(得分:1)

您的代码按Ansible 2.2.1.0中的预期工作。这是MCVE

- hosts: localhost
  connection: local
  gather_facts: no

  tasks:

    - command: 'dig @{{item}} -t NS google.com +time=1'
      ignore_errors: yes
      with_items:
        - 4.5.6.7  # some server that fails
      register: dig_output

    - debug: var=dig_output.results.0.stdout

    - meta: end_play
      when: (dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))

    - debug: var=dig_output.results.0.stdout

输出为:

PLAY [localhost] ***************************************************************

TASK [command] *****************************************************************
...ignoring
failed: [localhost] (item=4.5.6.7) => {"changed": true, "cmd": ["dig", "@4.5.6.7", "-t", "NS", "google.com", "+time=1"], "delta": "0:00:03.015272", "end": "2018-08-28 13:20:25.364956", "failed": true, "item": "4.5.6.7", "rc": 9, "start": "2018-08-28 13:20:22.349684", "stderr": "", "stdout": "\n; <<>> DiG 9.10.3-P4-Debian <<>> @4.5.6.7 -t NS google.com +time=1\n; (1 server found)\n;; global options: +cmd\n;; connection timed out; no servers could be reached", "stdout_lines": ["", "; <<>> DiG 9.10.3-P4-Debian <<>> @4.5.6.7 -t NS google.com +time=1", "; (1 server found)", ";; global options: +cmd", ";; connection timed out; no servers could be reached"], "warnings": []}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "dig_output.results.0.stdout": "\n; <<>> DiG 9.10.3-P4-Debian <<>> @4.5.6.7 -t NS google.com +time=1\n; (1 server found)\n;; global options: +cmd\n;; connection timed out; no servers could be reached"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

存在变量dig_output.results.0.stdout,并且when任务的meta表达式的值为true。播放结束,第二个debug任务被省略。

只要dig失败,它就会起作用。如果dig本身执行失败(未安装),则说明您已引用该错误。

- hosts: localhost
  connection: local
  gather_facts: no

  tasks:

    - command: 'gid @{{item}} -t NS google.com +time=1'
      ignore_errors: yes
      with_items:
        - 4.5.6.7  # some server that fails
      register: dig_output

    - debug: var=dig_output

    - meta: end_play
      when: (dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))

    - debug: var=dig_output.results.0.stdout

输出:

PLAY [localhost] ***************************************************************

TASK [command] *****************************************************************
...ignoring
failed: [localhost] (item=4.5.6.7) => {"cmd": "gid '' -t NS google.com +time=1", "failed": true, "item": "4.5.6.7", "msg": "[Errno 2] Datei oder Verzeichnis nicht gefunden", "rc": 2}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "dig_output": {
        "changed": false, 
        "failed": true, 
        "msg": "One or more items failed", 
        "results": [
            {
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "cmd": "gid '' -t NS google.com +time=1", 
                "failed": true, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "gid @4.5.6.7 -t NS google.com +time=1", 
                        "_uses_shell": false, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "warn": true
                    }, 
                    "module_name": "command"
                }, 
                "item": "4.5.6.7", 
                "msg": "[Errno 2] Datei oder Verzeichnis nicht gefunden", 
                "rc": 2
            }
        ]
    }
}
ERROR! The conditional check '(dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))' failed. The error was: error while evaluating conditional ((dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))): Unable to look up a name or access an attribute in template string ({% if (dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout)) %} True {% else %} False {% endif %}).
Make sure your variable name does not contain invalid characters like '-': argument of type 'StrictUndefined' is not iterable

The error appears to have been in '/home/szi/tmp/register.yml': line 15, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


    - meta: end_play
      ^ here

这意味着,在深入研究dig_output.results.0之前,应检查dig_output.results.failed

when: dig_output.failed or (dig_output|d('') == '') or ((dig_output|d('') != '') and ('NOERROR' not in dig_output.results.0.stdout))