Use apiv1 meraki (#2619)

This commit is contained in:
qgarnier 2021-02-26 15:39:31 +01:00 committed by GitHub
parent 1cb09f0adc
commit a41d05dac8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 144 additions and 41 deletions

View File

@ -43,13 +43,15 @@ sub new {
if (!defined($options{noptions})) { if (!defined($options{noptions})) {
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' }, 'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' }, 'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' }, 'proto:s' => { name => 'proto' },
'api-token:s' => { name => 'api_token' }, 'api-token:s' => { name => 'api_token' },
'timeout:s' => { name => 'timeout' }, 'timeout:s' => { name => 'timeout' },
'reload-cache-time:s' => { name => 'reload_cache_time' }, 'reload-cache-time:s' => { name => 'reload_cache_time' },
'ignore-permission-errors' => { name => 'ignore_permission_errors' } 'ignore-permission-errors' => { name => 'ignore_permission_errors' },
'use-extra-cache' => { name => 'use_extra_cache' },
'reload-extra-cache-time:s' => { name => 'reload_extra_cache_time' }
}); });
} }
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
@ -58,7 +60,14 @@ sub new {
$self->{http} = centreon::plugins::http->new(%options); $self->{http} = centreon::plugins::http->new(%options);
$self->{cache} = centreon::plugins::statefile->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options);
$self->{cache_checked} = 0; $self->{cache_checked} = 0;
$self->{cache_uplink_loss_latency} = {}; $self->{cache_extra_checked} = 0;
$self->{cached} = {
updated => 0,
uplink_statuses => {},
uplinks_loss_latency => {},
devices_statuses => {},
devices_connection_stats => {}
};
return $self; return $self;
} }
@ -80,6 +89,7 @@ sub check_options {
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
$self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : ''; $self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : '';
$self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? $self->{option_results}->{reload_cache_time} : 180; $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? $self->{option_results}->{reload_cache_time} : 180;
$self->{reload_cache_extra_time} = (defined($self->{option_results}->{reload_cache_extra_time})) ? $self->{option_results}->{reload_cache_extra_time} : 10;
$self->{ignore_permission_errors} = (defined($self->{option_results}->{ignore_permission_errors})) ? 1 : 0; $self->{ignore_permission_errors} = (defined($self->{option_results}->{ignore_permission_errors})) ? 1 : 0;
if (!defined($self->{hostname}) || $self->{hostname} eq '') { if (!defined($self->{hostname}) || $self->{hostname} eq '') {
@ -199,7 +209,7 @@ sub request_api {
while (1) { while (1) {
my $response = $self->{http}->request( my $response = $self->{http}->request(
hostname => $hostname, hostname => $hostname,
url_path => '/api/v0' . $options{endpoint}, url_path => '/api/v1' . $options{endpoint},
critical_status => '', critical_status => '',
warning_status => '', warning_status => '',
unknown_status => '' unknown_status => ''
@ -364,20 +374,26 @@ sub get_organization_device_statuses {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->cache_meraki_entities(); $self->cache_meraki_entities();
my $organization_ids = $self->filter_organizations(filter_name => $options{filter_name}); $self->load_extra_cache();
my $results = {}; return $self->{cached}->{devices_statuses}->{data} if (defined($self->{cached}->{devices_statuses}->{data}));
foreach my $id (@$organization_ids) {
$self->{cached}->{updated} = 1;
$self->{cached}->{devices_statuses} = {
update_time => time(),
data => {}
};
foreach my $id (keys %{$self->{cache_organizations}}) {
my $datas = $self->request_api( my $datas = $self->request_api(
endpoint => '/organizations/' . $id . '/deviceStatuses', endpoint => '/organizations/' . $id . '/devices/statuses',
hostname => $self->get_shard_hostname(organization_id => $id) hostname => $self->get_shard_hostname(organization_id => $id)
); );
foreach (@$datas) { foreach (@$datas) {
$results->{$_->{serial}} = $_; $self->{cached}->{devices_statuses}->{data}->{ $_->{serial} } = $_;
$results->{organizationId} = $id; $self->{cached}->{devices_statuses}->{data}->{organizationId} = $id;
} }
} }
return $results; return $self->{cached}->{devices_statuses}->{data};
} }
sub get_organization_api_requests_overview { sub get_organization_api_requests_overview {
@ -403,24 +419,58 @@ sub get_network_device_connection_stats {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->cache_meraki_entities(); $self->cache_meraki_entities();
$self->load_extra_cache();
my $timespan = defined($options{timespan}) ? $options{timespan} : 300; my $timespan = defined($options{timespan}) ? $options{timespan} : 300;
$timespan = 1 if ($timespan <= 0); $timespan = 1 if ($timespan <= 0);
return $self->request_api( if (!defined($self->{cached}->{devices_connection_stats}->{ $options{network_id} })) {
endpoint => '/networks/' . $options{network_id} . '/devices/' . $options{serial} . '/connectionStats?timespan=' . $options{timespan}, $self->{cached}->{updated} = 1;
hostname => $self->get_shard_hostname(network_id => $options{network_id}) $self->{cached}->{devices_connection_stats}->{ $options{network_id} } = {
); update_time => time(),
data => $self->request_api(
endpoint => '/networks/' . $options{network_id} . '/wireless/devices/connectionStats?timespan=' . $options{timespan},
hostname => $self->get_shard_hostname(network_id => $options{network_id})
)
};
}
my $result;
foreach (@{$self->{cached}->{devices_connection_stats}->{ $options{network_id} }->{data}}) {
if ($_->{serial} eq $options{serial}) {
$result = $_->{connectionStats};
last;
}
}
return $result;
} }
sub get_network_device_uplink { sub get_network_device_uplink {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->cache_meraki_entities(); $self->cache_meraki_entities();
$self->load_extra_cache();
return $self->request_api( if (!defined($self->{cached}->{uplink_statuses}->{ $options{organization_id} })) {
endpoint => '/networks/' . $options{network_id} . '/devices/' . $options{serial} . '/uplink', $self->{cached}->{updated} = 1;
hostname => $self->get_shard_hostname(network_id => $options{network_id}) $self->{cached}->{uplink_statuses}->{ $options{organization_id} } = {
); update_time => time(),
data => $self->request_api(
endpoint => '/organizations/' . $options{organization_id} . '/uplinks/statuses',
hostname => $self->get_shard_hostname(organization_id => $options{organization_id})
)
};
}
my $result;
foreach (@{$self->{cached}->{uplink_statuses}->{ $options{organization_id} }->{data}}) {
if ($_->{serial} eq $options{serial}) {
$result = $_->{uplinks};
last;
}
}
return $result;
} }
sub get_device_clients { sub get_device_clients {
@ -456,7 +506,7 @@ sub get_network_device_performance {
# 400 = feature not supported. 204 = no content # 400 = feature not supported. 204 = no content
return $self->request_api( return $self->request_api(
endpoint => '/networks/' . $options{network_id} . '/devices/' . $options{serial} . '/performance', endpoint => '/devices/' . $options{serial} . '/appliance/performance',
hostname => $self->get_shard_hostname(network_id => $options{network_id}), hostname => $self->get_shard_hostname(network_id => $options{network_id}),
ignore_codes => { 400 => 1, 204 => 1 } ignore_codes => { 400 => 1, 204 => 1 }
); );
@ -466,19 +516,25 @@ sub get_organization_uplink_loss_and_latency {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->cache_meraki_entities(); $self->cache_meraki_entities();
$self->load_extra_cache();
my $timespan = defined($options{timespan}) ? $options{timespan} : 300; my $timespan = defined($options{timespan}) ? $options{timespan} : 300;
$timespan = 1 if ($timespan <= 0); $timespan = 1 if ($timespan <= 0);
if (!defined($self->{cache_uplink_loss_latency}->{ $options{organization_id} })) { if (!defined($self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} })) {
$self->{cache_uplink_loss_latency}->{ $options{organization_id} } = $self->request_api( $self->{cached}->{updated} = 1;
endpoint => '/organizations/' . $options{organization_id} . '/uplinksLossAndLatency?timespan=' . $options{timespan}, $self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} } = {
hostname => $self->get_shard_hostname(organization_id => $options{organization_id}) update_time => time(),
); data => $self->request_api(
endpoint => '/organizations/' . $options{organization_id} . '/devices/uplinksLossAndLatency?timespan=' . $options{timespan},
hostname => $self->get_shard_hostname(organization_id => $options{organization_id})
)
};
} }
my $result = {}; my $result = {};
if (defined($self->{cache_uplink_loss_latency}->{ $options{organization_id} })) { if (defined($self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} }->{data})) {
foreach (@{$self->{cache_uplink_loss_latency}->{ $options{organization_id} }}) { foreach (@{$self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} }->{data}}) {
if ($options{serial} eq $_->{serial}) { if ($options{serial} eq $_->{serial}) {
$result->{ $_->{uplink} } = $_; $result->{ $_->{uplink} } = $_;
} }
@ -488,6 +544,41 @@ sub get_organization_uplink_loss_and_latency {
return $result; return $result;
} }
sub load_extra_cache {
my ($self, %options) = @_;
return if (!defined($self->{option_results}->{use_extra_cache}));
return if ($self->{cache_extra_checked} == 1);
$self->{cache_extra_checked} = 1;
my $has_cache_file = $self->{cache}->read(statefile => 'cache_extra_cisco_meraki_' . $self->get_token());
my $cached = $self->{cache}->get(name => 'cached');
$self->{cached} = $cached if (defined($cached));
if (defined($self->{cached}->{devices_statuses}->{update_time}) && ((time() - $self->{cached}->{devices_statuses}->{update_time}) > ($self->{reload_cache_extra_time} * 60))) {
$self->{cached}->{devices_statuses} = {};
}
foreach my $entry (('uplink_statuses', 'uplinks_loss_latency', 'devices_connection_stats')) {
next if (!defined($self->{cached}->{$entry}));
foreach (keys %{$self->{cached}->{$entry}}) {
if ((time() - $self->{cached}->{$entry}->{$_}->{update_time}) > ($self->{reload_cache_extra_time} * 60)) {
delete $self->{cached}->{$entry}->{$_};
}
}
}
}
sub close_extra_cache {
my ($self, %options) = @_;
return if (!defined($self->{option_results}->{use_extra_cache}));
if ($self->{cached}->{updated} == 1) {
$self->{cached}->{updated} = 0;
$self->{cache}->write(data => { cached => $self->{cached} });
}
}
1; 1;
__END__ __END__

View File

@ -299,7 +299,9 @@ sub new {
'filter-organization-id:s' => { name => 'filter_organization_id' }, 'filter-organization-id:s' => { name => 'filter_organization_id' },
'filter-tags:s' => { name => 'filter_tags' }, 'filter-tags:s' => { name => 'filter_tags' },
'add-switch-ports' => { name => 'add_switch_ports' }, 'add-switch-ports' => { name => 'add_switch_ports' },
'skip-traffic-disconnect-port' => { name => 'skip_traffic_disconnect_port' } 'skip-traffic-disconnect-port' => { name => 'skip_traffic_disconnect_port' },
'skip-clients' => { name => 'skip_clients' },
'skip-performance' => { name => 'skip_performance' }
}); });
return $self; return $self;
@ -350,7 +352,7 @@ sub add_uplink {
my $links = $options{custom}->get_network_device_uplink( my $links = $options{custom}->get_network_device_uplink(
serial => $options{serial}, serial => $options{serial},
network_id => $options{network_id} organization_id => $options{organization_id}
); );
if (defined($links)) { if (defined($links)) {
@ -479,7 +481,7 @@ sub manage_selection {
next; next;
} }
$devices->{ $_->{serial} } = $_->{model}; $devices->{ $_->{serial} } = { model => $_->{model}, organization_id => $organization->{id} };
} }
my $device_statuses = $options{custom}->get_organization_device_statuses(); my $device_statuses = $options{custom}->get_organization_device_statuses();
@ -505,7 +507,7 @@ sub manage_selection {
device_ports => {} device_ports => {}
}; };
if ($devices->{$serial} =~ /^(?:MG|MR)/) { if ($devices->{$serial}->{model} =~ /^(?:MG|MR)/) {
$self->add_connection_stats( $self->add_connection_stats(
custom => $options{custom}, custom => $options{custom},
timespan => $timespan, timespan => $timespan,
@ -514,7 +516,7 @@ sub manage_selection {
network_id => $cache_devices->{$serial}->{networkId} network_id => $cache_devices->{$serial}->{networkId}
); );
} }
if ($devices->{$serial} =~ /^(?:MS|MG|MR|MX)/) { if (!defined($self->{option_results}->{skip_clients}) && $devices->{$serial}->{model} =~ /^(?:MS|MG|MR|MX)/) {
$self->add_clients( $self->add_clients(
custom => $options{custom}, custom => $options{custom},
timespan => $timespan, timespan => $timespan,
@ -522,12 +524,12 @@ sub manage_selection {
name => $cache_devices->{$serial}->{name} name => $cache_devices->{$serial}->{name}
); );
} }
if ($devices->{$serial} =~ /^(?:MV|MS|MG|MR|MX)/) { if ($devices->{$serial}->{model} =~ /^(?:MV|MS|MG|MR|MX)/) {
$self->add_uplink( $self->add_uplink(
custom => $options{custom}, custom => $options{custom},
serial => $serial, serial => $serial,
name => $cache_devices->{$serial}->{name}, name => $cache_devices->{$serial}->{name},
network_id => $cache_devices->{$serial}->{networkId} organization_id => $devices->{$serial}->{organization_id}
); );
} }
if (defined($self->{option_results}->{add_switch_ports}) && $devices->{$serial} =~ /^MS/) { if (defined($self->{option_results}->{add_switch_ports}) && $devices->{$serial} =~ /^MS/) {
@ -537,13 +539,13 @@ sub manage_selection {
serial => $serial serial => $serial
); );
} }
if ($devices->{$serial} =~ /^MX/) { if ($devices->{$serial}->{model} =~ /^MX/) {
$self->add_performance( $self->add_performance(
custom => $options{custom}, custom => $options{custom},
serial => $serial, serial => $serial,
name => $cache_devices->{$serial}->{name}, name => $cache_devices->{$serial}->{name},
network_id => $cache_devices->{$serial}->{networkId} network_id => $cache_devices->{$serial}->{networkId}
); ) if (!defined($self->{option_results}->{skip_performance}));
$self->add_uplink_loss_latency( $self->add_uplink_loss_latency(
custom => $options{custom}, custom => $options{custom},
timespan => $timespan, timespan => $timespan,
@ -557,6 +559,8 @@ sub manage_selection {
if (defined($self->{global}->{ lc($device_statuses->{$serial}->{status}) })); if (defined($self->{global}->{ lc($device_statuses->{$serial}->{status}) }));
} }
$options{custom}->close_extra_cache();
if (scalar(keys %{$self->{devices}}) <= 0) { if (scalar(keys %{$self->{devices}}) <= 0) {
$self->{output}->output_add(short_msg => 'no devices found'); $self->{output}->output_add(short_msg => 'no devices found');
} }
@ -601,6 +605,14 @@ Filter devices by tags (Can be a regexp).
Add switch port statuses and traffic. Add switch port statuses and traffic.
=item B<--skip-clients>
Don't monitor clients traffic on device.
=item B<--skip-performance>
Don't monitor appliance perfscore.
=item B<--skip-traffic-disconnect-port> =item B<--skip-traffic-disconnect-port>
Skip port traffic counters if port status is disconnected. Skip port traffic counters if port status is disconnected.