#141 Avocent ACS files for correct discovery in Netdisco

Add support for ACS 5K/6K/8K terminal servers in Layer1::Cyclades requires new MIBs
Layer1::Cyclades test class
This commit is contained in:
Eric A. Miller
2018-03-31 23:25:10 -04:00
parent f676d27a3b
commit 0c711269ae
5 changed files with 864 additions and 51 deletions

View File

@@ -12,7 +12,7 @@ before_install:
- mkdir ~/netdisco-mibs
- cd ~/netdisco-mibs
install:
- curl -sL https://github.com/netdisco/netdisco-mibs/releases/download/4.006/netdisco-mibs.tar.gz | tar --strip-components=1 -zxf -
- curl -sL https://github.com/netdisco/netdisco-mibs/releases/download/4.007/netdisco-mibs.tar.gz | tar --strip-components=1 -zxf -
- cpanm --quiet --notest PkgConfig Test::CChecker Alien::zlib::Static Alien::OpenSSL::Static Alien::SNMP::MAXTC
before_script:
- 'cd ${TRAVIS_BUILD_DIR}'

View File

@@ -148,4 +148,5 @@ xt/lib/My/Test/Class.pm
xt/lib/Test/SNMP/Info.pm
xt/lib/Test/SNMP/Info/Layer1/Allied.pm
xt/lib/Test/SNMP/Info/Layer1/Asante.pm
xt/lib/Test/SNMP/Info/Layer1/Cyclades.pm
xt/lib/Test/SNMP/Info/Layer3/Timetra.pm

View File

@@ -474,7 +474,7 @@ See documentation in L<SNMP::Info::Layer1::Bayhub> for details.
=item SNMP::Info::Layer1::Cyclades
Subclass for Cyclades terminal servers.
Subclass for Cyclades/Avocent terminal servers.
See documentation in L<SNMP::Info::Layer1::Cyclades> for details.
@@ -1582,6 +1582,7 @@ sub device_type {
8072 => 'SNMP::Info::Layer3::NetSNMP',
9303 => 'SNMP::Info::Layer3::PacketFront',
10002 => 'SNMP::Info::Layer2::Ubiquiti',
10418 => 'SNMP::Info::Layer1::Cyclades',
12325 => 'SNMP::Info::Layer3::Pf',
12356 => 'SNMP::Info::Layer3::Fortinet',
14179 => 'SNMP::Info::Layer2::Airespace',
@@ -1621,6 +1622,7 @@ sub device_type {
5624 => 'SNMP::Info::Layer3::Enterasys',
6486 => 'SNMP::Info::Layer3::AlcatelLucent',
9303 => 'SNMP::Info::Layer3::PacketFront',
10418 => 'SNMP::Info::Layer1::Cyclades',
11898 => 'SNMP::Info::Layer2::Orinoco',
14179 => 'SNMP::Info::Layer2::Airespace',
14525 => 'SNMP::Info::Layer2::Trapeze',
@@ -1631,6 +1633,7 @@ sub device_type {
my %l1sysoidmap = (
2925 => 'SNMP::Info::Layer1::Cyclades',
10418 => 'SNMP::Info::Layer1::Cyclades',
);
my %l7sysoidmap = (

View File

@@ -1,7 +1,7 @@
# SNMP::Info::Layer1::Cyclades
# $Id$
#
# Copyright (c) 2008 Eric Miller
# Copyright (c) 2018 Eric Miller
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -43,34 +43,101 @@ $VERSION = '3.53';
%MIBS = (
%SNMP::Info::Layer1::MIBS,
'CYCLADES-ACS-SYS-MIB' => 'cyACSversion',
'CYCLADES-ACS-CONF-MIB' => 'cyEthIPaddr',
'CYCLADES-ACS-INFO-MIB' => 'cyISPortTty',
'CYCLADES-ACS-SYS-MIB' => 'cyACSversion',
'CYCLADES-ACS5K-SYS-MIB' => 'cyACS5Kversion',
'CYCLADES-ACS-CONF-MIB' => 'cyACSConf',
'CYCLADES-ACS5K-CONF-MIB' => 'cyACS5KConf',
'CYCLADES-ACS-INFO-MIB' => 'cyACSInfo',
'CYCLADES-ACS5K-INFO-MIB' => 'cyACS5KInfo',
'ACS-MIB' => 'acs6016',
'ACS8000-MIB' => 'acs8048',
);
%GLOBALS = (
# CYCLADES-ACS-SYS-MIB
%SNMP::Info::Layer1::GLOBALS,
'os_ver' => 'cyACSversion',
'cy_model' => 'cyACSpname',
'serial' => 'cyACSDevId',
'root_ip' => 'cyEthIPaddr',
'ps1_status' => 'cyACSPw1',
'ps2_status' => 'cyACSPw2',
# CYCLADES-ACS-SYS-MIB
'cy_os_ver' => 'cyACSversion',
'cy_model' => 'cyACSpname',
'cy_serial' => 'cyACSDevId',
'cy_ps1_status' => 'cyACSPw1',
'cy_ps2_status' => 'cyACSPw2',
# CYCLADES-ACS-CONF-MIB
'cy_root_ip' => 'CYCLADES_ACS_CONF_MIB__cyEthIPaddr',
# CYCLADES-ACS5K-SYS-MIB
'cy5k_os_ver' => 'cyACS5Kversion',
'cy5k_model' => 'cyACS5Kpname',
'cy5k_serial' => 'cyACS5KDevId',
'cy5k_ps1_status' => 'cyACS5KPw1',
'cy5k_ps2_status' => 'cyACS5KPw2',
# CYCLADES-ACS5K-CONF-MIB
'cy5k_root_ip' => 'CYCLADES_ACS5K_CONF_MIB__cyEthIPaddr',
# ACS-MIB
'acs_os_ver' => 'ACS_MIB__acsFirmwareVersion',
'acs_model' => 'ACS_MIB__acsProductModel',
'acs_serial' => 'ACS_MIB__acsSerialNumber',
'acs_ps1_status' => 'ACS_MIB__acsPowerSupplyStatePw1',
'acs_ps2_status' => 'ACS_MIB__acsPowerSupplyStatePw2',
# ACS8000-MIB
'acs8k_os_ver' => 'ACS8000_MIB__acsFirmwareVersion',
'acs8k_model' => 'ACS8000_MIB__acsProductModel',
'acs8k_serial' => 'ACS8000_MIB__acsSerialNumber',
'acs8k_ps1_status' => 'ACS8000_MIB__acsPowerSupplyStatePw1',
'acs8k_ps2_status' => 'ACS8000_MIB__acsPowerSupplyStatePw2',
);
%FUNCS = (
%SNMP::Info::Layer1::FUNCS,
# CYCLADES-ACS-INFO-MIB::cyInfoSerialTable
'cy_port_tty' => 'cyISPortTty',
'cy_port_name' => 'cyISPortName',
'cy_port_speed' => 'cyISPortSpeed',
'cy_port_cd' => 'cyISPortSigCD',
'cy_port_tty' => 'CYCLADES_ACS_INFO_MIB__cyISPortTty',
'cy_port_name' => 'CYCLADES_ACS_INFO_MIB__cyISPortName',
'cy_port_speed' => 'CYCLADES_ACS_INFO_MIB__cyISPortSpeed',
'cy_port_cd' => 'CYCLADES_ACS_INFO_MIB__cyISPortSigCD',
# CYCLADES-ACS-CONF-MIB::cySerialPortTable
'cy_port_socket' => 'cySPortSocketPort',
'cy_port_socket' => 'CYCLADES_ACS_CONF_MIB__cySPortSocketPort',
# CYCLADES-ACS5K-INFO-MIB::cyInfoSerialTable
'cy5k_port_tty' => 'CYCLADES_ACS5K_INFO_MIB__cyISPortTty',
'cy5k_port_name' => 'CYCLADES_ACS5K_INFO_MIB__cyISPortName',
'cy5k_port_speed' => 'CYCLADES_ACS5K_INFO_MIB__cyISPortSpeed',
'cy5k_port_cd' => 'CYCLADES_ACS5K_INFO_MIB__cyISPortSigCD',
# CYCLADES-ACS5K-CONF-MIB::cySerialPortTable
'cy5k_port_socket' => 'CYCLADES_ACS5K_CONF_MIB__cySPortSocketPort',
# ACS-MIB::acsSerialPortTable
'acs_port_tty' => 'ACS_MIB__acsSerialPortTableDeviceName',
'acs_port_name' => 'ACS_MIB__acsSerialPortTableName',
'acs_port_speed' => 'ACS_MIB__acsSerialPortTableComSpeed',
'acs_port_cd' => 'ACS_MIB__acsSerialPortTableSignalStateDCD',
# Equivalent to cySPortSocketPort doesn't exist in ACS-MIB
# Use 'acsSerialPortTableDeviceName' as an equivalent, it just needs
# to be unique so that we can differentiate between the index in the
# acsSerialPortTable from ifIndex which are both integers
# ACS-MIB::acsSerialPortTableEntry
'acs_port_socket' => 'ACS_MIB__acsSerialPortTableDeviceName',
# ACS8000-MIB::acsSerialPortTable
'acs8k_port_tty' => 'ACS8000_MIB__acsSerialPortTableDeviceName',
'acs8k_port_name' => 'ACS8000_MIB__acsSerialPortTableName',
'acs8k_port_speed' => 'ACS8000_MIB__acsSerialPortTableComSpeed',
'acs8k_port_cd' => 'ACS8000_MIB__acsSerialPortTableSignalStateDCD',
# Equivalent to cySPortSocketPort doesn't exist in ACS-MIB
# Use 'acsSerialPortTableDeviceName' as an equivalent, it just needs
# to be unique so that we can differentiate between the index in the
# acsSerialPortTable from ifIndex which are both integers
# ACS8000-MIB::acsSerialPortTableEntry
'acs8k_port_socket' => 'ACS8000_MIB__acsSerialPortTableDeviceName',
);
%MUNGE = ( %SNMP::Info::Layer1::MUNGE, );
@@ -82,21 +149,85 @@ sub layers {
}
sub os {
return 'cyclades';
return 'avocent';
}
# Use "short circuit" to return the first MIB instance that returns data to
# reduce network communications
# We'll try newest (acs*) first assuming those are most likely deployed
sub os_ver {
my $cyclades = shift;
return
$cyclades->acs_os_ver()
|| $cyclades->acs8k_os_ver()
|| $cyclades->cy5k_os_ver()
|| $cyclades->cy_os_ver()
|| undef;
}
sub vendor {
return 'cyclades';
return 'vertiv';
}
sub model {
my $cyclades = shift;
my $model = $cyclades->cy_model();
my $model
= $cyclades->acs_model()
|| $cyclades->acs8k_model()
|| $cyclades->cy5k_model()
|| $cyclades->cy_model()
|| undef;
return unless defined $model;
return lc($model) if ( defined $model );
return lc($model);
my $id = $cyclades->id();
my $prod = SNMP::translateObj($id);
return $prod || $id;
}
sub serial {
my $cyclades = shift;
return
$cyclades->acs_serial()
|| $cyclades->acs8k_serial()
|| $cyclades->cy5k_serial()
|| $cyclades->cy_serial()
|| undef;
}
sub root_ip {
my $cyclades = shift;
return
$cyclades->cy5k_root_ip()
|| $cyclades->cy_root_ip()
|| undef;
}
sub ps1_status {
my $cyclades = shift;
return
$cyclades->acs_ps1_status()
|| $cyclades->acs8k_ps1_status()
|| $cyclades->cy5k_ps1_status()
|| $cyclades->cy_ps1_status()
|| undef;
}
sub ps2_status {
my $cyclades = shift;
return
$cyclades->acs_ps2_status()
|| $cyclades->acs8k_ps2_status()
|| $cyclades->cy5k_ps2_status()
|| $cyclades->cy_ps2_status()
|| undef;
}
# Extend interface methods to include serial ports
@@ -109,7 +240,12 @@ sub i_index {
my $partial = shift;
my $orig_index = $cyclades->orig_i_index($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my %i_index;
foreach my $iid ( keys %$orig_index ) {
@@ -136,9 +272,19 @@ sub interfaces {
my $cyclades = shift;
my $partial = shift;
my $i_descr = $cyclades->orig_i_description($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_p_tty = $cyclades->cy_port_tty() || {};
my $i_descr = $cyclades->orig_i_description($partial) || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my $cy_p_tty
= $cyclades->acs_port_tty()
|| $cyclades->acs8k_port_tty()
|| $cyclades->cy5k_port_tty()
|| $cyclades->cy_port_tty()
|| {};
my %if;
foreach my $iid ( keys %$i_descr ) {
@@ -166,8 +312,18 @@ sub i_speed {
my $partial = shift;
my $i_speed = $cyclades->orig_i_speed($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_p_speed = $cyclades->cy_port_speed() || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my $cy_p_speed
= $cyclades->acs_port_speed()
|| $cyclades->acs8k_port_speed()
|| $cyclades->cy5k_port_speed()
|| $cyclades->cy_port_speed()
|| {};
my %i_speed;
foreach my $iid ( keys %$i_speed ) {
@@ -195,8 +351,18 @@ sub i_up {
my $partial = shift;
my $i_up = $cyclades->orig_i_up($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_p_up = $cyclades->cy_port_cd() || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my $cy_p_up
= $cyclades->acs_port_cd()
|| $cyclades->acs8k_port_cd()
|| $cyclades->cy5k_port_cd()
|| $cyclades->cy_port_cd()
|| {};
my %i_up;
foreach my $iid ( keys %$i_up ) {
@@ -224,8 +390,18 @@ sub i_description {
my $partial = shift;
my $i_desc = $cyclades->orig_i_description($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_p_desc = $cyclades->cy_port_name() || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my $cy_p_desc
= $cyclades->acs_port_name()
|| $cyclades->acs8k_port_name()
|| $cyclades->cy5k_port_name()
|| $cyclades->cy_port_name()
|| {};
my %descr;
foreach my $iid ( keys %$i_desc ) {
@@ -253,8 +429,18 @@ sub i_name {
my $partial = shift;
my $i_name = $cyclades->orig_i_name($partial) || {};
my $cy_index = $cyclades->cy_port_socket() || {};
my $cy_p_desc = $cyclades->cy_port_name() || {};
my $cy_index
= $cyclades->acs_port_socket()
|| $cyclades->acs8k_port_socket()
|| $cyclades->cy5k_port_socket()
|| $cyclades->cy_port_socket()
|| {};
my $cy_p_desc
= $cyclades->acs_port_name()
|| $cyclades->acs8k_port_name()
|| $cyclades->cy5k_port_name()
|| $cyclades->cy_port_name()
|| {};
my %i_name;
foreach my $iid ( keys %$i_name ) {
@@ -282,7 +468,8 @@ __END__
=head1 NAME
SNMP::Info::Layer1::Cyclades - SNMP Interface to Cyclades terminal servers
SNMP::Info::Layer1::Cyclades - SNMP Interface to Cyclades/Avocent terminal
servers
=head1 AUTHOR
@@ -309,7 +496,7 @@ Eric Miller
=head1 DESCRIPTION
Provides abstraction to the configuration information obtainable from a
Cyclades device through SNMP.
Cyclades/Avocent device through SNMP.
For speed or debugging purposes you can call the subclass directly, but not
after determining a more specific class using the method above.
@@ -334,6 +521,14 @@ my $cyclades = new SNMP::Info::Layer1::Cyclades(...);
=item F<CYCLADES-ACS-INFO-MIB>
=item F<CYCLADES-ACS5K-SYS-MIB>
=item F<CYCLADES-ACS5K-CONF-MIB>
=item F<CYCLADES-ACS5K-INFO-MIB>
=item F<ACS6000-MIB>
=back
=head2 Inherited MIBs
@@ -348,11 +543,11 @@ These are methods that return scalar value from SNMP
=item $cyclades->os_ver()
(C<cyACSversion>)
(C<acsFirmwareVersion>), (C<cyACS5Kversion>), or (C<cyACSversion>)
=item $cyclades->serial()
(C<cyACSDevId>)
(C<acsSerialNumber>), (C<cyACS5KDevId>), or (C<cyACSDevId>)
=item $cyclades->root_ip()
@@ -360,11 +555,11 @@ These are methods that return scalar value from SNMP
=item $cyclades->ps1_status()
(C<cyACSPw1>)
(C<acsPowerSupplyStatePw1>), (C<cyACS5KPw1>), or (C<cyACSPw1>)
=item $cyclades->ps2_status()
(C<cyACSPw2>)
(C<acsPowerSupplyStatePw2>), (C<cyACS5KPw2>), or (C<cyACSPw2>)
=back
@@ -379,15 +574,16 @@ to poll for an ARP cache so turn off reported Layer 2 and Layer 3.
=item $cyclades->vendor()
Returns 'cyclades'
Returns 'vertiv'
=item $cyclades->os()
Returns 'cyclades'
Returns 'avocent'
=item $cyclades->model()
Returns lower case (C<cyACSpname>)
Returns lower case (C<cyACSpname>) or (C<acsProductModel>) if it exists
otherwise tries to reference $cyclades->id() to one of the MIBs listed above
=back
@@ -409,31 +605,34 @@ to a hash.
Returns reference to map of IIDs to Interface index.
Extended to include serial ports. Serial ports are indexed with the
alternative labeling system for the serial port, the listening socket port
C<cySPortSocketPort> to avoid conflicts with C<ifIndex>.
alternative labeling system for the serial port, either the listening socket
port C<cySPortSocketPort> or C<acsSerialPortTableDeviceName> name to avoid
conflicts with C<ifIndex>.
=item $cyclades->interfaces()
Returns reference to map of IIDs to physical ports. Extended to include
serial ports, C<cyISPortTty>.
serial ports, C<acsSerialPortTableDeviceName> or C<cyISPortTty>.
=item $cyclades->i_speed()
Returns interface speed. Extended to include serial ports, C<cyISPortSpeed>.
Returns interface speed. Extended to include serial ports,
C<acsSerialPortTableComSpeed> or C<cyISPortSpeed>.
=item $cyclades->i_up()
Returns link status for each port. Extended to include serial ports,
C<cyISPortSigCD>.
C<acsSerialPortTableSignalStateDCD> or C<cyISPortSigCD>.
=item $cyclades->i_description()
Returns description of each port. Extended to include serial ports,
C<cyISPortName>.
C<acsSerialPortTableName> or C<cyISPortName>.
=item $cyclades->i_name()
Returns name of each port. Extended to include serial ports, C<cyISPortName>.
Returns name of each port. Extended to include serial ports,
C<acsSerialPortTableName> or C<cyISPortName>.
=back

View File

@@ -0,0 +1,610 @@
# Test::SNMP::Info::Layer1::Cyclades
#
# Copyright (c) 2018 Eric Miller
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the University of California, Santa Cruz nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package Test::SNMP::Info::Layer1::Cyclades;
use Test::Class::Most parent => 'My::Test::Class';
use SNMP::Info::Layer1::Cyclades;
sub setup : Tests(setup) {
my $test = shift;
$test->SUPER::setup;
my $phy_addr = pack( "H*", '0000944037B3' );
# Start with a common cache that will serve most tests
# Just define all alternatives to start with and alternatives in sequence to
# test short circuits, we can verify conditional coverage with Devel::Cover
my $cache_data = {
'_layers' => 1,
'_description' => 'My Bogus ACS6008 Description',
# ACS-MIB::acs6008
'_id' => '.1.3.6.1.4.1.10418.16.1.5',
'_acs_os_ver' => '6.00',
'_acs8k_os_ver' => '8.00',
'_cy5k_os_ver' => '2.02',
'_cy_os_ver' => '3.00',
'_acs_model' => 'ACS6032',
'_acs8k_model' => 'ACS8032',
'_cy5k_model' => 'ACS5024',
'_cy_model' => 'TS3000',
'_acs_serial' => 'ABC6000',
'_acs8k_serial' => 'ABC8000',
'_cy5k_serial' => 'ABC5000',
'_cy_serial' => 'ABC3000',
'_acs_ps1_status' => 'statePowerOn',
'_acs8k_ps1_status' => 'statePowerOff',
'_cy5k_ps1_status' => 'powerOFF',
'_cy_ps1_status' => 'powerON',
'_acs_ps2_status' => 'powerNotInstaled',
'_acs8k_ps2_status' => 'statePowerOn',
'_cy5k_ps2_status' => 'powerON',
'_cy_ps2_status' => 'noinstalled',
'_cy5k_root_ip' => '2.3.4.5',
'_cy_root_ip' => '1.2.3.4',
'_acs_port_tty' => 1,
'_acs8k_port_tty' => 1,
'_cy5k_port_tty' => 1,
'_cy_port_tty' => 1,
'_acs_port_name' => 1,
'_acs8k_port_name' => 1,
'_cy5k_port_name' => 1,
'_cy_port_name' => 1,
'_acs_port_speed' => 1,
'_acs8k_port_speed' => 1,
'_cy5k_port_speed' => 1,
'_cy_port_speed' => 1,
'_acs_port_cd' => 1,
'_acs8k_port_cd' => 1,
'_cy5k_port_cd' => 1,
'_cy_port_cd' => 1,
'_acs_port_socket' => 1,
'_acs8k_port_socket' => 1,
'_cy5k_port_socket' => 1,
'_cy_port_socket' => 1,
'_i_index' => 1,
'_i_description' => 1,
'_i_speed' => 1,
'_i_up' => 1,
'_i_name' => 1,
'store' => {
'i_index' => { 1 => 1 },
'i_speed' => { 1 => 10000000 },
'i_description' => { 1 => 'Interface 1 Description' },
'i_name' => { 1 => 'Interface 1 Name' },
'i_up' => { 1 => 'up' },
'acs_port_socket' => { 1 => 'ACS 1 Name', 2 => 'ACS 2 Name' },
'acs8k_port_socket' => { 1 => '8K 1 Name', 2 => '8K 2 Name' },
'cy5k_port_socket' => { 1 => '5K 1 Sock', 2 => '5K 2 Sock' },
'cy_port_socket' => { 1 => 'Port 1 Sock', 2 => 'Port 2 Sock' },
'acs_port_tty' => { 1 => 'ACS 1 TTY', 2 => 'ACS 2 TTY' },
'acs8k_port_tty' => { 1 => '8K 1 TTY', 2 => '8K 2 TTY' },
'cy5k_port_tty' => { 1 => '5K 1 TTY', 2 => '5K 2 TTY' },
'cy_port_tty' => { 1 => 'Port 1 TTY', 2 => 'Port 2 TTY' },
'acs_port_name' => { 1 => 'ACS 1 Name', 2 => 'ACS 2 Name' },
'acs8k_port_name' => { 1 => '8K 1 Name', 2 => '8K 2 Name' },
'cy5k_port_name' => { 1 => '5K 1 Name', 2 => '5K 2 Name' },
'cy_port_name' => { 1 => 'Port 1 Name', 2 => 'Port 2 Name' },
'acs_port_speed' => { 1 => 56000, 2 => 112000 },
'acs8k_port_speed' => { 1 => 112000, 2 => 384000 },
'cy5k_port_speed' => { 1 => 9600, 2 => 56000 },
'cy_port_speed' => { 1 => 2400, 2 => 9600 },
'acs_port_cd' => { 1 => 'down', 2 => 'up' },
'acs8k_port_cd' => { 1 => 'up', 2 => 'down' },
'cy5k_port_cd' => { 1 => 'down', 2 => 'down' },
'cy_port_cd' => { 1 => 'down', 2 => 'up' },
}
};
$test->{info}->cache($cache_data);
}
sub os : Tests(2) {
my $test = shift;
can_ok( $test->{info}, 'os' );
is( $test->{info}->os(), 'avocent', q(Vendor returns 'avocent') );
}
sub os_ver : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'os_ver' );
is( $test->{info}->os_ver(), '6.00', q(ACS version is expected value) );
delete $test->{info}{_acs_os_ver};
is( $test->{info}->os_ver(), '8.00',
q(ACS 8K version is expected value) );
delete $test->{info}{_acs8k_os_ver};
is( $test->{info}->os_ver(), '2.02',
q(ACS 5K version is expected value) );
delete $test->{info}{_cy5k_os_ver};
is( $test->{info}->os_ver(),
'3.00', q(Original Cyclades version is expected value) );
delete $test->{info}{_cy_os_ver};
is( $test->{info}->os_ver(),
undef, q(No MIB leaf data returns undef os_ver) );
}
sub vendor : Tests(2) {
my $test = shift;
can_ok( $test->{info}, 'vendor' );
is( $test->{info}->vendor(), 'vertiv', q(Vendor returns 'vertiv') );
}
sub model : Tests(7) {
my $test = shift;
can_ok( $test->{info}, 'model' );
is( $test->{info}->model(), 'acs6032', q(ACS model is expected value) );
delete $test->{info}{_acs_model};
is( $test->{info}->model(), 'acs8032',
q(ACS 8K model is expected value) );
delete $test->{info}{_acs8k_model};
is( $test->{info}->model(), 'acs5024',
q(ACS 5K model is expected value) );
delete $test->{info}{_cy5k_model};
is( $test->{info}->model(),
'ts3000', q(Original Cyclades model is expected value) );
delete $test->{info}{_cy_model};
is( $test->{info}->model(),
'acs6008', q(No MIB leaf data returns translated id) );
# We won't get to class without sysObjectID that matches enterprise id,
# so use one that isn't defined in MIB
$test->{info}{_id} = '.1.3.6.1.4.1.10418.16.1.6';
is( $test->{info}->model(),
'acsProducts.6',
q(Unknown id returns partially translated id) );
}
sub serial : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'serial' );
is( $test->{info}->serial(), 'ABC6000', q(ACS serial is expected value) );
delete $test->{info}{_acs_serial};
is( $test->{info}->serial(),
'ABC8000', q(ACS 8K serial is expected value) );
delete $test->{info}{_acs8k_serial};
is( $test->{info}->serial(),
'ABC5000', q(ACS 5K serial is expected value) );
delete $test->{info}{_cy5k_serial};
is( $test->{info}->serial(),
'ABC3000', q(Original Cyclades serial is expected value) );
delete $test->{info}{_cy_serial};
is( $test->{info}->serial(),
undef, q(No MIB leaf data returns undef serial) );
}
sub root_ip : Tests(4) {
my $test = shift;
can_ok( $test->{info}, 'root_ip' );
is( $test->{info}->root_ip(),
'2.3.4.5', q(ACS 5K root IP is expected value) );
delete $test->{info}{_cy5k_root_ip};
is( $test->{info}->root_ip(),
'1.2.3.4', q(Original Cyclades root IP is expected value) );
delete $test->{info}{_cy_root_ip};
is( $test->{info}->root_ip(),
undef, q(No MIB leaf data returns undef root IP) );
}
sub ps1_status : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'ps1_status' );
is( $test->{info}->ps1_status(),
'statePowerOn', q(ACS power supply 1 status is expected value) );
delete $test->{info}{_acs_ps1_status};
is( $test->{info}->ps1_status(),
'statePowerOff', q(ACS 8K power supply 1 status is expected value) );
delete $test->{info}{_acs8k_ps1_status};
is( $test->{info}->ps1_status(),
'powerOFF', q(ACS 5K power supply 1 status is expected value) );
delete $test->{info}{_cy5k_ps1_status};
is( $test->{info}->ps1_status(),
'powerON',
q(Original Cyclades power supply 1 status is expected value) );
delete $test->{info}{_cy_ps1_status};
is( $test->{info}->ps1_status(),
undef, q(No MIB leaf data returns undef power supply 1 status) );
}
sub ps2_status : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'ps2_status' );
is( $test->{info}->ps2_status(),
'powerNotInstaled', q(ACS power supply 2 status is expected value) );
delete $test->{info}{_acs_ps2_status};
is( $test->{info}->ps2_status(),
'statePowerOn', q(ACS 8K power supply 2 status is expected value) );
delete $test->{info}{_acs8k_ps2_status};
is( $test->{info}->ps2_status(),
'powerON', q(ACS 5K power supply 2 status is expected value) );
delete $test->{info}{_cy5k_ps2_status};
is( $test->{info}->ps2_status(),
'noinstalled',
q(Original Cyclades power supply 2 status is expected value) );
delete $test->{info}{_cy_ps2_status};
is( $test->{info}->ps2_status(),
undef, q(No MIB leaf data returns undef power supply 2 status) );
}
sub i_index : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'i_index' );
my $expected = {
'1' => '1',
'ACS 1 Name' => 'ACS 1 Name',
'ACS 2 Name' => 'ACS 2 Name'
};
cmp_deeply( $test->{info}->i_index(),
$expected, q(ACS interface indices have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
$expected = {
'1' => '1',
'8K 1 Name' => '8K 1 Name',
'8K 2 Name' => '8K 2 Name'
};
cmp_deeply( $test->{info}->i_index(),
$expected, q(ACS 8K interface indices have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
$expected = {
'1' => '1',
'5K 1 Sock' => '5K 1 Sock',
'5K 2 Sock' => '5K 2 Sock'
};
cmp_deeply( $test->{info}->i_index(),
$expected, q(ACS 5K interface indices have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
$expected = {
'1' => '1',
'Port 1 Sock' => 'Port 1 Sock',
'Port 2 Sock' => 'Port 2 Sock'
};
cmp_deeply( $test->{info}->i_index(),
$expected,
q(Original Cyclades interface indices have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->interfaces(),
{}, q(Empty SNMP table results in empty hash) );
}
sub interfaces : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'interfaces' );
my $expected = {
'1' => 'Interface 1 Description',
'ACS 1 Name' => 'ACS 1 TTY',
'ACS 2 Name' => 'ACS 2 TTY'
};
cmp_deeply( $test->{info}->interfaces(),
$expected, q(ACS interfaces have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
delete $test->{info}{_acs_port_tty};
delete $test->{info}{store}{acs_port_tty};
$expected = {
'1' => 'Interface 1 Description',
'8K 1 Name' => '8K 1 TTY',
'8K 2 Name' => '8K 2 TTY'
};
cmp_deeply( $test->{info}->interfaces(),
$expected, q(ACS 8K interfaces have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
delete $test->{info}{_acs8k_port_tty};
delete $test->{info}{store}{acs8k_port_tty};
$expected = {
'1' => 'Interface 1 Description',
'5K 1 Sock' => '5K 1 TTY',
'5K 2 Sock' => '5K 2 TTY'
};
cmp_deeply( $test->{info}->interfaces(),
$expected, q(ACS 5K interfaces have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
delete $test->{info}{_cy5k_port_tty};
delete $test->{info}{store}{cy5k_port_tty};
$expected = {
'1' => 'Interface 1 Description',
'Port 1 Sock' => 'Port 1 TTY',
'Port 2 Sock' => 'Port 2 TTY'
};
cmp_deeply( $test->{info}->interfaces(),
$expected, q(Original Cyclades interfaces have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->interfaces(),
{}, q(Empty SNMP table results in empty hash) );
}
sub i_speed : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'i_speed' );
# Munge in effect
my $expected = {
'1' => '10 Mbps',
'ACS 1 Name' => 56000,
'ACS 2 Name' => 112000
};
cmp_deeply( $test->{info}->i_speed(),
$expected, q(ACS interface speeds have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
delete $test->{info}{_acs_port_speed};
delete $test->{info}{store}{acs_port_speed};
$expected = {
'1' => '10 Mbps',
'8K 1 Name' => 112000,
'8K 2 Name' => 384000
};
cmp_deeply( $test->{info}->i_speed(),
$expected, q(ACS 8K interface speeds have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
delete $test->{info}{_acs8k_port_speed};
delete $test->{info}{store}{acs8k_port_speed};
$expected = {
'1' => '10 Mbps',
'5K 1 Sock' => 9600,
'5K 2 Sock' => 56000
};
cmp_deeply( $test->{info}->i_speed(),
$expected, q(ACS 5K interface speeds have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
delete $test->{info}{_cy5k_port_speed};
delete $test->{info}{store}{cy5k_port_speed};
$expected = {
'1' => '10 Mbps',
'Port 1 Sock' => 2400,
'Port 2 Sock' => 9600
};
cmp_deeply( $test->{info}->i_speed(),
$expected,
q(Original Cyclades interface speeds have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->i_speed(),
{}, q(Empty SNMP table results in empty hash) );
}
sub i_up : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'i_up' );
my $expected = {
'1' => 'up',
'ACS 1 Name' => 'down',
'ACS 2 Name' => 'up'
};
cmp_deeply( $test->{info}->i_up(),
$expected, q(ACS interface statuses have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
delete $test->{info}{_acs_port_cd};
delete $test->{info}{store}{acs_port_cd};
$expected = {
'1' => 'up',
'8K 1 Name' => 'up',
'8K 2 Name' => 'down'
};
cmp_deeply( $test->{info}->i_up(),
$expected, q(ACS 8K interface statuses have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
delete $test->{info}{_acs8k_port_cd};
delete $test->{info}{store}{acs8k_port_cd};
$expected = {
'1' => 'up',
'5K 1 Sock' => 'down',
'5K 2 Sock' => 'down'
};
cmp_deeply( $test->{info}->i_up(),
$expected, q(ACS 5K interface statuses have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
delete $test->{info}{_cy5k_port_cd};
delete $test->{info}{store}{cy5k_port_cd};
$expected = {
'1' => 'up',
'Port 1 Sock' => 'down',
'Port 2 Sock' => 'up'
};
cmp_deeply( $test->{info}->i_up(),
$expected,
q(Original Cyclades interface statuses have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->i_up(),
{}, q(Empty SNMP table results in empty hash) );
}
sub i_description : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'i_description' );
my $expected = {
'1' => 'Interface 1 Description',
'ACS 1 Name' => 'ACS 1 Name',
'ACS 2 Name' => 'ACS 2 Name'
};
cmp_deeply( $test->{info}->i_description(),
$expected, q(ACS interface descriptions have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
delete $test->{info}{_acs_port_name};
delete $test->{info}{store}{acs_port_name};
$expected = {
'1' => 'Interface 1 Description',
'8K 1 Name' => '8K 1 Name',
'8K 2 Name' => '8K 2 Name'
};
cmp_deeply( $test->{info}->i_description(),
$expected, q(ACS 8K interface descriptions have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
delete $test->{info}{_acs8k_port_name};
delete $test->{info}{store}{acs8k_port_name};
$expected = {
'1' => 'Interface 1 Description',
'5K 1 Sock' => '5K 1 Name',
'5K 2 Sock' => '5K 2 Name'
};
cmp_deeply( $test->{info}->i_description(),
$expected, q(ACS 5K interface descriptions have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
delete $test->{info}{_cy5k_port_name};
delete $test->{info}{store}{cy5k_port_name};
$expected = {
'1' => 'Interface 1 Description',
'Port 1 Sock' => 'Port 1 Name',
'Port 2 Sock' => 'Port 2 Name'
};
cmp_deeply( $test->{info}->i_description(),
$expected,
q(Original Cyclades interface descriptions have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->i_description(),
{}, q(Empty SNMP table results in empty hash) );
}
sub i_name : Tests(6) {
my $test = shift;
can_ok( $test->{info}, 'i_name' );
my $expected = {
'1' => 'Interface 1 Name',
'ACS 1 Name' => 'ACS 1 Name',
'ACS 2 Name' => 'ACS 2 Name'
};
cmp_deeply( $test->{info}->i_name(),
$expected, q(ACS interface descriptions have expected values) );
delete $test->{info}{_acs_port_socket};
delete $test->{info}{store}{acs_port_socket};
delete $test->{info}{_acs_port_name};
delete $test->{info}{store}{acs_port_name};
$expected = {
'1' => 'Interface 1 Name',
'8K 1 Name' => '8K 1 Name',
'8K 2 Name' => '8K 2 Name'
};
cmp_deeply( $test->{info}->i_name(),
$expected, q(ACS 8K interface descriptions have expected values) );
delete $test->{info}{_acs8k_port_socket};
delete $test->{info}{store}{acs8k_port_socket};
delete $test->{info}{_acs8k_port_name};
delete $test->{info}{store}{acs8k_port_name};
$expected = {
'1' => 'Interface 1 Name',
'5K 1 Sock' => '5K 1 Name',
'5K 2 Sock' => '5K 2 Name'
};
cmp_deeply( $test->{info}->i_name(),
$expected, q(ACS 5K interface descriptions have expected values) );
delete $test->{info}{_cy5k_port_socket};
delete $test->{info}{store}{cy5k_port_socket};
delete $test->{info}{_cy5k_port_name};
delete $test->{info}{store}{cy5k_port_name};
$expected = {
'1' => 'Interface 1 Name',
'Port 1 Sock' => 'Port 1 Name',
'Port 2 Sock' => 'Port 2 Name'
};
cmp_deeply( $test->{info}->i_name(),
$expected,
q(Original Cyclades interface descriptions have expected values) );
$test->{info}->clear_cache();
cmp_deeply( $test->{info}->i_name(),
{}, q(Empty SNMP table results in empty hash) );
}
1;