您的位置:首页 > 其它

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

2013-02-01 10:02 951 查看
#包名: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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: