[CTOR-284] new Datacore plugin with rest api (#4896)
Co-authored-by: Sophie Depassio <sdepassio@centreon.com>
This commit is contained in:
parent
058620c545
commit
321806011f
|
@ -1,14 +1,17 @@
|
|||
--filter-vdom
|
||||
--force-counters32
|
||||
Centreon
|
||||
Fortinet
|
||||
Datacore
|
||||
Fortigate
|
||||
Fortinet
|
||||
license-instances-usage-prct
|
||||
MBean
|
||||
OID
|
||||
oneaccess-sys-mib
|
||||
perfdata
|
||||
powershell
|
||||
proto
|
||||
Sansymphony
|
||||
queue-messages-inflighted
|
||||
SNMP
|
||||
space-usage-prct
|
||||
|
|
|
@ -30,10 +30,10 @@ jobs:
|
|||
- name: Install Node.js
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
|
||||
- name: Install Mockoon CLI
|
||||
run: npm install -g -D @mockoon/cli@3.1.0
|
||||
run: npm install -g -D @mockoon/cli@6.2.0
|
||||
|
||||
- name: Install perl dependencies
|
||||
uses: shogo82148/actions-setup-perl@28eae78d12c2bba1163aec45d123f6d9228bc307 # v1.29.0
|
||||
|
|
|
@ -943,9 +943,9 @@ List of methods:
|
|||
* **new**: class constructor. Overload if you need to add some specific options
|
||||
or to use a statefile.
|
||||
* **check_options**: overload if you need to check your specific options.
|
||||
* **manage_selection**: overload if *mandatory*. Method to get informations for
|
||||
* **manage_selection**: overload is *mandatory*. Method to get informations for
|
||||
the equipment.
|
||||
* **set_counters**: overload if **mandatory**. Method to configure counters.
|
||||
* **set_counters**: overload is **mandatory**. Method to configure counters.
|
||||
|
||||
**Class hardware**
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"dependencies": [
|
||||
]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"pkg_name": "centreon-plugin-Hardware-Storage-DataCore-Sansymphony-Restapi",
|
||||
"pkg_summary": "Centreon Plugin",
|
||||
"plugin_name": "centreon_datacore_api.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_custom.pm",
|
||||
"storage/datacore/api/"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"dependencies": [
|
||||
]
|
||||
}
|
|
@ -311,6 +311,14 @@ sub backtick {
|
|||
return (0, join("\n", @output), $return_code);
|
||||
}
|
||||
|
||||
sub is_empty {
|
||||
my $value = shift;
|
||||
if (!defined($value) or $value eq '') {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub trim {
|
||||
my ($value) = $_[0];
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
#
|
||||
# Copyright 2024 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 storage::datacore::restapi::custom::api;
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::http;
|
||||
use centreon::plugins::statefile;
|
||||
use JSON::XS;
|
||||
use centreon::plugins::misc qw(empty);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
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();
|
||||
}
|
||||
my $self = {};
|
||||
bless $self, $class;
|
||||
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'hostname:s' => { name => 'hostname' },
|
||||
'port:s' => { name => 'port', default => 443 },
|
||||
'proto:s' => { name => 'proto', default => 'https' },
|
||||
'timeout:s' => { name => 'timeout' },
|
||||
'username:s' => { name => 'username' },
|
||||
'password:s' => { name => 'password' },
|
||||
'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, default_backend => 'curl');
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub set_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{option_results} = $options{option_results};
|
||||
}
|
||||
sub set_defaults {}
|
||||
|
||||
# hostname,username and password are required options
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->{http}->set_options(%{$self->{option_results}});
|
||||
|
||||
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 50;
|
||||
|
||||
if (centreon::plugins::misc::is_empty($self->{option_results}->{hostname})) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Please set hostname option');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if (centreon::plugins::misc::is_empty($self->{option_results}->{username})) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Please set username option to authenticate against datacore rest api');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if (centreon::plugins::misc::is_empty($self->{option_results}->{password})) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Please set password option to authenticate against datacore rest api');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub settings {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return if (defined($self->{settings_done}));
|
||||
$self->{http}->add_header(key => 'ServerHost', value => $self->{option_results}->{hostname});
|
||||
$self->{http}->set_options(basic => 1, credentials => 1);
|
||||
$self->{settings_done} = 1;
|
||||
}
|
||||
|
||||
# wrapper around centreon::plugins::http::request to add authentication and decode json.
|
||||
# output : deserialized json from the api if not error found in http call.
|
||||
sub request_api {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
# datacore api require a ServerHost header with the hostname used to query the api to respond.
|
||||
# authentication is http standard basic auth.
|
||||
my $result = $self->{http}->request(
|
||||
username => $self->{option_results}->{username},
|
||||
password => $self->{option_results}->{password},
|
||||
unknown_status => $self->{option_results}->{unknown_http_status},
|
||||
warning_status => $self->{option_results}->{warning_http_status},
|
||||
critical_status => $self->{option_results}->{critical_http_status},
|
||||
%options,
|
||||
);
|
||||
# Declare a scalar to deserialize the JSON content string into a perl data structure
|
||||
my $decoded_content;
|
||||
eval {
|
||||
$decoded_content = JSON::XS->new->decode($result);
|
||||
};
|
||||
# Catch the error that may arise in case the data received is not JSON
|
||||
if ($@) {
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot decode JSON result");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
return $decoded_content;
|
||||
|
||||
}
|
||||
1;
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Datacore Sansymphony Rest API
|
||||
|
||||
=head1 REST API OPTIONS
|
||||
|
||||
Datacore Sansymphony Rest API
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--hostname>
|
||||
|
||||
Address of the Datacore server that hosts the API endpoint.
|
||||
|
||||
=item B<--port>
|
||||
|
||||
Port of the resource to connect to (default: 443).
|
||||
|
||||
=item B<--proto>
|
||||
|
||||
HTTP protocol, either http or https (default: 'https')
|
||||
|
||||
=item B<--username>
|
||||
|
||||
Username to access the endpoint.
|
||||
|
||||
=item B<--password>
|
||||
|
||||
Password to access the endpoint.
|
||||
|
||||
=item B<--timeout>
|
||||
|
||||
Set timeout in seconds (default: 10).
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<custom>.
|
|
@ -0,0 +1,174 @@
|
|||
#
|
||||
# Copyright 2024 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 storage::datacore::restapi::mode::alerts;
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::misc qw(empty);
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
my %alerts_level = ('trace' => 0, 'info' => 1, 'warning' => 2, 'error' => 3);
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'alerts', type => 0},
|
||||
];
|
||||
$self->{maps_counters}->{alerts} = [
|
||||
{
|
||||
label => 'error',
|
||||
nlabel => 'datacore.event.error.count',
|
||||
set => {
|
||||
key_values => [ { name => 'error' } ],
|
||||
output_template => 'number of error alerts : %s',
|
||||
perfdatas => [ { template => '%d', min => 0 } ]
|
||||
}
|
||||
}, {
|
||||
label => 'warning',
|
||||
nlabel => 'datacore.alerts.warning.count',
|
||||
set => {
|
||||
key_values => [ { name => 'warning' } ],
|
||||
output_template => 'number of warning alerts : %s',
|
||||
perfdatas => [ { template => '%d', min => 0 } ]
|
||||
}
|
||||
}, {
|
||||
label => 'info',
|
||||
nlabel => 'datacore.alerts.info.count',
|
||||
set => {
|
||||
key_values => [ { name => 'info' } ],
|
||||
output_template => 'number of info alerts : %s',
|
||||
perfdatas => [ { template => '%d', min => 0 } ]
|
||||
}
|
||||
}, {
|
||||
label => 'trace',
|
||||
nlabel => 'datacore.alerts.trace.count',
|
||||
set => {
|
||||
key_values => [ { name => 'trace' } ],
|
||||
output_template => 'number of trace alerts : %s',
|
||||
perfdatas => [ { template => '%d', min => 0 } ]
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
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-server:s' => { name => 'filter_server' },
|
||||
'max-alert-age:s' => { name => 'max_alert_age' } });
|
||||
|
||||
$self->{output} = $options{output};
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $alerts = $options{custom}->request_api(
|
||||
url_path => '/RestService/rest.svc/1.0/alerts'
|
||||
);
|
||||
|
||||
my %alerts_count = (
|
||||
0 => { count => 0, list => [] },
|
||||
1 => { count => 0, list => [] },
|
||||
2 => { count => 0, list => [] },
|
||||
3 => { count => 0, list => [] });
|
||||
|
||||
for my $alert (@$alerts) {
|
||||
|
||||
# spec require to filter on time of the log.
|
||||
$alert->{TimeStamp} =~ /\/Date\((\d+)\)\/$/;
|
||||
my $alert_date = $1;
|
||||
if (centreon::plugins::misc::is_empty($alert_date) or $alert_date !~ /^[0-9]*[.,]?\d*$/){
|
||||
$self->{output}->output_add(long_msg => "alert on $alert->{MachineName} have an invalid date : $alert->{TimeStamp}\n", debug => 1);
|
||||
next;
|
||||
}
|
||||
|
||||
# filter on age of the alert with a user defined max age
|
||||
next if (defined($self->{option_results}->{max_alert_age})
|
||||
and $alert_date < (time - $self->{option_results}->{max_alert_age}) * 1000);
|
||||
# filter on the machine issuing the alert with a user defined regex
|
||||
|
||||
if (!centreon::plugins::misc::is_empty($self->{option_results}->{filter_server})
|
||||
and $alert->{MachineName} !~ $self->{option_results}->{filter_server}) {
|
||||
$self->{output}->output_add(long_msg => "excluding alert from machine $alert->{MachineName}\n", debug => 1);
|
||||
next;
|
||||
}
|
||||
|
||||
$alerts_count{$alert->{Level}}->{count}++;
|
||||
# we don't want to clog the long output, so we keep only the few first logs.
|
||||
# we use a array instead of directly adding to long_output because we need to sort errors
|
||||
if (scalar(@{$alerts_count{$alert->{Level}}->{list}}) < 50) {
|
||||
push(@{$alerts_count{$alert->{Level}}->{list}}, $alert->{MessageText})
|
||||
}
|
||||
}
|
||||
|
||||
$self->{output}->output_add(long_msg => "error : " . join("\n", @{$alerts_count{$alerts_level{error}}->{list}}));
|
||||
$self->{output}->output_add(long_msg => "warning : " . join("\n", @{$alerts_count{$alerts_level{warning}}->{list}}));
|
||||
|
||||
|
||||
|
||||
$self->{alerts} = {
|
||||
trace => $alerts_count{$alerts_level{trace}}->{count},
|
||||
info => $alerts_count{$alerts_level{info}}->{count},
|
||||
warning => $alerts_count{$alerts_level{warning}}->{count},
|
||||
error => $alerts_count{$alerts_level{error}}->{count},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check Datacore alerts number exposed through the rest api
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--max-alert-age>
|
||||
|
||||
filter alerts to check those newer than this parameter (s)
|
||||
|
||||
=item B<--filter-server>
|
||||
|
||||
Define which devices should be monitored based on the MachineName. This option will be treated as a regular expression.
|
||||
By default all machine will be checked.
|
||||
|
||||
=item B<--warning/critical-*>
|
||||
|
||||
Warning and critical threshold on the number of alerts of a type before changing state.
|
||||
Replace * with trace, alert, warning, or error.
|
||||
|
||||
=back
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#
|
||||
# Copyright 2024 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 storage::datacore::restapi::mode::listpool;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(centreon::plugins::mode);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
});
|
||||
|
||||
|
||||
return $self;
|
||||
}
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
$self->{pools} = ();
|
||||
my $pool_list = $options{custom}->request_api(
|
||||
url_path => '/RestService/rest.svc/1.0/pools');
|
||||
|
||||
if (scalar(@$pool_list) == 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No pool found in api response.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
for my $pool (@$pool_list) {
|
||||
next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne ''
|
||||
&& $pool->{Alias} !~ /$self->{option_results}->{filter_name}/);
|
||||
push(@{$self->{pools}}, {
|
||||
ExtendedCaption => $pool->{ExtendedCaption},
|
||||
Caption => $pool->{Caption},
|
||||
Id => $pool->{Id},
|
||||
Alias => $pool->{Alias}}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
$self->manage_selection(%options);
|
||||
if (scalar $self->{pools} == 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No pool found.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
foreach (sort @{$self->{pools}}) {
|
||||
$self->{output}->output_add(long_msg => sprintf("[ExtendedCaption = %s] [Caption = %s] [Id = %s] [Alias = %s]",
|
||||
$_->{ExtendedCaption}, $_->{Caption}, $_->{Id}, $_->{Alias}));
|
||||
}
|
||||
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List pools : '
|
||||
);
|
||||
$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 => ['ExtendedCaption', 'Caption', 'Id', 'Alias']);
|
||||
}
|
||||
|
||||
sub disco_show {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->manage_selection(%options);
|
||||
|
||||
foreach (sort @{$self->{pools}}) {
|
||||
$self->{output}->add_disco_entry(ExtendedCaption => $_->{ExtendedCaption}, Caption => $_->{Caption},
|
||||
Id => $_->{Id}, Id => $_->{Id}, Alias => $_->{Alias});
|
||||
}
|
||||
}
|
||||
1;
|
||||
|
||||
=head1 MODE
|
||||
|
||||
List pools.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter pool name (can be a regexp).
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,148 @@
|
|||
#
|
||||
# Copyright 2024 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 storage::datacore::restapi::mode::monitorstatus;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
use JSON::XS;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
use centreon::plugins::misc qw(empty);
|
||||
|
||||
my %monitor_state = (1 => "Undefined", 2 => "Healthy", 4 => "Attention", 8 => "Warning", 16 => "Critical");
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
my $res = sprintf(
|
||||
"'%s' status : '%s', message is '%s'",
|
||||
$self->{result_values}->{extendedcaption},
|
||||
$self->{result_values}->{state},
|
||||
$self->{result_values}->{messagetext}
|
||||
);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 1, message_multiple => 'All memory usages are ok', skipped_code => { -10 => 1 } }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'state',
|
||||
type => 2,
|
||||
warning_default => '%{state} =~ /Warning/i',
|
||||
critical_default => '%{state} =~ /Critical/i',
|
||||
set => {
|
||||
key_values => [ { name => 'state' }, { name => 'extendedcaption' }, { name => 'messagetext' } ],
|
||||
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-caption:s' => { name => 'filter_caption' } });
|
||||
$self->{cache} = centreon::plugins::statefile->new(%options);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
$self->{cache}->check_options(option_results => $self->{option_results});
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if ($self->{cache}->read('statefile' => 'datacore_api_monitors' . md5_hex($self->{option_results}->{hostname} . $self->{option_results}->{username}))
|
||||
and $self->{cache}->get(name => 'expires_on') > time() + 1) {
|
||||
|
||||
return $self->{cache}->get(name => 'monitor_data');
|
||||
}
|
||||
|
||||
my $monitor_data = $options{custom}->request_api(
|
||||
url_path => '/RestService/rest.svc/1.0/monitors');
|
||||
|
||||
my $datas = { last_timestamp => time(), monitor_data => $monitor_data, expires_on => time() + 60 };
|
||||
$self->{cache}->write(data => $datas);
|
||||
|
||||
my $monitored_count = 0;
|
||||
for my $object (@$monitor_data) {
|
||||
|
||||
if (!centreon::plugins::misc::is_empty($self->{option_results}->{filter_caption})
|
||||
and $object->{ExtendedCaption} !~ $self->{option_results}->{filter_caption}) {
|
||||
next;
|
||||
}
|
||||
$self->{global}->{$monitored_count} = {
|
||||
state => $monitor_state{$object->{State}},
|
||||
messagetext => $object->{MessageText},
|
||||
extendedcaption => $object->{ExtendedCaption}
|
||||
};
|
||||
$monitored_count++;
|
||||
}
|
||||
# for now if no data is given to the counter, output is OK: with status ok, instead of unknown.
|
||||
# We manage this case in each plugin for now.
|
||||
if ($monitored_count == 0) {
|
||||
$self->{output}->add_option_msg(short_msg => 'No monitors where checked, please check filter_caption parameter and api response.');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
}
|
||||
|
||||
# as --filter-caption allow to filter element to check and this api don't allow parameter filtering, we should cache
|
||||
# the output in case a client make multiples check a minute.
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check Datacore monitor status exposed through the rest api.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-caption>
|
||||
|
||||
Define which element should be monitored based on the extended caption. This option will be treated as a regular expression.
|
||||
By default all elements will be checked.
|
||||
|
||||
=item B<--warning-state> B<--critical-state>
|
||||
|
||||
define which output from the api should be considered warning or critical.
|
||||
|
||||
warning_default = '%{state} =~ /Warning/i',
|
||||
|
||||
critical_default = '%{state} =~ /Critical/i',
|
||||
|
||||
possible value for state : Undefined, Healthy, Attention, Warning, Critical.
|
||||
|
||||
=back
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
#
|
||||
# Copyright 2024 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 storage::datacore::restapi::mode::poolspaceusage;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
use JSON::XS;
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
# BytesAllocatedPercentage is the disk usage of the pool
|
||||
# in datacore you can make thin provisionning, where you give to each partition more than what you really have.
|
||||
# oversubscribed is the number of Bytes allocated minus the number of bytes present in the system.
|
||||
{ name => 'BytesAllocatedPercentage', type => 0 },
|
||||
{ name => 'oversubscribed', type => 0 },
|
||||
];
|
||||
$self->{maps_counters}->{BytesAllocatedPercentage} = [
|
||||
|
||||
{
|
||||
label => 'bytesallocatedpercentage',
|
||||
nlabel => 'datacore.pool.bytesallocated.percentage',
|
||||
set => {
|
||||
key_values => [ { name => 'bytesallocatedpercentage' } ],
|
||||
output_template => 'Bytes Allocated : %s %%',
|
||||
perfdatas => [
|
||||
{ template => '%d', unit => '%', min => 0, max => 100 }
|
||||
]
|
||||
}
|
||||
} ];
|
||||
$self->{maps_counters}->{oversubscribed} = [ {
|
||||
label => 'oversubscribed',
|
||||
nlabel => 'datacore.pool.oversubscribed.bytes',
|
||||
set => {
|
||||
key_values => [ { name => 'oversubscribed' } ],
|
||||
output_template => 'Over subscribed bytes : %s',
|
||||
perfdatas => [
|
||||
{ template => '%d', unit => 'bytes', min => 0 }
|
||||
]
|
||||
}
|
||||
} ];
|
||||
}
|
||||
|
||||
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 => {
|
||||
'pool-id:s' => { name => 'pool_id' } });
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
if (centreon::plugins::misc::is_empty($self->{option_results}->{pool_id})) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Please set pool-id option');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $data = $options{custom}->request_api(
|
||||
url_path => '/RestService/rest.svc/1.0/performances/' . $self->{option_results}->{pool_id},
|
||||
);
|
||||
if (defined($data->[1])) {
|
||||
$self->{output}->add_option_msg(short_msg => 'multiples pools found in api response, only one is expected. Please check pool_id and datacore versions.');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
$self->{BytesAllocatedPercentage}->{bytesallocatedpercentage} = $data->[0]->{"BytesAllocatedPercentage"};
|
||||
$self->{oversubscribed}->{oversubscribed} = $data->[0]->{"BytesOverSubscribed"};
|
||||
|
||||
}
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check Datacore pool space and over subscribed usage exposed through the rest api.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--pool-id>
|
||||
|
||||
Id of the pool to check. See list-pool autodiscovery mode to list pools id (required).
|
||||
|
||||
=item B<--warning-oversubscribed> B<--critical-oversubscribed>
|
||||
|
||||
Warning and critical threshold on the number of Bytes suscribed over the real space of the pool.
|
||||
|
||||
=item B<--warning-bytesallocatedpercentage> B<--critical-bytesallocatedpercentage>
|
||||
|
||||
Warning and critical threshold on the percentage of bytes allocated in the pool.
|
||||
|
||||
=back
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package storage::datacore::restapi::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;
|
||||
|
||||
# A version, we don't really use it but could help if your want to version your code
|
||||
$self->{version} = '0.1';
|
||||
|
||||
$self->{modes} = {
|
||||
'pool-usage' => 'storage::datacore::restapi::mode::poolspaceusage',
|
||||
'alerts' => 'storage::datacore::restapi::mode::alerts',
|
||||
'list-pool' => 'storage::datacore::restapi::mode::listpool',
|
||||
'status-monitor' => 'storage::datacore::restapi::mode::monitorstatus',
|
||||
};
|
||||
$self->{custom_modes}->{api} = 'storage::datacore::restapi::custom::api';
|
||||
return $self;
|
||||
}
|
||||
1;
|
||||
=head1 PLUGIN DESCRIPTION
|
||||
|
||||
Check Datacore using rest API.
|
||||
|
|
@ -153,6 +153,7 @@ AWS CloudTrail check trail status
|
|||
FOR ${checktrailstatus_value} IN @{checktrailstatus_values}
|
||||
${output} Run
|
||||
... ${CMD} --mode=checktrailstatus --endpoint=http://localhost:3000/cloudtrail/gettrailstatus/${checktrailstatus_value.trailstatus} --trail-name=${checktrailstatus_value.trailname}
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${checktrailstatus_value.result}
|
||||
|
@ -188,6 +189,7 @@ AWS CloudTrail count events
|
|||
${command} Catenate ${command} --critical-count=${countevents_value.criticalcount}
|
||||
END
|
||||
${output} Run ${command}
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${countevents_value.result}
|
||||
|
@ -204,13 +206,7 @@ Start Mockoon
|
|||
... ${MOCKOON_JSON}
|
||||
... --port
|
||||
... 3000
|
||||
... --pname
|
||||
... aws-cloudtrail
|
||||
Wait For Process ${process}
|
||||
Sleep 5s
|
||||
|
||||
Stop Mockoon
|
||||
${process} Start Process
|
||||
... mockoon-cli
|
||||
... stop
|
||||
... mockoon-aws-cloudtrail
|
||||
Wait For Process ${process}
|
||||
Terminate All Processes
|
|
@ -14,29 +14,29 @@ Test Timeout 120s
|
|||
${CENTREON_PLUGINS} ${CURDIR}${/}..${/}..${/}..${/}src${/}centreon_plugins.pl
|
||||
${MOCKOON_JSON} ${CURDIR}${/}..${/}..${/}resources${/}mockoon${/}cloud-azure-policyinsights-policystates.json
|
||||
|
||||
${LOGIN_ENDPOINT} http://localhost:3000/login
|
||||
${LOGIN_ENDPOINT} http://localhost:3001/login
|
||||
${CMD} perl ${CENTREON_PLUGINS} --plugin=cloud::azure::policyinsights::policystates::plugin --subscription=subscription --tenant=tenant --client-id=client_id --client-secret=secret --login-endpoint=${LOGIN_ENDPOINT}
|
||||
|
||||
&{compliance_value1}
|
||||
... endpoint=http://localhost:3000/ok
|
||||
... endpoint=http://localhost:3001/ok
|
||||
... policyname=
|
||||
... resourcelocation=
|
||||
... resourcetype=
|
||||
... result=OK: Number of non compliant policies: 0 - All compliances states are ok | 'policies.non_compliant.count'=0;;;0;
|
||||
&{compliance_value2}
|
||||
... endpoint=http://localhost:3000/oknextlink
|
||||
... endpoint=http://localhost:3001/oknextlink
|
||||
... policyname=9daedab3-fb2d-461e-b861-71790eead4f6
|
||||
... resourcelocation=
|
||||
... resourcetype=
|
||||
... result=OK: Number of non compliant policies: 0 - All compliances states are ok | 'policies.non_compliant.count'=0;;;0;
|
||||
&{compliance_value3}
|
||||
... endpoint=http://localhost:3000/nok1
|
||||
... endpoint=http://localhost:3001/nok1
|
||||
... policyname=9daedab3-fb2d-461e-b861-71790eead4f6
|
||||
... resourcelocation=fr
|
||||
... resourcetype=
|
||||
... result=CRITICAL: Compliance state for policy '9daedab3-fb2d-461e-b861-71790eead4f6' on resource 'mypubip1' is 'NonCompliant' | 'policies.non_compliant.count'=1;;;0;
|
||||
&{compliance_value4}
|
||||
... endpoint=http://localhost:3000/nok2
|
||||
... endpoint=http://localhost:3001/nok2
|
||||
... policyname=9daedab3-fb2d-461e-b861-71790eead4f6
|
||||
... resourcelocation=fr
|
||||
... resourcetype=ip
|
||||
|
@ -66,6 +66,7 @@ Azure PolicyInsights PolicyStates compliance
|
|||
${command} Catenate ${command} --resource-type=${compliance_value.resourcetype}
|
||||
END
|
||||
${output} Run ${command}
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${compliance_value.result}
|
||||
|
@ -82,13 +83,7 @@ Start Mockoon
|
|||
... ${MOCKOON_JSON}
|
||||
... --port
|
||||
... 3000
|
||||
... --pname
|
||||
... azure-policyinsights
|
||||
Wait For Process ${process}
|
||||
Sleep 5s
|
||||
|
||||
Stop Mockoon
|
||||
${process} Start Process
|
||||
... mockoon-cli
|
||||
... stop
|
||||
... mockoon-azure-policyinsights
|
||||
Wait For Process ${process}
|
||||
Terminate All Processes
|
|
@ -0,0 +1,77 @@
|
|||
*** Settings ***
|
||||
Documentation datacore rest api plugin
|
||||
|
||||
Library Examples
|
||||
Library OperatingSystem
|
||||
Library Process
|
||||
Library String
|
||||
|
||||
Suite Setup Start Mockoon
|
||||
Suite Teardown Stop Mockoon
|
||||
Test Timeout 120s
|
||||
|
||||
*** Variables ***
|
||||
${CENTREON_PLUGINS} ${CURDIR}${/}..${/}..${/}..${/}src${/}centreon_plugins.pl
|
||||
${MOCKOON_JSON} ${CURDIR}${/}..${/}..${/}resources${/}mockoon${/}storage-datacore-restapi.json
|
||||
|
||||
${CMD} perl ${CENTREON_PLUGINS} --plugin=storage::datacore::restapi::plugin --password=pass --username=user --port=3000 --hostname=127.0.0.1 --proto=http
|
||||
|
||||
|
||||
*** Test Cases ***
|
||||
Datacore check pool usage
|
||||
[Documentation] Check Datacore pool usage
|
||||
[Tags] storage api
|
||||
${output} Run
|
||||
... ${CMD} --mode=pool-usage --critical-oversubscribed=${critical-oversubscribed} --warning-oversubscribed=${warning-oversubscribed} --warning-bytesallocatedpercentage=${warning-bytesallocatedpercentage} --critical-bytesallocatedpercentage=${critical-bytesallocatedpercentage} --pool-id=B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:{4dec1b5a-2577-11e5-80c3-00155d651622}
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${result}
|
||||
... Wrong output result for pool usage :\n\n ${output} \n\n ${result}\n\n
|
||||
|
||||
Examples: warning-bytesallocatedpercentage critical-bytesallocatedpercentage warning-oversubscribed critical-oversubscribed result --
|
||||
... 2 5 -1 3 CRITICAL: Bytes Allocated : 12 % WARNING: Over subscribed bytes : 0 | 'datacore.pool.bytesallocated.percentage'=12%;0:2;0:5;0;100 'datacore.pool.oversubscribed.bytes'=0bytes;0:-1;0:3;0;
|
||||
... 70 80 10 20 OK: Bytes Allocated : 12 % - Over subscribed bytes : 0 | 'datacore.pool.bytesallocated.percentage'=12%;0:70;0:80;0;100 'datacore.pool.oversubscribed.bytes'=0bytes;0:10;0:20;0;
|
||||
|
||||
Datacore check alert count
|
||||
[Documentation] Check Datacore pool usage
|
||||
[Tags] storage api
|
||||
${output} Run
|
||||
... ${CMD} --mode=alerts --warning-error=${warning-error} --critical-error=${critical-error} --warning-warning=${warning-warning} --critical-warning=${critical-warning}
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${result}
|
||||
... Wrong output result for alert count :\n\n ${output} \n\n ${result}\n\n
|
||||
|
||||
Examples: warning-error critical-error warning-warning critical-warning result --
|
||||
... 0 1 5 5 WARNING: number of error alerts : 1 | 'datacore.event.error.count'=1;0:0;0:1;0; 'datacore.alerts.warning.count'=1;0:5;0:5;0; 'datacore.alerts.info.count'=0;;;0; 'datacore.alerts.trace.count'=0;;;0;
|
||||
... 5 5 5 5 OK: number of error alerts : 1, number of warning alerts : 1, number of info alerts : 0, number of trace alerts : 0 | 'datacore.event.error.count'=1;0:5;0:5;0; 'datacore.alerts.warning.count'=1;0:5;0:5;0; 'datacore.alerts.info.count'=0;;;0; 'datacore.alerts.trace.count'=0;;;0;
|
||||
|
||||
Datacore check status monitor
|
||||
[Documentation] Check Datacore pool usage
|
||||
[Tags] storage api
|
||||
${output} Run
|
||||
... ${CMD} --mode=status-monitor
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${result}
|
||||
... Wrong output result for status monitor :\n${output} \nresult:\n${result}\n\n
|
||||
|
||||
Examples: result --
|
||||
... CRITICAL: 'State of HostVM2' status : 'Critical', message is 'Connected'
|
||||
|
||||
*** Keywords ***
|
||||
Start Mockoon
|
||||
${process} Start Process
|
||||
... mockoon-cli
|
||||
... start
|
||||
... --data
|
||||
... ${MOCKOON_JSON}
|
||||
... --port
|
||||
... 3000
|
||||
Sleep 5s
|
||||
|
||||
Stop Mockoon
|
||||
Terminate All Processes
|
|
@ -0,0 +1,174 @@
|
|||
{
|
||||
"uuid": "317849df-2152-4b89-88f7-f22ea37aab32",
|
||||
"lastMigration": 27,
|
||||
"name": "Storage datacore api",
|
||||
"endpointPrefix": "",
|
||||
"latency": 0,
|
||||
"port": 3000,
|
||||
"hostname": "",
|
||||
"folders": [],
|
||||
"routes": [
|
||||
{
|
||||
"uuid": "9d203639-fb39-402b-9759-91c156e247c6",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/pools",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "f8d1590b-878f-4884-9214-dea80580eb75",
|
||||
"body": "[{\r\n \"Caption\" : \"Disk pool 1\",\r\n \"ExtendedCaption\" : \"Disk pool 1 on StorageSvr001\",\r\n \"Id\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551:{d68b8a36-0ec4-11e5-80ba-00155d651622}\",\r\n \"Internal\" : false,\r\n \"SequenceNumber\" : 11963,\r\n \"Alias\" : \"Disk pool 1\",\r\n \"AutoTieringEnabled\" : true,\r\n \"ChunkSize\" : {\r\n \"Value\" : 134217728\r\n },\r\n \"Description\" : null,\r\n \"InSharedMode\" : false,\r\n \"IsAuthorized\" : true,\r\n \"MaxTierNumber\" : 3,\r\n \"PoolMode\" : 1,\r\n \"PoolStatus\" : 0,\r\n \"PresenceStatus\" : 1,\r\n \"SMPAApproved\" : false,\r\n \"ServerId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\r\n \"SharedPoolId\" : null,\r\n \"TierReservedPct\" : 0,\r\n \"Type\" : 0,\r\n \"IsBulk\" : false\r\n},\r\n{\r\n \"Caption\" : \"Shared pool 1\",\r\n \"ExtendedCaption\" : \"Shared pool 1 on StorageSvr002\",\r\n \"Id\" : \"B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:{4dec1b5a-2577-11e5-80c3-00155d651622}\",\r\n \"Internal\" : false,\r\n \"SequenceNumber\" : 11967,\r\n \"Alias\" : \"Shared pool 1\",\r\n \"AutoTieringEnabled\" : true,\r\n \"ChunkSize\" : {\r\n \"Value\" : 134217728\r\n },\r\n \"Description\" : null,\r\n \"InSharedMode\" : true,\r\n \"IsAuthorized\" : true,\r\n \"MaxTierNumber\" : 3,\r\n \"PoolMode\" : 1,\r\n \"PoolStatus\" : 0,\r\n \"PresenceStatus\" : 1,\r\n \"SMPAApproved\" : true,\r\n \"ServerId\" : \"B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D\",\r\n \"SharedPoolId\" : \"{4dec1b5a-2577-11e5-80c3-00155d651622}\",\r\n \"TierReservedPct\" : 0,\r\n \"Type\" : 0,\r\n \"IsBulk\" : false\r\n} ]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "8837f5cd-5ca3-4779-ba8e-6b46692c487b",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/performances/B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:%7B4dec1b5a-2577-11e5-80c3-00155d651622%7D",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "a5bf53e2-5edf-437e-a684-68315cfa7824",
|
||||
"body": "[\n {\n \"CollectionTime\": \"/Date(1486402608775)/\",\n \"NullCounterMap\": 0,\n \"BytesAllocated\": 6174015488,\n \"BytesAllocatedPercentage\": 12,\n \"BytesAvailable\": 47110422528,\n \"BytesAvailablePercentage\": 88,\n \"BytesInReclamation\": 0,\n \"BytesInReclamationPercentage\": 0,\n \"BytesOverSubscribed\": 0,\n \"BytesReserved\": 0,\n \"BytesReservedPercentage\": 0,\n \"BytesTotal\": 53284438016,\n \"EstimatedDepletionTime\": 2592000001,\n \"MaxPoolBytes\": 1108127332171776,\n \"MaxReadTime\" : 0,\n \"MaxReadWriteTime\" : 0,\n \"MaxWriteTime\" : 0,\n \"PercentAllocated\" : 12,\n \"PercentAvailable\" : 88,\n \"TotalBytesMigrated\" : 0,\n \"TotalBytesRead\" : 307200,\n \"TotalBytesTransferred\" : 2036756992,\n \"TotalBytesWritten\" : 2036470272,\n \"TotalOperations\" : 53002,\n \"TotalReadTime\" : 0,\n \"TotalReads\" : 18,\n \"TotalWriteTime\" : 74994,\n \"TotalWrites\" : 52998\n }\n]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "ce9e85c8-c72e-47d4-b70a-0fd3c3a6d703",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/alerts",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "b6425c83-2f13-4ffe-a9f6-c73feb54c2ec",
|
||||
"body": "[ {\n \"Caller\" : \"ServerMachineGroup.UpdateServers\",\n \"HighPriority\" : true,\n \"Id\" : {\n \"MachineId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SequenceNumber\" : 34937\n },\n \"Level\" : 2,\n \"MachineName\" : \"STORAGESVR001\",\n \"MessageData\" : [ \"StorageSvr002\" ],\n \"MessageText\" : \"Connection to server {0} has been lost.\",\n \"NeedsAcknowledge\" : false,\n \"Sources\" : [ {\n \"SourceCaption\" : \"Group1\",\n \"SourceId\" : \"4b428832-fd51-45df-9c21-ce267e1ceb7a\",\n \"SourceType\" : 12\n } ],\n \"TimeStamp\" : \"/Date(1437398005546)/\",\n \"UserId\" : null,\n \"UserName\" : null,\n \"Visibility\" : 64\n}, {\n \"Caller\" : \"BasePerfMonitor`1.SetState\",\n \"HighPriority\" : true,\n \"Id\" : {\n \"MachineId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SequenceNumber\" : 33985\n },\n \"Level\" : 3,\n \"MachineName\" : \"STORAGESVR001\",\n \"MessageData\" : null,\n \"MessageText\" : \"The Replication buffer free space of StorageSvr001 in Group1 is <= 10%\",\n \"NeedsAcknowledge\" : false,\n \"Sources\" : [ {\n \"SourceCaption\" : \"Replication buffer free space of StorageSvr001 in Group1\",\n \"SourceId\" : \"FallingThresholdPerfMonitor`1<A3E78CFA-DBEC-44E1-A23C-E9E262EC4551>ReplicationBufferPercentFreeSpace\",\n \"SourceType\" : 3\n }, {\n \"SourceCaption\" : \"StorageSvr001 in Group1\",\n \"SourceId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SourceType\" : 12\n }, {\n \"SourceCaption\" : \"Group1\",\n \"SourceId\" : \"4b428832-fd51-45df-9c21-ce267e1ceb7a\",\n \"SourceType\" : 12\n } ],\n \"TimeStamp\" : \"/Date(1437397587894)/\",\n \"UserId\" : null,\n \"UserName\" : null,\n \"Visibility\" : 64\n}]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "a916f10f-b2f2-498a-9b87-3aeffd80c8dc",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/monitors",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "d2713bdd-33e9-415a-bffe-16e279b1b753",
|
||||
"body": "[\n {\n \"Caption\": \"State\",\n \"ExtendedCaption\": \"State of HostVM2\",\n \"Id\": \"ClientMachineStateMonitor<ed89ef91d72142dc958e02c5b7014fac>\",\n \"Internal\": false,\n \"SequenceNumber\": 9417,\n \"Description\": \"Monitors the state of hosts.\",\n \"MessageText\": \"Connected\",\n \"MonitoredObjectId\": \"ed89ef91d72142dc958e02c5b7014fac\",\n \"State\": 16,\n \"TemplateId\": \"T(DataCore.Executive.Controller.ClientMachineStateMonitor<DataCore.Executive.Controller.ClientMachine>)\",\n \"TimeStamp\": \"/Date(1486136115475-0500)/\"\n },\n {\n \"Caption\": \"I/O latency\",\n \"ExtendedCaption\": \"I/O latency of Mirror of Virtual disk 1 on StorageSvr005\",\n \"Id\": \"RisingThresholdPerfMonitor`1<V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568>TotalOperationsTime\",\n \"Internal\": false,\n \"SequenceNumber\": 10036,\n \"Description\": \"Monitors the physical disks latency.\",\n \"MessageText\": \"Disabled\",\n \"MonitoredObjectId\": \"V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568\",\n \"State\": 1,\n \"TemplateId\": \"T(DataCore.Executive.Controller.RisingThresholdPerfMonitor`1[T]<V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568>TotalOperationsTime)\",\n \"TimeStamp\": \"/Date(1486148705910-0500)/\"\n }\n]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"responseMode": null
|
||||
}
|
||||
],
|
||||
"rootChildren": [
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "9d203639-fb39-402b-9759-91c156e247c6"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "8837f5cd-5ca3-4779-ba8e-6b46692c487b"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "ce9e85c8-c72e-47d4-b70a-0fd3c3a6d703"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "a916f10f-b2f2-498a-9b87-3aeffd80c8dc"
|
||||
}
|
||||
],
|
||||
"proxyMode": false,
|
||||
"proxyHost": "",
|
||||
"proxyRemovePrefix": false,
|
||||
"tlsOptions": {
|
||||
"enabled": false,
|
||||
"type": "CERT",
|
||||
"pfxPath": "",
|
||||
"certPath": "",
|
||||
"keyPath": "",
|
||||
"caPath": "",
|
||||
"passphrase": ""
|
||||
},
|
||||
"cors": true,
|
||||
"headers": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"proxyReqHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"proxyResHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"data": []
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"uuid": "8cba072c-7794-4ff7-ab36-158ef1abed39",
|
||||
"lastMigration": 32,
|
||||
"name": "Storage datacore api",
|
||||
"endpointPrefix": "",
|
||||
"latency": 0,
|
||||
"port": 3001,
|
||||
"hostname": "",
|
||||
"folders": [],
|
||||
"routes": [
|
||||
{
|
||||
"uuid": "148371c5-aaa7-4bf0-a818-e81a21aa7f9a",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/pools",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "003eae6e-f58f-44db-bd03-3b44ca578046",
|
||||
"body": "[ {\n \"Caption\" : \"Disk pool 1\",\n \"ExtendedCaption\" : \"Disk pool 1 on StorageSvr001\",\n \"Id\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551:{d68b8a36-0ec4-11e5-80ba-00155d651622}\",\n \"Internal\" : false,\n \"SequenceNumber\" : 11963,\n \"Alias\" : \"Disk pool 1\",\n \"AutoTieringEnabled\" : true,\n \"ChunkSize\" : {\n \"Value\" : 134217728\n },\n \"Description\" : null,\n \"InSharedMode\" : false,\n \"IsAuthorized\" : true,\n \"MaxTierNumber\" : 3,\n \"PoolMode\" : 1,\n \"PoolStatus\" : 0,\n \"PresenceStatus\" : 1,\n \"SMPAApproved\" : false,\n \"ServerId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SharedPoolId\" : null,\n \"TierReservedPct\" : 0,\n \"Type\" : 0,\n \"IsBulk\" : false\n},\n{\n \"Caption\" : \"Shared pool 1\",\n \"ExtendedCaption\" : \"Shared pool 1 on StorageSvr002\",\n \"Id\" : \"B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:{4dec1b5a-2577-11e5-80c3-00155d651622}\",\n \"Internal\" : false,\n \"SequenceNumber\" : 11967,\n \"Alias\" : \"Shared pool 1\",\n \"AutoTieringEnabled\" : true,\n \"ChunkSize\" : {\n \"Value\" : 134217728\n },\n \"Description\" : null,\n \"InSharedMode\" : true,\n \"IsAuthorized\" : true,\n \"MaxTierNumber\" : 3,\n \"PoolMode\" : 1,\n \"PoolStatus\" : 0,\n \"PresenceStatus\" : 1,\n \"SMPAApproved\" : true,\n \"ServerId\" : \"B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D\",\n \"SharedPoolId\" : \"{4dec1b5a-2577-11e5-80c3-00155d651622}\",\n \"TierReservedPct\" : 0,\n \"Type\" : 0,\n \"IsBulk\" : false\n} ]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "0c038179-3723-4d67-9bed-fc226629c847",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/performances/B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:%7B4dec1b5a-2577-11e5-80c3-00155d651622%7D",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "0eb0a2ca-2f12-40af-ba94-0feef989b6a1",
|
||||
"body": "[\n {\n \"CollectionTime\": \"/Date(1486402608775)/\",\n \"NullCounterMap\": 0,\n \"BytesAllocated\": 6174015488,\n \"BytesAllocatedPercentage\": 12,\n \"BytesAvailable\": 47110422528,\n \"BytesAvailablePercentage\": 88,\n \"BytesInReclamation\": 0,\n \"BytesInReclamationPercentage\": 0,\n \"BytesOverSubscribed\": 0,\n \"BytesReserved\": 0,\n \"BytesReservedPercentage\": 0,\n \"BytesTotal\": 53284438016,\n \"EstimatedDepletionTime\": 2592000001,\n \"MaxPoolBytes\": 1108127332171776,\n \"MaxReadTime\" : 0,\n \"MaxReadWriteTime\" : 0,\n \"MaxWriteTime\" : 0,\n \"PercentAllocated\" : 12,\n \"PercentAvailable\" : 88,\n \"TotalBytesMigrated\" : 0,\n \"TotalBytesRead\" : 307200,\n \"TotalBytesTransferred\" : 2036756992,\n \"TotalBytesWritten\" : 2036470272,\n \"TotalOperations\" : 53002,\n \"TotalReadTime\" : 0,\n \"TotalReads\" : 18,\n \"TotalWriteTime\" : 74994,\n \"TotalWrites\" : 52998\n }\n]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "b9f7dd2b-e1e1-4902-95ba-c6b76a1de390",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/alerts",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "a1dece29-074b-4100-a764-f7ddccdec8da",
|
||||
"body": "[ {\n \"Caller\" : \"ServerMachineGroup.UpdateServers\",\n \"HighPriority\" : true,\n \"Id\" : {\n \"MachineId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SequenceNumber\" : 34937\n },\n \"Level\" : 2,\n \"MachineName\" : \"STORAGESVR001\",\n \"MessageData\" : [ \"StorageSvr002\" ],\n \"MessageText\" : \"Connection to server {0} has been lost.\",\n \"NeedsAcknowledge\" : false,\n \"Sources\" : [ {\n \"SourceCaption\" : \"Group1\",\n \"SourceId\" : \"4b428832-fd51-45df-9c21-ce267e1ceb7a\",\n \"SourceType\" : 12\n } ],\n \"TimeStamp\" : \"/Date(1437398005546)/\",\n \"UserId\" : null,\n \"UserName\" : null,\n \"Visibility\" : 64\n}, {\n \"Caller\" : \"BasePerfMonitor`1.SetState\",\n \"HighPriority\" : true,\n \"Id\" : {\n \"MachineId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SequenceNumber\" : 33985\n },\n \"Level\" : 3,\n \"MachineName\" : \"STORAGESVR001\",\n \"MessageData\" : null,\n \"MessageText\" : \"The Replication buffer free space of StorageSvr001 in Group1 is <= 10%\",\n \"NeedsAcknowledge\" : false,\n \"Sources\" : [ {\n \"SourceCaption\" : \"Replication buffer free space of StorageSvr001 in Group1\",\n \"SourceId\" : \"FallingThresholdPerfMonitor`1<A3E78CFA-DBEC-44E1-A23C-E9E262EC4551>ReplicationBufferPercentFreeSpace\",\n \"SourceType\" : 3\n }, {\n \"SourceCaption\" : \"StorageSvr001 in Group1\",\n \"SourceId\" : \"A3E78CFA-DBEC-44E1-A23C-E9E262EC4551\",\n \"SourceType\" : 12\n }, {\n \"SourceCaption\" : \"Group1\",\n \"SourceId\" : \"4b428832-fd51-45df-9c21-ce267e1ceb7a\",\n \"SourceType\" : 12\n } ],\n \"TimeStamp\" : \"/Date(1437397587894)/\",\n \"UserId\" : null,\n \"UserName\" : null,\n \"Visibility\" : 64\n}]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "be0b350e-f8da-4998-a045-a3cf840745c0",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "RestService/rest.svc/1.0/monitors",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "6f53cd5e-7417-4fdf-a310-e2a7af4b7c3a",
|
||||
"body": "[\r\n {\r\n \"Caption\": \"State\",\r\n \"ExtendedCaption\": \"State of HostVM2\",\r\n \"Id\": \"ClientMachineStateMonitor<ed89ef91d72142dc958e02c5b7014fac>\",\r\n \"Internal\": false,\r\n \"SequenceNumber\": 9417,\r\n \"Description\": \"Monitors the state of hosts.\",\r\n \"MessageText\": \"Connected\",\r\n \"MonitoredObjectId\": \"ed89ef91d72142dc958e02c5b7014fac\",\r\n \"State\": 16,\r\n \"TemplateId\": \"T(DataCore.Executive.Controller.ClientMachineStateMonitor<DataCore.Executive.Controller.ClientMachine>)\",\r\n \"TimeStamp\": \"/Date(1486136115475-0500)/\"\r\n },\r\n {\r\n \"Caption\": \"I/O latency\",\r\n \"ExtendedCaption\": \"I/O latency of Mirror of Virtual disk 1 on StorageSvr005\",\r\n \"Id\": \"RisingThresholdPerfMonitor`1<V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568>TotalOperationsTime\",\r\n \"Internal\": false,\r\n \"SequenceNumber\": 10036,\r\n \"Description\": \"Monitors the physical disks latency.\",\r\n \"MessageText\": \"Disabled\",\r\n \"MonitoredObjectId\": \"V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568\",\r\n \"State\": 1,\r\n \"TemplateId\": \"T(DataCore.Executive.Controller.RisingThresholdPerfMonitor`1[T]<V.{2f652562-e7e3-11e6-80d7-00155d651611}-00000001_N.22690030D9218568>TotalOperationsTime)\",\r\n \"TimeStamp\": \"/Date(1486148705910-0500)/\"\r\n }\r\n]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": true,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
}
|
||||
],
|
||||
"rootChildren": [
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "148371c5-aaa7-4bf0-a818-e81a21aa7f9a"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "0c038179-3723-4d67-9bed-fc226629c847"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "b9f7dd2b-e1e1-4902-95ba-c6b76a1de390"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "be0b350e-f8da-4998-a045-a3cf840745c0"
|
||||
}
|
||||
],
|
||||
"proxyMode": false,
|
||||
"proxyHost": "",
|
||||
"proxyRemovePrefix": false,
|
||||
"tlsOptions": {
|
||||
"enabled": false,
|
||||
"type": "CERT",
|
||||
"pfxPath": "",
|
||||
"certPath": "",
|
||||
"keyPath": "",
|
||||
"caPath": "",
|
||||
"passphrase": ""
|
||||
},
|
||||
"cors": true,
|
||||
"headers": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"proxyReqHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"proxyResHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"data": [],
|
||||
"callbacks": []
|
||||
}
|
Loading…
Reference in New Issue