我正在尝试为绑定建立反向查找(PTR)记录。
我有一个 CSV 文件,其中 IP 和主机名字段已加载到字典中(来自 read_csv),所以我猜它实际上是一个字典列表:
ok: [localhost] => {
"msg": [
{
"changed": false,
"dict": {},
"failed": false,
"list": [
{
"hostname": "host1",
"ip": "10.32.1.32"
},
{
"hostname": "host2",
"ip": "10.50.6.71"
},
{
"hostname": "host3",
"ip": "10.36.254.41"
},
{
"hostname": "host4",
"ip": "10.36.254.42"
}
]
},
]
}
我有一个从上述字典中得出的唯一的反转最后两个八位字节列表:
ok: [localhost] => {
"msg": [
[
"32.10",
"50.10",
"36.10"
],
]
}
我想要的是一个如下所示的新字典(格式可能不正确,请原谅):
{
"32.10":
{
"hostname": "host1",
"ip": "10.32.1.32"
},
"50.10":
{
"hostname": "host2",
"ip": "10.50.6.71"
},
"36.10":
{
"hostname": "host3",
"ip": "10.36.254.41"
},
{
"hostname": "host4",
"ip": "10.36.254.42"
}
}
新的“超级”字典应该只包含匹配网络的 IP + 主机名条目(例如,所有 10.36.xx 条目都应位于“36.10”下)。
从这个新的字典中,我应该能够在模板中循环它来生成 PTR 记录。
我不知道如何合并这两个数据结构。:-/
谢谢你!
1
最佳答案
2
您可以使用来构建最终的词典。
像这样:
- hosts: localhost
gather_facts: false
vars:
results:
- hostname: host1
ip: 10.32.1.32
- hostname: host2
ip: 10.50.6.71
- hostname: host3
ip: 10.36.254.41
- hostname: host4
ip: 10.36.254.42
tasks:
- loop: "{{ results }}"
vars:
reversed: {}
key: >-
{{"{}.{}".format(*((item.ip.split('.'))[:2]|reverse))}}
set_fact:
reversed: >-
{{
reversed|combine({key: reversed.get(key, []) + [item]}, list_merge='append_rp')
}}
- debug:
var: "reversed"
我们使用以下表达式构造字典键:
{{"{}.{}".format(*((item.ip.split('.'))[:2]|reverse))}}
这会将“abcd”之类的内容转换为“ba”。我们使用它 + 过滤器combine
+过滤器list_merge
的选项combine
来获取最终的数据结构;上述剧本产生了以下输出:
TASK [debug] *******************************************************************
ok: [localhost] => {
"reversed": {
"32.10": [
{
"hostname": "host1",
"ip": "10.32.1.32"
}
],
"36.10": [
{
"hostname": "host3",
"ip": "10.36.254.41"
},
{
"hostname": "host4",
"ip": "10.36.254.42"
}
],
"50.10": [
{
"hostname": "host2",
"ip": "10.50.6.71"
}
]
}
}
1
-
larsks,我欠你太多了!非常感谢!它运行完美。唯一的问题是它不能与 ansible v2.9.6(Ubuntu 20.04)一起使用,我不得不升级到最新的 v2.12.2,它运行得很好。这正是我需要的。谢谢!
–
|
- 有了钥匙
keys: ['32.10', '50.10', '36.10']
- 选择值
vals: |
{% for k in keys|map('split', '.')|map('reverse')|map('join', '.') %}
- {{ results | selectattr('ip', 'match', k) }}
{% endfor %}
给出
vals: |-
- [{'hostname': 'host1', 'ip': '10.32.1.32'}]
- [{'hostname': 'host2', 'ip': '10.50.6.71'}]
- [{'hostname': 'host3', 'ip': '10.36.254.41'}, {'hostname': 'host4', 'ip': '10.36.254.42'}]
- 创建词典
rev: "{{ dict(keys|zip(vals|from_yaml)) }}"
给出你想要的
rev:
'32.10':
- {hostname: host1, ip: 10.32.1.32}
'36.10':
- {hostname: host3, ip: 10.36.254.41}
- {hostname: host4, ip: 10.36.254.42}
'50.10':
- {hostname: host2, ip: 10.50.6.71}
笔记:
- 完整测试剧本的示例
- hosts: localhost
vars:
keys: ['32.10', '50.10', '36.10']
results:
- {hostname: host1, ip: 10.32.1.32}
- {hostname: host2, ip: 10.50.6.71}
- {hostname: host3, ip: 10.36.254.41}
- {hostname: host4, ip: 10.36.254.42}
vals: |
{% for k in keys|map('split', '.')|map('reverse')|map('join', '.') %}
- {{ results | selectattr('ip', 'match', k) }}
{% endfor %}
rev: "{{ dict(keys|zip(vals|from_yaml)) }}"
tasks:
- debug:
var: vals
- debug:
var: rev | to_yaml
- (可选)将列表转换为字典
rev: "{{ dict(keys |
zip(vals |
from_yaml |
map('items2dict',
key_name='hostname',
value_name='ip'))) }}"
给出
rev:
'32.10':
host1: 10.32.1.32
'36.10':
host3: 10.36.254.41
host4: 10.36.254.42
'50.10':
host2: 10.50.6.71
, 或者
rev: "{{ dict(keys |
zip(vals |
from_yaml |
map('items2dict',
value_name='hostname',
key_name='ip'))) }}"
给出
rev:
'32.10':
10.32.1.32: host1
'36.10':
10.36.254.41: host3
10.36.254.42: host4
'50.10':
10.50.6.71: host2
|
–
|