From b9787f14fc55bcc7df0b4dcb8fdb0c61038c3ff0 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Mon, 18 May 2026 13:47:15 +0200 Subject: [PATCH 1/9] Add panorama-firewall-discovery mode --- src/network/paloalto/api/custom/api.pm | 36 ++-- .../api/mode/panoramafirewalldiscovery.pm | 157 ++++++++++++++++++ src/network/paloalto/api/plugin.pm | 3 +- .../backup/rubrik/graphql/rubrik-mockoon.json | 2 +- .../paloalto/api/mockoon-paloalto-api.json | 70 +++++++- tests/network/paloalto/api/system.robot | 56 +++++-- 6 files changed, 287 insertions(+), 37 deletions(-) create mode 100644 src/network/paloalto/api/mode/panoramafirewalldiscovery.pm diff --git a/src/network/paloalto/api/custom/api.pm b/src/network/paloalto/api/custom/api.pm index 0822d5d6d0..f8c934bc70 100644 --- a/src/network/paloalto/api/custom/api.pm +++ b/src/network/paloalto/api/custom/api.pm @@ -53,6 +53,7 @@ sub new { 'username:s' => { name => 'username', default => '' }, 'password:s' => { name => 'password', default => '' }, 'timeout:s' => { name => 'timeout', default => 30 }, + 'target:s' => { name => 'target', default => '' }, 'unknown-http-status:s' => { name => 'unknown_http_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, 'warning-http-status:s' => { name => 'warning_http_status', default => '' }, 'critical-http-status:s' => { name => 'critical_http_status', default => '' } @@ -78,17 +79,10 @@ sub set_defaults {} sub check_options { my ($self, %options) = @_; - $self->{hostname} = $self->{option_results}->{hostname}; - $self->{port} = $self->{option_results}->{port}; - $self->{proto} = $self->{option_results}->{proto}; - $self->{auth_type} = $self->{option_results}->{auth_type}; - $self->{api_key} = $self->{option_results}->{api_key}; - $self->{username} = $self->{option_results}->{username}; - $self->{password} = $self->{option_results}->{password}; - $self->{timeout} = $self->{option_results}->{timeout}; - $self->{unknown_http_status} = $self->{option_results}->{unknown_http_status}; - $self->{warning_http_status} = $self->{option_results}->{warning_http_status}; - $self->{critical_http_status} = $self->{option_results}->{critical_http_status}; + $self->{$_} = $self->{option_results}->{$_} foreach qw/hostname port proto timeout + auth_type api_key username password + target + unknown_http_status warning_http_status critical_http_status/; $self->{output}->option_exit(short_msg => "Need to specify --hostname option.") if $self->{hostname} eq ''; @@ -195,7 +189,8 @@ sub _http_request { url_path => '/api/', get_params => { 'type' => $options{type}, - 'cmd' => $options{cmd} + 'cmd' => $options{cmd}, + $self->{target} ? ( target => $self->{target} ) : () }, header => [ $self->_build_auth_header(), @@ -215,20 +210,17 @@ sub _parse_xml { $self->{output}->option_exit( short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']") if is_empty($content); - $self->{output}->option_exit(short_msg => "Cannot find XML response in API reply.") - unless $content =~ /(.*<\/response>)/ms; - - my ($xml, $status) = ($1, $2); - $self->{output}->option_exit(short_msg => "API response status: $status") - unless $status eq 'success'; - my $result; eval { - $result = XMLin($xml, ForceArray => $options{ForceArray} // [], KeyAttr => []); + $result = XMLin($content, ForceArray => $options{ForceArray} // [], KeyAttr => []); }; + $self->{output}->option_exit(short_msg => "Cannot decode XML response: $@") if $@; + $self->{output}->option_exit(short_msg => "API response status: ".value_of($result, "->{status}", "UNKNOWN")) + unless ref $result eq 'HASH' && $result->{status} && $result->{status} eq 'success'; + return $result->{result}; } @@ -304,6 +296,10 @@ Also used with --auth-type=api-key to auto-generate or regenerate the API key. Password. +=item B<--target> + +Firewall serial number to monitor. Only applicable when the hostname points to Panorama. + =item B<--timeout> HTTP request timeout in seconds (default: 30). diff --git a/src/network/paloalto/api/mode/panoramafirewalldiscovery.pm b/src/network/paloalto/api/mode/panoramafirewalldiscovery.pm new file mode 100644 index 0000000000..6135306c01 --- /dev/null +++ b/src/network/paloalto/api/mode/panoramafirewalldiscovery.pm @@ -0,0 +1,157 @@ +# +# Copyright 2026-Present Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::paloalto::api::mode::panoramafirewalldiscovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +use centreon::plugins::misc qw/json_encode is_excluded/; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "prettify" => { name => 'prettify' }, + 'only-connected' => { name => 'only_connected' }, + 'include-name:s' => { name => 'include_name', default => '' }, + 'exclude-name:s' => { name => 'exclude_name', default => '' }, + 'include-model:s' => { name => 'include_model', default => '' }, + 'exclude-model:s' => { name => 'exclude_model', default => '' }, + 'include-ip-address:s' => { name => 'include_ip_address', default => '' }, + 'exclude-ip-address:s' => { name => 'exclude_ip_address', default => '' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{output}->option_exit( short_msg => "The --target parameter is not allowed in this mode." ) + if $options{custom}->{target}; + + my $filter = $self->{option_results}->{only_connected} ? 'connected' : 'all'; + my $result = $self->{instances} = $options{custom}->request_api( + type => 'op', + cmd => "<$filter>", + ForceArray => [ 'entry' ] + ); + + $self->{devices} = [ ]; + + return unless $result && ref $result->{devices}->{entry} eq 'ARRAY'; + + foreach my $device (@{$result->{devices}->{entry}}) { + next unless $device->{serial}; + + my $item = { + Serial => $device->{serial}, + Name => $device->{name} // '', + HostName => $device->{hostname} // '', + Connected => $device->{connected} // '', + Model => $device->{model} // '', + IpAddress => $device->{'ip-address'} // '', + }; + + next if is_excluded($item->{Name}, $self->{option_results}->{include_name}, $self->{option_results}->{exclude_name}, output => $self->{output}) || + is_excluded($item->{Model}, $self->{option_results}->{include_model}, $self->{option_results}->{exclude_model}, output => $self->{output}) || + is_excluded($item->{IpAddress}, $self->{option_results}->{include_ip_address}, $self->{option_results}->{exclude_ip_address}, output => $self->{output}); + + push @{$self->{devices}}, $item; + } +} + +sub run { + my ($self, %options) = @_; + + my $disco_stats; + + $disco_stats->{start_time} = time(); + + $self->manage_selection(%options); + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @{$self->{devices}}; + $disco_stats->{results} = $self->{devices}; + + my $encoded_data = json_encode($disco_stats, + prettify => $self->{option_results}->{prettify}, + errstr => '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'); + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} +1; + +__END__ + +=head1 MODE + +Discover firewalls managed by Panorama. + +=over 8 + +=item B<--only-connected> + +Display only connected firewalls. + +=item B<--include-name> + +Filter firewall by name (can be a regex). + +=item B<--exclude-name> + +Exclude firewall by name (can be a regex). + +=item B<--include-model> + +Filter firewall by model (can be a regex). + +=item B<--exclude-model> + +Exclude firewall by model (can be a regex). + +=item B<--include-ip-address> + +Filter firewall by IP address (can be a regex). + +=item B<--exclude-ip-address> + +Exclude firewall IP by address (can be a regex). + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/src/network/paloalto/api/plugin.pm b/src/network/paloalto/api/plugin.pm index 99373650c5..1ad2b9d416 100644 --- a/src/network/paloalto/api/plugin.pm +++ b/src/network/paloalto/api/plugin.pm @@ -35,7 +35,8 @@ sub new { 'ha' => 'network::paloalto::api::mode::ha', 'licenses' => 'network::paloalto::api::mode::licenses', 'system' => 'network::paloalto::api::mode::system', - 'ipsec' => 'network::paloalto::api::mode::ipsec' + 'ipsec' => 'network::paloalto::api::mode::ipsec', + 'panorama-firewall-discovery' => 'network::paloalto::api::mode::panoramafirewalldiscovery' }; $self->{custom_modes}->{api} = 'network::paloalto::api::custom::api'; diff --git a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json index 2c7022088f..27c7266ea4 100644 --- a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json +++ b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json @@ -386,4 +386,4 @@ ], "data": [], "callbacks": [] -} +} \ No newline at end of file diff --git a/tests/network/paloalto/api/mockoon-paloalto-api.json b/tests/network/paloalto/api/mockoon-paloalto-api.json index c854211e63..a9a91b4a57 100644 --- a/tests/network/paloalto/api/mockoon-paloalto-api.json +++ b/tests/network/paloalto/api/mockoon-paloalto-api.json @@ -170,9 +170,16 @@ "value": "", "invert": false, "operator": "regex" + }, + { + "target": "query", + "modifier": "target", + "value": "", + "invert": false, + "operator": "null" } ], - "rulesOperator": "OR", + "rulesOperator": "AND", "disableTemplating": false, "fallbackTo404": false, "default": false, @@ -210,6 +217,67 @@ "default": false, "crudKey": "id", "callbacks": [] + }, + { + "uuid": "046ba2be-d382-4255-a575-dd5894136b30", + "body": "\n\n\n\n987654\nyes\nno\nno\nDUMMY-1-VM\n10.1.1.11\n\n81 days, 20:39:41\nvm\nPA-VM\n6.1.3\n555-3129\n2254-2693\n91873-10.274\n555-3129\npaulotonetworks\n2016.02.02.416\n6.1.3\n\n0.0.0\nno\nnormal\nno\n\n\n123456\nyes\nno\nno\nDUMMY-2-VM\n10.1.1.10\n\n81 days, 20:39:41\nvm\nPA-VM\n6.1.3\n555-3129\n2254-2693\n91873-10.274\n555-3129\npaulonetworks\n2016.02.02.416\n6.1.3\n\n0.0.0\nno\nnormal\nno\n\n\n\n", + "latency": 0, + "statusCode": 200, + "label": "LIST PANORAMA FIREWALL", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "cmd", + "value": "", + "invert": false, + "operator": "regex" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + }, + { + "uuid": "bcff18d8-0202-46ed-816a-82de046dee3e", + "body": "\n \n \n firewall\n 10.41.0.8\n 255.255.224.0\n 10.41.0.1\n no\n unknown\n fe80::21c:17cf:feff:c04a/64\n \n 00:1b:17:fc:c0:4a\n \n 12 days, 0:05:26\n pm-firewall\n 3000\n PA-3020\n 001802000104\n 1.PANORAMA\n 2.0.0\n 537-2965\n 2015/10/26 18:10:48\n 2149-2586\n 2015/10/26 15:31:55\n 537-2965\n 2015/10/26 18:10:48\n 0\n unknown\n paloaltonetworks\n 80683-89773\n unknown\n 2015.10.27.226\n 1445974904\n 2015/10/27 19:41:44\n 7.0.9\n 3000\n off\n on\n normal\n Valid\n \n \n", + "latency": 0, + "statusCode": 200, + "label": "SYSTEM PANORAMA", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "cmd", + "value": "", + "invert": false, + "operator": "regex" + }, + { + "target": "query", + "modifier": "target", + "value": "", + "invert": true, + "operator": "null" + } + ], + "rulesOperator": "AND", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] } ], "responseMode": null, diff --git a/tests/network/paloalto/api/system.robot b/tests/network/paloalto/api/system.robot index 79d9aef1c7..d2f7cdd40d 100644 --- a/tests/network/paloalto/api/system.robot +++ b/tests/network/paloalto/api/system.robot @@ -19,6 +19,7 @@ ${CMD} ${CENTREON_PLUGINS} ... --proto=http ... --mode=system + *** Test Cases *** paloalto-system ${tc} [Tags] network paloalto api system @@ -31,17 +32,44 @@ paloalto-system ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, software version: 10.1.12, WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; - ... 2 --warning-uptime=:1000 WARNING: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;0:1000;;0; - ... 3 --critical-uptime=:1000 CRITICAL: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;;0:1000;0; - ... 4 --warning-certificate-status='\\\%{cert_status} =~ /Valid/' WARNING: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; - ... 5 --critical-certificate-status='\\\%{cert_status} =~ /Valid/' CRITICAL: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; - ... 6 --warning-software-version='\\\%{sw_version} !~ /2\.0/' WARNING: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; - ... 7 --critical-software-version='\\\%{sw_version} !~ /2\.0/' CRITICAL: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; - ... 8 --warning-operational-mode='\\\%{operational_mode} =~ /normal/' WARNING: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; - ... 9 --critical-operational-mode='\\\%{operational_mode} =~ /normal/' CRITICAL: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; - ... 10 --warning-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' WARNING: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; - ... 11 --critical-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' CRITICAL: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; - - + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, software version: 10.1.12, WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... 2 + ... --warning-uptime=:1000 + ... WARNING: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;0:1000;;0; + ... 3 + ... --critical-uptime=:1000 + ... CRITICAL: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;;0:1000;0; + ... 4 + ... --warning-certificate-status='\\\%{cert_status} =~ /Valid/' + ... WARNING: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; + ... 5 + ... --critical-certificate-status='\\\%{cert_status} =~ /Valid/' + ... CRITICAL: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; + ... 6 + ... --warning-software-version='\\\%{sw_version} !~ /2\.0/' + ... WARNING: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; + ... 7 + ... --critical-software-version='\\\%{sw_version} !~ /2\.0/' + ... CRITICAL: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; + ... 8 + ... --warning-operational-mode='\\\%{operational_mode} =~ /normal/' + ... WARNING: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; + ... 9 + ... --critical-operational-mode='\\\%{operational_mode} =~ /normal/' + ... CRITICAL: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; + ... 10 + ... --warning-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' + ... WARNING: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... 11 + ... --critical-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' + ... CRITICAL: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... 12 + ... --target=001802000104 + ... OK: System uptime: 1037126 seconds, certificate status: Valid, operational mode: normal, software version: 1.PANORAMA, WildFire mode: Unknown | 'system.uptime.seconds'=1037126s;;;0; From fb5c911b56006de932566ec8e59f0a25957cf64e Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Thu, 28 May 2026 09:36:53 +0200 Subject: [PATCH 2/9] Update plugin --- src/centreon/plugins/constants.pm | 10 +- src/centreon/plugins/values.pm | 15 +- src/network/paloalto/api/custom/api.pm | 18 +- src/network/paloalto/api/mode/certificate.pm | 254 +++++++ ...oramafirewalldiscovery.pm => discovery.pm} | 23 +- src/network/paloalto/api/mode/environment.pm | 28 +- src/network/paloalto/api/mode/ha.pm | 3 + src/network/paloalto/api/mode/health.pm | 642 ++++++++++++++++++ src/network/paloalto/api/mode/ipsec.pm | 14 +- src/network/paloalto/api/mode/licenses.pm | 16 +- src/network/paloalto/api/mode/system.pm | 142 +++- src/network/paloalto/api/plugin.pm | 4 +- tests/network/paloalto/api/authent.robot | 31 +- tests/network/paloalto/api/certificate.robot | 97 +++ tests/network/paloalto/api/discovery.robot | 54 ++ tests/network/paloalto/api/environment.robot | 67 +- tests/network/paloalto/api/ha.robot | 51 +- tests/network/paloalto/api/health.robot | 175 +++++ tests/network/paloalto/api/ipsec.robot | 43 +- tests/network/paloalto/api/licenses.robot | 57 +- .../paloalto/api/mockoon-paloalto-api.json | 98 ++- tests/network/paloalto/api/system.robot | 42 +- 22 files changed, 1715 insertions(+), 169 deletions(-) create mode 100644 src/network/paloalto/api/mode/certificate.pm rename src/network/paloalto/api/mode/{panoramafirewalldiscovery.pm => discovery.pm} (85%) create mode 100644 src/network/paloalto/api/mode/health.pm create mode 100644 tests/network/paloalto/api/certificate.robot create mode 100644 tests/network/paloalto/api/discovery.robot create mode 100644 tests/network/paloalto/api/health.robot diff --git a/src/centreon/plugins/constants.pm b/src/centreon/plugins/constants.pm index 25e342c617..c56392e2a5 100644 --- a/src/centreon/plugins/constants.pm +++ b/src/centreon/plugins/constants.pm @@ -40,17 +40,23 @@ use constant { # Only used with COUNTER_TYPE_MULTIPLE counters COUNTER_MULTIPLE_INSTANCE => 0, # counter global to the instance - COUNTER_MULTIPLE_SUBINSTANCE => 1, # counter defined per subinstance + COUNTER_MULTIPLE_SUBINSTANCE => 1, # counter defined per sub instance # Define the nature of a counter ( numeric or text ) COUNTER_KIND_METRIC => 1, # numeric counter with thesholds and perfdata COUNTER_KIND_TEXT => 2, # text counter with status check and no perfdata + # Unit conversion constants + CONVERT_NONE => 0, # No conversion + CONVERT_STORAGE => 1, # Convert units using factor 1024 + CONVERT_NETWORK => 2, # Convert units using factore 1000 + MSG_JSON_DECODE_ERROR => 'Cannot decode response (add --debug option to display returned content)' }; our %EXPORT_TAGS = ( values => [ qw(NO_VALUE BUFFER_CREATION RUN_OK NOT_PROCESSED) ], + unit_conversion => [ qw(CONVERT_NONE CONVERT_STORAGE CONVERT_NETWORK) ], counter_types => [ qw(COUNTER_TYPE_GLOBAL COUNTER_TYPE_INSTANCE COUNTER_TYPE_GROUP COUNTER_TYPE_MULTIPLE) ], counter_multiple_types => [ qw(COUNTER_MULTIPLE_INSTANCE COUNTER_MULTIPLE_SUBINSTANCE) ], counter_kinds => [ qw(COUNTER_KIND_METRIC COUNTER_KIND_TEXT) ], @@ -134,7 +140,7 @@ Counter global to the instance. =item B -Counter defined per subinstance. +Counter defined per sub instance. =back diff --git a/src/centreon/plugins/values.pm b/src/centreon/plugins/values.pm index ff380f538f..5b8d788983 100644 --- a/src/centreon/plugins/values.pm +++ b/src/centreon/plugins/values.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -23,7 +23,7 @@ package centreon::plugins::values; use strict; use warnings; use centreon::plugins::misc; -use centreon::plugins::constants qw(:values); +use centreon::plugins::constants qw(:values :unit_conversion); # Warning message with sprintf and too much arguments. # Really annoying. Need to disable that warning @@ -158,14 +158,15 @@ sub output { if (defined($name)) { $value = $self->{result_values}->{$name}; - if ($self->{output_change_bytes} == 1) { + if ($self->{output_change_bytes} == CONVERT_STORAGE) { ($value, $unit) = $self->{perfdata}->change_bytes(value => $value); - } elsif ($self->{output_change_bytes} == 2) { + } elsif ($self->{output_change_bytes} == CONVERT_NETWORK) { ($value, $unit) = $self->{perfdata}->change_bytes(value => $value, network => 1); } } - return sprintf($self->{output_template}, $value, $unit); + my $output_template = $self->{output_template} =~ s!%\{([A-Za-z0-9_]+)\}! $self->{result_values}->{$1} // '' !ger; + return sprintf($output_template, $value, $unit); } sub use_instances { @@ -193,7 +194,9 @@ sub perfdata { my $cast_int = (defined($perf->{cast_int}) && $perf->{cast_int} == 1) ? 1 : 0; my $template = '%s'; - $template = $perf->{template} if (defined($perf->{template})); + $template = $perf->{template}=~ s!%\{([A-Za-z0-9_]+)\}! $self->{result_values}->{$1} // '' !ger + if defined $perf->{template}; + $label = $perf->{label} if (defined($perf->{label})); if (defined($perf->{min})) { $min = ($perf->{min} =~ /[^0-9.-]/) ? $self->{result_values}->{$perf->{min}} : $perf->{min}; diff --git a/src/network/paloalto/api/custom/api.pm b/src/network/paloalto/api/custom/api.pm index f8c934bc70..24dd4a8411 100644 --- a/src/network/paloalto/api/custom/api.pm +++ b/src/network/paloalto/api/custom/api.pm @@ -129,9 +129,9 @@ sub generate_api_key { my $content = $self->{http}->request( url_path => '/api/', method => 'POST', - get_param => ['type=keygen'], + get_param => [ 'type=keygen' ], query_form_post => 'user=' . uri_escape($self->{username}) . '&password=' . uri_escape($self->{password}), - header => ['Content-Type: application/x-www-form-urlencoded'], + header => [ 'Content-Type: application/x-www-form-urlencoded' ], unknown_status => '', warning_status => '', critical_status => '' @@ -185,13 +185,17 @@ sub _build_auth_header { sub _http_request { my ($self, %options) = @_; + my %params = ( + 'type' => $options{type} + ); + $params{'cmd'} = $options{cmd} if $options{cmd}; + $params{'action'} = $options{action} if $options{action}; + $params{'xpath'} = $options{xpath} if $options{xpath}; + $params{'target'} = $self->{target} if $self->{target}; + return $self->{http}->request( url_path => '/api/', - get_params => { - 'type' => $options{type}, - 'cmd' => $options{cmd}, - $self->{target} ? ( target => $self->{target} ) : () - }, + get_params => \%params, header => [ $self->_build_auth_header(), 'Accept: application/xml' diff --git a/src/network/paloalto/api/mode/certificate.pm b/src/network/paloalto/api/mode/certificate.pm new file mode 100644 index 0000000000..f1c2f63a06 --- /dev/null +++ b/src/network/paloalto/api/mode/certificate.pm @@ -0,0 +1,254 @@ +# +# Copyright 2026-Present Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::paloalto::api::mode::certificate; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::constants qw(:counters); +use DateTime::Format::Strptime; +use centreon::plugins::misc qw(is_excluded is_empty); + +sub prefix_device_output { + my ($self, %options) = @_; + return "Device '" . $options{instance_value}->{hostname} . "' (" . $options{instance_value}->{serial} . ") "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'devices', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_device_output', + message_multiple => 'All device certificates are OK' } + ]; + + $self->{maps_counters}->{devices} = [ + { + label => 'certificate-status', + type => COUNTER_KIND_TEXT, + critical_default => '%{cert_status} !~ /valid|ok/i', + set => { + key_values => [ { name => 'cert_status' }, { name => 'serial' }, { name => 'hostname' }, { name => 'connected' } ], + output_template => 'certificate status: %{cert_status}', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { + label => 'certificate-subject', + type => COUNTER_KIND_TEXT, + display_ok => 0, + set => { + key_values => [ { name => 'cert_subject' }, { name => 'serial' }, { name => 'hostname' }, { name => 'connected' } ], + output_template => 'subject: %{cert_subject}', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { + label => 'certificate-expiry', + nlabel => 'device.certificate.expiry.days', + set => { + key_values => [ { name => 'cert_expiry_days' }, { name => 'serial' }, { name => 'hostname' }, { name => 'connected' } ], + output_template => 'expires in: %{cert_expiry_days} days', + perfdatas => [ + { template => '%s', unit => 'd', min => 0 } + ] + } + }, + { + label => 'certificate-custom-usage', + type => COUNTER_KIND_TEXT, + display_ok => 0, + set => { + key_values => [ { name => 'custom_cert_usage' }, { name => 'serial' }, { name => 'hostname' }, { name => 'connected' } ], + output_template => 'custom certificate usage: %{custom_cert_usage}', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'include-device-serial:s' => { name => 'include_device_serial', default => '' }, + 'exclude-device-serial:s' => { name => 'exclude_device_serial', default => '' }, + 'include-device-hostname:s' => { name => 'include_device_hostname', default => '' }, + 'exclude-device-hostname:s' => { name => 'exclude_device_hostname', default => '' }, + 'connected-only' => { name => 'connected_only' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $filter = $self->{option_results}->{connected_only} ? 'connected' : 'all'; + my $result = $options{custom}->request_api( + type => 'op', + cmd => "<$filter>", + ForceArray => [ 'entry' ] + ); + + $self->{devices} = {}; + + $self->{output}->option_exit(short_msg => "No certificates found !") + unless ref $result->{devices} eq 'HASH'; + + foreach my $device (@{$result->{devices}->{entry}}) { + my $serial = $device->{name}; + my $hostname = $device->{hostname} // ''; + + next if is_excluded($serial, $self->{option_results}->{include_device_serial}, $self->{option_results}->{exclude_device_serial}, output => $self->{output}) || + is_excluded($hostname, $self->{option_results}->{include_device_hostname}, $self->{option_results}->{exclude_device_hostname}, output => $self->{output}); + + my $connected = lc($device->{connected} // 'no'); + my $cert_expiry_days = -1; + $cert_expiry_days = $self->_calculate_days_until_expiry($device->{'certificate-expiry'}) + if exists $device->{'certificate-expiry'}; + + $self->{devices}->{$serial} = { + serial => $serial, + hostname => $hostname, + connected => $connected, + cert_status => $device->{'certificate-status'} // '', + cert_subject => $device->{'certificate-subject-name'} // '', + cert_expiry_days => $cert_expiry_days, + custom_cert_usage => $device->{'custom-certificate-usage'} // '', + }; + } +} + +sub _calculate_days_until_expiry { + my ($self, $expiry_str) = @_; + + return -1 if is_empty($expiry_str); + + my $parser = DateTime::Format::Strptime->new( + pattern => '%b %d, %Y', + on_error => 'undef' + ); + + my $expiry_dt = $parser->parse_datetime($expiry_str); + return -1 unless $expiry_dt; + + my $now = DateTime->now(time_zone => 'UTC'); + my $duration = $expiry_dt - $now; + + return int($duration->in_units('days')); +} + +1; + +__END__ + +=head1 MODE + +Check Palo Alto Panorama managed devices certificate information. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^certificate-status$' + +=item B<--include-device-serial> + +Include only specific device by serial number (regexp can be used). + +=item B<--exclude-device-serial> + +Exclude specific device by serial number (regexp can be used). + +=item B<--include-device-hostname> + +Include only specific device by hostname (regexp can be used). + +=item B<--exclude-device-hostname> + +Exclude specific device by hostname (regexp can be used). + +=item B<--connected-only> + +Only check connected devices. + +=item B<--unknown-certificate-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{cert_status}, %{serial}, %{hostname}, %{connected} + +=item B<--warning-certificate-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{cert_status}, %{serial}, %{hostname}, %{connected} + +=item B<--critical-certificate-status> + +Define the conditions to match for the status to be CRITICAL (default: '%{cert_status} !~ /valid|ok/i'). +You can use the following variables: %{cert_status}, %{serial}, %{hostname}, %{connected} + +=item B<--unknown-certificate-subject> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{cert_subject}, %{serial}, %{hostname}, %{connected} + +=item B<--warning-certificate-subject> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{cert_subject}, %{serial}, %{hostname}, %{connected} + +=item B<--critical-certificate-subject> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{cert_subject}, %{serial}, %{hostname}, %{connected} + +=item B<--warning-certificate-expiry> + +Warning threshold for certificate expiry in days. + +=item B<--critical-certificate-expiry> + +Critical threshold for certificate expiry in days. + +=item B<--unknown-certificate-custom-usage> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{custom_cert_usage}, %{serial}, %{hostname}, %{connected} + +=item B<--warning-certificate-custom-usage> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{custom_cert_usage}, %{serial}, %{hostname}, %{connected} + +=item B<--critical-certificate-custom-usage> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{custom_cert_usage}, %{serial}, %{hostname}, %{connected} + +=back + +=cut diff --git a/src/network/paloalto/api/mode/panoramafirewalldiscovery.pm b/src/network/paloalto/api/mode/discovery.pm similarity index 85% rename from src/network/paloalto/api/mode/panoramafirewalldiscovery.pm rename to src/network/paloalto/api/mode/discovery.pm index 6135306c01..cf4a9d3a8d 100644 --- a/src/network/paloalto/api/mode/panoramafirewalldiscovery.pm +++ b/src/network/paloalto/api/mode/discovery.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::paloalto::api::mode::panoramafirewalldiscovery; +package network::paloalto::api::mode::discovery; use base qw(centreon::plugins::mode); @@ -34,9 +34,9 @@ sub new { $options{options}->add_options(arguments => { "prettify" => { name => 'prettify' }, - 'only-connected' => { name => 'only_connected' }, - 'include-name:s' => { name => 'include_name', default => '' }, - 'exclude-name:s' => { name => 'exclude_name', default => '' }, + 'connected-only' => { name => 'connected_only' }, + 'include-serial:s' => { name => 'include_serial', default => '' }, + 'exclude-serial:s' => { name => 'exclude_serial', default => '' }, 'include-model:s' => { name => 'include_model', default => '' }, 'exclude-model:s' => { name => 'exclude_model', default => '' }, 'include-ip-address:s' => { name => 'include_ip_address', default => '' }, @@ -57,7 +57,7 @@ sub manage_selection { $self->{output}->option_exit( short_msg => "The --target parameter is not allowed in this mode." ) if $options{custom}->{target}; - my $filter = $self->{option_results}->{only_connected} ? 'connected' : 'all'; + my $filter = $self->{option_results}->{connected_only} ? 'connected' : 'all'; my $result = $self->{instances} = $options{custom}->request_api( type => 'op', cmd => "<$filter>", @@ -73,14 +73,13 @@ sub manage_selection { my $item = { Serial => $device->{serial}, - Name => $device->{name} // '', HostName => $device->{hostname} // '', Connected => $device->{connected} // '', Model => $device->{model} // '', IpAddress => $device->{'ip-address'} // '', }; - next if is_excluded($item->{Name}, $self->{option_results}->{include_name}, $self->{option_results}->{exclude_name}, output => $self->{output}) || + next if is_excluded($item->{Serial}, $self->{option_results}->{include_serial}, $self->{option_results}->{exclude_serial}, output => $self->{output}) || is_excluded($item->{Model}, $self->{option_results}->{include_model}, $self->{option_results}->{exclude_model}, output => $self->{output}) || is_excluded($item->{IpAddress}, $self->{option_results}->{include_ip_address}, $self->{option_results}->{exclude_ip_address}, output => $self->{output}); @@ -120,17 +119,17 @@ Discover firewalls managed by Panorama. =over 8 -=item B<--only-connected> +=item B<--connected-only> Display only connected firewalls. -=item B<--include-name> +=item B<--include-serial> -Filter firewall by name (can be a regex). +Filter firewall by serial number (can be a regex). -=item B<--exclude-name> +=item B<--exclude-serial> -Exclude firewall by name (can be a regex). +Exclude firewall by serial number (can be a regex). =item B<--include-model> diff --git a/src/network/paloalto/api/mode/environment.pm b/src/network/paloalto/api/mode/environment.pm index 68e6538d7c..9193c74572 100644 --- a/src/network/paloalto/api/mode/environment.pm +++ b/src/network/paloalto/api/mode/environment.pm @@ -59,12 +59,9 @@ sub api_execute { $self->{data} = {}; # Process temperature data - if (defined($result->{thermal}->{Slot1}->{entry})) { - my $entries = $result->{thermal}->{Slot1}->{entry}; - $entries = [$entries] unless ref($entries) eq 'ARRAY'; - + if ($result->{thermal}->{Slot1}->{entry}) { my $temp_idx = 0; - foreach my $entry (@$entries) { + foreach my $entry (@{$result->{thermal}->{Slot1}->{entry}}) { $temp_idx++; my $instance = "thermal_slot" . ($entry->{slot} // 1) . "_index" . $temp_idx; $self->{data}->{temperatures}->{$instance} = { @@ -78,12 +75,9 @@ sub api_execute { } # Process fan data - if (defined($result->{fan}->{Slot1}->{entry})) { - my $entries = $result->{fan}->{Slot1}->{entry}; - $entries = [$entries] unless ref($entries) eq 'ARRAY'; - + if ($result->{fan}->{Slot1}->{entry}) { my $fan_idx = 0; - foreach my $entry (@$entries) { + foreach my $entry (@{$result->{fan}->{Slot1}->{entry}}) { $fan_idx++; my $instance = "fan_slot" . ($entry->{slot} // 1) . "_index" . $fan_idx; $self->{data}->{fans}->{$instance} = { @@ -96,12 +90,9 @@ sub api_execute { } # Process voltage (power) data - if (defined($result->{power}->{Slot1}->{entry})) { - my $entries = $result->{power}->{Slot1}->{entry}; - $entries = [$entries] unless ref($entries) eq 'ARRAY'; - + if ($result->{power}->{Slot1}->{entry}) { my $voltage_idx = 0; - foreach my $entry (@$entries) { + foreach my $entry (@{$result->{power}->{Slot1}->{entry}}) { $voltage_idx++; my $instance = "voltage_slot" . ($entry->{slot} // 1) . "_index" . $voltage_idx; $self->{data}->{voltages}->{$instance} = { @@ -115,12 +106,9 @@ sub api_execute { } # Process PSU (power supply) data - if (defined($result->{'power-supply'}->{Slot1}->{entry})) { - my $entries = $result->{'power-supply'}->{Slot1}->{entry}; - $entries = [$entries] unless ref($entries) eq 'ARRAY'; - + if ($result->{'power-supply'}->{Slot1}->{entry}) { my $psu_idx = 0; - foreach my $entry (@$entries) { + foreach my $entry (@{$result->{'power-supply'}->{Slot1}->{entry}}) { $psu_idx++; my $instance = "psu_slot" . ($entry->{slot} // 1) . "_index" . $psu_idx; $self->{data}->{psus}->{$instance} = { diff --git a/src/network/paloalto/api/mode/ha.pm b/src/network/paloalto/api/mode/ha.pm index c4182b7254..46f06e21cd 100644 --- a/src/network/paloalto/api/mode/ha.pm +++ b/src/network/paloalto/api/mode/ha.pm @@ -191,6 +191,9 @@ sub manage_selection { my $ha_mode = lc($group->{mode} // ''); my $platform_model = $local->{'platform-model'} // ''; + $self->{output}->option_exit(short_msg => "No matching device !") + unless $platform_model; + $self->{ha} = { platform_model => $platform_model, local_state => $local_state, diff --git a/src/network/paloalto/api/mode/health.pm b/src/network/paloalto/api/mode/health.pm new file mode 100644 index 0000000000..6834601e6a --- /dev/null +++ b/src/network/paloalto/api/mode/health.pm @@ -0,0 +1,642 @@ +# +# Copyright 2026-Present Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::paloalto::api::mode::health; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Time::Local qw(timelocal); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::constants qw(:counters :values); +use centreon::plugins::misc qw(is_empty is_excluded); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'include-device-serial:s' => { name => 'include_device_serial', default => '' }, + 'exclude-device-serial:s' => { name => 'exclude_device_serial', default => '' }, + 'include-device-hostname:s' => { name => 'include_device_hostname', default => '' }, + 'exclude-device-hostname:s' => { name => 'exclude_device_hostname', default => '' }, + 'include-plugin:s' => { name => 'include_plugin', default => '' }, + 'exclude-plugin:s' => { name => 'exclude_plugin', default => '' }, + 'include-template:s' => { name => 'include_template', default => '' }, + 'exclude-template:s' => { name => 'exclude_template', default => '' }, + 'connected-only' => { name => 'connected_only' } + }); + + return $self; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => COUNTER_TYPE_GLOBAL, prefix_output => 'Panorama ' }, + { name => 'devices', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_device_output', + message_multiple => 'All devices are ok' }, + { name => 'plugins', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_plugin_output', + message_multiple => 'All plugins are ok' }, + { name => 'device_groups', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_device_group_output', + message_multiple => 'All device groups are ok' }, + { name => 'templates', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_template_output', + message_multiple => 'All templates are ok' }, + { name => 'template_sync', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_template_sync_output', + message_multiple => 'All template assignments are synchronized' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'devices-total', nlabel => 'panorama.devices.total.count', set => { + key_values => [ { name => 'devices_total' } ], + output_template => 'total devices: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'devices-connected', nlabel => 'panorama.devices.connected.count', set => { + key_values => [ { name => 'devices_connected' } ], + output_template => 'connected devices: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'devices-out-of-sync', nlabel => 'panorama.devices.out_of_sync.count', set => { + key_values => [ { name => 'devices_out_of_sync' } ], + output_template => 'out of sync devices: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'device-groups-total', nlabel => 'panorama.device_groups.total.count', set => { + key_values => [ { name => 'device_groups_total' } ], + output_template => 'total device-groups: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'templates-total', nlabel => 'panorama.templates.total.count', set => { + key_values => [ { name => 'templates_total' } ], + output_template => 'total templates: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'template-assignments-total', nlabel => 'panorama.template_assignments.total.count', set => { + key_values => [ { name => 'template_assignments_total' } ], + output_template => 'template assignments: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'template-assignments-out-of-sync', nlabel => 'panorama.template_assignments.out_of_sync.count', set => { + key_values => [ { name => 'template_assignments_out_of_sync' } ], + output_template => 'template assignments out of sync: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + }, + { label => 'push-status', type => COUNTER_KIND_TEXT, + critical_default => '%{push_status} !~ /^(?:OK|success)$/i', + set => { + key_values => [ { name => 'push_status' } ], + output_template => 'last push status: %{push_status}', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'push-age', nlabel => 'panorama.push.age.seconds', + set => { + key_values => [ { name => 'push_age_seconds' } ], + output_template => 'last push age: %{push_age_seconds} seconds', + perfdatas => [ { template => '%s', unit => 's', min => 0 } ] + } + } + ]; + + $self->{maps_counters}->{devices} = [ + { label => 'device-connection-status', type => COUNTER_KIND_TEXT, + critical_default => '%{connected} ne "yes"', + set => { + key_values => [ { name => 'connected' }, { name => 'hostname' }, { name => 'serial' } ], + output_template => 'connected: %s', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'device-software-version', type => COUNTER_KIND_TEXT, display_ok => 0, + set => { + key_values => [ { name => 'sw_version' }, { name => 'hostname' }, { name => 'serial' } ], + output_template => 'software version: %s', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'device-ha-state', type => COUNTER_KIND_TEXT, display_ok => 0, + set => { + key_values => [ { name => 'ha_state' }, { name => 'hostname' }, { name => 'serial' } ], + output_template => 'HA state: %s', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{plugins} = [ + { label => 'plugin-status', type => COUNTER_KIND_TEXT, + critical_default => '%{status} !~ /success/i', + set => { + key_values => [ { name => 'status' }, { name => 'name' }, { name => 'version' } ], + output_template => 'status: %{status} (version: %{version})', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{device_groups} = [ + ]; + + $self->{maps_counters}->{templates} = [ + { label => 'template-devices-count', nlabel => 'template.devices.count', + set => { + key_values => [ { name => 'devices_count' }, { name => 'hostname' } ], + output_template => 'assigned devices: %s', + perfdatas => [ { template => '%s', min => 0 } ] + } + } + ]; + + $self->{maps_counters}->{template_sync} = [ + { label => 'template-sync-status', type => COUNTER_KIND_TEXT, + critical_default => '%{sync_status} ne "in-sync"', + set => { + key_values => [ { name => 'sync_status' }, { name => 'template_name' }, { name => 'device_serial' }, { name => 'vsys' } ], + output_template => 'template: %{template_name}, vsys: %{vsys}, status: %s', + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub prefix_device_output { + my ($self, %options) = @_; + return sprintf("device '%s' (%s) ", $options{instance_value}->{hostname}, $options{instance_value}->{serial}); +} + +sub prefix_plugin_output { + my ($self, %options) = @_; + return sprintf("plugin '%s' ", $options{instance_value}->{name}); +} + +sub prefix_device_group_output { + my ($self, %options) = @_; + return sprintf("device-group '%s' ", $options{instance_value}->{name}); +} + +sub prefix_template_output { + my ($self, %options) = @_; + return sprintf("template '%s' ", $options{instance_value}->{name}); +} + +sub prefix_template_sync_output { + my ($self, %options) = @_; + return sprintf("template-assignment '%s' ", $options{instance_value}->{device_serial}); +} + +sub _parse_panorama_timestamp { + my ($self, $timestamp) = @_; + + # Format: "2024/01/15 10:30:10" or similar + if ($timestamp && $timestamp =~ /(\d{4})\/(\d{2})\/(\d{2})\s+(\d{2}):(\d{2}):(\d{2})/) { + my ($year, $mon, $mday, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6); + return timelocal($sec, $min, $hour, $mday, $mon - 1, $year - 1900); + } + + return undef; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $custom = $options{custom}; + + $self->{global} = { + devices_total => 0, + devices_connected => 0, + devices_out_of_sync => 0, + device_groups_total => 0, + templates_total => 0, + template_assignments_total => 0, + template_assignments_out_of_sync => 0, + push_status => 'unknown', + push_age_seconds => -1 + }; + + $self->{devices} = {}; + $self->{plugins} = {}; + $self->{device_groups} = {}; + $self->{templates} = {}; + $self->{template_sync} = {}; + + # Get devices info + my $filter = $self->{option_results}->{connected_only} ? 'connected' : 'all'; + my $devices_result = $custom->request_api( + type => 'op', + cmd => "<$filter>", + ForceArray => [ 'entry' ] + ); + + my %devices_by_serial = (); + + if ($devices_result && $devices_result->{devices} && ref $devices_result->{devices}->{entry} eq 'ARRAY') { + foreach my $device (@{$devices_result->{devices}->{entry}}) { + my $serial = $device->{name}; + my $hostname = $device->{hostname} // ''; + + next if is_excluded($serial, $self->{option_results}->{include_device_serial}, $self->{option_results}->{exclude_device_serial}, output => $self->{output}) || + is_excluded($hostname, $self->{option_results}->{include_device_hostname}, $self->{option_results}->{exclude_device_hostname}, output => $self->{output}); + + my $connected = lc($device->{connected} // 'no'); + + # Determine sync status from vsys entries + my $sync_state = 'unknown'; + my %vsys_sync_states = (); + + if ($device->{vsys} && ref $device->{vsys}->{entry} eq 'ARRAY') { + foreach my $vsys_entry (@{$device->{vsys}->{entry}}) { + my $vsys_name = $vsys_entry->{name} // 'vsys1'; + my $vsys_status = $vsys_entry->{'shared-policy-status'} // 'unknown'; + $vsys_sync_states{$vsys_name} = $vsys_status; + + if ($vsys_status eq 'Out of Sync') { + $sync_state = 'Out of Sync'; + } elsif ($vsys_status eq 'In Sync' && $sync_state eq 'unknown') { + $sync_state = 'In Sync'; + } + } + } + + $self->{devices}->{$serial} = { + serial => $serial, + hostname => $hostname, + connected => $connected, + sync_state => $sync_state, + sw_version => $device->{'sw-version'} // 'unknown', + ha_state => $device->{ha}->{state} // 'unknown', + vsys_sync => \%vsys_sync_states + }; + + $devices_by_serial{$serial} = $self->{devices}->{$serial}; + + $self->{global}->{devices_total}++; + $self->{global}->{devices_connected}++ if $connected eq 'yes'; + $self->{global}->{devices_out_of_sync}++ if $sync_state eq 'Out of Sync'; + } + } + + # Get plugins info + my $plugins_result = $custom->request_api( + type => 'op', + cmd => '', + ForceArray => ['entry'] + ); + + if ($plugins_result && $plugins_result->{plugins} && ref $plugins_result->{plugins}->{entry} eq 'ARRAY') { + foreach my $plugin (@{$plugins_result->{plugins}->{entry}}) { + my $plugin_name = $plugin->{name} // ''; + next if is_excluded($plugin_name, $self->{option_results}->{include_plugin}, $self->{option_results}->{exclude_plugin}, output => $self->{output}); + + $self->{plugins}->{$plugin_name} = { + name => $plugin_name, + version => $plugin->{version} // 'unknown', + status => $plugin->{status} // 'unknown' + }; + } + } + + # Get templates info with assigned devices + my $templates_result = $custom->request_api( + type => 'config', + action => 'get', + xpath => "/config/devices/entry//template", + ForceArray => [ 'entry' ] + ); + + if ($templates_result && $templates_result->{template} && ref $templates_result->{template}->{entry} eq 'ARRAY') { + foreach my $template (@{$templates_result->{template}->{entry}}) { + my $template_name = $template->{name} // ''; + next if is_excluded($template_name, $self->{option_results}->{include_template}, $self->{option_results}->{exclude_template}, output => $self->{output}); + + my @assigned_devices = @{$template->{devices}->{entry} // []}; + my $devices_count = scalar(@assigned_devices); + + my $template_instance = $template_name; + $self->{templates}->{$template_instance} = { + name => $template_name, + devices_count => $devices_count, + description => $template->{description} // '' + }; + + $self->{global}->{templates_total}++; + + # Build template sync status entries + foreach my $assigned_device (@assigned_devices) { + my $device_serial = $assigned_device->{name} // ''; + next unless $device_serial; + + $self->{global}->{template_assignments_total}++; + + # Get device details if available + if (exists $devices_by_serial{$device_serial}) { + my $device_info = $devices_by_serial{$device_serial}; + my $vsys_sync_states = $device_info->{vsys_sync}; + + # Create entry for each vsys with sync status + foreach my $vsys_name (keys %{$vsys_sync_states}) { + my $sync_status = $vsys_sync_states->{$vsys_name} // 'unknown'; + my $entry_key = "$template_name-$device_serial-$vsys_name"; + + $self->{template_sync}->{$entry_key} = { + template_name => $template_name, + device_serial => $device_serial, + device_name => $device_info->{name}, + vsys => $vsys_name, + sync_status => lc($sync_status), + connected => $device_info->{connected} + }; + + if ($sync_status ne 'In Sync' && $sync_status ne 'unknown') { + $self->{global}->{template_assignments_out_of_sync}++; + } + } + } else { + # Device not found in devices list + my $entry_key = "$template_name-$device_serial-unknown"; + $self->{template_sync}->{$entry_key} = { + template_name => $template_name, + device_serial => $device_serial, + device_name => $device_serial, + vsys => 'unknown', + sync_status => 'disconnected', + connected => 'no' + }; + $self->{global}->{template_assignments_out_of_sync}++; + } + } + } + } + + # Get jobs info (push history) + my $jobs_result = $custom->request_api( + type => 'op', + cmd => '', + ForceArray => ['job'] + ); + + my $last_push = undef; + my $now = time(); + + if ($jobs_result && ref $jobs_result->{job} eq 'ARRAY') { + foreach my $job (@{$jobs_result->{job}}) { + next unless $job->{type} && $job->{type} =~ /^(?:CommitAll|Push)/i; + + my $result = $job->{result} // 'unknown'; + my $tfin = $job->{tfin} // $job->{tdeq}; + + # Keep only the most recent push job + if ($last_push) { + my $epoch = $self->_parse_panorama_timestamp($tfin); + if ($epoch && $last_push->{timestamp_epoch} && $epoch > $last_push->{timestamp_epoch}) { + my $age_seconds = ($now - $epoch); + $last_push = { + status => $result, + timestamp => $tfin, + timestamp_epoch => $epoch, + age_seconds => $age_seconds + }; + } + } else { + my $epoch = $self->_parse_panorama_timestamp($tfin); + my $age_seconds = $epoch ? ($now - $epoch) : -1; + $last_push = { + status => $result, + timestamp => $tfin, + timestamp_epoch => $epoch, + age_seconds => $age_seconds + }; + } + } + } + + # Add last push info if available + if ($last_push) { + $self->{global}->{push_status} = $last_push->{status}; + $self->{global}->{push_age_seconds} = $last_push->{age_seconds} || 0; + } +} + +1; + +__END__ + +=head1 MODE + +Check Palo Alto Panorama health status including managed devices, templates, template synchronization, and push operations. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^devices-total$' + +=item B<--include-device-serial> + +Include specific device by serial number (can be a regexp). + +=item B<--exclude-device-serial> + +Exclude specific device by serial number (can be a regexp). + +=item B<--include-device-hostname> + +Include specific device by hostname (can be a regexp). + +=item B<--exclude-device-hostname> + +Exclude specific device by hostname (can be a regexp). + +=item B<--include-plugin> + +Include specific plugin (can be a regexp). + +=item B<--exclude-plugin> + +Exclude specific plugin (can be a regexp). + +=item B<--include-template> + +Include specific template (can be a regexp). + +=item B<--exclude-template> + +Exclude specific template (can be a regexp). + +=item B<--unknown-device-connection-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{connected}, %{hostname}, %{serial} + +=item B<--warning-device-connection-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{connected}, %{hostname}, %{serial} + +=item B<--critical-device-connection-status> + +Define the conditions to match for the status to be CRITICAL (default: '%{connected} ne "yes"'). +You can use the following variables: %{connected}, %{hostname}, %{serial} + +=item B<--unknown-device-software-version> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{sw_version}, %{hostname}, %{serial} + +=item B<--warning-device-software-version> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{sw_version}, %{hostname}, %{serial} + +=item B<--critical-device-software-version> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{sw_version}, %{hostname}, %{serial} + +=item B<--unknown-device-ha-state> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{ha_state}, %{hostname}, %{serial} + +=item B<--warning-device-ha-state> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{ha_state}, %{hostname}, %{serial} + +=item B<--critical-device-ha-state> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{ha_state}, %{hostname}, %{serial} + +=item B<--unknown-plugin-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{status}, %{hostname}, %{version} + +=item B<--warning-plugin-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{status}, %{hostname}, %{version} + +=item B<--critical-plugin-status> + +Define the conditions to match for the status to be CRITICAL (default: '%{status} !~ /success/i'). +You can use the following variables: %{status}, %{hostname}, %{version} + +=item B<--unknown-push-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{push_status} + +=item B<--warning-push-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{push_status} + +=item B<--critical-push-status> + +Define the conditions to match for the status to be CRITICAL (default: '%{push_status} !~ /^(?:OK|success)$/i'). +You can use the following variables: %{push_status} + +=item B<--warning-push-age> + +Warning threshold for last push age (in seconds). + +=item B<--critical-push-age> + +Critical threshold for last push age (in seconds). + +=item B<--unknown-template-sync-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{sync_status}, %{template_name}, %{device_serial}, %{vsys} + +=item B<--warning-template-sync-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{sync_status}, %{template_name}, %{device_serial}, %{vsys} + +=item B<--critical-template-sync-status> + +Define the conditions to match for the status to be CRITICAL (default: '%{sync_status} ne "in-sync"'). +You can use the following variables: %{sync_status}, %{template_name}, %{device_serial}, %{vsys} + +=item B<--warning-devices-total> + +Warning threshold for total number of managed devices. + +=item B<--critical-devices-total> + +Critical threshold for total number of managed devices. + +=item B<--warning-devices-connected> + +Warning threshold for number of connected devices. + +=item B<--critical-devices-connected> + +Critical threshold for number of connected devices. + +=item B<--warning-devices-out-of-sync> + +Warning threshold for number of out-of-sync devices. + +=item B<--critical-devices-out-of-sync> + +Critical threshold for number of out-of-sync devices. + +=item B<--warning-templates-total> + +Warning threshold for total number of templates. + +=item B<--critical-templates-total> + +Critical threshold for total number of templates. + +=item B<--warning-template-assignments-total> + +Warning threshold for total number of template assignments. + +=item B<--critical-template-assignments-total> + +Critical threshold for total number of template assignments. + +=item B<--warning-template-assignments-out-of-sync> + +Warning threshold for number of out-of-sync template assignments. + +=item B<--critical-template-assignments-out-of-sync> + +Critical threshold for number of out-of-sync template assignments. + +=back + +=cut diff --git a/src/network/paloalto/api/mode/ipsec.pm b/src/network/paloalto/api/mode/ipsec.pm index f12d1d2f00..66d991baac 100644 --- a/src/network/paloalto/api/mode/ipsec.pm +++ b/src/network/paloalto/api/mode/ipsec.pm @@ -32,16 +32,11 @@ sub prefix_tunnel_output { return sprintf("tunnel '%s' ", $options{instance_value}->{name}); } -sub prefix_global_output { - my ($self, %options) = @_; - return 'Tunnels '; -} - sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, cb_prefix_output => 'prefix_global_output' }, + { name => 'global', type => COUNTER_TYPE_GLOBAL, prefix_output => 'Tunnels ' }, { name => 'tunnels', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_tunnel_output', message_multiple => 'All tunnels are ok' } ]; @@ -118,14 +113,15 @@ sub manage_selection { $self->{tunnels} = {}; $self->{global} = { tunnels_count => 0 }; - return unless ref $result->{entries} eq 'HASH'; + $self->{output}->option_exit(short_msg => "No matching device !") + unless ref $result->{entries} eq 'HASH'; foreach my $entry (@{$result->{entries}->{entry}}) { my $name = $entry->{name} // ''; my $gateway = $entry->{gateway} // ''; - next if is_excluded($name, $self->{option_results}->{include_tunnel_name}, $self->{option_results}->{exclude_tunnel_name}); - next if is_excluded($gateway, $self->{option_results}->{include_gateway_name}, $self->{option_results}->{exclude_gateway_name}); + next if is_excluded($name, $self->{option_results}->{include_tunnel_name}, $self->{option_results}->{exclude_tunnel_name}, output => $self->{output}) || + is_excluded($gateway, $self->{option_results}->{include_gateway_name}, $self->{option_results}->{exclude_gateway_name}, output => $self->{output}); $self->{tunnels}->{$name} = { name => $name, diff --git a/src/network/paloalto/api/mode/licenses.pm b/src/network/paloalto/api/mode/licenses.pm index d9c4f46902..862246a828 100644 --- a/src/network/paloalto/api/mode/licenses.pm +++ b/src/network/paloalto/api/mode/licenses.pm @@ -27,7 +27,6 @@ use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); use centreon::plugins::constants qw(:counters); use centreon::plugins::misc qw(is_excluded); -use DateTime; use DateTime::Format::Strptime; sub custom_expiration_output { @@ -42,16 +41,11 @@ sub prefix_license_output { return sprintf("license '%s' ", $options{instance_value}->{feature}); } -sub prefix_global_output { - my ($self, %options) = @_; - return 'Licenses '; -} - sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, cb_prefix_output => 'prefix_global_output' }, + { name => 'global', type => COUNTER_TYPE_GLOBAL, prefix_output => 'Licenses ' }, { name => 'licenses', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_license_output', message_multiple => 'All licenses are ok' } ]; @@ -130,7 +124,7 @@ sub manage_selection { foreach my $entry (@{$result->{licenses}->{entry}}) { my $feature = $entry->{feature} // ''; - next if is_excluded($feature, $self->{option_results}->{include_license_name}, $self->{option_results}->{exclude_license_name}); + next if is_excluded($feature, $self->{option_results}->{include_license_name}, $self->{option_results}->{exclude_license_name}, output => $self->{output}); my $days_left = -1; my $expires = $entry->{expires}; @@ -173,17 +167,17 @@ Exclude license names (regexp). =item B<--unknown-status> Define the conditions to match for the status to be UNKNOWN. -You can use the following variables: %{expired} +You can use the following variables: %{expired} %{feature} =item B<--warning-status> Define the conditions to match for the status to be WARNING. -You can use the following variables: %{expired} +You can use the following variables: %{expired} %{feature} =item B<--critical-status> Define the conditions to match for the status to be CRITICAL (default: '%{expired} =~ /yes/'). -You can use the following variables: %{expired} +You can use the following variables: %{expired} %{feature} =item B<--warning-expiration-days> diff --git a/src/network/paloalto/api/mode/system.pm b/src/network/paloalto/api/mode/system.pm index 695b286575..2fb30c3e52 100644 --- a/src/network/paloalto/api/mode/system.pm +++ b/src/network/paloalto/api/mode/system.pm @@ -25,18 +25,14 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); -use centreon::plugins::constants qw(:counters); - -sub prefix_global_output { - my ($self, %options) = @_; - return 'System '; -} +use centreon::plugins::constants qw(:counters :unit_conversion); +use centreon::plugins::misc qw/convert_bytes/; sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, cb_prefix_output => 'prefix_global_output' } + { name => 'global', type => COUNTER_TYPE_GLOBAL, prefix_output => 'System ' } ]; $self->{maps_counters}->{global} = [ @@ -71,7 +67,7 @@ sub set_counters { } }, { - label => 'software-version', + label => 'software-version', display_ok => 0, type => COUNTER_KIND_TEXT, set => { key_values => [ { name => 'sw_version' } ], @@ -80,14 +76,41 @@ sub set_counters { } }, { - label => 'wildfire-mode', + label => 'wildfire-mode', display_ok => 0, type => COUNTER_KIND_TEXT, set => { key_values => [ { name => 'wildfire_mode' } ], output_template => 'WildFire mode: %s', closure_custom_threshold_check => \&catalog_status_threshold_ng } + }, + { label => 'packet-rate', nlabel => 'system.sessions.packet.rate.persecond', set => { + key_values => [ { name => 'packet_rate' } ], + output_template => 'packet rate: %s p/s', + perfdatas => [ + { template => '%s', unit => 'p/s', min => 0 } + ] + } + }, + + { label => 'sessions-traffic', nlabel => 'system.sessions.throughput.bitspersecond', set => { + key_values => [ { name => 'throughput' } ], + output_template => 'throughput: %s %s/s', + output_change_bytes => CONVERT_NETWORK, + perfdatas => [ + { template => '%s', unit => 'b/s', min => 0 } + ] + } + }, + { label => 'active-sessions', nlabel => 'system.sessions.total.count', set => { + key_values => [ { name => 'active_sessions' } ], + output_template => 'total active sessions: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } } + ]; } @@ -112,15 +135,20 @@ sub manage_selection { cert_status => 'Unknown', operational_mode => 'Unknown', sw_version => 'Unknown', - wildfire_mode => 'Unknown' + wildfire_mode => 'Unknown', + packet_rate => 0, + throughput => 0, + active_sessions => 0 }; - return unless defined($result->{system}); + $self->{output}->option_exit(short_msg => "No matching device !") + unless ref $result->{system} eq 'HASH'; my $system = $result->{system}; # Parse uptime: "X days, HH:MM:SS" format - if (defined($system->{uptime})) { + # 0 days, 0:13:44 + if ($system->{uptime}) { my $uptime_str = $system->{uptime}; my $uptime_seconds = 0; @@ -146,6 +174,22 @@ sub manage_selection { $self->{global}->{wildfire_mode} = $system->{'wildfire-rt'} if $system->{'wildfire-rt'}; + + $result = $options{custom}->request_api( + type => 'op', + cmd => '' + ); + + return unless ref $result eq 'HASH'; + + $self->{global}->{packet_rate} = $result->{pps} + if exists $result->{pps}; + + $self->{global}->{throughput} = convert_bytes(value => $result->{kbps}, unit => 'kb', network => 1) + if exists $result->{kbps}; + + $self->{global}->{active_sessions} = $result->{'num-active'} + if exists $result->{'num-active'}; } 1; @@ -158,6 +202,11 @@ Check Palo Alto system information and status. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^uptime$' + =item B<--warning-uptime> Warning threshold for uptime in seconds. @@ -181,35 +230,74 @@ You can use the following variables: %{cert_status} Define the conditions to match for the status to be CRITICAL (default: '%{cert_status} !~ /Valid/i'). You can use the following variables: %{cert_status} -=back +=item B<--unknown-operational-mode> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{operational_mode} -=head1 AVAILABLE COUNTERS +=item B<--warning-operational-mode> -=over 8 +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{operational_mode} + +=item B<--critical-operational-mode> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{operational_mode} + +=item B<--unknown-software-version> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{sw_version} + +=item B<--warning-software-version> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{sw_version} + +=item B<--critical-software-version> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{sw_version} + +=item B<--unknown-wildfire-mode> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{wildfire_mode} + +=item B<--warning-wildfire-mode> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{wildfire_mode} + +=item B<--critical-wildfire-mode> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{wildfire_mode} -=item B +=item B<--warning-active-sessions> -Total number of active system counters. +Threshold. -=item B +=item B<--critical-active-sessions> -System uptime in seconds. +Threshold. -=item B +=item B<--warning-packet-rate> -Device certificate status (Valid/Invalid/etc). +Threshold in p/s. -=item B +=item B<--critical-packet-rate> -Current operational mode (normal/maintenance/etc). +Threshold in p/s. -=item B +=item B<--warning-sessions-traffic> -Software version string. +Threshold in b/s. -=item B +=item B<--critical-sessions-traffic> -WildFire mode status (Enabled/Disabled). +Threshold in b/s. =back diff --git a/src/network/paloalto/api/plugin.pm b/src/network/paloalto/api/plugin.pm index 1ad2b9d416..04b664ffd4 100644 --- a/src/network/paloalto/api/plugin.pm +++ b/src/network/paloalto/api/plugin.pm @@ -36,7 +36,9 @@ sub new { 'licenses' => 'network::paloalto::api::mode::licenses', 'system' => 'network::paloalto::api::mode::system', 'ipsec' => 'network::paloalto::api::mode::ipsec', - 'panorama-firewall-discovery' => 'network::paloalto::api::mode::panoramafirewalldiscovery' + 'discovery' => 'network::paloalto::api::mode::discovery', + 'health' => 'network::paloalto::api::mode::health', + 'certificate' => 'network::paloalto::api::mode::certificate' }; $self->{custom_modes}->{api} = 'network::paloalto::api::custom::api'; diff --git a/tests/network/paloalto/api/authent.robot b/tests/network/paloalto/api/authent.robot index e28f5d9240..44355cc529 100644 --- a/tests/network/paloalto/api/authent.robot +++ b/tests/network/paloalto/api/authent.robot @@ -17,10 +17,11 @@ ${CMD} ${CENTREON_PLUGINS} ... --hostname=${HOSTNAME} ... --port=${APIPORT} ... --proto=http -... --mode=system +... --mode=system + *** Test Cases *** -paloalto-environment ${tc} +authent ${tc} [Tags] network paloalto api environment ${command} Catenate ... ${CMD} @@ -28,9 +29,23 @@ paloalto-environment ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} UNKNOWN: With --auth-type=api-key: specify --api-key or --username/--password to auto-generate it. - ... 2 --auth-type=api-key UNKNOWN: With --auth-type=api-key: specify --api-key or --username/--password to auto-generate it. - ... 3 --auth-type=api-key --username=AA --password=BB OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, software version: 10.1.12, WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; - ... 4 --auth-type=basic UNKNOWN: Need to specify --username/--password options with --auth-type=basic. - ... 5 --auth-type=basic --username=AA --password=BB OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, software version: 10.1.12, WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... UNKNOWN: With --auth-type=api-key: specify --api-key or --username/--password to auto-generate it. + ... 2 + ... --auth-type=api-key + ... UNKNOWN: With --auth-type=api-key: specify --api-key or --username/--password to auto-generate it. + ... 3 + ... --auth-type=api-key --username=AA --password=BB + ... OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, packet rate: 0 p/s, throughput: 0.00 b/s, total active sessions: 0 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; + ... 4 + ... --auth-type=basic + ... UNKNOWN: Need to specify --username/--password options with --auth-type=basic. + ... 5 + ... --auth-type=basic --username=AA --password=BB + ... OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, packet rate: 0 p/s, throughput: 0.00 b/s, total active sessions: 0 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; diff --git a/tests/network/paloalto/api/certificate.robot b/tests/network/paloalto/api/certificate.robot new file mode 100644 index 0000000000..04a8faff40 --- /dev/null +++ b/tests/network/paloalto/api/certificate.robot @@ -0,0 +1,97 @@ +*** Settings *** +Documentation network::paloalto::api::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${INJECT_PERL} -Mfixed_date -I${CURDIR} +${MOCKOON_JSON} ${CURDIR}${/}mockoon-paloalto-api.json +${HOSTNAME} 127.0.0.1 +${APIPORT} 3000 +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::paloalto::api::plugin +... --mode=certificate +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --auth-type=api-key +... --api-key=D@pAs$W@rD + + +*** Test Cases *** +Certificate ${tc} + [Tags] network paloalto api + + ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default= + Set Environment Variable PERL5OPT ${INJECT_PERL} ${OLD_PERL5OPT} + + ${command}= Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 2 + ... --filter-counters=certificate + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 3 + ... --include-device-serial=LON + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -10 days | 'device.certificate.expiry.days'=-10d;;;0; + ... 4 + ... --exclude-device-serial=TOK + ... OK: All device certificates are OK | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; + ... 5 + ... --include-device-hostname='london' + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -10 days | 'device.certificate.expiry.days'=-10d;;;0; + ... 6 + ... --exclude-device-hostname='fw-tokyo.example.com' + ... OK: All device certificates are OK | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; + ... 7 + ... --connected-only=1 + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 8 + ... --unknown-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= + ... UNKNOWN: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 9 + ... --warning-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= + ... WARNING: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 10 + ... --critical-certificate-status="\\\%{cert_status} ne ''" + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid - Device 'fw-nyc.example.com' (FW-NYC) certificate status: Valid - Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 11 + ... --unknown-certificate-subject=1 --critical-certificate-status= + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 12 + ... --warning-certificate-subject=1 --critical-certificate-status= + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 13 + ... --critical-certificate-subject=1 --critical-certificate-status= + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 14 + ... --warning-certificate-expiry=1 --critical-certificate-status= + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) expires in: -10 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 14 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -22 days | 'device.certificate.expiry.days'=-10d;0:1;;0; 'device.certificate.expiry.days'=14d;0:1;;0; 'device.certificate.expiry.days'=-22d;0:1;;0; + ... 15 + ... --critical-certificate-expiry=1 --critical-certificate-status= + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) expires in: -10 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 14 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -22 days | 'device.certificate.expiry.days'=-10d;;0:1;0; 'device.certificate.expiry.days'=14d;;0:1;0; 'device.certificate.expiry.days'=-22d;;0:1;0; + ... 16 + ... --unknown-certificate-custom-usage=1 --critical-certificate-status= + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 17 + ... --warning-certificate-custom-usage=1 --critical-certificate-status= + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... 18 + ... --critical-certificate-custom-usage=1 --critical-certificate-status= + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; diff --git a/tests/network/paloalto/api/discovery.robot b/tests/network/paloalto/api/discovery.robot new file mode 100644 index 0000000000..e001db2b03 --- /dev/null +++ b/tests/network/paloalto/api/discovery.robot @@ -0,0 +1,54 @@ +*** Settings *** +Documentation Discover firewalls managed by Panorama. + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}mockoon-paloalto-api.json +${HOSTNAME} 127.0.0.1 +${APIPORT} 3000 +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::paloalto::api::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --mode=discovery + + +*** Test Cases *** +discovery ${tc} + [Tags] network paloalto api system + + ${command} Catenate + ... ${CMD} + ... --auth-type=api-key + ... --api-key=D@pAs$W@rD + ... ${extra_options} + + Ctn Run Command And Check Result As Json ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... {"discovered_items":3,"duration":0,"end_time":1779952768,"results":[{"Connected":"yes","HostName":"fw-nyc.example.com","IpAddress":"192.168.1.1","Model":"PA-850","Serial":"FW-NYC"},{"Connected":"yes","HostName":"fw-london.example.com","IpAddress":"192.168.1.2","Model":"PA-850","Serial":"FW-LONDON"},{"Connected":"no","HostName":"fw-tokyo.example.com","IpAddress":"192.168.1.3","Model":"PA-VM","Serial":"FW-TOKYO"}],"start_time":1779952768} + ... 2 + ... --include-model=PA-VM + ... {"discovered_items":1,"duration":0,"end_time":1779952789,"results":[{"Connected":"no","HostName":"fw-tokyo.example.com","IpAddress":"192.168.1.3","Model":"PA-VM","Serial":"FW-TOKYO"}],"start_time":1779952789} + ... 3 + ... --exclude-model=PA-VM + ... {"discovered_items":2,"duration":0,"end_time":1779952792,"results":[{"Connected":"yes","HostName":"fw-nyc.example.com","IpAddress":"192.168.1.1","Model":"PA-850","Serial":"FW-NYC"},{"Connected":"yes","HostName":"fw-london.example.com","IpAddress":"192.168.1.2","Model":"PA-850","Serial":"FW-LONDON"}],"start_time":1779952792} + ... 4 + ... --include-ip-address=192.168.1.2 + ... {"discovered_items":1,"duration":0,"end_time":1779952818,"results":[{"Connected":"yes","HostName":"fw-london.example.com","IpAddress":"192.168.1.2","Model":"PA-850","Serial":"FW-LONDON"}],"start_time":1779952818} + ... 5 + ... --exclude-ip-address=192.168.1.2 + ... {"discovered_items":2,"duration":0,"end_time":1779952822,"results":[{"Connected":"yes","HostName":"fw-nyc.example.com","IpAddress":"192.168.1.1","Model":"PA-850","Serial":"FW-NYC"},{"Connected":"no","HostName":"fw-tokyo.example.com","IpAddress":"192.168.1.3","Model":"PA-VM","Serial":"FW-TOKYO"}],"start_time":1779952822} diff --git a/tests/network/paloalto/api/environment.robot b/tests/network/paloalto/api/environment.robot index 18ad755f20..19880f934e 100644 --- a/tests/network/paloalto/api/environment.robot +++ b/tests/network/paloalto/api/environment.robot @@ -19,6 +19,7 @@ ${CMD} ${CENTREON_PLUGINS} ... --proto=http ... --mode=environment + *** Test Cases *** paloalto-environment ${tc} [Tags] network paloalto api environment @@ -30,19 +31,53 @@ paloalto-environment ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} OK: All 20 components are ok [3/3 fans, 2/2 power supplies, 5/5 temperatures, 10/10 voltages]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;;2500; '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.fan.count'=3;;;; 'hardware.psu.count'=2;;;; 'hardware.temperature.count'=5;;;; 'hardware.voltage.count'=10;;;; - ... 2 --component=fan OK: All 3 components are ok [3/3 fans]. | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;;2500; 'hardware.fan.count'=3;;;; - ... 3 --component=fan --filter='fan,Fan #2 RPM' --filter='fan,Fan #3 RPM' OK: All 1 components are ok [1/1 fans]. | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'hardware.fan.count'=1;;;; - ... 4 --component=fan --warning='fan,.*,9100' WARNING: Fan 'Fan #1 RPM' rpm is 9157 - Fan 'Fan #2 RPM' rpm is 9557 - Fan 'Fan #3 RPM' rpm is 9418 | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;0:9100;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;0:9100;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;0:9100;;2500; 'hardware.fan.count'=3;;;; - ... 5 --component=fan --critical='fan,.*,9100' CRITICAL: Fan 'Fan #1 RPM' rpm is 9157 - Fan 'Fan #2 RPM' rpm is 9557 - Fan 'Fan #3 RPM' rpm is 9418 | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;0:9100;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;0:9100;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;0:9100;2500; 'hardware.fan.count'=3;;;; - ... 6 --component=psu OK: All 2 components are ok [2/2 power supplies]. | 'hardware.psu.count'=2;;;; - ... 7 --component=psu --filter='psu,Supply #2' OK: All 1 components are ok [1/1 power supplies]. | 'hardware.psu.count'=1;;;; - ... 8 --component=voltage OK: All 10 components are ok [10/10 voltages]. | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.voltage.count'=10;;;; - ... 9 --component=voltage --filter='voltage,0' OK: All 6 components are ok [6/6 voltages]. | '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.voltage.count'=6;;;; - ... 10 --component=temperature OK: All 5 components are ok [5/5 temperatures]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'hardware.temperature.count'=5;;;; - ... 11 --component=temperature --filter='temperature,Management' OK: All 4 components are ok [4/4 temperatures]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'hardware.temperature.count'=4;;;; - ... 12 --component=temperature --warning='temperature,.*,45' WARNING: Temperature 'Temperature near Cavium (outlet)' value is 51.6 C - Temperature 'Temperature @ Cavium Core' value is 53.175 C | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;0:45;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;0:45;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;0:45;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;0:45;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;0:45;;0.0;85.0 'hardware.temperature.count'=5;;;; - ... 13 --component=temperature --critical='temperature,.*,45' CRITICAL: Temperature 'Temperature near Cavium (outlet)' value is 51.6 C - Temperature 'Temperature @ Cavium Core' value is 53.175 C | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;0:45;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;0:45;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;0:45;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;0:45;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;0:45;0.0;85.0 'hardware.temperature.count'=5;;;; - ... 14 --component=voltage --warning='voltage,.*,0' WARNING: Voltage '0.85V Power Rail' value is 0.860666666667 V - Voltage '3.3V SD Power Rail' value is 3.332 V - Voltage '0.9V Power Rail' value is 0.904 V - Voltage '1.0V Power Rail' value is 1.006 V - Voltage '1.1V Power Rail' value is 1.09466666667 V - Voltage '1.2V Power Rail' value is 1.224 V - Voltage '1.5V Power Rail' value is 1.51066666667 V - Voltage '1.8V Power Rail' value is 1.812 V - Voltage '2.5V Power Rail' value is 2.504 V - Voltage '3.3V Power Rail' value is 3.332 V | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;0:0;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;0:0;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;0:0;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;0:0;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;0:0;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;0:0;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;0:0;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;0:0;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;0:0;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;0:0;;2.97;3.63 'hardware.voltage.count'=10;;;; - ... 15 --component=voltage --critical='voltage,.*,0' CRITICAL: Voltage '0.85V Power Rail' value is 0.860666666667 V - Voltage '3.3V SD Power Rail' value is 3.332 V - Voltage '0.9V Power Rail' value is 0.904 V - Voltage '1.0V Power Rail' value is 1.006 V - Voltage '1.1V Power Rail' value is 1.09466666667 V - Voltage '1.2V Power Rail' value is 1.224 V - Voltage '1.5V Power Rail' value is 1.51066666667 V - Voltage '1.8V Power Rail' value is 1.812 V - Voltage '2.5V Power Rail' value is 2.504 V - Voltage '3.3V Power Rail' value is 3.332 V | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;0:0;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;0:0;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;0:0;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;0:0;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;0:0;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;0:0;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;0:0;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;0:0;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;0:0;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;0:0;2.97;3.63 'hardware.voltage.count'=10;;;; + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: All 20 components are ok [3/3 fans, 2/2 power supplies, 5/5 temperatures, 10/10 voltages]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;;2500; '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.fan.count'=3;;;; 'hardware.psu.count'=2;;;; 'hardware.temperature.count'=5;;;; 'hardware.voltage.count'=10;;;; + ... 2 + ... --component=fan + ... OK: All 3 components are ok [3/3 fans]. | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;;2500; 'hardware.fan.count'=3;;;; + ... 3 + ... --component=fan --filter='fan,Fan #2 RPM' --filter='fan,Fan #3 RPM' + ... OK: All 1 components are ok [1/1 fans]. | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;;2500; 'hardware.fan.count'=1;;;; + ... 4 + ... --component=fan --warning='fan,.*,9100' + ... WARNING: Fan 'Fan #1 RPM' rpm is 9157 - Fan 'Fan #2 RPM' rpm is 9557 - Fan 'Fan #3 RPM' rpm is 9418 | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;0:9100;;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;0:9100;;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;0:9100;;2500; 'hardware.fan.count'=3;;;; + ... 5 + ... --component=fan --critical='fan,.*,9100' + ... CRITICAL: Fan 'Fan #1 RPM' rpm is 9157 - Fan 'Fan #2 RPM' rpm is 9557 - Fan 'Fan #3 RPM' rpm is 9418 | 'Fan #1 RPM#hardware.fan.speed.rpm'=9157rpm;;0:9100;2500; 'Fan #2 RPM#hardware.fan.speed.rpm'=9557rpm;;0:9100;2500; 'Fan #3 RPM#hardware.fan.speed.rpm'=9418rpm;;0:9100;2500; 'hardware.fan.count'=3;;;; + ... 6 + ... --component=psu + ... OK: All 2 components are ok [2/2 power supplies]. | 'hardware.psu.count'=2;;;; + ... 7 + ... --component=psu --filter='psu,Supply #2' + ... OK: All 1 components are ok [1/1 power supplies]. | 'hardware.psu.count'=1;;;; + ... 8 + ... --component=voltage + ... OK: All 10 components are ok [10/10 voltages]. | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.voltage.count'=10;;;; + ... 9 + ... --component=voltage --filter='voltage,0' + ... OK: All 6 components are ok [6/6 voltages]. | '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;;2.97;3.63 'hardware.voltage.count'=6;;;; + ... 10 + ... --component=temperature + ... OK: All 5 components are ok [5/5 temperatures]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'hardware.temperature.count'=5;;;; + ... 11 + ... --component=temperature --filter='temperature,Management' + ... OK: All 4 components are ok [4/4 temperatures]. | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;;0.0;85.0 'hardware.temperature.count'=4;;;; + ... 12 + ... --component=temperature --warning='temperature,.*,45' + ... WARNING: Temperature 'Temperature near Cavium (outlet)' value is 51.6 C - Temperature 'Temperature @ Cavium Core' value is 53.175 C | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;0:45;;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;0:45;;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;0:45;;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;0:45;;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;0:45;;0.0;85.0 'hardware.temperature.count'=5;;;; + ... 13 + ... --component=temperature --critical='temperature,.*,45' + ... CRITICAL: Temperature 'Temperature near Cavium (outlet)' value is 51.6 C - Temperature 'Temperature @ Cavium Core' value is 53.175 C | 'Temperature near CPLD (inlet)#hardware.temperature.celsius'=40.9C;;0:45;0.0;60.0 'Temperature near Cavium (outlet)#hardware.temperature.celsius'=51.6C;;0:45;0.0;60.0 'Temperature near Management Port (inlet)#hardware.temperature.celsius'=38.0C;;0:45;0.0;60.0 'Temperature near Switch (midboard)#hardware.temperature.celsius'=45.0C;;0:45;0.0;60.0 'Temperature @ Cavium Core#hardware.temperature.celsius'=53.175C;;0:45;0.0;85.0 'hardware.temperature.count'=5;;;; + ... 14 + ... --component=voltage --warning='voltage,.*,0' + ... WARNING: Voltage '0.85V Power Rail' value is 0.860666666667 V - Voltage '3.3V SD Power Rail' value is 3.332 V - Voltage '0.9V Power Rail' value is 0.904 V - Voltage '1.0V Power Rail' value is 1.006 V - Voltage '1.1V Power Rail' value is 1.09466666667 V - Voltage '1.2V Power Rail' value is 1.224 V - Voltage '1.5V Power Rail' value is 1.51066666667 V - Voltage '1.8V Power Rail' value is 1.812 V - Voltage '2.5V Power Rail' value is 2.504 V - Voltage '3.3V Power Rail' value is 3.332 V | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;0:0;;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;0:0;;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;0:0;;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;0:0;;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;0:0;;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;0:0;;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;0:0;;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;0:0;;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;0:0;;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;0:0;;2.97;3.63 'hardware.voltage.count'=10;;;; + ... 15 + ... --component=voltage --critical='voltage,.*,0' + ... CRITICAL: Voltage '0.85V Power Rail' value is 0.860666666667 V - Voltage '3.3V SD Power Rail' value is 3.332 V - Voltage '0.9V Power Rail' value is 0.904 V - Voltage '1.0V Power Rail' value is 1.006 V - Voltage '1.1V Power Rail' value is 1.09466666667 V - Voltage '1.2V Power Rail' value is 1.224 V - Voltage '1.5V Power Rail' value is 1.51066666667 V - Voltage '1.8V Power Rail' value is 1.812 V - Voltage '2.5V Power Rail' value is 2.504 V - Voltage '3.3V Power Rail' value is 3.332 V | '0.85V Power Rail#hardware.voltage.volt'=0.860666666667V;;0:0;0.76;0.94 '3.3V SD Power Rail#hardware.voltage.volt'=3.332V;;0:0;2.97;3.63 '0.9V Power Rail#hardware.voltage.volt'=0.904V;;0:0;0.81;0.99 '1.0V Power Rail#hardware.voltage.volt'=1.006V;;0:0;0.9;1.1 '1.1V Power Rail#hardware.voltage.volt'=1.09466666667V;;0:0;0.99;1.21 '1.2V Power Rail#hardware.voltage.volt'=1.224V;;0:0;1.08;1.32 '1.5V Power Rail#hardware.voltage.volt'=1.51066666667V;;0:0;1.35;1.65 '1.8V Power Rail#hardware.voltage.volt'=1.812V;;0:0;1.62;1.98 '2.5V Power Rail#hardware.voltage.volt'=2.504V;;0:0;2.25;2.75 '3.3V Power Rail#hardware.voltage.volt'=3.332V;;0:0;2.97;3.63 'hardware.voltage.count'=10;;;; diff --git a/tests/network/paloalto/api/ha.robot b/tests/network/paloalto/api/ha.robot index 5140b34ae1..c0e1bb28fa 100644 --- a/tests/network/paloalto/api/ha.robot +++ b/tests/network/paloalto/api/ha.robot @@ -19,6 +19,7 @@ ${CMD} ${CENTREON_PLUGINS} ... --proto=http ... --mode=ha + *** Test Cases *** paloalto-ha ${tc} [Tags] network paloalto api ha @@ -30,15 +31,41 @@ paloalto-ha ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} OK: PA-850 status: state sync: synchronized, HA1 link: up, HA2 link: up, HA mode: active-passive, build compatibility: Match - ... 2 --warning-peer-state='\\\%{peer_state} =~ /active/' WARNING: PA-850 status: peer state: active (priority: 100, conn: up) - ... 3 --critical-peer-state='\\\%{peer_state} =~ /active/' CRITICAL: PA-850 status: peer state: active (priority: 100, conn: up) - ... 4 --warning-state-sync='\\\%{state_sync} =~ /synchronized/' WARNING: PA-850 status: state sync: synchronized - ... 5 --critical-state-sync='\\\%{state_sync} =~ /synchronized/' CRITICAL: PA-850 status: state sync: synchronized - ... 6 --warning-ha1-link-status='\\\%{ha1_status} =~ /up/' WARNING: PA-850 status: HA1 link: up - ... 7 --critical-ha1-link-status='\\\%{ha1_status} =~ /up/' CRITICAL: PA-850 status: HA1 link: up - ... 8 --warning-ha2-link-status='\\\%{ha2_status} =~ /up/' WARNING: PA-850 status: HA2 link: up - ... 9 --critical-ha2-link-status='\\\%{ha2_status} =~ /up/' CRITICAL: PA-850 status: HA2 link: up - ... 10 --warning-build-compat='\\\%{build_compat} =~ /Match/' WARNING: PA-850 status: build compatibility: Match - ... 11 --critical-build-compat='\\\%{build_compat} =~ /Match/' CRITICAL: PA-850 status: build compatibility: Match + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: PA-850 status: state sync: synchronized, HA1 link: up, HA2 link: up, HA mode: active-passive, build compatibility: Match + ... 2 + ... --warning-peer-state='\\\%{peer_state} =~ /active/' + ... WARNING: PA-850 status: peer state: active (priority: 100, conn: up) + ... 3 + ... --critical-peer-state='\\\%{peer_state} =~ /active/' + ... CRITICAL: PA-850 status: peer state: active (priority: 100, conn: up) + ... 4 + ... --warning-state-sync='\\\%{state_sync} =~ /synchronized/' + ... WARNING: PA-850 status: state sync: synchronized + ... 5 + ... --critical-state-sync='\\\%{state_sync} =~ /synchronized/' + ... CRITICAL: PA-850 status: state sync: synchronized + ... 6 + ... --warning-ha1-link-status='\\\%{ha1_status} =~ /up/' + ... WARNING: PA-850 status: HA1 link: up + ... 7 + ... --critical-ha1-link-status='\\\%{ha1_status} =~ /up/' + ... CRITICAL: PA-850 status: HA1 link: up + ... 8 + ... --warning-ha2-link-status='\\\%{ha2_status} =~ /up/' + ... WARNING: PA-850 status: HA2 link: up + ... 9 + ... --critical-ha2-link-status='\\\%{ha2_status} =~ /up/' + ... CRITICAL: PA-850 status: HA2 link: up + ... 10 + ... --warning-build-compat='\\\%{build_compat} =~ /Match/' + ... WARNING: PA-850 status: build compatibility: Match + ... 11 + ... --critical-build-compat='\\\%{build_compat} =~ /Match/' + ... CRITICAL: PA-850 status: build compatibility: Match diff --git a/tests/network/paloalto/api/health.robot b/tests/network/paloalto/api/health.robot new file mode 100644 index 0000000000..c23c23cd94 --- /dev/null +++ b/tests/network/paloalto/api/health.robot @@ -0,0 +1,175 @@ +*** Settings *** +Documentation network::paloalto::api::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${INJECT_PERL} -Mfixed_date -I${CURDIR} +${MOCKOON_JSON} ${CURDIR}${/}mockoon-paloalto-api.json +${HOSTNAME} 127.0.0.1 +${APIPORT} 3000 +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::paloalto::api::plugin +... --mode=health +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --auth-type=api-key +... --api-key=D@pAs$W@rD + + +*** Test Cases *** +Health ${tc} + [Tags] network paloalto api + + ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default= + Set Environment Variable PERL5OPT ${INJECT_PERL} ${OLD_PERL5OPT} + + ${command}= Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 2 + ... --filter-counters=template + ... CRITICAL: template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; + ... 3 + ... --include-device-hostname=toky --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 1, connected devices: 0, out of sync devices: 0, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 2, last push status: OK, last push age: 4029270 seconds - device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=1;;;0; 'panorama.devices.connected.count'=0;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=2;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 4 + ... --exclude-device-hostname=toky --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 2, connected devices: 2, out of sync devices: 1, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 2, last push status: OK, last push age: 4029270 seconds - All devices are ok - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=2;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=2;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 5 + ... --include-device-serial=LONDO --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 1, connected devices: 1, out of sync devices: 1, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 3, last push status: OK, last push age: 4029270 seconds - device 'fw-london.example.com' (FW-LONDON) connected: yes - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=1;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=3;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 6 + ... --exclude-device-serial=LONDO --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 2, connected devices: 1, out of sync devices: 0, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 1, last push status: OK, last push age: 4029270 seconds - All devices are ok - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=2;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 7 + ... --include-plugin=cisco --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 3, connected devices: 2, out of sync devices: 1, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 1, last push status: OK, last push age: 4029270 seconds - All devices are ok - plugin 'cisco' status: success (version: 2.1.0) - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 8 + ... --exclude-plugin=cisco --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 3, connected devices: 2, out of sync devices: 1, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 1, last push status: OK, last push age: 4029270 seconds - All devices are ok - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 9 + ... --include-template=dev --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 3, connected devices: 2, out of sync devices: 1, total device-groups: 0, total templates: 1, template assignments: 1, template assignments out of sync: 0, last push status: OK, last push age: 4029270 seconds - All devices are ok - All plugins are ok - template 'template-dev' template-devices-count : skipped (no value(s)) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=1;;;0; 'panorama.template_assignments.total.count'=1;;;0; 'panorama.template_assignments.out_of_sync.count'=0;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 10 + ... --exclude-template=dev --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... OK: Panorama total devices: 3, connected devices: 2, out of sync devices: 1, total device-groups: 0, total templates: 1, template assignments: 2, template assignments out of sync: 1, last push status: OK, last push age: 4029270 seconds - All devices are ok - All plugins are ok - template 'template-prod' template-devices-count : skipped (no value(s)) - All template assignments are synchronized | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=1;;;0; 'panorama.template_assignments.total.count'=2;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 11 + ... --unknown-device-connection-status='\\\%{connected} eq "yes"' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: device 'fw-london.example.com' (FW-LONDON) connected: yes - device 'fw-nyc.example.com' (FW-NYC) connected: yes | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 12 + ... --warning-device-connection-status='\\\%{connected} eq "yes"' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: device 'fw-london.example.com' (FW-LONDON) connected: yes - device 'fw-nyc.example.com' (FW-NYC) connected: yes | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 13 + ... --critical-device-connection-status='\\\%{connected} eq "yes"' --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: device 'fw-london.example.com' (FW-LONDON) connected: yes - device 'fw-nyc.example.com' (FW-NYC) connected: yes | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 14 + ... --unknown-device-software-version='\\\%{sw_version} =~ /1/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: device 'fw-london.example.com' (FW-LONDON) software version: 10.0.5 - device 'fw-nyc.example.com' (FW-NYC) software version: 10.1.3 - device 'fw-tokyo.example.com' (FW-TOKYO) software version: 10.1.1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 15 + ... --warning-device-software-version='\\\%{sw_version} =~ /1/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: device 'fw-london.example.com' (FW-LONDON) software version: 10.0.5 - device 'fw-nyc.example.com' (FW-NYC) software version: 10.1.3 - device 'fw-tokyo.example.com' (FW-TOKYO) software version: 10.1.1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 16 + ... --critical-device-software-version='\\\%{sw_version} =~ /1/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: device 'fw-london.example.com' (FW-LONDON) software version: 10.0.5 - device 'fw-nyc.example.com' (FW-NYC) software version: 10.1.3 - device 'fw-tokyo.example.com' (FW-TOKYO) software version: 10.1.1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 17 + ... --unknown-device-ha-state='\\\%{ha_state} =~ /passive/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: device 'fw-london.example.com' (FW-LONDON) HA state: passive | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 18 + ... --warning-device-ha-state='\\\%{ha_state} =~ /passive/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: device 'fw-london.example.com' (FW-LONDON) HA state: passive | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 19 + ... --critical-device-ha-state='\\\%{ha_state} =~ /passive/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: device 'fw-london.example.com' (FW-LONDON) HA state: passive | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 20 + ... --unknown-plugin-status='\\\%{status} =~ /failed/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: plugin 'vmware' status: failed (version: 1.5.2) | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 21 + ... --warning-plugin-status='\\\%{status} =~ /failed/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: plugin 'vmware' status: failed (version: 1.5.2) | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 22 + ... --critical-plugin-status='\\\%{status} !~ /failed/' --critical-device-connection-status= --critical-template-sync-status= + ... CRITICAL: plugin 'cisco' status: success (version: 2.1.0) - plugin 'nutanix' status: success (version: 1.0.3) | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 23 + ... --unknown-push-status='\\\%{push_status} =~ /OK/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: Panorama last push status: OK | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 24 + ... --warning-push-status='\\\%{push_status} =~ /OK/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama last push status: OK | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 25 + ... --critical-push-status='\\\%{push_status} =~ /OK/' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama last push status: OK | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 26 + ... --warning-push-age=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama last push age: 4029270 seconds | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;0:1;;0; + ... 27 + ... --critical-push-age=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama last push age: 4029270 seconds | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;0:1;0; + ... 28 + ... --unknown-template-sync-status='\\\%{sync_status} =~ /out of sync/i' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... UNKNOWN: template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 29 + ... --warning-template-sync-status='\\\%{sync_status} =~ /out of sync/i' --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 30 + ... --critical-template-sync-status='\\\%{sync_status} =~ /out of sync/i' --critical-device-connection-status= --critical-plugin-status= + ... CRITICAL: template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 31 + ... --warning-devices-total=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama total devices: 3 | 'panorama.devices.total.count'=3;0:1;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 32 + ... --critical-devices-total=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama total devices: 3 | 'panorama.devices.total.count'=3;;0:1;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 33 + ... --warning-devices-connected=1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama connected devices: 2 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;0:1;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 34 + ... --critical-devices-connected=1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama connected devices: 2 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;0:1;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 35 + ... --warning-devices-out-of-sync=3: --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama out of sync devices: 1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;3:;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 36 + ... --critical-devices-out-of-sync=3: --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama out of sync devices: 1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;3:;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 37 + ... --warning-templates-total=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama total templates: 2 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;0:1;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 38 + ... --critical-templates-total=:1 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama total templates: 2 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;0:1;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 39 + ... --warning-template-assignments-total=0 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama template assignments: 3 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;0:0;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 40 + ... --critical-template-assignments-total=0 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama template assignments: 3 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;0:0;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 41 + ... --warning-template-assignments-out-of-sync=0 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... WARNING: Panorama template assignments out of sync: 1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;0:0;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 42 + ... --critical-template-assignments-out-of-sync=0 --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= + ... CRITICAL: Panorama template assignments out of sync: 1 | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;0:0;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 43 + ... --include-device-serial=LONDO + ... CRITICAL: plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: unknown, status: disconnected - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: unknown, status: disconnected | 'panorama.devices.total.count'=1;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=3;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... 44 + ... --exclude-device-serial=LONDO + ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: unknown, status: disconnected - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.devices.total.count'=2;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; diff --git a/tests/network/paloalto/api/ipsec.robot b/tests/network/paloalto/api/ipsec.robot index a88592ee11..478649ae69 100644 --- a/tests/network/paloalto/api/ipsec.robot +++ b/tests/network/paloalto/api/ipsec.robot @@ -19,6 +19,7 @@ ${CMD} ${CENTREON_PLUGINS} ... --proto=http ... --mode=ipsec + *** Test Cases *** paloalto-ipsec ${tc} [Tags] network paloalto api tunnel @@ -31,13 +32,35 @@ paloalto-ipsec ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} OK: Tunnels count: 3 - All tunnels are ok | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; - ... 2 --include-gateway-name='ateway 3' OK: Tunnels count: 1 - tunnel 'Nom du tunnel 3' remain: 1727 seconds, encryption: G256, gateway: Nom de la Gateway 3 | 'tunnels.count'=1;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; - ... 3 --exclude-gateway-name='ateway 1' OK: Tunnels count: 2 - All tunnels are ok | 'tunnels.count'=2;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; - ... 4 --include-tunnel-name='unnel 2' OK: Tunnels count: 1 - tunnel 'Nom du tunnel 2' remain: 1727 seconds, encryption: G256, gateway: Nom de la Gateway 2 | 'tunnels.count'=1;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; - ... 5 --exclude-tunnel-name='unnel 3' OK: Tunnels count: 2 - All tunnels are ok | 'tunnels.count'=2;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; - ... 6 --warning-tunnels-count=:1 WARNING: Tunnels count: 3 | 'tunnels.count'=3;0:1;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; - ... 7 --critical-tunnels-count=:1 CRITICAL: Tunnels count: 3 | 'tunnels.count'=3;;0:1;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; - ... 8 --warning-remain-time=:1000 WARNING: tunnel 'Nom du tunnel 1' remain: 1727 seconds - tunnel 'Nom du tunnel 2' remain: 1727 seconds - tunnel 'Nom du tunnel 3' remain: 1727 seconds | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;0:1000;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;0:1000;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;0:1000;;0; - ... 9 --critical-remain-time=:1000 CRITICAL: tunnel 'Nom du tunnel 1' remain: 1727 seconds - tunnel 'Nom du tunnel 2' remain: 1727 seconds - tunnel 'Nom du tunnel 3' remain: 1727 seconds | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;0:1000;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;0:1000;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;0:1000;0; + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: Tunnels count: 3 - All tunnels are ok | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; + ... 2 + ... --include-gateway-name='ateway 3' + ... OK: Tunnels count: 1 - tunnel 'Nom du tunnel 3' remain: 1727 seconds, encryption: G256, gateway: Nom de la Gateway 3 | 'tunnels.count'=1;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; + ... 3 + ... --exclude-gateway-name='ateway 1' + ... OK: Tunnels count: 2 - All tunnels are ok | 'tunnels.count'=2;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; + ... 4 + ... --include-tunnel-name='unnel 2' + ... OK: Tunnels count: 1 - tunnel 'Nom du tunnel 2' remain: 1727 seconds, encryption: G256, gateway: Nom de la Gateway 2 | 'tunnels.count'=1;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; + ... 5 + ... --exclude-tunnel-name='unnel 3' + ... OK: Tunnels count: 2 - All tunnels are ok | 'tunnels.count'=2;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; + ... 6 + ... --warning-tunnels-count=:1 + ... WARNING: Tunnels count: 3 | 'tunnels.count'=3;0:1;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; + ... 7 + ... --critical-tunnels-count=:1 + ... CRITICAL: Tunnels count: 3 | 'tunnels.count'=3;;0:1;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;;0; + ... 8 + ... --warning-remain-time=:1000 + ... WARNING: tunnel 'Nom du tunnel 1' remain: 1727 seconds - tunnel 'Nom du tunnel 2' remain: 1727 seconds - tunnel 'Nom du tunnel 3' remain: 1727 seconds | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;0:1000;;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;0:1000;;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;0:1000;;0; + ... 9 + ... --critical-remain-time=:1000 + ... CRITICAL: tunnel 'Nom du tunnel 1' remain: 1727 seconds - tunnel 'Nom du tunnel 2' remain: 1727 seconds - tunnel 'Nom du tunnel 3' remain: 1727 seconds | 'tunnels.count'=3;;;0; 'Nom du tunnel 1#tunnel.remain.seconds'=1727s;;0:1000;0; 'Nom du tunnel 2#tunnel.remain.seconds'=1727s;;0:1000;0; 'Nom du tunnel 3#tunnel.remain.seconds'=1727s;;0:1000;0; diff --git a/tests/network/paloalto/api/licenses.robot b/tests/network/paloalto/api/licenses.robot index d4ea8bf163..fe6f1a8bd6 100644 --- a/tests/network/paloalto/api/licenses.robot +++ b/tests/network/paloalto/api/licenses.robot @@ -9,7 +9,7 @@ Test Timeout 120s *** Variables *** -${INJECT_PERL} -Mfixed_date -I${CURDIR} +${INJECT_PERL} -Mfixed_date -I${CURDIR} ${MOCKOON_JSON} ${CURDIR}${/}mockoon-paloalto-api.json ${HOSTNAME} 127.0.0.1 ${APIPORT} 3000 @@ -20,14 +20,15 @@ ${CMD} ${CENTREON_PLUGINS} ... --proto=http ... --mode=licenses + *** Test Cases *** paloalto-licenses ${tc} [Tags] network paloalto api licenses - ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default= + ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default= Set Environment Variable PERL5OPT ${INJECT_PERL} ${OLD_PERL5OPT} - ${command} Catenate + ${command}= Catenate ... ${CMD} ... --auth-type=api-key ... --api-key=D@pAs$W@rD @@ -35,15 +36,41 @@ paloalto-licenses ${tc} Ctn Run Command Without Connector And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} CRITICAL: license 'Standard' expired: yes, 0 days left | 'licenses.count'=13;;;0; 'Advanced DNS Security#license.empiration.days'=185d;;@0:0;-1; 'Advanced Threat Prevention#license.empiration.days'=185d;;@0:0;-1; 'Advanced URL Filtering#license.empiration.days'=185d;;@0:0;-1; 'Advanced WildFire License#license.empiration.days'=185d;;@0:0;-1; 'DNS Security#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Gateway#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; 'PAN-DB URL Filtering#license.empiration.days'=185d;;@0:0;-1; 'SD WAN#license.empiration.days'=185d;;@0:0;-1; 'Standard#license.empiration.days'=0d;;@0:0;-1; 'Threat Prevention#license.empiration.days'=185d;;@0:0;-1; 'WildFire License#license.empiration.days'=185d;;@0:0;-1; - ... 2 --include-license-name=Logging --warning-status='\\\%{expired}=~/no/' WARNING: license 'Logging Service' expired: no | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; - ... 3 --include-license-name=Logging --critical-status='\\\%{expired}=~/no/' CRITICAL: license 'Logging Service' expired: no | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; - ... 4 --include-license-name=GlobalProtect OK: Licenses count: 2 - All licenses are ok | 'licenses.count'=2;;;0; 'GlobalProtect Gateway#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; - ... 5 --warning-licenses-count=1000: --include-license-name=Logging WARNING: Licenses count: 1 | 'licenses.count'=1;1000:;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; - ... 6 --critical-licenses-count=1000: --include-license-name=Logging CRITICAL: Licenses count: 1 | 'licenses.count'=1;;1000:;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; - ... 7 --include-license-name=SD OK: Licenses count: 1 - license 'SD WAN' expired: no, 185 days left | 'licenses.count'=1;;;0; 'SD WAN#license.empiration.days'=185d;;@0:0;-1; - ... 8 --include-license-name=Logging --warning-expiration-days=1000 WARNING: license 'Logging Service' 1180 days left | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;0:1000;@0:0;-1; - ... 9 --include-license-name=Logging --critical-expiration-days=1000 CRITICAL: license 'Logging Service' 1180 days left | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;0:1000;-1; - ... 10 --include-license-name=Standard CRITICAL: license 'Standard' expired: yes, 0 days left | 'licenses.count'=1;;;0; 'Standard#license.empiration.days'=0d;;@0:0;-1; - ... 11 --include-license-name=Portal OK: Licenses count: 1 - license 'GlobalProtect Portal' expired: no, never expire | 'licenses.count'=1;;;0; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... CRITICAL: license 'Standard' expired: yes, 0 days left | 'licenses.count'=13;;;0; 'Advanced DNS Security#license.empiration.days'=185d;;@0:0;-1; 'Advanced Threat Prevention#license.empiration.days'=185d;;@0:0;-1; 'Advanced URL Filtering#license.empiration.days'=185d;;@0:0;-1; 'Advanced WildFire License#license.empiration.days'=185d;;@0:0;-1; 'DNS Security#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Gateway#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; 'PAN-DB URL Filtering#license.empiration.days'=185d;;@0:0;-1; 'SD WAN#license.empiration.days'=185d;;@0:0;-1; 'Standard#license.empiration.days'=0d;;@0:0;-1; 'Threat Prevention#license.empiration.days'=185d;;@0:0;-1; 'WildFire License#license.empiration.days'=185d;;@0:0;-1; + ... 2 + ... --include-license-name=Logging --warning-status='\\\%{expired}=~/no/' + ... WARNING: license 'Logging Service' expired: no | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; + ... 3 + ... --include-license-name=Logging --critical-status='\\\%{expired}=~/no/' + ... CRITICAL: license 'Logging Service' expired: no | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; + ... 4 + ... --include-license-name=GlobalProtect + ... OK: Licenses count: 2 - All licenses are ok | 'licenses.count'=2;;;0; 'GlobalProtect Gateway#license.empiration.days'=185d;;@0:0;-1; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; + ... 5 + ... --warning-licenses-count=1000: --include-license-name=Logging + ... WARNING: Licenses count: 1 | 'licenses.count'=1;1000:;;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; + ... 6 + ... --critical-licenses-count=1000: --include-license-name=Logging + ... CRITICAL: Licenses count: 1 | 'licenses.count'=1;;1000:;0; 'Logging Service#license.empiration.days'=1180d;;@0:0;-1; + ... 7 + ... --include-license-name=SD + ... OK: Licenses count: 1 - license 'SD WAN' expired: no, 185 days left | 'licenses.count'=1;;;0; 'SD WAN#license.empiration.days'=185d;;@0:0;-1; + ... 8 + ... --include-license-name=Logging --warning-expiration-days=1000 + ... WARNING: license 'Logging Service' 1180 days left | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;0:1000;@0:0;-1; + ... 9 + ... --include-license-name=Logging --critical-expiration-days=1000 + ... CRITICAL: license 'Logging Service' 1180 days left | 'licenses.count'=1;;;0; 'Logging Service#license.empiration.days'=1180d;;0:1000;-1; + ... 10 + ... --include-license-name=Standard + ... CRITICAL: license 'Standard' expired: yes, 0 days left | 'licenses.count'=1;;;0; 'Standard#license.empiration.days'=0d;;@0:0;-1; + ... 11 + ... --include-license-name=Portal + ... OK: Licenses count: 1 - license 'GlobalProtect Portal' expired: no, never expire | 'licenses.count'=1;;;0; 'GlobalProtect Portal#license.empiration.days'=-1d;;@0:0;-1; diff --git a/tests/network/paloalto/api/mockoon-paloalto-api.json b/tests/network/paloalto/api/mockoon-paloalto-api.json index a9a91b4a57..339152a90d 100644 --- a/tests/network/paloalto/api/mockoon-paloalto-api.json +++ b/tests/network/paloalto/api/mockoon-paloalto-api.json @@ -220,7 +220,7 @@ }, { "uuid": "046ba2be-d382-4255-a575-dd5894136b30", - "body": "\n\n\n\n987654\nyes\nno\nno\nDUMMY-1-VM\n10.1.1.11\n\n81 days, 20:39:41\nvm\nPA-VM\n6.1.3\n555-3129\n2254-2693\n91873-10.274\n555-3129\npaulotonetworks\n2016.02.02.416\n6.1.3\n\n0.0.0\nno\nnormal\nno\n\n\n123456\nyes\nno\nno\nDUMMY-2-VM\n10.1.1.10\n\n81 days, 20:39:41\nvm\nPA-VM\n6.1.3\n555-3129\n2254-2693\n91873-10.274\n555-3129\npaulonetworks\n2016.02.02.416\n6.1.3\n\n0.0.0\nno\nnormal\nno\n\n\n\n", + "body": "\n\n \n \n \n FW-NYC\n yes\n fw-nyc.example.com\n 192.168.1.1\n PA-850\n 10.1.3\n Valid\n CN=fw-nyc.example.com,O=Palo Alto Networks\n Dec 15, 2025\n No\n \n active\n \n FW-NYC-HA\n \n \n \n \n Root\n In Sync\n abc123def456\n \n \n \n \n FW-LONDON\n yes\n fw-london.example.com\n 192.168.1.2\n PA-850\n 10.0.5\n Valid\n CN=fw-london.example.com,O=Palo Alto Networks\n Mar 22, 2024\n Yes\n \n passive\n \n FW-LONDON-HA\n \n \n \n \n Root\n Out of Sync\n xyz789uvw012\n \n \n \n \n FW-TOKYO\n no\n fw-tokyo.example.com\n 192.168.1.3\n PA-VM\n 10.1.1\n Expired\n CN=fw-tokyo.example.com,O=Palo Alto Networks\n Jan 10, 2024\n No\n \n unknown\n \n unknown\n \n \n \n \n Root\n unknown\n \n \n \n \n \n \n", "latency": 0, "statusCode": 200, "label": "LIST PANORAMA FIREWALL", @@ -278,6 +278,102 @@ "default": false, "crudKey": "id", "callbacks": [] + }, + { + "uuid": "f4e5d6c7-8a9b-4c0d-1e2f-3a4b5c6d7e8f", + "body": "\n\n \n \n \n", + "latency": 0, + "statusCode": 200, + "label": "LIST PANORAMA TEMPLATES", + "headers": [ + { + "key": "Content-Type", + "value": "application/xml" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "xpath", + "value": "/config/devices/entry//template", + "invert": false, + "operator": "regex" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + }, + { + "uuid": "d5c6e7f8-9a0b-4c1d-2e3f-4a5b6c7d8e9f", + "body": "\n\n \n \n \n 2.1.0\n success\n \n \n 1.0.3\n success\n \n \n 1.5.2\n failed\n \n \n \n", + "latency": 0, + "statusCode": 200, + "label": "LIST PLUGINS", + "headers": [ + { + "key": "Content-Type", + "value": "application/xml" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "cmd", + "value": "", + "invert": false, + "operator": "regex" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + }, + { + "uuid": "e6d7f8a9-b1c2-4d3e-4f5a-6b7c8d9e0f10", + "body": "\n\n \n \n 123\n CommitAll\n FIN\n OK\n 2024/12/15 14:30:25\n 2024/12/15 14:25:10\n \n \n 124\n Push\n FIN\n OK\n 2024/12/16 08:45:30\n 2024/12/16 08:40:15\n \n \n", + "latency": 0, + "statusCode": 200, + "label": "LIST JOBS", + "headers": [ + { + "key": "Content-Type", + "value": "application/xml" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "cmd", + "value": "", + "invert": false, + "operator": "regex" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] } ], "responseMode": null, diff --git a/tests/network/paloalto/api/system.robot b/tests/network/paloalto/api/system.robot index d2f7cdd40d..4c4e8dd9d7 100644 --- a/tests/network/paloalto/api/system.robot +++ b/tests/network/paloalto/api/system.robot @@ -39,37 +39,55 @@ paloalto-system ${tc} ... -- ... 1 ... ${EMPTY} - ... OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, software version: 10.1.12, WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... OK: System uptime: 8552549 seconds, certificate status: Valid, operational mode: normal, packet rate: 0 p/s, throughput: 0.00 b/s, total active sessions: 0 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 2 ... --warning-uptime=:1000 - ... WARNING: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;0:1000;;0; + ... WARNING: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;0:1000;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 3 ... --critical-uptime=:1000 - ... CRITICAL: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;;0:1000;0; + ... CRITICAL: System uptime: 8552549 seconds | 'system.uptime.seconds'=8552549s;;0:1000;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 4 ... --warning-certificate-status='\\\%{cert_status} =~ /Valid/' - ... WARNING: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; + ... WARNING: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 5 ... --critical-certificate-status='\\\%{cert_status} =~ /Valid/' - ... CRITICAL: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; + ... CRITICAL: System certificate status: Valid | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 6 ... --warning-software-version='\\\%{sw_version} !~ /2\.0/' - ... WARNING: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; + ... WARNING: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 7 ... --critical-software-version='\\\%{sw_version} !~ /2\.0/' - ... CRITICAL: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; + ... CRITICAL: System software version: 10.1.12 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 8 ... --warning-operational-mode='\\\%{operational_mode} =~ /normal/' - ... WARNING: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; + ... WARNING: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 9 ... --critical-operational-mode='\\\%{operational_mode} =~ /normal/' - ... CRITICAL: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; + ... CRITICAL: System operational mode: normal | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 10 ... --warning-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' - ... WARNING: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... WARNING: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 11 ... --critical-wildfire-mode='\\\%{wildfire_mode} =~ /disabled/i' - ... CRITICAL: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; + ... CRITICAL: System WildFire mode: Disabled | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; ... 12 ... --target=001802000104 - ... OK: System uptime: 1037126 seconds, certificate status: Valid, operational mode: normal, software version: 1.PANORAMA, WildFire mode: Unknown | 'system.uptime.seconds'=1037126s;;;0; + ... OK: System uptime: 1037126 seconds, certificate status: Valid, operational mode: normal, packet rate: 0 p/s, throughput: 0.00 b/s, total active sessions: 0 | 'system.uptime.seconds'=1037126s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; + ... 13 + ... --warning-active-sessions=1: + ... WARNING: System total active sessions: 0 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;1:;;0; + ... 14 + ... --critical-active-sessions=1: + ... CRITICAL: System total active sessions: 0 | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;1:;0; + ... 15 + ... --warning-packet-rate=1: + ... WARNING: System packet rate: 0 p/s | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;1:;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; + ... 16 + ... --critical-packet-rate=1: + ... CRITICAL: System packet rate: 0 p/s | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;1:;0; 'system.sessions.throughput.bitspersecond'=0b/s;;;0; 'system.sessions.total.count'=0;;;0; + ... 17 + ... --warning-sessions-traffic=1: + ... WARNING: System throughput: 0.00 b/s | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;1:;;0; 'system.sessions.total.count'=0;;;0; + ... 18 + ... --critical-sessions-traffic=1: + ... CRITICAL: System throughput: 0.00 b/s | 'system.uptime.seconds'=8552549s;;;0; 'system.sessions.packet.rate.persecond'=0p/s;;;0; 'system.sessions.throughput.bitspersecond'=0b/s;;1:;0; 'system.sessions.total.count'=0;;;0; From ff72ec9aac1441c6780b6e0caaf65f0f794b66a2 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Thu, 28 May 2026 15:10:35 +0200 Subject: [PATCH 3/9] Update --- tests/apps/backup/rubrik/graphql/rubrik-mockoon.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json index 27c7266ea4..2c7022088f 100644 --- a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json +++ b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json @@ -386,4 +386,4 @@ ], "data": [], "callbacks": [] -} \ No newline at end of file +} From c71202015a77d6d85fdfba63d8794a352dc63d47 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Thu, 28 May 2026 17:48:59 +0200 Subject: [PATCH 4/9] Update --- src/network/paloalto/api/custom/api.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/paloalto/api/custom/api.pm b/src/network/paloalto/api/custom/api.pm index 24dd4a8411..416f1c8108 100644 --- a/src/network/paloalto/api/custom/api.pm +++ b/src/network/paloalto/api/custom/api.pm @@ -29,7 +29,7 @@ use XML::Simple; use MIME::Base64 qw(encode_base64); use URI::Escape qw(uri_escape); use Digest::SHA qw(sha256_hex); -use centreon::plugins::misc qw(is_empty); +use centreon::plugins::misc qw(is_empty value_of); sub new { my ($class, %options) = @_; From 584a63cdbb18b45c8b219b5ada2db0bb25628627 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Thu, 28 May 2026 17:55:42 +0200 Subject: [PATCH 5/9] Update --- src/network/paloalto/api/mode/health.pm | 10 +++++----- tests/network/paloalto/api/health.robot | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/paloalto/api/mode/health.pm b/src/network/paloalto/api/mode/health.pm index 6834601e6a..55c3eb29cc 100644 --- a/src/network/paloalto/api/mode/health.pm +++ b/src/network/paloalto/api/mode/health.pm @@ -177,7 +177,7 @@ sub set_counters { $self->{maps_counters}->{template_sync} = [ { label => 'template-sync-status', type => COUNTER_KIND_TEXT, - critical_default => '%{sync_status} ne "in-sync"', + critical_default => '%{sync_status} ne "in sync"', set => { key_values => [ { name => 'sync_status' }, { name => 'template_name' }, { name => 'device_serial' }, { name => 'vsys' } ], output_template => 'template: %{template_name}, vsys: %{vsys}, status: %s', @@ -362,7 +362,7 @@ sub manage_selection { # Create entry for each vsys with sync status foreach my $vsys_name (keys %{$vsys_sync_states}) { - my $sync_status = $vsys_sync_states->{$vsys_name} // 'unknown'; + my $sync_status = lc ($vsys_sync_states->{$vsys_name} // 'unknown'); my $entry_key = "$template_name-$device_serial-$vsys_name"; $self->{template_sync}->{$entry_key} = { @@ -370,11 +370,11 @@ sub manage_selection { device_serial => $device_serial, device_name => $device_info->{name}, vsys => $vsys_name, - sync_status => lc($sync_status), + sync_status => $sync_status, connected => $device_info->{connected} }; - if ($sync_status ne 'In Sync' && $sync_status ne 'unknown') { + if ($sync_status ne 'in sync' && $sync_status ne 'unknown') { $self->{global}->{template_assignments_out_of_sync}++; } } @@ -586,7 +586,7 @@ You can use the following variables: %{sync_status}, %{template_name}, %{device_ =item B<--critical-template-sync-status> -Define the conditions to match for the status to be CRITICAL (default: '%{sync_status} ne "in-sync"'). +Define the conditions to match for the status to be CRITICAL (default: '%{sync_status} ne "in sync"'). You can use the following variables: %{sync_status}, %{template_name}, %{device_serial}, %{vsys} =item B<--warning-devices-total> diff --git a/tests/network/paloalto/api/health.robot b/tests/network/paloalto/api/health.robot index c23c23cd94..4168fe52b5 100644 --- a/tests/network/paloalto/api/health.robot +++ b/tests/network/paloalto/api/health.robot @@ -43,10 +43,10 @@ Health ${tc} ... -- ... 1 ... ${EMPTY} - ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync | 'panorama.devices.total.count'=3;;;0; 'panorama.devices.connected.count'=2;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; ... 2 ... --filter-counters=template - ... CRITICAL: template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; + ... CRITICAL: template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync | 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; ... 3 ... --include-device-hostname=toky --critical-device-connection-status= --critical-plugin-status= --critical-template-sync-status= ... OK: Panorama total devices: 1, connected devices: 0, out of sync devices: 0, total device-groups: 0, total templates: 2, template assignments: 3, template assignments out of sync: 2, last push status: OK, last push age: 4029270 seconds - device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - All plugins are ok - All templates are ok - All template assignments are synchronized | 'panorama.devices.total.count'=1;;;0; 'panorama.devices.connected.count'=0;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=2;;;0; 'panorama.push.age.seconds'=4029270s;;;0; @@ -172,4 +172,4 @@ Health ${tc} ... CRITICAL: plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: unknown, status: disconnected - template-assignment 'FW-LONDON' template: template-prod, vsys: vsys1, status: out of sync - template-assignment 'FW-NYC' template: template-prod, vsys: unknown, status: disconnected | 'panorama.devices.total.count'=1;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=1;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=3;;;0; 'panorama.push.age.seconds'=4029270s;;;0; ... 44 ... --exclude-device-serial=LONDO - ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: unknown, status: disconnected - template-assignment 'FW-NYC' template: template-prod, vsys: vsys1, status: in sync | 'panorama.devices.total.count'=2;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; + ... CRITICAL: device 'fw-tokyo.example.com' (FW-TOKYO) connected: no - plugin 'vmware' status: failed (version: 1.5.2) - template-assignment 'FW-TOKYO' template: template-dev, vsys: vsys1, status: unknown - template-assignment 'FW-LONDON' template: template-prod, vsys: unknown, status: disconnected | 'panorama.devices.total.count'=2;;;0; 'panorama.devices.connected.count'=1;;;0; 'panorama.devices.out_of_sync.count'=0;;;0; 'panorama.device_groups.total.count'=0;;;0; 'panorama.templates.total.count'=2;;;0; 'panorama.template_assignments.total.count'=3;;;0; 'panorama.template_assignments.out_of_sync.count'=1;;;0; 'panorama.push.age.seconds'=4029270s;;;0; From f546a88b6d0fd00a9dc96468ee475e980a57b771 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Mon, 1 Jun 2026 15:21:19 +0200 Subject: [PATCH 6/9] FIx tests --- src/network/paloalto/api/mode/certificate.pm | 10 +++--- .../backup/rubrik/graphql/rubrik-mockoon.json | 2 +- tests/network/paloalto/api/certificate.robot | 36 +++++++++---------- tests/network/paloalto/api/fixed_date.pm | 6 +++- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/network/paloalto/api/mode/certificate.pm b/src/network/paloalto/api/mode/certificate.pm index f1c2f63a06..ed0309bd8d 100644 --- a/src/network/paloalto/api/mode/certificate.pm +++ b/src/network/paloalto/api/mode/certificate.pm @@ -70,7 +70,7 @@ sub set_counters { key_values => [ { name => 'cert_expiry_days' }, { name => 'serial' }, { name => 'hostname' }, { name => 'connected' } ], output_template => 'expires in: %{cert_expiry_days} days', perfdatas => [ - { template => '%s', unit => 'd', min => 0 } + { template => '%s', unit => 'd', min => 0, instance_use => 'hostname', label_extra_instance => 1 } ] } }, @@ -149,16 +149,14 @@ sub _calculate_days_until_expiry { my $parser = DateTime::Format::Strptime->new( pattern => '%b %d, %Y', - on_error => 'undef' + on_error => 'undef', + time_zone => 'UTC' ); my $expiry_dt = $parser->parse_datetime($expiry_str); return -1 unless $expiry_dt; - my $now = DateTime->now(time_zone => 'UTC'); - my $duration = $expiry_dt - $now; - - return int($duration->in_units('days')); + return int(($expiry_dt->epoch() - time()) / 86400); } 1; diff --git a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json index 2c7022088f..27c7266ea4 100644 --- a/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json +++ b/tests/apps/backup/rubrik/graphql/rubrik-mockoon.json @@ -386,4 +386,4 @@ ], "data": [], "callbacks": [] -} +} \ No newline at end of file diff --git a/tests/network/paloalto/api/certificate.robot b/tests/network/paloalto/api/certificate.robot index 04a8faff40..58554d6a3c 100644 --- a/tests/network/paloalto/api/certificate.robot +++ b/tests/network/paloalto/api/certificate.robot @@ -43,55 +43,55 @@ Certificate ${tc} ... -- ... 1 ... ${EMPTY} - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 2 ... --filter-counters=certificate - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 3 ... --include-device-serial=LON - ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -10 days | 'device.certificate.expiry.days'=-10d;;;0; + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; ... 4 ... --exclude-device-serial=TOK - ... OK: All device certificates are OK | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; + ... OK: All device certificates are OK | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; ... 5 ... --include-device-hostname='london' - ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -10 days | 'device.certificate.expiry.days'=-10d;;;0; + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; ... 6 ... --exclude-device-hostname='fw-tokyo.example.com' - ... OK: All device certificates are OK | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; + ... OK: All device certificates are OK | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; ... 7 ... --connected-only=1 - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 8 ... --unknown-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= - ... UNKNOWN: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... UNKNOWN: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 9 ... --warning-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= - ... WARNING: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... WARNING: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 10 ... --critical-certificate-status="\\\%{cert_status} ne ''" - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid - Device 'fw-nyc.example.com' (FW-NYC) certificate status: Valid - Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid - Device 'fw-nyc.example.com' (FW-NYC) certificate status: Valid - Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 11 ... --unknown-certificate-subject=1 --critical-certificate-status= - ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 12 ... --warning-certificate-subject=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 13 ... --critical-certificate-subject=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 14 ... --warning-certificate-expiry=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) expires in: -10 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 14 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -22 days | 'device.certificate.expiry.days'=-10d;0:1;;0; 'device.certificate.expiry.days'=14d;0:1;;0; 'device.certificate.expiry.days'=-22d;0:1;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;0:1;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;0:1;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;0:1;;0; ... 15 ... --critical-certificate-expiry=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) expires in: -10 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 14 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -22 days | 'device.certificate.expiry.days'=-10d;;0:1;0; 'device.certificate.expiry.days'=14d;;0:1;0; 'device.certificate.expiry.days'=-22d;;0:1;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;0:1;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;0:1;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;0:1;0; ... 16 ... --unknown-certificate-custom-usage=1 --critical-certificate-status= - ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 17 ... --warning-certificate-custom-usage=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; ... 18 ... --critical-certificate-custom-usage=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'device.certificate.expiry.days'=-10d;;;0; 'device.certificate.expiry.days'=14d;;;0; 'device.certificate.expiry.days'=-22d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; diff --git a/tests/network/paloalto/api/fixed_date.pm b/tests/network/paloalto/api/fixed_date.pm index 7726d3a692..8147d4a288 100644 --- a/tests/network/paloalto/api/fixed_date.pm +++ b/tests/network/paloalto/api/fixed_date.pm @@ -3,8 +3,12 @@ package fixed_date; # Copyright 2026-Present Centreon # Always use the same fixed date to test certificate validity +use DateTime; + BEGIN { - *CORE::GLOBAL::time = sub { 1738368000 }; + $now = 1738368000; + *CORE::GLOBAL::time = sub { $now }; + *DateTime::now = sub { DateTime->from_epoch(epoch => $now) }; } 1 From a50150290c48af7539320c325428ed55d0c5aada Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Tue, 2 Jun 2026 08:43:09 +0200 Subject: [PATCH 7/9] Update tests --- tests/network/paloalto/api/certificate.robot | 40 ++++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/network/paloalto/api/certificate.robot b/tests/network/paloalto/api/certificate.robot index 58554d6a3c..45770e5550 100644 --- a/tests/network/paloalto/api/certificate.robot +++ b/tests/network/paloalto/api/certificate.robot @@ -34,64 +34,64 @@ Certificate ${tc} ... ${CMD} ... ${extra_options} - Ctn Run Command And Check Result As Strings ${command} ${expected_result} + Ctn Run Command And Check Result As Regexp ${command} ${expected_regexp} Examples: ... tc ... extra_options - ... expected_result + ... expected_regexp ... -- ... 1 ... ${EMPTY} - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 2 ... --filter-counters=certificate - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 3 ... --include-device-serial=LON - ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; ... 4 ... --exclude-device-serial=TOK - ... OK: All device certificates are OK | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; + ... OK: All device certificates are OK \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; ... 5 ... --include-device-hostname='london' - ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; + ... OK: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid, expires in: -316 days \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; ... 6 ... --exclude-device-hostname='fw-tokyo.example.com' - ... OK: All device certificates are OK | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; + ... OK: All device certificates are OK \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; ... 7 ... --connected-only=1 - ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 8 ... --unknown-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= - ... UNKNOWN: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... UNKNOWN: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 9 ... --warning-certificate-status='\\\%{cert_status}=~/Expired/' --critical-certificate-status= - ... WARNING: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... WARNING: Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 10 ... --critical-certificate-status="\\\%{cert_status} ne ''" - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid - Device 'fw-nyc.example.com' (FW-NYC) certificate status: Valid - Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) certificate status: Valid - Device 'fw-nyc.example.com' (FW-NYC) certificate status: Valid - Device 'fw-tokyo.example.com' (FW-TOKYO) certificate status: Expired \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 11 ... --unknown-certificate-subject=1 --critical-certificate-status= - ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 12 ... --warning-certificate-subject=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 13 ... --critical-certificate-subject=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) subject: CN=fw-london.example.com,O=Palo Alto Networks - Device 'fw-nyc.example.com' (FW-NYC) subject: CN=fw-nyc.example.com,O=Palo Alto Networks - Device 'fw-tokyo.example.com' (FW-TOKYO) subject: CN=fw-tokyo.example.com,O=Palo Alto Networks \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 14 ... --warning-certificate-expiry=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;0:1;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;0:1;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;0:1;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;0:1;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;0:1;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;0:1;;0; ... 15 ... --critical-certificate-expiry=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;0:1;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;0:1;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;0:1;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) expires in: -316 days - Device 'fw-nyc.example.com' (FW-NYC) expires in: 317 days - Device 'fw-tokyo.example.com' (FW-TOKYO) expires in: -388 days \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;0:1;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;0:1;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;0:1;0; ... 16 ... --unknown-certificate-custom-usage=1 --critical-certificate-status= - ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... UNKNOWN: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 17 ... --warning-certificate-custom-usage=1 --critical-certificate-status= - ... WARNING: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... WARNING: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; ... 18 ... --critical-certificate-custom-usage=1 --critical-certificate-status= - ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No | 'fw-london.example.com#device.certificate.expiry.days'=-316d;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=317d;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=-388d;;;0; + ... CRITICAL: Device 'fw-london.example.com' (FW-LONDON) custom certificate usage: Yes - Device 'fw-nyc.example.com' (FW-NYC) custom certificate usage: No - Device 'fw-tokyo.example.com' (FW-TOKYO) custom certificate usage: No \\\| 'fw-london.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-nyc.example.com#device.certificate.expiry.days'=.*;;;0; 'fw-tokyo.example.com#device.certificate.expiry.days'=.*;;;0; From 8178cb06bb8e5259a7e3f8eab1ccdb59e18b43c6 Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Tue, 2 Jun 2026 08:59:47 +0200 Subject: [PATCH 8/9] Update plugin --- src/network/paloalto/api/mode/certificate.pm | 2 +- src/network/paloalto/api/mode/health.pm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/paloalto/api/mode/certificate.pm b/src/network/paloalto/api/mode/certificate.pm index ed0309bd8d..77905ed9e6 100644 --- a/src/network/paloalto/api/mode/certificate.pm +++ b/src/network/paloalto/api/mode/certificate.pm @@ -116,7 +116,7 @@ sub manage_selection { $self->{devices} = {}; $self->{output}->option_exit(short_msg => "No certificates found !") - unless ref $result->{devices} eq 'HASH'; + unless $result && ref $result->{devices} eq 'HASH'; foreach my $device (@{$result->{devices}->{entry}}) { my $serial = $device->{name}; diff --git a/src/network/paloalto/api/mode/health.pm b/src/network/paloalto/api/mode/health.pm index 55c3eb29cc..fe087f015d 100644 --- a/src/network/paloalto/api/mode/health.pm +++ b/src/network/paloalto/api/mode/health.pm @@ -368,7 +368,7 @@ sub manage_selection { $self->{template_sync}->{$entry_key} = { template_name => $template_name, device_serial => $device_serial, - device_name => $device_info->{name}, + device_name => $device_info->{hostname}, vsys => $vsys_name, sync_status => $sync_status, connected => $device_info->{connected} @@ -415,7 +415,7 @@ sub manage_selection { # Keep only the most recent push job if ($last_push) { my $epoch = $self->_parse_panorama_timestamp($tfin); - if ($epoch && $last_push->{timestamp_epoch} && $epoch > $last_push->{timestamp_epoch}) { + if ($epoch && (!$last_push->{timestamp_epoch} || $epoch > $last_push->{timestamp_epoch})) { my $age_seconds = ($now - $epoch); $last_push = { status => $result, From 24dc0136cddf02b528ef96881759d6293872cb0e Mon Sep 17 00:00:00 2001 From: Sylvain Cresto Date: Tue, 2 Jun 2026 12:01:17 +0200 Subject: [PATCH 9/9] Update after review --- src/network/paloalto/api/mode/health.pm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/network/paloalto/api/mode/health.pm b/src/network/paloalto/api/mode/health.pm index fe087f015d..ce58fc1788 100644 --- a/src/network/paloalto/api/mode/health.pm +++ b/src/network/paloalto/api/mode/health.pm @@ -58,8 +58,6 @@ sub set_counters { message_multiple => 'All devices are ok' }, { name => 'plugins', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_plugin_output', message_multiple => 'All plugins are ok' }, - { name => 'device_groups', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_device_group_output', - message_multiple => 'All device groups are ok' }, { name => 'templates', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_template_output', message_multiple => 'All templates are ok' }, { name => 'template_sync', type => COUNTER_TYPE_INSTANCE, cb_prefix_output => 'prefix_template_sync_output', @@ -162,9 +160,6 @@ sub set_counters { } ]; - $self->{maps_counters}->{device_groups} = [ - ]; - $self->{maps_counters}->{templates} = [ { label => 'template-devices-count', nlabel => 'template.devices.count', set => { @@ -243,7 +238,6 @@ sub manage_selection { $self->{devices} = {}; $self->{plugins} = {}; - $self->{device_groups} = {}; $self->{templates} = {}; $self->{template_sync} = {};