add(mode): new vpn tunnels mode to meraki api plugin + tests (#5084)
Co-authored-by: garnier-quentin <garnier.quentin@gmail.com> REFS: CTOR-98
This commit is contained in:
parent
1333b452fb
commit
294fa2b394
|
@ -241,16 +241,17 @@ sub write_cache_file {
|
|||
|
||||
sub get_cache_file_response {
|
||||
my ($self, %options) = @_;
|
||||
my $cache_filename = 'cache_meraki_'
|
||||
. md5_hex($self->{api_token} . '_' .(defined($self->{option_results}->{api_filter_orgs}) ?
|
||||
$self->{option_results}->{api_filter_orgs} : '')
|
||||
);
|
||||
|
||||
$self->{cache}->read(
|
||||
statefile => 'cache_meraki_' . md5_hex(
|
||||
$self->{api_token} . '_' .
|
||||
(defined($self->{option_results}->{api_filter_orgs}) ? $self->{option_results}->{api_filter_orgs} : '')
|
||||
)
|
||||
statefile => $cache_filename
|
||||
);
|
||||
$self->{datas} = $self->{cache}->get(name => 'response');
|
||||
if (!defined($self->{datas})) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Cache file missing');
|
||||
$self->{output}->add_option_msg(short_msg => 'Cache file missing or could not load ' . $cache_filename);
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
|
@ -261,7 +262,9 @@ sub call_datas {
|
|||
my ($self, %options) = @_;
|
||||
|
||||
$self->get_organizations();
|
||||
$self->get_networks(orgs => [keys %{$self->{datas}->{orgs}}]);
|
||||
if (!defined($options{skipNetworks})) {
|
||||
$self->get_networks(orgs => [keys %{$self->{datas}->{orgs}}]);
|
||||
}
|
||||
|
||||
if (!defined($options{skipDevices})) {
|
||||
$self->get_devices(orgs => [keys %{$self->{datas}->{orgs}}]);
|
||||
|
@ -269,6 +272,9 @@ sub call_datas {
|
|||
if (!defined($options{skipDevicesStatus})) {
|
||||
$self->get_organization_device_statuses(orgs => [keys %{$self->{datas}->{orgs}}]);
|
||||
}
|
||||
if (!defined($options{skipVpnTunnelsStatus})) {
|
||||
$self->get_organization_vpn_tunnels_statuses(orgs => [keys %{$self->{datas}->{orgs}}]);
|
||||
}
|
||||
|
||||
if (defined($options{cache})) {
|
||||
foreach my $orgId (keys %{$self->{datas}->{orgs}}) {
|
||||
|
@ -408,6 +414,26 @@ sub get_organization_device_statuses {
|
|||
return $self->{datas}->{devices_status};
|
||||
}
|
||||
|
||||
sub get_organization_vpn_tunnels_statuses {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{datas}->{vpn_tunnels_status} = {};
|
||||
foreach my $id (@{$options{orgs}}) {
|
||||
my $datas = $self->request_api(
|
||||
endpoint => '/organizations/' . $id . '/appliance/vpn/statuses',
|
||||
paginate => 300,
|
||||
hostname => $self->get_shard_hostname(organization_id => $id),
|
||||
ignore_codes => { 400 => 1 } # it can be disabled
|
||||
);
|
||||
foreach (@$datas) {
|
||||
$self->{datas}->{vpn_tunnels_status}->{ $_->{deviceSerial} } = $_;
|
||||
$self->{datas}->{vpn_tunnels_status}->{ $_->{deviceSerial} }->{organizationId} = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $self->{datas}->{vpn_tunnels_status};
|
||||
}
|
||||
|
||||
sub get_network_device_uplink {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
|
@ -444,7 +470,7 @@ sub get_organization_uplink_loss_and_latency {
|
|||
if (defined($datas)) {
|
||||
foreach (@$datas) {
|
||||
# sometimes uplink is undef. so we skip
|
||||
next if (!defined($_->{uplink}));
|
||||
next if (!defined($_->{uplink}) || !defined($_->{serial}));
|
||||
|
||||
$self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $_->{serial} } = {}
|
||||
if (!defined($self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $_->{serial} }));
|
||||
|
@ -554,7 +580,7 @@ Meraki REST API
|
|||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
api_token Rest API custom mode
|
||||
Rest API custom mode
|
||||
|
||||
=head1 REST API OPTIONS
|
||||
|
||||
|
@ -562,23 +588,23 @@ api_token Rest API custom mode
|
|||
|
||||
=item B<--hostname>
|
||||
|
||||
Meraki api hostname (default: 'api.meraki.com')
|
||||
Meraki API hostname (default: 'api.meraki.com')
|
||||
|
||||
=item B<--port>
|
||||
|
||||
Port used (default: 443)
|
||||
Define the TCP port to use to reach the API (default: 443).
|
||||
|
||||
=item B<--proto>
|
||||
|
||||
Specify https if needed (default: 'https')
|
||||
Define the protocol to reach the API (default: 'https').
|
||||
|
||||
=item B<--api-token>
|
||||
|
||||
Meraki api token.
|
||||
Meraki API token.
|
||||
|
||||
=item B<--timeout>
|
||||
|
||||
Set HTTP timeout
|
||||
Define the timeout for HTTP requests.
|
||||
|
||||
=item B<--ignore-permission-errors>
|
||||
|
||||
|
@ -586,15 +612,15 @@ Ignore permission errors (403 status code).
|
|||
|
||||
=item B<--ignore-orgs-api-disabled>
|
||||
|
||||
Ignore organizations with api disabled.
|
||||
Ignore organizations where the API is disabled.
|
||||
|
||||
=item B<--api-filter-orgs>
|
||||
|
||||
Filter organizations (regexp).
|
||||
Define the organizations to monitor (regular expression).
|
||||
|
||||
=item B<--cache-use>
|
||||
|
||||
Use the cache file (created with cache mode).
|
||||
Use the cache file instead of requesting the API (the cache file can be created with the cache mode).
|
||||
|
||||
=back
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ sub new {
|
|||
'filter-tags:s' => { name => 'filter_tags' },
|
||||
'add-switch-ports' => { name => 'add_switch_ports' },
|
||||
'filter-switch-port:s' => { name => 'filter_switch_port' },
|
||||
'filter-link-name:s' => { name => 'filter_link_name' },
|
||||
'skip-traffic-disconnect-port' => { name => 'skip_traffic_disconnect_port' },
|
||||
'skip-clients' => { name => 'skip_clients' },
|
||||
'skip-performance' => { name => 'skip_performance' },
|
||||
|
@ -373,6 +374,10 @@ sub add_uplink {
|
|||
foreach (@$links) {
|
||||
my $interface = lc($_->{interface});
|
||||
$interface =~ s/\s+//g;
|
||||
|
||||
next if (defined($self->{option_results}->{filter_link_name}) && $self->{option_results}->{filter_link_name} ne '' &&
|
||||
$interface !~ /$self->{option_results}->{filter_link_name}/);
|
||||
|
||||
$self->{devices}->{ $options{serial} }->{device_links}->{$interface} = {
|
||||
display => $interface,
|
||||
link_status => lc($_->{status})
|
||||
|
@ -396,7 +401,10 @@ sub add_uplink_loss_latency {
|
|||
foreach (values %$links) {
|
||||
my $interface = lc($_->{uplink});
|
||||
$interface =~ s/\s+//g;
|
||||
|
||||
next if (!defined($self->{devices}->{ $options{serial} }->{device_links}->{$interface}));
|
||||
next if (defined($self->{option_results}->{filter_link_name}) && $self->{option_results}->{filter_link_name} ne '' &&
|
||||
$interface !~ /$self->{option_results}->{filter_link_name}/);
|
||||
|
||||
my ($latency, $loss, $count) = (0, 0, 0);
|
||||
foreach my $ts (@{$_->{timeSeries}}) {
|
||||
|
@ -581,6 +589,10 @@ Check devices.
|
|||
|
||||
Filter devices by name (can be a regexp).
|
||||
|
||||
=item B<--filter-link-name>
|
||||
|
||||
Filter VPN links by name (can be a regexp).
|
||||
|
||||
=item B<--filter-network-id>
|
||||
|
||||
Filter devices by network ID (can be a regexp).
|
||||
|
@ -611,7 +623,7 @@ Don't monitor clients traffic on device.
|
|||
|
||||
=item B<--skip-performance>
|
||||
|
||||
Don't monitor appliance perfscore.
|
||||
Don't monitor appliance performance score.
|
||||
|
||||
=item B<--skip-connections>
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
#
|
||||
# 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 network::cisco::meraki::cloudcontroller::restapi::mode::listvpntunnels;
|
||||
|
||||
use base qw(centreon::plugins::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my @labels = (
|
||||
'organization_id',
|
||||
'organization_name',
|
||||
'network_id',
|
||||
'network_name',
|
||||
'device_serial',
|
||||
'mode',
|
||||
'status'
|
||||
);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-network-id:s' => { name => 'filter_network_id' },
|
||||
'filter-organization-name:s' => { name => 'filter_organization_name' },
|
||||
'filter-organization-id:s' => { name => 'filter_organization_id' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $organizations = $options{custom}->get_organizations();
|
||||
my $devices = $options{custom}->get_organization_vpn_tunnels_statuses(
|
||||
orgs => [keys %$organizations]
|
||||
);
|
||||
|
||||
my $results = {};
|
||||
foreach (keys %$devices) {
|
||||
next if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' &&
|
||||
$devices->{$_}->{networkId} !~ /$self->{option_results}->{filter_network_id}/);
|
||||
next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' &&
|
||||
$devices->{$_}->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/);
|
||||
|
||||
my $organization_name = $organizations->{ $devices->{$_}->{organizationId} }->{name};
|
||||
next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' &&
|
||||
$organization_name !~ /$self->{option_results}->{filter_organization_name}/);
|
||||
|
||||
$results->{$_} = {
|
||||
network_id => $devices->{$_}->{networkId},
|
||||
network_name => $devices->{$_}->{networkName},
|
||||
device_serial => $devices->{$_}->{deviceSerial},
|
||||
organization_id => $devices->{$_}->{organizationId},
|
||||
organization_name => $organization_name,
|
||||
mode => $devices->{$_}->{vpnMode},
|
||||
status => $devices->{$_}->{deviceStatus}
|
||||
};
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(custom => $options{custom});
|
||||
foreach my $instance (sort keys %$results) {
|
||||
$self->{output}->output_add(long_msg =>
|
||||
join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels))
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List VPN tunnels:'
|
||||
);
|
||||
$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 => [@labels]);
|
||||
}
|
||||
|
||||
sub disco_show {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(custom => $options{custom});
|
||||
foreach (sort keys %$results) {
|
||||
$self->{output}->add_disco_entry(
|
||||
%{$results->{$_}}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
List VPN tunnels.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-network-id>
|
||||
|
||||
Filter VPN tunnels by network ID (can be a regexp).
|
||||
|
||||
=item B<--filter-organization-id>
|
||||
|
||||
Filter VPN tunnels by organization ID (can be a regexp).
|
||||
|
||||
=item B<--filter-organization-name>
|
||||
|
||||
Filter VPN tunnels by organization name (can be a regexp).
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -126,7 +126,7 @@ sub manage_selection {
|
|||
(defined($self->{option_results}->{filter_organization_name}) ? $self->{option_results}->{filter_organization_name} : 'all')
|
||||
);
|
||||
|
||||
my $datas = $options{custom}->get_datas(skipDevices => 1, skipDevicesStatus => 1);
|
||||
my $datas = $options{custom}->get_datas(skipDevices => 1, skipDevicesStatus => 1, skipVpnTunnelsStatus => 1);
|
||||
|
||||
$self->{networks} = {};
|
||||
foreach my $id (keys %{$datas->{networks}}) {
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
#
|
||||
# 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 network::cisco::meraki::cloudcontroller::restapi::mode::vpntunnels;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'status: ' . $self->{result_values}->{status} . ' [mode: ' . $self->{result_values}->{mode} . ']';
|
||||
}
|
||||
|
||||
sub prefix_tunnel_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "vpn tunnel '" . $options{instance_value}->{deviceSerial} . "' ";
|
||||
}
|
||||
|
||||
sub prefix_global_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'Vpn tunnels ';
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } },
|
||||
{ name => 'tunnels', type => 1, cb_prefix_output => 'prefix_tunnel_output', message_multiple => 'All vpn tunnels are ok' }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'total-online', nlabel => 'vpn.tunnels.online.count', display_ok => 0, set => {
|
||||
key_values => [ { name => 'online' }, { name => 'total' } ],
|
||||
output_template => 'online: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'total-offline', nlabel => 'vpn.tunnels.offline.count', display_ok => 0, set => {
|
||||
key_values => [ { name => 'offline' }, { name => 'total' } ],
|
||||
output_template => 'offline: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'total-dormant', nlabel => 'vpn.tunnels.dormant.count', display_ok => 0, set => {
|
||||
key_values => [ { name => 'dormant' }, { name => 'total' } ],
|
||||
output_template => 'dormant: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, max => 'total' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{tunnels} = [
|
||||
{
|
||||
label => 'status', type => 2,
|
||||
critical_default => '%{status} =~ /offline/i',
|
||||
set => {
|
||||
key_values => [ { name => 'status' }, { name => 'mode' }, { name => 'deviceSerial' } ],
|
||||
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-network-name:s' => { name => 'filter_network_name' },
|
||||
'filter-organization-name:s' => { name => 'filter_organization_name' },
|
||||
'filter-organization-id:s' => { name => 'filter_organization_id' },
|
||||
'filter-device-serial:s' => { name => 'filter_device_serial' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $datas = $options{custom}->get_datas(skipDevices => 1, skipDevicesStatus => 1, skipNetworks => 1);
|
||||
|
||||
$self->{global} = { total => 0, online => 0, offline => 0, dormant => 0 };
|
||||
$self->{tunnels} = {};
|
||||
foreach my $id (keys %{$datas->{vpn_tunnels_status}}) {
|
||||
next if (defined($self->{option_results}->{filter_network_name}) && $self->{option_results}->{filter_network_name} ne '' &&
|
||||
$datas->{vpn_tunnels_status}->{$id}->{networkName} !~ /$self->{option_results}->{filter_network_name}/);
|
||||
|
||||
next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' &&
|
||||
$datas->{vpn_tunnels_status}->{$id}->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/);
|
||||
next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' &&
|
||||
$datas->{orgs}->{ $datas->{vpn_tunnels_status}->{$id}->{organizationId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/);
|
||||
|
||||
$self->{tunnels}->{$id} = {
|
||||
deviceSerial => $id,
|
||||
status => $datas->{vpn_tunnels_status}->{$id}->{deviceStatus},
|
||||
mode => $datas->{vpn_tunnels_status}->{$id}->{vpnMode}
|
||||
};
|
||||
|
||||
$self->{global}->{total}++;
|
||||
$self->{global}->{ lc($datas->{vpn_tunnels_status}->{$id}->{deviceStatus}) }++
|
||||
if (defined($self->{global}->{ lc($datas->{vpn_tunnels_status}->{$id}->{deviceStatus}) }));
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check VPN tunnels.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-network-name>
|
||||
|
||||
Filter VPN tunnels by network name (can be a regexp).
|
||||
|
||||
=item B<--filter-organization-id>
|
||||
|
||||
Filter VPN tunnels by organization ID (can be a regexp).
|
||||
|
||||
=item B<--filter-organization-name>
|
||||
|
||||
Filter VPN tunnels by organization name (can be a regexp).
|
||||
|
||||
=item B<--filter-device-serial>
|
||||
|
||||
Filter VPN tunnels by device serial (can be a regexp).
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Define the conditions to match for the status to be UNKNOWN.
|
||||
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
|
||||
|
||||
=item B<--warning-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
|
||||
|
||||
=item B<--critical-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{status} =~ /offline/i').
|
||||
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'total-online', 'total-offline', 'total-dormant'.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -30,13 +30,15 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$self->{modes} = {
|
||||
'api-requests' => 'network::cisco::meraki::cloudcontroller::restapi::mode::apirequests',
|
||||
'cache' => 'network::cisco::meraki::cloudcontroller::restapi::mode::cache',
|
||||
'devices' => 'network::cisco::meraki::cloudcontroller::restapi::mode::devices',
|
||||
'discovery' => 'network::cisco::meraki::cloudcontroller::restapi::mode::discovery',
|
||||
'list-devices' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listdevices',
|
||||
'list-tags' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listtags',
|
||||
'networks' => 'network::cisco::meraki::cloudcontroller::restapi::mode::networks'
|
||||
'api-requests' => 'network::cisco::meraki::cloudcontroller::restapi::mode::apirequests',
|
||||
'cache' => 'network::cisco::meraki::cloudcontroller::restapi::mode::cache',
|
||||
'devices' => 'network::cisco::meraki::cloudcontroller::restapi::mode::devices',
|
||||
'discovery' => 'network::cisco::meraki::cloudcontroller::restapi::mode::discovery',
|
||||
'list-devices' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listdevices',
|
||||
'list-tags' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listtags',
|
||||
'list-vpn-tunnels' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listvpntunnels',
|
||||
'networks' => 'network::cisco::meraki::cloudcontroller::restapi::mode::networks',
|
||||
'vpn-tunnels' => 'network::cisco::meraki::cloudcontroller::restapi::mode::vpntunnels'
|
||||
};
|
||||
|
||||
$self->{custom_modes}->{api} = 'network::cisco::meraki::cloudcontroller::restapi::custom::api';
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
--add-sysdesc
|
||||
--api-filter-orgs
|
||||
--api-password
|
||||
--api-token
|
||||
--api-version
|
||||
--cacert-file
|
||||
--cert-pkcs12
|
||||
|
@ -15,6 +17,7 @@
|
|||
--force-counters64
|
||||
--force-oid
|
||||
--get-param
|
||||
--ignore-orgs-api-disabled
|
||||
--lookup-perfdatas-nagios
|
||||
--map-speed-dsl
|
||||
--mqtt
|
||||
|
@ -47,6 +50,7 @@ Iwsva
|
|||
Loggly
|
||||
MBean
|
||||
MQTT
|
||||
Meraki
|
||||
Mosquitto
|
||||
NTLMv2
|
||||
NagVis
|
||||
|
@ -59,11 +63,16 @@ SNMP
|
|||
SSH
|
||||
Sansymphony
|
||||
SureBackup
|
||||
TCP
|
||||
TendMicro
|
||||
VDSL2
|
||||
VPN
|
||||
Veeam
|
||||
WSMAN
|
||||
XPath
|
||||
api.meraki.com
|
||||
connections-dhcp
|
||||
connections-dns
|
||||
deltaps
|
||||
df
|
||||
eth
|
||||
|
@ -93,6 +102,8 @@ space-usage-prct
|
|||
teampass
|
||||
timeframe
|
||||
topic-messages-inflighted
|
||||
total-offline-prct
|
||||
total-online-prct
|
||||
total-oper-down
|
||||
total-oper-up
|
||||
uptime
|
||||
|
|
|
@ -0,0 +1,480 @@
|
|||
{
|
||||
"uuid": "a1da12c3-97f5-4ab7-bec7-a30e1c36309a",
|
||||
"lastMigration": 32,
|
||||
"name": "Meraki.mockoon",
|
||||
"endpointPrefix": "",
|
||||
"latency": 0,
|
||||
"port": 3000,
|
||||
"hostname": "",
|
||||
"folders": [],
|
||||
"routes": [
|
||||
{
|
||||
"uuid": "77da22e2-4161-4be7-a598-62e372cf0438",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "4c2ab123-f20d-4e65-a422-096ecec496ce",
|
||||
"body": "",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "DATABUCKET",
|
||||
"filePath": "",
|
||||
"databucketID": "xl8l",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "3d572355-f7f4-4558-abc6-0e4c2c8b06f9",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/appliance/vpn/statuses",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "4baedfc4-2a1d-4dd1-aff6-e07f6c4144e9",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "DATABUCKET",
|
||||
"filePath": "",
|
||||
"databucketID": "zqoq",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": [],
|
||||
"body": "{}"
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "c8872c69-c290-4c5e-aa4b-18f8ffaf084b",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/networks",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "0723def4-07b5-4549-962a-e041423a9733",
|
||||
"body": "[]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "e7b443c0-4b6e-41b0-bfad-6b23fd14a9cd",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/devices",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "c1d9369d-ee0e-4b4c-b6df-5f64f4112382",
|
||||
"body": "[]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "83ae251f-e2ac-4eb0-bed3-9d024d2d4055",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/devices/statuses",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "e459d826-8630-498d-983f-5259052584b7",
|
||||
"body": "[]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "05351271-5695-4ccc-bdd2-75fd0ab68def",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/uplinks/statuses",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "e6e461fe-86d2-43c1-adb9-73047593e783",
|
||||
"body": "[]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
},
|
||||
{
|
||||
"uuid": "1ee10c37-cb78-4594-9fd9-006a3927f6f2",
|
||||
"type": "http",
|
||||
"documentation": "",
|
||||
"method": "get",
|
||||
"endpoint": "api/v1/organizations/123456789123456789/devices/uplinksLossAndLatency",
|
||||
"responses": [
|
||||
{
|
||||
"uuid": "18e3e93c-302d-4fda-86d1-9ffd1a8b8abd",
|
||||
"body": "[]",
|
||||
"latency": 0,
|
||||
"statusCode": 200,
|
||||
"label": "",
|
||||
"headers": [
|
||||
{
|
||||
"key": "access-control-allow-headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "access-control-allow-origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "content-security-policy",
|
||||
"value": "default-src 'none'"
|
||||
},
|
||||
{
|
||||
"key": "content-type",
|
||||
"value": "text/html; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"key": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
}
|
||||
],
|
||||
"bodyType": "INLINE",
|
||||
"filePath": "",
|
||||
"databucketID": "",
|
||||
"sendFileAsBody": false,
|
||||
"rules": [],
|
||||
"rulesOperator": "OR",
|
||||
"disableTemplating": false,
|
||||
"fallbackTo404": false,
|
||||
"default": false,
|
||||
"crudKey": "id",
|
||||
"callbacks": []
|
||||
}
|
||||
],
|
||||
"responseMode": null
|
||||
}
|
||||
],
|
||||
"rootChildren": [
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "77da22e2-4161-4be7-a598-62e372cf0438"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "3d572355-f7f4-4558-abc6-0e4c2c8b06f9"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "c8872c69-c290-4c5e-aa4b-18f8ffaf084b"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "e7b443c0-4b6e-41b0-bfad-6b23fd14a9cd"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "83ae251f-e2ac-4eb0-bed3-9d024d2d4055"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "05351271-5695-4ccc-bdd2-75fd0ab68def"
|
||||
},
|
||||
{
|
||||
"type": "route",
|
||||
"uuid": "1ee10c37-cb78-4594-9fd9-006a3927f6f2"
|
||||
}
|
||||
],
|
||||
"proxyMode": false,
|
||||
"proxyHost": "",
|
||||
"proxyRemovePrefix": false,
|
||||
"tlsOptions": {
|
||||
"enabled": false,
|
||||
"type": "CERT",
|
||||
"pfxPath": "",
|
||||
"certPath": "",
|
||||
"keyPath": "",
|
||||
"caPath": "",
|
||||
"passphrase": ""
|
||||
},
|
||||
"cors": true,
|
||||
"headers": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "Access-Control-Allow-Origin",
|
||||
"value": "*"
|
||||
},
|
||||
{
|
||||
"key": "Access-Control-Allow-Methods",
|
||||
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
|
||||
},
|
||||
{
|
||||
"key": "Access-Control-Allow-Headers",
|
||||
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
|
||||
}
|
||||
],
|
||||
"proxyReqHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"proxyResHeaders": [
|
||||
{
|
||||
"key": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"uuid": "80e9ddfd-1272-45d6-a29e-c927f0f8cebd",
|
||||
"id": "xl8l",
|
||||
"name": "Organizations",
|
||||
"documentation": "",
|
||||
"value": "[\n {\n \"id\": \"123456789123456789\",\n \"name\": \"Endor\",\n \"url\": \"http://127.0.0.1:3000/o/NQkU0cWc/manage/organization/overview\",\n \"samlConsumerUrl\": \"http://127.0.0.1:3000/saml/login/NQkU0cWc/RV3RrcB2UCVa\",\n \"samlConsumerUrls\": [\n \"http://127.0.0.1:3000/saml/login/NQkU0cWc/RV3RrcB2UCVa\"\n ],\n \"api\": {\n \"enabled\": true\n },\n \"licensing\": {\n \"model\": \"per-device\"\n },\n \"cloud\": {\n \"region\": {\n \"name\": \"Europe\",\n \"host\": {\n \"name\": \"Europe\"\n }\n }\n },\n \"management\": {\n \"details\": [\n {\n \"name\": \"customer number\",\n \"value\": \"56417983\"\n }\n ]\n }\n }\n]\n"
|
||||
},
|
||||
{
|
||||
"uuid": "337987b2-984c-4882-9e6e-83a2c2b714f5",
|
||||
"id": "zqoq",
|
||||
"name": "VPN Tunnels",
|
||||
"documentation": "",
|
||||
"value": "[\n {\n \"networkId\": \"Z_000000000000000001\",\n \"networkName\": \"ALDERAAN\",\n \"deviceSerial\": \"C3PO-R2P2-BB88\",\n \"deviceStatus\": \"dormant\",\n \"uplinks\": [],\n \"vpnMode\": \"spoke\",\n \"exportedSubnets\": [\n {\n \"name\": \"Single LAN Settings\",\n \"subnet\": \"172.16.254.24/29\"\n }\n ],\n \"merakiVpnPeers\": [\n {\n \"networkId\": \"Z_000000000000000002\",\n \"networkName\": \"KASHYYYK\",\n \"reachability\": \"unreachable\"\n },\n {\n \"networkId\": \"Z_000000000000000003\",\n \"networkName\": \"TATOOINE\",\n \"reachability\": \"unreachable\"\n },\n {\n \"networkId\": \"Z_000000000000000004\",\n \"networkName\": \"HOTH\",\n \"reachability\": \"unreachable\"\n }\n ],\n \"thirdPartyVpnPeers\": []\n }\n]"
|
||||
}
|
||||
],
|
||||
"callbacks": []
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
*** Settings ***
|
||||
Documentation Meraki VPN Tunnels
|
||||
|
||||
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
|
||||
|
||||
Suite Setup Start Mockoon ${MOCKOON_JSON}
|
||||
Test Timeout 120s
|
||||
|
||||
|
||||
*** Variables ***
|
||||
${MOCKOON_JSON} ${CURDIR}${/}meraki.mockoon.json
|
||||
|
||||
${CMD} ${CENTREON_PLUGINS} --plugin=network::cisco::meraki::cloudcontroller::restapi::plugin
|
||||
... --api-token=EEECGFCGFCGF
|
||||
... --statefile-dir=/dev/shm/
|
||||
|
||||
*** Test Cases ***
|
||||
Create cache from API
|
||||
[Tags] meraki api vpn network cache
|
||||
${output} Run
|
||||
... ${CMD} --mode=cache --proto http --port 3000 --hostname=127.0.0.1
|
||||
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... OK: Cache files created successfully
|
||||
... Wrong output result:\n\n ${output}\nInstead of:\n OK: Cache files created successfully\n\n
|
||||
# Mockoon is not needed any longer since the data are cached
|
||||
Stop Mockoon
|
||||
|
||||
Check if ${test_desc} works
|
||||
[Tags] meraki api vpn network
|
||||
${output} Run
|
||||
... ${CMD} --mode=vpn-tunnels --filter-network-name=${filter_network_name} --cache-use --critical-total-dormant=1:
|
||||
|
||||
${output} Strip String ${output}
|
||||
Should Be Equal As Strings
|
||||
... ${output}
|
||||
... ${expected}
|
||||
... Wrong output result:\n\n ${output}\nInstead of:\n ${expected}\n\n
|
||||
|
||||
Examples: test_desc filter_network_name expected --
|
||||
... all links .* OK: vpn tunnel 'C3PO-R2P2-BB88' status: dormant [mode: spoke] | 'vpn.tunnels.online.count'=0;;;0;1 'vpn.tunnels.offline.count'=0;;;0;1 'vpn.tunnels.dormant.count'=1;;1:;0;1
|
||||
... empty filter ${EMPTY} OK: vpn tunnel 'C3PO-R2P2-BB88' status: dormant [mode: spoke] | 'vpn.tunnels.online.count'=0;;;0;1 'vpn.tunnels.offline.count'=0;;;0;1 'vpn.tunnels.dormant.count'=1;;1:;0;1
|
||||
... absurd filter toto CRITICAL: Vpn tunnels dormant: 0 | 'vpn.tunnels.online.count'=0;;;0;0 'vpn.tunnels.offline.count'=0;;;0;0 'vpn.tunnels.dormant.count'=0;;1:;0;0
|
||||
|
Loading…
Reference in New Issue