在Ansible中对字典列表进行map和filter操作

114次阅读
没有评论

问题描述

有一个包含字典的列表,想在Ansible playbook中对其进行map和filter操作。具体要求是,对列表中的每个字典进行操作,如果字典中不存在’sudo’键,则添加一个’home’键,并设置其值为’/home/字典中的name值/’。用户想知道如何在Ansible playbook中实现这个操作,并希望将结果保存在一个变量中以供后续使用。用户还想知道是否可以使用with_items来实现,并询问是否可以使用register来保存输出结果。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

在Ansible playbook中,可以使用自定义过滤器来实现对字典列表的map和filter操作。首先,需要创建一个自定义过滤器来实现所需的操作。以下是一个示例的自定义过滤器代码:

# filter_plugins/addhomedir.py
class FilterModule:
    @staticmethod
    def add_home(_val):
        return [dict(user, home='/home/{0}/'.format(user['name'])) for user in
                _val if 'sudo' not in user]
    def filters(self):
        return {
            'add_homedir': self.add_home
        }

在上面的示例中,我们定义了一个名为add_home的自定义过滤器,它接受一个字典列表作为输入,并返回一个新的字典列表。在新的字典列表中,如果字典中不存在’sudo’键,则添加一个’home’键,并设置其值为’/home/字典中的name值/’。
接下来,在Ansible playbook中使用这个自定义过滤器。以下是一个示例的Ansible playbook代码:

# test1.yml
---
hosts: localhost
vars:
  users:
    - name: alice
      sudo: yes
    - name: bob
    - name: charlie
tasks:
  - debug:
      msg: "{{ users | add_homedir | list }}"

在上面的示例中,我们使用add_homedir过滤器对users变量进行了map和filter操作,并将结果打印出来。
请注意,使用自定义过滤器可能会增加复杂性,并且需要确保自定义过滤器的正确性和可靠性。

方案2

另一种方法是使用set_factsloop来实现所需的操作。以下是一个示例的Ansible playbook代码:

# test2.yml
---
hosts: localhost
vars:
  users:
    - name: alice
      sudo: yes
    - name: bob
    - name: charlie
tasks:
  - user:
      name: "{{ item['name'] }}"
      create_home: true
      home: "{{ '/home/{}/'.format(item['name']) }}"
    when: "'sudo' not in item"
    loop: "{{ users }}"

在上面的示例中,我们使用loop循环遍历users变量中的每个字典,并使用when条件判断是否满足过滤条件。如果满足条件,则使用user模块创建用户,并设置home属性为’/home/字典中的name值/’。
请注意,使用set_factsloop可以更直接地实现所需的操作,但可能会导致代码重复和冗长。

总结

在Ansible playbook中,可以使用自定义过滤器或set_factsloop来对字典列表进行map和filter操作。使用自定义过滤器可以更灵活地实现复杂的操作,但可能会增加复杂性。使用set_factsloop可以更直接地实现简单的操作,但可能会导致代码重复和冗长。根据具体需求和代码风格,选择合适的方法来实现所需的操作。

正文完