dictionary - Ansible 过滤器将特定键从字典中提取到另一个字典中
问题描述
使用 nios 查找模块,我可以获得记录的字典列表
- set_fact:
records: "{{ lookup('community.general.nios', 'record:a', filter={'name~': 'abc.com'}) }}"
这会返回类似
- ref: record:a/someBase64:name/view
name: abc.com
ipv4addr: 1.2.3.4
view: default
- ref: record:a/someBase64:name/view
name: def.abc.com
ipv4addr: 1.2.3.5
view: default
- ref: record:a/someBase64:name/view
name: ghi.abc.com
ipv4addr: 1.2.3.6
view: default
我想将其转换为 dicts 的 dict{name}: a: {ipv4addr}
abc.com:
a: 1.2.3.4
def.abc.com:
a: 1.2.3.5
ghi.abc.com:
a: 1.2.3.6
这样我就可以运行类似的查找来获取其他记录类型(例如 cname)并将它们组合到同一个字典中。items2dict 过滤器似乎已经完成了一半,但我想要在a:
下面添加键。
解决方案
如果您只是想要一个将名称映射到 ipv4 地址的字典,例如:
{
"abc.com": "1.2.3.4",
...
}
你可以使用一个简单的json_query
表达式。看一下
set_fact
以下示例中的任务:
- hosts: localhost
gather_facts: false
vars:
data:
- ref: record:a/someBase64:name/view
name: abc.com
ipv4addr: 1.2.3.4
view: default
- ref: record:a/someBase64:name/view
name: def.abc.com
ipv4addr: 1.2.3.5
view: default
- ref: record:a/someBase64:name/view
name: ghi.abc.com
ipv4addr: 1.2.3.6
view: default
tasks:
- set_fact:
name_map: "{{ dict(data|json_query('[].[name, ipv4addr]')) }}"
- debug:
var: name_map
运行该剧本将输出:
PLAY [localhost] ***************************************************************
TASK [set_fact] ****************************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"name_map": {
"abc.com": "1.2.3.4",
"def.abc.com": "1.2.3.5",
"ghi.abc.com": "1.2.3.6"
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
您可以使用类似的结构来提取其他数据(例如cname
记录)。这将为您提供每种数据类型的字典,而不是按照您的要求将所有内容合并到一个字典中,但这最终可能会更容易使用。
要获得您想要的结构,您可以set_fact
在循环中使用,如下所示:
- hosts: localhost
vars:
data:
- ref: record:a/someBase64:name/view
name: abc.com
ipv4addr: 1.2.3.4
view: default
- ref: record:a/someBase64:name/view
name: def.abc.com
ipv4addr: 1.2.3.5
view: default
- ref: record:a/someBase64:name/view
name: ghi.abc.com
ipv4addr: 1.2.3.6
view: default
gather_facts: false
tasks:
- set_fact:
name_map: "{{ name_map|combine({item.name: {'a': item.ipv4addr}}) }}"
loop: "{{ data }}"
vars:
name_map: {}
- debug:
var: name_map
这将产生:
PLAY [localhost] ***************************************************************
TASK [set_fact] ****************************************************************
ok: [localhost] => (item={'ref': 'record:a/someBase64:name/view', 'name': 'abc.com', 'ipv4addr': '1.2.3.4', 'view': 'default'})
ok: [localhost] => (item={'ref': 'record:a/someBase64:name/view', 'name': 'def.abc.com', 'ipv4addr': '1.2.3.5', 'view': 'default'})
ok: [localhost] => (item={'ref': 'record:a/someBase64:name/view', 'name': 'ghi.abc.com', 'ipv4addr': '1.2.3.6', 'view': 'default'})
TASK [debug] *******************************************************************
ok: [localhost] => {
"name_map": {
"abc.com": {
"a": "1.2.3.4"
},
"def.abc.com": {
"a": "1.2.3.5"
},
"ghi.abc.com": {
"a": "1.2.3.6"
}
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
推荐阅读
- arrays - 如果行匹配,则将列添加到具有来自另一个数组中某个位置的值的数组
- python - 'file' 是什么意思
"' 代表 python 调试器和回溯? - r - 我如何模拟首先选择随机玩家,然后重复该序列?
- java - 有没有一种简单的方法可以从 Java 中相同接口的多个实现创建级联函数?
- c# - 如何在 .NET 中列出支持的 C# 语言版本
- c# - 在我的 Mac m1 终端中找不到 dotnet 命令
- reactjs - 动态更改 animateCamera 俯仰和缩放属性不起作用
- sql - 随着时间的推移选择每个不同的值,而不会丢失两者之间的 NULL
- java - 我的代码超过了时间限制。如何让我的代码更加优化?
- java - 如何在 PDF 查看器中正确组织页面呈现