对比分析Paramiko、Netmiko和NAPALM网络自动化的三大利器
开始使用自动化的用户应该首先对Python 脚本语言和数据结构有基本的了解,例如列表、元组、字典和集合。他们还想学习Jinja2模板语言和YAML(YAML 不是标记语言)的基础知识。当用户结合 Python 脚本、用于模板的 Jinja2、用于数据表示的 YAML 和下面的自动化库时,用户将获得一个强大的自动化框架。
自动化库
使用 Python 和自动化库的网络自动化可以简化与网络设备的通信。在本文中,我们将介绍三个网络自动化库:Paramiko、Netmiko 和 NAPALM,或具有多供应商支持的网络自动化可编程抽象层。每个库都建立在其前身之上,以提供更多的抽象层,使用户能够构建更高效的自动化系统。
Paramiko
Paramiko是一个低级安全外壳 (SSH) 客户端库。我们可以使用它以编程方式控制通过安全 SSH 连接连接到网络设备的命令行界面 (CLI)。使用该库,用户可以发送一个人通常会键入的命令并解析每个命令的执行结果,也称为屏幕抓取。
下面的 Python 脚本使用 Paramiko 库来查询 Cisco Catalyst 3560 路由器的地址解析协议 ( ARP ) 表。脚本的第一步是识别设备所连接的交换机端口。
#!/usr/bin/env python3
import sys
from time import sleep
import paramiko
router = "192.168.1.108"
# Create an ssh connection and set terminal length 0
conn = paramiko.SSHClient()
conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
conn.connect(router, username="tester", password="foobar")
router_conn = conn.invoke_shell()
print('Successfully connected to %s' % router)
router_conn.send('terminal length 0\n')
sleep(1) # Wait for the cmd to be sent and processed
# Send the command and wait for it to execute
router_conn.send("show arp\n")
sleep(2)
# Read the output, decode into UTF-8 (ASCII) text, and print
print(router_conn.recv(5000).decode("utf-8"))
第 1 到 5 行导入我们需要的附加库并定义我们要查询的路由器的 IP 地址。第 7 到 14 行创建到路由器的 SSH 连接并使用名称tester和密码foobar登录。发送命令以禁用输出分页。第 16 到 18 行发送show arp命令,第 21 行读取命令结果并打印它。脚本结束时连接关闭。
结果如下:
$ ./paramiko-example.py
Successfully connected to 192.168.1.108
test-sw>terminal length 0
test-sw>show arp
Protocol Address Age (min) Hardware Addr Type Interface
Internet 192.168.1.1 1 0025.9c1a.4c89 ARPA Vlan1
Internet 192.168.1.3 0 0c84.dcc4.8569 ARPA Vlan1
Internet 192.168.1.108 - bcc4.933e.49c0 ARPA Vlan1
Internet 192.168.1.141 0 4c32.7596.b70b ARPA Vlan1
test-sw>
Paramiko 为网络设备提供了一个低级的 SSH 接口。许多因设备型号而异的参数都编码在脚本中,包括不同操作系统的命令语法变化。此外,我们还必须处理收集数据、更改配置和验证这些更改的所有细节。要进行配置更改,我们需要管理流程的每个步骤——启用访问、进入配置模式、发送更改和保存更改。幸运的是,其他框架,比如 Netmiko,为我们做了很多这样的工作。
Netmiko
该Netmiko库可以帮助用户隐藏的常用设备通信功能的许多细节。它使用 Paramiko 进行低级 SSH 连接,但它提供了与各种网络设备模型通信的更大抽象。Netmiko 支持的设备范围很广,Netmiko 脚本比 Paramiko 脚本短很多,如下所示。
#!/usr/bin/env python3
import sys
from time import sleep
from netmiko import ConnectHandler
dev = {
'device_type': 'cisco_ios',
'host': '192.168.1.108',
'username': 'tester',
'password': 'foobar',
} # Use a dictionary to pass the login parameters
# Connect to the device
router_conn = ConnectHandler(**dev)
# Send the command and print the result
print(router_conn.send_command("show arp\n"))
第 1 到第 4 行导入必要的模块,第 5 到第 10 行然后创建一个 Python 字典,其中包含此设备的连接参数。当使用许多设备时,用户将需要额外的代码来迭代设备,他们可以通过字典列表轻松完成。设备连接是一行,另一行发送命令并打印输出。
Netmiko 输出也更短,从命令输出周围剥离了设备提示:
$ ./netmiko-example.py
Protocol Address Age (min) Hardware Addr Type Interface
Internet 192.168.1.1 1 0025.9c1a.4c89 ARPA Vlan1
Internet 192.168.1.3 0 0c84.dcc4.8569 ARPA Vlan1
Internet 192.168.1.108 - bcc4.933e.49c0 ARPA Vlan1
Internet 168.1.141 0 4c32.7596.b70b ARPA Vlan1
Netmiko 使用device_type定义来正确处理与设备的通信,我们不必做任何特定于设备的工作。虽然 Netmiko 使用户能够发出设备命令并获得响应,但它并不能自动进行配置管理。这就是我们使用 NAPALM 的地方。
NAPALM
NAPALM建立在 Netmiko 之上,提供了一种与设备配置交互的机制。它支持比 Netmiko 更小的一组设备:Arista、Juniper 和 Cisco(IOS、IOS XR、NX-OS 和 NX-OS SSH)。它还支持检索基本设备数据的大量getter函数。以下脚本使用get_arp_table()函数:
#!/usr/bin/env python3
import sys
import time
import napalm
import os
import json
dev_type = 'ios'
dev_creds = {
'hostname': '192.168.1.108',
'username': 'tester',
'password': 'foobar',
'optional_args': {'secret': 'foobar'}
} # Use a dictionary for the login parameters
driver = napalm.get_network_driver(dev_type)
conn = driver(**dev_creds)
conn.open()
output = conn.get_arp_table()
print(json.dumps(output, indent=2))
conn.close()
使用 NAPALM 的设置比使用 Netmiko 的时间长,因为它需要更多的库,并且必须以不同的方式指定登录参数,如第 2 到 13 行。在第 15 到第 17 行建立连接。最后,检索 ARP 表信息。
NAPALM 以 Python 字典格式返回它,所以我们使用一个库函数来漂亮地打印它:
$ ./napalm-example.py
[
{
"interface": "Vlan1",
"mac": "00:25:9C:1A:4C:89",
"ip": "192.168.1.1",
"age": 0.0
},
{
"interface": "Vlan1",
"mac": "0C:84:DC:C4:85:69",
"ip": "192.168.1.3",
"age": 0.0
},
{
"interface": "Vlan1",
"mac": "BC:C4:93:3E:49:C0",
"ip": "192.168.1.108",
"age": 0.0
},
{
"interface": "Vlan1",
"mac": "4C:32:75:96:B7:0B",
"ip": "192.168.1.141",
"age": 2.0
}
]
字典输出可以直接在 Python 中使用。其他库提供 CLI 文本输出,必须将其转换为 Python 数据结构才能用于其他目的。
NAPALM 的真正强大之处在于它能够处理配置,包括以下内容:
- 配置替换
- 配置合并
- 配置比较
- 提交部署的配置
- 丢弃候选配置
- 回滚到先前的配置