如何将Ansible Playbook输出转换为可解析的JSON/Python字典?
把Ansible Playbook输出转为结构化JSON的方法
一、在Ansible Playbook中直接生成目标格式
直接修改现有Playbook,添加数据整理任务,一步到位输出符合要求的JSON结构,无需事后解析:
--- - name: Cisco Switch Configuration hosts: eleni gather_facts: false become: true vars: ansible_network_os: ios ansible_connection: network_cli tasks: - name: 获取设备uptime信息 ios_command: commands: - show version | i uptime register: show_output - name: 汇总为IP-uptime键值对字典 set_fact: uptime_dict: "{{ uptime_dict | default({}) | combine( { inventory_hostname: show_output.stdout | join('\n') } ) }}" delegate_to: localhost run_once: true - name: 输出结构化JSON debug: var: uptime_dict | to_nice_json delegate_to: localhost run_once: true # 可选:将结果保存到本地文件 - name: 保存JSON到本地 copy: content: "{{ uptime_dict | to_nice_json }}" dest: "./switch_uptime.json" delegate_to: localhost run_once: true
关键说明:
set_fact任务通过combine把每个主机的IP(inventory_hostname)和uptime内容(show_output.stdout用join('\n')合并多行)汇总成一个字典delegate_to: localhost和run_once: true确保只在本地执行一次汇总操作,避免重复生成数据
二、解析已有的Ansible原始输出(Python脚本)
如果已经拿到了Ansible控制台的原始输出,用Python脚本解析并转换为目标JSON:
import re import json # 替换为你的Ansible原始输出内容 raw_ansible_output = """ PLAY [Cisco Switch Configuration] ******************************************************************************************************************************************************************************************** TASK [show uptime and show interface] **************************************************************************************************************************************************************************************** ok: [10.135.147.138] ok: [10.135.147.205] ok: [10.135.147.134] TASK [Display raw output] **************************************************************************************************************************************************************************************************** ok: [10.135.147.205] => { "show_output.stdout": [ "sr12sw0013 uptime is 2 weeks, 5 days, 3 hours, 1 minute" ] } ok: [10.135.147.134] => { "show_output.stdout": [ "sr12swp004 uptime is 2 weeks, 5 days, 3 hours, 1 minute\nSwitch uptime : 2 weeks, 5 days, 3 hours, 3 minutes" ] } ok: [10.135.147.138] => { "show_output.stdout": [ "sr12swp008 uptime is 2 weeks, 5 days, 3 hours, 1 minute" ] } """ # 正则匹配每个主机的IP和对应的uptime内容 match_pattern = r'ok: \[(.*?)\] => \{.*?"show_output.stdout": \[(.*?)\]\}' matches = re.finditer(match_pattern, raw_ansible_output, re.DOTALL) result_dict = {} for match in matches: ip_addr = match.group(1).strip() # 处理字符串转义,还原换行符并去除多余引号 uptime_content = match.group(2).strip().strip('"').replace(r'\n', '\n') result_dict[ip_addr] = uptime_content # 输出格式化后的JSON print(json.dumps(result_dict, indent=4))
关键说明:
- 用
re.DOTALL让正则支持跨行匹配,精准提取每个主机的IP和uptime内容 - 处理字符串中的转义字符,确保输出内容和原始一致
内容的提问来源于stack exchange,提问作者R__raki__
相关产品推荐
相关产品推荐

