我需要检查两个子词典中是否没有使用相同的端口。
my_dict:
first:
redis:
port: 1234
second:
redis:
port: 1235
third:
redis:
port: 1234
在任务中,我可以使用以下内容:
- debug:
msg: '{{ my_dict | dict2items | map(attribute="value.redis.port") | list }}'
返回:
['1234', '1235', '1234']
我需要的是一些只过滤重复项的方法。所以我得到:
['1234', '1234']
回。
基本上,我需要检查端口是否重复,以及它们是否应用检查的失败任务,并显示导致冲突的项目。
有任何想法吗?
@stacksonstacks链接到的过滤器在这种特定情况下没有用,因为端口总数总是相同的,只有它们的数量发生变化:set([1,2,2,2]) == set([1,2])
总是True
所以我们真正想要的是按端口分组,并查找长度大于1的子节点。然后,我们可以提取导致冲突的密钥的名称以便报告它们。
tasks:
- set_fact:
bogus: >-
{%- for port_num, dicts in (my_dict | dict2items | groupby('value.redis.port'))
if (dicts|length) > 1 -%}
{{ dicts | map(attribute='key') | list }}
{%- endfor -%}
- debug: var=item
when: '{{ (bogus | length) > 0 }}'
with_items: '{{ bogus }}'
非常感谢你的帮助马修!
我觉得有点太难看有事实等等,所以我决定快速制作一个过滤插件......或者更重要的是,添加mathstuff.py文件。
添加:
def duplicate(a):
if isinstance(a, collections.Hashable):
c = set(a)
else:
s = {}
c = []
for x in a:
if x not in s:
s[x] = 1
else:
if s[x] == 1:
c.append(x)
s[x] += 1
return c
在文档的主体中,并添加:
'duplicate': duplicate,
进入:
class FilterModule(object):
''' Ansible math jinja2 filters '''
def filters(self):
filters = {
所以Jinja2
知道过滤器。
当我有空的时候我会发出一个拉取请求,但是如果有人在此期间找到这个请求,或者如果你不想/不能更新Ansible,那么下面的工作很有用:
- debug:
msg: '{{ my_dict | dict2items | map(attribute="value.redis.port") | list | duplicate }}'
返回:
['1234']
我用更大的样本进行了一些测试,它按预期工作。
请享用!