[python]路由表脚本生成程序


老实说这是老东西了,自己之前用scala写过,用ruby写过,这次是用python第二次实现,github上这种生成脚本也挺多的,自己全当是练手。
这个脚本其实就是把apnic提供的数据过滤出指定数据并解析然后生成路由表更新脚本的程序。用途相信各位也清楚,以下是自己重复造轮子的过程:

程序的主逻辑是读取apnic数据,用正则表达式过滤和解析,用解析出来的数据生成路由表修改脚本和恢复脚本。

首先是读取apnic数据。个人的方式是查找当前目录,然后脚本所在目录,如果再没有自动下载文件到脚本所在目录并返回。这里没有read on fly,即边下载边读,也没有比对并确保最新的逻辑。之后可以考虑加上。

使用正则表达式过滤并解析的代码如下。解析结果是个CIDR格式,即网关的IP和对应子网掩码的路由前缀数。原始数据中IP后面的数据是子网主机数。

理论上接下就直接用解析出来的CIDR生成脚本了,但是考虑到部分网站或者内网也要纳入这个脚本,所以个人额外加了个excluding_net的配置,解析代码如下:
excluding_net中支持#开始的注释,忽略空行,允许直接host或者CIDR格式的单行配置。

excluding_net配置样例

接下来才是用上面解析出来的CIDR数据生成脚本。在撰写如何生成脚本的代码中个人考虑了好久,主要是因为不同平台生成的脚本文件名,命令模式不同。
首先我可以确定一点,默认网关IP是可以通过命令得到,而不应该在生成脚本时决定。否则笔记本一会儿有线一会儿无线网关地址变化了就麻烦了。
第二是如果默认网关地址变化,那么恢复默认网关时即恢复脚本时,需要通过类似/tmp/prev_gw来交互。
再加上脚本头,一些容错处理的话,程序中嵌入脚本文本会很多,自然而然会想到模板。不过我并没有使用通用的模板,直接分离为脚本头和route设置命令,同时增加输出脚本名配置用于定位脚本头模板和输出的脚本的名字。配置如下:

这里字典的key是转换过的平台名,value的四个值分别是启动脚本名,启动脚本命令模板,恢复脚本名,恢复脚本命令模板。每个命令模板接受CIDR格式的tuple。
为了方便输出,个人用了个类来集合输出操作,这个类在初始化时就会把头模板填充进来。

基于上面类的输出代码,比没有类的时候要短小很多:

最后脚本还做了一点平台支持的逻辑,即根据sys.platform决定用那个平台,比如linux2 -> linux, darwin -> mac。上面代码的platform是转换过的平台关键字。另外支持命令行第一个参数指定平台。

完整代码在这里