加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-16 00:19:14 所属栏目:大数据 来源:网络整理
导读:#包名: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 = sh
#包名: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("quitn"); $telnet->waitfor("/$prompt/");
						last SWITCH;
				   };

	/^SUPERMODE$/ && do {
						$this->super; $telnet->put("quitn");
						$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("supern");
		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-confign");

	#处理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 versionn");

	#处理disp ver的多页显示情况
	my ($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 startupn"); 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 startupn"); 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 startupn"); 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 startupn"); 
								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_servern");

						($pre,$match) = $telnet->waitfor('/User(.*)/');
						return 0 if !$match or $match !~ /User(.*)/;
						$telnet->put("$ftp_usern");
						$telnet->waitfor('/Password:$/');

						$telnet->put("$ftp_passwordn");
						$telnet->waitfor('/[ftp]$/');

						#3. 设置为二进制方式
						$telnet->put("binn"); $telnet->waitfor('/[ftp]$/');

						#4. 创建存放配置文件的目录
						$telnet->put("mkdir netconfign");
						$telnet->waitfor('/[ftp]$/');

						#5. 进入目录
						$telnet->put("cd netconfign");
						$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_namen");
						$telnet->waitfor('/[ftp]$/');
												
						#7. 进入备份目录
						$telnet->put("cd $dir_namen");
						$telnet->waitfor('/[ftp]$/');

						#8. 上传备份文件
						$telnet->put("put $config_namen"); ($pre,undef) =
						$telnet->waitfor('/[ftp]$/');
						
						return 0 if $pre !~ /200 PORT Command successful./;

						#退出ftp
						$telnet->put("quitn"); $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 usersn");
	#处理disp users的多页显示情况
	my ($prematch,$match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=
		$prematch; if($match =~ /--- More ---/){
			$telnet->put(" ");
		}
	}}while $match =~ /--- More ---/;

	$_ = $tmp_type; SWITCH: {
			do {
			# 生成命令行
			$in =~ /[+|*]s+d+s+VTYs+(d+)s+dd:dd:dds/; my $ui =
			$1; my $cmd = "user-interface vty $ui";

			if(! $this->sys){
				$telnet->put("systemn"); $telnet->waitfor("/$prompt/");
			}

			$telnet->put("$cmdn"); $telnet->waitfor("/$prompt/");

			$telnet->put("screen-length 0n"); $telnet->waitfor("/$prompt/");

			$telnet->put("quitn"); $telnet->waitfor("/$prompt/");
			
			$telnet->put("returnn"); $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 usersn");
	#处理disp users的多页显示情况
	my ($prematch,$match) = $telnet->waitfor("/--- More ---|$prompt/"); $in .=
		$prematch; if($match =~ /--- More ---/){
			$telnet->put(" ");
		}
	}}while $match =~ /--- More ---/;

	$_ = $tmp_type;

	SWITCH: {
			do {
			# 生成命令行
			$in =~ /[+|*]s+d+s+VTYs+(d+)s+dd:dd:dds/; my $ui =
			$1; my $cmd = "user-interface vty $ui";

			if(! $this->sys){
				$telnet->put("systemn"); $telnet->waitfor("/$prompt/");
			}

			$telnet->put("$cmdn"); $telnet->waitfor("/$prompt/");

			$telnet->put("undo screen-lengthn"); $telnet->waitfor("/$prompt/");

			$telnet->put("quitn"); $telnet->waitfor("/$prompt/");
			
			$telnet->put("returnn"); $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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读