如何遍历字典列表及其内容列表

时间:2020-09-22 12:35:21

标签: ansible

我有以下变量

---

- hosts: all

  vars:
    new_service:
      name: test
      Unit:
      - option: Description
        value: "Testname"
      Service:
      - option: ExecStart
        value: "/usr/bin/python3 -m http.server 8080"
      - option: WorkingDirectory
        value: /home/test/testservice/html

我希望能够使用ini_file模块创建服务模板,以便将上述var转换为以下ini文件

[Unit]
Description=Testname

[Service]
ExecStart=/usr/bin/python3 -m http.server 8080
WorkingDirectory=/home/test/testservice/html

我不知道该如何遍历。我当时正在考虑使用product()来遍历嵌套列表,也许是这样?

  - name: "Create new unit section of service file"
    ini_file:
      path: "~{{ USERNAME }}/.config/systemd/user/{{ new_service[name] }}"
      section: "{{ item.0 }}"
      option: "{{ item.1.option }}"
      value: "{{ item.1.value }}"
    loop: "{{ ['unit', 'service'] | product({{ new_service[item.0] }})"

但是我不认为项目是在循环定义本身中定义的

(我使用ini_file而不是模板的原因是因为我希望服务文件创建能够按需处理任意数量的字段)

1 个答案:

答案 0 :(得分:3)

您仍然可以使用模板来具有可变数量的节和选项。在此处将loopini_file一起使用并不是有效的IMO。唯一真正的用例是,如果您只需要添加新内容,就保留文件的原始内容。但是性能将大大低于单个模板,特别是如果您有很多元素。

我看到的唯一困难是您的字典中有一个name属性,它不是节标题。但这很容易排除。

template.j2

{% for section in new_service %}
{% if section != 'name' %}
[{{ section }}]
{% for option in new_service[section] %}
{{ option.option }}={{ option.value }}
{% endfor %}

{% endif %}
{% endfor %}

返回原始问题

如果您确实想遍历循环路径,仍然可以,但是需要花费大量精力来处理实际的数据结构(loop / set_fact / ...以最终获得单个可循环结构)。

如果可能,我将其更改为以下内容:

new_service:
  name: test
  sections:
    - section: Unit
      options:
        - option: Description
          value: "Testname"
    - section: Service
      options:
        - option: ExecStart
          value: "/usr/bin/python3 -m http.server 8080"
        - option: WorkingDirectory
          value: /home/test/testservice/html

然后您可以使用subelements lookup直接循环浏览此结构。请注意,"name"(位于顶层)不是var,而是您的服务名称值的字符串标识符,应这样使用(在我的以下示例中固定):

  - name: "Create new unit section of service file"
    ini_file:
      path: "~{{ USERNAME }}/.config/systemd/user/{{ new_service.name }}"
      section: "{{ item.0.section }}"
      option: "{{ item.1.option }}"
      value: "{{ item.1.value }}"
    loop: "{{ lookup('subelements', new_service.sections, 'options') }}"

如果需要,您也可以轻松地使我的第一个示例模板适应这种新的数据结构。