|
| 1 | +# |
| 2 | +# Copyright 2023 Centreon (http://www.centreon.com/) |
| 3 | +# |
| 4 | +# Centreon is a full-fledged industry-strength solution that meets |
| 5 | +# the needs in IT infrastructure and application monitoring for |
| 6 | +# service performance. |
| 7 | +# |
| 8 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 9 | +# you may not use this file except in compliance with the License. |
| 10 | +# You may obtain a copy of the License at |
| 11 | +# |
| 12 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 13 | +# |
| 14 | +# Unless required by applicable law or agreed to in writing, software |
| 15 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 16 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 17 | +# See the License for the specific language governing permissions and |
| 18 | +# limitations under the License. |
| 19 | +# |
| 20 | + |
| 21 | +package network::aruba::aoscx::snmp::mode::stack; |
| 22 | + |
| 23 | +use base qw(centreon::plugins::templates::counter); |
| 24 | + |
| 25 | +use strict; |
| 26 | +use warnings; |
| 27 | +use Digest::MD5 qw(md5_hex); |
| 28 | +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); |
| 29 | + |
| 30 | +sub custom_member_status_output { |
| 31 | + my ($self, %options) = @_; |
| 32 | + |
| 33 | + my $msg = sprintf( |
| 34 | + 'role: %s [state: %s]', |
| 35 | + $self->{result_values}->{role}, |
| 36 | + $self->{result_values}->{state}, |
| 37 | + ); |
| 38 | + return $msg; |
| 39 | +} |
| 40 | + |
| 41 | +sub custom_member_status_calc { |
| 42 | + my ($self, %options) = @_; |
| 43 | + |
| 44 | + $self->{result_values}->{roleLast} = $options{old_datas}->{$self->{instance} . '_role'}; |
| 45 | + $self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'}; |
| 46 | + |
| 47 | + $self->{result_values}->{stateLast} = $options{old_datas}->{$self->{instance} . '_state'}; |
| 48 | + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; |
| 49 | + if (!defined($options{old_datas}->{$self->{instance} . '_role'})) { |
| 50 | + $self->{error_msg} = "buffer creation"; |
| 51 | + return -2; |
| 52 | + } |
| 53 | + |
| 54 | + return 0; |
| 55 | +} |
| 56 | + |
| 57 | +sub custom_port_status_output { |
| 58 | + my ($self, %options) = @_; |
| 59 | + |
| 60 | + my $msg = sprintf( |
| 61 | + 'operational status: %s [admin status: %s]', |
| 62 | + $self->{result_values}->{oper_status}, |
| 63 | + $self->{result_values}->{admin_status} |
| 64 | + ); |
| 65 | + return $msg; |
| 66 | +} |
| 67 | + |
| 68 | +sub set_counters { |
| 69 | + my ($self, %options) = @_; |
| 70 | + |
| 71 | + $self->{maps_counters_type} = [ |
| 72 | + { name => 'member', |
| 73 | + type => 3, |
| 74 | + cb_prefix_output => 'prefix_member_output', |
| 75 | + cb_long_output => 'member_long_output', |
| 76 | + indent_long_output => ' ', |
| 77 | + message_multiple => 'All stack members are ok', |
| 78 | + group => |
| 79 | + [ |
| 80 | + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, |
| 81 | + { name => 'port', |
| 82 | + display_long => 1, |
| 83 | + cb_prefix_output => 'prefix_port_output', |
| 84 | + message_multiple => 'All ports are ok', |
| 85 | + type => 1, |
| 86 | + skipped_code => { -10 => 1 } }, |
| 87 | + ] |
| 88 | + } |
| 89 | + ]; |
| 90 | + |
| 91 | + $self->{maps_counters}->{global} = [ |
| 92 | + { label => 'member-status', threshold => 0, set => { |
| 93 | + key_values => [ { name => 'role' }, { name => 'display' }, { name => 'state'} ], |
| 94 | + closure_custom_calc => $self->can('custom_member_status_calc'), |
| 95 | + closure_custom_output => $self->can('custom_member_status_output'), |
| 96 | + closure_custom_perfdata => sub {return 0;}, |
| 97 | + closure_custom_threshold_check => \&catalog_status_threshold, |
| 98 | + } |
| 99 | + }, |
| 100 | + ]; |
| 101 | + |
| 102 | + $self->{maps_counters}->{port} = [ |
| 103 | + { label => 'port-status', threshold => 0, set => { |
| 104 | + key_values => |
| 105 | + [ { name => 'oper_status' }, { name => 'admin_status' }, { name => 'display' } ], |
| 106 | + closure_custom_calc => \&catalog_status_calc, |
| 107 | + closure_custom_output => $self->can('custom_port_status_output'), |
| 108 | + closure_custom_perfdata => sub {return 0;}, |
| 109 | + closure_custom_threshold_check => \&catalog_status_threshold, |
| 110 | + } |
| 111 | + }, |
| 112 | + ]; |
| 113 | +} |
| 114 | + |
| 115 | +sub member_long_output { |
| 116 | + my ($self, %options) = @_; |
| 117 | + |
| 118 | + return "checking stack member '" . $options{instance_value}->{display} . "'"; |
| 119 | +} |
| 120 | + |
| 121 | +sub prefix_member_output { |
| 122 | + my ($self, %options) = @_; |
| 123 | + |
| 124 | + return "Stack member '" . $options{instance_value}->{display} . "' "; |
| 125 | +} |
| 126 | + |
| 127 | +sub prefix_port_output { |
| 128 | + my ($self, %options) = @_; |
| 129 | + |
| 130 | + return "port '" . $options{instance_value}->{display} . "' "; |
| 131 | +} |
| 132 | + |
| 133 | +sub new { |
| 134 | + my ($class, %options) = @_; |
| 135 | + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); |
| 136 | + bless $self, $class; |
| 137 | + |
| 138 | + $options{options}->add_options(arguments => { |
| 139 | + 'unknown-member-status:s' => { name => 'unknown_member_status', default => '' }, |
| 140 | + 'warning-member-status:s' => { name => 'warning_member_status', default => '' }, |
| 141 | + 'critical-member-status:s' => { name => 'critical_member_status', default => '%{role} ne %{roleLast}' }, |
| 142 | + 'unknown-port-status:s' => { name => 'unknown_port_status', default => '' }, |
| 143 | + 'warning-port-status:s' => { name => 'warning_port_status', default => '' }, |
| 144 | + 'critical-port-status:s' => { |
| 145 | + name => 'critical_port_status', |
| 146 | + default => '%{admin_status} eq "up" and %{oper_status} ne "up"' |
| 147 | + }, |
| 148 | + }); |
| 149 | + |
| 150 | + return $self; |
| 151 | +} |
| 152 | + |
| 153 | +sub check_options { |
| 154 | + my ($self, %options) = @_; |
| 155 | + $self->SUPER::check_options(%options); |
| 156 | + |
| 157 | + $self->change_macros( |
| 158 | + macros => [ |
| 159 | + 'unknown_member_status', 'warning_member_status', 'critical_member_status', |
| 160 | + 'unknown_port_status', 'warning_port_status', 'critical_port_status' |
| 161 | + ] |
| 162 | + ); |
| 163 | +} |
| 164 | + |
| 165 | +my $map_member_state = { |
| 166 | + 0 => 'unusedId', |
| 167 | + 1 => 'missing', |
| 168 | + 2 => 'provision', |
| 169 | + 3 => 'commander', |
| 170 | + 4 => 'standby', |
| 171 | + 5 => 'member', |
| 172 | + 6 => 'shutdown', |
| 173 | + 7 => 'booting', |
| 174 | + 8 => 'communicationFailure', |
| 175 | + 9 => 'incompatibleOs', |
| 176 | + 10 => 'unknownState', |
| 177 | + 11 => 'standbyBooting' |
| 178 | +}; |
| 179 | +my $map_member_role_status = { |
| 180 | + 1 => 'active', |
| 181 | + 2 => 'notInService', |
| 182 | + 3 => 'notReady', |
| 183 | + 4 => 'createAndGo', |
| 184 | + 5 => 'createAndWait', |
| 185 | + 6 => 'destroy' |
| 186 | +}; |
| 187 | +my $map_port_admin_status = { |
| 188 | + 1 => 'enabled', |
| 189 | + 2 => 'disabled' |
| 190 | +}; |
| 191 | +my $map_port_operation_status = { |
| 192 | + 1 => 'up', |
| 193 | + 2 => 'down', |
| 194 | + 3 => 'disabled', |
| 195 | + 4 => 'blocked' |
| 196 | +}; |
| 197 | + |
| 198 | +my $mapping_member_table = { |
| 199 | + stackMemberSerialNum => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.14' }, |
| 200 | + stackMemberRoleStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.7', map => $map_member_role_status }, |
| 201 | + stackMemberState => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.9', map => $map_member_state }, |
| 202 | +}; |
| 203 | +my $mapping_port_table = { |
| 204 | + stackPortAdminStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1.8', map => $map_port_admin_status }, |
| 205 | + stackPortOperStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1.3', map => $map_port_operation_status } |
| 206 | +}; |
| 207 | + |
| 208 | +my $oid_memberTableEntry = '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1'; |
| 209 | +my $oid_portTableEntry = '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1'; |
| 210 | + |
| 211 | +sub manage_selection { |
| 212 | + my ($self, %options) = @_; |
| 213 | + |
| 214 | + $self->{member} = {}; |
| 215 | + my $snmp_result = $options{snmp}->get_multiple_table( |
| 216 | + oids => [ |
| 217 | + { oid => $oid_memberTableEntry }, |
| 218 | + { oid => $mapping_member_table->{stackMemberSerialNum}->{oid} }, |
| 219 | + { oid => $mapping_member_table->{stackMemberRoleStatus}->{oid} }, |
| 220 | + { oid => $mapping_member_table->{stackMemberState}->{oid} } |
| 221 | + , |
| 222 | + { oid => $oid_portTableEntry }, |
| 223 | + { oid => $mapping_port_table->{stackPortAdminStatus}->{oid} }, |
| 224 | + { oid => $mapping_port_table->{stackPortOperStatus}->{oid} }, |
| 225 | + , |
| 226 | + ], |
| 227 | + nothing_quit => 1 |
| 228 | + ); |
| 229 | + |
| 230 | + foreach my $oid (keys %{$snmp_result->{$oid_memberTableEntry}}) { |
| 231 | + next if ($oid !~ /^$mapping_member_table->{stackMemberRoleStatus}->{oid}\.(.*)$/); |
| 232 | + my $instance_id = $1; |
| 233 | + my $result = $options{snmp}->map_instance( |
| 234 | + mapping => $mapping_member_table, |
| 235 | + results => $snmp_result->{$oid_memberTableEntry}, |
| 236 | + instance => $instance_id); |
| 237 | + |
| 238 | + $self->{member}->{$result->{stackMemberSerialNum}} = { |
| 239 | + display => $result->{stackMemberSerialNum}, |
| 240 | + global => { |
| 241 | + display => $result->{stackMemberSerialNum}, |
| 242 | + role => $result->{stackMemberRoleStatus}, |
| 243 | + state => $result->{stackMemberState}, |
| 244 | + }, |
| 245 | + port => {}, |
| 246 | + }; |
| 247 | + |
| 248 | + foreach (keys %{$snmp_result->{$oid_portTableEntry}}) { |
| 249 | + next if (!/^$mapping_port_table->{stackPortOperStatus}->{oid}\.$instance_id\.(.*?)\.(.*)$/); |
| 250 | + my $port_name = $1; |
| 251 | + my $result2 = $options{snmp}->map_instance( |
| 252 | + mapping => $mapping_port_table, |
| 253 | + results => $snmp_result->{$oid_portTableEntry}, |
| 254 | + instance => $instance_id . '.' . $port_name . '.1'); |
| 255 | + |
| 256 | + $self->{member}->{$result->{stackMemberSerialNum}}->{port}->{$port_name} = { |
| 257 | + display => $port_name, |
| 258 | + admin_status => $result2->{stackPortAdminStatus}, |
| 259 | + oper_status => $result2->{stackPortOperStatus}, |
| 260 | + }; |
| 261 | + } |
| 262 | + } |
| 263 | + |
| 264 | + $self->{cache_name} = "aruba_aoscx_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . |
| 265 | + (defined($self->{option_results}->{filter_counters}) ? |
| 266 | + md5_hex($self->{option_results}->{filter_counters}) : |
| 267 | + md5_hex('all')); |
| 268 | +} |
| 269 | + |
| 270 | +1; |
| 271 | + |
| 272 | +__END__ |
| 273 | +
|
| 274 | +=head1 MODE |
| 275 | +
|
| 276 | +Check stack members. |
| 277 | +
|
| 278 | +=over 8 |
| 279 | +
|
| 280 | +=item B<--unknown-member-status> |
| 281 | +
|
| 282 | +Define the conditions to match for the status to be UNKNOWN (Default: ''). |
| 283 | +You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast} |
| 284 | +
|
| 285 | +=item B<--warning-member-status> |
| 286 | +
|
| 287 | +Define the conditions to match for the status to be WARNING (Default: ''). |
| 288 | +You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast} |
| 289 | +
|
| 290 | +=item B<--critical-member-status> |
| 291 | +
|
| 292 | +Define the conditions to match for the status to be CRITICAL (Default: '%{role} ne %{roleLast}'). |
| 293 | +You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast} |
| 294 | +
|
| 295 | +=item B<--unknown-port-status> |
| 296 | +
|
| 297 | +Define the conditions to match for the status to be UNKNOWN (Default: ''). |
| 298 | +You can use the following variables: %{admin_status}, %{oper_status}, %{display} |
| 299 | +
|
| 300 | +=item B<--warning-port-status> |
| 301 | +
|
| 302 | +Define the conditions to match for the status to be WARNING (Default: ''). |
| 303 | +You can use the following variables: %{admin_status}, %{oper_status}, %{display} |
| 304 | +
|
| 305 | +=item B<--critical-port-status> |
| 306 | +
|
| 307 | +Define the conditions to match for the status to be CRITICAL (Default: '%{admin_status} eq "up" and %{oper_status} ne "up"'). |
| 308 | +You can use the following variables: %{admin_status}, %{oper_status}, %{display} |
| 309 | +
|
| 310 | +=back |
| 311 | +
|
| 312 | +=cut |
0 commit comments