(plugin) cloud::talend::tmc (#4135)

This commit is contained in:
qgarnier 2023-01-11 10:33:27 +00:00 committed by Kevin Duret
parent d3085b55e4
commit 9e13a36b3a
11 changed files with 1930 additions and 2 deletions

View File

@ -113,8 +113,14 @@ sub check_options {
}
}
$self->{statefile_format} = defined($options{option_results}->{statefile_format}) && $options{option_results}->{statefile_format} =~ /^(?:dumper|json|storable)$/ ?
$options{option_results}->{statefile_format} : 'dumper';
$self->{statefile_format} = 'dumper';
if (defined($options{option_results}->{statefile_format}) && $options{option_results}->{statefile_format} ne '' &&
$options{option_results}->{statefile_format} =~ /^(?:dumper|json|storable)$/) {
$self->{statefile_format} = $options{option_results}->{statefile_format};
} elsif (defined($options{default_format}) && $options{default_format} =~ /^(?:dumper|json|storable)$/) {
$self->{statefile_format} = $options{default_format};
}
if (defined($options{option_results}->{statefile_storable})) {
$self->{statefile_format} = 'storable';
}

View File

@ -0,0 +1,420 @@
#
# Copyright 2023 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::talend::tmc::custom::api;
use strict;
use warnings;
use centreon::plugins::http;
use centreon::plugins::statefile;
use JSON::XS;
use Digest::MD5 qw(md5_hex);
use centreon::plugins::misc;
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 => {
'region:s' => { name => 'region' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'api-token:s' => { name => 'api_token' },
'timeout:s' => { name => 'timeout' },
'cache-use' => { name => 'cache_use' },
'unknown-http-status:s' => { name => 'unknown_http_status' },
'warning-http-status:s' => { name => 'warning_http_status' },
'critical-http-status:s' => { name => 'critical_http_status' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{http} = centreon::plugins::http->new(%options);
$self->{cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
$self->{region} = (defined($self->{option_results}->{region})) ? lc($self->{option_results}->{region}) : '';
$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->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 50;
$self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : '';
$self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300';
$self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : '';
$self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : '';
if ($self->{region} !~ /^eu|us|us-west|ap|au/) {
$self->{output}->add_option_msg(short_msg => "Need to specify --region option. Can be: eu, us, us-west, ap, au.");
$self->{output}->option_exit();
}
if ($self->{api_token} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --api-token option.");
$self->{output}->option_exit();
}
$self->{cache}->check_options(option_results => $self->{option_results}, default_format => 'json');
return 0;
}
sub get_hostname {
my ($self, %options) = @_;
return $self->{hostname};
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{hostname} = 'api.' . $self->{region} . '.cloud.talend.com';
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{http}->add_header(key => 'Content-Type', value => 'application/json');
$self->{http}->add_header(key => 'Accept', value => 'application/json');
}
sub settings {
my ($self, %options) = @_;
return if (defined($self->{settings_done}));
$self->build_options_for_httplib();
$self->{http}->set_options(%{$self->{option_results}});
$self->{settings_done} = 1;
}
sub request_api {
my ($self, %options) = @_;
$self->settings();
my $items = [];
my $offset = 0;
while (1) {
my $body = {};
my $get_param = [];
if (defined($options{paging})) {
$body->{limit} = 100;
$body->{offset} = $offset;
$get_param = ['limit=100', 'offset=' . $offset];
}
if (defined($options{body})) {
foreach (keys %{$options{body}}) {
if (defined($options{body}->{$_})) {
$body->{$_} = $options{body}->{$_};
push @$get_param, $_ . '=' . $options{body}->{$_};
}
}
}
if ($options{method} eq 'POST') {
eval {
$body = encode_json($body);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => 'cannot encode json request');
$self->{output}->option_exit();
}
}
my ($content) = $self->{http}->request(
method => $options{method},
url_path => $options{endpoint},
get_param => $options{method} eq 'GET' ? $get_param : undef,
header => ['Authorization: Bearer ' . $self->{api_token}],
query_form_post => $options{method} eq 'POST' ? $body : undef,
unknown_status => $self->{unknown_http_status},
warning_status => $self->{warning_http_status},
critical_status => $self->{critical_http_status}
);
if (!defined($content) || $content eq '') {
$self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']");
$self->{output}->option_exit();
}
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
$self->{output}->option_exit();
}
if (!defined($options{paging})) {
push @$items, @$decoded;
last;
}
push @$items, @{$decoded->{items}};
last if (scalar(@$items) >= $decoded->{total});
$offset += 100;
}
return $items;
}
sub cache_environments {
my ($self, %options) = @_;
my $datas = $self->get_environments(disable_cache => 1);
$self->write_cache_file(
statefile => 'environments',
response => $datas
);
return $datas;
}
sub cache_plans_execution {
my ($self, %options) = @_;
my $datas = $self->get_plans_execution(disable_cache => 1, from => $options{from}, to => $options{to});
$self->write_cache_file(
statefile => 'plans_execution',
response => $datas
);
return $datas;
}
sub cache_tasks_execution {
my ($self, %options) = @_;
my $datas = $self->get_tasks_execution(disable_cache => 1, from => $options{from}, to => $options{to});
$self->write_cache_file(
statefile => 'tasks_execution',
response => $datas
);
return $datas;
}
sub cache_plans_config {
my ($self, %options) = @_;
my $datas = $self->get_plans_config(disable_cache => 1);
$self->write_cache_file(
statefile => 'plans_config',
response => $datas
);
return $datas;
}
sub cache_tasks_config {
my ($self, %options) = @_;
my $datas = $self->get_tasks_config(disable_cache => 1);
$self->write_cache_file(
statefile => 'tasks_config',
response => $datas
);
return $datas;
}
sub cache_remote_engines {
my ($self, %options) = @_;
my $datas = $self->get_remote_engines(disable_cache => 1);
$self->write_cache_file(
statefile => 'remote_engines',
response => $datas
);
return $datas;
}
sub write_cache_file {
my ($self, %options) = @_;
$self->{cache}->read(statefile => 'cache_talend_tmc_' . $options{statefile} . '_' . $self->{region} . '_' . md5_hex($self->{api_token}));
$self->{cache}->write(data => {
update_time => time(),
response => $options{response}
});
}
sub get_cache_file_response {
my ($self, %options) = @_;
$self->{cache}->read(statefile => 'cache_talend_tmc_' . $options{statefile} . '_' . $self->{region} . '_' . md5_hex($self->{api_token}));
my $response = $self->{cache}->get(name => 'response');
if (!defined($response)) {
$self->{output}->add_option_msg(short_msg => 'Cache file missing');
$self->{output}->option_exit();
}
return $response;
}
sub get_environments {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'environments')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache}));
return $self->request_api(method => 'GET', endpoint => '/orchestration/environments');
}
sub get_plans_execution {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'plans_execution')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache})
&& !(defined($options{planId}) && $options{planId} ne ''));
return $self->request_api(
method => 'GET',
endpoint => (defined($options{planId}) && $options{planId} ne '') ?
'/processing/executables/plans/' . $options{planId} . '/executions' : '/processing/executables/plans/executions',
body => {
from => $options{from},
to => $options{to},
environmentId => $options{environmentId}
},
paging => 1
);
}
sub get_tasks_execution {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'tasks_execution')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache})
&& !(defined($options{taskId}) && $options{taskId} ne ''));
return $self->request_api(
method => 'POST',
endpoint => (defined($options{taskId}) && $options{taskId} ne '') ?
'/processing/executables/tasks/' . $options{taskId} . '/executions' : '/processing/executables/tasks/executions',
body => {
from => $options{from},
to => $options{to},
environmentId => $options{environmentId}
},
paging => 1
);
}
sub get_plans_config {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'plans_config')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache}));
return $self->request_api(
method => 'GET',
endpoint => '/orchestration/executables/plans',
paging => 1
);
}
sub get_tasks_config {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'tasks_config')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache}));
return $self->request_api(
method => 'GET',
endpoint => '/orchestration/executables/tasks',
paging => 1
);
}
sub get_remote_engines {
my ($self, %options) = @_;
return $self->get_cache_file_response(statefile => 'remote_engines')
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache}));
return $self->request_api(
method => 'GET',
endpoint => '/processing/runtimes/remote-engines'
);
}
1;
__END__
=head1 NAME
Cloud Talend REST API
=head1 SYNOPSIS
Rest API custom mode
=head1 REST API OPTIONS
=over 8
=item B<--region>
Region (Required). Can be: eu, us, us-west, ap, au.
=item B<--port>
Port used (Default: 443)
=item B<--proto>
Specify https if needed (Default: 'https')
=item B<--api-token>
API token.
=item B<--timeout>
Set HTTP timeout
=item B<--cache-use>
Use the cache file (created with cache mode).
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,90 @@
#
# Copyright 2023 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::talend::tmc::mode::cache;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
'since-timeperiod:s' => { name => 'since_timeperiod' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (!defined($self->{option_results}->{since_timeperiod}) || $self->{option_results}->{since_timeperiod} eq '') {
$self->{option_results}->{since_timeperiod} = 86400;
}
}
sub manage_selection {
my ($self, %options) = @_;
my $to = time();
$options{custom}->cache_environments();
$options{custom}->cache_remote_engines();
$options{custom}->cache_tasks_config();
$options{custom}->cache_tasks_execution(
from => ($to - $self->{option_results}->{since_timeperiod}) * 1000,
to => $to * 1000
);
$options{custom}->cache_plans_config();
$options{custom}->cache_plans_execution(
from => ($to - $self->{option_results}->{since_timeperiod}) * 1000,
to => $to * 1000
);
$self->{output}->output_add(
severity => 'OK',
short_msg => 'Cache files created successfully'
);
}
1;
__END__
=head1 MODE
Create cache files (other modes could use it with --cache-use option).
=over 8
=item B<--since-timeperiod>
Time period to get tasks and plans execution informations (in seconds. Default: 86400).
=back
=cut

View File

@ -0,0 +1,92 @@
#
# Copyright 2023 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::talend::tmc::mode::listenvironments;
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;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->get_environments(disable_cache => 1);
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->output_add(long_msg => sprintf('[id: %s][name: %s]', $_->{id}, $_->{name}));
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List environments:'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['id', 'name']);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->add_disco_entry(%$_);
}
}
1;
__END__
=head1 MODE
List environments.
=over 8
=back
=cut

View File

@ -0,0 +1,103 @@
#
# Copyright 2023 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::talend::tmc::mode::listplans;
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;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->cache_plans_config(disable_cache => 1);
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[id: %s][name: %s][environmentName: %s]',
$_->{executable},
$_->{name},
$_->{workspace}->{environment}->{name}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List plans:'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['id', 'name', 'environmentName']);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->add_disco_entry(
id => $_->{executable},
name => $_->{name},
environmentName => $_->{workspace}->{environment}->{name}
);
}
}
1;
__END__
=head1 MODE
List plans.
=over 8
=back
=cut

View File

@ -0,0 +1,105 @@
#
# Copyright 2023 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::talend::tmc::mode::listremoteengines;
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;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->cache_remote_engines(disable_cache => 1);
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[id: %s][name: %s][status: %s][environmentName: %s]',
$_->{id},
$_->{name},
$_->{status},
$_->{workspace}->{environment}->{name}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List remote engines:'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['id', 'name', 'status', 'environmentName']);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->add_disco_entry(
id => $_->{id},
name => $_->{name},
status => $_->{status},
environmentName => $_->{workspace}->{environment}->{name}
);
}
}
1;
__END__
=head1 MODE
List remote engines.
=over 8
=back
=cut

View File

@ -0,0 +1,103 @@
#
# Copyright 2023 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::talend::tmc::mode::listtasks;
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;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->cache_tasks_config(disable_cache => 1);
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[id: %s][name: %s][environmentName: %s]',
$_->{executable},
$_->{name},
$_->{workspace}->{environment}->{name}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List tasks:'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['id', 'name', 'environmentName']);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->add_disco_entry(
id => $_->{executable},
name => $_->{name},
environmentName => $_->{workspace}->{environment}->{name}
);
}
}
1;
__END__
=head1 MODE
List tasks.
=over 8
=back
=cut

View File

@ -0,0 +1,388 @@
#
# Copyright 2023 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::talend::tmc::mode::plans;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use Digest::MD5;
use DateTime;
use POSIX;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::misc;
use centreon::plugins::statefile;
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_last_exec_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
instances => $self->{result_values}->{name},
unit => $self->{instance_mode}->{option_results}->{unit},
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_last_exec_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub custom_duration_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
instances => $self->{result_values}->{name},
unit => $self->{instance_mode}->{option_results}->{unit},
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_duration_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub plan_long_output {
my ($self, %options) = @_;
return sprintf(
"checking plan '%s'",
$options{instance_value}->{name}
);
}
sub prefix_plan_output {
my ($self, %options) = @_;
return sprintf(
"plan '%s' ",
$options{instance_value}->{name}
);
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Number of plans ';
}
sub prefix_execution_output {
my ($self, %options) = @_;
return sprintf(
"execution '%s' [started: %s] ",
$options{instance_value}->{executionId},
$options{instance_value}->{started}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
{
name => 'plans', type => 3, cb_prefix_output => 'prefix_plan_output', cb_long_output => 'plan_long_output', indent_long_output => ' ', message_multiple => 'All plans are ok',
group => [
{ name => 'failed', type => 0 },
{ name => 'timers', type => 0, skipped_code => { -10 => 1 } },
{ name => 'executions', type => 1, cb_prefix_output => 'prefix_execution_output', message_multiple => 'executions are ok', display_long => 1, skipped_code => { -10 => 1 } },
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'plans-executions-detected', display_ok => 0, nlabel => 'plans.executions.detected.count', set => {
key_values => [ { name => 'detected' } ],
output_template => 'executions detected: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{failed} = [
{ label => 'plan-executions-failed-prct', nlabel => 'plan.executions.failed.percentage', set => {
key_values => [ { name => 'failedPrct' } ],
output_template => 'number of failed executions: %.2f %%',
perfdatas => [
{ template => '%.2f', unit => '%', min => 0, max => 100, label_extra_instance => 1 }
]
}
}
];
$self->{maps_counters}->{timers} = [
{ label => 'plan-execution-last', nlabel => 'plan.execution.last', set => {
key_values => [ { name => 'lastExecSeconds' }, { name => 'lastExecHuman' }, { name => 'name' } ],
output_template => 'last execution %s',
output_use => 'lastExecHuman',
closure_custom_perfdata => $self->can('custom_last_exec_perfdata'),
closure_custom_threshold_check => $self->can('custom_last_exec_threshold')
}
},
{ label => 'plan-running-duration', nlabel => 'plan.running.duration', set => {
key_values => [ { name => 'durationSeconds' }, { name => 'durationHuman' }, { name => 'name' } ],
output_template => 'running duration %s',
output_use => 'durationHuman',
closure_custom_perfdata => $self->can('custom_duration_perfdata'),
closure_custom_threshold_check => $self->can('custom_duration_threshold')
}
}
];
$self->{maps_counters}->{executions} = [
{
label => 'execution-status',
type => 2,
critical_default => '%{status} =~ /execution_failed/i',
set => {
key_values => [
{ name => 'status' }, { name => 'planName' }
],
output_template => "status: %s",
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'plan-id:s' => { name => 'plan_id' },
'environment-name:s' => { name => 'environment_name' },
'since-timeperiod:s' => { name => 'since_timeperiod' },
'unit:s' => { name => 'unit', default => 's' }
});
$self->{cache_exec} = centreon::plugins::statefile->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
$self->{option_results}->{unit} = 's';
}
if (!defined($self->{option_results}->{since_timeperiod}) || $self->{option_results}->{since_timeperiod} eq '') {
$self->{option_results}->{since_timeperiod} = 86400;
}
$self->{cache_exec}->check_options(option_results => $self->{option_results}, default_format => 'json');
}
sub manage_selection {
my ($self, %options) = @_;
my $environments = $options{custom}->get_environments();
my $environmentId;
if (defined($self->{option_results}->{environment_name}) && $self->{option_results}->{environment_name} ne '') {
foreach (@$environments) {
if ($_->{name} eq $self->{option_results}->{environment_name}) {
$environmentId = $_->{id};
last;
}
}
if (!defined($environmentId)) {
$self->{output}->add_option_msg(short_msg => 'unknown environment name ' . $self->{option_results}->{environment_name});
$self->{output}->option_exit();
}
}
my $plans_config = $options{custom}->get_plans_config();
my $to = time();
my $plans_exec = $options{custom}->get_plans_execution(
from => ($to - $self->{option_results}->{since_timeperiod}) * 1000,
to => $to * 1000,
environmentId => $environmentId,
planId => $self->{option_results}->{plan_id}
);
$self->{cache_exec}->read(statefile => 'talend_tmc_' . $self->{mode} . '_' .
Digest::MD5::md5_hex(
(defined($self->{option_results}->{plan_id}) ? $self->{option_results}->{plan_id} : '') . '_' .
(defined($self->{option_results}->{environment_name}) ? $self->{option_results}->{environment_name} : '')
)
);
my $ctime = time();
my $last_exec_times = $self->{cache_exec}->get(name => 'plans');
$last_exec_times = {} if (!defined($last_exec_times));
$self->{global} = { detected => 0 };
$self->{plans} = {};
foreach my $plan (@$plans_config) {
next if (defined($self->{option_results}->{plan_id}) && $self->{option_results}->{plan_id} ne '' && $plan->{executable} ne $self->{option_results}->{plan_id});
next if (defined($environmentId) && $plan->{workspace}->{environment}->{id} ne $environmentId);
$self->{plans}->{ $plan->{name} } = {
name => $plan->{name},
timers => {},
executions => {}
};
my ($last_exec, $older_running_exec);
my ($failed, $total) = (0, 0);
foreach my $plan_exec (@$plans_exec) {
next if ($plan_exec->{planId} ne $plan->{executable});
if (!defined($plan_exec->{finishTimestamp})) {
$older_running_exec = $plan_exec;
}
if (!defined($last_exec)) {
$last_exec = $plan_exec;
}
$self->{global}->{detected}++;
$failed++ if ($plan_exec->{status} =~ /execution_failed/);
$total++;
}
$self->{plans}->{ $plan->{name} }->{failed} = {
failedPrct => $total > 0 ? $failed * 100 / $total : 0
};
if (defined($last_exec)) {
$self->{plans}->{ $plan->{name} }->{executions}->{ $last_exec->{executionId} } = {
executionId => $last_exec->{executionId},
planName => $plan->{name},
started => $last_exec->{startTimestamp},
status => $last_exec->{status}
};
$last_exec->{startTimestamp} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6);
$last_exec_times->{ $plan->{name} } = $dt->epoch();
}
$self->{plans}->{ $plan->{name} }->{timers} = {
name => $plan->{name},
lastExecSeconds => defined($last_exec_times->{ $plan->{name} }) ? $ctime - $last_exec_times->{ $plan->{name} } : -1,
lastExecHuman => 'never'
};
if (defined($last_exec_times->{ $plan->{name} })) {
$self->{plans}->{ $plan->{name} }->{timers}->{lastExecHuman} = centreon::plugins::misc::change_seconds(value => $ctime - $last_exec_times->{ $plan->{name} });
}
if (defined($older_running_exec)) {
$older_running_exec->{startTimestamp} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6);
my $duration = $ctime - $dt->epoch();
$self->{plans}->{ $plan->{name} }->{timers}->{durationSeconds} = $duration;
$self->{plans}->{ $plan->{name} }->{timers}->{durationHuman} = centreon::plugins::misc::change_seconds(value => $duration);
}
}
$self->{cache_exec}->write(data => {
plans => $last_exec_times
});
}
1;
__END__
=head1 MODE
Check plans.
=over 8
=item B<--plan-id>
Plan filter.
=item B<--environment-name>
Environment filter.
=item B<--since-timeperiod>
Time period to get plans execution informations (in seconds. Default: 86400).
=item B<--unit>
Select the unit for last execution time threshold. May be 's' for seconds, 'm' for minutes,
'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=item B<--unknown-execution-status>
Set unknown threshold for last plan execution status.
Can used special variables like: %{status}, %{planName}
=item B<--warning-execution-status>
Set warning threshold for last plan execution status.
Can used special variables like: %{status}, %{planName}
=item B<--critical-execution-status>
Set critical threshold for last plan execution status (Default: '{status} =~ /execution_failed/i').
Can used special variables like: %{status}, %{planName}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'plans-executions-detected', 'plan-executions-failed-prct',
'plan-execution-last', 'plan-running-duration'.
=back
=cut

View File

@ -0,0 +1,178 @@
#
# Copyright 2023 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::talend::tmc::mode::remoteengines;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
'status: %s [availability: %s]',
$self->{result_values}->{status},
$self->{result_values}->{availability}
);
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Number of remote engines ';
}
sub prefix_engine_output {
my ($self, %options) = @_;
return sprintf(
"remote engine '%s' ",
$options{instance_value}->{name}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
{ name => 'engines', type => 1, cb_prefix_output => 'prefix_engine_output', message_multiple => 'All remote engines are ok', skipped_code => { -10 => 1 } }
];
$self->{maps_counters}->{global} = [
{ label => 'remote-engines-detected', display_ok => 0, nlabel => 'remote_engines.detected.count', set => {
key_values => [ { name => 'detected' } ],
output_template => 'detected: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'remote-engines-unpaired', display_ok => 0, nlabel => 'remote_engines.unpaired.count', set => {
key_values => [ { name => 'unpaired' }, { name => 'detected' } ],
output_template => 'unpaired: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'detected' }
]
}
}
];
$self->{maps_counters}->{engines} = [
{
label => 'status',
type => 2,
critical_default => '%{availability} !~ /retired/ and %{status} =~ /unpaired/i',
set => {
key_values => [
{ name => 'status' }, { name => 'availability' }, { name => 'name' }
],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-name:s' => { name => 'filter_name' },
'filter-environment-name:s' => { name => 'filter_environment_name' }
});
return $self;
}
my $map_availability = { AVAILABLE => 'available', NOT_AVAILABLE => 'notAvailable', RETIRED => 'retired' };
my $map_status = { PAIRED => 'paired', NOT_PAIRED => 'unpaired' };
sub manage_selection {
my ($self, %options) = @_;
my $engines = $options{custom}->get_remote_engines();
$self->{global} = { detected => 0, unpaired => 0 };
$self->{tasks} = {};
foreach my $engine (@$engines) {
next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$engine->{name} !~ /$self->{option_results}->{filter_name}/);
next if (defined($self->{option_results}->{filter_environment_name}) && $self->{option_results}->{filter_environment_name} ne '' &&
$engine->{workspace}->{environment}->{name} !~ /$self->{option_results}->{filter_environment_name}/);
$self->{engines}->{ $engine->{name} } = {
name => $engine->{name},
availability => $map_availability->{ $engine->{availability} },
status => $map_status->{ $engine->{status} }
};
$self->{global}->{detected}++;
$self->{global}->{unpaired}++ if ($engine->{status} eq 'NOT_PAIRED');
}
}
1;
__END__
=head1 MODE
Check remote engines.
=over 8
=item B<--filter-name>
Remote engine name filter (Can be a regexp).
=item B<--filter-environment-name>
Environment filter (Can be a regexp).
=item B<--unknown-status>
Set unknown threshold for status.
Can used special variables like: %{status}, %{availability}, %{name}
=item B<--warning-status>
Set warning threshold for status.
Can used special variables like: %{status}, %{availability}, %{name}
=item B<--critical-status>
Set critical threshold for status (Default: '%{availability} !~ /retired/ and %{status} =~ /unpaired/i').
Can used special variables like: %{status}, %{availability}, %{name}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'remote-engines-detected', 'remote-engines-unpaired'.
=back
=cut

View File

@ -0,0 +1,388 @@
#
# Copyright 2023 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::talend::tmc::mode::tasks;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use Digest::MD5;
use DateTime;
use POSIX;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::misc;
use centreon::plugins::statefile;
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_last_exec_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
instances => $self->{result_values}->{name},
unit => $self->{instance_mode}->{option_results}->{unit},
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_last_exec_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub custom_duration_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
instances => $self->{result_values}->{name},
unit => $self->{instance_mode}->{option_results}->{unit},
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_duration_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub task_long_output {
my ($self, %options) = @_;
return sprintf(
"checking task '%s'",
$options{instance_value}->{name}
);
}
sub prefix_task_output {
my ($self, %options) = @_;
return sprintf(
"task '%s' ",
$options{instance_value}->{name}
);
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Number of tasks ';
}
sub prefix_execution_output {
my ($self, %options) = @_;
return sprintf(
"execution '%s' [started: %s] ",
$options{instance_value}->{executionId},
$options{instance_value}->{started}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
{
name => 'tasks', type => 3, cb_prefix_output => 'prefix_task_output', cb_long_output => 'task_long_output', indent_long_output => ' ', message_multiple => 'All tasks are ok',
group => [
{ name => 'failed', type => 0 },
{ name => 'timers', type => 0, skipped_code => { -10 => 1 } },
{ name => 'executions', type => 1, cb_prefix_output => 'prefix_execution_output', message_multiple => 'executions are ok', display_long => 1, skipped_code => { -10 => 1 } },
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'tasks-executions-detected', display_ok => 0, nlabel => 'tasks.executions.detected.count', set => {
key_values => [ { name => 'detected' } ],
output_template => 'executions detected: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{failed} = [
{ label => 'task-executions-failed-prct', nlabel => 'task.executions.failed.percentage', set => {
key_values => [ { name => 'failedPrct' } ],
output_template => 'number of failed executions: %.2f %%',
perfdatas => [
{ template => '%.2f', unit => '%', min => 0, max => 100, label_extra_instance => 1 }
]
}
}
];
$self->{maps_counters}->{timers} = [
{ label => 'task-execution-last', nlabel => 'task.execution.last', set => {
key_values => [ { name => 'lastExecSeconds' }, { name => 'lastExecHuman' }, { name => 'name' } ],
output_template => 'last execution %s',
output_use => 'lastExecHuman',
closure_custom_perfdata => $self->can('custom_last_exec_perfdata'),
closure_custom_threshold_check => $self->can('custom_last_exec_threshold')
}
},
{ label => 'task-running-duration', nlabel => 'task.running.duration', set => {
key_values => [ { name => 'durationSeconds' }, { name => 'durationHuman' }, { name => 'name' } ],
output_template => 'running duration %s',
output_use => 'durationHuman',
closure_custom_perfdata => $self->can('custom_duration_perfdata'),
closure_custom_threshold_check => $self->can('custom_duration_threshold')
}
}
];
$self->{maps_counters}->{executions} = [
{
label => 'execution-status',
type => 2,
critical_default => '%{status} =~ /deploy_failed|execution_rejected|execution_failed|terminated_timeout/i',
set => {
key_values => [
{ name => 'status' }, { name => 'taskName' }
],
output_template => "status: %s",
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'task-id:s' => { name => 'task_id' },
'environment-name:s' => { name => 'environment_name' },
'since-timeperiod:s' => { name => 'since_timeperiod' },
'unit:s' => { name => 'unit', default => 's' }
});
$self->{cache_exec} = centreon::plugins::statefile->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
$self->{option_results}->{unit} = 's';
}
if (!defined($self->{option_results}->{since_timeperiod}) || $self->{option_results}->{since_timeperiod} eq '') {
$self->{option_results}->{since_timeperiod} = 86400;
}
$self->{cache_exec}->check_options(option_results => $self->{option_results}, default_format => 'json');
}
sub manage_selection {
my ($self, %options) = @_;
my $environments = $options{custom}->get_environments();
my $environmentId;
if (defined($self->{option_results}->{environment_name}) && $self->{option_results}->{environment_name} ne '') {
foreach (@$environments) {
if ($_->{name} eq $self->{option_results}->{environment_name}) {
$environmentId = $_->{id};
last;
}
}
if (!defined($environmentId)) {
$self->{output}->add_option_msg(short_msg => 'unknown environment name ' . $self->{option_results}->{environment_name});
$self->{output}->option_exit();
}
}
my $tasks_config = $options{custom}->get_tasks_config();
my $to = time();
my $tasks_exec = $options{custom}->get_tasks_execution(
from => ($to - $self->{option_results}->{since_timeperiod}) * 1000,
to => $to * 1000,
environmentId => $environmentId,
taskId => $self->{option_results}->{task_id}
);
$self->{cache_exec}->read(statefile => 'talend_tmc_' . $self->{mode} . '_' .
Digest::MD5::md5_hex(
(defined($self->{option_results}->{task_id}) ? $self->{option_results}->{task_id} : '') . '_' .
(defined($self->{option_results}->{environment_name}) ? $self->{option_results}->{environment_name} : '')
)
);
my $ctime = time();
my $last_exec_times = $self->{cache_exec}->get(name => 'tasks');
$last_exec_times = {} if (!defined($last_exec_times));
$self->{global} = { detected => 0 };
$self->{tasks} = {};
foreach my $task (@$tasks_config) {
next if (defined($self->{option_results}->{task_id}) && $self->{option_results}->{task_id} ne '' && $task->{executable} ne $self->{option_results}->{task_id});
next if (defined($environmentId) && $task->{workspace}->{environment}->{id} ne $environmentId);
$self->{tasks}->{ $task->{name} } = {
name => $task->{name},
timers => {},
executions => {}
};
my ($last_exec, $older_running_exec);
my ($failed, $total) = (0, 0);
foreach my $task_exec (@$tasks_exec) {
next if ($task_exec->{taskId} ne $task->{executable});
if (!defined($task_exec->{finishTimestamp})) {
$older_running_exec = $task_exec;
}
if (!defined($last_exec)) {
$last_exec = $task_exec;
}
$self->{global}->{detected}++;
$failed++ if ($task_exec->{status} =~ /deploy_failed|execution_rejected|execution_failed|terminated_timeout/);
$total++;
}
$self->{tasks}->{ $task->{name} }->{failed} = {
failedPrct => $total > 0 ? $failed * 100 / $total : 0
};
if (defined($last_exec)) {
$self->{tasks}->{ $task->{name} }->{executions}->{ $last_exec->{executionId} } = {
executionId => $last_exec->{executionId},
taskName => $task->{name},
started => $last_exec->{startTimestamp},
status => $last_exec->{status}
};
$last_exec->{startTimestamp} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6);
$last_exec_times->{ $task->{name} } = $dt->epoch();
}
$self->{tasks}->{ $task->{name} }->{timers} = {
name => $task->{name},
lastExecSeconds => defined($last_exec_times->{ $task->{name} }) ? $ctime - $last_exec_times->{ $task->{name} } : -1,
lastExecHuman => 'never'
};
if (defined($last_exec_times->{ $task->{name} })) {
$self->{tasks}->{ $task->{name} }->{timers}->{lastExecHuman} = centreon::plugins::misc::change_seconds(value => $ctime - $last_exec_times->{ $task->{name} });
}
if (defined($older_running_exec)) {
$older_running_exec->{startTimestamp} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6);
my $duration = $ctime - $dt->epoch();
$self->{tasks}->{ $task->{name} }->{timers}->{durationSeconds} = $duration;
$self->{tasks}->{ $task->{name} }->{timers}->{durationHuman} = centreon::plugins::misc::change_seconds(value => $duration);
}
}
$self->{cache_exec}->write(data => {
tasks => $last_exec_times
});
}
1;
__END__
=head1 MODE
Check tasks.
=over 8
=item B<--task-id>
Task filter.
=item B<--environment-name>
Environment filter.
=item B<--since-timeperiod>
Time period to get tasks execution informations (in seconds. Default: 86400).
=item B<--unit>
Select the unit for last execution time threshold. May be 's' for seconds, 'm' for minutes,
'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=item B<--unknown-execution-status>
Set unknown threshold for last task execution status.
Can used special variables like: %{status}, %{taskName}
=item B<--warning-execution-status>
Set warning threshold for last task execution status.
Can used special variables like: %{status}, %{taskName}
=item B<--critical-execution-status>
Set critical threshold for last task execution status (Default: %{status} =~ /deploy_failed|execution_rejected|execution_failed|terminated_timeout/i).
Can used special variables like: %{status}, %{taskName}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'tasks-executions-detected', 'task-executions-failed-prct',
'task-execution-last', 'task-running-duration'.
=back
=cut

View File

@ -0,0 +1,55 @@
#
# Copyright 2023 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::talend::tmc::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{modes} = {
'cache' => 'cloud::talend::tmc::mode::cache',
'list-environments' => 'cloud::talend::tmc::mode::listenvironments',
'list-plans' => 'cloud::talend::tmc::mode::listplans',
'list-remote-engines' => 'cloud::talend::tmc::mode::listremoteengines',
'list-tasks' => 'cloud::talend::tmc::mode::listtasks',
'plans' => 'cloud::talend::tmc::mode::plans',
'remote-engines' => 'cloud::talend::tmc::mode::remoteengines',
'tasks' => 'cloud::talend::tmc::mode::tasks'
};
$self->{custom_modes}->{api} = 'cloud::talend::tmc::custom::api';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Talend Cloud Management Console using API.
=cut