add kubernetes nodes usage, add kubectl custom mode
This commit is contained in:
parent
b1a4daadbb
commit
6db0612269
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::custom::api;
|
||||
package cloud::kubernetes::custom::api;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -44,11 +44,11 @@ sub new {
|
|||
if (!defined($options{noptions})) {
|
||||
$options{options}->add_options(arguments => {
|
||||
"hostname:s" => { name => 'hostname' },
|
||||
"url-path:s" => { name => 'url_path' },
|
||||
"port:s" => { name => 'port' },
|
||||
"proto:s" => { name => 'proto' },
|
||||
"token:s" => { name => 'token' },
|
||||
"timeout:s" => { name => 'timeout' },
|
||||
"config-file:s" => { name => 'config_file' },
|
||||
});
|
||||
}
|
||||
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
|
||||
|
@ -88,7 +88,6 @@ sub check_options {
|
|||
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef;
|
||||
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
|
||||
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
|
||||
$self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '';
|
||||
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
|
||||
$self->{token} = (defined($self->{option_results}->{token})) ? $self->{option_results}->{token} : '';
|
||||
|
||||
|
@ -111,7 +110,6 @@ sub build_options_for_httplib {
|
|||
$self->{option_results}->{timeout} = $self->{timeout};
|
||||
$self->{option_results}->{port} = $self->{port};
|
||||
$self->{option_results}->{proto} = $self->{proto};
|
||||
$self->{option_results}->{url_path} = $self->{url_path};
|
||||
$self->{option_results}->{warning_status} = '';
|
||||
$self->{option_results}->{critical_status} = '';
|
||||
$self->{option_results}->{unknown_status} = '';
|
||||
|
@ -122,66 +120,38 @@ sub settings {
|
|||
|
||||
$self->build_options_for_httplib();
|
||||
$self->{http}->add_header(key => 'Accept', value => 'application/json');
|
||||
if (defined($self->{access_token})) {
|
||||
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token});
|
||||
if (defined($self->{token})) {
|
||||
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{token});
|
||||
}
|
||||
$self->{http}->set_options(%{$self->{option_results}});
|
||||
}
|
||||
|
||||
sub get_connection_info {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{hostname} . ":" . $self->{port};
|
||||
}
|
||||
|
||||
sub get_hostname {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{hostname};
|
||||
}
|
||||
|
||||
sub get_port {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{port};
|
||||
}
|
||||
|
||||
sub get_token {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{option_results}->{token};
|
||||
}
|
||||
|
||||
sub request_api {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if (!defined($self->{access_token})) {
|
||||
$self->{access_token} = $self->get_token();
|
||||
}
|
||||
|
||||
$self->settings;
|
||||
|
||||
$self->{output}->output_add(long_msg => "Query URL: '" . $self->{proto} . "://" . $self->{hostname} .
|
||||
$self->{url_path} . $options{url_path} . "'", debug => 1);
|
||||
|
||||
my $content = $self->{http}->request(url_path => $self->{url_path} . $options{url_path});
|
||||
$self->{output}->output_add(long_msg => "URL: '" . $self->{proto} . '://' . $self->{hostname} .
|
||||
':' . $self->{port} . $options{url_path} . "'", debug => 1);
|
||||
|
||||
my $response = $self->{http}->request(url_path => $options{url_path});
|
||||
|
||||
if ($self->{http}->get_code() != 200) {
|
||||
my $decoded;
|
||||
eval {
|
||||
$decoded = JSON::XS->new->utf8->decode($content);
|
||||
$decoded = JSON::XS->new->utf8->decode($response);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{output}->output_add(long_msg => $content, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
|
||||
$self->{output}->output_add(long_msg => $response, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $response");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if (defined($decoded->{code})) {
|
||||
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{message}, debug => 1);
|
||||
$self->{output}->output_add(long_msg => "Error message: " . $decoded->{message}, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "API return error code '" . $decoded->{code} . "' (add --debug option for detailed message)");
|
||||
$self->{output}->option_exit();
|
||||
} else {
|
||||
$self->{output}->output_add(long_msg => "Error message : " . $decoded, debug => 1);
|
||||
$self->{output}->output_add(long_msg => "Error message: " . $decoded, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "API return error code '" . $self->{http}->get_code() . "' (add --debug option for detailed message)");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
@ -189,16 +159,89 @@ sub request_api {
|
|||
|
||||
my $decoded;
|
||||
eval {
|
||||
$decoded = JSON::XS->new->utf8->decode($content);
|
||||
$decoded = JSON::XS->new->utf8->decode($response);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
|
||||
$self->{output}->output_add(long_msg => $response, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $response");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
sub kubernetes_list_daemonsets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/daemonsets');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_deployments {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/deployments');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_ingresses {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/extensions/v1beta1/ingresses');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_namespaces {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/api/v1/namespaces');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_nodes {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/api/v1/nodes');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_replicasets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/replicasets');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_services {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/v1/services');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_statefulsets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/statefulsets');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_pods {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->request_api(method => 'GET', url_path => '/api/v1/pods');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
|
@ -0,0 +1,255 @@
|
|||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::custom::kubectl;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use DateTime;
|
||||
use JSON::XS;
|
||||
|
||||
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' },
|
||||
"port:s" => { name => 'port' },
|
||||
"proto:s" => { name => 'proto' },
|
||||
"token:s" => { name => 'token' },
|
||||
"timeout:s" => { name => 'timeout', default => 10 },
|
||||
"config-file:s" => { name => 'config_file' },
|
||||
"sudo" => { name => 'sudo' },
|
||||
"command:s" => { name => 'command', default => 'kubectl' },
|
||||
"command-path:s" => { name => 'command_path' },
|
||||
"command-options:s" => { name => 'command_options', default => '' },
|
||||
});
|
||||
}
|
||||
$options{options}->add_help(package => __PACKAGE__, sections => 'CLI OPTIONS', once => 1);
|
||||
|
||||
$self->{output} = $options{output};
|
||||
$self->{mode} = $options{mode};
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub set_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{option_results} = $options{option_results};
|
||||
}
|
||||
|
||||
sub set_defaults {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
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) = @_;
|
||||
|
||||
$self->{config_file} = (defined($self->{option_results}->{config_file})) ? $self->{option_results}->{config_file} : '';
|
||||
|
||||
if (!defined($self->{config_file}) || $self->{config_file} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --config-file option.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub execute {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->output_add(long_msg => "Command line: '" . $self->{option_results}->{command} . " " . $options{cmd_options} . "'", debug => 1);
|
||||
|
||||
my ($response, $exit_code) = centreon::plugins::misc::execute(
|
||||
output => $self->{output},
|
||||
options => $self->{option_results},
|
||||
sudo => $self->{option_results}->{sudo},
|
||||
command => $self->{option_results}->{command},
|
||||
command_path => $self->{option_results}->{command_path},
|
||||
command_options => $options{cmd_options},
|
||||
no_quit => 1
|
||||
);
|
||||
|
||||
if ($exit_code != 0) {
|
||||
$self->{output}->output_add(long_msg => "Error message: " . $response, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "CLI return error code '" . $exit_code . "' (add --debug option for detailed message)");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $decoded;
|
||||
eval {
|
||||
$decoded = JSON::XS->new->utf8->decode($response);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{output}->output_add(long_msg => $response, debug => 1);
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
sub kubernetes_list_daemonsets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get daemonsets --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_deployments {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get deployments --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_ingresses {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get ingresses --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_namespaces {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get namespaces --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_nodes {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get nodes --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_replicasets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get replicasets --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_services {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get services --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_statefulsets {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get statefulsets --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub kubernetes_list_pods {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $response = $self->execute(cmd_options => 'get pods --all-namespaces --output=json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kubernetes CLI (kubectl)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Kubernetes CLI (kubectl) custom mode
|
||||
|
||||
=head1 CLI OPTIONS
|
||||
|
||||
Kubernetes CLI (kubectl)
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--config-file>
|
||||
|
||||
Kubernetes configuration file path
|
||||
(Example: --config-file='/root/.kube/config').
|
||||
|
||||
=item B<--timeout>
|
||||
|
||||
Set timeout in seconds (Default: 10).
|
||||
|
||||
=item B<--sudo>
|
||||
|
||||
Use 'sudo' to execute the command.
|
||||
|
||||
=item B<--command>
|
||||
|
||||
Command to get information (Default: 'kubectl').
|
||||
Can be changed if you have output in a file.
|
||||
|
||||
=item B<--command-path>
|
||||
|
||||
Command path (Default: none).
|
||||
|
||||
=item B<--command-options>
|
||||
|
||||
Command options (Default: none).
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<custom>.
|
||||
|
||||
=cut
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::daemonsetstatus;
|
||||
package cloud::kubernetes::mode::daemonsetstatus;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -129,7 +129,7 @@ sub manage_selection {
|
|||
|
||||
$self->{daemonsets} = {};
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/daemonsets');
|
||||
my $results = $options{custom}->kubernetes_list_daemonsets();
|
||||
|
||||
foreach my $daemonset (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::deploymentstatus;
|
||||
package cloud::kubernetes::mode::deploymentstatus;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -125,7 +125,7 @@ sub manage_selection {
|
|||
|
||||
$self->{deployments} = {};
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/deployments');
|
||||
my $results = $options{custom}->kubernetes_list_deployments();
|
||||
|
||||
foreach my $deployment (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listdaemonsets;
|
||||
package cloud::kubernetes::mode::listdaemonsets;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/daemonsets');
|
||||
my $results = $options{custom}->kubernetes_list_daemonsets();
|
||||
|
||||
foreach my $daemonset (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listdeployments;
|
||||
package cloud::kubernetes::mode::listdeployments;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/deployments');
|
||||
my $results = $options{custom}->kubernetes_list_deployments();
|
||||
|
||||
foreach my $deployment (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listingresses;
|
||||
package cloud::kubernetes::mode::listingresses;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/extensions/v1beta1/ingresses');
|
||||
my $results = $options{custom}->kubernetes_list_ingresses();
|
||||
|
||||
foreach my $ingress (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listnamespaces;
|
||||
package cloud::kubernetes::mode::listnamespaces;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -46,7 +46,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/api/v1/namespaces');
|
||||
my $results = $options{custom}->kubernetes_list_namespaces();
|
||||
|
||||
foreach my $namespace (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listnodes;
|
||||
package cloud::kubernetes::mode::listnodes;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -46,7 +46,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/api/v1/nodes');
|
||||
my $results = $options{custom}->kubernetes_list_nodes();
|
||||
|
||||
foreach my $node (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listpods;
|
||||
package cloud::kubernetes::mode::listpods;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/api/v1/pods');
|
||||
my $results = $options{custom}->kubernetes_list_pods();
|
||||
|
||||
foreach my $pod (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listreplicasets;
|
||||
package cloud::kubernetes::mode::listreplicasets;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/replicasets');
|
||||
my $results = $options{custom}->kubernetes_list_replicasets();
|
||||
|
||||
foreach my $replicaset (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::listservices;
|
||||
package cloud::kubernetes::mode::listservices;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/api/v1/services');
|
||||
my $results = $options{custom}->kubernetes_list_services();
|
||||
|
||||
foreach my $service (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::liststatefulsets;
|
||||
package cloud::kubernetes::mode::liststatefulsets;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -47,7 +47,7 @@ sub check_options {
|
|||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/apis/apps/v1/statefulsets');
|
||||
my $results = $options{custom}->kubernetes_list_statefulsets();
|
||||
|
||||
foreach my $statefulset (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
|
@ -0,0 +1,199 @@
|
|||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::mode::nodeusage;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
|
||||
|
||||
sub custom_usage_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $label = 'allocated_pods';
|
||||
my $value_perf = $self->{result_values}->{allocated};
|
||||
my $extra_label = '';
|
||||
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
|
||||
my %total_options = ();
|
||||
if ($self->{instance_mode}->{option_results}->{units} eq '%') {
|
||||
$total_options{total} = $self->{result_values}->{allocatable};
|
||||
$total_options{cast_int} = 1;
|
||||
}
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => $label . $extra_label,
|
||||
value => $value_perf,
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options),
|
||||
min => 0, max => $self->{result_values}->{allocatable}
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_usage_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my ($exit, $threshold_value);
|
||||
$threshold_value = $self->{result_values}->{allocated};
|
||||
if ($self->{instance_mode}->{option_results}->{units} eq '%') {
|
||||
$threshold_value = $self->{result_values}->{prct_allocated};
|
||||
}
|
||||
$exit = $self->{perfdata}->threshold_check(
|
||||
value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]
|
||||
);
|
||||
return $exit;
|
||||
}
|
||||
|
||||
sub custom_usage_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Pods Capacity: %s, Allocatable: %s, Allocated: %s (%.2f%%)",
|
||||
$self->{result_values}->{capacity},
|
||||
$self->{result_values}->{allocatable},
|
||||
$self->{result_values}->{allocated},
|
||||
$self->{result_values}->{prct_allocated});
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_usage_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'};
|
||||
$self->{result_values}->{capacity} = $options{new_datas}->{$self->{instance} . '_capacity'};
|
||||
$self->{result_values}->{allocatable} = $options{new_datas}->{$self->{instance} . '_allocatable'};
|
||||
$self->{result_values}->{allocated} = $options{new_datas}->{$self->{instance} . '_allocated'};
|
||||
$self->{result_values}->{prct_allocated} = ($self->{result_values}->{allocatable} > 0) ? $self->{result_values}->{allocated} * 100 / $self->{result_values}->{allocatable} : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output',
|
||||
message_multiple => 'All nodes usage are ok', skipped_code => { -11 => 1 } },
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{nodes} = [
|
||||
{ label => 'allocated-pods', set => {
|
||||
key_values => [ { name => 'capacity' }, { name => 'allocatable' }, { name => 'allocated' },
|
||||
{ name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_usage_calc'),
|
||||
closure_custom_output => $self->can('custom_usage_output'),
|
||||
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
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' },
|
||||
"units:s" => { name => 'units', default => '%' },
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->change_macros(macros => ['warning_status', 'critical_status']);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{nodes} = {};
|
||||
|
||||
my $nodes = $options{custom}->kubernetes_list_nodes();
|
||||
|
||||
foreach my $node (@{$nodes->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$node->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) {
|
||||
$self->{output}->output_add(long_msg => "skipping '" . $node->{metadata}->{name} . "': no matching filter name.", debug => 1);
|
||||
next;
|
||||
}
|
||||
|
||||
$self->{nodes}->{$node->{metadata}->{name}} = {
|
||||
display => $node->{metadata}->{name},
|
||||
capacity => $node->{status}->{capacity}->{pods},
|
||||
allocatable => $node->{status}->{allocatable}->{pods},
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar(keys %{$self->{nodes}}) <= 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No nodes found.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $pods = $options{custom}->kubernetes_list_pods();
|
||||
|
||||
foreach my $pod (@{$pods->{items}}) {
|
||||
next if (defined($pod->{spec}->{nodeName}) && !defined($self->{nodes}->{$pod->{spec}->{nodeName}}));
|
||||
$self->{nodes}->{$pod->{spec}->{nodeName}}->{allocated}++;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check node usage.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter node name (can be a regexp).
|
||||
|
||||
=item B<--warning-allocated-pods>
|
||||
|
||||
Threshold warning for pods allocation.
|
||||
|
||||
=item B<--critical-allocated-pods>
|
||||
|
||||
Threshold critical for pods allocation.
|
||||
|
||||
=item B<--units>
|
||||
|
||||
Units of thresholds (Default: '%') (Can be '%' or absolute).
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::mode::podstatus;
|
||||
package cloud::kubernetes::mode::podstatus;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
|
@ -205,6 +205,7 @@ sub new {
|
|||
$options{options}->add_options(arguments => {
|
||||
"filter-name:s" => { name => 'filter_name' },
|
||||
"filter-namespace:s" => { name => 'filter_namespace' },
|
||||
"extra-filter:s@" => { name => 'extra_filter' },
|
||||
"warning-pod-status:s" => { name => 'warning_pod_status', default => '' },
|
||||
"critical-pod-status:s" => { name => 'critical_pod_status', default => '%{status} !~ /running/i' },
|
||||
"warning-container-status:s" => { name => 'warning_container_status', default => '' },
|
||||
|
@ -218,7 +219,13 @@ sub new {
|
|||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
|
||||
$self->{extra_filter} = {};
|
||||
foreach my $filter (@{$self->{option_results}->{extra_filter}}) {
|
||||
next if ($filter !~ /(.*)=(.*)/);
|
||||
$self->{extra_filter}->{$1} = $2;
|
||||
}
|
||||
|
||||
$self->change_macros(macros => ['warning_pod_status', 'critical_pod_status',
|
||||
'warning_container_status', 'critical_container_status']);
|
||||
}
|
||||
|
@ -228,7 +235,7 @@ sub manage_selection {
|
|||
|
||||
$self->{pods} = {};
|
||||
|
||||
my $results = $options{custom}->request_api(url_path => '/api/v1/pods');
|
||||
my $results = $options{custom}->kubernetes_list_pods();
|
||||
|
||||
foreach my $pod (@{$results->{items}}) {
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
|
@ -238,9 +245,18 @@ sub manage_selection {
|
|||
}
|
||||
if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' &&
|
||||
$pod->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) {
|
||||
$self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1);
|
||||
$self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching filter namespace.", debug => 1);
|
||||
next;
|
||||
}
|
||||
my $next = 0;
|
||||
foreach my $label (keys %{$self->{extra_filter}}) {
|
||||
if (!defined($pod->{metadata}->{labels}->{$label}) || $pod->{metadata}->{labels}->{$label} !~ /$self->{extra_filter}->{$label}/) {
|
||||
$self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching extra filter.", debug => 1);
|
||||
$next = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
next if ($next == 1);
|
||||
|
||||
$self->{pods}->{$pod->{metadata}->{uid}}->{display} = $pod->{metadata}->{name};
|
||||
$self->{pods}->{$pod->{metadata}->{uid}}->{global} = {
|
||||
|
@ -280,6 +296,20 @@ Check pod status.
|
|||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter pod name (can be a regexp).
|
||||
|
||||
=item B<--filter-namespace>
|
||||
|
||||
Filter pod namespace (can be a regexp).
|
||||
|
||||
=item B<--extra-filter>
|
||||
|
||||
Add an extra filter based on labels (Can be multiple)
|
||||
|
||||
Example : --extra-filter='app=mynewapp'
|
||||
|
||||
=item B<--warning-pod-status>
|
||||
|
||||
Set warning threshold for status (Default: '').
|
|
@ -18,7 +18,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
package cloud::kubernetes::restapi::plugin;
|
||||
package cloud::kubernetes::plugin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -31,21 +31,23 @@ sub new {
|
|||
|
||||
$self->{version} = '1.0';
|
||||
%{$self->{modes}} = (
|
||||
'daemonset-status' => 'cloud::kubernetes::restapi::mode::daemonsetstatus',
|
||||
'deployment-status' => 'cloud::kubernetes::restapi::mode::deploymentstatus',
|
||||
'list-daemonsets' => 'cloud::kubernetes::restapi::mode::listdaemonsets',
|
||||
'list-deployments' => 'cloud::kubernetes::restapi::mode::listdeployments',
|
||||
'list-ingresses' => 'cloud::kubernetes::restapi::mode::listingresses',
|
||||
'list-namespaces' => 'cloud::kubernetes::restapi::mode::listnamespaces',
|
||||
'list-nodes' => 'cloud::kubernetes::restapi::mode::listnodes',
|
||||
'list-pods' => 'cloud::kubernetes::restapi::mode::listpods',
|
||||
'list-replicasets' => 'cloud::kubernetes::restapi::mode::listreplicasets',
|
||||
'list-services' => 'cloud::kubernetes::restapi::mode::listservices',
|
||||
'list-statefulsets' => 'cloud::kubernetes::restapi::mode::liststatefulsets',
|
||||
'pod-status' => 'cloud::kubernetes::restapi::mode::podstatus',
|
||||
'daemonset-status' => 'cloud::kubernetes::mode::daemonsetstatus',
|
||||
'deployment-status' => 'cloud::kubernetes::mode::deploymentstatus',
|
||||
'list-daemonsets' => 'cloud::kubernetes::mode::listdaemonsets',
|
||||
'list-deployments' => 'cloud::kubernetes::mode::listdeployments',
|
||||
'list-ingresses' => 'cloud::kubernetes::mode::listingresses',
|
||||
'list-namespaces' => 'cloud::kubernetes::mode::listnamespaces',
|
||||
'list-nodes' => 'cloud::kubernetes::mode::listnodes',
|
||||
'list-pods' => 'cloud::kubernetes::mode::listpods',
|
||||
'list-replicasets' => 'cloud::kubernetes::mode::listreplicasets',
|
||||
'list-services' => 'cloud::kubernetes::mode::listservices',
|
||||
'list-statefulsets' => 'cloud::kubernetes::mode::liststatefulsets',
|
||||
'node-usage' => 'cloud::kubernetes::mode::nodeusage',
|
||||
'pod-status' => 'cloud::kubernetes::mode::podstatus',
|
||||
);
|
||||
|
||||
$self->{custom_modes}{api} = 'cloud::kubernetes::restapi::custom::api';
|
||||
$self->{custom_modes}{api} = 'cloud::kubernetes::custom::api';
|
||||
$self->{custom_modes}{kubectl} = 'cloud::kubernetes::custom::kubectl';
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -61,6 +63,6 @@ __END__
|
|||
|
||||
=head1 PLUGIN DESCRIPTION
|
||||
|
||||
Check Kubernetes cluster using API.
|
||||
Check Kubernetes cluster using CLI (kubectl) or RestAPI.
|
||||
|
||||
=cut
|
Loading…
Reference in New Issue