当前位置: 代码迷 >> 交换机/路由器 >> Perl访问华为系列交换机路由器配备参数模块
  详细解决方案

Perl访问华为系列交换机路由器配备参数模块

热度:2422   发布时间:2013-02-26 00:00:00.0
Perl访问华为系列交换机路由器配置参数模块
#包名:HWNET 功能:对华为交换机和路由器进行自动维护的包 引用方法:use HWNET;#package HWNET;use strict; use Data::Dump qw(dump); use Net::Telnet; use POSIX qw(strftime);use Net::Ping;## 用于测试的子程序#sub test{	#读取子程序参数	my $this = shift;	my $telnet = $this->{'TELNET_OBJECT'}; 	my $prompt = $this->{'PROMPT'};	$telnet->put("\n");	#my ($prematch, $match) = $telnet->waitfor("/$prompt/");	print $telnet->lastline;		return ;}## 功能:支持的设备型号列表##   列表项示例:#	 S8016' => 'Quidway S8016 Routing Switch'#      ^#	设备型号 'disp ver'命令输出结果中标志设备型号的特征字符串## 说明: 如果需要支持新的设备型号支持,需要在此列表中增加相应的条目#my %device_type_list =(	'S8016'				=>	'Quidway S8016 Routing Switch', 	'NE05'				=>	'Quidway NetEngine 05',	'NE40-8'			=>	'Quidway NetEngine 40-8 Universal Switching Router', 	'NE16'				=>	'Quidway NetEngine 16E', 	'AR46-40'			=>	'Quidway AR46-40', 	'S3050'				=>	'Quidway	S3050C', 	'S2026'				=>	'Quidway S2026', 	'S2403H-EI'		=>	'Quidway S2403H-EI',	'S3526E'			=>	'Quidway S3526E', 	'S2008-EI'			=>	'Quidway S2008-EI', 	'S3050C'			=>	'Quidway S3050C', 	);# 返回程序包支持的设备型号列表sub supported_device_type_list{	return keys %device_type_list;}## HWNET对象的构造器#sub new{	my $class = shift; 	my $this = {				'STATE'=>'UNCONNECTED',				'INPUT_LOG'=>'in.txt',				'OUTPUT_LOG'=>'out.txt',				'TIMEOUT'=>5, 'PROMPT'=>''				};	return bless $this, $class;}##登录到网络设备的用户视图#sub reset{	my $this = shift;		# 关闭telnet对象	my $telnet = $this->{'TELNET_OBJECT'}; 	$telnet->close() if $telnet;	# 将各对象各属性复位到初始值	$this = {			'STATE'				=>	'UNCONNECTED',			'INPUT_LOG'		=>	'input_log.txt', 			'OUTPUT_LOG'	=>	'output_log.txt',			'TIMEOUT'		=>	5, 			'PROMPT'			=>	''			};		} sub login{	#读取子程序参数	my ($this, $host,$username, $password,$su_password) = @_;	my $prompt = $this->{'PROMPT'}; 	$prompt = '(?:<.+?>|\[.+?\])$' if !$prompt;	my $ret=undef; #设置子程序默认返回值	# 验证子程序执行的前提条件	return $ret if $this->{'STATE'} ne 'UNCONNECTED';		my $input_log = $this->{'INPUT_LOG'}; 	my $output_log = $this->{'OUTPUT_LOG'}; 	my $timeout = $this->{'TIMEOUT'}; 	my $telnet = Net::Telnet->new(		Timeout=>$timeout, 		Prompt=>"/$prompt/",		Input_log=>$input_log, 		Output_log=>$output_log, 		Errmode=>'return'	);	#如果建立telnet对象失败,返回	return $ret unless $telnet;	$this->{'STATE'}='CONNECTED'; #设置HWNET对象状态	#登录到普通用户模式	return $ret unless $telnet->open($host); 	my (undef, $match) =	$telnet->waitfor('/Password:|Username:/');	if($match eq 'Username:'){		return $ret unless $telnet->put($username."\n"); 		return $ret unless		$telnet->waitfor("/Password:/");	} 	return $ret unless $telnet->put($password."\n"); 	return $ret unless	$telnet->waitfor("/$prompt/");	$this->{'STATE'} = 'USERMODE';	#保存登录参数给后续操作使用	$this->{'TELNET_OBJECT'} = $telnet; 	$this->{'USERNAME'} = $username;	$this->{'PASSWORD'} = $password; 	$this->{'SU_PASSWORD'} = $su_password;	$this->{'PROMPT'} = $prompt;	$ret = 1; 	return $ret;}##退出登录#sub logout{	my $this = shift; 	my $state = $this->{'STATE'}; 	my $telnet =	$this->{'TELNET_OBJECT'}; 	my $prompt = $this->{'PROMPT'};	# 根据TELNET_OBJECT对象所处的不同状态进行不同的操作	$_ = $state;	SWITCH: { /^UNCONNECTED$/ && do {						last SWITCH;				   };	/^CONNECTED$/ && do {						last SWITCH;				   };	/^USERMODE$/ && do {						$telnet->put("quit\n"); $telnet->waitfor("/$prompt/");						last SWITCH;				   };	/^SUPERMODE$/ && do {						$this->super; $telnet->put("quit\n");						$telnet->waitfor("/$prompt/"); last SWITCH;					};	}		$this->{'STATE'} = 'UNCONNECTED'; $telnet->close if $telnet; $telnet =	undef;	return 1;}##进入super模式#sub super{		#读取子程序参数	my $this = shift;	my $telnet = $this->{'TELNET_OBJECT'}; return undef unless $telnet;		my $su_password = $this->{'SU_PASSWORD'};	my $prompt = $this->{'PROMPT'};	my	$state = $this->{'STATE'};	my $ret = undef;	my $myret = undef;	if($state eq 'USERMODE'){		#进入超级用户模式		$myret = $telnet->put("super\n");		goto out unless $myret;		my (undef, $match) = $telnet->waitfor("/ Password:|$prompt/i");		goto out if !defined($match);		if($match =~ /Password:/){			goto out unless $telnet->put($su_password."\n");			goto out unless	$telnet->waitfor("/$prompt/");		}				$this->{'STATE'} = 'SUPERMODE'; my $ret = 1;	}	out: return $ret;}##获取设备sysname#sub get_sysname{		#读取子程序参数	my $this = shift; my $ret = undef; my $in="";	my $telnet = $this->{'TELNET_OBJECT'}; my $prompt = $this->{'PROMPT'}; my	$state = $this->{'STATE'};	#进入super模式	$this->super;	# TODO: 此处需要进行错误处理	#读取设备版本信息	$telnet->put("disp current-config\n");	#处理disp current-config的多页显示情况	my ($prematch, $match); do{{		($prematch, $match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=		$prematch; if($match =~ /--- More ---/){			$telnet->put(" ");		}	}}while $match =~ /--- More ---/;	$in =~ /sysname (.+)\n/;	$ret = $1; return $ret;}##获取设备型号#sub get_device_type{	#读取子程序参数	my $this = shift; my $ret = undef; my $in="";	my $telnet = $this->{'TELNET_OBJECT'}; my $su_password =	$this->{'SU_PASSWORD'}; my $prompt = $this->{'PROMPT'}; my $state =	$this->{'STATE'};	$this->super;	#读取设备版本信息	$telnet->put("disp version\n");	#处理disp ver的多页显示情况	my ($prematch, $match); do{{		($prematch, $match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=		$prematch; if($match =~ /--- More ---/){			$telnet->put(" ");		}	}}while $match =~ /--- More ---/;	#根据设备特征串匹配设备类型	study $in; for(keys %device_type_list){		$ret = $_, last if $in =~ /$device_type_list{$_}/;	}	return $ret;}## TODO: 增加对于错误处理的可靠性#sub backup_config{		#读取参数	my $this = shift;	#读取ftp服务器的参数	my ($ftp_server, $ftp_user, $ftp_password) = @_; my $p =	Net::Ping->new('tcp', 5);	return 0 if ! $p->ping($ftp_server); # 如果ftp服务器无法ping通则返回	#设置telnet参数	my $telnet = $this->{'TELNET_OBJECT'}; my $su_password =	$this->{'SU_PASSWORD'}; my $prompt = $this->{'PROMPT'};	# 判断系统的类型	my $sys_name = $this->get_sysname; my $sys_type = $this->get_device_type;	print STDERR $sys_type, "\n";	#根据系统类型的不同执行不同的配置备份过程	$_ = $sys_type; SWITCH: {	//     && do { # 统一的过程						#0. 进入特权用户模式						$this->super;										#1. 确定配置文件名(要根据不同的设备型号来确定)						my ($pre, $match, $ret); my $config_name = 'config.cfg';						CONFIG_TYPE:{							/^NE05$/ && do{								$telnet->put("disp startup\n"); my								($prematch,undef) =								$telnet->waitfor("/$prompt/"); 								$prematch =~	/Next startup saved-configuration file:\s+(.+)$/m; 								$telnet->buffer_empty;								$config_name = $1; last CONFIG_TYPE;							};							/^S8016$/ && do{								$config_name = 'vrpcfg.zip'; last CONFIG_TYPE;							}; /^NE40-8$/ && do{								#$telnet->put("disp startup\n"); my								#($prematch,undef) =								#$telnet->waitfor("/$prompt/"); $prematch =~								#/Next startup saved-configuration								#file:\s+(.+)$/m;								$telnet->buffer_empty; 								$config_name = 'vrpcfg.zip'; 								last CONFIG_TYPE;							}; /^NE16$/ && do{								$telnet->put("disp startup\n"); my								($prematch,undef) =								$telnet->waitfor("/$prompt/"); $prematch =~ /Next startup saved-configuration file:\s+(.+)$/m; 								$telnet->buffer_empty;								$config_name = $1; last CONFIG_TYPE;							}; /^AR46-40$/ && do{								$telnet->put("disp startup\n"); 								my ($prematch,undef) = $telnet->waitfor("/$prompt/"); 								$prematch =~	/Next startup saved-configuration file:\s+(.+)$/m; 								$telnet->buffer_empty;								$config_name = $1; 								last CONFIG_TYPE;							}; /^S3050$/ && do{								$config_name = 'vrpcfg.txt'; 								last CONFIG_TYPE;							};							/^S3050C$/ && do{								$config_name = 'vrpcfg.txt'; 								last CONFIG_TYPE;							};														/^S3526E$/ && do{								$config_name = 'vrpcfg.txt'; 								last CONFIG_TYPE;							};							/^S2026$/ && do{								$config_name = 'vrpcfg.txt';								last CONFIG_TYPE;							}; /^S2403H-EI$/ && do{								$config_name = 'vrpcfg.txt';								last CONFIG_TYPE;							}; /^S2008-EI$/ && do{								$config_name = 'vrpcfg.txt';								last CONFIG_TYPE;							};						}						# 检查配置文件名						return 0 if $config_name eq '';						#2. 登录ftp服务器						# 延迟						sleep 2;						#						$telnet->put("ftp $ftp_server\n");						($pre, $match) = $telnet->waitfor('/User\(.*\)/');						return 0 if !$match or $match !~ /User\(.*\)/;						$telnet->put("$ftp_user\n");						$telnet->waitfor('/Password:$/');						$telnet->put("$ftp_password\n");						$telnet->waitfor('/\[ftp\]$/');						#3. 设置为二进制方式						$telnet->put("bin\n"); $telnet->waitfor('/\[ftp\]$/');						#4. 创建存放配置文件的目录						$telnet->put("mkdir netconfig\n");						$telnet->waitfor('/\[ftp\]$/');						#5. 进入目录						$telnet->put("cd netconfig\n");						$telnet->waitfor('/\[ftp\]$/');						#6. 生成备份目录名						my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);						$year += 1900; $mon += 1;						my $dir_name = "$year-$mon-${mday}_$sys_name";						$telnet->put("mkdir $dir_name\n");						$telnet->waitfor('/\[ftp\]$/');																		#7. 进入备份目录						$telnet->put("cd $dir_name\n");						$telnet->waitfor('/\[ftp\]$/');						#8. 上传备份文件						$telnet->put("put $config_name\n"); ($pre, undef) =						$telnet->waitfor('/\[ftp\]$/');												return 0 if $pre !~ /200 PORT Command successful\./;						#退出ftp						$telnet->put("quit\n"); $telnet->waitfor("/$prompt/");						last SWITCH;				   };#   /^$/ && do {#                       last SWITCH;#                  };	} return 1;}## 功能:将当前登录的vty终端设置为不暂停状态#sub set_vty_no_pause{	#读取子程序参数	my $this = shift; my $ret = undef; my $in="";	my $telnet = $this->{'TELNET_OBJECT'}; my $prompt = $this->{'PROMPT'}; my	$state = $this->{'STATE'};	my $tmp_type = $this->get_device_type;	$this->super;	#获取当前用户的虚拟终端号	$telnet->put("disp users\n");	#处理disp users的多页显示情况	my ($prematch, $match); do{{		($prematch, $match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=		$prematch; if($match =~ /--- More ---/){			$telnet->put(" ");		}	}}while $match =~ /--- More ---/;	$_ = $tmp_type; SWITCH: {			do {			# 生成命令行			$in =~ /[\+|\*]\s+\d+\s+VTY\s+(\d+)\s+\d\d:\d\d:\d\d\s/; my $ui =			$1; my $cmd = "user-interface vty $ui";			if(! $this->sys){				$telnet->put("system\n"); $telnet->waitfor("/$prompt/");			}			$telnet->put("$cmd\n"); $telnet->waitfor("/$prompt/");			$telnet->put("screen-length 0\n"); $telnet->waitfor("/$prompt/");			$telnet->put("quit\n"); $telnet->waitfor("/$prompt/");						$telnet->put("return\n"); $telnet->waitfor("/$prompt/");			last SWITCH;		}	}	$ret = 1; return $ret;}## 功能:将当前登录的vty终端设置为可暂停状态#sub set_vty_pause{	#读取子程序参数	my $this = shift; my $ret = undef; my $in="";		my $telnet = $this->{'TELNET_OBJECT'}; my $prompt = $this->{'PROMPT'}; my	$state = $this->{'STATE'};	my $tmp_type = $this->get_device_type;	$this->super;	#获取当前用户的虚拟终端号	$telnet->put("disp users\n");	#处理disp users的多页显示情况	my ($prematch, $match); do{{		($prematch, $match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=		$prematch; if($match =~ /--- More ---/){			$telnet->put(" ");		}	}}while $match =~ /--- More ---/;	$_ = $tmp_type;	SWITCH: {			do {			# 生成命令行			$in =~ /[\+|\*]\s+\d+\s+VTY\s+(\d+)\s+\d\d:\d\d:\d\d\s/; my $ui =			$1; my $cmd = "user-interface vty $ui";			if(! $this->sys){				$telnet->put("system\n"); $telnet->waitfor("/$prompt/");			}			$telnet->put("$cmd\n"); $telnet->waitfor("/$prompt/");			$telnet->put("undo screen-length\n"); $telnet->waitfor("/$prompt/");			$telnet->put("quit\n"); $telnet->waitfor("/$prompt/");						$telnet->put("return\n"); $telnet->waitfor("/$prompt/");			last SWITCH;		}	}	$ret = 1; return $ret;}## 功能:判断系统是否处理在system-view视图,是则返回1,否则返回0。#sub sys{	#读取子程序参数	my $this = shift;	my $telnet = $this->{'TELNET_OBJECT'}; my $prompt = $this->{'PROMPT'};	$telnet->put("\n"); my ($prematch, $match) = $telnet->waitfor("/$prompt/");	return 1 if $match =~ /\]$/; return 0 if $match =~ />$/; return 0;}sub send_ctrl_k{	my $this = shift;	my $telnet = $this->{'TELNET_OBJECT'}; my $prompt = $this->{'PROMPT'};	$telnet->put("\cK"); my ($prematch, $match) = $telnet->waitfor("/$prompt/");	return 1;}sub change_password{}##执行指定的命令#sub exec_cmd{	my $this = shift;	my $cmd = shift;	my $telnet = $this->{'TELNET_OBJECT'};	$telnet->cmd($cmd);} 1;