在Ansible中将yaml哈希值转换为json哈希键

时间:2019-04-12 09:53:41

标签: json ansible yaml ansible-facts jmespath

我正在尝试让Ansible将哈希数组转换为键值对列表,其中键是来自第一个哈希的值之一,而值是与第一个哈希不同的值。

一个例子会有所帮助。

我要转换:-

TASK [k8s_cluster : Cluster create | debug result of private ec2_vpc_subnet_facts] ***
ok: [localhost] => {
    "result": {
        "subnets": [
            {
                "availability_zone": "eu-west-1c", 
                "subnet_id": "subnet-cccccccc", 
            }, 
            {
                "availability_zone": "eu-west-1a", 
                "subnet_id": "subnet-aaaaaaaa", 
            }, 
            {
                "availability_zone": "eu-west-1b", 
                "subnet_id": "subnet-bbbbbbbb", 
            }
        ]
    }
}

进入

eu-west-1a: subnet-aaaaaaaa   
eu-west-1b: subnet-bbbbbbbb    
eu-west-1c: subnet-cccccccc 

我尝试过result.subnets | map('subnet.availability_zone': 'subnets.subnet_id')(根本不起作用)和json_query('subnets[*].subnet_id',它们只是挑选出subnet_id值并将它们放入列表中。

我想我可以使用Zip和Hash in Ruby来做到这一点,但我不知道如何在Ansible中或更具体地在Jmespath中进行这项工作。

2 个答案:

答案 0 :(得分:1)

我已经生成了以下列表,我将在生成的列表中添加一行(首先要共享)

---
- name: play
  hosts: localhost
  tasks:
    - name: play
      include_vars: vars.yml

    - name: debug
      debug:
        msg: "{% for each in subnets %}{{ each.availability_zone }}:{{ each.subnet_id  }}{% raw %},{% endraw %}{% endfor %}"

输出--->

ok: [localhost] => {
    "msg": "eu-west-1c:subnet-cccccccc,eu-west-1a:subnet-aaaaaaaa,eu-west-1b:subnet-bbbbbbbb,"
}

答案 1 :(得分:0)

Jmespath不允许在多重选择哈希中使用动态名称。我发现an extension to jmespath允许通过使用键引用来执行此操作,但这不是纯jmespath实现的一部分,也不是可实现的。

要做到这一点,您将必须创建一个新变量并在其中填充一个循环。可能还有其他使用其他过滤器的方法,但这是我想出的解决方案:

extern char **environ;
char **e; for(e=environ; *e; e++) {}
size_t envsz =  ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);