如何从JSON输出在Ansible中构建指定结构的字典
Ansible 任务结果结构化处理方案
问题场景
我有一个针对2个及以上URL执行的Ansible任务,每个URL返回的变量结构一致但具体值不同,任务的JSON注册表数据如下:
{ "msg": { "results": [ { "url": "http://0.0.0.1:xxx1", "othervar": "othervar", "othervar2": "othervar2", "json": { "messages": [ { "message": "This is message number 1", "message2": "This is message2 number 1" }, { "message": "This is message number 2", "message2": "This is message2 number 2" }, { "message": "This is message number 3", "message2": "This is message2 number 3" } ] } }, { "url": "http://0.0.0.2:xxx2", "othervar": "othervar", "othervar2": "othervar2", "json": { "messages": [ { "message": "This is message number 1", "message2": "This is message2 number 1" }, { "message": "This is message number 2", "message2": "This is message2 number 2" }, { "message": "This is message number 3", "message2": "This is message2 number 3" } ] } } ] } }
预期结果
需要提取url、message和message2变量,整合成以下两种结构之一:
选项1:按URL分组
{ "message": [ { "url": "http://0.0.0.1:xxx1", "content": [ { "message": "This is message number 1", "message2": "This is message2 number 1" }, { "message": "This is message number 2", "message2": "This is message2 number 2" }, { "message": "This is message number 3", "message2": "This is message2 number 3" } ] }, { "url": "http://0.0.0.2:xxx2", "content": [ { "message": "This is message number 1", "message2": "This is message2 number 1" }, { "message": "This is message number 2", "message2": "This is message2 number 2" }, { "message": "This is message number 3", "message2": "This is message2 number 3" } ] } ] }
选项2:展开所有消息条目
{ "message": [ { "url": "http://0.0.0.1:xxx1", "message": "This is message number 1", "message2": "This is message2 number 1" }, { "url": "http://0.0.0.1:xxx1", "message": "This is message number 2", "message2": "This is message2 number 2" }, { "url": "http://0.0.0.1:xxx1", "message": "This is message number 3", "message2": "This is message2 number 3" }, { "url": "http://0.0.0.2:xxx2", "message": "This is message number 1", "message2": "This is message2 number 1" }, { "url": "http://0.0.0.2:xxx2", "message": "This is message number 2", "message2": "This is message2 number 2" }, { "url": "http://0.0.0.2:xxx2", "message": "This is message number 3", "message2": "This is message2 number 3" } ] }
实现方案
生成选项1结构
使用set_fact结合Jinja2循环,遍历每个URL的结果,提取url并将json.messages作为content字段:
- name: 构建选项1的结构化数据 set_fact: option1_result: message: >- {% set output = [] %} {% for res in msg.results %} {% set _ = output.append({'url': res.url, 'content': res.json.messages}) %} {% endfor %} {{ output }}
生成选项2结构
同样用set_fact嵌套循环,先遍历每个URL结果,再遍历该URL下的所有消息条目,将url与每个消息字典合并:
- name: 构建选项2的结构化数据 set_fact: option2_result: message: >- {% set output = [] %} {% for res in msg.results %} {% for msg_item in res.json.messages %} {% set _ = output.append({'url': res.url} | combine(msg_item)) %} {% endfor %} {% endfor %} {{ output }}
执行完上述任务后,option1_result和option2_result变量就分别对应两种预期结构,可直接在后续任务中调用。
内容的提问来源于stack exchange,提问作者asking
相关产品推荐
相关产品推荐

