work on docker plugin

This commit is contained in:
qgarnier 2017-06-30 16:58:52 +02:00
parent 7aecf037ae
commit e7f371cded
2 changed files with 58 additions and 21 deletions

View File

@ -59,9 +59,10 @@ sub new {
"cacert-file:s" => { name => 'cacert_file' }, "cacert-file:s" => { name => 'cacert_file' },
"cert-pwd:s" => { name => 'cert_pwd' }, "cert-pwd:s" => { name => 'cert_pwd' },
"cert-pkcs12" => { name => 'cert_pkcs12' }, "cert-pkcs12" => { name => 'cert_pkcs12' },
"api-display" => { name => 'api_display' }, "api-display" => { name => 'api_display' },
"api-write-file:s" => { name => 'api_write_file' }, "api-write-file:s" => { name => 'api_write_file' },
"api-read-file:s" => { name => 'api_read_file' }, "api-read-file:s" => { name => 'api_read_file' },
"reload-cache-time:s" => { name => 'reload_cache_time', default => 300 },
}); });
} }
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
@ -112,7 +113,7 @@ sub check_options {
foreach my $node_name (@{$self->{hostname}}) { foreach my $node_name (@{$self->{hostname}}) {
if ($node_name ne '') { if ($node_name ne '') {
$self->{http}->{$node_name} = centreon::plugins::http->new(output => $self->{output}); $self->{http}->{$node_name} = centreon::plugins::http->new(output => $self->{output});
$self->{options_results}->{hostname} = $node_name; $self->{option_results}->{hostname} = $node_name;
$self->{http}->{$node_name}->set_options(%{$self->{option_results}}); $self->{http}->{$node_name}->set_options(%{$self->{option_results}});
} }
} }
@ -170,20 +171,46 @@ sub api_read_file {
return $content; return $content;
} }
sub cache_containers {
my ($self, %options) = @_;
my $has_cache_file = $options{statefile}->read(statefile => 'cache_docker_containers_' . join(':', @{$self->{hostname}}) . '_' . $self->{option_results}->{port});
my $timestamp_cache = $options{statefile}->get(name => 'last_timestamp');
my $containers = $options{statefile}->get(name => 'containers');
if ($has_cache_file == 0 || !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($options{reload_cache_time})))) {
$containers = {};
my $datas = { last_timestamp => time(), containers => $containers };
foreach my $node_name (keys %{$self->{http}}) {
my $list_containers = $self->internal_api_list_containers(node_name => $node_name);
foreach my $container (@$list_containers) {
$containers->{$container->{Id}} = {
State => $container->{State},
NodeName => $node_name,
Name => join(':', @{$container->{Names}}),
};
}
}
$options{statefile}->write(data => $containers);
}
return $containers;
}
sub internal_api_list_containers { sub internal_api_list_containers {
my ($self, %options) = @_; my ($self, %options) = @_;
my $response = $self->{http}->{$options{node_name}}->request( my $response = $self->{http}->{$options{node_name}}->request(
url_path => '/containers/json?all=true', url_path => '/containers/json?all=true',
critical_status => '', warning_status => ''); unknown_status => '', critical_status => '', warning_status => '');
my $containers; my $containers;
eval { eval {
$containers = JSON::XS->new->utf8->decode($response); $containers = JSON::XS->new->utf8->decode($response);
}; };
if ($@) { if ($@) {
$containers = []; $containers = [];
$self->output_add(severity => 'UNKNOWN', $self->{output}->output_add(severity => 'UNKNOWN',
short_msg => "Node '$options{node_name}': cannot decode json get containers response: $@"); short_msg => "Node '$options{node_name}': cannot decode json get containers response: $@");
} }
return $containers; return $containers;
@ -194,7 +221,7 @@ sub internal_api_get_container_stats {
my $response = $self->{http}->{$options{node_name}}->request( my $response = $self->{http}->{$options{node_name}}->request(
url_path => '/containers/' . $options{container_id} . '/stats?stream=false', url_path => '/containers/' . $options{container_id} . '/stats?stream=false',
critical_status => '', warning_status => ''); unknown_status => '', critical_status => '', warning_status => '');
my $container_stats; my $container_stats;
eval { eval {
$container_stats = JSON::XS->new->utf8->decode($response); $container_stats = JSON::XS->new->utf8->decode($response);
@ -215,19 +242,16 @@ sub api_get_containers {
return $self->api_read_file(); return $self->api_read_file();
} }
my $content_total = {}; my $content_total = $self->cache_containers(statefile => $options{statefile});
foreach my $node_name (keys %{$self->{http}}) { if (defined($options{container_id}) && $options{container_id} ne '' && defined($content_total->{$options{container_id}})) {
my $containers = $self->internal_api_list_containers(node_name => $node_name); $content_total->{$options{container_id}}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$options{container_id}}->{NodeName}, container_id => $options{container_id});
foreach my $container (@$containers) { } else {
$content_total->{$container->{Id}} = { foreach my $container_id (keys %{$content_total}) {
State => $container->{State}, $content_total->{$container_id}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$container_id}->{NodeName}, container_id => $container_id);
NodeName => $node_name,
Name => join(':', @{$container->{Names}}),
};
$content_total->{$container->{Id}}->{Stats} = $self->internal_api_get_container_stats(node_name => $node_name, container_id => $container->{Id});
} }
} }
$self->api_display();
return $content_total; return $content_total;
} }
@ -319,6 +343,10 @@ Print json api in a file (to be used with --api-display).
Read API from file. Read API from file.
=item B<--reload-cache-time>
Time in seconds before reloading list containers cache (default: 300)
=back =back
=head1 DESCRIPTION =head1 DESCRIPTION

View File

@ -125,11 +125,13 @@ sub new {
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"container-id:s" => { name => 'container_id' },
"filter-name:s" => { name => 'filter_name' }, "filter-name:s" => { name => 'filter_name' },
"warning-container-status:s" => { name => 'warning_container_status' }, "warning-container-status:s" => { name => 'warning_container_status' },
"critical-container-status:s" => { name => 'critical_container_status', default => '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i' }, "critical-container-status:s" => { name => 'critical_container_status', default => '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i' },
}); });
$self->{statefile_cache_containers} = centreon::plugins::statefile->new(%options);
return $self; return $self;
} }
@ -139,6 +141,7 @@ sub check_options {
$instance_mode = $self; $instance_mode = $self;
$self->change_macros(); $self->change_macros();
$self->{statefile_cache_containers}->check_options(%options);
} }
sub prefix_containers_output { sub prefix_containers_output {
@ -161,7 +164,7 @@ sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->{containers} = {}; $self->{containers} = {};
my $result = $options{custom}->api_get_containers(); my $result = $options{custom}->api_get_containers(container_id => $self->{option_results}->{container_id}, statefile => $self->{statefile_cache_containers});
use Data::Dumper; use Data::Dumper;
print Data::Dumper::Dumper($result); print Data::Dumper::Dumper($result);
exit(1); exit(1);
@ -203,9 +206,13 @@ Check container usage.
=over 8 =over 8
=item B<--container-id>
Exact container ID.
=item B<--filter-name> =item B<--filter-name>
Filter name (can be a regexp). Filter by container name (can be a regexp).
=item B<--filter-counters> =item B<--filter-counters>
@ -232,6 +239,8 @@ Can used special variables like: %{id}, %{name}, %{status}.
Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i'). Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i').
Can used special variables like: %{id}, %{name}, %{status}. Can used special variables like: %{id}, %{name}, %{status}.
=back =back
=cut =cut