【问题标题】:Ansible: How to fix to_nice_yaml output quotation and line-breaks?Ansible:如何修复 to_nice_yaml 输出引号和换行符?
【发布时间】:2021-03-16 07:05:52
【问题描述】:

我有这个 YAML 文件(我将我的问题提炼到最低限度):

scalar: simple_value
empty:
list:
  - 1
  - 2
  - 3
complex:
  - first:
      one: 1
      two: 2
  - second:
      one: 3
      two: 4
weird: "{{ '{{' }} something {{ '}}' }}"
weirder: "{{ '{{' }} 'TTT' if something == 'blah' else 'FFF' {{ '}}' }}"
weirdest: "&lcub2; ansible_date_time.year &rcub2;.&lcub2; ansible_date_time.month &rcub2;.&lcub2; ansible_date_time.day &rcub2;"

还有这个剧本:

---
- hosts: localhost
  tasks:
    - name: Load
      include_vars:
        file: ./vars.yml
        name: object
    - name: Write
      copy:
        content: "{{ object | to_nice_yaml(indent=2) }}"
        dest: ./outv.yml

输出文件是这样的:

complex:
- first:
    one: 1
    two: 2
- second:
    one: 3
    two: 4
empty: null
list:
- 1
- 2
- 3
scalar: simple_value
weird: '{{ something }}'
weirder: '{{ ''TTT'' if something == ''blah'' else ''FFF'' }}'
weirdest: '&lcub2; ansible_date_time.year &rcub2;.&lcub2; ansible_date_time.month
  &rcub2;.&lcub2; ansible_date_time.day &rcub2;'

虽然我认为输出和输入列表缩进都是正确且等效的,并且Jinja escaping 处理得当,但我不确定weirder 的值引用。 而且我不明白weirdest 值的换行符。

YAMLint 说没问题,但实际上恢复了“正常”引用并在语法检查期间重新加入换行符。

有没有办法通过过滤器to_nice_yaml(或任何其他过滤器)强制使用双引号?

有没有办法避免换行(或者可能有原因)?

【问题讨论】:

    标签: ansible yaml escaping line-breaks quoting


    【解决方案1】:

    关于您在weirdest 中观察到的换行符,文档中对此进行了解释:

    to_yamlto_nice_yaml 过滤器使用 PyYAML library,它具有默认的 80 个符号字符串长度限制。这会导致第 80 个符号后出现意外换行(如果第 80 个符号后有空格) 为避免此类行为并生成长行,请使用 width 选项。您必须使用硬编码数字来定义宽度,而不是像 float("inf") 这样的结构,因为过滤器不支持代理 Python 函数。
    例如:

    {{ some_variable | to_yaml(indent=8, width=1337) }} 
    {{ some_variable | to_nice_yaml(indent=8, width=1337) }}
    

    来源:https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#formatting-data-yaml-and-json


    然后,在文档中的解释之后,他们还指出了这样一个事实:

    过滤器确实支持传递其他 YAML 参数。如需完整列表,请参阅PyYAML documentation

    所以有一些关于双引号字符串的内容:default_style='"'

    更多细节可以在here找到。


    所以,剧本:

    - hosts: all
      gather_facts: no
          
      tasks:
        - copy:
            content:  "{{ object | to_nice_yaml(indent=2, width=1337, default_style='\"') }}"
            dest: ./outv.yml
          vars:
            object:
              scalar: simple_value
              empty:
              list:
                - 1
                - 2
                - 3
              complex:
                - first:
                    one: 1
                    two: 2
                - second:
                    one: 3
                    two: 4
              weird: "{{ '{{' }} something {{ '}}' }}"
              weirder: "{{ '{{' }} 'TTT' if something == 'blah' else 'FFF' {{ '}}' }}"
              weirdest: "&lcub2; ansible_date_time.year &rcub2;.&lcub2; ansible_date_time.month &rcub2;.&lcub2; ansible_date_time.day &rcub2;"
    

    给出一个文件 outv.yml 包含:

    "complex":
    - "first":
        "one": !!int "1"
        "two": !!int "2"
    - "second":
        "one": !!int "3"
        "two": !!int "4"
    "empty": !!null "null"
    "list":
    - !!int "1"
    - !!int "2"
    - !!int "3"
    "scalar": "simple_value"
    "weird": "{{ something }}"
    "weirder": "{{ 'TTT' if something == 'blah' else 'FFF' }}"
    "weirdest": "&lcub2; ansible_date_time.year &rcub2;.&lcub2; ansible_date_time.month &rcub2;.&lcub2; ansible_date_time.day &rcub2;"
    

    请注意,!!int!!null 语法在 YAML 中称为 explicit typing,并在链接文档中进行了说明。

    【讨论】: