使用 Ansible 的 CLI 命令结果为 json
CLI Command result to json using Ansible
大家下午好,
我需要从 5 个交换机获取 BGP table 详细信息。
为此,我使用带有 Cisco 模块的 Ansible 在这 5 个交换机上发送 CLI 命令“show bgp l2vpn evpn vrf all”。
它运行良好,但我需要获取 JSON 才能过滤结果。
我尝试的第一个选项是使用 | json Ansible 中的选项:
---
- name: Playbook
hosts: all
gather_facts: false
tasks:
- name: run show bgp on remote devices
cisco.nxos.nxos_command:
commands: show bgp l2vpn evpn vrf all | json
register: cli_result
- local_action:
module: copy
content: "{{ cli_result | to_nice_json(indent=2) }}"
dest: home/cli_result.json
此选项适用于一个交换机,但一旦我在 5 个交换机上启动它,我就好像内存不足或其他原因,我收到错误 错误!一名工人被发现处于死亡状态.
我不知道这个问题是否来自我正在使用的服务器,它不够强大,或者是否是其他原因。
此外,我注意到 | json 选项使剧本非常慢,当我在没有这个选项的情况下启动剧本时,它快了 5 倍。
所以我的问题是:有没有办法将 CLI 命令结果转换为 json,例如 Python?
当然,我尝试使用 python 模块 json 来转换它,但它正在将它转换成 12000 行的一大块,只有一个键和一个巨大的值。
而 | Ansible 中的 json 选项使许多不同的键变得非常清晰。
这是 CLI 命令的结果:
BGP routing table information for VRF default, address family L2VPN EVPN
BGP table version is xxxxx, Local Router ID is xx.xx.xx.xx
Status: s-suppressed, x-deleted, S-stale, d-dampened, h-history, *-valid, >-best
Path type: i-internal, e-external, c-confed, l-local, a-aggregate, r-redist, I-injected
Origin codes: i - IGP, e - EGP, ? - incomplete, | - multipath, & - backup, 2 - best2
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: xxxxx:xxxxx
* i[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx
xx.xx.xx.xx 000 0 xxxxx xxxxx i
*>i xx.xx.xx.xx 000 0 xxxxx xxxxx i
* i[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx
xx.xx.xx.xx 000 0 xxxxx xxxxx i
*>i xx.xx.xx.xx 000 0 xxxxx xxxxx i
.......
这是 | 的结果json Ansible 选项:
{
"changed": false,
"failed": false,
"stdout": [
{
"TABLE_vrf": {
"ROW_vrf": {
"TABLE_afi": {
"ROW_afi": {
"TABLE_safi": {
"ROW_safi": {
"TABLE_rd": {
"ROW_rd": [
{
"TABLE_prefix": {
"ROW_prefix": [
{
"TABLE_path": {
"ROW_path": [
{
"aspath": "xxxxx xxxxx",
"best": "none",
"bestcode": null,
"ipnexthop": "0.0.0.0",
"localpref": "000",
"origin": "i",
"pathnr": "0",
"status": "valid",
"statuscode": "*",
"type": "internal",
"typecode": "i",
"weight": "0"
},
{
"aspath": "xxxxx xxxxx",
"best": "bestpath",
"bestcode": ">",
"ipnexthop": "0.0.0.0",
"localpref": "000",
"origin": "i",
"pathnr": "1",
"status": "valid",
"statuscode": "*",
"type": "internal",
"typecode": "i",
"weight": "0"
}
]
},
"nonipprefix": "[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx"
},
这是我用 Python 转换的 CLI 命令的结果:
{
"changed": false,
"failed": false,
"stdout": [containing the whole block of cli command result with ',' after each line]
}
非常感谢您的帮助,
问:“有没有办法将CLI命令结果转换成JSON?”
答:在你的情况下,最好的选择可能是 ansible.netcommon.cli_parse。
问:“正在为一个开关工作,但一旦我在 5 个开关上启动它...”
答:你运行任务local_action同时进行所有切换。 运行 它只写一次并写入所有数据,例如,在字典中。鉴于清单和下面的剧本进行测试
shell> cat hosts
sw1
sw2
sw3
shell> cat playbook.yml
- name: Playbook
hosts: all
gather_facts: false
tasks:
- set_fact:
cli_result:
stdout:
- TABLE_vrf:
ROW_vrf: to be continued
- copy:
content: "{{ _dict|to_nice_yaml(indent=2) }}"
dest: cli_result.json
delegate_to: localhost
run_once: true
vars:
_keys: "{{ ansible_play_hosts }}"
_vals: "{{ ansible_play_hosts|
map('extract', hostvars, ['cli_result', 'stdout'])|
list }}"
_dict: "{{ dict(_keys|zip(_vals)) }}"
剧本创建文件cli_result.json
sw1:
- TABLE_vrf:
ROW_vrf: to be continued
sw2:
- TABLE_vrf:
ROW_vrf: to be continued
sw3:
- TABLE_vrf:
ROW_vrf: to be continued
大家下午好,
我需要从 5 个交换机获取 BGP table 详细信息。 为此,我使用带有 Cisco 模块的 Ansible 在这 5 个交换机上发送 CLI 命令“show bgp l2vpn evpn vrf all”。
它运行良好,但我需要获取 JSON 才能过滤结果。
我尝试的第一个选项是使用 | json Ansible 中的选项:
---
- name: Playbook
hosts: all
gather_facts: false
tasks:
- name: run show bgp on remote devices
cisco.nxos.nxos_command:
commands: show bgp l2vpn evpn vrf all | json
register: cli_result
- local_action:
module: copy
content: "{{ cli_result | to_nice_json(indent=2) }}"
dest: home/cli_result.json
此选项适用于一个交换机,但一旦我在 5 个交换机上启动它,我就好像内存不足或其他原因,我收到错误 错误!一名工人被发现处于死亡状态.
我不知道这个问题是否来自我正在使用的服务器,它不够强大,或者是否是其他原因。
此外,我注意到 | json 选项使剧本非常慢,当我在没有这个选项的情况下启动剧本时,它快了 5 倍。
所以我的问题是:有没有办法将 CLI 命令结果转换为 json,例如 Python?
当然,我尝试使用 python 模块 json 来转换它,但它正在将它转换成 12000 行的一大块,只有一个键和一个巨大的值。 而 | Ansible 中的 json 选项使许多不同的键变得非常清晰。
这是 CLI 命令的结果:
BGP routing table information for VRF default, address family L2VPN EVPN
BGP table version is xxxxx, Local Router ID is xx.xx.xx.xx
Status: s-suppressed, x-deleted, S-stale, d-dampened, h-history, *-valid, >-best
Path type: i-internal, e-external, c-confed, l-local, a-aggregate, r-redist, I-injected
Origin codes: i - IGP, e - EGP, ? - incomplete, | - multipath, & - backup, 2 - best2
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: xxxxx:xxxxx
* i[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx
xx.xx.xx.xx 000 0 xxxxx xxxxx i
*>i xx.xx.xx.xx 000 0 xxxxx xxxxx i
* i[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx
xx.xx.xx.xx 000 0 xxxxx xxxxx i
*>i xx.xx.xx.xx 000 0 xxxxx xxxxx i
.......
这是 | 的结果json Ansible 选项:
{
"changed": false,
"failed": false,
"stdout": [
{
"TABLE_vrf": {
"ROW_vrf": {
"TABLE_afi": {
"ROW_afi": {
"TABLE_safi": {
"ROW_safi": {
"TABLE_rd": {
"ROW_rd": [
{
"TABLE_prefix": {
"ROW_prefix": [
{
"TABLE_path": {
"ROW_path": [
{
"aspath": "xxxxx xxxxx",
"best": "none",
"bestcode": null,
"ipnexthop": "0.0.0.0",
"localpref": "000",
"origin": "i",
"pathnr": "0",
"status": "valid",
"statuscode": "*",
"type": "internal",
"typecode": "i",
"weight": "0"
},
{
"aspath": "xxxxx xxxxx",
"best": "bestpath",
"bestcode": ">",
"ipnexthop": "0.0.0.0",
"localpref": "000",
"origin": "i",
"pathnr": "1",
"status": "valid",
"statuscode": "*",
"type": "internal",
"typecode": "i",
"weight": "0"
}
]
},
"nonipprefix": "[x]:[0]:[0]:[xx]:[xxxx.xxxx.xxxx]:[0]:[0.0.0.0]/xxx"
},
这是我用 Python 转换的 CLI 命令的结果:
{
"changed": false,
"failed": false,
"stdout": [containing the whole block of cli command result with ',' after each line]
}
非常感谢您的帮助,
问:“有没有办法将CLI命令结果转换成JSON?”
答:在你的情况下,最好的选择可能是 ansible.netcommon.cli_parse。
问:“正在为一个开关工作,但一旦我在 5 个开关上启动它...”
答:你运行任务local_action同时进行所有切换。 运行 它只写一次并写入所有数据,例如,在字典中。鉴于清单和下面的剧本进行测试
shell> cat hosts
sw1
sw2
sw3
shell> cat playbook.yml
- name: Playbook
hosts: all
gather_facts: false
tasks:
- set_fact:
cli_result:
stdout:
- TABLE_vrf:
ROW_vrf: to be continued
- copy:
content: "{{ _dict|to_nice_yaml(indent=2) }}"
dest: cli_result.json
delegate_to: localhost
run_once: true
vars:
_keys: "{{ ansible_play_hosts }}"
_vals: "{{ ansible_play_hosts|
map('extract', hostvars, ['cli_result', 'stdout'])|
list }}"
_dict: "{{ dict(_keys|zip(_vals)) }}"
剧本创建文件cli_result.json
sw1:
- TABLE_vrf:
ROW_vrf: to be continued
sw2:
- TABLE_vrf:
ROW_vrf: to be continued
sw3:
- TABLE_vrf:
ROW_vrf: to be continued