From 26c4b67d2856793015ce6180b91d7286524f973e Mon Sep 17 00:00:00 2001 From: sfarouq-ext <116093375+sfarouq-ext@users.noreply.github.com> Date: Mon, 27 Jan 2025 16:05:40 +0100 Subject: [PATCH] enh(fortinet): add option last-update (licenses) (#5399) Refs: CTOR-1126 Co-authored-by: chris.mvila --- .../fortigate/restapi/mode/licenses.pm | 32 ++++++- .../fortigate/restapi/License-api.json | 92 +++++++++++++++++++ .../fortinet/fortigate/restapi/licenses.robot | 35 +++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/network/fortinet/fortigate/restapi/License-api.json create mode 100644 tests/network/fortinet/fortigate/restapi/licenses.robot diff --git a/src/network/fortinet/fortigate/restapi/mode/licenses.pm b/src/network/fortinet/fortigate/restapi/mode/licenses.pm index 54870fe7a..27d97d0b2 100644 --- a/src/network/fortinet/fortigate/restapi/mode/licenses.pm +++ b/src/network/fortinet/fortigate/restapi/mode/licenses.pm @@ -45,6 +45,18 @@ sub custom_expires_perfdata { ); } +sub custom_last_update_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => floor($self->{result_values}->{last_update_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } + ] + ); +} + sub custom_expires_threshold { my ($self, %options) = @_; @@ -95,7 +107,17 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_expires_perfdata'), closure_custom_threshold_check => $self->can('custom_expires_threshold') } + }, + { label => 'last-update', set => { + key_values => [ { name => 'last_update_seconds' }, { name => 'last_update_human' }, { name => 'name' } ], + output_template => 'last_update is %s', + output_use => 'last_update_human', + #closure_custom_perfdata => $self->can('custom_expires_perfdata'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_last_update_threshold') + } } + ]; } @@ -132,6 +154,14 @@ sub add_license { name => $options{name}, status => $options{entry}->{status} }; + + if (defined($options{entry}->{last_update})) { + $self->{licenses}->{ $options{name} }->{last_update_seconds} = time() - $options{entry}->{last_update}; + $self->{licenses}->{ $options{name} }->{last_update_human} = centreon::plugins::misc::change_seconds( + value => $self->{licenses}->{ $options{name} }->{last_update_seconds} + ); + } + if (defined($options{entry}->{expires})) { $self->{licenses}->{ $options{name} }->{expires_seconds} = $options{entry}->{expires} - time(); $self->{licenses}->{ $options{name} }->{expires_seconds} = 0 if ($self->{licenses}->{ $options{name} }->{expires_seconds} < 0); @@ -192,7 +222,7 @@ Select the time unit for the expiration thresholds. May be 's' for seconds, 'm' =item B<--warning-*> B<--critical-*> Thresholds. -Can be: 'expires'. +Can be: 'expires', 'last-update' =back diff --git a/tests/network/fortinet/fortigate/restapi/License-api.json b/tests/network/fortinet/fortigate/restapi/License-api.json new file mode 100644 index 000000000..8b3505da3 --- /dev/null +++ b/tests/network/fortinet/fortigate/restapi/License-api.json @@ -0,0 +1,92 @@ +{ + "uuid": "edae28cc-0d15-4208-9e84-a3bec3f4032f", + "lastMigration": 32, + "name": "Output api (copy)", + "endpointPrefix": "", + "latency": 0, + "port": 3001, + "hostname": "", + "folders": [], + "routes": [ + { + "uuid": "fd224d5e-66c5-49dc-a1aa-c8f0cc3db291", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "api/v2/monitor/license/status/select/", + "responses": [ + { + "uuid": "700dc720-1251-4d1d-9f18-03e4fa8ffee4", + "body": "{\n \"http_method\": \"GET\",\n \"results\": {\n \"fortiguard\": {\n \"type\": \"cloud_service_status\",\n \"supported\": true,\n \"connected\": true,\n \"has_updated\": true,\n \"update_server_usa\": false,\n \"next_scheduled_update\": 1731938460,\n \"scheduled_updates_enabled\": true,\n \"server_address\": \"xx.xx.xx.xx:443\",\n \"fortigate_wan_ip\": \"xx.xx.xx.xx\"\n },\n \"forticare\": {\n \"type\": \"cloud_service_status\",\n \"status\": \"registered\",\n \"registration_supported\": true,\n \"account\": \"support.xxxxx@xxxxx.fr\",\n \"support\": {\n \"hardware\": {\n \"status\": \"licensed\",\n \"support_level\": \"Advanced HW\",\n \"expires\": 1737244800\n },\n \"enhanced\": {\n \"status\": \"licensed\",\n \"support_level\": \"Premium\",\n \"expires\": 1737244800\n }\n },\n \"company\": \"xxxxxxxxx\",\n \"industry\": \"\"\n },\n \"forticloud\": {\n \"type\": \"cloud_service_status\",\n \"status\": \"cloud_logged_out\"\n },\n \"security_rating\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"no_license\",\n \"version\": \"0.00000\",\n \"entitlement\": \"FGSA\",\n \"last_update\": 978303600\n },\n \"antivirus\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"1.00000\",\n \"expires\": 1515888000,\n \"entitlement\": \"AVDB\",\n \"last_update\": 1523293620,\n \"last_update_attempt\": 1672054760,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\",\n \"db_status\": \"db_type_extended\",\n \"engine\": {\n \"version\": \"6.00298\",\n \"last_update\": 1709239320,\n \"last_update_attempt\": 1567573458,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\"\n }\n },\n \"mobile_malware\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"0.00000\",\n \"expires\": 1515888000,\n \"entitlement\": \"AVDB\",\n \"last_update\": 978303600,\n \"last_update_attempt\": 1672054760,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\"\n },\n \"ai_malware_detection\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"0.00000\",\n \"expires\": 1515888000,\n \"entitlement\": \"AVDB\",\n \"last_update\": 978303600\n },\n \"ips\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"6.00741\",\n \"expires\": 1515888000,\n \"entitlement\": \"NIDS\",\n \"last_update\": 1448933400,\n \"last_update_attempt\": 1567573458,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\",\n \"db_status\": \"db_type_normal\",\n \"engine\": {\n \"version\": \"7.00181\",\n \"last_update\": 1709587380,\n \"last_update_attempt\": 1567573458,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\"\n }\n },\n \"industrial_db\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"no_license\",\n \"version\": \"6.00741\",\n \"entitlement\": \"ISSS\",\n \"last_update\": 1448933400\n },\n \"appctrl\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"licensed\",\n \"version\": \"25.00592\",\n \"expires\": 1737244800,\n \"entitlement\": \"FMWR\",\n \"last_update\": 1620125365,\n \"last_update_attempt\": 1620125372,\n \"last_update_result_status\": \"update_result_no_updates\",\n \"last_update_method_status\": \"update_method_sched\"\n },\n \"internet_service_db\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"licensed\",\n \"version\": \"7.03943\",\n \"last_update\": 1731726154,\n \"last_update_attempt\": 1731934873,\n \"last_update_result_status\": \"update_result_no_updates\",\n \"last_update_method_status\": \"update_method_sched\"\n },\n \"device_os_id\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"licensed\",\n \"version\": \"1.00177\",\n \"expires\": 1737244800,\n \"entitlement\": \"FMWR\",\n \"last_update\": 1726887673,\n \"last_update_attempt\": 1731934873,\n \"last_update_result_status\": \"update_result_no_updates\",\n \"last_update_method_status\": \"update_method_sched\"\n },\n \"botnet_ip\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"licensed\",\n \"version\": \"7.03943\",\n \"last_update\": 1731726154,\n \"last_update_attempt\": 1731934873,\n \"last_update_result_status\": \"update_result_no_updates\",\n \"last_update_method_status\": \"update_method_sched\"\n },\n \"botnet_domain\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"0.00000\",\n \"expires\": 1515888000,\n \"entitlement\": \"AVDB\",\n \"last_update\": 978303600,\n \"last_update_attempt\": 1672054760,\n \"last_update_result_status\": \"update_result_not_authorized\",\n \"last_update_method_status\": \"update_method_manual\"\n },\n \"malicious_urls\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"1.00001\",\n \"expires\": 1515888000,\n \"entitlement\": \"NIDS\",\n \"last_update\": 1672054760,\n \"last_update_attempt\": 1672054760,\n \"last_update_result_status\": \"update_result_success\",\n \"last_update_method_status\": \"update_method_sched\"\n },\n \"blacklisted_certificates\": {\n \"type\": \"downloaded_fds_object\",\n \"status\": \"expired\",\n \"version\": \"0.00000\",\n \"expires\": 1516147200,\n \"entitlement\": \"FURL\",\n \"last_update\": 978303600\n },\n \"web_filtering\": {\n \"type\": \"live_fortiguard_service\",\n \"status\": \"expired\",\n \"expires\": 1516147200,\n \"entitlement\": \"FURL\",\n \"category_list_version\": 9,\n \"running\": false\n },\n \"outbreak_prevention\": {\n \"type\": \"live_fortiguard_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"ZHVO\"\n },\n \"antispam\": {\n \"type\": \"live_fortiguard_service\",\n \"status\": \"expired\",\n \"expires\": 1516147200,\n \"entitlement\": \"SPAM\"\n },\n \"sdwan_network_monitor\": {\n \"type\": \"live_fortiguard_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"SWNM\"\n },\n \"iot_detection\": {\n \"type\": \"live_fortiguard_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"IOTH\"\n },\n \"forticloud_logging\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"free_license\",\n \"used_bytes\": 0,\n \"max_bytes\": 0,\n \"log_retention_days\": 7\n },\n \"forticloud_sandbox\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"free_license\",\n \"expires\": 1515888000,\n \"entitlement\": \"AVDB\",\n \"files_uploaded_daily\": 0,\n \"max_files_daily\": 100\n },\n \"fortianalyzer_cloud\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"FAZC\"\n },\n \"fortianalyzer_cloud_premium\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"AFAC\"\n },\n \"fortimanager_cloud\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"FMGC\"\n },\n \"fortiipam_cloud\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"IPMC\"\n },\n \"fortisandbox_cloud\": {\n \"type\": \"live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"FSAC\"\n },\n \"fortiems_cloud\": {\n \"type\": \"account_level_live_cloud_service\",\n \"status\": \"expires_soon\",\n \"expires\": 1732838400,\n \"entitlement\": \"FCEM\"\n },\n \"fortimanager_cloud_alci\": {\n \"type\": \"account_level_live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"FMGC\"\n },\n \"fortisandbox_cloud_alci\": {\n \"type\": \"account_level_live_cloud_service\",\n \"status\": \"no_license\",\n \"entitlement\": \"FSAP\"\n },\n \"vdom\": {\n \"type\": \"platform\",\n \"can_upgrade\": false,\n \"used\": 2,\n \"max\": 10\n },\n \"sms\": {\n \"type\": \"other\",\n \"status\": \"unavailable\",\n \"used\": 0,\n \"max\": 100\n }\n },\n \"vdom\": \"root\",\n \"path\": \"license\",\n \"name\": \"status\",\n \"action\": \"select\",\n \"status\": \"success\",\n \"serial\": \"FG100E4Q17017027\",\n \"version\": \"v7.0.15\",\n \"build\": 632\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + } + ], + "rootChildren": [ + { + "type": "route", + "uuid": "fd224d5e-66c5-49dc-a1aa-c8f0cc3db291" + } + ], + "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": [], + "callbacks": [] +} \ No newline at end of file diff --git a/tests/network/fortinet/fortigate/restapi/licenses.robot b/tests/network/fortinet/fortigate/restapi/licenses.robot new file mode 100644 index 000000000..afb9954c1 --- /dev/null +++ b/tests/network/fortinet/fortigate/restapi/licenses.robot @@ -0,0 +1,35 @@ +*** Settings *** +Documentation Check licenses. + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + +** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}License-api.json + +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::fortinet::fortigate::restapi::plugin +... --hostname=${HOSTNAME} +... --proto='http' +... --access-token=mokoon-token +... --port=${APIPORT} + +*** Test Cases *** +licenses ${tc} + [Tags] network fortinet fortigate restapi + ${command} Catenate + ... ${CMD} + ... --mode=licenses + ... ${extra_options} + Ctn Verify Command Output ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 --warning-status='\\\%{name} eq /web_filtering/i' CRITICAL: License 'ai_malware_detection' status: expired - License 'antispam' status: expired - License 'antivirus' status: expired - License 'blacklisted_certificates' status: expired - License 'botnet_domain' status: expired - License 'ips' status: expired - License 'malicious_urls' status: expired - License 'mobile_malware' status: expired - License 'web_filtering' status: expired | 'ai_malware_detection#license.expires.seconds'=0s;;;0; 'antispam#license.expires.seconds'=0s;;;0; 'antivirus#license.expires.seconds'=0s;;;0; 'appctrl#license.expires.seconds'=0s;;;0; 'blacklisted_certificates#license.expires.seconds'=0s;;;0; 'botnet_domain#license.expires.seconds'=0s;;;0; 'device_os_id#license.expires.seconds'=0s;;;0; 'forticare:support:enhanced#license.expires.seconds'=0s;;;0; 'forticare:support:hardware#license.expires.seconds'=0s;;;0; 'forticloud_sandbox#license.expires.seconds'=0s;;;0; 'fortiems_cloud#license.expires.seconds'=0s;;;0; 'ips#license.expires.seconds'=0s;;;0; + ... 2 --critical-status='\\\%{status} =~ /unavailable/i' CRITICAL: License 'sms' status: unavailable | 'ai_malware_detection#license.expires.seconds'=0s;;;0; 'antispam#license.expires.seconds'=0s;;;0; 'antivirus#license.expires.seconds'=0s;;;0; 'appctrl#license.expires.seconds'=0s;;;0; 'blacklisted_certificates#license.expires.seconds'=0s;;;0; 'botnet_domain#license.expires.seconds'=0s;;;0; 'device_os_id#license.expires.seconds'=0s;;;0; 'forticare:support:enhanced#license.expires.seconds'=0s;;;0; 'forticare:support:hardware#license.expires.seconds'=0s;;;0; 'forticloud_sandbox#license.expires.seconds'=0s;;;0; 'fortiems_cloud#license.expires.seconds'=0s;;;0; 'ips#license.expires.seconds'=0s;;;0; 'malicious_urls#license.expires.seconds'=0s;;;0; 'mobile_malware#license.expires.seconds'=0s;;;0; 'web_filtering#license.expires.seconds'=0s;;;0; + ... 3 --filter-name='sms' OK: License 'sms' status: unavailable + ... 4 --unit='w' CRITICAL: License 'ai_malware_detection' status: expired - License 'antispam' status: expired - License 'antivirus' status: expired - License 'blacklisted_certificates' status: expired - License 'botnet_domain' status: expired - License 'ips' status: expired - License 'malicious_urls' status: expired - License 'mobile_malware' status: expired - License 'web_filtering' status: expired | 'ai_malware_detection#license.expires.weeks'=0w;;;0; 'antispam#license.expires.weeks'=0w;;;0; 'antivirus#license.expires.weeks'=0w;;;0; 'appctrl#license.expires.weeks'=0w;;;0; 'blacklisted_certificates#license.expires.weeks'=0w;;;0; 'botnet_domain#license.expires.weeks'=0w;;;0; 'device_os_id#license.expires.weeks'=0w;;;0; 'forticare:support:enhanced#license.expires.weeks'=0w;;;0; 'forticare:support:hardware#license.expires.weeks'=0w;;;0; 'forticloud_sandbox#license.expires.weeks'=0w;;;0; 'fortiems_cloud#license.expires.weeks'=0w;;;0; 'ips#license.expires.weeks'=0w;;;0; 'malicious_urls#license.expires.weeks'=0w;;;0; 'mobile_malware#license.expires.weeks'=0w;;;0; 'web_filtering#license.expires.weeks'=0w;;;0; + ... 5 --critical-status='' --warning-expires=0 --critical-expires=20 OK: All licenses are ok | 'ai_malware_detection#license.expires.seconds'=0s;0:0;0:20;0; 'antispam#license.expires.seconds'=0s;0:0;0:20;0; 'antivirus#license.expires.seconds'=0s;0:0;0:20;0; 'appctrl#license.expires.seconds'=0s;0:0;0:20;0; 'blacklisted_certificates#license.expires.seconds'=0s;0:0;0:20;0; 'botnet_domain#license.expires.seconds'=0s;0:0;0:20;0; 'device_os_id#license.expires.seconds'=0s;0:0;0:20;0; 'forticare:support:enhanced#license.expires.seconds'=0s;0:0;0:20;0; 'forticare:support:hardware#license.expires.seconds'=0s;0:0;0:20;0; 'forticloud_sandbox#license.expires.seconds'=0s;0:0;0:20;0; 'fortiems_cloud#license.expires.seconds'=0s;0:0;0:20;0; 'ips#license.expires.seconds'=0s;0:0;0:20;0; 'malicious_urls#license.expires.seconds'=0s;0:0;0:20;0; 'mobile_malware#license.expires.seconds'=0s;0:0;0:20;0; 'web_filtering#license.expires.seconds'=0s;0:0;0:20;0; + ... 6 --warning-status='' --warning-last-update=0 --critical-last-update=100 --filter-name='forticloud_sandbox' OK: License 'forticloud_sandbox' status: free_license, expires in 0 | 'forticloud_sandbox#license.expires.seconds'=0s;;;0; \ No newline at end of file