在模板内使用基于列表的事实会产生错误

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

我正在使用以下事实:

- name: Set server ips fact
  ansible.builtin.set_fact:
    k3s_server_ips: "{{ k3s_server_hosts | map('extract', hostvars, ['ansible_default_ipv4', 'address']) }}"
  when: ansible_host in k3s_server_hosts

这会产生:

ok: [apollo] => changed=false
  ansible_facts:
    k3s_server_ips:
    - 192.168.4.2
    - 192.168.4.3
    - 192.168.4.4

当我在 Jinja2 模板中使用定义的事实时:

kubeProxy:
  endpoints: '{{ k3s_server_ips }}'

显示以下错误:

Traceback (most recent call last):
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/executor/task_executor.py", line 526, in _execute
    self._task.post_validate(templar=templar)
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/playbook/task.py", line 290, in post_validate
    super(Task, self).post_validate(templar)
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/playbook/base.py", line 543, in post_validate
    value = method(attribute, getattr(self, name), templar)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/playbook/task.py", line 298, in _post_validate_args
    args = templar.template(value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/template/__init__.py", line 791, in template
    d[k] = self.template(
           ^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/template/__init__.py", line 764, in template
    result = self.do_template(
             ^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/template/__init__.py", line 1010, in do_template
    res = myenv.concat(rf)
          ^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/template/native_helpers.py", line 43, in ansible_eval_concat
    head = list(islice(nodes, 2))
           ^^^^^^^^^^^^^^^^^^^^^^
  File "<template>", line 18, in root
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/template/__init__.py", line 295, in wrapper
    ret = func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/ansible/plugins/filter/core.py", line 221, in from_yaml
    return yaml_load(text_type(to_text(data, errors='surrogate_or_strict')))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/ansible/9.4.0/libexec/lib/python3.12/site-packages/yaml/constructor.py", line 49, in get_single_data
    node = self.get_single_node()
           ^^^^^^^^^^^^^^^^^^^^^^
  File "yaml/_yaml.pyx", line 673, in yaml._yaml.CParser.get_single_node
  File "yaml/_yaml.pyx", line 687, in yaml._yaml.CParser._compose_document
  File "yaml/_yaml.pyx", line 731, in yaml._yaml.CParser._compose_node
  File "yaml/_yaml.pyx", line 845, in yaml._yaml.CParser._compose_mapping_node
  File "yaml/_yaml.pyx", line 731, in yaml._yaml.CParser._compose_node
  File "yaml/_yaml.pyx", line 847, in yaml._yaml.CParser._compose_mapping_node
  File "yaml/_yaml.pyx", line 860, in yaml._yaml.CParser._parse_next_event
yaml.scanner.ScannerError: mapping values are not allowed in this context
  in "<unicode string>", line 26, column 68
fatal: [apollo]: FAILED! => changed=false

仅当我在模板内使用事实时才会发生这种情况,如果我在任务内使用

k3s_server_ips
,则不会有问题。

作为解决方法,我尝试过:

kubeProxy:
  endpoints:
{% for ip in k3s_server_ips %}
    - {{ ip }}
{% endfor %}

这解决了问题。我想知道是否有更好的实现。

ansible jinja2
1个回答
0
投票

对于名为

templates/my_list.j2
的 Jinja2 模板作为输入且内容为

kubeProxy:
  endpoints:
    {{ k3s_server_ips | to_nice_yaml(indent=4) | trim | indent(4) }}
  as_well:
{% for ip in k3s_server_ips %}
    - {{ ip }}
{% endfor %}

使用最小的示例剧本进行处理

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    k3s_server_ips:
      - 192.168.4.2
      - 192.168.4.3
      - 192.168.4.4

  tasks:

  - template:
      src: templates/my_list.j2
      dest: kubeProxy.endpoints.yml

  - name: "Set from template"
    set_fact:
      my_list: "{{ lookup('ansible.builtin.template', 'templates/my_list.j2') }}"

  - debug:
      msg: "{{ my_list | from_yaml }}"

将产生

的输出
TASK [debug] ******
ok: [localhost] =>
  msg:
    kubeProxy:
      as_well:
      - 192.168.4.2
      - 192.168.4.3
      - 192.168.4.4
      endpoints:
      - 192.168.4.2
      - 192.168.4.3
      - 192.168.4.4

还有一个名为

kubeProxy.endpoints.yml
的文件,其内容为

kubeProxy:
  endpoints:
    - 192.168.4.2
    - 192.168.4.3
    - 192.168.4.4
  as_well:
    - 192.168.4.2
    - 192.168.4.3
    - 192.168.4.4

感谢和类似的问答

© www.soinside.com 2019 - 2024. All rights reserved.