clay584.parse_genie

パースジェニー

公開

Ansibleロール Ansibleバージョン Pythonバージョン

ビルド状態 Ansible品質スコア

注意!!! - コマンドのパースに失敗した場合、パースライブラリにバグがある可能性があります。その場合は、こちらに問題を報告してください。

ネットワークジェニーフィルタは、すべてのCiscoネットワークオペレーティングシステムからの非構造化のネットワークCLIコマンド出力を受け取り、構造化データを出力します。他のネットワークCLIパーサ(parse_cli、parse_cli_textfsm)に似ていますが、このパーサはCiscoが開発した非常に成熟した堅牢なライブラリ「ジェニー」に基づいています(基盤となるフレームワークはpyATSです)。これにより、1200以上のパーサが提供され、構成とCLI出力を標準的でOSに依存しないデータモデルに正規化された構造化データに変換します。

ジェニーライブラリは、従来のパースよりもはるかに少ないコードで表形式および非表形式の自由形式テキストをパースするエンジンとしても機能します。したがって、Ciscoデバイスだけでなく、他のベンダーの出力をパースするために使用できます。ただし、カスタムパーサを書く必要があります。このリリースにはカスタムパーサを使用する機能は含まれていません。サポートされるパーサは、ユーザーがAnsibleコントロールマシンにインストールしたジェニーのリリースに含まれるものです。

サポートされているオペレーティングシステムとコマンドのリスト、ならびに特定のコマンドに対して返されるフィールドとデータ型を詳述するデータのスキーマ定義は、以下のリンクからCiscoで入手できます。

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

前提条件

このプラグインでは、次のものが必要です:

  1. Python 3.4以上
  2. pyATSおよびジェニーパッケージ
  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. ジェニーとpyATSをインストールします。 pip install genie
  6. Ansible Galaxyからparse_genieロールをインストールします。 ansible-galaxy install clay584.parse_genie

AnsibleからジェニーOSへのマッピング

以下は、Ansibleの ansible_network_os からジェニーの os へのマッピングです:

AnsibleネットワークOS ジェニーOS
ios ios, iosxe
nxos nxos
iosxr iosxr
junos junos

もしIOSまたはIOS-XEを使用している場合、AnsibleはIOSとIOS-XEを同じものと見なすため、ansible_network_os = ios となります。しかし、ジェニーはCLI出力を正しくパースするために、IOSかIOS-XEのどちらかを特定する必要があります。このフィルタプラグインに ansible_network_os を渡すと、parse_genieは最初に os=ios でジェニーを使用してパースを試み、失敗した場合は次に os=iosxe で試みます。

プレイブックを作成する際にこの点を念頭に置いておいてください。parse_genieには本当のOSを渡す方が良いルールでしょう。それを行うためには、他のインベントリ変数またはhost_varを保持し、各ネットワークデバイスのためにジェニーOSを指定し、その変数をparse_genieのOSとして使用することができます。

使用法

フィルタプラグインをプレイブックで利用する前に、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') }}

より深い抽象化を行いたい場合は、platformparse_genie に追加できます。

{{ 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 Software, Version 16.05.01b
      Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.5.1b, RELEASE SOFTWARE (fc1)
      Technical Support: http://www.cisco.com/techsupport
      Copyright (c) 1986-2017 by Cisco Systems, Inc.
      Compiled Tue 11-Apr-17 16:41 by mcpre


      Cisco IOS-XEソフトウェア、著作権 (c) 2005-2017 by Cisco Systems, Inc.
      All rights reserved.  Certain components of Cisco IOS-XEソフトウェアはGNU General Public License ("GPL") Version 2.0の下でライセンスされています。 
      GPLバージョン2.0の下でライセンスされたソフトウェアコードは、無保証の無料ソフトウェアとして提供されます。 
      あなたはこのGPLコードを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の暗号製品に関する米国の法律の要約は、以下のURLで確認できます:
      http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

      さらなる支援が必要な場合は、[email protected]までメールを送信してお問い合わせください。

      ライセンスレベル: ax
      ライセンスタイプ: デフォルト。 有効なライセンスが見つかりませんでした。
      次回リロードライセンスレベル: ax

      cisco CSR1000V (VXE)プロセッサ (revision VXE) は1126522K/3075Kバイトのメモリを持っています。
      プロセッサーボードID 9TKUWGKX5MO
      2つのギガビットイーサネットインターフェース
      32768Kバイトの不揮発性設定メモリ。
      3018840Kバイトの物理メモリ。
      bootflash:での仮想ハードディスクは7774207Kバイトです。
      webui:ではWebUI ODMファイルは0Kバイトです。

      設定レジスタは0x2102です。

  tasks:
  - name: parse_genieロールを読み込む
    include_role:
      name: clay584.parse_genie

  - name: ジェニーフィルタのデバッグ
    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 [ジーニーフィルタのデバッグ] ******************************************************
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ジェニーは、1200のコマンドをサポートしており、数を増やしていますが、Ciscoにより開発されたパーサがないshowコマンドの場合、一般的な表形式のパース機能があります。ジェニーの表形式パース機能に関する詳細は、oper_fill_tabularの文書を参照してください。

表形式パースの仕組み

パーサが構築されている場合は、コマンドの出力をパースするために必要なのは、commandcommand outputosの3つだけです。しかし、パーサが構築されていない場合は、コマンド出力をパースする際の追加情報を指定する必要があります。この追加データは二つの要素からなります:

  1. ヘッダー - コマンドの出力に示される列ヘッダー。
  2. インデックス - パーサが返す辞書アイテムのキー。

以下の例を検討します:

  1. コマンド:show ip sla summary
  2. コマンド出力:
IPSLAs Latest Operation Summary
Codes: * active, ^ inactive, ~ pending
All Stats are in milliseconds. Stats with u are in microseconds

ID           Type           Destination       Stats               Return        Last
                                                                  Code          Run
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             20 seconds ago
*2           icmp-echo       10.0.0.2          RTT=1              OK              3 seconds ago
  1. ヘッダー - IDTypeDestinationStatsReturn CodeLast Run
  2. インデックス - このデータのインデックスとしてID列を使用する。
  3. パーサ出力:
{'*1': {'Destination ': '10.0.0.2',
        'ID ': '*1',
        'Last Run': '20 seconds ago',
        'Return Code': 'OK',
        'Stats ': 'RTT=900u',
        'Type ': 'udp-jitter'},
 '*2': {'Destination ': '10.0.0.2',
        'ID ': '*2',
        'Last Run': '3 seconds ago',
        'Return Code': 'OK',
        'Stats ': 'RTT=1',
        'Type ': 'icmp-echo'}}

表形式パースを使用する準備

この表形式パースを使用するには、まず与えられたOSのコマンドに対してheadersindexをAnsibleプレイブックで読み込める形式に構築します。そのために、プレイブック内に以下の形式のvarsファイルを作成する必要があります。これはOSごとにコマンドで整理され、各コマンドの下にヘッダーとインデックスが定義されています。各ネットワークOSに対して、任意の数のコマンドをこのデータ構造内で定義できます。

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 0
  iosxe:
    "show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 1

上記のyaml形式のPython相当コードは:

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Type", 
            "Destination", 
            "Stats", 
            "Return", 
            "Last"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Run"
          ]
        ], 
        "index": [
          0
        ]
      }
    }, 
    "iosxe": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Type", 
            "Destination", 
            "Stats", 
            "Return", 
            "Last"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Run"
          ]
        ], 
        "index": [
          1
        ]
      }
    }
  }
}

プレイブック内でタブularパーサを呼び出す

一般的な表形式コマンドとそのヘッダーおよびインデックスを定義した今、プレイブックから実際に呼び出すことができます。

まず、一般的なコマンドパースのメタデータが含まれたvarsファイルを読み込みます。

- name: 一般的なコマンドメタデータを持つvarsファイルを読み込む
  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": {
            "Destination ": "10.0.0.2",
            "ID ": "*1",
            "Last Run": "20 seconds ago",
            "Return Code": "OK",
            "Stats ": "RTT=900u",
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            "ID ": "*2",
            "Last Run": "3 seconds ago",
            "Return Code": "OK",
            "Stats ": "RTT=1",
            "Type ": "icmp-echo"
        }
    }
}

フル例 #1

プレイブック:


---

- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      IPSLAs Latest Operation Summary
      Codes: * active, ^ inactive, ~ pending
      All Stats are in milliseconds. Stats with u are in microseconds

      ID           Type           Destination       Stats               Return        Last
                                                                        Code          Run
      ------------------------------------------------------------------------------------------------
      *1           udp-jitter      10.0.0.2          RTT=900u           OK             20 seconds ago
      *2           icmp-echo       10.0.0.2          RTT=1              OK              3 seconds ago

  tasks:
    - name: Parse Genieロールを読み込む
      include_role:
        name: clay584.parse_genie

    - name: 一般的なコマンドメタデータを持つvarsファイルを読み込む
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: 一般的なタブ形式データのためのジェニーフィルタをテストする
      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
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 0
  iosxe:
    "test show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 1

プレイブック出力:


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

TASK [ファクト収集] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Parse Genieロールを読み込む] ***************************************************************************************************************************************************************************************************************************************************

TASK [varsを読み込む] ***************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [一般的なタブ形式データのためのジェニーフィルタをテストする] *************************************************************************************************************************************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Destination ": "10.0.0.2",
            "ID ": "*1",
            "Last Run": "20 seconds ago",
            "Return Code": "OK",
            "Stats ": "RTT=900u",
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            "ID ": "*2",
            "Last Run": "3 seconds ago",
            "Return Code": "OK",
            "Stats ": "RTT=1",
            "Type ": "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. ジェニーと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.