loops - 循环没有迭代列表的最后一行
问题描述
我在剧本中创建了一个模板,我想用哈希列表进行迭代。我想将此输出添加到另一个 var 以在以下模块中使用。
模板有效,循环看起来也有效,但它从不添加列表中的最后一项。我在测试游戏中重新创建了它。
---
- hosts: localhost
tasks:
- name: Init
set_fact:
foo: []
fqdn: "test.com"
template: []
- name: portlist
set_fact:
portlist:
- { port: 9091, index: 1 }
- { port: 9092, index: 2 }
- { port: 9093, index: 3 }
- { port: 9094, index: 4 }
- name: generate policy
set_fact:
template:
- name: "traffic to {{ item.port }}"
index: "{{ item.index }}"
match:
desc: "[{{ item.port }}]" # The field needs to be passed as a list
name: "{{ fqdn }}_{{ item.port }}"
port: "{{ item.port }}"
foo: "{{ foo + template }}"
loop: "{{ portlist }}"
- debug:
var: foo
我知道我可以使用默认值而不是初始化 vars 来使这个游戏更小,但这感觉更容易阅读以进行故障排除。
该播放会产生一个哈希列表,然后我可以将其输入到策略模块中。然而,它只给了我列表中的 3 个项目,并且错过了端口列表中的最后一个项目。
TASK [debug] ***************************************************
ok: [localhost] => {
"foo": [
{
"action": {
"ref": "test.com_9091",
"this": true
},
"enable": true,
"index": "1",
"match": {
"port": {
"criteria": "IS_IN",
"port": [
9091
]
}
},
"name": "traffic to 9091"
},
{
"action": {
"ref": "test.com_9092",
"this": true
},
"enable": true,
"index": "2",
"match": {
"port": {
"criteria": "IS_IN",
"port": [
9092
]
}
},
"name": "traffic to 9092"
},
{
"action": {
"ref": "test.com_9093",
"this": true
},
"enable": true,
"index": "3",
"match": {
"port": {
"criteria": "IS_IN",
"port": [
9093
]
}
},
"name": "traffic to 9093"
}
]
}
解决方案
您的问题是由于在任务完成set_fact
之前定义的变量不可用。set_fact
这意味着当您设置:
foo: "{{ foo + template }}"
template
您可以从上一个循环迭代中看到 的值。
处理此问题的一种方法是重写您的set_fact
任务以foo
直接设置:
---
- hosts: localhost
gather_facts: false
vars:
fqdn: "test.com"
portlist:
- {port: 9091, index: 1}
- {port: 9092, index: 2}
- {port: 9093, index: 3}
- {port: 9094, index: 4}
tasks:
- name: generate policy
set_fact:
foo: >-
{{
foo + [{
'name': 'traffic to {}'.format(item.port),
'index': item.index,
'match': {
'desc': "[{}]".format(item.port),
'name': '{}_{}'.format(fqdn, item.port),
'port': item.port
}
}]
}}
vars:
foo: []
loop: "{{ portlist }}"
- debug:
var: foo
这将输出:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
"foo": [
{
"index": 1,
"match": {
"desc": "[9091]",
"name": "test.com_9091",
"port": 9091
},
"name": "traffic to 9091"
},
{
"index": 2,
"match": {
"desc": "[9092]",
"name": "test.com_9092",
"port": 9092
},
"name": "traffic to 9092"
},
{
"index": 3,
"match": {
"desc": "[9093]",
"name": "test.com_9093",
"port": 9093
},
"name": "traffic to 9093"
},
{
"index": 4,
"match": {
"desc": "[9094]",
"name": "test.com_9094",
"port": 9094
},
"name": "traffic to 9094"
}
]
}
如果您发现基于模板的解决方案更具可读性,您可以使用以下两个set_fact
任务重写它:
---
- hosts: localhost
gather_facts: false
vars:
fqdn: "test.com"
portlist:
- {port: 9091, index: 1}
- {port: 9092, index: 2}
- {port: 9093, index: 3}
- {port: 9094, index: 4}
tasks:
- name: generate policy
set_fact:
template:
name: "traffic to {{ item.port }}"
index: "{{ item.index }}"
match:
desc: "[{{ item.port }}]" # The field needs to be passed as a list
name: "{{ fqdn }}_{{ item.port }}"
port: "{{ item.port }}"
loop: "{{ portlist }}"
register: foo
- set_fact:
foo: "{{ foo.results | map(attribute='ansible_facts.template') | list }}"
- debug:
var: foo
推荐阅读
- c++ - 我的 PowerShell 脚本未按预期工作(用于编译 C++ 文件)
- css - 有没有办法将 Bootstrap 类属性写入 CSS 文件,或者有没有办法让它工作?
- powershell - 无法将参数传递给 ConvertTo-SecureString,只有脚本定义的变量
- perl - Perl Tcl::pTk 读取 Tcl 版本
- java - 执行方法时如何写入和保存日志文件(通过应用程序属性设置级别)
- javascript - 使用 HTML5 和 javascript 从 iPhone Chrome 录音
- initialization - 在 Cobol 中初始化可变长度
- javascript - 在 DOM 中加载后,我可以取消注释 JavaScript 函数中的注释代码行吗?
- apache - Websphere 应用程序问题中的 IHS 与 Apache
- typescript - typescript error TS2531 Object is possibly 'null' is NOT being suppressed by strictNullChecks : false