* add compatibility for cisco TC
This commit is contained in:
qgarnier 2020-09-02 11:19:57 +02:00 committed by GitHub
parent f46ae9c2c1
commit 1489326501
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 175 additions and 82 deletions

View File

@ -158,6 +158,7 @@ sub set_method {
my ($self, %options) = @_;
$self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => undef);
$self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => undef);
$self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPGET'), parameter => 1);
if ($options{request}->{method} eq 'GET') {
@ -318,7 +319,7 @@ sub request {
my $headers = [];
my $content_type_forced = 0;
foreach my $key (keys %{$options{request}->{headers}}) {
push @$headers, $key . ':' . $options{request}->{headers}->{$key};
push @$headers, $key . ':' . (defined($options{request}->{headers}->{$key}) ? $options{request}->{headers}->{$key} : '');
if ($key =~ /content-type/i) {
$content_type_forced = 1;
}

View File

@ -50,7 +50,8 @@ sub new {
'proto:s' => { name => 'proto' },
'api-username:s' => { name => 'api_username' },
'api-password:s' => { name => 'api_password' },
'timeout:s' => { name => 'timeout', default => 30 }
'timeout:s' => { name => 'timeout', default => 30 },
'no-session' => { name => 'no_session' }
});
}
@ -74,27 +75,28 @@ sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30;
$self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : undef;
$self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : undef;
$self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : '';
$self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : '';
$self->{no_session} = (defined($self->{option_results}->{no_session})) ? 1 : 0;
if (!defined($self->{hostname}) || $self->{hostname} eq '') {
if ($self->{hostname} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --hostname option.");
$self->{output}->option_exit();
}
if (!defined($self->{api_username}) || $self->{api_username} eq '') {
if ($self->{api_username} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --api-username option.");
$self->{output}->option_exit();
}
if (!defined($self->{api_password}) || $self->{api_password} eq '') {
if ($self->{api_password} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --api-password option.");
$self->{output}->option_exit();
}
$self->{cache}->check_options(option_results => $self->{option_results});
$self->{cache}->check_options(option_results => $self->{option_results}) if ($self->{no_session} == 0);
return 0;
}
@ -105,6 +107,12 @@ sub build_options_for_httplib {
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{timeout} = $self->{timeout};
if ($self->{no_session} == 1) {
$self->{option_results}->{credentials} = 1;
$self->{option_results}->{basic} = 1;
$self->{option_results}->{username} = $self->{api_username};
$self->{option_results}->{password} = $self->{api_password};
}
}
sub settings {
@ -116,21 +124,6 @@ sub settings {
$self->{http}->set_options(%{$self->{option_results}});
}
sub json_decode {
my ($self, %options) = @_;
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($options{content});
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
return $decoded;
}
sub clean_session_cookie {
my ($self, %options) = @_;
@ -179,7 +172,7 @@ sub request_api {
my ($self, %options) = @_;
$self->settings();
if (!defined($self->{session_cookie})) {
if ($self->{no_session} == 0 && !defined($self->{session_cookie})) {
$self->authenticate(statefile => $self->{cache});
}
@ -189,7 +182,7 @@ sub request_api {
);
# Maybe there is an issue with the session_cookie. So we retry.
if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) {
if ($self->{no_session} == 0 && ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300)) {
$self->clean_session_cookie(statefile => $self->{cache});
$self->authenticate(statefile => $self->{cache});
$content = $self->{http}->request(
@ -251,6 +244,10 @@ Set password.
Threshold for HTTP timeout (Default: '30').
=item B<--no-session>
To be used for legacy version (before CE 8.0).
=back
=cut

View File

@ -221,7 +221,7 @@ __END__
=head1 MODE
Check call channels in real-time.
Check call channels in real-time (since CE 8.3)
=over 8

View File

@ -207,7 +207,7 @@ __END__
=head1 MODE
Check call history.
Check call history (since TC 6.3)
=over 8

View File

@ -119,7 +119,7 @@ __END__
=head1 MODE
Check certificates validity.
Check certificates validity (since CE 9.2)
=over 8

View File

@ -44,6 +44,7 @@ sub set_system {
['Unknown', 'UNKNOWN']
],
temperature => [
['n/a', 'OK'],
['Normal', 'OK'],
['.*', 'CRITICAL']
],
@ -55,6 +56,7 @@ sub set_system {
['Succeeded', 'OK']
],
software_urgency => [
['n/a', 'OK'],
['Low', 'OK'],
['Medium', 'OK'],
['Critical', 'CRITICAL']
@ -116,6 +118,11 @@ sub execute_custom {
url_path => '/status.xml',
ForceArray => ['Microphone', 'HDMI', 'Line', 'InternalSpeaker', 'Camera', 'Connector', 'Source']
);
my $system_version = 'unknown';
$system_version = $self->{results}->{version} if (defined($self->{results}->{version}));
$self->{output}->output_add(long_msg => 'system version: ' . $system_version);
}
1;

View File

@ -55,11 +55,13 @@ sub check {
$self->{components}->{ad} = { name => 'audio devices', total => 0, skip => 0 };
return if ($self->check_filter(section => 'ad'));
# since CE 9.8
check_ad(
$self,
entry => $self->{results}->{Audio}->{Devices}->{HandsetUSB},
instance => 'handsetUSB'
);
# since CE 9.8
check_ad(
$self,
entry => $self->{results}->{Audio}->{Devices}->{HeadsetUSB},

View File

@ -23,13 +23,23 @@ package hardware::devices::cisco::ces::restapi::mode::components::aic;
use strict;
use warnings;
#<Connectors item="1">
# <Microphone item="1">
# <EcReferenceDelay item="1">0</EcReferenceDelay>
# </Microphone>
# <Microphone item="2">
# <EcReferenceDelay item="1">0</EcReferenceDelay>
# </Microphone>
#</Connectors>
sub check_aic {
my ($self, %options) = @_;
foreach (@{$options{entry}->{ $options{element} }}) {
my $instance = $options{element} . ':' . $_->{item};
next if (!defined($_->{ConnectionStatus}) && !defined($_->{EcReferenceDelay}));
my $ec_reference_delay = ref($_->{EcReferenceDelay}) eq 'HASH' ? $_->{EcReferenceDelay}->{content} : $_->{EcReferenceDelay};
next if (!defined($_->{ConnectionStatus}) && !defined($ec_reference_delay));
next if ($self->check_filter(section => 'aic', instance => $instance));
$self->{components}->{aic}->{total}++;
@ -40,7 +50,7 @@ sub check_aic {
$instance,
defined($_->{ConnectionStatus}) ? $_->{ConnectionStatus} : 'n/a',
$instance,
defined($_->{EcReferenceDelay}) ? $_->{EcReferenceDelay} : '-'
defined($ec_reference_delay) ? $ec_reference_delay : '-'
)
);
@ -54,15 +64,15 @@ sub check_aic {
}
}
if (defined($_->{EcReferenceDelay})) {
my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'aiclatency', instance => $instance, value => $_->{EcReferenceDelay});
if (defined($ec_reference_delay)) {
my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'aiclatency', instance => $instance, value => $ec_reference_delay);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf(
"audio input connector '%s' latency is %s ms",
$instance, $_->{EcReferenceDelay}
$instance, $ec_reference_delay
)
);
}
@ -70,9 +80,9 @@ sub check_aic {
unit => 'ms',
nlabel => 'component.audio.input.connector.latency.milliseconds',
instances => [$options{element}, $_->{item}],
value => $_->{EcReferenceDelay},
value => $ec_reference_delay,
warning => $warn,
critical => $crit,
critical => $crit
);
}
}

View File

@ -85,18 +85,21 @@ sub check {
$self->{components}->{aoc} = { name => 'audio output connectors', total => 0, skip => 0 };
return if ($self->check_filter(section => 'aoc'));
# since CE 9.4
check_aoc(
$self,
entry => $self->{results}->{Audio}->{Output}->{Connectors},
element => 'HDMI',
instance => 'item'
);
# since CE 9.4
check_aoc(
$self,
entry => $self->{results}->{Audio}->{Output}->{Connectors},
element => 'InternalSpeaker',
instance => 'item'
);
# since CE 8.1
check_aoc(
$self,
entry => $self->{results}->{Audio}->{Output}->{Connectors},

View File

@ -23,6 +23,15 @@ package hardware::devices::cisco::ces::restapi::mode::components::camera;
use strict;
use warnings;
#<Camera item="1">
# <Capabilities item="1">
# <Options item="1">ptzf</Options>
# </Capabilities>
# <Connected item="1">True</Connected>
# ...
#</Camera>
#
sub check {
my ($self) = @_;
@ -30,28 +39,32 @@ sub check {
$self->{components}->{camera} = { name => 'cameras', total => 0, skip => 0 };
return if ($self->check_filter(section => 'camera'));
return if (!defined($self->{results}->{Cameras}->{Camera}));
my $cameras = defined($self->{results}->{Cameras}->{Camera}) ? $self->{results}->{Cameras}->{Camera} : $self->{results}->{Camera};
foreach (@{$self->{results}->{Cameras}->{Camera}}) {
return if (!$cameras);
foreach (@$cameras) {
my $instance = $_->{item};
next if ($self->check_filter(section => 'camera', instance => $instance));
$self->{components}->{camera}->{total}++;
my $connected = ref($_->{Connected}) eq 'HASH' ? $_->{Connected}->{content} : $_->{Connected};
$self->{output}->output_add(
long_msg => sprintf(
"camera '%s' connection status is '%s' [instance: %s]",
$instance,
$_->{Connected},
$instance,
$connected,
$instance
)
);
my $exit = $self->get_severity(label => 'connected', section => 'camera.status', value => $_->{Connected});
my $exit = $self->get_severity(label => 'connected', section => 'camera.status', value => $connected);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("camera '%s' connection status is '%s'", $instance, $_->{Connected})
short_msg => sprintf("camera '%s' connection status is '%s'", $instance, $connected)
);
}
}

View File

@ -36,29 +36,35 @@ sub check {
return if ($self->check_filter(section => 'software', instance => $instance));
$self->{components}->{software}->{total}++;
my $status = ref($self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status}) eq 'HASH' ?
$self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status}->{content} : $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status};
my $urgency = ref($self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency}) eq 'HASH' ?
$self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency}->{content} : $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency};
$urgency = 'n/a' if (!defined($urgency));
$self->{output}->output_add(
long_msg => sprintf(
"software '%s' status is '%s' [instance: %s, urgency: %s]",
$instance,
$self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status},
$status,
$instance,
$self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency}
$urgency
)
);
my $exit = $self->get_severity(section => 'software_status', value => $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status});
my $exit = $self->get_severity(section => 'software_status', value => $status);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("software '%s' status is '%s'", $instance, $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Status})
short_msg => sprintf("software '%s' status is '%s'", $instance, $status)
);
}
$exit = $self->get_severity(section => 'software_urgency', value => $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency});
$exit = $self->get_severity(section => 'software_urgency', value => $urgency);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("software '%s' urgency is '%s'", $instance, $self->{results}->{Provisioning}->{Software}->{UpgradeStatus}->{Urgency})
short_msg => sprintf("software '%s' urgency is '%s'", $instance, $urgency)
);
}
}

View File

@ -30,7 +30,12 @@ sub check {
$self->{components}->{temperature} = { name => 'temperature', total => 0, skip => 0 } ;
return if ($self->check_filter(section => 'temperature'));
return if (!defined($self->{results}->{SystemUnit}->{Hardware}->{Monitoring}->{Temperature}));
my $temp_status = $self->{results}->{SystemUnit}->{Hardware}->{Monitoring}->{Temperature}->{Status};
$temp_status = 'n/a' if (!defined($temp_status));
my $temp_value = ref($self->{results}->{SystemUnit}->{Hardware}->{Temperature}) eq 'HASH' ?
$self->{results}->{SystemUnit}->{Hardware}->{Temperature}->{content} : undef;
return if (!defined($temp_status) && !defined($temp_value));
my $instance = 1;
return if ($self->check_filter(section => 'temperature', instance => $instance));
@ -38,20 +43,43 @@ sub check {
$self->{output}->output_add(
long_msg => sprintf(
"temperature '%s' status is '%s' [instance: %s]",
"temperature '%s' status is '%s' [instance: %s, value: %s]",
$instance,
$self->{results}->{SystemUnit}->{Hardware}->{Monitoring}->{Temperature}->{Status},
$instance
$temp_status,
$instance,
defined($temp_value) ? $temp_value : '-'
)
);
my $exit = $self->get_severity(section => 'temperature', value => $self->{results}->{SystemUnit}->{Hardware}->{Monitoring}->{Temperature}->{Status});
my $exit = $self->get_severity(section => 'temperature', value => $temp_status);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("temperarture '%s' status is '%s'", $instance, $self->{results}->{SystemUnit}->{Hardware}->{Monitoring}->{Temperature})
short_msg => sprintf("temperature '%s' status is '%s'", $instance, $temp_status)
);
}
return if (!defined($temp_value));
my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $temp_value);
if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf(
"temperature '%s' is %s C",
$instance, $temp_value
)
);
}
$self->{output}->perfdata_add(
unit => 'C',
nlabel => 'component.hardware.temperature.celsius',
instances => 'system',
value => $temp_value,
warning => $warn,
critical => $crit
);
}
1;

View File

@ -38,20 +38,24 @@ sub check {
next if ($self->check_filter(section => 'vis', instance => $instance));
$self->{components}->{vis}->{total}++;
my $format_status = defined($_->{Resolution}->{FormatStatus}) && ref($_->{Resolution}->{FormatStatus}) eq 'HASH' ?
$_->{Resolution}->{FormatStatus}->{content} :
$_->{FormatStatus};
$self->{output}->output_add(
long_msg => sprintf(
"video input source '%s' format status is '%s' [instance: %s]",
$instance,
$_->{FormatStatus},
$format_status,
$instance
)
);
my $exit = $self->get_severity(section => 'format_status', value => $_->{FormatStatus});
my $exit = $self->get_severity(section => 'format_status', value => $format_status);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("video input source '%s' format status is '%s'", $instance, $_->{FormatStatus})
short_msg => sprintf("video input source '%s' format status is '%s'", $instance, $format_status)
);
}
}

View File

@ -39,15 +39,6 @@ sub custom_status_output {
);
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{description} = $options{new_datas}->{$self->{instance} . '_Description'};
$self->{result_values}->{level} = $options{new_datas}->{$self->{instance} . '_Level'};
$self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_Type'};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
@ -59,8 +50,7 @@ sub set_counters {
$self->{maps_counters}->{alarm} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'Description' }, { name => 'Level' }, { name => 'Type' } ],
closure_custom_calc => $self->can('custom_status_calc'),
key_values => [ { name => 'description' }, { name => 'level' }, { name => 'type' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold
@ -76,6 +66,7 @@ sub new {
$options{options}->add_options(arguments => {
'filter-msg:s' => { name => 'filter_msg' },
'legacy-tc' => { name => 'legacy_tc' },
'warning-status:s' => { name => 'warning_status', default => '%{level} =~ /warning|minor/i' },
'critical-status:s' => { name => 'critical_status', default => '%{level} =~ /critical|major/i' }
});
@ -90,25 +81,50 @@ sub check_options {
$self->change_macros(macros => ['warning_status', 'critical_status']);
}
#<Command>
#<DiagnosticsResult status="OK">
# <Message item="1">
# <Description item="1">System is in standby mode.</Description>
# <Level item="1">Skipped</Level>
# <References item="1"/>
# <Type item="1">SelectedVideoInputSourceConnected</Type>
# </Message>
#</DiagnosticsResult>
#</Command>
sub manage_selection {
my ($self, %options) = @_;
$self->{alarms}->{global} = { alarm => {} };
my $post = '<Command><Diagnostics><Run><ResultSet>Alerts</ResultSet></Run></Diagnostics></Command>';
my $label = 'DiagnosticsRunResult';
if (defined($self->{option_results}->{legacy_tc})) {
$post = '<Command><SystemUnit><Diagnostics><Run><ResultSet>Alerts</ResultSet></Run></Diagnostics></SystemUnit></Command>';
$label = 'DiagnosticsResult';
}
my $result = $options{custom}->request_api(
method => 'POST',
url_path => '/putxml',
query_form_post => '<Command><Diagnostics><Run><ResultSet>Alerts</ResultSet></Run></Diagnostics></Command>',
query_form_post => $post,
ForceArray => ['Message']
);
foreach (@{$result->{DiagnosticsRunResult}->{Message}}) {
$self->{alarms}->{global} = { alarm => {} };
foreach (@{$result->{$label}->{Message}}) {
my $description = ref($_->{Description}) eq 'HASH' ? $_->{Description}->{content} : $_->{Description};
my $level = ref($_->{Level}) eq 'HASH' ? $_->{Level}->{content} : $_->{Level};
my $type = ref($_->{Type}) eq 'HASH' ? $_->{Type}->{content} : $_->{Type};
if (defined($self->{option_results}->{filter_msg}) && $self->{option_results}->{filter_msg} ne '' &&
$_->{Description} !~ /$self->{option_results}->{filter_msg}/) {
$self->{output}->output_add(long_msg => "skipping '" . $_->{Description} . "': no matching filter.", debug => 1);
$description !~ /$self->{option_results}->{filter_msg}/) {
$self->{output}->output_add(long_msg => "skipping '" . $description . "': no matching filter.", debug => 1);
next;
}
$self->{alarms}->{global}->{alarm}->{$_->{item}} = $_;
$self->{alarms}->{global}->{alarm}->{ $_->{item} } = {
description => $description,
level => $level,
type => $type
};
}
}
@ -119,6 +135,8 @@ __END__
=head1 MODE
Check diagnostic messages.
Since TC 6.0: SystemUnit Diagnostics Run (use --legacy-tc option)
Since CE 8.0: Diagnostics Run
=over 8
@ -126,6 +144,10 @@ Check diagnostic messages.
Filter by message (can be a regexp).
=item B<--legacy-tc>
Use old legacy command.
=item B<--warning-status>
Set warning threshold for status (Default: '%{level} =~ /warning|minor/i')

View File

@ -108,7 +108,7 @@ __END__
=head1 MODE
Check peripherals device connected.
Check peripherals device connected (since TC 7.2).
=over 8

View File

@ -89,7 +89,7 @@ __END__
=head1 MODE
Check sessions.
Check sessions (since CE 8.2)
=over 8

View File

@ -31,7 +31,7 @@ sub new {
bless $self, $class;
$self->{version} = '1.0';
%{$self->{modes}} = (
$self->{modes}} = {
'components' => 'hardware::devices::cisco::ces::restapi::mode::components',
'calls-summary' => 'hardware::devices::cisco::ces::restapi::mode::callssummary',
'calls-rt' => 'hardware::devices::cisco::ces::restapi::mode::callsrt',
@ -39,9 +39,9 @@ sub new {
'diagnostics' => 'hardware::devices::cisco::ces::restapi::mode::diagnostics',
'peripherals' => 'hardware::devices::cisco::ces::restapi::mode::peripherals',
'sessions' => 'hardware::devices::cisco::ces::restapi::mode::sessions'
);
};
$self->{custom_modes}{api} = 'hardware::devices::cisco::ces::restapi::custom::api';
$self->{custom_modes}->{api} = 'hardware::devices::cisco::ces::restapi::custom::api';
return $self;
}