当ansible查找失败时,如何回退到默认值?

当ansible查找失败时,如何回退到默认值?,ansible,jinja2,Ansible,Jinja2,我有点惊讶地发现,他的代码出现了IOError异常,而不是默认忽略值 #!/usr/bin/env ansible-playbook -i localhost, --- - hosts: localhost tasks: - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') | default(omit) }}" 如何加载值而不引发异常 请注意,lookup模块支持一个默认值参数,但

我有点惊讶地发现,他的代码出现了IOError异常,而不是默认忽略值

#!/usr/bin/env ansible-playbook -i localhost,
---
- hosts: localhost
  tasks:
    - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') | default(omit) }}"
如何加载值而不引发异常

请注意,lookup模块支持一个默认值参数,但是这个参数对我来说是无用的,因为它只有在可以打开文件时才能工作


我需要一个默认值,即使在打开文件失败时也可以使用。

据我所知,Jinja2不幸不支持任何try/catch机制

因此,您要么将ini查找插件/文件问题修补到Ansible团队,要么使用以下难看的解决方法:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - debug: msg="{{ lookup('first_found', dict(files=['test-ini.conf'], skip=true)) | ternary(lookup('ini', 'foo section=DEFAULT file=test-ini.conf'), omit) }}"

在本例中,
first\u found
lookup返回文件名(如果文件存在),否则返回空列表。如果文件存在,
三元
过滤器调用
ini
查找,否则将返回
忽略
占位符。

为避免路径不存在时出现错误,请在尝试查找之前使用条件检查路径:

---

- hosts: localhost
  tasks:

    - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
      when: missing-file.conf | exists
您也可以将其与
set\u fact
一起使用,然后在需要时使用它时省略未定义的变量:

- hosts: localhost
  tasks:

    - set_fact:
        foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
      when: missing-file.conf | exists

    - debug:
        var: foo  # undefined
        msg: "{{ foo | default(omit) }}"  # omitted
请注意,在控制器上运行查找和设置。如果需要检查主机上的路径,请使用
stat
slurp
fetch
模块:

- stat:
    file: missing-remote-file-with-text-i-want
  register: file

- slurp:
    src: missing-remote-file-with-text-i-want
  register: slurp
  when: file.stat.exists

- set_fact:
    foo: "{{ slurp.content | b64decode }}"
  when: file.stat.exists

- fetch:
    src: missing-file.conf
    dest: /tmp/fetched
    fail_on_missing: False

- set_fact:
    bar: "{{ lookup('ini', 'foo section=DEFAULT file=/tmp/fetched/' + inventory_hostname + '/missing-file.conf') }}"
  when: ('/tmp/fetched/' + inventory_hostname + '/missing-file.conf') | exists
第二个注意事项,在Ansible
v2.5
中,使用路径测试的语法已更改,格式现在为:

- set_fact:
    foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
  when: missing-file.conf is exists

在使用默认过滤器之前,您还可以使用
from_yaml
过滤器转换输入文件

- name: "load a yaml file or a default value"
  set_fact:
    myvar: "{{ lookup('file', 'myfile.yml', errors='ignore') | from_yaml | default(mydefaultObject, true) }}"

丑陋是一种轻描淡写的说法,也许丑陋更合适从好的方面看,它似乎正在发挥作用。尽管如此,我还是会避免使用它,因为它会使代码很难为他人阅读或审阅。谢谢