Ansible / jinja2 输出
Ansible / jinja2 output
我是 运行 RHEL 7.4 上的 Ansible 2.7.5。 (我知道它很旧;我会尽快升级——保证)。 zip 特性出现在 Ansible 2.3 中。无论如何,我似乎无法通过 zip 过滤器获得几个列表来正确创建字典。
我已经从变量文件中读取了列表。该列表在循环中的 network_interfaces['computer_type']
后面;这是来自调试输出:
[{u'interface': u'bond0.160', u'notes': u'note160'},
{u'interface': u'bond0.197', u'notes': u'note197'},
{u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
问题是,我正在尝试将您在上面看到的接口名称连同它们的值(现在作为示例是“注释”)一起放入字典中。但是,当我尝试执行下面 _reused_val
的第一个示例中所示的 dict (_keys|zip(_vals))
时,我得到了相应的错误消息编号 1。因此为了调试,我重新运行了我的任务,并取消注释 #2,并且随后取消注释#3。
- debug:
msg: >
ITEM: {{ item }}
* :::network_interfaces::: {{ network_interfaces[computer_type] }}
* :::_keys::: {{ _keys }}
* :::_vals::: {{ _vals }}
* :::_reused_val::: {{ _reused_val }}
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
_vals: "{{ network_interfaces[computer_type] }}" # returns a list
_reused_val: "{{ dict(_keys|zip(_vals)) }}" #1
#_reused_val: "{{ _keys|zip(_vals) | list }}" #2
#_reused_val: "{{ _keys|zip(_vals) }}" #3
输出显示 reused_val
(我稍微调整了间距以使其更易于阅读):
1- "msg": "Unexpected templating type error occurred on ({{ dict(_keys|zip(_vals)) }}): <lambda>() takes exactly 0 arguments (1 given)"
2- [(u'bond0.160', {u'interface': u'bond0.160', u'notes': u'note160'}),
(u'bond0.197', {u'interface': u'bond0.197', u'notes': u'note197'}),
(u'bond1', {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'})]
3- <itertools.izip object at 0x7f311c048dd0>
#1 是我要开始工作的 - dict(_keys|zip(_vals))
。
我不知道为什么 #3 显示一个 itertools.izip 对象。我认为它应该 return 一个列表。对于#2,我不知道那些括号是干什么用的。是因为列表里有3本词典吗?
最后,这里是案例 #3 的消息的完整输出;为了便于阅读,我稍微打破了线条:
"ITEM: big_computer * :::network_interfaces:::
[{u'interface': u'bond0.160', u'notes': u'note160'}, {u'interface': u'bond0.197', u'notes': u'note1
97'}, {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
* :::_keys::: [u'bond0.160', u'bond0.197', u'bond1']
* :::_vals::: [{u'interface': u'bond0.160', u'notes': u'note160'}, {u'interface': u'bond0.197', u'notes': u'note197'}, {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
* :::_reused_val::: <itertools.izip object at 0x7fc768049cb0>\n"
这项工作是我在 提出的问题的结果
我正在尝试按照这些示例进行操作,但经过一天的工作,我仍然卡住了。谢谢。
我认为你应该升级你的 Ansible。
使用 ansible 2.10.8,下面的剧本 运行s 没有错误,我认为它会产生你想要的输出。这与您所拥有的基本相同,除了我在 debug
任务中使用列表来生成更清晰的输出。
- hosts: localhost
gather_facts: false
vars:
network_interfaces:
big_computer:
- interface: bond0.160
notes: note160
- interface: bond0.197
notes: note197
- interface: bond1
notes: 'bonded, numa1, broadcom devices'
tasks:
- debug:
msg:
- "ITEM: {{ item }}"
- "network_interfaces: {{ network_interfaces[computer_type] }}"
- "keys: {{ _keys }}"
- "vals: {{ _vals }}"
- "reused_val: {{ _reused_val }}"
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
_vals: "{{ network_interfaces[computer_type] }}" # returns a list
_reused_val: "{{ dict(_keys|zip(_vals)) }}" #1
运行 这会产生:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: ['bond0.160', 'bond0.197', 'bond1']",
"vals: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"reused_val: {'bond0.160': {'interface': 'bond0.160', 'notes': 'note160'}, 'bond0.197': {'interface': 'bond0.197', 'notes': 'note197'}, 'bond1': {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}}"
]
}
如果我 运行 使用 Ansible 2.7.5,我仍然没有看到您报告的任何错误(这就是为什么包含 运行nable example in your question),但我也没有得到与 2.10.8 相同的行为。我得到:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: ['bond0.160', 'bond0.197', 'bond1']",
"vals: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"reused_val: {'[': '[', \"'\": 's', 'b': \"'\", 'o': 'n', 'n': 'o', 'd': 't', '0': 'd', '.': '0', '1': 'e', '6': 'a', ',': \"'\", ' ': ',', '9': '1', '7': '6', ']': \"'\"}"
]
}
所以,除了最后一步,一切都很好。这里最大的问题是 Ansible 2.7.5 不能很好地处理字符串值以外的任何内容。当你写这个...
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
结果是一个 string 值,而不是一个列表,而在最近的
Ansible 的版本 _keys
变量 将 是一个列表。我们可以工作
通过显式序列化和反序列化所有内容来解决这个问题
to/from JSON:
- debug:
msg:
- "ITEM: {{ item }}"
- "network_interfaces: {{ network_interfaces[computer_type] }}"
- "keys: {{ _keys }}"
- "vals: {{ _vals }}"
- "reused_val: {{ _reused_val }}"
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list|to_json }}"
_vals: "{{ network_interfaces[computer_type]|to_json }}"
_reused_val: "{{ dict(_keys|from_json|zip(_vals|from_json)) }}"
这会产生与原始版本 2.10.8 相同的输出:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: [\"bond0.160\", \"bond0.197\", \"bond1\"]",
"vals: [{\"interface\": \"bond0.160\", \"notes\": \"note160\"}, {\"interface\": \"bond0.197\", \"notes\": \"note197\"}, {\"interface\": \"bond1\", \"notes\": \"bonded, numa1, broadcom devices\"}]",
"reused_val: {'bond0.160': {'interface': 'bond0.160', 'notes': 'note160'}, 'bond0.197': {'interface': 'bond0.197', 'notes': 'note197'}, 'bond1': {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}}"
]
}
...但这是一个糟糕的解决方案,并且只是为了更清洁
升级。
我是 运行 RHEL 7.4 上的 Ansible 2.7.5。 (我知道它很旧;我会尽快升级——保证)。 zip 特性出现在 Ansible 2.3 中。无论如何,我似乎无法通过 zip 过滤器获得几个列表来正确创建字典。
我已经从变量文件中读取了列表。该列表在循环中的 network_interfaces['computer_type']
后面;这是来自调试输出:
[{u'interface': u'bond0.160', u'notes': u'note160'},
{u'interface': u'bond0.197', u'notes': u'note197'},
{u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
问题是,我正在尝试将您在上面看到的接口名称连同它们的值(现在作为示例是“注释”)一起放入字典中。但是,当我尝试执行下面 _reused_val
的第一个示例中所示的 dict (_keys|zip(_vals))
时,我得到了相应的错误消息编号 1。因此为了调试,我重新运行了我的任务,并取消注释 #2,并且随后取消注释#3。
- debug:
msg: >
ITEM: {{ item }}
* :::network_interfaces::: {{ network_interfaces[computer_type] }}
* :::_keys::: {{ _keys }}
* :::_vals::: {{ _vals }}
* :::_reused_val::: {{ _reused_val }}
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
_vals: "{{ network_interfaces[computer_type] }}" # returns a list
_reused_val: "{{ dict(_keys|zip(_vals)) }}" #1
#_reused_val: "{{ _keys|zip(_vals) | list }}" #2
#_reused_val: "{{ _keys|zip(_vals) }}" #3
输出显示 reused_val
(我稍微调整了间距以使其更易于阅读):
1- "msg": "Unexpected templating type error occurred on ({{ dict(_keys|zip(_vals)) }}): <lambda>() takes exactly 0 arguments (1 given)"
2- [(u'bond0.160', {u'interface': u'bond0.160', u'notes': u'note160'}),
(u'bond0.197', {u'interface': u'bond0.197', u'notes': u'note197'}),
(u'bond1', {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'})]
3- <itertools.izip object at 0x7f311c048dd0>
#1 是我要开始工作的 - dict(_keys|zip(_vals))
。
我不知道为什么 #3 显示一个 itertools.izip 对象。我认为它应该 return 一个列表。对于#2,我不知道那些括号是干什么用的。是因为列表里有3本词典吗?
最后,这里是案例 #3 的消息的完整输出;为了便于阅读,我稍微打破了线条:
"ITEM: big_computer * :::network_interfaces:::
[{u'interface': u'bond0.160', u'notes': u'note160'}, {u'interface': u'bond0.197', u'notes': u'note1
97'}, {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
* :::_keys::: [u'bond0.160', u'bond0.197', u'bond1']
* :::_vals::: [{u'interface': u'bond0.160', u'notes': u'note160'}, {u'interface': u'bond0.197', u'notes': u'note197'}, {u'interface': u'bond1', u'notes': u'bonded, numa1, broadcom device'}]
* :::_reused_val::: <itertools.izip object at 0x7fc768049cb0>\n"
这项工作是我在
我认为你应该升级你的 Ansible。
使用 ansible 2.10.8,下面的剧本 运行s 没有错误,我认为它会产生你想要的输出。这与您所拥有的基本相同,除了我在 debug
任务中使用列表来生成更清晰的输出。
- hosts: localhost
gather_facts: false
vars:
network_interfaces:
big_computer:
- interface: bond0.160
notes: note160
- interface: bond0.197
notes: note197
- interface: bond1
notes: 'bonded, numa1, broadcom devices'
tasks:
- debug:
msg:
- "ITEM: {{ item }}"
- "network_interfaces: {{ network_interfaces[computer_type] }}"
- "keys: {{ _keys }}"
- "vals: {{ _vals }}"
- "reused_val: {{ _reused_val }}"
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
_vals: "{{ network_interfaces[computer_type] }}" # returns a list
_reused_val: "{{ dict(_keys|zip(_vals)) }}" #1
运行 这会产生:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: ['bond0.160', 'bond0.197', 'bond1']",
"vals: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"reused_val: {'bond0.160': {'interface': 'bond0.160', 'notes': 'note160'}, 'bond0.197': {'interface': 'bond0.197', 'notes': 'note197'}, 'bond1': {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}}"
]
}
如果我 运行 使用 Ansible 2.7.5,我仍然没有看到您报告的任何错误(这就是为什么包含 运行nable example in your question),但我也没有得到与 2.10.8 相同的行为。我得到:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: ['bond0.160', 'bond0.197', 'bond1']",
"vals: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"reused_val: {'[': '[', \"'\": 's', 'b': \"'\", 'o': 'n', 'n': 'o', 'd': 't', '0': 'd', '.': '0', '1': 'e', '6': 'a', ',': \"'\", ' ': ',', '9': '1', '7': '6', ']': \"'\"}"
]
}
所以,除了最后一步,一切都很好。这里最大的问题是 Ansible 2.7.5 不能很好地处理字符串值以外的任何内容。当你写这个...
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list }}"
结果是一个 string 值,而不是一个列表,而在最近的
Ansible 的版本 _keys
变量 将 是一个列表。我们可以工作
通过显式序列化和反序列化所有内容来解决这个问题
to/from JSON:
- debug:
msg:
- "ITEM: {{ item }}"
- "network_interfaces: {{ network_interfaces[computer_type] }}"
- "keys: {{ _keys }}"
- "vals: {{ _vals }}"
- "reused_val: {{ _reused_val }}"
loop: [ " {{ computer_type }} " ]
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='interface')|list|to_json }}"
_vals: "{{ network_interfaces[computer_type]|to_json }}"
_reused_val: "{{ dict(_keys|from_json|zip(_vals|from_json)) }}"
这会产生与原始版本 2.10.8 相同的输出:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => (item= big_computer ) => {
"msg": [
"ITEM: big_computer ",
"network_interfaces: [{'interface': 'bond0.160', 'notes': 'note160'}, {'interface': 'bond0.197', 'notes': 'note197'}, {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}]",
"keys: [\"bond0.160\", \"bond0.197\", \"bond1\"]",
"vals: [{\"interface\": \"bond0.160\", \"notes\": \"note160\"}, {\"interface\": \"bond0.197\", \"notes\": \"note197\"}, {\"interface\": \"bond1\", \"notes\": \"bonded, numa1, broadcom devices\"}]",
"reused_val: {'bond0.160': {'interface': 'bond0.160', 'notes': 'note160'}, 'bond0.197': {'interface': 'bond0.197', 'notes': 'note197'}, 'bond1': {'interface': 'bond1', 'notes': 'bonded, numa1, broadcom devices'}}"
]
}
...但这是一个糟糕的解决方案,并且只是为了更清洁 升级。