てくなべ

インフラ、ネットワーク、自動化などの技術的なことを書いていきます。

Ansible の napalm-ansible モジュール群でCisco IOS 機器の様々な情報を取得する

f:id:akira6592:20170527215846p:plain

■ はじめに

マルチベンダー対応のネットワーク機器制御ライブラリのNAPALMには、ansibleと連携するための napalm-ansible というモジュール群があります。 今回はその中の napalm_get_facts というモジュールを利用して Cisco IOS 機器の様々な情報を取得してみます。

[githubリポジトリ]

GitHub - napalm-automation/napalm-ansibleGitHub - napalm-automation/napalm-ansible

[参考情報(Aristaでの例)]

AnsibleとNAPALMの連携を試してみた | ネットワークエンジニアを目指して - ブログ

なお、標準モジュールである ios_facts を利用する場合は、以下の記事をご参照ください。

tekunabe.hatenablog.jp


■ 準備

NAPAM のインストー

あらかじめ NAPALM をインストールします。

pip install napalm

napalm-ansible モジュール群のダウンロードと配置

git clone https://github.com/napalm-automation/napalm-ansible.git

napalm-automation ディレクトリ配下の library ディレクトリを、作成予定の playbook と同じディレクトリに配置します。


■ 基本情報の取得

まず、基本的な情報を取得してみます。

Playbook

以下のようなplaybook を作成します。ansible.cfg は特に作成していません。

---
- hosts: cisco   # イベントリファイルで定義済み
  gather_facts: no
  connection: local

  tasks:
    - name: get facts from device
      napalm_get_facts:
        hostname: "{{ inventory_hostname }}"
        provider: "{{ cli }}"
      register: result

    - name: debug
      debug:
        msg: "{{ result }}"

  vars:
    cli: # 認証情報
      username: "{{ ansible_user }}"          # ログインユーザー
      password: "{{ ansible_password }}"      # ログインパスワード
      dev_os: "ios"                           # デバイスのOS

なお、napalm_get_facts モジュールには filter オプションがあり、情報取得する対象を指定することができます。 デフォルトは facts となっており、ホスト名やシリアルナンバーなど基本的な情報を取得します。facts 以外については後述します。

実行結果

実行して結果を確認してみます。

[root@localhost ~]# ansible-playbook nf.yml

PLAY [cisco] **********************************************************************

TASK [get facts from device] ******************************************************
ok: [x.x.x.x]

TASK [debug] **********************************************************************
ok: [x.x.x.x] => {
    "changed": false,
    "msg": {
        "ansible_facts": {
            "facts": {
                "fqdn": "csr1.********.com",
                "hostname": "csr1",
                "interface_list": [
                    "GigabitEthernet1",
                    "GigabitEthernet2",
                    "GigabitEthernet3",
                    "GigabitEthernet4"
                ],
                "model": "CSR1000V",
                "os_version": "CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M),                                                                        SOFTWARE (fc3)",
                "serial_number": "XXXXXXXXXXX",
                "uptime": 1080,
                "vendor": "Cisco"
            }
        },
        "changed": false
    }
}

PLAY RECAP ************************************************************************
x.x.x.x             : ok=2    changed=0    unreachable=0    failed=0

基本的な情報が取得できました。


■ facts 以外の情報取得方法について

指定できる対象

前述のように filter オプションでは情報取得する対象を指定することができます。 指定できるものは Cisco IOS の場合は以下の通りです。

  • arp_table
  • bgp_neighbors
  • config
  • environment
  • facts
  • interfaces
  • interfaces_counters
  • interfaces_ip
  • lldp_neighbors
  • lldp_neighbors_detail
  • mac_address_table
  • ntp_servers
  • ntp_stats
  • optics
  • snmp_information

指定できる値は、napalm-automation 自身のドキュメントには記述されいませんが、 NAPALM本体の「Getters support matrix」のIOS(今回の場合)の列を見ると分かります。

Supported Devices — NAPALM 1 documentation

例) get_config に対応していれば filterconfig が指定でき、以下のように記述できる。

      napalm_get_facts:
        hostname: "{{ inventory_hostname }}"
        provider: "{{ cli }}"
        filter:
          - "config"

それぞれどのように取得できるのか試します。 ※あまり設定が入っていない機器で試したので情報が少ないです。

arp_table

今回の環境では特に通信していないため空となりました。

"arp_table": []

bgp_neighbors

今回の環境ではBGPは未設定のため空となりました。

"bgp_neighbors": {}

config

running-config が取得できました。

"config": {
                "candidate": "",
                "running": "Building configuration...\n\nCurrent configuration : 39iguration change at 11:25:09 UTC Sat May 27 2017\n!\nversion 16.3\n(略)
}

environment

ハードウェア状況の情報が取得できました。

"environment": {
    "cpu": {
        "0": {
            "%usage": 0.0
        }
    },
    "fans": {
        "invalid": {
            "status": true
        }
    },
    "memory": {
        "available_ram": 1765843468,
        "used_ram": 333704364
    },
    "power": {
        "invalid": {
            "capacity": -1.0,
            "output": -1.0,
            "status": true
        }
    },
    "temperature": {
        "invalid": {
            "is_alert": false,
            "is_critical": false,
            "temperature": -1.0
        }
    }
}

facts

再掲になりますが、ホスト名やシリアルナンバーなどの基本的な情報が取得できました。

"facts": {
    "fqdn": "csr1.********.com",
    "hostname": "csr1",
    "interface_list": [
        "GigabitEthernet1",
        "GigabitEthernet2",
        "GigabitEthernet3",
        "GigabitEthernet4"
    ],
    "model": "CSR1000V",
    "os_version": "CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), SOFTWARE (fc3)",
    "serial_number": "XXXXXXXXXXX",
    "uptime": 1200,
    "vendor": "Cisco"
}

interfaces

インターフェース情報が取得できました。

"interfaces": {
    "GigabitEthernet1": {
        "description": "N/A",
        "is_enabled": true,
        "is_up": true,
        "last_flapped": -1.0,
        "mac_address": "2C:C2:60:XX:XX:XX",
        "speed": 1000
    },
    "GigabitEthernet2": {
        "description": "N/A",
        "is_enabled": true,
        "is_up": true,
        "last_flapped": -1.0,
        "mac_address": "2C:C2:60:XX:XX:XX",
        "speed": 1000
    },
    "GigabitEthernet3": {
        "description": "N/A",
        "is_enabled": true,
        "is_up": true,
        "last_flapped": -1.0,
        "mac_address": "2C:C2:60:XX:XX:XX",
        "speed": 1000
    },
    "GigabitEthernet4": {
        "description": "N/A",
        "is_enabled": true,
        "is_up": true,
        "last_flapped": -1.0,
        "mac_address": "2C:C2:60:XX:XX:XX",
        "speed": 1000
    }
}

interfaces_counters

インターフェースのカウンタ情報が取得できました。

"interfaces_counters": {
    "GigabitEthernet1": {
        "rx_broadcast_packets": 0,
        "rx_discards": 0,
        "rx_errors": 753,
        "rx_multicast_packets": 0,
        "rx_octets": 68538,
        "rx_unicast_packets": 980,
        "tx_broadcast_packets": -1,
        "tx_discards": 0,
        "tx_errors": 0,
        "tx_multicast_packets": -1,
        "tx_octets": 199698,
        "tx_unicast_packets": 1358
    },
    (省略)
    }
}

interfaces_ip

IPアドレスが設定されているインターフェースの情報が取得できました。

"interfaces_ip": {
    "GigabitEthernet1": {
        "ipv4": {
            "10.0.0.51": {
                "prefix_length": 24
            }
        }
    }
}

lldp_neighbors

今回の環境では未設定のため空となりました。

"lldp_neighbors": {}

lldp_neighbors_detail

今回の環境では未設定のため空となりました。

"lldp_neighbors_detail": {}

mac_address_table

今回の環境では未通信のため空となりました。

"mac_address_table": []

ntp_servers

今回の環境では未設定のため空となりました。

"ntp_servers": {}

ntp_stats

今回の環境では未設定のため空となりました。

"ntp_stats": []

optics

今回の環境ではSFP等のスロットはないため空となりました。

"optics": {}

snmp_information

今回の環境では未設定のため特に意味のない値となりました。

"snmp_information": {
    "chassis_id": "%SNMP agent not enabled",
    "community": {},
    "contact": "unknown",
    "location": "unknown"
}

■ さいごに

稼働中のネットワーク機器の情報を収集したいケースは割とよくあると思いますが、自作しなくてもここまでできますので、もし、取得したい情報がこのモジュールで取得できるのであれば、利用してみるのもよいのではないでしょうか。

なお、Ansible を利用せずに、pythonスクリプト中でなるべくパース処理の手間を省きたい場合は、TextFSMというライブラリと ntc-template というテンプレート集を利用するのが良いと思います。 github.com github.com