网络管理:网络设备的批量化操作-创新互联

新浪微博: @wandering

创新互联公司是专业的定边网站建设公司,定边接单;提供网站设计、网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行定边网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

博客地址:  dayong.info

在深入进行网络工作一段时间后,开始着手解决AAA、NTP、SYSLOG基础服务(简称:基础服务)的可用性和线上设备相关配置的正确性问题。

前期,一边优化、重构基础服务,一边修正线上配置。但这个项目是个系统工程,无法在短期内完成,因此即要保持战果让已修正的配置不再出错,还希望新增加的设备可以直接进行正确配置。另外,如何保证其他工程师也正确配置设备,也是需要解决的问题,毕竟工作最终是需要多个团队共同协作的。

因此,自动检查线上所有重要交换机和路由器的网管服务、Spanning-Tree、VTP Mode等重要配置是否正确,成了必须优先解决的问题。

最直接的方法就是直接检查相应配置,这符合网络管理人员的思维和操作习惯。因此,决定优先解决多台设备的批量执行命令需求。

本人一直对程序设计有这样的观点,不能解决问题的程序不是好程序,因此程序首先要实现功能,其次才是程序的效能。只有在规模、需求达到相当程度后才有必要对效率、性能追求极致。对非专业开发人员来说更是要注意精力、时间的分配,20%的投入获得80%的回报其投入产出比是相当可观的,再多花80%的精力去提升最多20%的性能是必须慎重对待的。因此,决定采用模拟人机交互方式实现网络设备的批量化操作。

程序实现基本逻辑是:

 1)自动登录交换机、路由器批量执行命令,将结果输出。

 2)对输出结果进行二次处理,实现不同目标。

这样,基本可以解决大部分网络管理需要,其主要优点是简单,会操作交换机/路由器的人就可以使用。但是,此方法大的问题是效率,因为本质上只是由程序模仿手工操作,需要考虑cli可以接受的操作频率等问题。曾考虑过SNMP、TCL-Script、NET-CONF等方法,但考虑到自己的能力及精力分配、跨厂商平台兼容性问题最终放弃。

网上可以查到的模拟人工命令交互操作的方法有2个:perl、expect

首先考虑的是perl,因为有perl编程基础,有其他同事写好的相似功能脚本,但最终放弃。因为perl的switch模块不支持Cisco的Nexus平台内容输出,其解决方法非常复杂,要修改switch模块的源代码,这样会产生自己的分支,管理维护成本太高,不利于程序的持续开发和推广 。

最后,选择expect,其原理是执行命令,根据不同输出反馈采取不同操作,重复这个过程。

关于expect的学习使用,不在本文的关注范围。

以下最新版本的代码:

#!/usr/local/bin/expect
#
# Statement:      sw-telnet.exp    
#
#             ip for telnet
#     For example, sw-backup is cmd-prefix of sw-backup.cmd.h4c and
#                 sw-backup.cmd.cisco
#            uid for telnet
#            pwd for telnet
#
#
# Depends:        .cmd.h4c
#                 .cmd.cisco
#
# 
# Last modified:  2012/05/24
#
# 


set path_cmd "/aaa/bin"
set cmd_telnet "telnet"
set timeout_default 10
set timeout $timeout_default
set vendor "cisco"

# Arg 1
set ip [lindex $argv 0]
if { $ip == "" } {
   puts ""
   puts "Statement: command    "
   puts "                    ^^"
   puts "            ip for telnet"
   puts "    For example, sw-backup is cmd-prefix of sw-backup.cmd.h4c and"
   puts "                sw-backup.cmd.cisco"
   puts "           uid for telnet"
   puts "           pwd for telnet"
   puts ""
   exit 1
}

# Arg 2
set cmd_prefix [lindex $argv 1]
if { $cmd_prefix == "" } {
   puts ""
   puts "Statement: command    "
   puts "                         ^^^^^^^^^^"
   puts "            ip for telnet"
   puts "    For example, sw-backup is cmd-prefix of sw-backup.cmd.h4c and"
   puts "                sw-backup.cmd.cisco"
   puts "           uid for telnet"
   puts "           pwd for telnet"
   puts ""
   exit 1
}

# Arg 3
set uid [lindex $argv 2]
if { $uid == "" } {
   #set uid "backup"
   puts ""
   puts "Statement: command    "
   puts "                                      ^^^"
   puts "            ip for telnet"
   puts "    For example, sw-backup is cmd-prefix of sw-backup.cmd.h4c and"
   puts "                sw-backup.cmd.cisco"
   puts "           uid for telnet"
   puts "           pwd for telnet"
   puts ""
   exit 1
}
 
# Arg 4
set pwd [lindex $argv 3]
if { $pwd == "" } {
   #set pwd "M2dpSF6rSU"
   puts ""
   puts "Statement: command    "
   puts "                                            ^^^"
   puts "            ip for telnet"
   puts "    For example, sw-backup is cmd-prefix of sw-backup.cmd.h4c and"
   puts "                sw-backup.cmd.cisco"
   puts "           uid for telnet"
   puts "           pwd for telnet"
   puts ""
   exit 1
}




#___ start telnet ___

spawn $cmd_telnet "$ip"
sleep 1
expect "H3C" { set vendor "h4c" }
expect -re "Username:|Login:|login:" {
   send "$uid\r"
   sleep 1
}

expect "Password:" {
   send "$pwd\r"
   sleep 1
}


#_____ login failed _____
expect {
   "Access denied" { exit }
   "Connection refused" { exit }
   "Login failed" { exit }
   "Login incorrect" { exit }
   "Login invalid" { exit }
   "Password incorrect." { exit }
   "timeout expired!" { exit }
}



#_____ Command sets selection by vendor (cisco, h4c) _____

switch -- $vendor cisco { # vendor: cisco

   set timeout_cisco 60
   set timeout $timeout_cisco

   #___ get commands __
   set file [ open "$path_cmd/$cmd_prefix.cmd.$vendor" "r" ]
   set cmd_count 0
   while 1 {
      if { [gets $file line] == -1 } break
      incr cmd_count
      set cmd_list($cmd_count) $line
   }
   close $file

   expect -re ".*# *$"
   send "term len 0\r\n\n\n"

   set i 1
   while { $i <= $cmd_count } {
      expect -re ".*# *$"
      send "$cmd_list($i)\r\n\n\n"
      incr i
      sleep 1
   }
   
   expect -re ".*# *$"
   send "exit\r"

} h4c { # vendor: h4c

   set timeout_h4c 10
   set timeout $timeout_h4c

   #___ get commands __
   set file [ open "$path_cmd/$cmd_prefix.cmd.$vendor" "r" ]
   set cmd_count 0
   while 1 {
      if { [gets $file line] == -1 } break
      incr cmd_count
      set cmd_list($cmd_count) $line
   }
   close $file

   set i 1
   while { $i <= $cmd_count } {
      expect -re "<.*>$"
      send "$cmd_list($i)\r\r\r\r"

      expect -re "\- More \-+$" {
         set timeout 3
         set more "yes"
         while {$more == "yes"} {
            #puts "___ more ___\r"
            send " "
            expect -re "<.*>$" {
               #puts "___ there's no more ___"
               set more "no"
            }
         }
         set timeout $timeout_h4c
      }

      incr i
      sleep 1
   }
    
   expect -re "<.*>$"
   send "quit\r"
   
} default { # vendor: unkown

   puts "\nError: Unkown Vendor!\n"
   exit

}



expect eof
puts "\nVendor: $vendor"
puts "Command list:"
set i 1
while { $i <= $cmd_count } {
   puts "$i) $cmd_list($i)"
   incr i
}
puts ""
exit

*注:脚本目前只支持Cisco和H3C两个主流平台。


*注:注意设置程序运行路径变量 path_cmd 。

举例,假设需要对设备1.2.3.4做以下操作:

  1)备份running-config

  2)查看cpu状态

首先,需要建立4个文件,脚本会自动判断Cisco或H3C设备类型执行相应命令集:

  1)backup.cmd.cisco


dir show ver show inv show run

  2)backup.cmd.h4c

dir disp verion disp device manuinfo disp curr

  3)version.cmd.cisco

show process cpu sort | exclude 0.00% show process cpu history

  4)version.cmd.h4c

display cpu-usage

其次,写crontab:


0    3 * * *  /aaa/bin/sw-telnet.exp 1.2.3.4 backup  test_uid test_pwd  >  /bak/1.2.3.4_show-run_$(date +"%Y%m%d") 
*/10 * * * *  /aaa/bin/sw-telnet.exp 1.2.3.4 version test_uid test_pwd  >> /bak/1.2.3.4_show-ver_$(date +"%Y%m%d")

OK,这样就实现了对1.2.3.4的自动抓取running-config和记录cpu状态。



在此代码基础上,完成了以下工作:

  • 对全网重要设备抓取running-config,并实现关键配置检查报警

  • 对某产品相关服务器接入交换机端口进行流量监控、报警(公司监控不能查看port-channel属性)

  • 对某IDC核心交换机的mac地址表监控,增减幅度超过5%报警



自动批量执行命令脚本是核心代码,可以通过其它程序调用实现更复杂的功能,例如对多个IP批量操作,具体实现本文不再赘述。

希望本文能够对有需要的朋友有所帮助,程序代码可以任意使用。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:网络管理:网络设备的批量化操作-创新互联
浏览路径:http://myzitong.com/article/cdpsop.html