From 5857f2b3ac62185c820ad2069729056ace3fb8d6 Mon Sep 17 00:00:00 2001
From: garnier-quentin <garnier.quentin@gmail.com>
Date: Tue, 6 Aug 2019 10:54:51 +0200
Subject: [PATCH 1/4] Fix #1608

---
 centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm b/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm
index 725d87902..12e452e91 100644
--- a/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm
+++ b/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm
@@ -102,7 +102,7 @@ sub check_options {
         $self->{option_results}->{ssl_opt} = ['SSL_verify_mode => SSL_VERIFY_NONE'];
         $self->{ssl_opts} = 'SSL_verify_mode => SSL_VERIFY_NONE';
     } else {
-        foreach (keys @{$self->{option_results}->{ssl_opt}}) {
+        foreach (@{$self->{option_results}->{ssl_opt}}) {
             $self->{ssl_opts} .= "$_, ";
         }
     }

From 655a5ed93df01e89f17219af0999ecdb131c7855 Mon Sep 17 00:00:00 2001
From: garnier-quentin <garnier.quentin@gmail.com>
Date: Tue, 6 Aug 2019 13:16:40 +0200
Subject: [PATCH 2/4] add perle ids snmp plugin

---
 .../network/perle/ids/snmp/mode/alarms.pm     | 193 ++++++++++++++++++
 .../perle/ids/snmp/mode/components/psu.pm     |  70 +++++++
 .../ids/snmp/mode/components/resources.pm     |  37 ++++
 .../ids/snmp/mode/components/temperature.pm   |  83 ++++++++
 .../network/perle/ids/snmp/mode/hardware.pm   | 119 +++++++++++
 .../perle/ids/snmp/mode/systemusage.pm        | 125 ++++++++++++
 .../network/perle/ids/snmp/plugin.pm          |  52 +++++
 7 files changed, 679 insertions(+)
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/alarms.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/components/psu.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/components/resources.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/components/temperature.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/hardware.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/mode/systemusage.pm
 create mode 100644 centreon-plugins/network/perle/ids/snmp/plugin.pm

diff --git a/centreon-plugins/network/perle/ids/snmp/mode/alarms.pm b/centreon-plugins/network/perle/ids/snmp/mode/alarms.pm
new file mode 100644
index 000000000..71b7adf74
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/alarms.pm
@@ -0,0 +1,193 @@
+#
+# Copyright 2018 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::perle::ids::snmp::mode::alarms;
+
+use base qw(centreon::plugins::templates::counter);
+
+use strict;
+use warnings;
+use POSIX;
+use centreon::plugins::misc;
+use centreon::plugins::statefile;
+use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
+
+sub custom_status_output {
+    my ($self, %options) = @_;
+    
+    my $msg = sprintf("alarm [severity: %s] [source: %s] [text: %s] %s", $self->{result_values}->{severity},
+        $self->{result_values}->{source}, $self->{result_values}->{text}, $self->{result_values}->{generation_time});
+    return $msg;
+}
+
+sub custom_status_calc {
+    my ($self, %options) = @_;
+    
+    $self->{result_values}->{source} = $options{new_datas}->{$self->{instance} . '_perleEntityAlarmSourceName'};
+    $self->{result_values}->{text} = $options{new_datas}->{$self->{instance} . '_perleEntityAlarmDescr'};
+    $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_perleEntityAlarmSeverity'};
+    $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'};
+    $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_perleEntityAlarmTimeStamp'};
+    return 0;
+}
+
+sub set_counters {
+    my ($self, %options) = @_;
+    
+    $self->{maps_counters_type} = [
+        { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 },
+          group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] 
+        }
+    ];
+    
+    $self->{maps_counters}->{alarm} = [
+        { label => 'status', threshold => 0, set => {
+                key_values => [ { name => 'perleEntityAlarmDescr' }, { name => 'perleEntityAlarmSeverity' }, { name => 'perleEntityAlarmTimeStamp' },
+                    { name => 'since' }, { name => 'perleEntityAlarmSourceName' }, { name => 'perleEntityAlarmType' } ],
+                closure_custom_calc => $self->can('custom_status_calc'),
+                closure_custom_output => $self->can('custom_status_output'),
+                closure_custom_perfdata => sub { return 0; },
+                closure_custom_threshold_check => \&catalog_status_threshold,
+            }
+        },
+    ];
+}
+
+sub new {
+    my ($class, %options) = @_;
+    my $self = $class->SUPER::new(package => __PACKAGE__, %options);
+    bless $self, $class;
+    
+    $options{options}->add_options(arguments => {
+        'filter-msg:s'        => { name => 'filter_msg' },
+        'warning-status:s'    => { name => 'warning_status', default => '%{severity} =~ /minor/i' },
+        'critical-status:s'   => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' },
+        'memory'              => { name => 'memory' },
+    });
+
+    $self->{statefile_cache} = centreon::plugins::statefile->new(%options);
+    return $self;
+}
+
+sub check_options {
+    my ($self, %options) = @_;
+    $self->SUPER::check_options(%options);
+
+    $self->change_macros(macros => ['warning_status', 'critical_status']);
+    if (defined($self->{option_results}->{memory})) {
+        $self->{statefile_cache}->check_options(%options);
+    }
+}
+
+my %map_severity = (
+    1 => 'critical',
+    2 => 'major',
+    3 => 'minor',
+    4 => 'info',
+);
+
+my $mapping = {
+    perleEntityAlarmSourceName  => { oid => '.1.3.6.1.4.1.1966.22.11.1.1.1.3' },
+    perleEntityAlarmSeverity    => { oid => '.1.3.6.1.4.1.1966.22.11.1.1.1.4', map => \%map_severity },
+    perleEntityAlarmDescr       => { oid => '.1.3.6.1.4.1.1966.22.11.1.1.1.5' },
+    perleEntityAlarmTimeStamp   => { oid => '.1.3.6.1.4.1.1966.22.11.1.1.1.6' },
+};
+my $oid_perleEntityAlarmEntry = '.1.3.6.1.4.1.1966.22.11.1.1.1';
+
+sub manage_selection {
+    my ($self, %options) = @_;
+
+    $self->{alarms}->{global} = { alarm => {} };
+    my $snmp_result = $options{snmp}->get_table(
+        oid => $oid_perleEntityAlarmEntry,
+        start => $mapping->{perleEntityAlarmSourceName}->{oid},
+        end => $mapping->{perleEntityAlarmDescr}->{oid}
+    );
+
+    my $last_time;
+    if (defined($self->{option_results}->{memory})) {
+        $self->{statefile_cache}->read(statefile => "cache_perle_ids_" . $options{snmp}->get_hostname()  . '_' . $options{snmp}->get_port(). '_' . $self->{mode});
+        $last_time = $self->{statefile_cache}->get(name => 'last_time');
+    }
+
+    my ($i, $current_time) = (1, time());
+    foreach my $oid (keys %{$snmp_result}) {
+        next if ($oid !~ /^$mapping->{perleEntityAlarmSeverity}->{oid}\.(.*)$/);
+        my $instance = $1;
+        my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
+        
+        my $create_time = $result->{perleEntityAlarmTimeStamp};
+        $result->{perleEntityAlarmTimeStamp} = strftime("%d/%m/%Y %H:%M:%S", localtime($result->{perleEntityAlarmTimeStamp}));
+        if (!defined($create_time)) {
+            $self->{manager}->{output}->output_add(
+                severity => 'UNKNOWN',
+                short_msg => "Can't get date '" . $create_time . "'"
+            );
+            next;
+        }
+        
+        next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time);
+        if (defined($self->{option_results}->{filter_msg}) && $self->{option_results}->{filter_msg} ne '' &&
+            $result->{radwllMilOduAgnLastEventsText} !~ /$self->{option_results}->{perleEntityAlarmDescr}/) {
+            $self->{output}->output_add(long_msg => "skipping '" . $result->{radwllMilOduAgnLastEventsText} . "': no matching filter.", debug => 1);
+            next;
+        }
+        
+        my $diff_time = $current_time - $create_time;
+        $self->{alarms}->{global}->{alarm}->{$i} = { %$result, since => $diff_time };
+        $i++;
+    }
+    
+    if (defined($self->{option_results}->{memory})) {
+        $self->{statefile_cache}->write(data => { last_time => $current_time });
+    }
+}
+        
+1;
+
+__END__
+
+=head1 MODE
+
+Check alarms.
+
+=over 8
+
+=item B<--filter-msg>
+
+Filter by message (can be a regexp).
+
+=item B<--warning-status>
+
+Set warning threshold for status (Default: '%{severity} =~ /minor/i')
+Can used special variables like: %{severity}, %{text}, %{source}, %{since}
+
+=item B<--critical-status>
+
+Set critical threshold for status (Default: '%{severity} =~ /critical|major/i').
+Can used special variables like: %{severity}, %{text}, %{source}, %{since}
+
+=item B<--memory>
+
+Only check new alarms.
+
+=back
+
+=cut
diff --git a/centreon-plugins/network/perle/ids/snmp/mode/components/psu.pm b/centreon-plugins/network/perle/ids/snmp/mode/components/psu.pm
new file mode 100644
index 000000000..fbafdfec8
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/components/psu.pm
@@ -0,0 +1,70 @@
+#
+# Copyright 2019 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::perle::ids::snmp::mode::components::psu;
+
+use strict;
+use warnings;
+use network::perle::ids::snmp::mode::components::resources qw($map_status);
+
+my $mapping = {
+    perleEnvMonPowerSupplyStatusDescr  => { oid => '.1.3.6.1.4.1.1966.22.12.1.1.1.2' },
+    perleEnvMonPowerSupplyState        => { oid => '.1.3.6.1.4.1.1966.22.12.1.1.1.3', map => $map_status },
+};
+my $oid_perleEnvMonPowerSupplyStatusEntry = '.1.3.6.1.4.1.1966.22.12.1.1.1';
+
+sub load {
+    my ($self) = @_;
+    
+    push @{$self->{request}}, {
+        oid => $oid_perleEnvMonPowerSupplyStatusEntry, 
+        start => $mapping->{perleEnvMonPowerSupplyStatusDescr}->{oid},
+        end => $mapping->{perleEnvMonPowerSupplyState}->{oid},
+    };
+}
+
+sub check {
+    my ($self) = @_;
+
+    $self->{output}->output_add(long_msg => "Checking power supplies");
+    $self->{components}->{psu} = { name => 'psu', total => 0, skip => 0 };
+    return if ($self->check_filter(section => 'psu'));
+
+    foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_perleEnvMonPowerSupplyStatusEntry}})) {
+        next if ($oid !~ /^$mapping->{perleEnvMonPowerSupplyState}->{oid}\.(.*)$/);
+        my $instance = $1;
+        my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_perleEnvMonPowerSupplyStatusEntry}, instance => $instance);
+        
+        next if ($self->check_filter(section => 'psu', instance => $instance, name => $result->{perleEnvMonPowerSupplyStatusDescr}));
+        next if ($result->{perleEnvMonPowerSupplyState} =~ /notPresent/i &&
+                 $self->absent_problem(section => 'psu', instance => $instance, name => $result->{perleEnvMonPowerSupplyStatusDescr}));
+        
+        $self->{components}->{psu}->{total}++;
+        $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]",
+                                                        $result->{perleEnvMonPowerSupplyStatusDescr}, $result->{perleEnvMonPowerSupplyState}, $instance));
+        my $exit = $self->get_severity(label => 'default', section => 'psu', name => $result->{perleEnvMonPowerSupplyStatusDescr}, value => $result->{perleEnvMonPowerSupplyState});
+        if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
+            $self->{output}->output_add(severity => $exit,
+                                        short_msg => sprintf("Power supply '%s' status is '%s'", $result->{perleEnvMonPowerSupplyStatusDescr}, $result->{perleEnvMonPowerSupplyState}));
+        }
+    }
+}
+
+1;
diff --git a/centreon-plugins/network/perle/ids/snmp/mode/components/resources.pm b/centreon-plugins/network/perle/ids/snmp/mode/components/resources.pm
new file mode 100644
index 000000000..ea898b0de
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/components/resources.pm
@@ -0,0 +1,37 @@
+#
+# Copyright 2019 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::perle::ids::snmp::mode::components::resources;
+
+use strict;
+use warnings;
+use Exporter;
+
+our $map_status;
+
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw($map_status);
+
+$map_status = {
+    1 => 'normal', 2 => 'warning', 3 => 'critical',
+    4 => 'shutdown', 5 => 'notPresent', 6 => 'notFunctioning',
+};
+
+1;
diff --git a/centreon-plugins/network/perle/ids/snmp/mode/components/temperature.pm b/centreon-plugins/network/perle/ids/snmp/mode/components/temperature.pm
new file mode 100644
index 000000000..166f0c6e1
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/components/temperature.pm
@@ -0,0 +1,83 @@
+#
+# Copyright 2019 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::perle::ids::snmp::mode::components::temperature;
+
+use strict;
+use warnings;
+use network::perle::ids::snmp::mode::components::resources qw($map_status);
+
+my $mapping = {
+    perleEnvMonTemperatureStatusDescr  => { oid => '.1.3.6.1.4.1.1966.22.12.1.2.1.2' },
+    perleEnvMonTemperatureStatusValue  => { oid => '.1.3.6.1.4.1.1966.22.12.1.2.1.3' },
+    perleEnvMonTemperatureState        => { oid => '.1.3.6.1.4.1.1966.22.12.1.2.1.5', map => $map_status },
+};
+my $oid_perleEnvMonTemperatureStatusEntry = '.1.3.6.1.4.1.1966.22.12.1.2.1';
+
+sub load {
+    my ($self) = @_;
+    
+    push @{$self->{request}}, { oid => $oid_perleEnvMonTemperatureStatusEntry };
+}
+
+sub check {
+    my ($self) = @_;
+
+    $self->{output}->output_add(long_msg => "Checking temperatures");
+    $self->{components}->{temperature} = { name => 'temperatures', total => 0, skip => 0 };
+    return if ($self->check_filter(section => 'temperature'));
+
+    my ($exit, $warn, $crit, $checked);
+    foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_perleEnvMonTemperatureStatusEntry}})) {
+        next if ($oid !~ /^$mapping->{perleEnvMonTemperatureState}->{oid}\.(.*)$/);
+        my $instance = $1;
+        my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_perleEnvMonTemperatureStatusEntry}, instance => $instance);
+        
+        next if ($self->check_filter(section => 'temperature', instance => $instance, name => $result->{perleEnvMonTemperatureStatusDescr}));
+        next if ($result->{perleEnvMonTemperatureState} =~ /notPresent/i &&
+                 $self->absent_problem(section => 'temperature', instance => $instance, name => $result->{perleEnvMonTemperatureStatusDescr}));
+        
+        $self->{components}->{temperature}->{total}++;
+        $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, value = %s]",
+                                                        $result->{perleEnvMonTemperatureStatusDescr}, $result->{perleEnvMonTemperatureState}, $instance, 
+                                                        $result->{perleEnvMonTemperatureStatusValue}));
+        $exit = $self->get_severity(label => 'default', section => 'temperature', value => $result->{perleEnvMonTemperatureState});
+        if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
+            $self->{output}->output_add(severity => $exit,
+                                        short_msg => sprintf("Temperature '%s' status is '%s'", $result->{perleEnvMonTemperatureStatusDescr}, $result->{perleEnvMonTemperatureState}));
+        }
+        
+        ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, name => $result->{perleEnvMonTemperatureStatusDescr}, value => $result->{perleEnvMonTemperatureStatusValue});            
+        if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
+            $self->{output}->output_add(severity => $exit,
+                                        short_msg => sprintf("Temperature '%s' is '%s' C", $result->{perleEnvMonTemperatureStatusDescr}, $result->{perleEnvMonTemperatureStatusValue}));
+        }
+        $self->{output}->perfdata_add(
+            label => 'temperature', unit => 'C',
+            nlabel => 'hardware.temperature.celsius',
+            instances => $result->{perleEnvMonTemperatureStatusDescr},
+            value => $result->{perleEnvMonTemperatureStatusValue},
+            warning => $warn,
+            critical => $crit
+        );
+    }
+}
+
+1;
diff --git a/centreon-plugins/network/perle/ids/snmp/mode/hardware.pm b/centreon-plugins/network/perle/ids/snmp/mode/hardware.pm
new file mode 100644
index 000000000..82bbdf105
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/hardware.pm
@@ -0,0 +1,119 @@
+#
+# Copyright 2019 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::perle::ids::snmp::mode::hardware;
+
+use base qw(centreon::plugins::templates::hardware);
+
+use strict;
+use warnings;
+
+sub set_system {
+    my ($self, %options) = @_;
+    
+    $self->{regexp_threshold_overload_check_section_option} = '^(temperature|psu)$';
+    $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$';
+    
+    $self->{cb_hook2} = 'snmp_execute';    
+    $self->{thresholds} = {
+        default => [
+            ['normal', 'OK'],
+            ['warning', 'WARNING'],
+            ['critical', 'CRITICAL'],
+            ['shutdown', 'CRITICAL'],
+            ['notPresent', 'OK'],
+            ['notFunctioning', 'CRITICAL'],
+        ],
+    };
+    
+    $self->{components_path} = 'network::perle::ids::snmp::mode::components';
+    $self->{components_module} = ['temperature', 'psu'];
+}
+
+sub snmp_execute {
+    my ($self, %options) = @_;
+    
+    $self->{snmp} = $options{snmp};
+    $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request});
+}
+
+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 => {});
+    
+    return $self;
+}
+
+1;
+
+__END__
+
+=head1 MODE
+
+Check hardware.
+
+=over 8
+
+=item B<--component>
+
+Which component to check (Default: '.*').
+Can be: 'temperature', 'psu'.
+
+=item B<--add-name-instance>
+
+Add literal description for instance value (used in filter, absent-problem and threshold options).
+
+=item B<--filter>
+
+Exclude some parts (comma seperated list) (Example: --filter=psu)
+Can also exclude specific instance: --filter=psu,1
+
+=item B<--absent-problem>
+
+Return an error if an entity is not 'present' (default is skipping) (comma seperated list)
+Can be specific or global: --absent-problem=psu,1
+
+=item B<--no-component>
+
+Return an error if no compenents are checked.
+If total (with skipped) is 0. (Default: 'critical' returns).
+
+=item B<--threshold-overload>
+
+Set to overload default threshold values (syntax: section,[instance,]status,regexp)
+It used before default thresholds (order stays).
+Example: --threshold-overload='psu,CRITICAL,^(?!(normal|initial)$)'
+
+=item B<--warning>
+
+Set warning threshold for 'temperature' (syntax: type,regexp,threshold)
+Example: --warning='temperature,.*,40'
+
+=item B<--critical>
+
+Set critical threshold for 'temperature' (syntax: type,regexp,threshold)
+Example: --critical='temperature,.*,50'
+
+=back
+
+=cut
diff --git a/centreon-plugins/network/perle/ids/snmp/mode/systemusage.pm b/centreon-plugins/network/perle/ids/snmp/mode/systemusage.pm
new file mode 100644
index 000000000..856859df2
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/mode/systemusage.pm
@@ -0,0 +1,125 @@
+#
+# Copyright 2019 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::perle::ids::snmp::mode::systemusage;
+
+use base qw(centreon::plugins::templates::counter);
+
+use strict;
+use warnings;
+
+sub set_counters {
+    my ($self, %options) = @_;
+    
+    $self->{maps_counters_type} = [
+        { name => 'global', type => 0, message_separator => ' - ' },
+    ];
+    
+    $self->{maps_counters}->{global} = [
+        { label => 'cpu-load', nlabel => 'cpu.utilization.percentage', set => {
+                key_values => [ { name => 'cpu_load' } ],
+                output_template => 'cpu load : %.2f %%',
+                perfdatas => [
+                    { value => 'cpu_load_absolute', template => '%.2f',
+                      min => 0, max => 100, unit => '%' },
+                ],
+            }
+        },
+        { label => 'memory-free', nlabel => 'memory.free.bytes', set => {
+                key_values => [ { name => 'memory_free' } ],
+                output_template => 'memory free : %s %s',
+                output_change_bytes => 1,
+                perfdatas => [
+                    { value => 'memory_free_absolute', template => '%d',
+                      min => 0, unit => 'B' },
+                ],
+            }
+        },
+        { label => 'flashdisk-free', nlabel => 'flashdisk.free.bytes', set => {
+                key_values => [ { name => 'flashdisk_free' } ],
+                output_template => 'flash disk free : %s %s',
+                output_change_bytes => 1,
+                perfdatas => [
+                    { value => 'flashdisk_free_absolute', template => '%d',
+                      min => 0, unit => 'B' },
+                ],
+            }
+        },
+    ];
+}
+
+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 => {});
+   
+    return $self;
+}
+
+sub manage_selection {
+    my ($self, %options) = @_;
+
+    my $oid_perleAverageCPUUtilization = '.1.3.6.1.4.1.1966.22.44.1.24.0';
+    my $oid_perleMemory = '.1.3.6.1.4.1.1966.22.44.1.25.0'; # 295928 Kbytes free
+    my $oid_perleFlashdisk = '.1.3.6.1.4.1.1966.22.44.1.26.0';
+    my $result = $options{snmp}->get_leef(
+        oids => [
+            $oid_perleAverageCPUUtilization, $oid_perleMemory, $oid_perleFlashdisk
+        ],
+        nothing_quit => 1
+    );
+
+    my ($cpu_load, $mem_free, $flashdisk_free);
+    $cpu_load = $1
+        if (defined($result->{$oid_perleAverageCPUUtilization}) && $result->{$oid_perleAverageCPUUtilization} =~ /((?:\d+)(?:\.\d+)?)/);
+    $mem_free = $1 * 1024 if (defined($result->{$oid_perleMemory}) && $result->{$oid_perleMemory} =~ /(\d+)/);
+    $flashdisk_free = $1 * 1024 if (defined($result->{$oid_perleFlashdisk}) && $result->{$oid_perleFlashdisk} =~ /(\d+)/);
+    $self->{global} = { 
+        cpu_load => $cpu_load,
+        memory_free => $mem_free,
+        flashdisk_free => $flashdisk_free,
+    };
+}
+
+1;
+
+__END__
+
+=head1 MODE
+
+Check system usage.
+
+=over 8
+
+=item B<--filter-counters>
+
+Only display some counters (regexp can be used).
+Example: --filter-counters='^memory-free$'
+
+=item B<--warning-*> B<--critical-*>
+
+Thresholds.
+Can be: 'memory-free' (B), 'cpu-load' (%), 'flashdisk-free' (B)
+
+=back
+
+=cut
diff --git a/centreon-plugins/network/perle/ids/snmp/plugin.pm b/centreon-plugins/network/perle/ids/snmp/plugin.pm
new file mode 100644
index 000000000..e131fb9db
--- /dev/null
+++ b/centreon-plugins/network/perle/ids/snmp/plugin.pm
@@ -0,0 +1,52 @@
+#
+# Copyright 2019 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::perle::ids::snmp::plugin;
+
+use strict;
+use warnings;
+use base qw(centreon::plugins::script_snmp);
+
+sub new {
+    my ($class, %options) = @_;
+    my $self = $class->SUPER::new(package => __PACKAGE__, %options);
+    bless $self, $class;
+
+    $self->{version} = '1.0';
+    %{$self->{modes}} = (
+        'alarms'           => 'network::perle::ids::snmp::mode::alarms',
+        'hardware'         => 'network::perle::ids::snmp::mode::hardware',
+        'interfaces'       => 'snmp_standard::mode::interfaces',
+        'list-interfaces'  => 'snmp_standard::mode::listinterfaces',
+        'system-usage'     => 'network::perle::ids::snmp::mode::systemusage',
+    );
+
+    return $self;
+}
+
+1;
+
+__END__
+
+=head1 PLUGIN DESCRIPTION
+
+Check Perle IDS (200, 300, 400) in SNMP.
+
+=cut

From 1c1cd8dd5899bb1eb8d7f16347e9e444b87261e3 Mon Sep 17 00:00:00 2001
From: garnier-quentin <garnier.quentin@gmail.com>
Date: Tue, 6 Aug 2019 15:01:15 +0200
Subject: [PATCH 3/4] add hanwha camera snmp plugin

---
 .../hanwha/snmp/mode/components/sdcard.pm     |  57 ++++++++++
 .../hanwha/snmp/mode/components/service.pm    |  81 ++++++++++++++
 .../camera/hanwha/snmp/mode/hardware.pm       | 100 ++++++++++++++++++
 .../devices/camera/hanwha/snmp/plugin.pm      |  48 +++++++++
 4 files changed, 286 insertions(+)
 create mode 100644 centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/sdcard.pm
 create mode 100644 centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/service.pm
 create mode 100644 centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/hardware.pm
 create mode 100644 centreon-plugins/hardware/devices/camera/hanwha/snmp/plugin.pm

diff --git a/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/sdcard.pm b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/sdcard.pm
new file mode 100644
index 000000000..e9151fb1b
--- /dev/null
+++ b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/sdcard.pm
@@ -0,0 +1,57 @@
+#
+# Copyright 2019 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 hardware::devices::camera::hanwha::snmp::mode::components::sdcard;
+
+use strict;
+use warnings;
+
+my $oid_nwCam = '.1.3.6.1.4.1.36849.1.2';
+
+sub load {}
+
+sub check {
+    my ($self) = @_;
+
+    $self->{output}->output_add(long_msg => "Checking sdcard");
+    $self->{components}->{sdcard} = { name => 'sdcard', total => 0, skip => 0 };
+    return if ($self->check_filter(section => 'sdcard'));
+
+    my $branch_sdcard_status = '4.3.0';
+
+    foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_nwCam}})) {
+        next if ($oid !~ /^$oid_nwCam\.(\d+)\.$branch_sdcard_status$/);
+
+        my $instance = '0';
+        my $sdcard_status = $self->{results}->{$oid_nwCam}->{$oid};
+        next if ($self->check_filter(section => 'sdcard', instance => $instance));
+        
+        $self->{components}->{sdcard}->{total}++;
+        $self->{output}->output_add(long_msg => sprintf("sdcard '%s' status is '%s' [instance = %s]",
+                                                        $instance, $sdcard_status, $instance));
+        my $exit = $self->get_severity(section => 'sdcard', instance => $instance, value => $sdcard_status);
+        if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
+            $self->{output}->output_add(severity => $exit,
+                                        short_msg => sprintf("sdcard '%s' status is '%s'", $instance, $sdcard_status));
+        }
+    }
+}
+
+1;
diff --git a/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/service.pm b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/service.pm
new file mode 100644
index 000000000..f2c680883
--- /dev/null
+++ b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/components/service.pm
@@ -0,0 +1,81 @@
+#
+# Copyright 2019 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 hardware::devices::camera::hanwha::snmp::mode::components::service;
+
+use strict;
+use warnings;
+
+my $services = {
+    '3.1.1.1' => 'alarmInput1',
+    '3.1.2.1' => 'alarmInput2',
+    '3.1.3.1' => 'alarmInput3',
+    '3.1.4.1' => 'alarmInput4',
+    '3.2.1.1' => 'relayOutput1',
+    '3.2.2.1' => 'relayOutput2',
+    '3.2.3.1' => 'relayOutput3',
+    '3.2.4.1' => 'relayOutput4',
+    '3.3.1'   => 'motionDetection',
+    '3.4.1'   => 'videoAnalytics',
+    '3.5.1'   => 'faceDetection',
+    '3.6.1'   => 'networkDisconnection',
+    '3.7.1'   => 'tampering',
+    '3.8.1'   => 'audioDetection',
+    '3.10.1'  => 'defocus',
+    '3.11.1'  => 'fogDetection',
+    '3.12.1'  => 'soundClassification',
+    '3.13.1'  => 'shockDetection',
+    '3.14.1'  => 'temperatureDetection',
+};
+my $oid_nwCam = '.1.3.6.1.4.1.36849.1.2';
+
+sub load {}
+
+sub check {
+    my ($self) = @_;
+
+    $self->{output}->output_add(long_msg => "Checking services");
+    $self->{components}->{service} = { name => 'services', total => 0, skip => 0 };
+    return if ($self->check_filter(section => 'service'));
+
+    foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_nwCam}})) {
+        next if ($oid !~ /^$oid_nwCam\.(\d+)\.(.*?)\.0$/);
+        my ($product_id, $service) = ($1, $2);
+        next if (!defined($services->{$service}));
+
+        my $instance = $services->{$service};
+        my $service_status = $self->{results}->{$oid_nwCam}->{$oid};
+        my $service_date = defined($self->{results}->{$oid_nwCam}->{$oid_nwCam . '.' . $product_id . '.' . $service . '.1'}) ? 
+            $self->{results}->{$oid_nwCam}->{$oid_nwCam . '.' . $product_id . '.' . $service . '.1'} : '-';
+        
+        next if ($self->check_filter(section => 'service', instance => $instance));
+        
+        $self->{components}->{service}->{total}++;
+        $self->{output}->output_add(long_msg => sprintf("service '%s' status is '%s' [instance = %s] [date = %s]",
+                                                        $instance, $service_status, $instance, $service_date));
+        my $exit = $self->get_severity(section => 'service', instance => $instance, value => $service_status);
+        if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
+            $self->{output}->output_add(severity => $exit,
+                                        short_msg => sprintf("service '%s' status is '%s'", $instance, $service_status));
+        }
+    }
+}
+
+1;
diff --git a/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/hardware.pm b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/hardware.pm
new file mode 100644
index 000000000..aec345f0f
--- /dev/null
+++ b/centreon-plugins/hardware/devices/camera/hanwha/snmp/mode/hardware.pm
@@ -0,0 +1,100 @@
+#
+# Copyright 2019 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 hardware::devices::camera::hanwha::snmp::mode::hardware;
+
+use base qw(centreon::plugins::templates::hardware);
+
+use strict;
+use warnings;
+
+sub set_system {
+    my ($self, %options) = @_;
+    
+    $self->{regexp_threshold_overload_check_section_option} = '^service|sdcard$';
+
+    $self->{cb_hook2} = 'snmp_execute';    
+    $self->{thresholds} = {
+        service => [
+            ['low', 'OK'],
+            ['high', 'CRITICAL'],
+        ],
+        sdcard => [
+            ['normal', 'OK'],
+            ['fail', 'CRITICAL'],
+        ],
+    };
+    
+    $self->{components_path} = 'hardware::devices::camera::hanwha::snmp::mode::components';
+    $self->{components_module} = ['service', 'sdcard'];
+}
+
+sub snmp_execute {
+    my ($self, %options) = @_;
+
+    $self->{snmp} = $options{snmp};
+    my $oid_nwCam = '.1.3.6.1.4.1.36849.1.2';
+    $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_nwCam } ]);
+}
+
+sub new {
+    my ($class, %options) = @_;
+    my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, no_performance => 1, no_absent => 1);
+    bless $self, $class;
+    
+    $options{options}->add_options(arguments => {});
+    
+    return $self;
+}
+
+1;
+
+__END__
+
+=head1 MODE
+
+Check hardware.
+
+=over 8
+
+=item B<--component>
+
+Which component to check (Default: '.*').
+Can be: 'service', 'sdcard'.
+
+=item B<--filter>
+
+Exclude some parts (comma seperated list)
+Can also exclude specific instance: --filter=instance,relayOutput1
+
+=item B<--no-component>
+
+Return an error if no compenents are checked.
+If total (with skipped) is 0. (Default: 'critical' returns).
+
+=item B<--threshold-overload>
+
+Set to overload default threshold values (syntax: section,[instance,]status,regexp)
+It used before default thresholds (order stays).
+Example: --threshold-overload='service,relayOutpu1,OK,high'
+
+=back
+
+=cut
diff --git a/centreon-plugins/hardware/devices/camera/hanwha/snmp/plugin.pm b/centreon-plugins/hardware/devices/camera/hanwha/snmp/plugin.pm
new file mode 100644
index 000000000..d2778de8b
--- /dev/null
+++ b/centreon-plugins/hardware/devices/camera/hanwha/snmp/plugin.pm
@@ -0,0 +1,48 @@
+#
+# Copyright 2019 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 hardware::devices::camera::hanwha::snmp::plugin;
+
+use strict;
+use warnings;
+use base qw(centreon::plugins::script_snmp);
+
+sub new {
+    my ($class, %options) = @_;
+    my $self = $class->SUPER::new(package => __PACKAGE__, %options);
+    bless $self, $class;
+
+    $self->{version} = '1.0';
+    %{$self->{modes}} = (
+        'hardware'  => 'hardware::devices::camera::hanwha::snmp::mode::hardware',
+    );
+
+    return $self;
+}
+
+1;
+
+__END__
+
+=head1 PLUGIN DESCRIPTION
+
+Check Hanwha camera in SNMP.
+
+=cut

From 86e5c2ca48867735970c2ea869ec14edc7cb0f15 Mon Sep 17 00:00:00 2001
From: garnier-quentin <garnier.quentin@gmail.com>
Date: Tue, 6 Aug 2019 15:12:50 +0200
Subject: [PATCH 4/4] enhance indent

---
 .../gorgy/ntpserver/snmp/mode/globalstatus.pm | 39 ++++++++++---------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/centreon-plugins/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm b/centreon-plugins/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm
index 061ebbdef..8ce1a958c 100644
--- a/centreon-plugins/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm
+++ b/centreon-plugins/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm
@@ -90,13 +90,12 @@ sub new {
     my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
     bless $self, $class;
     
-    $options{options}->add_options(arguments =>
-                                {
-                                  "warning-sync-status:s"   => { name => 'warning_sync_status', default => '%{sync_status} =~ /Running with autonomy|Free running/i' },
-                                  "critical-sync-status:s"  => { name => 'critical_sync_status', default => '%{sync_status} =~ /Server locked|Never synchronized|Server not synchronized/i' },
-                                  "warning-timebase-status:s"   => { name => 'warning_timebase_status', default => '%{timebase_status} =~ /^(?!(XO|XO OK|TCXO Precision < 2usec|OCXO Precision < 1usec)$)/i' },
-                                  "critical-timebase-status:s"  => { name => 'critical_timebase_status', default => '%{timebase_status} =~ /^XO$/i' },
-                                });
+    $options{options}->add_options(arguments => {
+        'warning-sync-status:s'      => { name => 'warning_sync_status', default => '%{sync_status} =~ /Running with autonomy|Free running/i' },
+        'critical-sync-status:s'     => { name => 'critical_sync_status', default => '%{sync_status} =~ /Server locked|Never synchronized|Server not synchronized/i' },
+        'warning-timebase-status:s'  => { name => 'warning_timebase_status', default => '%{timebase_status} =~ /^(?!(XO|XO OK|TCXO Precision < 2usec|OCXO Precision < 1usec)$)/i' },
+        'critical-timebase-status:s' => { name => 'critical_timebase_status', default => '%{timebase_status} =~ /^XO$/i' },
+    });
     
     return $self;
 }
@@ -140,18 +139,22 @@ my $mapping = {
 sub manage_selection {
     my ($self, %options) = @_;
 
-    my $snmp_result = $options{snmp}->get_leef(oids => [
-                                                    $mapping->{currentSyncState}->{oid} . '.0',
-                                                    $mapping->{timeBaseState}->{oid} . '.0',
-                                                    $mapping->{powerDownFlags}->{oid} . '.0',
-                                                    $mapping->{ntpRequestsNumber}->{oid} . '.0',
-                                               ],
-                                               nothing_quit => 1);
+    my $snmp_result = $options{snmp}->get_leef(
+        oids => [
+            $mapping->{currentSyncState}->{oid} . '.0',
+            $mapping->{timeBaseState}->{oid} . '.0',
+            $mapping->{powerDownFlags}->{oid} . '.0',
+            $mapping->{ntpRequestsNumber}->{oid} . '.0',
+        ],
+        nothing_quit => 1
+    );
     my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0');
-    $self->{global} = { sync_status     => $result->{currentSyncState}, 
-                        timebase_status => $result->{timeBaseState}, 
-                        ntp_requests    => $result->{ntpRequestsNumber} };
-    
+    $self->{global} = {
+        sync_status     => $result->{currentSyncState}, 
+        timebase_status => $result->{timeBaseState}, 
+        ntp_requests    => $result->{ntpRequestsNumber}
+    };
+
     $self->{cache_name} = "gorgy_ntpserver_" . $self->{mode} . '_' . $options{snmp}->get_hostname()  . '_' . $options{snmp}->get_port() . '_' .
         (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
 }