diff --git a/apps/cluster/mscs/local/mode/listnodes.pm b/apps/cluster/mscs/local/mode/listnodes.pm new file mode 100644 index 000000000..28ab65f79 --- /dev/null +++ b/apps/cluster/mscs/local/mode/listnodes.pm @@ -0,0 +1,128 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::listnodes; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Win32::OLE; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'up', + 1 => 'down', + 2 => 'paused', + 3 => 'joining', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{nodes} = {}; + my $query = "Select * from MSCluster_Node"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{nodes}->{$name} = { name => $name, state => $state }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{nodes}}) { + $self->{output}->output_add(long_msg => "'" . $name . "' [state = " . $self->{nodes}->{$name}->{state} . "]"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List Nodes:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(disco => 1); + foreach my $name (sort keys %{$self->{nodes}}) { + $self->{output}->add_disco_entry(name => $name, state => $self->{nodes}->{$name}->{state}); + } +} + +1; + +__END__ + +=head1 MODE + +List nodes. + +=over 8 + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=back + +=cut + \ No newline at end of file diff --git a/apps/cluster/mscs/local/mode/listresources.pm b/apps/cluster/mscs/local/mode/listresources.pm new file mode 100644 index 000000000..504c36e76 --- /dev/null +++ b/apps/cluster/mscs/local/mode/listresources.pm @@ -0,0 +1,148 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::listresources; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Win32::OLE; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'inherited', + 1 => 'initializing', + 2 => 'online', + 3 => 'offline', + 4 => 'failed', + 128 => 'pending', + 129 => 'online pending', + 130 => 'offline pending', +); + +my %map_class = ( + 0 => 'unknown', + 1 => 'storage', + 2 => 'network', + 32768 => 'user', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{resources} = {}; + my $query = "Select * from MSCluster_Resource"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + my $class = $map_class{$obj->{ResourceClass}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{resources}->{$obj->{Id}} = { name => $name, state => $state, owner_node => $obj->{OwnerNode}, + class => $class }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(); + foreach my $id (sort keys %{$self->{resources}}) { + $self->{output}->output_add(long_msg => "'" . $self->{resources}->{$id}->{name} . + "' [state = " . $self->{resources}->{$id}->{state} . "]" . + "[owner node = " . $self->{resources}->{$id}->{owner_node} . "]" . + "[class = " . $self->{resources}->{$id}->{class} . "]"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List Resources:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'state', 'id', 'owner_node', 'class']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(disco => 1); + foreach my $id (sort keys %{$self->{resources}}) { + $self->{output}->add_disco_entry(name => $self->{resources}->{$id}->{name}, + state => $self->{resources}->{$id}->{state}, + id => $id, + owner_node => $self->{resources}->{$id}->{owner_node}, + class => $self->{resources}->{$id}->{class}); + } +} + +1; + +__END__ + +=head1 MODE + +List resources. + +=over 8 + +=item B<--filter-name> + +Filter resource name (can be a regexp). + +=back + +=cut + \ No newline at end of file diff --git a/apps/cluster/mscs/local/mode/networkstatus.pm b/apps/cluster/mscs/local/mode/networkstatus.pm new file mode 100644 index 000000000..594034c4b --- /dev/null +++ b/apps/cluster/mscs/local/mode/networkstatus.pm @@ -0,0 +1,199 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::networkstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Win32::OLE; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'network', type => 1, cb_prefix_output => 'prefix_network_output', message_multiple => 'All networks are ok' } + ]; + + $self->{maps_counters}->{network} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + 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 => $self->can('custom_threshold_output'), + } + }, + ]; +} + +my $instance_mode; + +sub custom_threshold_output { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } elsif (defined($instance_mode->{option_results}->{unknown_status}) && $instance_mode->{option_results}->{unknown_status} ne '' && + eval "$instance_mode->{option_results}->{unknown_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'state : ' . $self->{result_values}->{state}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_network_output { + my ($self, %options) = @_; + + return "Network '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{state} =~ /unknown/' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /down|paritioned|unavailable/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'unknown_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'unavailable', + 1 => 'down', + 2 => 'paritioned', + 3 => 'up', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{network} = {}; + my $query = "Select * from MSCluster_Network"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{network}->{$obj->{ID}} = { display => $name, state => $state }; + } +} + +1; + +__END__ + +=head1 MODE + +Check network status. + +=over 8 + +=item B<--filter-name> + +Filter interface name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Can used special variables like: %{state}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: none). +Can used special variables like: %{state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state} =~ /down|paritioned|unavailable/'). +Can used special variables like: %{state}, %{display} + +=back + +=cut \ No newline at end of file diff --git a/apps/cluster/mscs/local/mode/nodestatus.pm b/apps/cluster/mscs/local/mode/nodestatus.pm new file mode 100644 index 000000000..b8706ce12 --- /dev/null +++ b/apps/cluster/mscs/local/mode/nodestatus.pm @@ -0,0 +1,199 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::nodestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Win32::OLE; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'node', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All nodes are ok' } + ]; + + $self->{maps_counters}->{node} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + 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 => $self->can('custom_threshold_output'), + } + }, + ]; +} + +my $instance_mode; + +sub custom_threshold_output { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } elsif (defined($instance_mode->{option_results}->{unknown_status}) && $instance_mode->{option_results}->{unknown_status} ne '' && + eval "$instance_mode->{option_results}->{unknown_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'state : ' . $self->{result_values}->{state}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{state} =~ /unknown/' }, + "warning-status:s" => { name => 'warning_status', default => '%{state} =~ /pause|joining/' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /down/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'unknown_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'up', + 1 => 'down', + 2 => 'paused', + 3 => 'joining', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{node} = {}; + my $query = "Select * from MSCluster_Node"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{node}->{$name} = { display => $name, state => $state }; + } +} + +1; + +__END__ + +=head1 MODE + +Check node status. + +=over 8 + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Can used special variables like: %{state}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{state} =~ /pause|joining/'). +Can used special variables like: %{state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state} =~ /down/'). +Can used special variables like: %{state}, %{display} + +=back + +=cut \ No newline at end of file diff --git a/apps/cluster/mscs/local/mode/resourcegroupstatus.pm b/apps/cluster/mscs/local/mode/resourcegroupstatus.pm new file mode 100644 index 000000000..b64a9a080 --- /dev/null +++ b/apps/cluster/mscs/local/mode/resourcegroupstatus.pm @@ -0,0 +1,222 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::resourcegroupstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Win32::OLE; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'rg', type => 1, cb_prefix_output => 'prefix_rg_output', message_multiple => 'All resource groups are ok' } + ]; + + $self->{maps_counters}->{rg} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' }, { name => 'owner_node' }, { name => 'preferred_owners' } ], + 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 => $self->can('custom_threshold_output'), + } + }, + ]; +} + +my $instance_mode; +my $instance_current; + +sub is_preferred_node { + if (!defined($instance_current->{result_values}->{preferred_owners}) || + scalar(@{$instance_current->{result_values}->{preferred_owners}}) == 0) { + return 1; + } + + foreach my $pref_node (@{$instance_current->{result_values}->{preferred_owners}}) { + if ($pref_node eq $instance_current->{result_values}->{owner_node}) { + return 1; + } + } + + return 0; +} + +sub custom_threshold_output { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + $instance_current = $self; + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } elsif (defined($instance_mode->{option_results}->{unknown_status}) && $instance_mode->{option_results}->{unknown_status} ne '' && + eval "$instance_mode->{option_results}->{unknown_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'state : ' . $self->{result_values}->{state} . ' [node: ' . $self->{result_values}->{owner_node} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{owner_node} = $options{new_datas}->{$self->{instance} . '_owner_node'}; + $self->{result_values}->{preferred_owners} = $options{new_datas}->{$self->{instance} . '_preferred_owners'}; + return 0; +} + +sub prefix_rg_output { + my ($self, %options) = @_; + + return "Resource group '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{state} =~ /unknown/' }, + "warning-status:s" => { name => 'warning_status', default => 'not is_preferred_node()' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /failed|offline/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'unknown_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'online', + 1 => 'offline', + 2 => 'failed', + 3 => 'partial online', + 4 => 'pending', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{rg} = {}; + my $query = "Select * from MSCluster_ResourceGroup"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + my $preferred_owners = []; + $obj->GetPreferredOwners(\$preferred_owners) if ($obj->can('GetPreferredOwners')); + + $self->{rg}->{$obj->{Id}} = { display => $name, state => $state, owner_node => $obj->{OwnerNode}, + preferred_owners => $preferred_owners }; + } +} + +1; + +__END__ + +=head1 MODE + +Check resource group status. + +=over 8 + +=item B<--filter-name> + +Filter resource group name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Can used special variables like: %{state}, %{display}, %{owner_node} + +=item B<--warning-status> + +Set warning threshold for status (Default: 'not is_preferred_node()'). +Can used special variables like: %{state}, %{display}, %{owner_node} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state} =~ /failed|offline/'). +Can used special variables like: %{state}, %{display}, %{owner_node} + +=back + +=cut \ No newline at end of file diff --git a/apps/cluster/mscs/local/mode/resourcestatus.pm b/apps/cluster/mscs/local/mode/resourcestatus.pm new file mode 100644 index 000000000..1adcb2e44 --- /dev/null +++ b/apps/cluster/mscs/local/mode/resourcestatus.pm @@ -0,0 +1,204 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::mode::resourcestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Win32::OLE; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'resource', type => 1, cb_prefix_output => 'prefix_resource_output', message_multiple => 'All resources are ok' } + ]; + + $self->{maps_counters}->{resource} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' }, { name => 'owner_node' } ], + 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 => $self->can('custom_threshold_output'), + } + }, + ]; +} + +my $instance_mode; + +sub custom_threshold_output { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } elsif (defined($instance_mode->{option_results}->{unknown_status}) && $instance_mode->{option_results}->{unknown_status} ne '' && + eval "$instance_mode->{option_results}->{unknown_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'state : ' . $self->{result_values}->{state} . ' [node: ' . $self->{result_values}->{owner_node} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{owner_node} = $options{new_datas}->{$self->{instance} . '_owner_node'}; + return 0; +} + +sub prefix_resource_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{state} =~ /unknown/' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /failed|offline/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'unknown_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_state = ( + -1 => 'unknown', + 0 => 'inherited', + 1 => 'initializing', + 2 => 'online', + 3 => 'offline', + 4 => 'failed', + 128 => 'pending', + 129 => 'online pending', + 130 => 'offline pending', +); + +sub manage_selection { + my ($self, %options) = @_; + + # winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\mscluster + my $wmi = Win32::OLE->GetObject('winmgmts:root\mscluster'); + if (!defined($wmi)) { + $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); + $self->{output}->option_exit(); + } + + $self->{resource} = {}; + my $query = "Select * from MSCluster_Resource"; + my $resultset = $wmi->ExecQuery($query); + foreach my $obj (in $resultset) { + my $name = $obj->{Name}; + my $state = $map_state{$obj->{State}}; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{resource}->{$obj->{Id}} = { display => $name, state => $state, owner_node => $obj->{OwnerNode} }; + } +} + +1; + +__END__ + +=head1 MODE + +Check resource status. + +=over 8 + +=item B<--filter-name> + +Filter resource name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Can used special variables like: %{state}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: none). +Can used special variables like: %{state}, %{display}, %{owner_node} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state} =~ /failed|offline/'). +Can used special variables like: %{state}, %{display}, %{owner_node} + +=back + +=cut \ No newline at end of file diff --git a/apps/cluster/mscs/local/plugin.pm b/apps/cluster/mscs/local/plugin.pm new file mode 100644 index 000000000..482d7d4c7 --- /dev/null +++ b/apps/cluster/mscs/local/plugin.pm @@ -0,0 +1,53 @@ +# +# Copyright 2016 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 apps::cluster::mscs::local::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'list-nodes' => 'apps::cluster::mscs::local::mode::listnodes', + 'list-resources' => 'apps::cluster::mscs::local::mode::listresources', + 'network-status' => 'apps::cluster::mscs::local::mode::networkstatus', + 'node-status' => 'apps::cluster::mscs::local::mode::nodestatus', + 'resource-status' => 'apps::cluster::mscs::local::mode::resourcestatus', + 'resourcegroup-status' => 'apps::cluster::mscs::local::mode::resourcegroupstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Cluster Service. + +=cut