Ansible循环获取下一个值

Ansible循环获取下一个值,ansible,yaml,Ansible,Yaml,我目前在循环中执行特定任务时遇到一些困难。 首先,我需要循环特定结构: companies: - name: Facebook company_url: "https://www.facebook.com" company_certificate: "Facebook.crt" port_type: "AS2" create_filematch: "yes" filters: - name: "ORDERS" reg

我目前在循环中执行特定任务时遇到一些困难。 首先,我需要循环特定结构:

companies:
  - name: Facebook
    company_url: "https://www.facebook.com"
    company_certificate: "Facebook.crt"
    port_type: "AS2"
    create_filematch: "yes"
    filters:
        - name: "ORDERS"
          regex: "ORDER*"
        - name: "INVOICES"
          regex: "INVOICE*"
  - name: Google
    company_url: "https://www.google.com"
    company_certificate: "Google.crt"
    port_type: "AS2"
    create_filematch: "yes"
    filters:
        - name: "ORDERS"
          regex: "ORDER*"
        - name: "INVOICES"
          regex: "INVOICE*"
我需要循环“过滤器”的子元素。我正在使用以下循环:

loop: "{{ companies | subelements('filters', skip_missing=True) }}"
问题是我需要在模板中填充两个字段:matchelse匹配字段应该是循环的当前项。第二个字段应为下一项

例如,如果我有以下子元素结构: 子元素: sub1:值 sub2:值 sub3:值

然后在这些子元素上使用循环,模板中的两个字段应该如下所示:

match_send=sub1
else_send=sub2
然后是下一项

match_send=sub2
else_send=sub3
我该怎么做


谢谢。

尽管我发表了意见,但我认为我找到了解决办法。 你可以和你一起使用

我想出了一个有效的例子:

---
- hosts: localhost
  vars:
  - list1:
    - a
    - b
    - c
  tasks:
  - name: with_together
    debug:
      msg: "{{ item.0 }} - {{ item.1 }}"
    with_together:
      - "{{ list1 }}"
      - "{{ list1[1:] }}"
其中:

TASK [with_together] ************************************************************************************************************************************************
ok: [localhost] => (item=[u'a', u'b']) => {
    "msg": "a - b"
}
ok: [localhost] => (item=[u'b', u'c']) => {
    "msg": "b - c"
}
ok: [localhost] => (item=[u'c', None]) => {
    "msg": "c - "
}

我相信您可以根据您的用例对其进行调整。

尽管有我的评论,但我认为我找到了解决方案。 你可以和你一起使用

我想出了一个有效的例子:

---
- hosts: localhost
  vars:
  - list1:
    - a
    - b
    - c
  tasks:
  - name: with_together
    debug:
      msg: "{{ item.0 }} - {{ item.1 }}"
    with_together:
      - "{{ list1 }}"
      - "{{ list1[1:] }}"
其中:

TASK [with_together] ************************************************************************************************************************************************
ok: [localhost] => (item=[u'a', u'b']) => {
    "msg": "a - b"
}
ok: [localhost] => (item=[u'b', u'c']) => {
    "msg": "b - c"
}
ok: [localhost] => (item=[u'c', None]) => {
    "msg": "c - "
}
我相信您可以根据您的用例调整它

Q:“match和else。match字段应该是循环的当前项。第二个字段应该是下一项。”

A:为了这个目的。比如说

- hosts: localhost
  vars:
    companies:
      - name: 'Amazon'
        filters:
          - 'filter-A1'
          - 'filter-A2'
          - 'filter-A3'
      - name: 'Facebook'
        filters:
          - 'filter-F1'
          - 'filter-F2'
          - 'filter-F3'
      - name: 'Google'
        filters:
          - 'filter-G1'
          - 'filter-G2'
          - 'filter-G3'

  tasks:

    - debug:
        msg:
          - "match: {{ item.0.name }} -
                    {{ item.1 }}"
          - "else: {{ ansible_loop.nextitem.0.name|default('last item') }} -
                   {{ ansible_loop.nextitem.1|default('last subitem') }}"
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        extended: true
给予

问:“我希望它表现得像这样:”

例如,当它到达Facebook的最后一个子项时,next_item的值应为空

A:试试这个

    - debug:
        msg: "{{ msg.split('\n') }}"
      vars:
        msg: |
          - match: {{ item.0.name }} -  {{ item.1 }}
          {% if item.0.name == ansible_loop.nextitem.0.name|default('last item') %}
          - else: {{ ansible_loop.nextitem.0.name }} -  {{ ansible_loop.nextitem.1 }}
          {% else %}
          - else: ''
          {% endif %}
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        label: "{{ item.0.name }}"
        extended: true
最后,如果您想使用此列表创建变量,请尝试

    - set_fact:
        companies1: "{{ companies1|default([]) + [company|from_yaml] }}"
      vars:
        company: |
          [{match: '{{ item.0.name }} - {{ item.1 }}'},
          {%- if item.0.name == ansible_loop.nextitem.0.name|default('last item') %}
          {else: '{{ ansible_loop.nextitem.0.name }} -  {{ ansible_loop.nextitem.1 }}'}]
          {%- else %}
          {else: ''}]
          {% endif %}
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        label: "{{ item.0.name }}"
        extended: true
    - debug:
        msg: "{{ msg.split('\n') }}"
      vars:
        msg: "{{ companies1|to_yaml }}"
给予

Q:“match和else。match字段应该是循环的当前项。第二个字段应该是下一项。”

A:为了这个目的。比如说

- hosts: localhost
  vars:
    companies:
      - name: 'Amazon'
        filters:
          - 'filter-A1'
          - 'filter-A2'
          - 'filter-A3'
      - name: 'Facebook'
        filters:
          - 'filter-F1'
          - 'filter-F2'
          - 'filter-F3'
      - name: 'Google'
        filters:
          - 'filter-G1'
          - 'filter-G2'
          - 'filter-G3'

  tasks:

    - debug:
        msg:
          - "match: {{ item.0.name }} -
                    {{ item.1 }}"
          - "else: {{ ansible_loop.nextitem.0.name|default('last item') }} -
                   {{ ansible_loop.nextitem.1|default('last subitem') }}"
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        extended: true
给予

问:“我希望它表现得像这样:”

例如,当它到达Facebook的最后一个子项时,next_item的值应为空

A:试试这个

    - debug:
        msg: "{{ msg.split('\n') }}"
      vars:
        msg: |
          - match: {{ item.0.name }} -  {{ item.1 }}
          {% if item.0.name == ansible_loop.nextitem.0.name|default('last item') %}
          - else: {{ ansible_loop.nextitem.0.name }} -  {{ ansible_loop.nextitem.1 }}
          {% else %}
          - else: ''
          {% endif %}
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        label: "{{ item.0.name }}"
        extended: true
最后,如果您想使用此列表创建变量,请尝试

    - set_fact:
        companies1: "{{ companies1|default([]) + [company|from_yaml] }}"
      vars:
        company: |
          [{match: '{{ item.0.name }} - {{ item.1 }}'},
          {%- if item.0.name == ansible_loop.nextitem.0.name|default('last item') %}
          {else: '{{ ansible_loop.nextitem.0.name }} -  {{ ansible_loop.nextitem.1 }}'}]
          {%- else %}
          {else: ''}]
          {% endif %}
      loop: "{{ companies|subelements('filters', skip_missing=True) }}"
      loop_control:
        label: "{{ item.0.name }}"
        extended: true
    - debug:
        msg: "{{ msg.split('\n') }}"
      vars:
        msg: "{{ companies1|to_yaml }}"
给予



我不确定我是否理解:您谈论的是模板,所以希望能够使用子元素列表作为模板的数据输入?是的,我希望使用子元素填充我的模板。问题是我知道如何用当前循环项填充模板,但在模板中的某个点,我需要获得循环的下一项的值。好吧,我想你不能这样做。如果它是一个要渲染的大模板,那么您可以传递整个列表并在模板内使用loop.nextitem。但是当您使用循环时,渲染任务一次只接收一个元素。是的,这是我的担心。我找到的唯一解决方案是让一个子元素包含下一个子元素的名称。但在我看来,这是一个丑陋的解决方案。我不确定我是否理解:您谈论的是模板,所以您希望能够使用子元素列表作为模板的数据输入?是的,我希望使用子元素填充我的模板。问题是我知道如何用当前循环项填充模板,但在模板中的某个点,我需要获得循环的下一项的值。好吧,我想你不能这样做。如果它是一个要渲染的大模板,那么您可以传递整个列表并在模板内使用loop.nextitem。但是当您使用循环时,渲染任务一次只接收一个元素。是的,这是我的担心。我找到的唯一解决方案是让一个子元素包含下一个子元素的名称。但在我看来,这是一个丑陋的解决方案。对于你的答案,这就是我一直在寻找的。我仍然有一个问题,如果我到达最后一个子项,下一个项将不会为空,但它将拾取循环的第一个项。如果您对如何停止此行为有想法:)是否希望所有子项都像筛选器Gx那样工作?是的,但当我到达子元素列表的最后一项时,ansible_loop.nextitem将获取列表中第一项的值:(你能重现我的例子吗?是的。我知道现在发生了什么。我误解了next_item参数。我只想要所选项目的next_item。如果你举个例子,我希望它的行为如下:“msg”:[“match:Facebook-filter-F2”,“else:Facebook-filter-F3”]-“msg”:[“匹配:Facebook-filter-F3”,“其他:”]例如,当它到达Facebook的最后一个子项时,next_item的值应该是空的。谢谢你的回答,这就是我一直在寻找的。我仍然有一个问题,如果我到达最后一个子项,next_item将不会是空的,但它将拾取循环的第一个项。如果你知道如何停止这种行为:)是否希望所有子项都像筛选器Gx那样工作?是的,但当我到达子元素列表的最后一项时,ansible_loop.nextitem将获取列表中第一项的值:(你能重现我的例子吗?是的。我知道现在发生了什么。我误解了next_item参数。我只想要所选项目的next_item。如果你举个例子,我希望它的行为如下:“msg”:[“match:Facebook-filter-F2”,“else:Facebook-filter-F3”]-“msg”:[”匹配:Facebook-filter-F3“,”else:“]因此,当它到达Facebook的最后一个子项时,例如,next_项的值应该为空。