clay584.parse_genie

解析精灵

已发布

Ansible 角色 Ansible 版本 Python 版本

构建状态 Ansible 质量评分

注意!!! - 如果您遇到命令解析失败的问题,可能是 Cisco 维护的解析库中存在错误。对于这些问题,您可以在这里提交问题。

网络解析精灵过滤器将所有 Cisco 网络操作系统的非结构化网络 CLI 命令输出转换为结构化数据。虽然与其他可用的网络 CLI 解析器(如 parse_cli, parse_cli_textfsm)相似,但此解析器是由 Cisco 开发的成熟且强大的库 Genie(及其底层框架 pyATS)提供支持。它提供了超过1200个解析器,可以将配置和 CLI 输出转换为结构化数据,这些数据是规范化的,并符合标准的、与操作系统无关的数据模型。

Genie 库也可以作为引擎,使用比传统解析需要更少的代码解析表格和非表格的自由格式文本。因此,它可以用于解析任何厂商的输出,而不仅限于 Cisco 设备的输出。但是,这将涉及编写自定义解析器。本版本不包含使用自定义解析器的功能。支持的解析器为用户在其 Ansible 控制机上安装的 Genie 版本中包含的解析器。

支持的操作系统和命令列表,以及数据模式定义(描述任何给定命令将返回哪些字段和数据类型),可通过以下链接从 Cisco 获取。

https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/parsers

前提条件

此插件需要以下内容:

  1. Python 3.4+
  2. pyATS 和 Genie 包
  3. Ansible 2.7+(只要满足其他要求,应该可以在更旧的版本上工作)

安装

请按照以下说明操作,确保过滤插件可以在您的剧本中正常工作:

  1. 创建一个目录用于您的剧本并进入该目录。mkdir network_ops && cd network_ops
  2. 创建一个虚拟环境。python3 -m venv .venv
  3. 激活虚拟环境。source .venv/bin/activate
  4. 安装 Ansible。pip install ansible
  5. 安装 Genie 和 pyATS。pip install genie
  6. 从 Ansible Galaxy 安装 parse_genie 角色。ansible-galaxy install clay584.parse_genie

Ansible 到 Genie 操作系统映射

以下是 Ansible 的 ansible_network_os 到 Genie 的 os 的映射:

Ansible 网络操作系统 Genie 操作系统
ios ios, iosxe
nxos nxos
iosxr iosxr
junos junos

如果您使用的是 IOS 或 IOS-XE,可能会存在歧义,因为 Ansible 将 IOS 和 IOS-XE 视为相同,因此 ansible_network_os = ios,但 Genie 需要明确知道它是 IOS 还是 IOS-XE,以便正确解析 CLI 输出。如果您将 ansible_network_os 传递给此过滤插件,并且其值等于 ios,parse_genie 将首先尝试使用 os=ios 进行解析,如果失败,则将尝试使用 os=iosxe 进行解析。

因此,在创建剧本时请记住这一点。最好是将实际的操作系统传递给 parse_genie。您可以通过维持另一个库存变量或主机变量来指定每个网络设备的 Genie 操作系统,然后使用该变量作为 parse_genie 的操作系统。

使用方法

在尝试在剧本中使用 parse_genie 之前,请确保先读取 parse_genie 角色。

...省略...

  tasks:
  - name: 读取 parse_genie 角色
    include_role:
      name: clay584.parse_genie
      
...省略...

简短示例

要将网络设备 CLI 命令的输出转换为结构化数据,如下例所示使用 parse_genie 过滤器(请勿使用简化的 CLI 命令)。

将来自 Cisco IOS-XE 设备的 show version 命令的 CLI 输出转换为结构化数据:

{{ cli_output | parse_genie(command='show version', os='iosxe') }}

为了更深层次的抽象,您可能还想向 parse_genie 添加 platform

{{ cli_output | parse_genie(command='show version', os='iosxe', platform='asr1k') }}

上述示例将产生以下结果:

{
    "version": {
        "chassis": "CSR1000V",
        "chassis_sn": "9TKUWGKX5MO",
        "curr_config_register": "0x2102",
        "disks": {
            "bootflash:.": {
                "disk_size": "7774207",
                "type_of_disk": "virtual hard disk"
            },
            "webui:.": {
                "disk_size": "0",
                "type_of_disk": "WebUI ODM Files"
            }
        },
        "hostname": "host-172-16-1-96",
        "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
        "image_type": "production image",
        "last_reload_reason": "Reload Command",
        "license_level": "ax",
        "license_type": "Default. No valid license found.",
        "main_mem": "1126522",
        "mem_size": {
            "non-volatile configuration": "32768",
            "physical": "3018840"
        },
        "next_reload_license_level": "ax",
        "number_of_intfs": {
            "Gigabit Ethernet": "2"
        },
        "os": "IOS-XE",
        "platform": "Virtual XE",
        "processor_type": "VXE",
        "rom": "IOS-XE ROMMON",
        "rtr_type": "CSR1000V",
        "system_image": "bootflash:packages.conf",
        "uptime": "2 minutes",
        "uptime_this_cp": "3 minutes",
        "version": "16.5.1b,",
        "version_short": "16.5"
    }
}

完整示例 #1

剧本:

---

- hosts: localhost
  connection: local
  vars:
    show_version_output: |
      Cisco IOS XE 软件,版本 16.05.01b
      Cisco IOS 软件 [Everest], 虚拟 XE 软件 (X86_64_LINUX_IOSD-UNIVERSALK9-M), 版本 16.5.1b, 发行软件 (fc1)
      技术支持: http://www.cisco.com/techsupport
      版权所有 (c) 1986-2017 由 Cisco 系统公司。
      编译于 2017 年 4 月 11 日星期二 16:41,编写者 mcpre

      Cisco IOS-XE 软件,版权所有 (c) 2005-2017  Cisco 系统公司。
      版权所有。 Cisco IOS-XE 软件的某些组件根据 GNU 通用公共许可证("GPL") 版本 2.0 获得许可。
      根据 GPL 版本 2.0 授权的代码是免版权费的软件,完全不提供任何保证。您可以根据 GPL 版本 2.0 的条款重新分发和/或修改此代码。
      有关更多详细信息,请参阅与 IOS-XE 软件一起提供的文档或“许可证通知”文件,或提供在 IOS-XE 软件随附的传单中的适用 URL。

      ROM: IOS-XE ROMMON

      host-172-16-1-96 正在运行 2 分钟
      此控制处理器的运行时间为 3 分钟
      系统返回 ROM 由于重新加载
      系统映像文件为 "bootflash:packages.conf"
      上次重新加载原因: 重新加载命令

      本产品包含加密功能,受美国及当地国家进口、出口、转移和使用法律的制约。交付 Cisco 加密产品不代表第三方有权导入、导出、分发或使用加密。
      进口商、出口商、分销商和用户负责遵守美国和当地国家法律。使用本产品即表示您同意遵守适用的法律法规。如果您无法遵守美国和当地法律,请立即退还此产品。

      美国法律概述适用于 Cisco 加密产品,您可以在以下网址查找到:
      http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

      如需进一步帮助,请通过电子邮件联系 [email protected]

      许可证级别: ax
      许可证类型: 默认。未找到有效许可证。
      下次重新加载许可证级别: ax

      cisco CSR1000V (VXE) 处理器 (修订版 VXE) 拥有 1126522K/3075K 字节内存。
      处理器板 ID 9TKUWGKX5MO
      2 个千兆以太网接口
      32768K 字节非易失性配置内存。
      3018840K 字节物理内存。
      7774207K 字节虚拟硬盘在 bootflash:。
      0K 字节 WebUI ODM 文件在 webui:。

      配置寄存器为 0x2102

  tasks:
  - name: 读取 parse_genie 角色
    include_role:
      name: clay584.parse_genie

  - name: 调试 Genie 过滤器
    debug:
      msg: "{{ show_version_output | parse_genie(command='show version', os='iosxe') }}"
    delegate_to: localhost

输出:

$ ansible-playbook -i inventory debug.yml

PLAY [localhost] *************************************************************************

TASK [收集事实] *******************************************************************
ok: [localhost]

TASK [读取 parse_genie 角色] **********************************************************

TASK [调试 Genie 过滤器] ****************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "version": {
            "chassis": "CSR1000V",
            "chassis_sn": "9TKUWGKX5MO",
            "curr_config_register": "0x2102",
            "disks": {
                "bootflash:.": {
                    "disk_size": "7774207",
                    "type_of_disk": "virtual hard disk"
                },
                "webui:.": {
                    "disk_size": "0",
                    "type_of_disk": "WebUI ODM Files"
                }
            },
            "hostname": "host-172-16-1-96",
            "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
            "image_type": "production image",
            "last_reload_reason": "Reload Command",
            "license_level": "ax",
            "license_type": "Default. No valid license found.",
            "main_mem": "1126522",
            "mem_size": {
                "non-volatile configuration": "32768",
                "physical": "3018840"
            },
            "next_reload_license_level": "ax",
            "number_of_intfs": {
                "Gigabit Ethernet": "2"
            },
            "os": "IOS-XE",
            "platform": "Virtual XE",
            "processor_type": "VXE",
            "rom": "IOS-XE ROMMON",
            "rtr_type": "CSR1000V",
            "system_image": "bootflash:packages.conf",
            "uptime": "2 minutes",
            "uptime_this_cp": "3 minutes",
            "version": "16.5.1b,",
            "version_short": "16.5"
        }
    }
}

完整示例 #2

剧本:

---

- hosts: csr1000v
  gather_facts: False
  tasks:
  - name: 读取 parse_genie 角色
    include_role:
      name: clay584.parse_genie

  - name: 从设备获取数据
    ios_command:
      commands: show arp vrf Mgmt-intf
    register: arp_output

  - name: 打印结构化数据
    debug:
      msg: "{{ arp_output['stdout'][0] | parse_genie(command='show arp vrf Mgmt-intf', os='iosxe') }}"
    delegate_to: localhost

输出:

$ ansible-playbook -i inventory playbook.yml

PLAY [csr1000v] **************************************************************************

TASK [读取 parse_genie 角色] **********************************************************

TASK [从设备获取数据] **************************************************************
ok: [csr1000v]

TASK [打印结构化数据] *************************************************************
ok: [csr1000v -> localhost] => {
    "msg": {
        "interfaces": {
            "GigabitEthernet1": {
                "ipv4": {
                    "neighbors": {
                        "172.16.1.111": {
                            "age": "0",
                            "ip": "172.16.1.111",
                            "link_layer_address": "5e00.4004.0000",
                            "origin": "dynamic",
                            "protocol": "Internet",
                            "type": "ARPA"
                        },
                        "172.16.1.114": {
                            "age": "-",
                            "ip": "172.16.1.114",
                            "link_layer_address": "5e00.4001.0000",
                            "origin": "static",
                            "protocol": "Internet",
                            "type": "ARPA"
                        }
                    }
                }
            }
        }
    }
}

通用表格解析

Cisco Genie 支持 1200 个命令,并且数量还在增加,但对于没有由 Cisco 构建的解析器的显示命令,可以使用通用表格解析功能。有关 Genie 表格解析功能的更多信息,请参见他们的oper_fill_tabular文档。

表格解析的工作原理

为了当有解析器时解析命令输出,只需提供 commandcommand outputos。但是,如果没有构建解析器,您必须指定一些额外的信息,以帮助解析器确定如何解析命令输出。这些额外的数据有两个部分:

  1. 表头 - 作为命令输出的一部分显示的列标题。
  2. 索引 - 解析器将返回的字典项的关键字。

考虑以下示例:

  1. 命令: show ip sla summary
  2. 命令输出:
IPSLAs 最新操作摘要
代码: * 活动, ^ 非活动, ~ 待定
所有统计数据均以毫秒为单位。带有 u 的统计数据以微秒为单位

ID           类型           目标地址       统计数据               返回        上次执行
                                                                            代码          执行
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             20 秒前
*2           icmp-echo       10.0.0.2          RTT=1              OK              3 秒前
  1. 表头 - ID, 类型, 目标地址, 统计数据, 返回代码, 上次执行
  2. 索引 - 我们希望使用 ID 列作为从解析器获取回来的数据的索引。
  3. 解析器输出:
{'*1': {'目标地址 ': '10.0.0.2',
        'ID ': '*1',
        '上次执行': '20 秒前',
        '返回代码': 'OK',
        '统计 ': 'RTT=900u',
        '类型 ': 'udp-jitter'},
 '*2': {'目标地址 ': '10.0.0.2',
        'ID ': '*2',
        '上次执行': '3 秒前',
        '返回代码': 'OK',
        '统计 ': 'RTT=1',
        '类型 ': 'icmp-echo'}}

准备使用表格解析器

为了使用此表格解析器,我们必须首先为给定操作系统上的给定命令构建 headersindex,格式可以被 Ansible 剧本读取,并随后传递给 parse_genie 过滤插件。

为此,您必须在剧本中创建一个变量文件,格式如下。它按照操作系统,然后是命令组织。在每个命令下,定义了表头和索引。您可以为每个网络操作系统定义任意数量的命令,只要在此数据结构中即可。

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - 类型
          - 目标地址
          - 统计
          - 返回
          - 上次
        - - ''
          - ''
          - ''
          - ''
          - 代码
          - 执行
      index:
        - 0
  iosxe:
    "show ip sla summary":
      headers:
        - - ID
          - 类型
          - 目标地址
          - 统计
          - 返回
          - 上次
        - - ''
          - ''
          - ''
          - ''
          - 代码
          - 执行
      index:
        - 1

上述 yaml 格式的 Python 等效代码是:

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "类型", 
            "目标地址", 
            "统计", 
            "返回", 
            "上次"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "代码", 
            "执行"
          ]
        ], 
        "index": [
          0
        ]
      }
    }, 
    "iosxe": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "类型", 
            "目标地址", 
            "统计", 
            "返回", 
            "上次"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "代码", 
            "执行"
          ]
        ], 
        "index": [
          1
        ]
      }
    }
  }
}

在剧本中调用表格解析器

现在我们已经定义了通用表格命令及其头和索引,我们可以从剧本中实际调用它。

首先,我们读取包含表格命令解析元数据的变量文件。

- name: 包含含有通用命令元数据的变量文件
  include_vars:
    file: parse_genie_generic_commands.yml
    name: parse_genie

接下来,我们将命令输出传递给 parse_genie,但稍多几个额外参数。

- name: 解析通用表格命令输出
  debug:
    msg: "{{ command_output | parse_genie(command='show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
  delegate_to: localhost

解析后的输出如下所示:

ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "目标地址 ": "10.0.0.2",
            "ID ": "*1",
            "上次执行": "20 秒前",
            "返回代码": "OK",
            "统计 ": "RTT=900u",
            "类型 ": "udp-jitter"
        },
        "*2": {
            "目标地址 ": "10.0.0.2",
            "ID ": "*2",
            "上次执行": "3 秒前",
            "返回代码": "OK",
            "统计 ": "RTT=1",
            "类型 ": "icmp-echo"
        }
    }
}

完整示例 #1

剧本:


---

- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      IPSLAs 最新操作摘要
      代码: * 活动, ^ 非活动, ~ 待定
      所有统计数据均以毫秒为单位。带有 u 的统计数据以微秒为单位

      ID           类型           目标地址       统计数据               返回        上次执行
                                                                        代码          执行
      ------------------------------------------------------------------------------------------------
      *1           udp-jitter      10.0.0.2          RTT=900u           OK             20 秒前
      *2           icmp-echo       10.0.0.2          RTT=1              OK              3 秒前

  tasks:
    - name: 包含解析精灵角色
      include_role:
        name: clay584.parse_genie

    - name: 包含含有通用表格命令元数据的变量文件
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: 测试通用表格数据的 Genie 过滤器
      debug:
        msg: "{{ out_ios_sla | parse_genie(command='test show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
      delegate_to: localhost

parse_genie_generic_commands.yml 内容:


---

parse_genie:
  ios:
    "test show ip sla summary":
      headers:
        - - ID
          - 类型
          - 目标地址
          - 统计
          - 返回
          - 上次
        - - ''
          - ''
          - ''
          - ''
          - 代码
          - 执行
      index:
        - 0
  iosxe:
    "test show ip sla summary":
      headers:
        - - ID
          - 类型
          - 目标地址
          - 统计
          - 返回
          - 上次
        - - ''
          - ''
          - ''
          - ''
          - 代码
          - 执行
      index:
        - 1

剧本输出:


PLAY [localhost] ******************************************************************************************************************************************************************************************************************************************************************

TASK [收集事实] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [包含解析精灵角色] ***************************************************************************************************************************************************************************************************************************************************

TASK [包含变量] ***************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [测试通用表格数据的 Genie 过滤器] *********************************************************************************************************************************************************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "目标地址 ": "10.0.0.2",
            "ID ": "*1",
            "上次执行": "20 秒前",
            "返回代码": "OK",
            "统计 ": "RTT=900u",
            "类型 ": "udp-jitter"
        },
        "*2": {
            "目标地址 ": "10.0.0.2",
            "ID ": "*2",
            "上次执行": "3 秒前",
            "返回代码": "OK",
            "统计 ": "RTT=1",
            "类型 ": "icmp-echo"
        }
    }
}

PLAY RECAP ************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   

开发

设置您的开发环境:

  1. 克隆该仓库并进入。 git clone https://github.com/clay584/parse_genie.git && cd parse_genie
  2. 创建一个虚拟环境。 python3 -m venv .venv
  3. 激活虚拟环境。 source .venv/bin/activate
  4. 安装 Ansible。 pip install ansible
  5. 安装 Genie 和 pyATS。 pip install genie
  6. 安装 yamllint。 pip install yamllint

测试

运行这些命令进行本地测试:

  1. 检查所有 YAML 文件的语法。 yamllint -c yamllint_config.yml *
  2. 运行测试剧本。 ansible-playbook tests/test.yml --connection=local -i tests/inventory

推送

Ansible Galaxy 在标签上工作。

  1. git commit -m"whatever'
  2. git tag -a X.X.X - 其中 X.X.X 是语义版本号。
  3. git push origin master
  4. git push X.X.X
关于项目

Filter plugin for network CLI parsing using Cisco's Genie/pyATS

安装
ansible-galaxy install clay584.parse_genie
许可证
gpl-3.0
下载
63.8k
拥有者
Brought to you by Carl's Jr.