Ansible 数据操作 - 列表转换

Ansible data manipulation - List trasformation

我需要将一个简单列表转换为一个复杂列表。

简单的看起来像这样:

customers:
  - customer01-node01.private.foo.it
  - customer02-node01.private.foo.it
  - customer04-node03.private.foo.it
  - customer03-node02.private.foo.it
  - customer05-node02.private.foo.it
  - customer01-node04.private.foo.it
  - customer02-node04.private.foo.it
  - customer04-node06.private.foo.it
  - customer03-node05.private.foo.it
  - customer05-node05.private.foo.it

我正在尝试找到一种方法来获得一个复杂的节点,按客户对节点进行分组。 我要找的最终结果是这个:

customers_list:
  - customer: customer01
    nodes:
      - node01.private.foo.it
      - node04.private.foo.it
  - customer: customer02
    nodes:
      - node01.private.foo.it
      - node04.private.foo.it
  - customer: customer03
    nodes:
      - node02.private.foo.it
      - node05.private.foo.it
  - customer: customer04
    nodes:
      - node03.private.foo.it
      - node06.private.foo.it
  - customer: customer05
    nodes:
      - node02.private.foo.it
      - node05.private.foo.it

解析数据

    - set_fact:
        customers_parsed: "{{ customers_parsed|d([]) + [{'customer': _customer,
                                                         'node': _node}] }}"
      loop: "{{ customers }}"
      vars:
        _customer: "{{ item.split('-')|first }}"
        _node: "{{ item.split('-')|last }}"

给予

  customers_parsed:
  - customer: customer01
    node: node01.private.foo.it
  - customer: customer02
    node: node01.private.foo.it
  - customer: customer04
    node: node03.private.foo.it
  - customer: customer03
    node: node02.private.foo.it
  - customer: customer05
    node: node02.private.foo.it
  - customer: customer01
    node: node04.private.foo.it
  - customer: customer02
    node: node04.private.foo.it
  - customer: customer04
    node: node06.private.foo.it
  - customer: customer03
    node: node05.private.foo.it
  - customer: customer05
    node: node05.private.foo.it

然后 group the items by 属性 customer 并连接列表

    - set_fact:
        customers_list: "{{ customers_list|d([]) + [{'customer': item.0,
                                                     'nodes': _nodes}] }}"
      loop: "{{ customers_parsed|groupby('customer') }}"
      vars:
        _nodes: "{{ item.1|map(attribute='node')|list }}"

给予

  customers_list:
  - customer: customer01
    nodes:
    - node01.private.foo.it
    - node04.private.foo.it
  - customer: customer02
    nodes:
    - node01.private.foo.it
    - node04.private.foo.it
  - customer: customer03
    nodes:
    - node02.private.foo.it
    - node05.private.foo.it
  - customer: customer04
    nodes:
    - node03.private.foo.it
    - node06.private.foo.it
  - customer: customer05
    nodes:
    - node02.private.foo.it
    - node05.private.foo.it

您可以使用自定义过滤器:

您在剧本文件夹中创建了一个文件夹 filter_plugins(我已将文件命名为 myfilters.py 并且过滤器 自定义)

myfilters.py 文件夹 filter_plugins:

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'custom': self.custom
        }

    def custom(self, listvar):
        result = {}
        final = []
        for it in listvar:
            f, s = it.split('-')
            if f in result:
                result[f].append(s)
            else:
                result[f] = [s]
        
        for k in result:
            final.append({'customer':k, 'nodes': result[k]})

        return final

剧本:

---
- hosts: localhost
  vars:
    customers:
      - customer01-node01.private.foo.it
      - customer02-node01.private.foo.it
      - customer04-node03.private.foo.it
      - customer03-node02.private.foo.it
      - customer05-node02.private.foo.it
      - customer01-node04.private.foo.it
      - customer02-node04.private.foo.it
      - customer04-node06.private.foo.it
      - customer03-node05.private.foo.it
      - customer05-node05.private.foo.it
  tasks:
    - name: parsevar
      set_fact: 
        customers_list: "{{ customers | custom }}"
        
    - name: display
      debug: 
        msg: "{{ customers_list }}"

结果:

ok: [localhost] => {
    "msg": [
        {
            "customer": "customer01",
            "nodes": [
                "node01.private.foo.it",
                "node04.private.foo.it"
            ]
        },
        {
            "customer": "customer02",
            "nodes": [
                "node01.private.foo.it",
                "node04.private.foo.it"
            ]
        },
        {
            "customer": "customer04",
            "nodes": [
                "node03.private.foo.it",
                "node06.private.foo.it"
            ]
        },
        {
            "customer": "customer03",
            "nodes": [
                "node02.private.foo.it",
                "node05.private.foo.it"
            ]
        },
        {
            "customer": "customer05",
            "nodes": [
                "node02.private.foo.it",
                "node05.private.foo.it"
            ]
        }
    ]
}

使用自定义过滤器的优势:您只有一个任务来转换数据