+ update cisco ucs mode equipment (WIP)
This commit is contained in:
parent
4d6819804a
commit
cb2b261c51
|
@ -22,59 +22,62 @@ package hardware::server::cisco::ucs::mode::components::blade;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_overall_status);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsComputeBladePresence => { oid => '.1.3.6.1.4.1.9.9.719.1.9.2.1.45', map => \%mapping_presence },
|
||||||
|
};
|
||||||
|
my $mapping2 = {
|
||||||
|
cucsComputeBladeOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.9.2.1.42', map => \%mapping_overall_status },
|
||||||
|
};
|
||||||
|
my $oid_cucsComputeBladeDn = '.1.3.6.1.4.1.9.9.719.1.9.2.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsComputeBladePresence}->{oid} },
|
||||||
|
{ oid => $mapping2->{cucsComputeBladeOperState}->{oid} }, { oid => $oid_cucsComputeBladeDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
|
||||||
$self->{output}->output_add(long_msg => "Checking blades");
|
$self->{output}->output_add(long_msg => "Checking blades");
|
||||||
$self->{components}->{blade} = {name => 'blades', total => 0, skip => 0};
|
$self->{components}->{blade} = {name => 'blades', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'blade'));
|
return if ($self->check_exclude(section => 'blade'));
|
||||||
|
|
||||||
my $oid_cucsComputeBladePresence = '.1.3.6.1.4.1.9.9.719.1.9.2.1.45';
|
|
||||||
my $oid_cucsComputeBladeOperState = '.1.3.6.1.4.1.9.9.719.1.9.2.1.42';
|
|
||||||
my $oid_cucsComputeBladeDn = '.1.3.6.1.4.1.9.9.719.1.9.2.1.2';
|
|
||||||
|
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsComputeBladeDn}})) {
|
||||||
{ oid => $oid_cucsComputeBladePresence },
|
$oid =~ /\.(\d+)$/;
|
||||||
{ oid => $oid_cucsComputeBladeOperState },
|
my $instance = $1;
|
||||||
{ oid => $oid_cucsComputeBladeDn },
|
my $fan_dn = $self->{results}->{$oid_cucsComputeBladeDn}->{$oid};
|
||||||
]
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsComputeBladePresence}->{oid}}, instance => $instance);
|
||||||
);
|
my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsComputeBladeOperState}->{oid}}, instance => $instance);
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsComputeBladePresence}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $blade_index = $1;
|
|
||||||
my $blade_dn = $result->{$oid_cucsComputeBladeDn}->{$oid_cucsComputeBladeDn . '.' . $blade_index};
|
|
||||||
my $blade_operstate = defined($result->{$oid_cucsComputeBladeOperState}->{$oid_cucsComputeBladeOperState . '.' . $blade_index}) ?
|
|
||||||
$result->{$oid_cucsComputeBladeOperState}->{$oid_cucsComputeBladeOperState . '.' . $blade_index} : 0; # unknown
|
|
||||||
my $blade_presence = defined($result->{$oid_cucsComputeBladePresence}->{$oid_cucsComputeBladePresence . '.' . $blade_index}) ?
|
|
||||||
$result->{$oid_cucsComputeBladePresence}->{$oid_cucsComputeBladePresence . '.' . $blade_index} : 0;
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'blade', instance => $blade_dn));
|
next if ($self->absent_problem(section => 'blade', instance => $blade_dn));
|
||||||
next if ($self->check_exclude(section => 'blade', instance => $blade_dn));
|
next if ($self->check_exclude(section => 'blade', instance => $blade_dn));
|
||||||
|
|
||||||
my $exit = $self->get_severity(section => 'blade', threshold => 'presence', value => $blade_presence);
|
$self->{output}->output_add(long_msg => sprintf("blade '%s' state is '%s' [presence: %s].",
|
||||||
|
$blade_dn, $result2->{cucsComputeBladeOperState}),
|
||||||
|
$result->{cucsComputeBladePresence})
|
||||||
|
));
|
||||||
|
|
||||||
|
my $exit = $self->get_severity(section => 'default.presence', label => 'blade.presence', value => $result->{cucsComputeBladePresence}));
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("blade '%s' presence is: '%s'",
|
short_msg => sprintf("blade '%s' presence is: '%s'",
|
||||||
$blade_dn, ${$thresholds->{presence}{$blade_presence}}[0])
|
$blade_dn, $result->{cucsComputeBladePresence})
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{components}->{blade}->{total}++;
|
$self->{components}->{blade}->{total}++;
|
||||||
|
|
||||||
$self->{output}->output_add(long_msg => sprintf("blade '%s' state is '%s' [presence: %s].",
|
$exit = $self->get_severity(section => 'default.overall_status', label => 'blade.overall_status', value => $result2->{cucsComputeBladeOperState}));
|
||||||
$blade_dn, ${$thresholds->{overall_status}->{$blade_operstate}}[0],
|
|
||||||
${$thresholds->{presence}->{$blade_presence}}[0]
|
|
||||||
));
|
|
||||||
$exit = $self->get_severity(section => 'blade', threshold => 'overall_status', value => $blade_operstate);
|
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("blade '%s' state is '%s'.",
|
short_msg => sprintf("blade '%s' state is '%s'.",
|
||||||
$blade_dn, ${$thresholds->{overall_status}->{$blade_operstate}}[0]
|
$blade_dn, $result2->{cucsComputeBladeOperState})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,32 +22,34 @@ package hardware::server::cisco::ucs::mode::components::chassis;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_operability);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
# Don't do the 'presence'. Is 'unknown' ??!!!
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsEquipmentChassisOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.7.1.27', map => \%mapping_operability },
|
||||||
|
};
|
||||||
|
my $oid_cucsEquipmentChassisDn = '.1.3.6.1.4.1.9.9.719.1.15.7.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsEquipmentChassisOperState}->{oid} },
|
||||||
|
{ oid => $oid_cucsEquipmentChassisDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
|
||||||
$self->{output}->output_add(long_msg => "Checking chassis");
|
$self->{output}->output_add(long_msg => "Checking chassis");
|
||||||
$self->{components}->{chassis} = {name => 'chassis', total => 0, skip => 0};
|
$self->{components}->{chassis} = {name => 'chassis', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'chassis'));
|
return if ($self->check_exclude(section => 'chassis'));
|
||||||
|
|
||||||
# Don't do the 'presence'. Is 'unknown' ??!!!
|
|
||||||
my $oid_cucsEquipmentChassisOperState = '.1.3.6.1.4.1.9.9.719.1.15.7.1.27';
|
|
||||||
my $oid_cucsEquipmentChassisDn = '.1.3.6.1.4.1.9.9.719.1.15.7.1.2';
|
|
||||||
|
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentChassisDn}})) {
|
||||||
{ oid => $oid_cucsEquipmentChassisOperState },
|
$oid =~ /\.(\d+)$/;
|
||||||
{ oid => $oid_cucsEquipmentChassisDn },
|
my $instance = $1;
|
||||||
]
|
my $chassis_dn = $self->{results}->{$oid_cucsEquipmentChassisDn}->{$oid};
|
||||||
);
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentChassisOperState}->{oid}}, instance => $instance);
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentChassisOperState}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $chassis_index = $1;
|
|
||||||
my $chassis_dn = $result->{$oid_cucsEquipmentChassisDn}->{$oid_cucsEquipmentChassisDn . '.' . $chassis_index};
|
|
||||||
my $chassis_operstate = defined($result->{$oid_cucsEquipmentChassisOperState}->{$oid_cucsEquipmentChassisOperState . '.' . $chassis_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentChassisOperState}->{$oid_cucsEquipmentChassisOperState . '.' . $chassis_index} : 0; # unknown
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'chassis', instance => $chassis_dn));
|
next if ($self->absent_problem(section => 'chassis', instance => $chassis_dn));
|
||||||
next if ($self->check_exclude(section => 'chassis', instance => $chassis_dn));
|
next if ($self->check_exclude(section => 'chassis', instance => $chassis_dn));
|
||||||
|
@ -55,13 +57,13 @@ sub check {
|
||||||
$self->{components}->{chassis}->{total}++;
|
$self->{components}->{chassis}->{total}++;
|
||||||
|
|
||||||
$self->{output}->output_add(long_msg => sprintf("chassis '%s' state is '%s'.",
|
$self->{output}->output_add(long_msg => sprintf("chassis '%s' state is '%s'.",
|
||||||
$chassis_dn, ${$thresholds->{operability}->{$chassis_operstate}}[0]
|
$chassis_dn, $result->{cucsEquipmentChassisOperState}
|
||||||
));
|
));
|
||||||
my $exit = $self->get_severity(section => 'chassis', threshold => 'operability', value => $chassis_operstate);
|
my $exit = $self->get_severity(section => 'default.operability', label => 'chassis.operability', value => $result->{cucsEquipmentChassisOperState});
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("chassis '%s' state is '%s'.",
|
short_msg => sprintf("chassis '%s' state is '%s'.",
|
||||||
$chassis_dn, ${$thresholds->{operability}->{$chassis_operstate}}[0]
|
$chassis_dn, $result->{cucsEquipmentChassisOperState}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,58 +22,62 @@ package hardware::server::cisco::ucs::mode::components::fan;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsEquipmentFanPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.12.1.13', map => \%mapping_presence },
|
||||||
|
};
|
||||||
|
my $mapping2 = {
|
||||||
|
cucsEquipmentFanOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.12.1.9', map => \%mapping_operability },
|
||||||
|
};
|
||||||
|
my $oid_cucsEquipmentFanDn = '.1.3.6.1.4.1.9.9.719.1.15.12.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsEquipmentFanPresence}->{oid} },
|
||||||
|
{ oid => $mapping2->{cucsEquipmentFanOperState}->{oid} }, { oid => $oid_cucsEquipmentFanDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
|
||||||
$self->{output}->output_add(long_msg => "Checking fans");
|
$self->{output}->output_add(long_msg => "Checking fans");
|
||||||
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
|
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'fan'));
|
return if ($self->check_exclude(section => 'fan'));
|
||||||
|
|
||||||
my $oid_cucsEquipmentFanPresence = '.1.3.6.1.4.1.9.9.719.1.15.12.1.13';
|
|
||||||
my $oid_cucsEquipmentFanOperState = '.1.3.6.1.4.1.9.9.719.1.15.12.1.9';
|
|
||||||
my $oid_cucsEquipmentFanDn = '.1.3.6.1.4.1.9.9.719.1.15.12.1.2';
|
|
||||||
|
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentFanDn}})) {
|
||||||
{ oid => $oid_cucsEquipmentFanPresence },
|
$oid =~ /\.(\d+)$/;
|
||||||
{ oid => $oid_cucsEquipmentFanOperState },
|
my $instance = $1;
|
||||||
{ oid => $oid_cucsEquipmentFanDn },
|
my $fan_dn = $self->{results}->{$oid_cucsEquipmentFanDn}->{$oid};
|
||||||
]
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentFanPresence}->{oid}}, instance => $instance);
|
||||||
);
|
my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentFanOperState}->{oid}}, instance => $instance);
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentFanPresence}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $fan_index = $1;
|
|
||||||
my $fan_dn = $result->{$oid_cucsEquipmentFanDn}->{$oid_cucsEquipmentFanDn . '.' . $fan_index};
|
|
||||||
my $fan_operstate = defined($result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index} : 0; # unknown
|
|
||||||
my $fan_presence = defined($result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index} : 0;
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'fan', instance => $fan_dn));
|
next if ($self->absent_problem(section => 'fan', instance => $fan_dn));
|
||||||
next if ($self->check_exclude(section => 'fan', instance => $fan_dn));
|
next if ($self->check_exclude(section => 'fan', instance => $fan_dn));
|
||||||
|
|
||||||
my $exit = $self->get_severity(section => 'fan', threshold => 'presence', value => $fan_presence);
|
$self->{output}->output_add(long_msg => sprintf("fan '%s' state is '%s' [presence: %s].",
|
||||||
|
$fan_dn, $result2->{cucsEquipmentFanOperState},
|
||||||
|
$result->{cucsEquipmentFanPresence}
|
||||||
|
));
|
||||||
|
|
||||||
|
my $exit = $self->get_severity(section => 'default.presence', label => 'fan.presence', value => $result->{cucsEquipmentFanPresence});
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("fan '%s' presence is: '%s'",
|
short_msg => sprintf("fan '%s' presence is: '%s'",
|
||||||
$fan_dn, ${$thresholds->{presence}->{$fan_presence}}[0])
|
$fan_dn, $result->{cucsEquipmentFanPresence})
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{components}->{fan}->{total}++;
|
$self->{components}->{fan}->{total}++;
|
||||||
$self->{output}->output_add(long_msg => sprintf("fan '%s' state is '%s' [presence: %s].",
|
|
||||||
$fan_dn, ${$thresholds->{operability}->{$fan_operstate}}[0],
|
$exit = $self->get_severity(section => 'default.operability', label => 'fan.operability', value => $result2->{cucsEquipmentFanOperState});
|
||||||
${$thresholds->{presence}->{$fan_presence}}[0]
|
|
||||||
));
|
|
||||||
$exit = $self->get_severity(section => 'fan', threshold => 'operability', value => $fan_operstate);
|
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("fan '%s' state is '%s'.",
|
short_msg => sprintf("fan '%s' state is '%s'.",
|
||||||
$fan_dn, ${$thresholds->{operability}->{$fan_operstate}}[0]
|
$fan_dn, $result2->{cucsEquipmentFanOperState}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,59 +22,62 @@ package hardware::server::cisco::ucs::mode::components::fex;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsEquipmentFexPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.19.1.24', map => \%mapping_presence },
|
||||||
|
};
|
||||||
|
my $mapping2 = {
|
||||||
|
cucsEquipmentFexOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.19.1.21', map => \%mapping_operability },
|
||||||
|
};
|
||||||
|
my $oid_cucsEquipmentFexDn = '.1.3.6.1.4.1.9.9.719.1.15.19.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsEquipmentFexPresence}->{oid} },
|
||||||
|
{ oid => $mapping2->{cucsEquipmentFexOperState}->{oid} }, { oid => $oid_cucsEquipmentFexDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
|
||||||
$self->{output}->output_add(long_msg => "Checking fabric extenders");
|
$self->{output}->output_add(long_msg => "Checking fabric extenders");
|
||||||
$self->{components}->{fex} = {name => 'fabric extenders', total => 0, skip => 0};
|
$self->{components}->{fex} = {name => 'fabric extenders', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'fex'));
|
return if ($self->check_exclude(section => 'fex'));
|
||||||
|
|
||||||
my $oid_cucsEquipmentFexDn = '.1.3.6.1.4.1.9.9.719.1.15.19.1.2';
|
|
||||||
my $oid_cucsEquipmentFexOperState = '.1.3.6.1.4.1.9.9.719.1.15.19.1.21';
|
|
||||||
my $oid_cucsEquipmentFexPresence = '.1.3.6.1.4.1.9.9.719.1.15.19.1.24';
|
|
||||||
|
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentFexDn}})) {
|
||||||
{ oid => $oid_cucsEquipmentFexDn },
|
$oid =~ /\.(\d+)$/;
|
||||||
{ oid => $oid_cucsEquipmentFexOperState },
|
my $instance = $1;
|
||||||
{ oid => $oid_cucsEquipmentFexPresence },
|
my $fex_dn = $self->{results}->{$oid_cucsEquipmentFexDn}->{$oid};
|
||||||
]
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentFexPresence}->{oid}}, instance => $instance);
|
||||||
);
|
my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentFexOperState}->{oid}}, instance => $instance);
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentFexDn}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $fex_index = $1;
|
|
||||||
my $fex_dn = $result->{$oid_cucsEquipmentFexDn}->{$oid_cucsEquipmentFexDn . '.' . $fex_index};
|
|
||||||
my $fex_operstate = defined($result->{$oid_cucsEquipmentFexOperState}->{$oid_cucsEquipmentFexOperState . '.' . $fex_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentFexOperState}->{$oid_cucsEquipmentFexOperState . '.' . $fex_index} : 0; # unknown
|
|
||||||
my $fex_presence = defined($result->{$oid_cucsEquipmentFexPresence}->{$oid_cucsEquipmentFexPresence . '.' . $fex_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentFexPresence}->{$oid_cucsEquipmentFexPresence . '.' . $fex_index} : 0;
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'fex', instance => $fex_dn));
|
next if ($self->absent_problem(section => 'fex', instance => $fex_dn));
|
||||||
next if ($self->check_exclude(section => 'fex', instance => $fex_dn));
|
next if ($self->check_exclude(section => 'fex', instance => $fex_dn));
|
||||||
|
|
||||||
my $exit = $self->get_severity(section => 'fex', threshold => 'presence', value => $fex_presence);
|
$self->{output}->output_add(long_msg => sprintf("Fabric extender '%s' state is '%s' [presence: %s].",
|
||||||
|
$fex_dn, $result2->{cucsEquipmentFexOperState},
|
||||||
|
$result->{cucsEquipmentFexPresence}
|
||||||
|
));
|
||||||
|
|
||||||
|
my $exit = $self->get_severity(section => 'default.presence', label => 'fex.presence', value => $result->{cucsEquipmentFexPresence});
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("Fabric extender '%s' presence is: '%s'",
|
short_msg => sprintf("Fabric extender '%s' presence is: '%s'",
|
||||||
$fex_dn, ${$thresholds->{presence}->{$fex_presence}}[0])
|
$fex_dn, $result->{cucsEquipmentFexPresence}
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{components}->{fex}->{total}++;
|
$self->{components}->{fex}->{total}++;
|
||||||
|
|
||||||
$self->{output}->output_add(long_msg => sprintf("Fabric extender '%s' state is '%s' [presence: %s].",
|
$exit = $self->get_severity(section => 'default.presence', label => 'fex.operability', value => $result2->{cucsEquipmentFexOperState});
|
||||||
$fex_dn, ${$thresholds->{operability}->{$fex_operstate}}[0],
|
|
||||||
${$thresholds->{presence}->{$fex_presence}}[0]
|
|
||||||
));
|
|
||||||
$exit = $self->get_severity(section => 'fex', threshold => 'operability', value => $fex_operstate);
|
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("Fabric extender '%s' state is '%s'.",
|
short_msg => sprintf("Fabric extender '%s' state is '%s'.",
|
||||||
$fex_dn, ${$thresholds->{operability}->{$fex_operstate}}[0]
|
$fex_dn, $result2->{cucsEquipmentFexOperState}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,23 @@ package hardware::server::cisco::ucs::mode::components::iocard;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsEquipmentIOCardPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.30.1.31', map => \%mapping_presence },
|
||||||
|
};
|
||||||
|
my $mapping2 = {
|
||||||
|
cucsEquipmentIOCardOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.30.1.25', map => \%mapping_operability },
|
||||||
|
};
|
||||||
|
my $oid_cucsEquipmentIOCardDn = '.1.3.6.1.4.1.9.9.719.1.15.30.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsEquipmentIOCardPresence}->{oid} },
|
||||||
|
{ oid => $mapping2->{cucsEquipmentIOCardOperState}->{oid} }, { oid => $oid_cucsEquipmentIOCardDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
@ -31,50 +47,38 @@ sub check {
|
||||||
$self->{output}->output_add(long_msg => "Checking io cards");
|
$self->{output}->output_add(long_msg => "Checking io cards");
|
||||||
$self->{components}->{iocard} = {name => 'io cards', total => 0, skip => 0};
|
$self->{components}->{iocard} = {name => 'io cards', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'iocard'));
|
return if ($self->check_exclude(section => 'iocard'));
|
||||||
|
|
||||||
my $oid_cucsEquipmentIOCardPresence = '.1.3.6.1.4.1.9.9.719.1.15.30.1.31';
|
|
||||||
my $oid_cucsEquipmentIOCardOperState = '.1.3.6.1.4.1.9.9.719.1.15.30.1.25';
|
|
||||||
my $oid_cucsEquipmentIOCardDn = '.1.3.6.1.4.1.9.9.719.1.15.30.1.2';
|
|
||||||
|
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentIOCardDn}})) {
|
||||||
{ oid => $oid_cucsEquipmentIOCardPresence },
|
$oid =~ /\.(\d+)$/;
|
||||||
{ oid => $oid_cucsEquipmentIOCardOperState },
|
my $instance = $1;
|
||||||
{ oid => $oid_cucsEquipmentIOCardDn },
|
my $iocard_dn = $self->{results}->{$oid_cucsEquipmentIOCardDn}->{$oid};
|
||||||
]
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentIOCardPresence}->{oid}}, instance => $instance);
|
||||||
);
|
my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentIOCardOperState}->{oid}}, instance => $instance);
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentIOCardPresence}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $iocard_index = $1;
|
|
||||||
my $iocard_dn = $result->{$oid_cucsEquipmentIOCardDn}->{$oid_cucsEquipmentIOCardDn . '.' . $iocard_index};
|
|
||||||
my $iocard_operstate = defined($result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index} : 0; # unknown
|
|
||||||
my $iocard_presence = defined($result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index} : 0;
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'iocard', instance => $iocard_dn));
|
next if ($self->absent_problem(section => 'iocard', instance => $iocard_dn));
|
||||||
next if ($self->check_exclude(section => 'iocard', instance => $iocard_dn));
|
next if ($self->check_exclude(section => 'iocard', instance => $iocard_dn));
|
||||||
|
|
||||||
my $exit = $self->get_severity(section => 'iocard', threshold => 'presence', value => $iocard_presence);
|
$self->{output}->output_add(long_msg => sprintf("IO cards '%s' state is '%s' [presence: %s].",
|
||||||
|
$iocard_dn, $result2->{cucsEquipmentIOCardOperState},
|
||||||
|
$result->{cucsEquipmentIOCardPresence}
|
||||||
|
));
|
||||||
|
|
||||||
|
my $exit = $self->get_severity(section => 'default.presence', label => 'iocard.presence', value => $result->{cucsEquipmentIOCardPresence});
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("IO cards '%s' presence is: '%s'",
|
short_msg => sprintf("IO cards '%s' presence is: '%s'",
|
||||||
$iocard_dn, ${$thresholds->{presence}->{$iocard_presence}}[0])
|
$iocard_dn, $result->{cucsEquipmentIOCardPresence})
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{components}->{iocard}->{total}++;
|
$self->{components}->{iocard}->{total}++;
|
||||||
|
|
||||||
$self->{output}->output_add(long_msg => sprintf("IO cards '%s' state is '%s' [presence: %s].",
|
$exit = $self->get_severity(section => 'default.operability', label => 'iocard.operability', value => $result2->{cucsEquipmentIOCardOperState});
|
||||||
$iocard_dn, ${$thresholds->{operability}->{$iocard_operstate}}[0],
|
|
||||||
${$thresholds->{presence}->{$iocard_presence}}[0]
|
|
||||||
));
|
|
||||||
$exit = $self->get_severity(section => 'iocard', threshold => 'operability', value => $iocard_operstate);
|
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("IO cards '%s' state is '%s'.",
|
short_msg => sprintf("IO cards '%s' state is '%s'.",
|
||||||
$iocard_dn, ${$thresholds->{operability}->{$iocard_operstate}}[0]
|
$iocard_dn, $result2->{cucsEquipmentIOCardOperState}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,23 @@ package hardware::server::cisco::ucs::mode::components::psu;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability);
|
||||||
|
|
||||||
|
# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB'
|
||||||
|
my $mapping1 = {
|
||||||
|
cucsEquipmentPsuPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.56.1.11', map => \%mapping_presence },
|
||||||
|
};
|
||||||
|
my $mapping2 = {
|
||||||
|
cucsEquipmentPsuOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.56.1.7', map => \%mapping_operability },
|
||||||
|
};
|
||||||
|
my $oid_cucsEquipmentPsuDn = '.1.3.6.1.4.1.9.9.719.1.15.56.1.2';
|
||||||
|
|
||||||
|
sub load {
|
||||||
|
my (%options) = @_;
|
||||||
|
|
||||||
|
push @{$options{request}}, { oid => $mapping1->{cucsEquipmentPsuPresence}->{oid} },
|
||||||
|
{ oid => $mapping2->{cucsEquipmentPsuOperState}->{oid} }, { oid => $oid_cucsEquipmentPsuDn };
|
||||||
|
}
|
||||||
|
|
||||||
sub check {
|
sub check {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
@ -32,49 +48,37 @@ sub check {
|
||||||
$self->{components}->{psu} = {name => 'psus', total => 0, skip => 0};
|
$self->{components}->{psu} = {name => 'psus', total => 0, skip => 0};
|
||||||
return if ($self->check_exclude(section => 'psu'));
|
return if ($self->check_exclude(section => 'psu'));
|
||||||
|
|
||||||
my $oid_cucsEquipmentPsuPresence = '.1.3.6.1.4.1.9.9.719.1.15.56.1.11';
|
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentPsuDn}})) {
|
||||||
my $oid_cucsEquipmentPsuOperState = '.1.3.6.1.4.1.9.9.719.1.15.56.1.7';
|
$oid =~ /\.(\d+)$/;
|
||||||
my $oid_cucsEquipmentPsuDn = '.1.3.6.1.4.1.9.9.719.1.15.56.1.2';
|
my $instance = $1;
|
||||||
|
my $psu_dn = $self->{results}->{$oid_cucsEquipmentPsuDn}->{$oid};
|
||||||
my $result = $self->{snmp}->get_multiple_table(oids => [
|
my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentPsuPresence}->{oid}}, instance => $instance);
|
||||||
{ oid => $oid_cucsEquipmentPsuPresence },
|
my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentPsuOperState}->{oid}}, instance => $instance);
|
||||||
{ oid => $oid_cucsEquipmentPsuOperState },
|
|
||||||
{ oid => $oid_cucsEquipmentPsuDn },
|
|
||||||
]
|
|
||||||
);
|
|
||||||
foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentPsuPresence}})) {
|
|
||||||
# index
|
|
||||||
$key =~ /\.(\d+)$/;
|
|
||||||
my $psu_index = $1;
|
|
||||||
my $psu_dn = $result->{$oid_cucsEquipmentPsuDn}->{$oid_cucsEquipmentPsuDn . '.' . $psu_index};
|
|
||||||
my $psu_operstate = defined($result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index} : 0; # unknown
|
|
||||||
my $psu_presence = defined($result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index}) ?
|
|
||||||
$result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index} : 0;
|
|
||||||
|
|
||||||
next if ($self->absent_problem(section => 'psu', instance => $psu_dn));
|
next if ($self->absent_problem(section => 'psu', instance => $psu_dn));
|
||||||
next if ($self->check_exclude(section => 'psu', instance => $psu_dn));
|
next if ($self->check_exclude(section => 'psu', instance => $psu_dn));
|
||||||
|
|
||||||
my $exit = $self->get_severity(section => 'psu', threshold => 'presence', value => $psu_presence);
|
$self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [presence: %s].",
|
||||||
|
$psu_dn, $result2->{cucsEquipmentPsuOperState},
|
||||||
|
$result->{cucsEquipmentPsuPresence}
|
||||||
|
));
|
||||||
|
|
||||||
|
my $exit = $self->get_severity(section => 'default.presence', label => 'psu.presence', value => $result->{cucsEquipmentPsuPresence});
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("power supply '%s' presence is: '%s'",
|
short_msg => sprintf("power supply '%s' presence is: '%s'",
|
||||||
$psu_dn, ${$thresholds->{presence}->{$psu_presence}}[0])
|
$psu_dn, $result->{cucsEquipmentPsuPresence})
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{components}->{psu}->{total}++;
|
$self->{components}->{psu}->{total}++;
|
||||||
|
|
||||||
$self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [presence: %s].",
|
$exit = $self->get_severity(section => 'default.operability', label => 'psu.operability', value => $result2->{cucsEquipmentPsuOperState});
|
||||||
$psu_dn, ${$thresholds->{operability}->{$psu_operstate}}[0],
|
|
||||||
${$thresholds->{presence}->{$psu_presence}}[0]
|
|
||||||
));
|
|
||||||
$exit = $self->get_severity(section => 'psu', threshold => 'operability', value => $psu_operstate);
|
|
||||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||||
$self->{output}->output_add(severity => $exit,
|
$self->{output}->output_add(severity => $exit,
|
||||||
short_msg => sprintf("power supply '%s' state is '%s'.",
|
short_msg => sprintf("power supply '%s' state is '%s'.",
|
||||||
$psu_dn, ${$thresholds->{operability}->{$psu_operstate}}[0]
|
$psu_dn, $result2->{cucsEquipmentPsuOperState}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,85 +25,163 @@ use warnings;
|
||||||
use Exporter;
|
use Exporter;
|
||||||
|
|
||||||
our $thresholds;
|
our $thresholds;
|
||||||
|
our %mapping_presence;
|
||||||
|
our %mapping_operability;
|
||||||
|
our %mapping_overall_status;
|
||||||
|
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT_OK = qw($thresholds);
|
our @EXPORT_OK = qw($thresholds %mapping_presence %mapping_operability %mapping_overall_status);
|
||||||
|
|
||||||
|
%mapping_presence = (
|
||||||
|
0 => 'unknown',
|
||||||
|
1 => 'empty',
|
||||||
|
10 => 'equipped',
|
||||||
|
11 => 'missing',
|
||||||
|
12 => 'mismatch',
|
||||||
|
13 => 'equippedNotPrimary',
|
||||||
|
20 => 'equippedIdentityUnestablishable',
|
||||||
|
21 => 'mismatchIdentityUnestablishable',
|
||||||
|
30 => 'inaccessible',
|
||||||
|
40 => 'unauthorized',
|
||||||
|
100 => 'notSupported',
|
||||||
|
);
|
||||||
|
%mapping_operability = (
|
||||||
|
0 => 'unknown',
|
||||||
|
1 => 'operable',
|
||||||
|
2 => 'inoperable',
|
||||||
|
3 => 'degraded',
|
||||||
|
4 => 'poweredOff',
|
||||||
|
5 => 'powerProblem',
|
||||||
|
6 => 'removed',
|
||||||
|
7 => 'voltageProblem',
|
||||||
|
8 => 'thermalProblem',
|
||||||
|
9 => 'performanceProblem',
|
||||||
|
10 => 'accessibilityProblem',
|
||||||
|
11 => 'identityUnestablishable',
|
||||||
|
12 => 'biosPostTimeout',
|
||||||
|
13 => 'disabled',
|
||||||
|
51 => 'fabricConnProblem',
|
||||||
|
52 => 'fabricUnsupportedConn',
|
||||||
|
81 => 'config',
|
||||||
|
82 => 'equipmentProblem',
|
||||||
|
83 => 'decomissioning',
|
||||||
|
84 => 'chassisLimitExceeded',
|
||||||
|
100 => 'notSupported',
|
||||||
|
101 => 'discovery',
|
||||||
|
102 => 'discoveryFailed',
|
||||||
|
104 => 'postFailure',
|
||||||
|
105 => 'upgradeProblem',
|
||||||
|
106 => 'peerCommProblem',
|
||||||
|
107 => 'autoUpgrade',
|
||||||
|
);
|
||||||
|
%mapping_overall_status = (
|
||||||
|
0 => 'indeterminate',
|
||||||
|
1 => 'unassociated',
|
||||||
|
10 => 'ok',
|
||||||
|
11 => 'discovery',
|
||||||
|
12 => 'config',
|
||||||
|
13 => 'unconfig'
|
||||||
|
14 => 'power-off',
|
||||||
|
15 => 'restart',
|
||||||
|
20 => 'maintenance',
|
||||||
|
21 => 'test',
|
||||||
|
29 => 'compute-mismatch',
|
||||||
|
30 => 'compute-failed',
|
||||||
|
31 => 'degraded',
|
||||||
|
32 => 'discovery-failed',
|
||||||
|
33 => 'config-failure',
|
||||||
|
34 => 'unconfig-failed',
|
||||||
|
35 => 'test-failed',
|
||||||
|
36 => 'maintenance-failed',
|
||||||
|
40 => 'removed',
|
||||||
|
41 => 'disabled',
|
||||||
|
50 => 'inaccessible',
|
||||||
|
60 => 'thermal-problem',
|
||||||
|
61 => 'power-problem',
|
||||||
|
62 => 'voltage-problem',
|
||||||
|
63 => 'inoperable',
|
||||||
|
101 => 'decommissioning',
|
||||||
|
201 => 'bios-restore',
|
||||||
|
202 => 'cmos-reset',
|
||||||
|
203 => 'diagnostics',
|
||||||
|
204 => 'diagnostic-failed',
|
||||||
|
);
|
||||||
|
|
||||||
$thresholds = {
|
$thresholds = {
|
||||||
presence => {
|
'default.presence' => [
|
||||||
0 => ['unknown', 'UNKNOWN'],
|
['unknown', 'UNKNOWN'],
|
||||||
1 => ['empty', 'OK'],
|
['empty', 'OK'],
|
||||||
10 => ['equipped', 'OK'],
|
['equipped', 'OK'],
|
||||||
11 => ['missing', 'WARNING'],
|
['missing', 'WARNING'],
|
||||||
12 => ['mismatch', 'WARNING'],
|
['mismatch', 'WARNING'],
|
||||||
13 => ['equippedNotPrimary', 'OK'],
|
['equippedNotPrimary', 'OK'],
|
||||||
20 => ['equippedIdentityUnestablishable', 'WARNING'],
|
['equippedIdentityUnestablishable', 'WARNING'],
|
||||||
21 => ['mismatchIdentityUnestablishable', 'WARNING'],
|
['mismatchIdentityUnestablishable', 'WARNING'],
|
||||||
30 => ['inaccessible', 'UNKNOWN'],
|
['inaccessible', 'UNKNOWN'],
|
||||||
40 => ['unauthorized', 'UNKNOWN'],
|
['unauthorized', 'UNKNOWN'],
|
||||||
100 => ['notSupported', 'WARNING'],
|
['notSupported', 'WARNING'],
|
||||||
},
|
],
|
||||||
operability => {
|
'default.operability' => [
|
||||||
0 => ['unknown', 'UNKNOWN'],
|
['unknown', 'UNKNOWN'],
|
||||||
1 => ['operable', 'OK'],
|
['operable', 'OK'],
|
||||||
2 => ['inoperable', 'CRITICAL'],
|
['inoperable', 'CRITICAL'],
|
||||||
3 => ['degraded', 'WARNING'],
|
['degraded', 'WARNING'],
|
||||||
4 => ['poweredOff', 'WARNING'],
|
['poweredOff', 'WARNING'],
|
||||||
5 => ['powerProblem', 'CRITICAL'],
|
['powerProblem', 'CRITICAL'],
|
||||||
6 => ['removed', 'WARNING'],
|
['removed', 'WARNING'],
|
||||||
7 => ['voltageProblem', 'CRITICAL'],
|
['voltageProblem', 'CRITICAL'],
|
||||||
8 => ['thermalProblem', 'CRITICAL'],
|
['thermalProblem', 'CRITICAL'],
|
||||||
9 => ['performanceProblem', 'CRITICAL'],
|
['performanceProblem', 'CRITICAL'],
|
||||||
10 => ['accessibilityProblem', 'WARNING'],
|
['accessibilityProblem', 'WARNING'],
|
||||||
11 => ['identityUnestablishable', 'WARNING'],
|
['identityUnestablishable', 'WARNING'],
|
||||||
12 => ['biosPostTimeout', 'WARNING'],
|
['biosPostTimeout', 'WARNING'],
|
||||||
13 => ['disabled', 'OK'],
|
['disabled', 'OK'],
|
||||||
51 => ['fabricConnProblem', 'WARNING'],
|
['fabricConnProblem', 'WARNING'],
|
||||||
52 => ['fabricUnsupportedConn', 'WARNING'],
|
['fabricUnsupportedConn', 'WARNING'],
|
||||||
81 => ['config', 'OK'],
|
['config', 'OK'],
|
||||||
82 => ['equipmentProblem', 'CRITICAL'],
|
['equipmentProblem', 'CRITICAL'],
|
||||||
83 => ['decomissioning', 'WARNING'],
|
['decomissioning', 'WARNING'],
|
||||||
84 => ['chassisLimitExceeded', 'WARNING'],
|
['chassisLimitExceeded', 'WARNING'],
|
||||||
100 => ['notSupported', 'WARNING'],
|
['notSupported', 'WARNING'],
|
||||||
101 => ['discovery', 'OK'],
|
['discovery', 'OK'],
|
||||||
102 => ['discoveryFailed', 'WARNING'],
|
['discoveryFailed', 'WARNING'],
|
||||||
104 => ['postFailure', 'WARNING'],
|
['postFailure', 'WARNING'],
|
||||||
105 => ['upgradeProblem', 'WARNING'],
|
['upgradeProblem', 'WARNING'],
|
||||||
106 => ['peerCommProblem', 'WARNING'],
|
['peerCommProblem', 'WARNING'],
|
||||||
107 => ['autoUpgrade', 'OK'],
|
['autoUpgrade', 'OK'],
|
||||||
},
|
],
|
||||||
overall_status => {
|
'default.overall_status' => [
|
||||||
0 => ['indeterminate', 'UNKNOWN'],
|
['indeterminate', 'UNKNOWN'],
|
||||||
1 => ['unassociated', 'OK'],
|
['unassociated', 'OK'],
|
||||||
10 => ['ok', 'OK'],
|
['ok', 'OK'],
|
||||||
11 => ['discovery', 'OK'],
|
['discovery', 'OK'],
|
||||||
12 => ['config', 'OK'],
|
['config', 'OK'],
|
||||||
13 => ['unconfig', 'OK'],
|
['unconfig', 'OK'],
|
||||||
14 => ['power-off', 'WARNING'],
|
['power-off', 'WARNING'],
|
||||||
15 => ['restart', 'WARNING'],
|
['restart', 'WARNING'],
|
||||||
20 => ['maintenance', 'OK'],
|
['maintenance', 'OK'],
|
||||||
21 => ['test', 'OK'],
|
['test', 'OK'],
|
||||||
29 => ['compute-mismatch', 'WARNING'],
|
['compute-mismatch', 'WARNING'],
|
||||||
30 => ['compute-failed', 'WARNING'],
|
['compute-failed', 'WARNING'],
|
||||||
31 => ['degraded', 'WARNING'],
|
['degraded', 'WARNING'],
|
||||||
32 => ['discovery-failed', 'WARNING'],
|
['discovery-failed', 'WARNING'],
|
||||||
33 => ['config-failure', 'WARNING'],
|
['config-failure', 'WARNING'],
|
||||||
34 => ['unconfig-failed', 'WARNING'],
|
['unconfig-failed', 'WARNING'],
|
||||||
35 => ['test-failed', 'WARNING'],
|
['test-failed', 'WARNING'],
|
||||||
36 => ['maintenance-failed', 'WARNING'],
|
['maintenance-failed', 'WARNING'],
|
||||||
40 => ['removed', 'WARNING'],
|
['removed', 'WARNING'],
|
||||||
41 => ['disabled', 'OK'],
|
['disabled', 'OK'],
|
||||||
50 => ['inaccessible', 'WARNING'],
|
['inaccessible', 'WARNING'],
|
||||||
60 => ['thermal-problem', 'CRITICAL'],
|
['thermal-problem', 'CRITICAL'],
|
||||||
61 => ['power-problem', 'CRITICAL'],
|
['power-problem', 'CRITICAL'],
|
||||||
62 => ['voltage-problem', 'CRITICAL'],
|
['voltage-problem', 'CRITICAL'],
|
||||||
63 => ['inoperable', 'CRITICAL'],
|
['inoperable', 'CRITICAL'],
|
||||||
101 => ['decommissioning', 'WARNING'],
|
['decommissioning', 'WARNING'],
|
||||||
201 => ['bios-restore', 'WARNING'],
|
['bios-restore', 'WARNING'],
|
||||||
202 => ['cmos-reset', 'WARNING'],
|
['cmos-reset', 'WARNING'],
|
||||||
203 => ['diagnostics', 'OK'],
|
['diagnostics', 'OK'],
|
||||||
204 => ['diagnostic-failed', 'WARNING'],
|
['diagnostic-failed', 'WARNING'],
|
||||||
},
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -25,12 +25,6 @@ use base qw(centreon::plugins::mode);
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
use hardware::server::cisco::ucs::mode::components::resources qw($thresholds);
|
||||||
use hardware::server::cisco::ucs::mode::components::fan;
|
|
||||||
use hardware::server::cisco::ucs::mode::components::psu;
|
|
||||||
use hardware::server::cisco::ucs::mode::components::iocard;
|
|
||||||
use hardware::server::cisco::ucs::mode::components::chassis;
|
|
||||||
use hardware::server::cisco::ucs::mode::components::blade;
|
|
||||||
use hardware::server::cisco::ucs::mode::components::fex;
|
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, %options) = @_;
|
my ($class, %options) = @_;
|
||||||
|
@ -41,8 +35,8 @@ sub new {
|
||||||
$options{options}->add_options(arguments =>
|
$options{options}->add_options(arguments =>
|
||||||
{
|
{
|
||||||
"exclude:s" => { name => 'exclude' },
|
"exclude:s" => { name => 'exclude' },
|
||||||
"absent-problem:s" => { name => 'absent' },
|
"absent-problem:s@" => { name => 'absent_problem' },
|
||||||
"component:s" => { name => 'component', default => 'all' },
|
"component:s" => { name => 'component', default => '.*' },
|
||||||
"no-component:s" => { name => 'no_component' },
|
"no-component:s" => { name => 'no_component' },
|
||||||
"threshold-overload:s@" => { name => 'threshold_overload' },
|
"threshold-overload:s@" => { name => 'threshold_overload' },
|
||||||
});
|
});
|
||||||
|
@ -63,64 +57,69 @@ sub check_options {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->{absent_problem} = [];
|
||||||
|
foreach my $val (@{$self->{option_results}->{absent_problem}}) {
|
||||||
|
next if (!defined($val) || $val eq '');
|
||||||
|
my @values = split (/,/, $val);
|
||||||
|
push @{$self->{absent_problem}}, { filter => $values[0], instance => $values[1] };
|
||||||
|
}
|
||||||
|
|
||||||
$self->{overload_th} = {};
|
$self->{overload_th} = {};
|
||||||
foreach my $val (@{$self->{option_results}->{threshold_overload}}) {
|
foreach my $val (@{$self->{option_results}->{threshold_overload}}) {
|
||||||
if ($val !~ /^(.*?),(.*?),(.*?),(.*)$/) {
|
next if (!defined($val) || $val eq '');
|
||||||
$self->{output}->add_option_msg(short_msg => "Wrong treshold-overload option '" . $val . "'.");
|
my @values = split (/,/, $val);
|
||||||
|
if (scalar(@values) < 3) {
|
||||||
|
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'.");
|
||||||
|
$self->{output}->option_exit();
|
||||||
|
}
|
||||||
|
my ($section, $instance, $status, $filter);
|
||||||
|
if (scalar(@values) == 3) {
|
||||||
|
($section, $status, $filter) = @values;
|
||||||
|
$instance = '.*';
|
||||||
|
} else {
|
||||||
|
($section, $instance, $status, $filter) = @values;
|
||||||
|
}
|
||||||
|
if ($section !~ /^(fan|psu|chassis|iocard|blade|fex)\.(presence|operability|overall_status)$/) {
|
||||||
|
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'.");
|
||||||
$self->{output}->option_exit();
|
$self->{output}->option_exit();
|
||||||
}
|
}
|
||||||
my ($section, $type, $status, $filter) = ($1, $2, $3, $4);
|
|
||||||
if ($self->{output}->is_litteral_status(status => $status) == 0) {
|
if ($self->{output}->is_litteral_status(status => $status) == 0) {
|
||||||
$self->{output}->add_option_msg(short_msg => "Wrong treshold-overload status '" . $val . "'.");
|
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'.");
|
||||||
$self->{output}->option_exit();
|
$self->{output}->option_exit();
|
||||||
}
|
}
|
||||||
$self->{overload_th}->{$section} = { } if (!defined($self->{overload_th}->{$section}));
|
$self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section}));
|
||||||
$self->{overload_th}->{$section}->{$type} = { } if (!defined($self->{overload_th}->{$section}->{$type}));
|
push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance };
|
||||||
$self->{overload_th}->{$section}->{$type}->{$filter} = $status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub global {
|
|
||||||
my ($self, %options) = @_;
|
|
||||||
|
|
||||||
hardware::server::cisco::ucs::mode::components::fan::check($self);
|
|
||||||
hardware::server::cisco::ucs::mode::components::psu::check($self);
|
|
||||||
hardware::server::cisco::ucs::mode::components::iocard::check($self);
|
|
||||||
hardware::server::cisco::ucs::mode::components::chassis::check($self);
|
|
||||||
hardware::server::cisco::ucs::mode::components::blade::check($self);
|
|
||||||
hardware::server::cisco::ucs::mode::components::fex::check($self);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub component {
|
|
||||||
my ($self, %options) = @_;
|
|
||||||
|
|
||||||
if ($self->{option_results}->{component} eq 'fan') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::fan::check($self);
|
|
||||||
} elsif ($self->{option_results}->{component} eq 'psu') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::psu::check($self);
|
|
||||||
} elsif ($self->{option_results}->{component} eq 'iocard') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::iocard::check($self);
|
|
||||||
} elsif ($self->{option_results}->{component} eq 'chassis') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::chassis::check($self);
|
|
||||||
} elsif ($self->{option_results}->{component} eq 'blade') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::blade::check($self);
|
|
||||||
} elsif ($self->{option_results}->{component} eq 'fex') {
|
|
||||||
hardware::server::cisco::ucs::mode::components::fex::check($self);
|
|
||||||
} else {
|
|
||||||
$self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'.");
|
|
||||||
$self->{output}->option_exit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run {
|
sub run {
|
||||||
my ($self, %options) = @_;
|
my ($self, %options) = @_;
|
||||||
# $options{snmp} = snmp object
|
|
||||||
$self->{snmp} = $options{snmp};
|
$self->{snmp} = $options{snmp};
|
||||||
|
|
||||||
if ($self->{option_results}->{component} eq 'all') {
|
my $snmp_request = [];
|
||||||
$self->global();
|
my @components = ('fan', 'psu', 'chassis', 'iocard', 'blade', 'fex');
|
||||||
} else {
|
foreach (@components) {
|
||||||
$self->component();
|
if (/$self->{option_results}->{component}/) {
|
||||||
|
my $mod_name = "hardware::server::cisco::ucs::mode::components::$_";
|
||||||
|
centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name,
|
||||||
|
error_msg => "Cannot load module '$mod_name'.");
|
||||||
|
my $func = $mod_name->can('load');
|
||||||
|
$func->(request => $snmp_request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scalar(@{$snmp_request}) == 0) {
|
||||||
|
$self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'.");
|
||||||
|
$self->{output}->option_exit();
|
||||||
|
}
|
||||||
|
$self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request);
|
||||||
|
|
||||||
|
foreach (@components) {
|
||||||
|
if (/$self->{option_results}->{component}/) {
|
||||||
|
my $mod_name = "hardware::server::cisco::ucs::mode::components::$_";
|
||||||
|
my $func = $mod_name->can('check');
|
||||||
|
$func->($self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $total_components = 0;
|
my $total_components = 0;
|
||||||
|
@ -130,12 +129,13 @@ sub run {
|
||||||
# Skipping short msg when no components
|
# Skipping short msg when no components
|
||||||
next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0);
|
next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0);
|
||||||
$total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
|
$total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
|
||||||
$display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name};
|
my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
|
||||||
|
$display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name};
|
||||||
$display_by_component_append = ', ';
|
$display_by_component_append = ', ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{output}->output_add(severity => 'OK',
|
$self->{output}->output_add(severity => 'OK',
|
||||||
short_msg => sprintf("All %s components [%s] are ok.",
|
short_msg => sprintf("All %s components are ok [%s].",
|
||||||
$total_components,
|
$total_components,
|
||||||
$display_by_component)
|
$display_by_component)
|
||||||
);
|
);
|
||||||
|
@ -144,11 +144,30 @@ sub run {
|
||||||
$self->{output}->output_add(severity => $self->{no_components},
|
$self->{output}->output_add(severity => $self->{no_components},
|
||||||
short_msg => 'No components are checked.');
|
short_msg => 'No components are checked.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{output}->display();
|
$self->{output}->display();
|
||||||
$self->{output}->exit();
|
$self->{output}->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub absent_problem {
|
||||||
|
my ($self, %options) = @_;
|
||||||
|
|
||||||
|
foreach (@{$self->{absent_problem}}) {
|
||||||
|
if ($options{section} =~ /$_->{filter}/) {
|
||||||
|
if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) {
|
||||||
|
$self->{output}->output_add(severity => 'CRITICAL',
|
||||||
|
short_msg => sprintf("Component '%s' instance '%s' is not present",
|
||||||
|
$options{section}, $options{instance}));
|
||||||
|
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)"));
|
||||||
|
$self->{components}->{$options{section}}->{skip}++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sub check_exclude {
|
sub check_exclude {
|
||||||
my ($self, %options) = @_;
|
my ($self, %options) = @_;
|
||||||
|
|
||||||
|
@ -167,31 +186,26 @@ sub check_exclude {
|
||||||
|
|
||||||
sub get_severity {
|
sub get_severity {
|
||||||
my ($self, %options) = @_;
|
my ($self, %options) = @_;
|
||||||
|
my $status = 'UNKNOWN'; # default
|
||||||
|
|
||||||
my $status = ${$thresholds->{$options{threshold}}->{$options{value}}}[1];
|
if (defined($self->{overload_th}->{$options{section}})) {
|
||||||
if (defined($self->{overload_th}->{$options{section}}->{$options{threshold}})) {
|
foreach (@{$self->{overload_th}->{$options{section}}}) {
|
||||||
foreach (keys %{$self->{overload_th}->{$options{section}}->{$options{threshold}}}) {
|
if ($options{value} =~ /$_->{filter}/i &&
|
||||||
if (${$thresholds->{$options{threshold}}->{$options{value}}}[0] =~ /$_/i) {
|
(!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) {
|
||||||
$status = $self->{overload_th}->{$options{section}}->{$options{threshold}}->{$_};
|
$status = $_->{status};
|
||||||
last;
|
return $status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $status;
|
my $label = defined($options{label}) ? $options{label} : $options{section};
|
||||||
}
|
foreach (@{$thresholds->{$label}}) {
|
||||||
|
if ($options{value} =~ /$$_[0]/i) {
|
||||||
sub absent_problem {
|
$status = $$_[1];
|
||||||
my ($self, %options) = @_;
|
return $status;
|
||||||
|
}
|
||||||
if (defined($self->{option_results}->{absent}) &&
|
|
||||||
$self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) {
|
|
||||||
$self->{output}->output_add(severity => 'CRITICAL',
|
|
||||||
short_msg => sprintf("Component '%s' instance '%s' is not present",
|
|
||||||
$options{section}, $options{instance}));
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -206,13 +220,13 @@ Check Hardware (Fans, Power supplies, chassis, io cards, blades, fabric extender
|
||||||
|
|
||||||
=item B<--component>
|
=item B<--component>
|
||||||
|
|
||||||
Which component to check (Default: 'all').
|
Which component to check (Default: '.*').
|
||||||
Can be: 'fan', 'psu', 'chassis', 'iocard', 'blade', 'fex'
|
Can be: 'fan', 'psu', 'chassis', 'iocard', 'blade', 'fex'.
|
||||||
|
|
||||||
=item B<--exclude>
|
=item B<--exclude>
|
||||||
|
|
||||||
Exclude some parts (comma seperated list) (Example: --exclude=fan)
|
Exclude some parts (comma seperated list) (Example: --exclude=fan)
|
||||||
Can also exclude specific instance: --exclude=fan#/sys/chassis-7/fan-module-1-7/fan-1#
|
Can be specific or global: --absent-problem=fan,/sys/chassis-7/fan-module-1-7/fan-1
|
||||||
|
|
||||||
=item B<--absent-problem>
|
=item B<--absent-problem>
|
||||||
|
|
||||||
|
@ -226,8 +240,9 @@ If total (with skipped) is 0. (Default: 'critical' returns).
|
||||||
|
|
||||||
=item B<--threshold-overload>
|
=item B<--threshold-overload>
|
||||||
|
|
||||||
Set to overload default threshold values (syntax: section,threshold,status,regexp)
|
Set to overload default threshold values (syntax: section,[instance,]status,regexp)
|
||||||
Example: --threshold-overload='fan,operability,OK,poweredOff|removed'
|
It used before default thresholds (order stays).
|
||||||
|
Example: --threshold-overload='fan.operability,OK,poweredOff|removed'
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue