属性错误:“列表”对象没有属性“分割线”

问题描述 投票:0回答:2

考虑以下测试手册:

---
- name: Node Tolerations
  hosts: localhost
  gather_facts: false
  vars:
    tolerations:
      - key: node.cilium.io/agent-not-ready
        operator: Exists
        effect: NoExecute
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
  tasks:
    - name: Set node tolerations fact
      ansible.builtin.set_fact:
        node_tolerations: "{{ (node_tolerations | default([]) | union([':'.join((item.key, item.effect))])) }}"
      with_items: '{{ tolerations }}'

    - name: Set node taint fact
      ansible.builtin.set_fact:
        node_taint: "{{ node_tolerations | select('search', 'control-plane') }}"

    - name: Variable output
      ansible.builtin.debug:
        var: node_taint

这会产生预期的结果:

ok: [localhost] =>
  node_taint:
  - node-role.kubernetes.io/control-plane:NoSchedule

在 Jinja2 模板中使用

node_taint
事实时:

node-taint:
  {{ node_taint | indent(2) }}

生成以下错误:

AttributeError: 'list' object has no attribute 'splitlines'

作为临时解决方法,我使用了:

node-taint:
  - {{ node_taint | join }}

但我更喜欢最初的 Jinja2 格式,它允许我定义正确的缩进。我想知道您是否可以提供一些见解,什么是正确的解决方案。

编辑:我对上述详细剧本的第二个用法是:

tolerations:
  {{ tolerations | indent(2) }}

这会产生相同的错误。我宁愿避免在 Jinja 模板内使用

for
循环并在事实级别操作数据,从而允许我在模板内使用适当的
indent

ansible jinja2
2个回答
0
投票

由于

node_toleration
是一个列表,您可以对其进行迭代,为每个项目生成一行缩进输出:

node-taint:
{% for toleration in node_toleration | select('search', 'control-plane') %}
{{ ' ' * 2 }}- {{ toleration }}
{% endfor %}

或:

node-taint:
{% for toleration in node_toleration | select('search', 'control-plane') %}
{{ '- ' + toleration | indent(2) }}
{% endfor %}

0
投票

鉴于 mre 列表

  node_taint:
    - node-role.0
    - node-role.1
    - node-role.2

下面的调试

   - debug:
       var: node_taint

提供 YAML 格式

  node_taint:
  - node-role.0
  - node-role.1
  - node-role.2

如果你想缩进行

    - debug:
        msg: |
          node_taint:
            {{ node_taint | indent(2) }}

您会收到以下错误,因为 node_taint 的值不是字符串

...错误是:AttributeError:'list'对象没有属性'splitlines'

引用函数indent

jinja-filters.indent(s: str, width: int | str = 4, ...

返回string的副本,每行缩进4个空格。第一行和空行默认不缩进。

解决方案是将node_taint的值转换为字符串。使用过滤器 to_nice_yaml

    - debug:
        msg: |
          node_taint:
            {{ node_taint | to_nice_yaml | indent(2) }}

给予

  msg: |-
    node_taint:
      - node-role.0
      - node-role.1
      - node-role.2

用于测试的完整剧本示例

- hosts: localhost

  vars:

    node_taint:
      - node-role.0
      - node-role.1
      - node-role.2

  tasks:

    - debug:
        var: node_taint

    - debug:
        msg: |
          node_taint:
            {{ node_taint | to_yaml | indent(2) }}

    - debug:
        msg: |
          node_taint:
            {{ node_taint | to_nice_yaml | indent(2) }}
© www.soinside.com 2019 - 2024. All rights reserved.