参加できませんでしたが、2017/7/7 に第10回 Jenkins勉強会が実施されたそうです。 www.meetup.com
資料のまとめた見当たらなかったので、自分で探してこちらにまとめさせていただきます。
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
参加できませんでしたが、2017/7/7 に第10回 Jenkins勉強会が実施されたそうです。 www.meetup.com
資料のまとめた見当たらなかったので、自分で探してこちらにまとめさせていただきます。
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
7月と8月にネットワーク自動化の勉強会を開催しますのでご案内いたします。(2回とも同一内容です。)
近年、APIに対応していないネットワーク機器でも自動化できる方法が増えてきました。 一方で、「興味はあるけど、試してみる時間も環境もない!」という方も多いのではないでしょうか。
そんな方のために、自動化のためのツールやライブラリを使ってみた所感や、 それぞれの特徴などについてデモを交えながらご紹介します。 自動化ツール導入の参考にして下さい。
1.構成管理ツール
2.Pythonライブラリ
※一部デモ実施予定
日時場所などの詳細は以下のconnpassのページをご覧ください。
よろしくお願いいたします。
2017/06/09 に「Python 3 エンジニア認定基礎試験」が開始されました。
6/10に受験して合格しましたので、感想や自分の勉強方法を書きたいと思います。
特にクセもなく、素直な問題が多く、基礎試験という名の通りとだ感じました。 公開されている各分野の出題率を確認するとわかりますが、基礎知識にあたるがよく出題されるようになっています。
試験の認定教材でもある、オライリーの「Pythonチュートリアル 第3版」を利用しました。 www.oreilly.co.jp
Pythonの公式サイトにもPythonチュートリアルのコンテンツがあるのですが、単純に紙が好きなので書籍を購入しました。 なお、書籍が想定しているバージョンは3.5.1です。
「Pythonチュートリアル 第3版」を一通り読み込みました。
なお、Pythonチュートリアルは、プログラミングの基礎についてはあまり書かれていません。 そのため、プログラミング自体の経験がない方は、必要に応じてもっと基礎的な内容を ていねいに説明した本を併せて読むほうが勉強を進めやすいかもしれません。
書籍を読んで気になった箇所はJupyter Notebook(厳密にはAzure Notebooks)に コードと自分用の説明を書いて「動くあんちょこ」としてまとめました。
まだこの試験対策の問題が見当たらなかったので、自分で問題を作って勉強仲間のコミュニティに出題していました。 正解と不正解の選択肢を考えて作ることで、勘違いしやすい仕様や曖昧な理解の箇所も整理できた気がします。
Pythonの基礎を身に付けるける良いきっかけになったと思います。 PythonにはNAPALMのように開発が活発なネットワーク機器向けのライブラリがありますし、Pythonが読めるとAnsibleの詳細な挙動も読み取れたりするので、今後もPythonとのお付き合いはこれからも続くと思います。
ネットワーク自動化関連で、気になっている書籍が2つあるのでご紹介します。 どちらも現在のところ2017年8月発売予定となっています。
https://www.amazon.co.jp/dp/1491931256/
自動化に向けてネットワークエンジニアが身に着けるべきスキルについての書籍。 オライリーのサイトで、Early Release 版がチラ見できます。 https://library.oreilly.com/book/0636920042082/network-programmability-and-automation/toc
「そもそもJSON、YAMLとは何か」といった説明もあり、結構基礎的なことも書かれているようです。
https://www.amazon.co.jp/dp/B06XPQV549/
Python をベースとしたネットワーク自動化についての書籍で、Ansibleについても書かれているようです。
以下引用です。
What you will learn
Ansible 2.3 でCombination Filters というリストの組み合わせを生成するフィルターが追加されました。 公式ドキュメントに使用例が載っていますが、いくつか実際に試してみて出力結果を含めて確認します。
Filters — Ansible Documentation
1つのリストを元に組み合わせを生成します。
例:リスト[1,2,3,4,5]
から2つ選ぶ組み合わせを生成する
- name: give me combinations for sets of 2 debug: msg="{{ [1,2,3,4,5]|combinations(2)|list }}"
"msg": [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ] ]
Python の zip
関数のように、リストから組み合わせを生成します。
2つのリストの長さが異なる場合は、短いほうに合わせられます。
例:2つのリストが統合する
- name: give me shortest combo of 2 lists debug: msg="{{ [1,2,3]|zip(['a','b','c','d','e','f'])|list }}"
"msg": [ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]
Python の zip_longest
関数のように、リストから組み合わせを生成します。
前述の zip
とは異なり、2つのリストの長さが異なる場合は、長いほうに合わせられます。
足りない部分はfillvalue
で指定したもので補完されます。
例:3つのリストを統合し、足りない部分は 'X'
で補完する
- name: give me longest combo of 3 lists , fill with X debug: msg="{{ [1,2,3]|zip_longest(['a','b','c','d','e','f'], [21, 22, 23], fillvalue='X')|list }}"
"msg": [ [ 1, "a", 21 ], [ 2, "b", 22 ], [ 3, "c", 23 ], [ "X", "d", "X" ], [ "X", "e", "X" ], [ "X", "f", "X" ] ]
他の方法で代替できるケースもありそうですが、複雑になる場合はこれらのフィルターを利用するのが便利そうです。
以上です。
Netmiko とは、Cisco IOS や Juniper Junos などのネットワーク機器にSSHでログインして操作するのを助けてくれるPythonのライブラリです。 例えば、ログインやコンフィギュレーションモードへの移行、ログアウトなどの操作は関数として抽象化されています。 IPアドレスやOSPFの設定など、細かい設定はコマンドを直接指定するタイプです。
上記リポジトリの説明にはSSH接続と記載されていますが、過去のリリースノート等を確認するとTELNETでも接続できるようです。 今回はCisco IOS機器へのTELNETを試してみます。
[参考] Netmiko 1.0 Release · Issue #245 · ktbyers/netmiko · GitHub
[通常の使い方] Netmiko Quickstart - Network to Code, LLC
【ご注意】 盗聴や改ざん等のセキュリティ上の観点により、 TELNETではなくSSHが推奨されます。 この記事はTELNETを推奨する意図はありません。 ネットワーク自動化系のライブラリやツールは、 CLIはSSH経由のものが多いため「TELNETが可能なものもある」 ということを知識、経験としておさえておくために 検証した結果を記事にしたものです。
Netmiko をインストールします。
pip install netmiko
以下の要件のコードを記述します。
description
を設定running-config
を確認Netmiko の仕様として、通常通りSSHであれば device_type
に "cisco_ios"
と指定するところ、 "cisco_ios_telnet"
と指定するところがポイントです。
from netmiko import ConnectHandler # デバイスのタイプやIPアドレス、認証情報をディクショナリで定義 cisco = { "device_type": "cisco_ios_telnet", "ip": "192.168.1.13", # 接続先のCisco IOS機器 "username": "testuser", # ログインユーザー "password": "testpassword", # ログインパスワード "secret": "enablepassword" # enable パスワード } # TELNET接続して、コネクションオブジェクトを取得 net_connect = ConnectHandler(**cisco) # 特権モードへ移行する net_connect.enable() print("--- [●事前確認] ---") # show コマンドを実行 output = net_connect.send_command("show run int vlan 1") # 結果を出力 print(output) # 実行したい設定コマンドをリストで定義 lines = ["int vlan 1", "description hogehoge"] # 設定コマンドを実行(事前のconf tも自動で実行される) output= net_connect.send_config_set(lines) print("\n--- [●事後確認] ---") # show コマンドを実行 output = net_connect.send_command("show run int vlan 1") # 結果を出力 print(output) # 切断 net_connect.disconnect()
以下のように description が正常に追加されました。
--- [●事前確認] --- Building configuration... Current configuration : 77 bytes ! interface Vlan1 ip address 10.0.101.1 255.255.255.0 ip ospf cost 10 end --- [●事後確認] --- Building configuration... Current configuration : 99 bytes ! interface Vlan1 description hogehoge ip address 10.0.101.1 255.255.255.0 ip ospf cost 10 end
念のため、本当にTELNET接続しているのか確認します。ここでは wireshark でパケットキャプチャして確認します。
※自身の管理下の環境で確認しています。
さらに 「Follow TCP Stream」で当該TELNETセッションを流れを確認します。
Netmiko を利用して、TELNET経由で Cisco IOS 機器へ簡単な設定をすることができました。 ただし、冒頭の注意書きの通りTELNETはセキュリティ観点で推奨されません。 もし、既存の自動化システムの調査していてNetmikoが利用されている場合、SSHだと決めつけずにtelnetかもしれないという確認のきっかけにはなるかと思います。
マルチベンダー対応のネットワーク機器制御ライブラリのNAPALMには、ansibleと連携するための napalm-ansible
というモジュール群があります。
今回はその中の napalm_get_facts
というモジュールを利用して Cisco IOS 機器の様々な情報を取得してみます。
GitHub - napalm-automation/napalm-ansibleGitHub - napalm-automation/napalm-ansible
[参考情報(Aristaでの例)]
AnsibleとNAPALMの連携を試してみた – ネットワークエンジニアが日々の出来事を語る
なお、標準モジュールである ios_facts
を利用する場合は、以下の記事をご参照ください。
あらかじめ NAPALM をインストールします。
pip install napalm
napalm-ansible
モジュール群のダウンロードと配置git clone https://github.com/napalm-automation/napalm-ansible.git
napalm-automation
ディレクトリ配下の library
ディレクトリを、作成予定の 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
基本的な情報が取得できました。
前述のように filter
オプションでは情報取得する対象を指定することができます。
指定できるものは Cisco IOS の場合は以下の通りです。
指定できる値は、napalm-automation
自身のドキュメントには記述されいませんが、
NAPALM本体の「Getters support matrix」のIOS(今回の場合)の列を見ると分かります。
Supported Devices — NAPALM 1 documentation
例)
get_config に対応していれば filter
に config
が指定でき、以下のように記述できる。
napalm_get_facts: hostname: "{{ inventory_hostname }}" provider: "{{ cli }}" filter: - "config"
それぞれどのように取得できるのか試します。 ※あまり設定が入っていない機器で試したので情報が少ないです。
今回の環境では特に通信していないため空となりました。
"arp_table": []
今回の環境ではBGPは未設定のため空となりました。
"bgp_neighbors": {}
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": { "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": { "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": { "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": { "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 }, (省略) } }
IPアドレスが設定されているインターフェースの情報が取得できました。
"interfaces_ip": { "GigabitEthernet1": { "ipv4": { "10.0.0.51": { "prefix_length": 24 } } } }
今回の環境では未設定のため空となりました。
"lldp_neighbors": {}
今回の環境では未設定のため空となりました。
"lldp_neighbors_detail": {}
今回の環境では未通信のため空となりました。
"mac_address_table": []
今回の環境では未設定のため空となりました。
"ntp_servers": {}
今回の環境では未設定のため空となりました。
"ntp_stats": []
今回の環境ではSFP等のスロットはないため空となりました。
"optics": {}
今回の環境では未設定のため特に意味のない値となりました。
"snmp_information": { "chassis_id": "%SNMP agent not enabled", "community": {}, "contact": "unknown", "location": "unknown" }
稼働中のネットワーク機器の情報を収集したいケースは割とよくあると思いますが、自作しなくてもここまでできますので、もし、取得したい情報がこのモジュールで取得できるのであれば、利用してみるのもよいのではないでしょうか。
なお、Ansible を利用せずに、pythonスクリプト中でなるべくパース処理の手間を省きたい場合は、TextFSMというライブラリと ntc-template というテンプレート集を利用するのが良いと思います。 github.com github.com