Ansible 将对象的可转换列表减少为单个串的串联对象值

Ansible 将对象的可转换列表减少为单个串的串联对象值,ansible,Ansible,我试图解析elasticache_factsansible模块的输出,以“addr1:port1 addr2:port2…”格式的字符串形式提取memcached节点的IP和端口(我想将此字符串存储在应用程序中使用的配置映射中) 基本上,我想从DICT列表中选取两个字段“地址”和“端口”,如下所示: list1: - endpoint: address: "addr1" port: "port1" - endpoint: address: "addr2" po

我试图解析
elasticache_facts
ansible模块的输出,以“addr1:port1 addr2:port2…”格式的字符串形式提取memcached节点的IP和端口(我想将此字符串存储在应用程序中使用的配置映射中)

基本上,我想从DICT列表中选取两个字段“地址”和“端口”,如下所示:

list1:
- endpoint: 
    address: "addr1"
    port: "port1"
- endpoint: 
    address: "addr2"
    port: "port2"
# register the output of the facts to something I know
elasticache_facts:
  region: "{{ terraform.region }}"
  name: "{{ cluster }}-{{ env }}"
register: elasticache

#declare an empty var in vars file to be used as accumulator
memcache_hosts: ""

# iterate through the list of nodes and append the fields to my string; I will have some extra spaces(separators) but that's ok
set_fact:
  memcache_hosts: "{{ memcache_hosts }} {{item.endpoint.address}}:{{item.endpoint.port}}"
with_items: "{{ elasticache.elasticache_clusters[0].cache_nodes}}"
并像上面那样连接它们

我有一个丑陋的解决方案是这样的:

list1:
- endpoint: 
    address: "addr1"
    port: "port1"
- endpoint: 
    address: "addr2"
    port: "port2"
# register the output of the facts to something I know
elasticache_facts:
  region: "{{ terraform.region }}"
  name: "{{ cluster }}-{{ env }}"
register: elasticache

#declare an empty var in vars file to be used as accumulator
memcache_hosts: ""

# iterate through the list of nodes and append the fields to my string; I will have some extra spaces(separators) but that's ok
set_fact:
  memcache_hosts: "{{ memcache_hosts }} {{item.endpoint.address}}:{{item.endpoint.port}}"
with_items: "{{ elasticache.elasticache_clusters[0].cache_nodes}}"
是否有一些不那么丑陋的方法将列表过滤到所需的格式

也许有一个我不知道的魔法过滤器

我还可以获得两个列表,一个是主机列表,一个是端口列表,将它们压缩,然后用它制作一个dict,但我只找到了一些难看的to_json,然后用regex将其制作成字符串。 我也在考虑用python编写一个自定义过滤器,但似乎做得太过分了


谢谢你的帮助

这里有两种方法可以实现您想要的目标:

#!/usr/bin/env ansible-playbook
---
- name: Lets munge some data
  hosts: localhost
  become: false
  gather_facts: false
  vars:
    my_list:
    - address: '10.0.0.0'
      port: '80' 
    - address: '10.0.0.1'
      port: '88' 
  tasks:
  - name: Quicky and dirty inline jinja2
    debug: 
      msg: "{% for item in my_list %}{{ item.address }}:{{ item.port }}{% if not loop.last %} {% endif %}{% endfor %}"

  # Note the to_json | from_json workaround for https://github.com/ansible/ansible/issues/27299
  - name: Using JSON Query
    vars:
      jmes_path: "join(':', [address, port])"
    debug: 
      msg: "{{ my_list | to_json | from_json | map('json_query', jmes_path) | join(' ') }}"
上述产出:

PLAY [Lets munge some data] **********************************************************************************************************************************

TASK [Quicky and dirty inline jinja2] ************************************************************************************************************************
ok: [localhost] => {
    "msg": "10.0.0.0:80 10.0.0.1:88"
}

TASK [Using JSON Query] **************************************************************************************************************************************
ok: [localhost] => {
    "msg": "10.0.0.0:80 10.0.0.1:88"
}

PLAY RECAP ***************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

谢谢!它工作得很好!第一个看起来非常直截了当,可读性很强。我会选那个。我有点惭愧我自己没有找到它。我知道有一些原始的jinja2格式,但不确定语法。我写了一个python过滤器,因为我想“黄金工具”很复杂。但这显然更优雅。第二个似乎是纯粹的黑魔法:)我正在阅读您为to_json提供的链接。祝你一切顺利!不幸的是,我不能给你投票:“谢谢你的反馈!那些声誉低于15的人所投的票会被记录下来,但不会改变公开显示的帖子分数。”