如何将PyATS Ansible输出的JSON转换为指定格式CSV文件
多VRF嵌套JSON转CSV解决方案
典型JSON结构参考(适配你的report.json)
假设你的输出文件结构如下(若实际键名不同,对应修改后续代码即可):
{ "device_name": "sw01", "vrfs": { "default": { "interfaces": { "GigabitEthernet0/1": { "neighbors": [ {"ip": "192.168.1.2", "mac": "00:11:22:33:44:55"}, {"ip": "192.168.1.3", "mac": "00:11:22:33:44:66"} ] } } }, "vrf_red": { "interfaces": { "GigabitEthernet0/3": { "neighbors": [ {"ip": "10.0.0.2", "mac": "00:11:22:33:44:88"} ] } } } } }
方法一:Python脚本处理(推荐,逻辑清晰)
用Python遍历嵌套层级,直接生成目标CSV:
import json import csv # 读取JSON文件 with open('report.json', 'r') as json_file: data = json.load(json_file) # 定义CSV表头 csv_header = ['设备名', 'VRF名', '接口名', '邻居IP', 'MAC'] # 写入CSV with open('neighbor_report.csv', 'w', newline='', encoding='utf-8') as csv_file: writer = csv.writer(csv_file) writer.writerow(csv_header) # 适配单设备/多设备两种结构 devices = data if isinstance(data, list) else [data] for dev in devices: dev_name = dev.get('device_name', '未知设备') # 遍历每个VRF for vrf_name, vrf_info in dev.get('vrfs', {}).items(): # 遍历VRF下的接口 for intf_name, intf_info in vrf_info.get('interfaces', {}).items(): # 遍历接口下的邻居 for neighbor in intf_info.get('neighbors', []): ip = neighbor.get('ip', '无IP') mac = neighbor.get('mac', '无MAC') writer.writerow([dev_name, vrf_name, intf_name, ip, mac])
使用说明:
- 如果你的JSON是多设备数组(比如
[{}, {}, ...]),脚本自动适配,无需修改。 - 若JSON键名和示例不符(比如设备名是
hostname,邻居IP是address),修改代码中get()方法的参数即可。
方法二:Ansible Playbook内处理
如果要在Ansible流程中直接完成转换,可通过嵌套循环拆分结构,再生成CSV:
- name: 转换多VRF JSON为CSV hosts: localhost vars: report_data: "{{ lookup('file', 'report.json') | from_json }}" csv_header: "设备名,VRF名,接口名,邻居IP,MAC\n" csv_rows: [] tasks: - name: 遍历VRF、接口、邻居生成CSV行 set_fact: csv_rows: "{{ csv_rows + [ '%s,%s,%s,%s,%s' | format(dev_name, vrf, intf, neigh.ip, neigh.mac) ] }}" loop: "{{ report_data.vrfs | dict2items }}" loop_control: loop_var: vrf_item vars: dev_name: "{{ report_data.device_name }}" vrf: "{{ vrf_item.key }}" with_subelements: - "{{ vrf_item.value.interfaces | dict2items | json_query('[].{intf: key, neighbors: value.neighbors}') }}" - neighbors vars: intf: "{{ item.0.intf }}" neigh: "{{ item.1 }}" - name: 拼接CSV内容 set_fact: csv_content: "{{ csv_header + '\n'.join(csv_rows) }}" - name: 写入CSV文件 copy: content: "{{ csv_content }}" dest: "./neighbor_report.csv"
注意:如果你的JSON结构更复杂,Ansible的嵌套循环容易出问题,优先用Python脚本方案。
内容的提问来源于stack exchange,提问作者everlearning777
相关产品推荐
相关产品推荐

