From d23c44e686c104bbe713c9d6b652b40f485bf03e Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 7 Feb 2022 14:18:57 +0100 Subject: [PATCH] (plugin) network::cisco::meraki::cloudcontroller::restapi - change cache system + add pagination (#3466) --- .../cloudcontroller/restapi/custom/api.pm | 667 +++++++----------- .../restapi/mode/apirequests.pm | 36 +- .../cloudcontroller/restapi/mode/cache.pm | 60 ++ .../cloudcontroller/restapi/mode/devices.pm | 129 ++-- .../cloudcontroller/restapi/mode/discovery.pm | 22 +- .../restapi/mode/listdevices.pm | 24 +- .../cloudcontroller/restapi/mode/listtags.pm | 12 +- .../cloudcontroller/restapi/mode/networks.pm | 71 +- .../meraki/cloudcontroller/restapi/plugin.pm | 8 +- 9 files changed, 444 insertions(+), 585 deletions(-) create mode 100644 centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/cache.pm diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/custom/api.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/custom/api.pm index df199ba93..aff0f871f 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/custom/api.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/custom/api.pm @@ -50,11 +50,8 @@ sub new { 'timeout:s' => { name => 'timeout' }, 'reload-cache-time:s' => { name => 'reload_cache_time' }, 'ignore-permission-errors' => { name => 'ignore_permission_errors' }, - 'use-extra-cache' => { name => 'use_extra_cache' }, - 'reload-extra-cache-time:s' => { name => 'reload_extra_cache_time' }, - 'trace-api:s' => { name => 'trace_api' }, - 'trace-api-response:s' => { name => 'trace_api_response' }, - 'api-requests-disabled' => { name => 'api_requests_disabled' } + 'timespan:s' => { name => 'timespan' }, + 'cache-use' => { name => 'cache_use' } }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); @@ -62,17 +59,12 @@ sub new { $self->{output} = $options{output}; $self->{http} = centreon::plugins::http->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options); - $self->{cache_checked} = 0; - $self->{cache_extra_checked} = 0; - $self->{cached} = { - updated => 0, + + $self->{datas} = { uplink_statuses => {}, - uplinks_loss_latency => {}, - devices_statuses => {}, - devices_connection_stats => {}, - devices_performance => {}, - devices_clients => {} + uplinks_loss_latency => {} }; + $self->{devices_connection_stats} = {}; return $self; } @@ -96,6 +88,7 @@ sub check_options { $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? $self->{option_results}->{reload_cache_time} : 180; $self->{reload_extra_cache_time} = (defined($self->{option_results}->{reload_extra_cache_time})) ? $self->{option_results}->{reload_extra_cache_time} : 10; $self->{ignore_permission_errors} = (defined($self->{option_results}->{ignore_permission_errors})) ? 1 : 0; + $self->{timespan} = (defined($self->{option_results}->{timespan})) ? $self->{option_results}->{timespan} : 300; if (!defined($self->{hostname}) || $self->{hostname} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); @@ -106,19 +99,8 @@ sub check_options { $self->{output}->option_exit(); } - if (defined($self->{option_results}->{trace_api})) { - centreon::plugins::misc::mymodule_load( - output => $self->{output}, - module => 'Time::HiRes', - error_msg => "Cannot load module 'Time::HiRes'." - ); - centreon::plugins::misc::mymodule_load( - output => $self->{output}, - module => 'POSIX', - error_msg => "Cannot load module 'POSIX'." - ); - } - + # we force to use storable module + $self->{option_results}->{statefile_storable} = 1; $self->{cache}->check_options(option_results => $self->{option_results}); return 0; } @@ -129,44 +111,21 @@ sub get_token { return md5_hex($self->{api_token}); } -sub trace_api { - my ($self, %options) = @_; - - my $trace_file = $self->{option_results}->{trace_api} ne '' ? $self->{option_results}->{trace_api} : '/tmp/cisco_meraki_plugins.trace'; - open(FH, '>>', $trace_file) or return ; - - my $date_start = POSIX::strftime('%Y%m%d %H:%M:%S', localtime($options{time_start})); - $date_start .= sprintf('.%03d', ($options{time_start} - int($options{time_start})) * 1000); - - my $time_end = Time::HiRes::time(); - my $date_end = POSIX::strftime('%Y%m%d %H:%M:%S', localtime($time_end)); - $date_end .= sprintf('.%03d', ($time_end - int($time_end)) * 1000); - print FH "$date_start - $date_end - $$ - $self->{api_token} - $options{url} - $options{code}\n"; - if (defined($self->{option_results}->{trace_api_response})) { - if ($self->{option_results}->{trace_api_response} =~ /(\d+)/ && length($options{response}) < $1) { - print FH $options{response} . "\n"; - } else { - print FH $options{response} . "\n"; - } - } - close FH; -} - sub get_shard_hostname { my ($self, %options) = @_; my $organization_id = $options{organization_id}; my $network_id = $options{network_id}; - if (defined($options{serial}) && defined($self->{cache_devices}->{ $options{serial} })) { - $network_id = $self->{cache_devices}->{ $options{serial} }->{networkId}; + if (defined($options{serial}) && defined($self->{datas}->{devices}->{ $options{serial} })) { + $network_id = $self->{datas}->{devices}->{ $options{serial} }->{networkId}; } - if (defined($network_id) && defined($self->{cache_networks}->{$network_id})) { - $organization_id = $self->{cache_networks}->{$network_id}->{organizationId}; + if (defined($network_id) && defined($self->{datas}->{networks}->{$network_id})) { + $organization_id = $self->{datas}->{networks}->{$network_id}->{organizationId}; } if (defined($organization_id)) { - if (defined($self->{cache_organizations}->{$organization_id}) - && $self->{cache_organizations}->{$organization_id}->{url} =~ /^(?:http|https):\/\/(.*?)\//) { + if (defined($self->{datas}->{orgs}->{$organization_id}) + && $self->{datas}->{orgs}->{$organization_id}->{url} =~ /^(?:http|https):\/\/(.*?)\//) { return $1; } } @@ -174,49 +133,6 @@ sub get_shard_hostname { return undef; } -sub get_cache_organizations { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - return $self->{cache_organizations}; -} - -sub get_cache_networks { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - return $self->{cache_networks}; -} - -sub get_organization { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - my $organization_id; - if (defined($options{network_id})) { - $organization_id = $self->{cache_networks}->{ $options{network_id} }->{organizationId}; - } - my $organization; - $organization = $self->{cache_organizations}->{$organization_id} - if (defined($organization_id) && defined($self->{cache_organizations}->{$organization_id})); - - return $organization; -} - -sub get_organization_id { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - return $self->{cache_networks}->{ $options{network_id} }->{organizationId}; -} - -sub get_cache_devices { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - return $self->{cache_devices}; -} - sub build_options_for_httplib { my ($self, %options) = @_; @@ -236,8 +152,6 @@ sub settings { sub request_api { my ($self, %options) = @_; - return undef if (defined($self->{option_results}->{api_requests_disabled})); - $self->settings(); my $hostname = $self->{hostname}; @@ -249,20 +163,23 @@ sub request_api { #403: Forbidden- You don't have permission to do that. #404: Not found- No such URL, or you don't have access to the API or organization at all. #429: Too Many Requests- You submitted more than 5 calls in 1 second to an Organization, triggering rate limiting. This also applies for API calls made across multiple organizations that triggers rate limiting for one of the organizations. - my $time_start; + my $results = []; + my ($full_url, $get_param); + if (defined($options{paginate})) { + $get_param = ['perPage=' . $options{paginate}]; + } while (1) { - $time_start = Time::HiRes::time() if (defined($self->{option_results}->{trace_api})); my $response = $self->{http}->request( + full_url => $full_url, hostname => $hostname, url_path => '/api/v1' . $options{endpoint}, + get_param => $get_param, critical_status => '', warning_status => '', unknown_status => '' ); my $code = $self->{http}->get_code(); - $self->trace_api(time_start => $time_start, url => $hostname . '/api/v1' . $options{endpoint}, code => $code, response => $response) - if (defined($self->{option_results}->{trace_api})); return [] if ($code == 403 && $self->{ignore_permission_errors} == 1); return undef if (defined($options{ignore_codes}) && defined($options{ignore_codes}->{$code})); @@ -286,121 +203,288 @@ sub request_api { $self->{output}->option_exit(); } + if (defined($options{paginate})) { + push @$results, @$content; + + my ($link) = $self->{http}->get_header(name => 'Link'); + return $results if (!defined($link) || $link !~ /,\s+<([^;]*?)>;\s+rel=next/); + + $get_param = undef; + $full_url = $1; + next; + } + return ($content); } } -sub cache_meraki_entities { +sub write_cache_file { my ($self, %options) = @_; - return if ($self->{cache_checked} == 1); + $self->{cache}->read(statefile => 'cache_meraki_' . md5_hex($self->{api_token})); + $self->{cache}->write(data => { + update_time => time(), + response => $self->{datas} + }); +} - $self->{cache_checked} = 1; - my $has_cache_file = $self->{cache}->read(statefile => 'cache_cisco_meraki_' . $self->get_token()); - my $timestamp_cache = $self->{cache}->get(name => 'last_timestamp'); - $self->{cache_organizations} = $self->{cache}->get(name => 'organizations'); - $self->{cache_networks} = $self->{cache}->get(name => 'networks'); - $self->{cache_devices} = $self->{cache}->get(name => 'devices'); +sub get_cache_file_response { + my ($self, %options) = @_; - if ($has_cache_file == 0 || !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{reload_cache_time}) * 60))) { - $self->{cache_organizations} = $self->get_organizations( - disable_cache => 1 - ); - $self->{cache_networks} = $self->get_networks( - organizations => [keys %{$self->{cache_organizations}}], - disable_cache => 1 - ); - $self->{cache_devices} = $self->get_devices( - organizations => [keys %{$self->{cache_organizations}}], - disable_cache => 1 - ); - - $self->{cache}->write(data => { - last_timestamp => time(), - organizations => $self->{cache_organizations}, - networks => $self->{cache_networks}, - devices => $self->{cache_devices} - }); + $self->{cache}->read(statefile => 'cache_meraki_' . md5_hex($self->{api_token})); + $self->{datas} = $self->{cache}->get(name => 'response'); + if (!defined($self->{datas})) { + $self->{output}->add_option_msg(short_msg => 'Cache file missing'); + $self->{output}->option_exit(); } + + return $self->{datas}; +} + +sub call_datas { + my ($self, %options) = @_; + + $self->get_organizations(); + $self->get_networks(orgs => [keys %{$self->{datas}->{orgs}}]); + + if (!defined($options{skipDevices})) { + $self->get_devices(orgs => [keys %{$self->{datas}->{orgs}}]); + } + if (!defined($options{skipDevicesStatus})) { + $self->get_organization_device_statuses(orgs => [keys %{$self->{datas}->{orgs}}]); + } + + if (defined($options{cache})) { + foreach my $orgId (keys %{$self->{datas}->{orgs}}) { + $self->get_network_device_uplink(orgId => $orgId); + } + foreach my $orgId (keys %{$self->{datas}->{orgs}}) { + $self->get_organization_uplink_loss_and_latency(orgId => $orgId); + } + } +} + +sub cache_datas { + my ($self, %options) = @_; + + $self->call_datas(cache => 1); + $self->write_cache_file(); + + return $self->{datas}; +} + +sub get_datas { + my ($self, %options) = @_; + + return $self->get_cache_file_response() if (defined($self->{option_results}->{cache_use})); + $self->call_datas(%options); + return $self->{datas}; } sub get_organizations { my ($self, %options) = @_; - $self->cache_meraki_entities(); - return $self->{cache_organizations} if (!defined($options{disable_cache}) || $options{disable_cache} == 0); my $datas = $self->request_api(endpoint => '/organizations'); - my $results = {}; + $self->{datas}->{orgs} = {}; if (defined($datas)) { - $results->{$_->{id}} = $_ foreach (@$datas); + foreach (@$datas) { + $self->{datas}->{orgs}->{ $_->{id} } = { + name => $_->{name}, + url => $_->{url} + }; + } } - return $results; + return $self->{datas}->{orgs}; } sub get_networks { my ($self, %options) = @_; - $self->cache_meraki_entities(); - return $self->{cache_networks} if (!defined($options{disable_cache}) || $options{disable_cache} == 0); - - my $results = {}; - foreach my $id (keys %{$self->{cache_organizations}}) { + $self->{datas}->{networks} = {}; + foreach my $id (@{$options{orgs}}) { my $datas = $self->request_api( endpoint => '/organizations/' . $id . '/networks', hostname => $self->get_shard_hostname(organization_id => $id) ); if (defined($datas)) { - $results->{ $_->{id} } = $_ foreach (@$datas); + foreach (@$datas) { + if (defined($options{extended})) { + $self->{datas}->{networks}->{ $_->{id} } = $_; + } else { + $self->{datas}->{networks}->{ $_->{id} } = { + name => $_->{name}, + organizationId => $_->{organizationId} + }; + } + } } } - return $results; + return $self->{datas}->{networks}; } sub get_devices { my ($self, %options) = @_; - $self->cache_meraki_entities(); - return $self->{cache_devices} if (!defined($options{disable_cache}) || $options{disable_cache} == 0); - - my $results = {}; - foreach my $id (keys %{$self->{cache_organizations}}) { + $self->{datas}->{devices} = {}; + foreach my $id (@{$options{orgs}}) { my $datas = $self->request_api( endpoint => '/organizations/' . $id . '/devices', + paginate => 1000, hostname => $self->get_shard_hostname(organization_id => $id) ); if (defined($datas)) { - $results->{ $_->{serial} } = $_ foreach (@$datas); + foreach (@$datas) { + if (defined($options{extended})) { + $self->{datas}->{devices}->{ $_->{serial} } = $_; + $self->{datas}->{devices}->{ $_->{serial} }->{orgId} = $id; + } else { + $self->{datas}->{devices}->{ $_->{serial} } = { + name => $_->{name}, + networkId => $_->{networkId}, + orgId => $id, + tags => $_->{tags}, + model => $_->{model} + }; + } + } } } + return $self->{datas}->{devices}; +} + +sub get_organization_device_statuses { + my ($self, %options) = @_; + + $self->{datas}->{devices_status} = {}; + foreach my $id (@{$options{orgs}}) { + my $datas = $self->request_api( + endpoint => '/organizations/' . $id . '/devices/statuses', + paginate => 1000, + hostname => $self->get_shard_hostname(organization_id => $id) + ); + foreach (@$datas) { + if (defined($options{extended})) { + $self->{datas}->{devices_status}->{ $_->{serial} } = $_; + } else { + $self->{datas}->{devices_status}->{ $_->{serial} } = { + status => $_->{status} + }; + } + } + } + + return $self->{datas}->{devices_status}; +} + +sub get_network_device_uplink { + my ($self, %options) = @_; + + if (!defined($self->{datas}->{uplink_statuses}->{ $options{orgId} })) { + $self->{datas}->{uplink_statuses}->{ $options{orgId} } = {}; + my $datas = $self->request_api( + endpoint => '/organizations/' . $options{orgId} . '/uplinks/statuses', + paginate => 1000, + hostname => $self->get_shard_hostname(organization_id => $options{orgId}) + ); + foreach (@$datas) { + $self->{datas}->{uplink_statuses}->{ $options{orgId} }->{ $_->{serial} } = $_->{uplinks}; + } + } + + return defined($options{serial}) ? + $self->{datas}->{uplink_statuses}->{ $options{orgId} }->{ $options{serial} } : + $self->{datas}->{uplink_statuses}->{ $options{orgId} }; +} + +sub get_organization_uplink_loss_and_latency { + my ($self, %options) = @_; + + if (!defined($self->{datas}->{uplinks_loss_latency}->{ $options{orgId} })) { + $self->{datas}->{uplinks_loss_latency}->{ $options{orgId} } = {}; + my $datas = $self->request_api( + endpoint => '/organizations/' . $options{orgId} . '/devices/uplinksLossAndLatency?timespan=' . $self->{timespan}, + paginate => 1000, + hostname => $self->get_shard_hostname(organization_id => $options{orgId}) + ); + foreach (@$datas) { + $self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $_->{serial} } = {} + if (!defined($self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $_->{serial} })); + $self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $_->{serial} }->{ $_->{uplink} } = $_; + } + } + + return defined($options{serial}) ? + $self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }->{ $options{serial} } : + $self->{datas}->{uplinks_loss_latency}->{ $options{orgId} }; +} + +sub get_device_clients { + my ($self, %options) = @_; + + return $self->request_api( + endpoint => '/devices/' . $options{serial} . '/clients?timespan=' . $self->{timespan}, + hostname => $self->get_shard_hostname(serial => $options{serial}) + ) +} + +sub get_device_switch_port_statuses { + my ($self, %options) = @_; + + return $self->request_api( + endpoint => '/devices/' . $options{serial} . '/switchPortStatuses?timespan=' . $self->{timespan}, + hostname => $self->get_shard_hostname(serial => $options{serial}) + ); +} + +sub get_network_device_connection_stats { + my ($self, %options) = @_; + + if (!defined($self->{devices_connection_stats}->{ $options{network_id} })) { + $self->{devices_connection_stats}->{ $options{network_id} } = {}; + my $datas = $self->request_api( + endpoint => '/networks/' . $options{network_id} . '/wireless/devices/connectionStats?timespan=' . $self->{timespan}, + hostname => $self->get_shard_hostname(network_id => $options{network_id}) + ); + foreach (@$datas) { + $self->{devices_connection_stats}->{ $options{network_id} }->{ $_->{serial} } = $_->{connectionStats}; + } + } + + return defined($options{serial}) ? + $self->{devices_connection_stats}->{ $options{network_id} }->{ $options{serial} } : + $self->{devices_connection_stats}->{ $options{network_id} }; +} + +sub get_network_device_performance { + my ($self, %options) = @_; + + $self->request_api( + endpoint => '/devices/' . $options{serial} . '/appliance/performance', + hostname => $self->get_shard_hostname(network_id => $options{network_id}), + ignore_codes => { 400 => 1, 204 => 1 } + ); +} + +sub get_organization_api_requests_overview { + my ($self, %options) = @_; + + my $results = {}; + foreach my $id (@{$options{orgs}}) { + $results->{$id} = $self->request_api( + endpoint => '/organizations/' . $id . '/apiRequests/overview?timespan=' . $self->{timespan}, + hostname => $self->get_shard_hostname(organization_id => $id) + ); + } + return $results; } -sub filter_organizations { - my ($self, %options) = @_; - - my $organization_ids = []; - foreach (values %{$self->{cache_organizations}}) { - if (!defined($options{filter_name}) || $options{filter_name} eq '') { - push @$organization_ids, $_->{id}; - } elsif ($_->{name} =~ /$options{filter_name}/) { - push @$organization_ids, $_->{id}; - } - } - - return $organization_ids; -} - sub get_networks_connection_stats { my ($self, %options) = @_; - $self->cache_meraki_entities(); - - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - return $self->request_api( endpoint => '/networks/' . $options{network_id}, hostname => $self->get_shard_hostname(network_id => $options{network_id}), @@ -411,246 +495,13 @@ sub get_networks_connection_stats { sub get_networks_clients { my ($self, %options) = @_; - $self->cache_meraki_entities(); - - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - return $self->request_api( - endpoint => '/networks/' . $options{network_id} . '/clients?timespan=' . $options{timespan}, + endpoint => '/networks/' . $options{network_id} . '/clients?timespan=' . $self->{timespan}, hostname => $self->get_shard_hostname(network_id => $options{network_id}), ignore_codes => { 400 => 1 } ); } -sub get_organization_device_statuses { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - return $self->{cached}->{devices_statuses}->{data} if (defined($self->{cached}->{devices_statuses}->{data})); - - $self->{cached}->{updated} = 1; - $self->{cached}->{devices_statuses} = { - update_time => time(), - data => {} - }; - foreach my $id (keys %{$self->{cache_organizations}}) { - my $datas = $self->request_api( - endpoint => '/organizations/' . $id . '/devices/statuses', - hostname => $self->get_shard_hostname(organization_id => $id) - ); - foreach (@$datas) { - $self->{cached}->{devices_statuses}->{data}->{ $_->{serial} } = $_; - $self->{cached}->{devices_statuses}->{data}->{organizationId} = $id; - } - } - - return $self->{cached}->{devices_statuses}->{data}; -} - -sub get_organization_api_requests_overview { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - my $organization_ids = $self->filter_organizations(filter_name => $options{filter_name}); - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - - my $results = {}; - foreach my $id (@$organization_ids) { - $results->{$id} = $self->request_api( - endpoint => '/organizations/' . $id . '/apiRequests/overview?timespan=' . $options{timespan}, - hostname => $self->get_shard_hostname(organization_id => $id) - ); - } - - return $results; -} - -sub get_network_device_connection_stats { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - - if (!defined($self->{cached}->{devices_connection_stats}->{ $options{network_id} })) { - $self->{cached}->{updated} = 1; - $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 { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - - if (!defined($self->{cached}->{uplink_statuses}->{ $options{organization_id} })) { - $self->{cached}->{updated} = 1; - $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 { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - - if (!defined($self->{cached}->{devices_clients}->{ $options{serial} })) { - $self->{cached}->{updated} = 1; - # 400 = feature not supported. 204 = no content - $self->{cached}->{devices_clients}->{ $options{serial} } = { - update_time => time(), - data => $self->request_api( - endpoint => '/devices/' . $options{serial} . '/clients?timespan=' . $options{timespan}, - hostname => $self->get_shard_hostname(serial => $options{serial}) - ) - }; - } - - return $self->{cached}->{devices_clients}->{ $options{serial} }->{data}; -} - -sub get_device_switch_port_statuses { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - - return $self->request_api( - endpoint => '/devices/' . $options{serial} . '/switchPortStatuses?timespan=' . $options{timespan}, - hostname => $self->get_shard_hostname(serial => $options{serial}) - ); -} - -sub get_network_device_performance { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - - if (!defined($self->{cached}->{devices_performance}->{ $options{serial} })) { - $self->{cached}->{updated} = 1; - # 400 = feature not supported. 204 = no content - $self->{cached}->{devices_performance}->{ $options{serial} } = { - update_time => time(), - data => $self->request_api( - endpoint => '/devices/' . $options{serial} . '/appliance/performance', - hostname => $self->get_shard_hostname(network_id => $options{network_id}), - ignore_codes => { 400 => 1, 204 => 1 } - ) - }; - } - - return $self->{cached}->{devices_performance}->{ $options{serial} }->{data}; -} - -sub get_organization_uplink_loss_and_latency { - my ($self, %options) = @_; - - $self->cache_meraki_entities(); - $self->load_extra_cache(); - - my $timespan = defined($options{timespan}) ? $options{timespan} : 300; - $timespan = 1 if ($timespan <= 0); - - if (!defined($self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} })) { - $self->{cached}->{updated} = 1; - $self->{cached}->{uplinks_loss_latency}->{ $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 = {}; - if (defined($self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} }->{data})) { - foreach (@{$self->{cached}->{uplinks_loss_latency}->{ $options{organization_id} }->{data}}) { - if ($options{serial} eq $_->{serial}) { - $result->{ $_->{uplink} } = $_; - } - } - } - - 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_extra_cache_time} * 60))) { - $self->{cached}->{devices_statuses} = {}; - } - - foreach my $entry (('uplink_statuses', 'uplinks_loss_latency', 'devices_connection_stats', 'devices_performance', 'devices_clients')) { - next if (!defined($self->{cached}->{$entry})); - - foreach (keys %{$self->{cached}->{$entry}}) { - if ((time() - $self->{cached}->{$entry}->{$_}->{update_time}) > ($self->{reload_extra_cache_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; __END__ @@ -687,14 +538,14 @@ Meraki api token. Set HTTP timeout -=item B<--reload-cache-time> - -Time in minutes before reloading cache file (default: 180). - =item B<--ignore-permission-errors> Ignore permission errors (403 status code). +=item B<--cache-use> + +Use the cache file (created with cache mode). + =back =head1 DESCRIPTION diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/apirequests.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/apirequests.pm index 09b17bd39..28ce0dc08 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/apirequests.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/apirequests.pm @@ -38,8 +38,7 @@ sub set_counters { key_values => [ { name => 'requests_200' }, { name => 'display' } ], output_template => 'code 200: %s', perfdatas => [ - { value => 'requests_200', - template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } ] } }, @@ -47,8 +46,7 @@ sub set_counters { key_values => [ { name => 'requests_404' }, { name => 'display' } ], output_template => 'code 404: %s', perfdatas => [ - { value => 'requests_404', - template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } ] } }, @@ -56,8 +54,7 @@ sub set_counters { key_values => [ { name => 'requests_429' }, { name => 'display' } ], output_template => 'code 429: %s', perfdatas => [ - { value => 'requests_429', - template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } ] } } @@ -72,7 +69,7 @@ sub prefix_organization_output { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { @@ -85,23 +82,18 @@ sub new { sub manage_selection { my ($self, %options) = @_; - $self->{cache_name} = 'meraki_' . $self->{mode} . '_' . $options{custom}->get_token() . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_organization_name}) ? md5_hex($self->{option_results}->{filter_organization_name}) : md5_hex('all')); - my $last_timestamp = $self->read_statefile_key(key => 'last_timestamp'); - my $timespan = 300; - $timespan = time() - $last_timestamp if (defined($last_timestamp)); - - my $cache_organizations = $options{custom}->get_cache_organizations(); - my $api_requests = $options{custom}->get_organization_api_requests_overview(timespan => $timespan, filter_name => $self->{option_results}->{filter_organization_name}); + my $orgs = $options{custom}->get_organizations(); $self->{organizations} = {}; - foreach my $id (keys %$api_requests) { - $self->{organizations}->{$id} = { - display => $cache_organizations->{$id}->{name}, - requests_200 => defined($api_requests->{$id}->{responseCodeCounts}->{200}) ? $api_requests->{$id}->{responseCodeCounts}->{200} : 0, - requests_404 => defined($api_requests->{$id}->{responseCodeCounts}->{404}) ? $api_requests->{$id}->{responseCodeCounts}->{404} : 0, - requests_429 => defined($api_requests->{$id}->{responseCodeCounts}->{429}) ? $api_requests->{$id}->{responseCodeCounts}->{429} : 0, + foreach my $orgId (keys %$orgs) { + next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' && + $orgs->{orgId}->{name} !~ /$self->{option_results}->{filter_organization_name}/); + my $api_requests = $options{custom}->get_organization_api_requests_overview(orgs => [$orgId]); + $self->{organizations}->{$orgId} = { + display => $orgs->{$orgId}->{name}, + requests_200 => defined($api_requests->{$orgId}->{responseCodeCounts}->{200}) ? $api_requests->{$orgId}->{responseCodeCounts}->{200} : 0, + requests_404 => defined($api_requests->{$orgId}->{responseCodeCounts}->{404}) ? $api_requests->{$orgId}->{responseCodeCounts}->{404} : 0, + requests_429 => defined($api_requests->{$orgId}->{responseCodeCounts}->{429}) ? $api_requests->{$orgId}->{responseCodeCounts}->{429} : 0 }; } diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/cache.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/cache.pm new file mode 100644 index 000000000..ee40026a3 --- /dev/null +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/cache.pm @@ -0,0 +1,60 @@ +# +# Copyright 2022 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::cache; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $options{custom}->cache_datas(); + $self->{output}->output_add( + severity => 'OK', + short_msg => 'Cache files created successfully' + ); +} + +1; + +__END__ + +=head1 MODE + +Create cache files (other modes could use it with --cache-use option). + +=over 8 + +=back + +=cut diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm index ebb5c2b34..2a22550be 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm @@ -312,7 +312,6 @@ sub add_connection_stats { my ($self, %options) = @_; my $connections = $options{custom}->get_network_device_connection_stats( - timespan => $options{timespan}, serial => $options{serial}, network_id => $options{network_id} ); @@ -330,7 +329,6 @@ sub add_clients { my ($self, %options) = @_; my $clients = $options{custom}->get_device_clients( - timespan => $options{timespan}, serial => $options{serial} ); @@ -353,7 +351,7 @@ sub add_uplink { my $links = $options{custom}->get_network_device_uplink( serial => $options{serial}, - organization_id => $options{organization_id} + orgId => $options{orgId} ); if (defined($links)) { @@ -371,11 +369,9 @@ sub add_uplink { sub add_uplink_loss_latency { my ($self, %options) = @_; - # 5 minutes max timespan my $links = $options{custom}->get_organization_uplink_loss_and_latency( - timespan => 300, serial => $options{serial}, - organization_id => $options{custom}->get_organization_id(network_id => $options{network_id}) + orgId => $options{orgId} ); return if (!defined($links)); @@ -422,7 +418,6 @@ sub add_switch_port_statuses { my ($self, %options) = @_; my $ports = $options{custom}->get_device_switch_port_statuses( - timespan => $options{timespan}, serial => $options{serial} ); @@ -443,54 +438,14 @@ sub manage_selection { my ($self, %options) = @_; $self->{cache_name} = 'meraki_' . $self->{mode} . '_' . $options{custom}->get_token() . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_device_name}) ? md5_hex($self->{option_results}->{filter_device_name}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_network_id}) ? md5_hex($self->{option_results}->{filter_network_id}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_organization_id}) ? md5_hex($self->{option_results}->{filter_organization_id}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_organization_name}) ? md5_hex($self->{option_results}->{filter_organization_name}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_tags}) ? md5_hex($self->{option_results}->{filter_tags}) : md5_hex('all')); - my $last_timestamp = $self->read_statefile_key(key => 'last_timestamp'); - my $timespan = 300; - $timespan = time() - $last_timestamp if (defined($last_timestamp)); - - my $cache_devices = $options{custom}->get_cache_devices(); - my $devices = {}; - foreach (values %$cache_devices) { - if (defined($self->{option_results}->{filter_device_name}) && $self->{option_results}->{filter_device_name} ne '' && - $_->{name} !~ /$self->{option_results}->{filter_device_name}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' && - $_->{networkId} !~ /$self->{option_results}->{filter_network_id}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - if (defined($self->{option_results}->{filter_tags}) && $self->{option_results}->{filter_tags} ne '') { - my $tags; - $tags = join(' ', @{$_->{tags}}) if (defined($_->{tags})); - if (!defined($tags) || $tags !~ /$self->{option_results}->{filter_tags}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - } - - my $organization = $options{custom}->get_organization(network_id => $_->{networkId}); - if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && - $organization->{id} !~ /$self->{option_results}->{filter_organization_id}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' && - $organization->{name} !~ /$self->{option_results}->{filter_organization_name}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - - $devices->{ $_->{serial} } = { model => $_->{model}, organization_id => $organization->{id} }; - } - - my $device_statuses = $options{custom}->get_organization_device_statuses(); + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : 'all') . '_' . + (defined($self->{option_results}->{filter_device_name}) ? $self->{option_results}->{filter_device_name} : 'all') . '_' . + (defined($self->{option_results}->{filter_network_id}) ? $self->{option_results}->{filter_network_id} : 'all') . '_' . + (defined($self->{option_results}->{filter_organization_id}) ? $self->{option_results}->{filter_organization_id} : 'all') . '_' . + (defined($self->{option_results}->{filter_organization_name}) ? $self->{option_results}->{filter_organization_name} : 'all') . '_' . + (defined($self->{option_results}->{filter_tags}) ? $self->{option_results}->{filter_tags} : 'all') + ); # | /clients | /connectionStats | /performance | /uplink | /uplinksLossAndLatency | /switchPortStatuses #-------------------|----------|---------------------------------|---------|------------------------|----------------------- @@ -500,73 +455,87 @@ sub manage_selection { # MX [appliance] | X | | X | X | X | # MR [wireless] | X | X | | X | | + my $datas = $options{custom}->get_datas(); + $self->{global} = { total => 0, online => 0, offline => 0, alerting => 0, offline_prct => 0, online_prct => 0 }; $self->{devices} = {}; - foreach my $serial (keys %$devices) { + foreach my $serial (keys %{$datas->{devices}}) { + next if (defined($self->{option_results}->{filter_device_name}) && $self->{option_results}->{filter_device_name} ne '' && + $datas->{devices}->{$serial}->{name} !~ /$self->{option_results}->{filter_device_name}/); + next if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' && + $datas->{devices}->{$serial}->{networkId} !~ /$self->{option_results}->{filter_network_id}/); + + if (defined($self->{option_results}->{filter_tags}) && $self->{option_results}->{filter_tags} ne '') { + my $tags; + $tags = join(' ', @{$datas->{devices}->{$serial}->{tags}}) if (defined($datas->{devices}->{$serial}->{tags})); + if (!defined($tags) || $tags !~ /$self->{option_results}->{filter_tags}/) { + next; + } + } + next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && + $datas->{devices}->{$serial}->{orgId} !~ /$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->{devices}->{$serial}->{orgId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/); + $self->{devices}->{$serial} = { - display => $cache_devices->{$serial}->{name}, + display => $datas->{devices}->{$serial}->{name}, device_status => { - display => $cache_devices->{$serial}->{name}, - status => $device_statuses->{$serial}->{status} + display => $datas->{devices}->{$serial}->{name}, + status => $datas->{devices_status}->{$serial}->{status} }, device_links => {}, device_ports => {} }; - if (!defined($self->{option_results}->{skip_connections}) && $devices->{$serial}->{model} =~ /^(?:MG|MR)/) { + if (!defined($self->{option_results}->{skip_connections}) && $datas->{devices}->{$serial}->{model} =~ /^(?:MG|MR)/) { $self->add_connection_stats( custom => $options{custom}, - timespan => $timespan, serial => $serial, - name => $cache_devices->{$serial}->{name}, - network_id => $cache_devices->{$serial}->{networkId} + name => $datas->{devices}->{$serial}->{name}, + network_id => $datas->{devices}->{$serial}->{networkId} ); } - if (!defined($self->{option_results}->{skip_clients}) && $devices->{$serial}->{model} =~ /^(?:MS|MG|MR|MX)/) { + if (!defined($self->{option_results}->{skip_clients}) && $datas->{devices}->{$serial}->{model} =~ /^(?:MS|MG|MR|MX)/) { $self->add_clients( custom => $options{custom}, - timespan => $timespan, serial => $serial, - name => $cache_devices->{$serial}->{name} + name => $datas->{devices}->{$serial}->{name} ); } - if ($devices->{$serial}->{model} =~ /^(?:MV|MS|MG|MR|MX)/) { + if ($datas->{devices}->{$serial}->{model} =~ /^(?:MV|MS|MG|MR|MX)/) { $self->add_uplink( custom => $options{custom}, serial => $serial, - name => $cache_devices->{$serial}->{name}, - organization_id => $devices->{$serial}->{organization_id} + name => $datas->{devices}->{$serial}->{name}, + orgId => $datas->{devices}->{$serial}->{orgId} ); } - if (defined($self->{option_results}->{add_switch_ports}) && $devices->{$serial} =~ /^MS/) { + if (defined($self->{option_results}->{add_switch_ports}) && $datas->{devices}->{$serial}->{model} =~ /^MS/) { $self->add_switch_port_statuses( custom => $options{custom}, - timespan => $timespan, serial => $serial ); } - if ($devices->{$serial}->{model} =~ /^MX/) { + if ($datas->{devices}->{$serial}->{model} =~ /^MX/) { $self->add_performance( custom => $options{custom}, serial => $serial, - name => $cache_devices->{$serial}->{name}, - network_id => $cache_devices->{$serial}->{networkId} + name => $datas->{devices}->{$serial}->{name}, + network_id => $datas->{devices}->{$serial}->{networkId} ) if (!defined($self->{option_results}->{skip_performance})); + $self->add_uplink_loss_latency( custom => $options{custom}, - timespan => $timespan, serial => $serial, - network_id => $cache_devices->{$serial}->{networkId} + orgId => $datas->{devices}->{$serial}->{orgId} ); } $self->{global}->{total}++; - $self->{global}->{ lc($device_statuses->{$serial}->{status}) }++ - if (defined($self->{global}->{ lc($device_statuses->{$serial}->{status}) })); + $self->{global}->{ lc($datas->{devices_status}->{$serial}->{status}) }++ + if (defined($self->{global}->{ lc($datas->{devices_status}->{$serial}->{status}) })); } - $options{custom}->close_extra_cache(); - if (scalar(keys %{$self->{devices}}) <= 0) { $self->{output}->output_add(short_msg => 'no devices found'); } diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/discovery.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/discovery.pm index a9225bd69..9291f2b0e 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/discovery.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/discovery.pm @@ -60,10 +60,13 @@ sub discovery_devices { my ($self, %options) = @_; my $devices = $options{custom}->get_devices( - organizations => [keys %{$options{organizations}}], - disable_cache => 1 + orgs => [keys %{$options{organizations}}], + extended => 1 + ); + my $devices_statuses = $options{custom}->get_organization_device_statuses( + orgs => [keys %{$options{organizations}}], + extended => 1 ); - my $devices_statuses = $options{custom}->get_organization_device_statuses(); my @results; foreach (values %$devices) { @@ -72,9 +75,9 @@ sub discovery_devices { next if (defined($self->{option_results}->{filter_tags}) && $self->{option_results}->{filter_tags} ne '' && (!defined($_->{tags}) || $_->{tags} !~ /$self->{option_results}->{filter_tags}/)); next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && - $options{networks}->{ $_->{networkId} }->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/); + $_->{orgId} !~ /$self->{option_results}->{filter_organization_id}/); next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' && - $options{organizations}->{ $options{networks}->{ $_->{networkId} }->{organizationId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/); + $options{organizations}->{ $_->{orgId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/); my $node = { name => $_->{name}, @@ -93,7 +96,7 @@ sub discovery_devices { lan_ip => $_->{lanIp}, network_id => $_->{networkId}, network_name => $options{networks}->{ $_->{networkId} }->{name}, - organization_name => $options{organizations}->{ $options{networks}->{ $_->{networkId} }->{organizationId} }->{name}, + organization_name => $options{organizations}->{ $_->{orgId} }->{name}, configuration_updated_at => $_->{configurationUpdatedAt}, last_reported_at => $devices_statuses->{ $_->{serial} }->{lastReportedAt} }; @@ -144,11 +147,10 @@ sub run { $disco_stats->{start_time} = time(); - my $organizations = $options{custom}->get_organizations(disable_cache => 1); - + my $organizations = $options{custom}->get_organizations(); my $networks = $options{custom}->get_networks( - organizations => [keys %{$organizations}], - disable_cache => 1 + orgs => [keys %{$organizations}], + extended => 1 ); if ($self->{option_results}->{resource_type} eq 'network') { diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listdevices.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listdevices.pm index f46a12331..e0490e0e5 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listdevices.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listdevices.pm @@ -48,17 +48,20 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - my $organizations = $options{custom}->get_organizations(disable_cache => 1); + my $organizations = $options{custom}->get_organizations(); my $networks = $options{custom}->get_networks( - organizations => [keys %$organizations], - disable_cache => 1 + orgs => [keys %$organizations], + extended => 1 ); my $devices = $options{custom}->get_devices( - organizations => [keys %$organizations], - disable_cache => 1 + orgs => [keys %$organizations], + extended => 1 + ); + my $devices_statuses = $options{custom}->get_organization_device_statuses( + orgs => [keys %$organizations], + extended => 1 ); - my $devices_statuses = $options{custom}->get_organization_device_statuses(); my $results = {}; foreach (keys %$devices) { next if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' && @@ -69,14 +72,15 @@ sub manage_selection { next if (!defined($tags) || $tags !~ /$self->{option_results}->{filter_tags}/); } next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && - $networks->{ $devices->{$_}->{networkId} }->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/); + $devices->{$_}->{orgId} !~ /$self->{option_results}->{filter_organization_id}/); - my $organization_name = $organizations->{ $networks->{ $devices->{$_}->{networkId} }->{organizationId} }->{name}; + my $organization_name = $organizations->{ $devices->{$_}->{orgId} }->{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->{$_} = { - %{$devices->{$_}}, + name => $devices->{$_}->{name}, + tags => $devices->{$_}->{tags}, status => $devices_statuses->{ $devices->{$_}->{serial} }->{status}, public_ip => $devices_statuses->{ $devices->{$_}->{serial} }->{publicIp}, network_name => $networks->{ $devices->{$_}->{networkId} }->{name}, @@ -129,7 +133,7 @@ sub disco_show { network_name => $_->{network_name}, network_id => $_->{networkId}, organization_name => $_->{organization_name}, - tags => defined($_->{tags}) ? $_->{tags} : '' + tags => defined($_->{tags}) ? join(',', @{$_->{tags}}) : '' ); } } diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listtags.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listtags.pm index 81b3f569c..d1b24b709 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listtags.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/listtags.pm @@ -48,14 +48,12 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - my $organizations = $options{custom}->get_organizations(disable_cache => 1); + my $organizations = $options{custom}->get_organizations(); my $networks = $options{custom}->get_networks( - organizations => [keys %$organizations], - disable_cache => 1 + orgs => [keys %$organizations] ); my $devices = $options{custom}->get_devices( - organizations => [keys %$organizations], - disable_cache => 1 + orgs => [keys %$organizations] ); my $results = {}; @@ -64,9 +62,9 @@ sub manage_selection { 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 '' && - $networks->{ $devices->{$_}->{networkId} }->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/); + $devices->{$_}->{orgId} !~ /$self->{option_results}->{filter_organization_id}/); - my $organization_name = $organizations->{ $networks->{ $devices->{$_}->{networkId} }->{organizationId} }->{name}; + my $organization_name = $organizations->{ $devices->{$_}->{orgId} }->{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}/); diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/networks.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/networks.pm index 96d620451..4c42cc2ff 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/networks.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/mode/networks.pm @@ -26,6 +26,12 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); +sub prefix_network_output { + my ($self, %options) = @_; + + return "Network '" . $options{instance_value}->{display} . "' "; +} + sub set_counters { my ($self, %options) = @_; @@ -95,12 +101,6 @@ sub set_counters { ]; } -sub prefix_network_output { - my ($self, %options) = @_; - - return "Network '" . $options{instance_value}->{display} . "' "; -} - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); @@ -119,47 +119,30 @@ sub manage_selection { my ($self, %options) = @_; $self->{cache_name} = 'meraki_' . $self->{mode} . '_' . $options{custom}->get_token() . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_network_name}) ? md5_hex($self->{option_results}->{filter_network_name}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_organization_id}) ? md5_hex($self->{option_results}->{filter_organization_id}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_organization_name}) ? md5_hex($self->{option_results}->{filter_organization_name}) : md5_hex('all')); - my $last_timestamp = $self->read_statefile_key(key => 'last_timestamp'); - my $timespan = 300; - $timespan = time() - $last_timestamp if (defined($last_timestamp)); + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : 'all') . '_' . + (defined($self->{option_results}->{filter_network_name}) ? $self->{option_results}->{filter_network_name} : 'all') . '_' . + (defined($self->{option_results}->{filter_organization_id}) ? $self->{option_results}->{filter_organization_id} : 'all') . '_' . + (defined($self->{option_results}->{filter_organization_name}) ? $self->{option_results}->{filter_organization_name} : 'all') + ); + + my $datas = $options{custom}->get_datas(skipDevices => 1, skipDevicesStatus => 1); $self->{networks} = {}; + foreach my $id (keys %{$datas->{networks}}) { + next if (defined($self->{option_results}->{filter_network_name}) && $self->{option_results}->{filter_network_name} ne '' && + $datas->{networks}->{$id}->{name} !~ /$self->{option_results}->{filter_network_name}/); - my $cache_networks = $options{custom}->get_cache_networks(); - foreach (values %$cache_networks) { - if (defined($self->{option_results}->{filter_network_name}) && $self->{option_results}->{filter_network_name} ne '' && - $_->{name} !~ /$self->{option_results}->{filter_network_name}/) { - $self->{output}->output_add(long_msg => "skipping network '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - - my $organization = $options{custom}->get_organization(network_id => $_->{id}); - if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && - $organization->{id} !~ /$self->{option_results}->{filter_organization_id}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } - if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' && - $organization->{name} !~ /$self->{option_results}->{filter_organization_name}/) { - $self->{output}->output_add(long_msg => "skipping device '" . $_->{name} . "': no matching filter.", debug => 1); - next; - } + next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' && + $datas->{networks}->{$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->{networks}->{$id}->{organizationId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/); - my $connections = $options{custom}->get_networks_connection_stats( - timespan => $timespan, - network_id => $_->{id} - ); - my $clients = $options{custom}->get_networks_clients( - timespan => $timespan, - network_id => $_->{id} - ); + my $connections = $options{custom}->get_networks_connection_stats(network_id => $id); + my $clients = $options{custom}->get_networks_clients(network_id => $id); - $self->{networks}->{ $_->{id} } = { - display => $_->{name}, + $self->{networks}->{$id} = { + display => $datas->{networks}->{$id}->{name}, assoc => defined($connections->{assoc}) ? $connections->{assoc} : 0, auth => defined($connections->{auth}) ? $connections->{auth} : 0, dhcp => defined($connections->{dhcp}) ? $connections->{dhcp} : 0, @@ -170,8 +153,8 @@ sub manage_selection { if (defined($clients)) { foreach my $client (@$clients) { - $self->{networks}->{ $_->{id} }->{traffic_in} += $client->{usage}->{recv} * 8; - $self->{networks}->{ $_->{id} }->{traffic_out} += $client->{usage}->{sent} * 8; + $self->{networks}->{$id}->{traffic_in} += $client->{usage}->{recv} * 8; + $self->{networks}->{$id}->{traffic_out} += $client->{usage}->{sent} * 8; } } } diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/plugin.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/plugin.pm index 962225d04..287c68f04 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/plugin.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/restapi/plugin.pm @@ -29,15 +29,15 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; - %{$self->{modes}} = ( + $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', + 'list-tags' => 'network::cisco::meraki::cloudcontroller::restapi::mode::listtags', 'networks' => 'network::cisco::meraki::cloudcontroller::restapi::mode::networks' - ); + }; $self->{custom_modes}->{api} = 'network::cisco::meraki::cloudcontroller::restapi::custom::api'; return $self;