在Ansible Dictionary中查找重复项

问题描述 投票:0回答:2

我需要检查两个子词典中是否没有使用相同的端口。

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']

回。

基本上,我需要检查端口是否重复,以及它们是否应用检查的失败任务,并显示导致冲突的项目。

有任何想法吗?

python ansible jinja2
2个回答
0
投票

@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 }}'

0
投票

非常感谢你的帮助马修!

我觉得有点太难看有事实等等,所以我决定快速制作一个过滤插件......或者更重要的是,添加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']

我用更大的样本进行了一些测试,它按预期工作。

请享用!

© www.soinside.com 2019 - 2024. All rights reserved.