MyException - 我的异常网
当前位置:我的异常网» 交换机/路由器 » Perl访问华为系列交换机路由器配备参数模块

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

www.MyException.Cn  网友分享于:2015-08-26  浏览:5次
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;

文章评论

程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
一个程序员的时间管理
一个程序员的时间管理
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员和编码员之间的区别
程序员和编码员之间的区别
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
总结2014中国互联网十大段子
总结2014中国互联网十大段子
Java程序员必看电影
Java程序员必看电影
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
那些争议最大的编程观点
那些争议最大的编程观点
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
我是如何打败拖延症的
我是如何打败拖延症的
每天工作4小时的程序员
每天工作4小时的程序员
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员必看的十大电影
程序员必看的十大电影
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
编程语言是女人
编程语言是女人
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
鲜为人知的编程真相
鲜为人知的编程真相
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
漫画:程序员的工作
漫画:程序员的工作
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
 程序员的样子
程序员的样子
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
旅行,写作,编程
旅行,写作,编程
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
我的丈夫是个程序员
我的丈夫是个程序员
程序员都该阅读的书
程序员都该阅读的书
为什么程序员都是夜猫子
为什么程序员都是夜猫子
代码女神横空出世
代码女神横空出世
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
中美印日四国程序员比较
中美印日四国程序员比较
10个调试和排错的小建议
10个调试和排错的小建议
程序员的鄙视链
程序员的鄙视链
老程序员的下场
老程序员的下场
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有