Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion lib/SNMP/Info/Layer3/Huawei.pm
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ $VERSION = '3.973000';
'HUAWEI-IF-EXT-MIB' => 'hwTrunkIfIndex',
'HUAWEI-L2IF-MIB' => 'hwL2IfPortIfIndex',
'HUAWEI-POE-MIB' => 'hwPoePower',
'HUAWEI-SYS-MAN-MIB' => 'hwPatchVersion',
'HUAWEI-ENTITY-EXTENT-MIB' => 'hwEntityFanState',
);

Expand Down Expand Up @@ -97,6 +98,9 @@ $VERSION = '3.973000';
# HUAWEI-ENTITY-EXTENT-MIB::hwPwrStatusTable
'hw_pwr_state' => 'hwEntityPwrState',
'hw_pwr_descr' => 'hwEntityPwrDesc',

# HUAWEI-SYS-MAN-MIB::hwPatchFileTable
'hw_patch_version' => 'hwPatchVersion',
);

%MUNGE = (
Expand All @@ -121,13 +125,61 @@ sub os {

if ( defined ($descr) && $descr =~ /\b(VRP)\b/ ) {
return $1;
}elsif ( defined ($descr) && $descr =~ /\b(YunShan OS)\b/i ) {
return "YunShan OS";
} else {
return "huawei";
}
return "huawei";
}

sub os_ver {
my $huawei = shift;

my $patchstr = $huawei->_os_patch();
# Prefer extracting uniform V600R023C10SPC500-style version strings from sysDescr first
# we trim the base kernel version like 5.170 to make the netdisco inventory page nicer
my $descr = $huawei->description();
if ( defined $descr && $descr =~ /(V\d{3}[A-Za-z0-9]+)/ ) {
return $patchstr ? ($1 . " ".$patchstr) : $1;
#return $1 + $patchstr;
}else{
# if there is no version in the V\d{3}-style, use the old approach of returning more
return $huawei->_os_ver_legacy();
}
}

sub _os_patch {
my $huawei = shift;

# Patches are based on the release, e.g.
# os_ver hw_patch_version
# V600R023C10SPC500 -> V600R023HP1501 -> Hot Patch 1501
# V200R011C10SPC600 -> V200R011SPC102 -> Service Pack Collection 102
# V200R011C10SPC600 -> V200R011SPH033 -> Special Patch Hotfix 033
# V200R022C00SPC100 -> V200R022CO0SPC100B189 -> APs are somehow different, this is AP Build 189 - just use B189
# V200R023C00SPC100 -> V200R023CO0SPH180 -> APs without baseline in patch name, use SPH180
#
# we only return the last segment like HP1501

my $patches = $huawei->hw_patch_version();

# hwPatchTable.hwPatchEntry.hwPatchVersion should only return one row (at a somewhat random-looking index),
# but we join up multiple results just in case
my $patchstr = join ' ',
map {
my $s = $_;
$s =~ s/^V\d{3}R\d{3}//; # drop VRP prefix
$s =~ s/.*?([A-Z]+\d+)$/$1/; # only use last suffix to skip the extra bits in APs
$s;
} values %$patches;

return $patchstr;
}


sub _os_ver_legacy {
my $huawei = shift;

my $entity_os = $huawei->entity_derived_os_ver();
if ( defined $entity_os and $entity_os !~ /^\s*$/ ) {
return $entity_os;
Expand Down
88 changes: 78 additions & 10 deletions xt/lib/Test/SNMP/Info/Layer3/Huawei.pm
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ sub setup : Tests(setup) {
'_hw_fan_descr' => 1,
'_hw_pwr_state' => 1,
'_hw_pwr_descr' => 1,
'_hw_patch_version' => 1,

'store' => {
'hw_patch_version' => { },
'i_index' => {1 => 1, 6 => 6, 7 => 7, 8 => 8, 108 => 108},
'i_description' => {
1 => 'InLoopBack0',
Expand Down Expand Up @@ -120,54 +122,120 @@ sub vendor : Tests(2) {
is($test->{info}->vendor(), 'huawei', q(Vendor returns 'huawei'));
}

sub os : Tests(3) {
sub os : Tests(5) {
my $test = shift;

can_ok($test->{info}, 'os');
is($test->{info}->os(), 'VRP', q(OS returns 'VRP' when description matches));
is($test->{info}->os(), 'VRP', q(OS returns 'VRP' when V100 description matches));

my $descr = "Huawei YunShan OS\nVersion 1.23.1.1 (S5700 V600R023C10SPC500)\n"
."Copyright (C) 2021-2024 Huawei Technologies Co., Ltd.";
$test->{info}{_description} = $descr;
is($test->{info}->os(), 'YunShan OS', q(OS returns 'YunShan OS' when V600 description matches));

$descr = "Huawei Versatile Routing Platform Software\r\nVRP (R) software,Version 5.170 (S5700 V200R011C10SPC600)\r\n"
."Copyright (C) 2007 Huawei Technologies Co., Ltd.";
$test->{info}{_description} = $descr;
is($test->{info}->os(), 'VRP', q(OS returns 'VRP' when V200 description matches));

$test->{info}->clear_cache();
is($test->{info}->os(), 'huawei', q(... and 'huawei' when it doesn't));
is($test->{info}->os(), 'huawei', q(... and 'huawei' as fallback if nothing else matches));
}

sub os_ver_with_patch : Tests(2) {
my $test = shift;

can_ok($test->{info}, 'os_ver');

my $descr = "Huawei YunShan OS\nVersion 1.23.1.1 (S5700 V600R023C10SPC500)\n"
."Copyright (C) 2021-2024 Huawei Technologies Co., Ltd.";
$test->{info}{_description} = $descr;
$test->{info}{store}{hw_patch_version}{'1'} = 'V600R023HP1501';
#$test->{info}{store}{hw_fan_state}{'1.2'} = 'normal';
is(
$test->{info}->os_ver(),
'V600R023C10SPC500 HP1501',
q(OS version returned with patch example 1)
);
}

sub os_patch : Tests {
my $test = shift;

can_ok($test->{info}, '_os_patch');

# more explanation is in _os_patch
my %cases = (
'V600R023HP1501' => 'HP1501',
'V200R011SPC102' => 'SPC102',
'V200R011SPH033' => 'SPH033',
'V200R022C00SPC100B189' => 'B189',
'V200R023CO0SPH180' => 'SPH180',
);

while (my ($input, $expected) = each %cases) {
$test->{info}{store}{hw_patch_version} = { '1' => $input };
is( $test->{info}->_os_patch(), $expected, "extracting patch from $input" );
}
}

sub os_ver : Tests(7) {

sub os_ver : Tests(9) {
my $test = shift;

can_ok($test->{info}, 'os_ver');

is(
$test->{info}->os_ver(),
'8.100 V100R005C10SPC200',
'V100R005C10SPC200',
q(OS version returned from 'sysDescr' example 1)
);

# this first batch is ending up in _os_ver_legacy

my $descr = 'Version 3.40, Release 0311P07 Quidway Series Router AR28-31 ';
$test->{info}{_description} = $descr;

is($test->{info}->os_ver(),
'3.40 0311P07', q(OS version returned from 'sysDescr'example 2));

$descr = 'Version 3.40, Feature 0308 Quidway Series Router AR46-40 ';
$test->{info}{_description} = $descr;

is($test->{info}->os_ver(),
'3.40 0308', q(OS version returned from 'sysDescr'example 3));

$descr = 'Version 3.40, Feature 0121L01.Quidway Router AR18-34E.';
$test->{info}{_description} = $descr;

is($test->{info}->os_ver(),
'3.40 0121L01', q(OS version returned from 'sysDescr'example 4));

# contemporary os_ver

$descr = 'software,Version 5.120 (AR151 V200R003C01SPC100) ';
$test->{info}{_description} = $descr;

is(
$test->{info}->os_ver(),
'5.120 V200R003C01SPC100',
'V200R003C01SPC100',
q(OS version returned from 'sysDescr'example 5)
);

$descr = "Huawei YunShan OS\nVersion 1.23.1.1 (S5700 V600R023C10SPC500)\n"
."Copyright (C) 2021-2024 Huawei Technologies Co., Ltd.";
$test->{info}{_description} = $descr;
is(
$test->{info}->os_ver(),
'V600R023C10SPC500',
q(OS version returned from 'sysDescr'example 6)
);

$descr = "Huawei Versatile Routing Platform Software\r\nVRP (R) software,Version 5.170 (S5700 V200R011C10SPC600) \r\n"
."Copyright (C) 2007 Huawei Technologies Co., Ltd.";
$test->{info}{_description} = $descr;
is(
$test->{info}->os_ver(),
'V200R011C10SPC600',
q(OS version returned from 'sysDescr'example 7)
);

$test->{info}->clear_cache();
is($test->{info}->os_ver(), undef, q(No data returns undef OS version));
}
Expand Down