【问题标题】:Ansible testing variable typeAnsible 测试变量类型
【发布时间】:2016-01-21 16:28:52
【问题描述】:

我正在使用一个现有角色,我希望对其进行修改以扩展其功能。目前,它的任务之一是创建目录。这些目录作为包含字符串列表的变量传递给角色,然后在with_items 语句中迭代。但是,我更愿意传递表格的字典列表,例如{name: foo, mode: 751}.

到目前为止一切顺利;我可以简单地编辑角色以使其接受这种输入。但是,我也想让它向后兼容旧格式,即项目是字符串的地方。

有没有办法测试变量的类型,然后基于此返回不同的值(或执行不同的任务)?也许使用 Jinja2 过滤器?我简要地查看了手册中列出的conditionals,但没有任何东西引起我的注意,可以在这种情况下使用。

【问题讨论】:

    标签: jinja2 ansible


    【解决方案1】:

    您可以使用default() 来实现向后兼容性。

    - file:
        path: "{{ item.name | default(item) }}"
        mode: "{{ item.mode | default(omit) }}"
        state: directory
      with_items: your_list
    

    如果item 具有name 属性,请使用它,否则只需使用项目本身。

    您的字典中可能拥有的所有其他属性也是如此。特殊变量omit 会从任务中省略整个选项,就好像没有模式被传递给file 模块一样。当然,您可以设置任何其他默认值。

    文档参考:

    【讨论】:

    • 嗯,我确定我已经尝试过了。谢谢,这是一个不错且干净的解决方案!尽管它比我的问题允许的更通用(因为我错误地寻找类型检查解决方案),但它完全符合要求。
    • 我知道,它实际上并没有回答你的问题。 Afaik 没有简单的方法来测试类型。 Jinja2 有一个测试过滤器| string,但我从来没有让它工作。 | iterable 过滤器有效 - 不幸的是,字符串也是可迭代的......可以为此创建自定义过滤器插件,但我认为如果可以简单地使用 default,那将是一个开销。至少在这种情况下。
    • 是的,包括一个自定义过滤器,用于处理简单的单行差异会造成不必要的混乱。
    【解决方案2】:

    最快的解决方案是有两个任务,并让它们在相反的条件下触发。不幸的是,列表中的所有项目都必须使用相同的形式(您不能混合和匹配字符串和字典)。

    - name: create dirs (strings)
      file:
        ...
      with_items: items
      when: string(items[0])
    
    - name: create dirs (dicts)
      file:
        ...
      with_items: items
      when: not string(items[0])
    

    【讨论】:

    • 它告诉我ERROR! 'string' is undefined。你能给我一个指向该函数文档的链接吗?
    • @Joost 我使用的是 jinja2 文档,而不是 ansible 文档。无论如何,乌冬丹的答案要好得多。
    猜你喜欢
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2020-07-09
    • 2018-04-21
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2020-05-21
    相关资源
    最近更新 更多