【问题标题】:How to fallback to a default value when ansible lookup fails?当ansible查找失败时如何回退到默认值?
【发布时间】:2017-04-04 15:58:27
【问题描述】:

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

#!/usr/bin/env ansible-playbook -i localhost,
---
- hosts: localhost
  tasks:
    - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') | default(omit) }}"

如何在不引发异常的情况下加载值?

请注意,查找模块支持默认值参数,但这个对我来说没用,因为它只有在可以打开文件时才有效。

我需要一个默认值,即使它无法打开文件。

【问题讨论】:

    标签: ansible jinja2


    【解决方案1】:

    据我所知 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_found 如果文件存在则查找返回文件名,否则返回空列表。如果文件存在,则ternary过滤器调用ini查找,否则返回omit占位符。

    【讨论】:

    • 丑陋是轻描淡写,也许丑陋更合适! ;) 从好的方面来说,它似乎正在发挥作用。尽管如此,我还是会避免使用它,因为它使其他人很难阅读或审查代码。谢谢!
    【解决方案2】:

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

    ---
    
    - hosts: localhost
      tasks:
    
        - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
          when: missing-file.conf | exists
    

    您也可以将其与set_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
    

    请注意,查找和Jinja2 tests控制器 上运行。如果您需要检查主机上的路径,请使用statslurpfetch 模块:

    - 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
    

    【讨论】:

      【解决方案3】:

      您还可以在使用默认过滤器之前使用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) }}"
      

      【讨论】:

        【解决方案4】:

        您可以按如下方式使用阻止/救援:

        - hosts: localhost
          tasks:
            - block:
                - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
              rescue:
                - debug: msg="omit"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-08
          • 1970-01-01
          • 2018-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多