有关与Junos PyEZ一起使用的文章-“ Python微框架,使您可以管理和自动化运行Junos OS的设备”自动化和控制,这是我们所喜欢的一切。 编写本文中描述的脚本可实现多个目标-学习Python并自动化在运行Junos OS的设备上收集信息或更改配置的任务。 之所以选择该特定的Python + Junos PyEZ软件包,是因为进入Python编程语言的门槛低,而且Junos PyEZ库的易用性不需要Junos OS专业知识。
挑战赛
审核公司拥有的ipv4免费子网。 子网空闲的标准是在充当运行Junos OS的路由器的交换机上的路由中没有关于子网的记录。
实作
Python + Junos PyEZ,尽管通过paramiko和ssh.exec_command有诱惑力,
结果,有必要在被调查设备上为netconf设备配置网络管理协议。 在此示例中,Netconf通过远程过程调用(RPC)与设备配合使用,并使用XML提供接收的信息。
使用以下命令从PyPI安装当前版本的Junos PyEZ:
$ pip install junos-eznc
您还可以使用以下命令从GitHub上的项目的主要分支中进行安装:
$ pip install git+https://github.com/Juniper/py-junos-eznc.git
还有一个选择
$ pip install -r requirements.txt
此命令将安装系统中缺少的工作所需的库。 在我的
requirements.txt版本中,只有两个,在编写脚本时指出了最新版本:
junos-eznc netaddr
默认脚本使用系统中当前用户的名称,您可以使用密钥show_route.py -u <user_name> getpass.getpass以另一个用户的名称登录。getpass接受来自stdin的密码,因此该密码将不会保留在系统中。 要连接到设备,您还需要根据要求输入其主机名或ip地址。 已收到设备授权所需的所有数据。
Junos PyEZ支持通过ssh使用控制台,telnet或netconf连接到运行Junos OS的设备。 本文考虑了最后一个选择。
要连接到设备,使用jnpr.junos模块的Device类。
with jnpr.junos.Device(host=router, user=args.name, passwd=password) as dev:
通过远程过程调用或对远程过程的调用,发出有关路由器已知的所有路由的请求,对此更为方便。
data = dev.rpc.get_route_information()
Junos OS上的类似命令
user@router> show route | display xml
将rpc命令添加到命令的末尾,我们将获得请求标签,并将其与RPC方法的名称进行匹配,这样您就可以找到其他感兴趣的名称。 值得注意的是,编写请求标签的语法与方法名称不同,即用下划线替换连字符。
user@router> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1R1/junos"> <rpc> <get-route-information> </get-route-information> </rpc> </rpc-reply>
我收到了xml格式的路由数据,我只通过标签
<rt-destination> xxx.xxx.xxx.xxx/yy </ rt-destination>选择了我感兴趣的路由数据,并将其以字符串格式作为列表写入了变量,从而获得了一个列表繁忙的子网。
route_list = data.xpath("//rt-destination/text()")
我将其余部分包装在while循环中,以便在需要检查与路由器已知的子网不同的子网时,不重新执行对路由器的请求。 值得一提的是,我请求的路由器仅通过OSPF知道路由,因此,对于边界路由器,最好对请求进行一些更改以减少脚本时间
data = dev.rpc.get_ospf_route_information()
现在让我们看看while循环的内容
开始时,将提示用户输入一个带掩码的子网,并且该子网距同一子网的网络不得超过三个八位位组,这是设置搜索范围所必需的。 我不太喜欢这种设置条件和搜索范围的方法,但是到目前为止,我还没有找到更好的解决方案。 接下来,从所获得的route_list子网列表中,使用包含不超过三个八位位组的变量,选择我感兴趣的子网
tmp = re.search(r'^%s\S*' % subnet_search, route_list[i])
通过netaddr模块IPNetwork,我将子网作为ipv4地址列表
range_subnet = netaddr.IPNetwork(tmp.group(0))
使用用户通过掩码输入的网络中的IPNetwork,我得到了一个地址范围,并形成了该范围内所有地址的列表,以便与繁忙地址列表进行比较。
for i in set(net_list).difference(set(busyip)): freeip.append(i)
我得到了子网形式的免费地址列表
print(netaddr.IPSet(freeip))
以下是完整的脚本,已在ex4550,ex4600型号的路由器上测试过