ลองใช้ Nornir (Python Automation Framework) กับ Cisco IOS XR และ Nokia 7750 SR

Nornir อีกหนึ่ง Automation Tools สุดเจ๋งบน Python

Nopnithi Khaokaew (Game)
3 min readJul 8, 2019

— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —

— — — — — — — — — — — — — — — — — — — — — — — -

ฝากคอร์ส Python for Network Automation ผมด้วยครับ

— — — — — — — — — — — — — — — — — — — — — — — -

เห็นว่า Nornir ถูกปล่อยมาได้ประมาณปีนึงแล้ว(ตั้งแต่ May 2018) แต่ยังไม่มีคนไทยพูดถึงมันเลยบน internet ดังนั้นผมเลยขอชิงเปิดซิงก่อนเลยละกันครับ ฮ่า ๆ

Nornir คืออะไร?

Nornir (ชื่อเดิมคือ Brigade) คือ Python Automation Framework ซึ่งถูกออกแบบมาเป็น agentless ดังนั้นมันก็แค่ telnet หรือ SSH ตรงไปยัง remote device เพื่อจัดการได้เลย แน่นอนว่ามันก็จะคล้ายกับ Ansible นั่นแหละครับ

ความเหมือนและแตกต่างของ Nornir กับ Ansible

ในส่วนของ inventory เช่น hosts.yaml หรือ groups.yaml ของ Nornir นั้นมี concept เดียวกับ Ansible เลยโดยเขียนด้วย YAML เหมือนกัน

แต่ในส่วนจัดการ task นั้นต่างกันเพราะ Ansible จะใช้ Playbook ซึ่งต้องเขียนบน YAML ด้วย syntax ของมันเอง ในขณะที่ Nornir จะใช้การเขียนเป็น Python code เลย และนี่คือจุดเด่นของ Nornir เพราะมันมีความยืดหยุ่นกว่าเยอะ

Nornir ยืดหยุ่นกว่า Ansible ยังไง?

ปกติแล้วการใช้ Ansible อาจไม่มีปัญหาเลยถ้างาน automation ของคุณไม่ได้มีความซับซ้อนและตรงไปตรงมา เช่น หากคุณต้องการรัน show ip interface brief บน router สัก 50 ตัว จากนั้นบันทึก result ที่ได้ลง text file

แต่เมื่อใดที่คุณเริ่มมี condition ซับซ้อนมาก หรือโดยเฉพาะถ้าต้องมี condition ในการเชื่อมโยงระหว่าง task หรือโดยเฉพาะ host ขึ้นมาละก็…งานหยาบเลย (ถามว่าทำได้มั้ย ทำได้ครับ แต่บางทีมัน workaround จนน่ารำคาญและรกไป)

หรืออีกจุดด้อยเลยคือการนำ Ansible ไป integrate เข้ากับ backend ของ application ตัวอื่น ๆ เนี่ยไม่มีทาง smooth จนกลืนเป็นเนื้อเดียวกันแบบ Nornir แน่นอน

ดังนั้น Nornir ที่เกิดมาเพื่อให้เราจัดการกับ task ด้วย Python code อยู่แล้ว มันจึงยืดหยุ่นและสะดวกกว่ามากหาก coding skill ของเราอยู่ในระดับโปร

วิธีติดตั้ง Nornir และเริ่มต้นใช้งานแบบสั้น ๆ

ติดตั้ง Nornir ใน Python

pip3 install nornir

สร้าง directory ของ project นี้

ใครใช้ Windows ก็สร้างตามปกติไปนะครับ 555

mkdir hello_nornir
cd hello_nornir
mkdir inventory

สร้างไฟล์ config.yaml ใน hello_nornir/config.yaml

---
core:
num_workers: 40
inventory:
plugin: nornir.plugins.inventory.simple.SimpleInventory
options:
host_file: "inventory/hosts.yaml"
group_file: "inventory/groups.yaml"
defaults_file: "inventory/defaults.yaml"

สร้างไฟล์ hosts.yaml ใน hello_nornir/inventory/hosts.yaml

จากตัวอย่างนี้ถ้าใครจะทำตามเป๊ะ ๆ (แต่คงไม่มีมั้ง) จะไป error ตรง host ที่เป็น nokia ครับ เพราะตามจริง platform ต้องเป็น alcatel_sros ครับ แถมต้องไปแก้ code บางส่วนของ netmiko ด้วยเพราะมันมี bug อยู่ ซึ่งในที่นี้ผมได้ modify เอาไว้แล้ว

---
xr1:
hostname: 192.168.100.201
platform: iosxr
groups:
- cisco
data:
loopback:
0: 1.1.1.1
1: 11.11.11.11
xr2:
hostname: 192.168.100.202
platform: iosxr
groups:
- cisco
data:
loopback:
0: 2.2.2.2
1: 22.22.22.22
sr1:
hostname: 192.168.100.203
platform: nokia_sros
groups:
- nokia
data:
loopback:
0: 3.3.3.3
1: 33.33.33.33
sr2:
hostname: 192.168.100.204
platform: nokia_sros
groups:
- nokia
data:
loopback:
0: 4.4.4.4
1: 44.44.44.44

สร้างไฟล์ groups.yaml ใน hello_nornir/inventory/groups.yaml

---
main:
data:
domain: nopnithi.com
cisco:
username: nopnithi
password: cisco1234
data:
type: network_device
groups:
- main
nokia:
username: nopnithi
password: nokia1234
data:
type: network_device
groups:
- main

สร้างไฟล์ demo1.py ใน hello_nornir/demo1.py

เริ่มต้นแบบ basic สุด ๆ ลองประมาณนี้ดูครับ อันนี้เป็นการใช้ NAPALM ในการ get interface บน Cisco IOS XR ครับ

from nornir import InitNornir
from nornir.plugins.tasks import networking
from nornir.plugins.functions.text import print_result
nr = InitNornir(config_file='config.yaml')
xr = nr.filter(platform='iosxr')
result = xr.run(task=networking.napalm_get, getters=['interfaces'])
print_result(result)

สร้างไฟล์ demo2.py ใน hello_nornir/demo1.py

from nornir import InitNornir
# from nornir.plugins.tasks import commands
from
nornir.plugins.tasks import networking, text
from nornir.plugins.functions.text import print_result
from mylib.nokia_ssh import *

def run(task):
create_loopback_netmiko(task)
remove_loopback(task)

def create_loopback_netmiko(task):
r = task.run(
task=text.template_file,
name='Generate Configuration For Create Loopback Interface',
template='create_loopback.j2',
path=f'templates/{task.host.platform}'
)
task.host['config'] = r.result

task.run(
task=networking.netmiko_send_config,
name='Create Loopback Interface',
config_commands=task.host['config'].splitlines()
)

def create_loopback_mylib(task):
r = task.run(
task=text.template_file,
name='Create Loopback Interface',
template='create_loopback.j2',
path=f'templates/{task.host.platform}'
)
task.host['config'] = r.result
# Start: My SSH library for Nokia SR OS
mylib = NokiaSSH(
ip=task.host.hostname,
username=task.host.username,
password=task.host.password
)
mylib.connect()
mylib.disable_continue()
mylib.send_command_multiline(task.host['config'].splitlines())
mylib.save()
mylib.disconnect()
# End: My SSH library for Nokia SR OS
return
mylib.cleaned_output

def remove_loopback(task):
r = task.run(
task=text.template_file,
name='Generate Configuration For Remove Loopback Interface',
template='remove_loopback.j2',
path=f'templates/{task.host.platform}'
)
task.host['config'] = r.result

task.run(
task=networking.netmiko_send_config,
name='Remove Loopback Interface',
config_commands=task.host['config'].splitlines()
)

def show_interfaces_napalm(task):
result = task.run(task=networking.napalm_get, getters=['interfaces'])
return result

def filter_hosts(host):
return len(host.name) >= 10 and host.name[0] == 's'

if __name__ == '__main__':

nr = InitNornir(config_file='config.yaml')
cisco = nr.filter(platform='iosxr')
nokia = nr.filter(platform='nokia_sros')
some = nr.filter(filter_func=filter_hosts).inventory.hosts.keys()

result = nr.run(task=run, num_workers=4)
print_result(result)

สำหรับตัวอย่างนี้แนะนำว่าให้ลองไปดูในวิดีโอดีกว่าครับ ผมจะลองใช้งานให้ดูว่า Nornir มันยืดหยุ่นยังไงกันแน่

ลองใช้งาน Nornir (Python Automation Framework)

ข้อมูลเพิ่มเติม:
https://nornir.readthedocs.io/en/stable/

— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —

--

--

Nopnithi Khaokaew (Game)
Nopnithi Khaokaew (Game)

Written by Nopnithi Khaokaew (Game)

Cloud Solutions Architect & Hobbyist Developer | 6x AWS Certified, CKA, CKAD, 2x HashiCorp Certified (Terraform, Vault), etc.