使用JMESPath和/或Ansible组合JSON项目

问题描述

我有一本Ansible剧本,它查询设备清单API并获取一个JSON结果,该结果包含许多采用以下格式的记录:

{
    "service_level": "Test","tags": [
        "Application:MyApp1"
    ],"fqdn": "matestsvcapp1.vipcustomers.com","ip": "172.20.11.237","name": "matestsvcapp1.vipcustomers.com"
}

然后我遍历这些烦人的任务,以查询我关心的每个IP地址的JSON结果:

- name: Set JMESQuery
  set_fact:
    jmesquery: "Devices[?ip_addresses[?ip.contains(@,'{{ ip_to_query }}' )]].{ip: '{{ ip_to_query }}',tags: tags[],service_level: service_level }"

- name: Store values
  set_fact:
    inven_results: "{{ (inven_results| default([])) + (existing_device_info.json | to_json | from_json | json_query(jmesquery)) }}"

然后我继续在ansible中执行其他任务,将这些数据推送到其他系统中,一切正常。

但是,我刚收到管理层的要求,他们希望在将数据放入其中的某些系统中看到“服务级别”表示为标签。因此,我需要将'tags'和'service_level'项目组合在一起,结果如下所示:

{ 
    "tags": [
        "Application:MyApp1","service_level:Test"
    ],"name": "matestsvcapp1.vipcustomers.com"
}

我尝试使用join function修改JMESPath查询以将结果结合在一起,并尝试使用combine or map以“可调整的”方式进行操作,但是我都无法那些都可以工作。

解决此问题的正确方法有何想法?预先感谢!

注意:“标签”是一个字符串列表,即使以key:value格式编写,它实际上也只是一个字符串。

解决方法

要添加两个数组,您可以使用const uri = 'mongodb://localhost:27017'; const dbName = 'myDB'; const MongoClient = require('mongodb').MongoClient; async function main() { const client = new MongoClient(uri); await client.connect(); const session = client.startSession(); try { await session.withTransaction(async () => { const orders = client.db(dbName).collection('orders'); const money = client.db(dbName).collection('money'); let doc = await orders.findOne({orderID: 123}); if (doc && doc.status === 1) { console.log("Money Already Added"); return } await orders.updateOne({orderID: 123},{'$set': {status: 1}}); await money.insertOne({orderID: 123,userID: 100,amount: 300},{session}); console.log("Money added"); }); await session.commitTransaction(); } catch (e) { console.log(e); } finally { await session.endSession(); await client.close(); } } main() 运算符,如下所示:

+

结果:

ansible localhost -m debug -a 'msg="{{ b + ["String3"] }}"' -e '{"b":["String1","String2"]}'

因此,如果我将您的json代码作为localhost | SUCCESS => { "msg": [ "String1","String2","String3" ] } ,则可以运行

test.json

结果:

ansible localhost -m debug -a 'msg="{{ tags + ["service_level:" ~ service_level ] }}"' -e @test.json

基于此知识,您可以使用set_fact将此新数组放入变量中以供以后使用。