diff --git a/cloud/docker/custom/dockerapi.pm b/cloud/docker/custom/dockerapi.pm new file mode 100644 index 000000000..15df49d8b --- /dev/null +++ b/cloud/docker/custom/dockerapi.pm @@ -0,0 +1,218 @@ +# +# 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 cloud::docker::custom::dockerapi; + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::http; +use JSON; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { + "hostname:s" => { name => 'hostname' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "proxyurl:s" => { name => 'proxyurl' }, + "proxypac:s" => { name => 'proxypac' }, + "timeout:s" => { name => 'timeout' }, + "ssl:s" => { name => 'ssl' }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(output => $self->{output}); + + return $self; + +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "You need to specify --hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{proto}) || $self->{option_results}->{proto} eq '') { + $self->{output}->add_option_msg(short_msg => "You need to specify --proto option."); + $self->{output}->option_exit(); + } + +} + +sub api_request { + my ($self, %options) = @_; + + $self->{option_results}->{url_path} = $options{urlpath}; + $self->{option_results}->{port} = $options{port}; + $self->{method} = 'GET'; + $self->{option_results}->{get_param} = []; + push @{$self->{option_results}->{get_param}}, "all=true", "stream=false"; + + $self->{http}->set_options(%{$self->{option_results}}); + + my $webcontent; + my $jsoncontent = $self->{http}->request(method => $self->{method}); + + my $json = JSON->new; + + eval { + $webcontent = $json->decode($jsoncontent); + }; + + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot retrieve any information"); + $self->{output}->option_exit(); + } + + return $webcontent; +} + +1; + +__END__ + +=head1 NAME + +Docker REST API + +=head1 SYNOPSIS + +Docker Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +IP Addr/FQDN of the webserver host + +=item B<--proto> + +Specify https if needed (Default: 'http') + +=item B<--credentials> + +Specify this option if you access webpage over basic authentification + +=item B<--username> + +Specify username for basic authentification (Mandatory if --credentials is specidied) + +=item B<--password> + +Specify password for basic authentification (Mandatory if --credentials is specidied) + +=item B<--proxyurl> + +Proxy URL + +=item B<--proxypac> + +Proxy pac file (can be an url or local file) + +=item B<--timeout> + +Threshold for HTTP timeout (Default: 5) + +=item B<--ssl> + +Specify SSL version (example : 'sslv3', 'tlsv1'...) + +=item B<--cert-file> + +Specify certificate to send to the webserver + +=item B<--key-file> + +Specify key to send to the webserver + +=item B<--cacert-file> + +Specify root certificate to send to the webserver + +=item B<--cert-pwd> + +Specify certificate's password + +=item B<--cert-pkcs12> + +Specify type of certificate (PKCS12) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/cloud/docker/mode/blockio.pm b/cloud/docker/mode/blockio.pm index b21a6446f..566308002 100644 --- a/cloud/docker/mode/blockio.pm +++ b/cloud/docker/mode/blockio.pm @@ -24,40 +24,29 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; use centreon::plugins::statefile; -use JSON; +use centreon::plugins::http; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, + "port:s" => { name => 'port' }, "name:s" => { name => 'name' }, "id:s" => { name => 'id' }, "warning-read:s" => { name => 'warning-read' }, "critical-read:s" => { name => 'critical-read' }, "warning-write:s" => { name => 'warning-write' }, "critical-write:s" => { name => 'critical-write' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, }); $self->{statefile_value} = centreon::plugins::statefile->new(%options); $self->{http} = centreon::plugins::http->new(output => $self->{output}); + return $self; } @@ -90,14 +79,6 @@ sub check_options { $self->{output}->option_exit(); } - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "stream=false"; - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/stats"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/stats"; - } - $self->{http}->set_options(%{$self->{option_results}}); $self->{statefile_value}->check_options(%options); } @@ -113,20 +94,17 @@ sub run { $self->{statefile_value}->read(statefile => 'docker_' . $self->{option_results}->{name} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); } - my $jsoncontent = $self->{http}->request(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/stats"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/stats"; + } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my $read_bytes = $webcontent->{blkio_stats}->{io_service_bytes_recursive}->[0]->{value}; my $write_bytes = $webcontent->{blkio_stats}->{io_service_bytes_recursive}->[1]->{value}; @@ -204,23 +182,11 @@ __END__ Check Container's Block I/O usage -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -230,6 +196,8 @@ Specify one container's id Specify one container's name +=head2 MODE OPTIONS + =item B<--warning-read> Threshold warning in B/s for Read I/O. @@ -246,38 +214,6 @@ Threshold warning in B/s for Write I/O. Threshold critical in B/s for Write I/O. -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - =back =cut diff --git a/cloud/docker/mode/containerstate.pm b/cloud/docker/mode/containerstate.pm index 8d38e896c..05007f6bf 100644 --- a/cloud/docker/mode/containerstate.pm +++ b/cloud/docker/mode/containerstate.pm @@ -24,8 +24,6 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; -use JSON; my $thresholds = { state => [ @@ -43,27 +41,15 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, + "port:s" => { name => 'port' }, "name:s" => { name => 'name' }, "id:s" => { name => 'id' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, "threshold-overload:s@" => { name => 'threshold_overload' }, }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); return $self; } @@ -95,18 +81,6 @@ sub check_options { $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; } - - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/json"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/json"; - } else { - $self->{option_results}->{url_path} = "/containers/json"; - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "all=true"; - } - $self->{http}->set_options(%{$self->{option_results}}); - } sub get_severity { @@ -133,20 +107,17 @@ sub get_severity { sub run { my ($self, %options) = @_; - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/json"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/json"; } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; + + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my ($result,$containername,$containertime); my $exit = 'OK'; @@ -228,23 +199,11 @@ __END__ Check Container's state -=over 8 +=head2 DOCKER OPTIONS -=item B<--hostname> +item B<--port> -IP Addr/FQDN of Docker's API - -=item B<--port> - -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -254,37 +213,7 @@ Specify one container's id Specify one container's name -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) +=head2 MODE OPTIONS =item B<--threshold-overload> diff --git a/cloud/docker/mode/cpu.pm b/cloud/docker/mode/cpu.pm index b0f3d1f9e..17ad4c315 100644 --- a/cloud/docker/mode/cpu.pm +++ b/cloud/docker/mode/cpu.pm @@ -24,34 +24,22 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; use centreon::plugins::statefile; -use JSON; +use centreon::plugins::http; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, - "name:s" => { name => 'name' }, - "id:s" => { name => 'id' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, + "port:s" => { name => 'port' }, + "name:s" => { name => 'name' }, + "id:s" => { name => 'id' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, }); $self->{statefile_value} = centreon::plugins::statefile->new(%options); @@ -84,14 +72,6 @@ sub check_options { $self->{output}->option_exit(); } - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "stream=false"; - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/stats"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/stats"; - } - $self->{http}->set_options(%{$self->{option_results}}); $self->{statefile_value}->check_options(%options); } @@ -105,32 +85,32 @@ sub run { $self->{statefile_value}->read(statefile => 'docker_' . $self->{option_results}->{name} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); } - my $jsoncontent = $self->{http}->request(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/stats"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/stats"; + } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my $cpu_totalusage = $webcontent->{cpu_stats}->{cpu_usage}->{total_usage}; my $cpu_systemusage = $webcontent->{cpu_stats}->{system_cpu_usage}; my @cpu_number = @{$webcontent->{cpu_stats}->{cpu_usage}->{percpu_usage}}; + my $cpu_throttledtime = $webcontent->{cpu_stats}->{throttling_data}->{throttled_time}; my $new_datas = {}; $new_datas->{cpu_totalusage} = $cpu_totalusage; $new_datas->{cpu_systemusage} = $cpu_systemusage; + $new_datas->{cpu_throttledtime} = $cpu_throttledtime; my $old_cpu_totalusage = $self->{statefile_value}->get(name => 'cpu_totalusage'); my $old_cpu_systemusage = $self->{statefile_value}->get(name => 'cpu_systemusage'); + my $old_cpu_throttledtime = $self->{statefile_value}->get(name => 'cpu_throttledtime'); - if ((!defined($old_cpu_totalusage)) || (!defined($old_cpu_systemusage))) { + if ((!defined($old_cpu_totalusage)) || (!defined($old_cpu_systemusage)) || (!defined($old_cpu_throttledtime))) { $self->{output}->output_add(severity => 'OK', short_msg => "Buffer creation..."); $self->{statefile_value}->write(data => $new_datas); @@ -147,22 +127,35 @@ sub run { $old_cpu_systemusage = 0; } + if ($new_datas->{cpu_throttledtime} < $old_cpu_throttledtime) { + # We set 0. Has reboot. + $old_cpu_throttledtime = 0; + } + my $delta_totalusage = $cpu_totalusage - $old_cpu_totalusage; my $delta_systemusage = $cpu_systemusage - $old_cpu_systemusage; + my $delta_throttledtime = $cpu_throttledtime - $old_cpu_throttledtime; + # Nano second to second + my $throttledtime = $delta_throttledtime / 10 ** 9; my $prct_cpu = (($delta_totalusage / $delta_systemusage) * scalar(@cpu_number)) * 100; my $exit = $self->{perfdata}->threshold_check(value => $prct_cpu, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit, - short_msg => sprintf("CPU Usage is %.2f%%", $prct_cpu)); + short_msg => sprintf("CPU Usage is %.2f%% (Throttled Time: %.3fs)", $prct_cpu, $throttledtime)); $self->{output}->perfdata_add(label => "cpu", unit => '%', - value => $prct_cpu, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, - max => 100, - ); + value => $prct_cpu, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, + max => 100, + ); + $self->{output}->perfdata_add(label => "throttled", unit => 's', + value => $throttledtime, + min => 0, + ); + $self->{statefile_value}->write(data => $new_datas); @@ -179,23 +172,11 @@ __END__ Check Container's CPU usage -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -205,6 +186,8 @@ Specify one container's id Specify one container's name +=head2 MODE OPTIONS + =item B<--warning> Threshold warning in percent. @@ -213,38 +196,6 @@ Threshold warning in percent. Threshold critical in percent. -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - =back =cut diff --git a/cloud/docker/mode/image.pm b/cloud/docker/mode/image.pm index 0c257213e..7ea69365a 100644 --- a/cloud/docker/mode/image.pm +++ b/cloud/docker/mode/image.pm @@ -32,13 +32,10 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, + "port:s" => { name => 'port' }, "name:s" => { name => 'name' }, "id:s" => { name => 'id' }, "image:s" => { name => 'image' }, @@ -88,32 +85,25 @@ sub check_options { $self->{output}->option_exit(); } - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/json"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/json"; - } - $self->{http}->set_options(%{$self->{option_results}}); } sub run { my ($self, %options) = @_; - my ($jsoncontent,$jsoncontent2, $webcontent, $webcontent2); + my ($jsoncontent, $webcontent, $webcontent2); - $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/stats"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/stats"; } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; + + $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my $container_id = $webcontent->{Image}; @@ -123,12 +113,12 @@ sub run { $self->{option_results}->{hostname} = $self->{option_results}->{registry_hostname}; $self->{http}->set_options(%{$self->{option_results}}); - $jsoncontent2 = $self->{http}->request(); + $jsoncontent = $self->{http}->request(); my $json2 = JSON->new; eval { - $webcontent2 = $json2->decode($jsoncontent2); + $webcontent2 = $json2->decode($jsoncontent); }; if ($@) { @@ -166,23 +156,11 @@ __END__ Check Container's image viability with a registry -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -192,6 +170,8 @@ Specify the container's id Specify the container's name +=head2 MODE OPTIONS + =item B<--image> Specify the image's name diff --git a/cloud/docker/mode/info.pm b/cloud/docker/mode/info.pm index 16d84779e..e6dd0f1e4 100644 --- a/cloud/docker/mode/info.pm +++ b/cloud/docker/mode/info.pm @@ -25,62 +25,37 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use centreon::plugins::http; -use JSON; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/info' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, + "port:s" => { name => 'port' } }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); return $self; } sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - - $self->{http}->set_options(%{$self->{option_results}}); } sub run { my ($self, %options) = @_; + my $urlpath = "/info"; + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; - my $jsoncontent = $self->{http}->request();; + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } - - - $self->{output}->output_add(severity => 'OK', + $self->{output}->output_add(severity => 'OK', short_msg => sprintf("Docker is running")); $self->{output}->perfdata_add(label => "containers", @@ -122,55 +97,11 @@ __END__ Check Docker information -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker information (Default: '/') - -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) +Port used by Docker =back diff --git a/cloud/docker/mode/listcontainers.pm b/cloud/docker/mode/listcontainers.pm index e96baaf62..01c096b1a 100644 --- a/cloud/docker/mode/listcontainers.pm +++ b/cloud/docker/mode/listcontainers.pm @@ -24,46 +24,27 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; -use JSON; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.1'; + $self->{version} = '1.2'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "exclude:s" => { name => 'exclude' }, - "timeout:s" => { name => 'timeout' }, + "port:s" => { name => 'port' }, + "exclude:s" => { name => 'exclude' }, }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); $self->{container_infos} = (); + return $self; } sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - - $self->{option_results}->{url_path} = $self->{option_results}->{url_path}."containers/json"; - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "all=true"; - - $self->{http}->set_options(%{$self->{option_results}}) } sub check_exclude { @@ -76,23 +57,15 @@ sub check_exclude { return 0; } -sub api_request { +sub listcontainer_request { my ($self, %options) = @_; - my $jsoncontent = $self->{http}->request(); + my $urlpath = "/containers/json"; + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); foreach my $val (@$webcontent) { my $containerstate; @@ -124,7 +97,7 @@ sub disco_format { sub disco_show { my ($self, %options) = @_; - $self->api_request(); + $self->listcontainer_request(%options); foreach my $containername (keys %{$self->{container_infos}}) { $self->{output}->add_disco_entry(name => $containername, @@ -138,7 +111,7 @@ sub disco_show { sub run { my ($self, %options) = @_; - $self->api_request(); + $self->listcontainer_request(%options); foreach my $containername (keys %{$self->{container_infos}}) { $self->{output}->output_add(long_msg => sprintf("%s [id = %s , image = %s, state = %s]", @@ -164,60 +137,18 @@ __END__ List Docker containers -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') +Port used by Docker -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker containers (Default: '/') - -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver +=head2 MODE OPTIONS =item B<--exlude> Exclude specific container's state (comma seperated list) (Example: --exclude=Paused,Running) -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - =back =cut diff --git a/cloud/docker/mode/listnodes.pm b/cloud/docker/mode/listnodes.pm new file mode 100644 index 000000000..caa9f22e5 --- /dev/null +++ b/cloud/docker/mode/listnodes.pm @@ -0,0 +1,154 @@ +# +# 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 cloud::docker::mode::listnodes; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +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 => + { + "port:s" => { name => 'port' }, + "exclude:s" => { name => 'exclude' }, + }); + + $self->{node_infos} = (); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub check_exclude { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{status}}(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping ${options{status}} nodes.")); + return 1; + } +return 0; +} + +sub listnode_request { + my ($self, %options) = @_; + + my $urlpath = "/nodes"; + my $port = $self->{option_results}->{port}; + + my $nodeapi = $options{custom}; + my $webcontent = $nodeapi->api_request(urlpath => $urlpath, + port => $port); + + foreach my $val (@$webcontent) { + next if ($self->check_exclude(status => $val->{Status}->{State})); + my $nodeid = $val->{ID}; + $self->{node_infos}->{$nodeid}->{hostname} = $val->{Description}->{Hostname}; + $self->{node_infos}->{$nodeid}->{role} = $val->{Spec}->{Role}; + $self->{node_infos}->{$nodeid}->{availability} = $val->{Spec}->{Availability}; + $self->{node_infos}->{$nodeid}->{state} = $val->{Status}->{State}; + if ($val->{Spec}->{Role} eq 'manager') { + $self->{node_infos}->{$nodeid}->{reachability} = $val->{ManagerStatus}->{Reachability}; + } else { + $self->{node_infos}->{$nodeid}->{reachability} = ''; + } + + } +} + +sub disco_format { + my ($self, %options) = @_; + + my $names = ['id', 'hostname', 'role', 'state', 'availability', 'reachability']; + $self->{output}->add_disco_format(elements => $names); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->listnode_request(%options); + + foreach my $nodeid (keys %{$self->{node_infos}}) { + $self->{output}->add_disco_entry(id => $nodeid, + hostname => $self->{node_infos}->{$nodeid}->{hostname}, + role => $self->{node_infos}->{$nodeid}->{role}, + state => $self->{node_infos}->{$nodeid}->{state}, + availability => $self->{node_infos}->{$nodeid}->{availability}, + reachability => $self->{node_infos}->{$nodeid}->{reachability}, + ); + } +} + +sub run { + my ($self, %options) = @_; + + $self->listnode_request(%options); + + foreach my $nodeid (keys %{$self->{node_infos}}) { + $self->{output}->output_add(long_msg => sprintf("%s [hostname = %s , role = %s, state = %s, availability = %s, reachability = %s]", + $nodeid, + $self->{node_infos}->{$nodeid}->{hostname}, + $self->{node_infos}->{$nodeid}->{role}, + $self->{node_infos}->{$nodeid}->{state}, + $self->{node_infos}->{$nodeid}->{availability}, + $self->{node_infos}->{$nodeid}->{reachability})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List Swarm nodes:'); + + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + + exit 0; +} + +1; + +__END__ + +=head1 MODE + +List Docker Swarm nodes + +=head2 DOCKER OPTIONS + +=item B<--port> + +Port used by Docker + +=head2 MODE OPTIONS + +=item B<--exlude> + +Exclude specific node's state (comma seperated list) (Example: --exclude=disconnected) + +=back + +=cut diff --git a/cloud/docker/mode/memory.pm b/cloud/docker/mode/memory.pm index f4300210a..8ede73677 100644 --- a/cloud/docker/mode/memory.pm +++ b/cloud/docker/mode/memory.pm @@ -24,33 +24,20 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; -use JSON; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, - "name:s" => { name => 'name' }, - "id:s" => { name => 'id' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, + "port:s" => { name => 'port' }, + "name:s" => { name => 'name' }, + "id:s" => { name => 'id' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, }); return $self; @@ -79,61 +66,72 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } - - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "stream=false"; - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/stats"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/stats"; - } - - $self->{http}->set_options(%{$self->{option_results}}); } sub run { my ($self, %options) = @_; - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/stats"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/stats"; } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; + + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my $total_size = $webcontent->{memory_stats}->{limit}; my $memory_used = $webcontent->{memory_stats}->{usage}; my $memory_free = $webcontent->{memory_stats}->{limit} - $webcontent->{memory_stats}->{usage}; my $prct_used = $memory_used * 100 / $total_size; my $prct_free = 100 - $prct_used; + my $failed_counter = $webcontent->{memory_stats}->{failcnt}; + my $memory_cached = $webcontent->{memory_stats}->{stats}->{cache}; + my $memory_rss = $webcontent->{memory_stats}->{stats}->{rss}; my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); + my ($cached_value, $cached_unit) = $self->{perfdata}->change_bytes(value => $memory_cached); + my ($rss_value, $rss_unit) = $self->{perfdata}->change_bytes(value => $memory_rss); + $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s %.2f%%)", + short_msg => sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s %.2f%%) Cached: %s RSS: %s Failed: %s", $total_value . " " . $total_unit, $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free) + $free_value . " " . $free_unit, $prct_free, + $cached_value . " " . $cached_unit, + $rss_value . " " . $rss_unit, + $failed_counter) ); $self->{output}->perfdata_add(label => "used", - value => $webcontent->{memory_stats}->{usage}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), - min => 0, - max => $webcontent->{memory_stats}->{limit}, - ); + value => $webcontent->{memory_stats}->{usage}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), + min => 0, + max => $webcontent->{memory_stats}->{limit}, + ); + + $self->{output}->perfdata_add(label => "cached", + value => $webcontent->{memory_stats}->{stats}->{cache}, + min => 0, + ); + + $self->{output}->perfdata_add(label => "rss", + value => $webcontent->{memory_stats}->{stats}->{rss}, + min => 0, + ); + + $self->{output}->perfdata_add(label => "failed", + value => $webcontent->{memory_stats}->{failcnt}, + min => 0, + ); $self->{output}->display(); $self->{output}->exit(); @@ -148,23 +146,11 @@ __END__ Check Container's memory usage -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -174,6 +160,8 @@ Specify one container's id Specify one container's name +=head2 MODE OPTIONS + =item B<--warning> Threshold warning in percent. @@ -182,38 +170,6 @@ Threshold warning in percent. Threshold critical in percent. -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - =back =cut diff --git a/cloud/docker/mode/nodestate.pm b/cloud/docker/mode/nodestate.pm new file mode 100644 index 000000000..a4e2a48c7 --- /dev/null +++ b/cloud/docker/mode/nodestate.pm @@ -0,0 +1,159 @@ +# +# 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 cloud::docker::mode::nodestate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $thresholds = { + state => [ + ['ready', 'OK'], + ['disconnected', 'WARNING'], + ['down', 'CRITICAL'], + ['unknown', 'UNKNOWN'], + ], +}; + +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 => + { + "port:s" => { name => 'port' }, + "id:s" => { name => 'id' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if ((defined($self->{option_results}->{id})) && ($self->{option_results}->{id} eq '')) { + $self->{output}->add_option_msg(short_msg => "You need to specify the id option"); + $self->{output}->option_exit(); + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + if ($val !~ /^(.*?),(.*?),(.*)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $status, $filter) = ($1, $2, $3); + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; + } +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i) { + $status = $_->{status}; + return $status; + } + } + } + foreach (@{$thresholds->{$options{section}}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + return $status; +} + +sub run { + my ($self, %options) = @_; + + my $urlpath = "/nodes/".$self->{option_results}->{id}; + my $port = $self->{option_results}->{port}; + my $nodeapi = $options{custom}; + + my $webcontent = $nodeapi->api_request(urlpath => $urlpath, + port => $port); + + my $exit = $self->get_severity(section => 'state', value => $webcontent->{Status}->{State}); + + if (defined($webcontent->{ManagerStatus}->{Reachability})) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%s node is %s (Availability: %s - Reachability: %s)", + $webcontent->{Spec}->{Role}, + $webcontent->{Status}->{State}, + $webcontent->{Spec}->{Availability}, + $webcontent->{ManagerStatus}->{Reachability})); + } else { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%s node is %s (Availability: %s)", + $webcontent->{Spec}->{Role}, + $webcontent->{Status}->{State}, + $webcontent->{Spec}->{Availability})); + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check Swarm Node's state + +=head2 DOCKER OPTIONS + +item B<--port> + +Port used by Docker + +=item B<--id> + +Specify one node's id + +=head2 MODE OPTIONS + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='state,CRITICAL,^(?!(disconnected)$)' + +=back + +=cut diff --git a/cloud/docker/mode/traffic.pm b/cloud/docker/mode/traffic.pm index 1318c6a5e..64d05a4bb 100644 --- a/cloud/docker/mode/traffic.pm +++ b/cloud/docker/mode/traffic.pm @@ -24,40 +24,29 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::http; use centreon::plugins::statefile; -use JSON; +use centreon::plugins::http; sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '1.1'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '2376'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/' }, - "name:s" => { name => 'name' }, - "id:s" => { name => 'id' }, - "warning-in:s" => { name => 'warning_in' }, - "critical-in:s" => { name => 'critical_in' }, - "warning-out:s" => { name => 'warning_out' }, - "critical-out:s" => { name => 'critical_out' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "timeout:s" => { name => 'timeout' }, + "port:s" => { name => 'port' }, + "name:s" => { name => 'name' }, + "id:s" => { name => 'id' }, + "warning-in:s" => { name => 'warning_in' }, + "critical-in:s" => { name => 'critical_in' }, + "warning-out:s" => { name => 'warning_out' }, + "critical-out:s" => { name => 'critical_out' }, }); $self->{statefile_value} = centreon::plugins::statefile->new(%options); $self->{http} = centreon::plugins::http->new(output => $self->{output}); + return $self; } @@ -90,14 +79,6 @@ sub check_options { $self->{output}->option_exit(); } - $self->{option_results}->{get_param} = []; - push @{$self->{option_results}->{get_param}}, "stream=false"; - if (defined($self->{option_results}->{id})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{id}."/stats"; - } elsif (defined($self->{option_results}->{name})) { - $self->{option_results}->{url_path} = "/containers/".$self->{option_results}->{name}."/stats"; - } - $self->{http}->set_options(%{$self->{option_results}}); $self->{statefile_value}->check_options(%options); } @@ -113,20 +94,17 @@ sub run { $self->{statefile_value}->read(statefile => 'docker_' . $self->{option_results}->{name} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); } - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); + my $urlpath; + if (defined($self->{option_results}->{id})) { + $urlpath = "/containers/".$self->{option_results}->{id}."/stats"; + } elsif (defined($self->{option_results}->{name})) { + $urlpath = "/containers/".$self->{option_results}->{name}."/stats"; } + my $port = $self->{option_results}->{port}; + my $containerapi = $options{custom}; + + my $webcontent = $containerapi->api_request(urlpath => $urlpath, + port => $port); my $rx_bytes = $webcontent->{network}->{rx_bytes}; my $tx_bytes = $webcontent->{network}->{tx_bytes}; @@ -203,23 +181,11 @@ __END__ Check Container's Network traffic usage -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of Docker's API +=head2 DOCKER OPTIONS =item B<--port> -Port used by Docker's API (Default: '2576') - -=item B<--proto> - -Specify https if needed (Default: 'https') - -=item B<--urlpath> - -Set path to get Docker's container information (Default: '/') +Port used by Docker =item B<--id> @@ -229,6 +195,8 @@ Specify one container's id Specify one container's name +=head2 MODE OPTIONS + =item B<--warning-in> Threshold warning in b/s for 'in' traffic. @@ -245,38 +213,6 @@ Threshold warning in b/s for 'out' traffic. Threshold critical in b/s for 'out' traffic. -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username - -=item B<--password> - -Specify password - -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - -=item B<--cert-file> - -Specify certificate to send to the webserver - -=item B<--key-file> - -Specify key to send to the webserver - -=item B<--cacert-file> - -Specify root certificate to send to the webserver - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - =back =cut diff --git a/cloud/docker/plugin.pm b/cloud/docker/plugin.pm index ebb0824a4..88ce56726 100644 --- a/cloud/docker/plugin.pm +++ b/cloud/docker/plugin.pm @@ -22,14 +22,14 @@ package cloud::docker::plugin; use strict; use warnings; -use base qw(centreon::plugins::script_simple); +use base qw(centreon::plugins::script_custom); sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '0.2'; + $self->{version} = '0.3'; %{$self->{modes}} = ( 'blockio' => 'cloud::docker::mode::blockio', 'containerstate' => 'cloud::docker::mode::containerstate', @@ -37,12 +37,23 @@ sub new { 'image' => 'cloud::docker::mode::image', 'info' => 'cloud::docker::mode::info', 'list-containers' => 'cloud::docker::mode::listcontainers', + 'list-nodes' => 'cloud::docker::mode::listnodes', 'memory' => 'cloud::docker::mode::memory', + 'nodestate' => 'cloud::docker::mode::nodestate', 'traffic' => 'cloud::docker::mode::traffic', ); + + $self->{custom_modes}{dockerapi} = 'cloud::docker::custom::dockerapi'; return $self; } +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + + 1; __END__ @@ -50,6 +61,6 @@ __END__ =head1 PLUGIN DESCRIPTION Check Docker and containers through its HTTPS Remote API (https://docs.docker.com/reference/api/docker_remote_api/). -Requirements: Docker 1.7.1+ and Docker API 1.19+ +Requirements: Docker 1.12.0+ and Docker API 1.24+ =cut