【问题标题】:Ansible Filter/Parse output to jsonAnsible 过滤器/解析输出到 json
【发布时间】:2021-03-21 10:00:55
【问题描述】:

我正在尝试将 ansible-playbook 输出过滤为有效的 json 输出,以便我可以使用它。 我得到的输出是:

ok: [r-sw01] => {
    "configlets | selectattr(\"name\", \"eq\", \"r-sw01\")": [
        {
            "config": "hostname r-sw01\n\ninterface Management1\n   ip address 10.10.24.10/24\n\ninterface Port-Channel20\n   description USR\n   switchport mode trunk\n\ninterface Ethernet99-100\n   description  USR_Po20\n   speed forced 25gfull\n",
            "containerCount": 0,
            "containers": [],
            "dateTimeInLongFormat": 1615984781483,
            "devices": [
                "r-sw01"
            ],
            "editable": true,
            "isAutoBuilder": "",
            "isDefault": "no",
            "isDraft": false,
            "key": "configlet_71ef71",
            "name": "r-sw01",
            "netElementCount": 0,
            "note": "",
            "reconciled": false,
            "sslConfig": false,
            "type": "Static",
            "typeStudioConfiglet": false,
            "user": "chal",
            "visible": true
        }
    ]
}

来自这个剧本:

---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")

尝试使用 python 过滤它:

configlet_settings = subprocess.Popen(["ansible-playbook", "configlets.yml", "-e", tag ,"-i", "inventory.ini"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = configlet_settings.communicate()
out = out.decode()
out = out.split('\n')
r = re.search(r"configlets.*\[(.*?)\]", str(out))
r = r.group(1)
my_lst = re.findall(r"\w+", r)

但我只是得到 (['r', 'sw01'],)

当我尝试更改正则表达式时或“无”时,我如何才能获得此输出的有效 json?我不需要| selectattr(\"name\", \"eq\", \"r-sw01\")",只需要后面的内容

编辑- 尝试将输出重定向到文件:

  ---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  vars:
    var: var
    vars_files:
            - vars.yml
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")

    - name: write JSON to a file
      copy:
         content: "{{ var|to_nice_json }}"
         dest: somefile.json

出现错误:

FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined

【问题讨论】:

  • 尝试解析 Ansible 的输出似乎是在浪费时间。如果您想要从 Ansible 输出 JSON,只需将 JSON 写入文件,使用 templatecopy 任务,然后只需将文件读入代码即可。无需手动解析。 Ansible 具有用于将数据序列化为 JSON/YAML/等的过滤器。
  • 我如何重定向 var?我在 debug- local_action: copy content=var dest=somelog.log 也尝试了 content={{var}} 之后添加了这个

标签: python regex ansible jmespath


【解决方案1】:

如果要将 Ansible 变量的 JSON 序列化写入文件,可以执行以下操作:

- name: write JSON to a file
  copy:
    content: "{{ var|to_nice_json }}"
    dest: somelog.json

然后将其导入您的 Python 代码:

import json

with open('somelog.json') as fd:
  data = json.load(fd)

【讨论】:

  • Playbook 返回错误:FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined - 已编辑的问题与 playbook 更改
  • 您是否定义了一个名为var 的变量?如果不是,请使用您尝试转储的变量的名称。
  • 我需要在哪里定义它?完整的剧本在问题中,请让我知道我应该做什么
  • 这实际上需要你知道你想要做什么。您要转储到 JSON 的变量的名称是什么?是configlets吗?不管是什么,将content 表达式中的var 替换为变量的名称。
  • 为过滤configlets 上的输出而创建的 var 并仅按名称给我相关信息,因为 configlets 有很多信息,在过滤后我只想要它正在过滤的 json。如果我将配置文件放在它的内容而不是 var 我得到完整的信息,如果没有办法将过滤后的信息放在var 上记录文件,这就足够了:)
猜你喜欢
  • 2022-01-12
  • 2021-07-02
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
相关资源
最近更新 更多