Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CTOR-775] - Fix apps::backup::rubrik::restapi::mode::jobs long output #5171

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"dependencies": [
"libdatetime-perl",
"libdigest-md5-perl",
"libjson-perl"
]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"dependencies": [
"perl(DateTime)",
"perl(Digest::MD5)",
"perl(JSON::XS)"
]
}
36 changes: 29 additions & 7 deletions src/apps/backup/rubrik/restapi/mode/jobs.pm
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ sub new {
'filter-location-name:s' => { name => 'filter_location_name' },
'filter-object-type:s' => { name => 'filter_object_type' },
'unit:s' => { name => 'unit', default => 's' },
'limit:s' => { name => 'limit' }
'limit:s' => { name => 'limit' },
'check-retention' => { name => 'check_retention' }
});

$self->{cache_exec} = centreon::plugins::statefile->new(%options);
Expand All @@ -247,7 +248,11 @@ sub check_options {
sub manage_selection {
my ($self, %options) = @_;

my $jobs_exec = $options{custom}->get_jobs_monitoring(get_param => [ 'limit=' . $self->{option_results}->{limit} ]);
my $get_param = [ 'limit=' . $self->{option_results}->{limit} ];
if (defined($self->{option_results}->{filter_job_type}) && $self->{option_results}->{filter_job_type} ne '') {
push @{$get_param}, 'job_type=' . $self->{option_results}->{filter_job_type};
}
my $jobs_exec = $options{custom}->get_jobs_monitoring(get_param => $get_param);

$self->{cache_exec}->read(statefile => 'rubrik_' . $self->{mode} . '_' .
Digest::MD5::md5_hex(
Expand All @@ -260,7 +265,8 @@ sub manage_selection {
);
my $ctime = time();
my $last_exec_times = $self->{cache_exec}->get(name => 'jobs');
$last_exec_times = {} if (!defined($last_exec_times));
$last_exec_times = {} if (!defined($last_exec_times));
my %jobs_detected = ();

$self->{global} = { detected => 0 };
$self->{jobs} = {};
Expand All @@ -269,13 +275,13 @@ sub manage_selection {
$job_exec->{objectId} !~ /$self->{option_results}->{filter_job_id}/);
next if (defined($self->{option_results}->{filter_job_name}) && $self->{option_results}->{filter_job_name} ne '' &&
$job_exec->{objectName} !~ /$self->{option_results}->{filter_job_name}/);
next if (defined($self->{option_results}->{filter_job_type}) && $self->{option_results}->{filter_job_type} ne '' &&
$job_exec->{jobType} !~ /$self->{option_results}->{filter_job_type}/i);
next if (defined($self->{option_results}->{filter_object_type}) && $self->{option_results}->{filter_object_type} ne '' &&
$job_exec->{objectType} !~ /$self->{option_results}->{filter_object_type}/i);
next if (defined($self->{option_results}->{filter_location_name}) && $self->{option_results}->{filter_location_name} ne '' &&
$job_exec->{locationName} !~ /$self->{option_results}->{filter_location_name}/);

$self->{global}->{detected}++;
$jobs_detected{$job_exec->{objectName}} = 1;
$job_exec->{jobType} = lc($job_exec->{jobType});

if (!defined($self->{jobs}->{ $job_exec->{objectId} })) {
Expand All @@ -302,7 +308,6 @@ sub manage_selection {
$last_exec = $_;
}

$self->{global}->{detected}++;
# Failure, Scheduled, Success, SuccessfulWithWarnings, Active, Canceled
$failed++ if ($_->{jobStatus} =~ /Failure/i);
$total++;
Expand All @@ -326,7 +331,9 @@ sub manage_selection {
$last_exec_times->{ $job_exec->{objectId} } = {
jobName => $job_exec->{objectName},
jobType => $job_exec->{jobType},
epoch => $dt->epoch()
epoch => $dt->epoch(),
objectType => $job_exec->{objectType},
locationName => $job_exec->{locationName}
};
}

Expand Down Expand Up @@ -355,6 +362,8 @@ sub manage_selection {
$self->{jobs}->{$objectId} = {
name => $last_exec_times->{$objectId}->{jobName},
jobType => $last_exec_times->{$objectId}->{jobType},
objectType => $last_exec_times->{$objectId}->{objectType},
locationName => $last_exec_times->{$objectId}->{locationName},
timers => {
jobName => $last_exec_times->{$objectId}->{jobName},
jobType => $last_exec_times->{$objectId}->{jobType},
Expand All @@ -364,6 +373,15 @@ sub manage_selection {
};
}

if ($self->{global}->{detected} == 0 && defined($self->{option_results}->{check_retention})) {
my $jobs_last_detected = $self->{cache_exec}->get(name => 'jobs');
foreach my $job_id (keys %{$jobs_last_detected}) {
if (!defined($jobs_detected{$jobs_last_detected->{$job_id}->{jobName}})) {
$self->{global}->{detected}++;
}
}
}

$self->{cache_exec}->write(data => {
jobs => $last_exec_times
});
Expand Down Expand Up @@ -407,6 +425,10 @@ Select the time unit for last execution time thresholds. May be 's' for seconds,

Define the number of entries to retrieve for the pagination (default: 500).

=item B<--check-retention>

Use the retention file to check if a job have been detected once but does not appear in the API response.

=item B<--unknown-execution-status>

Set unknown threshold for last job execution status.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"uuid": "c8fba1bd-af32-4acd-83a2-5b26a0152183",
"lastMigration": 32,
"name": "Rubrik2",
"endpointPrefix": "api/v1",
"latency": 0,
"port": 3000,
"hostname": "",
"folders": [],
"routes": [
{
"uuid": "b9fdb329-671b-48d0-a906-d58e45a70527",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "job_monitoring",
"responses": [
{
"uuid": "4aac7b2c-2947-4e6b-83a4-094da73ecc5a",
"body": "{\r\n \"jobMonitoringInfoList\": [\r\n {\r\n \"jobMonitoringState\": \"Success\",\r\n \"jobStatus\": \"Success\",\r\n \"jobType\": \"Backup\",\r\n \"objectId\": \"VolumeGroup:::123a456-123a-456b-789c-123456789\",\r\n \"objectType\": \"WindowsVolumeGroup\",\r\n \"objectName\": \"centreon.groupe.active volumes\",\r\n \"locationId\": \"Host:::123c456-a123-b456-c789-123a456\",\r\n \"locationName\": \"centreon.groupe.active\",\r\n \"slaDomainId\": \"1234a456-123a-456b-aaaa-12345\",\r\n \"slaDomainName\": \"CENTREON-DOMAIN\",\r\n \"startTime\": \"2024-07-18T20:00:01.382Z\",\r\n \"endTime\": \"2024-07-19T06:42:16.355Z\",\r\n \"lastSuccessfulJobTime\": \"2024-07-16T20:00:01.382Z\",\r\n \"nextJobTime\": \"2023-11-07T20:00:00.000Z\",\r\n \"isFirstFullSnapshot\": false,\r\n \"sourceClusterName\": \"LOCAL\",\r\n \"sourceClusterId\": \"aaaaaa-123a-456b-aaaa-12345\",\r\n \"retryCount\": 0,\r\n \"maximumAttemptsForJob\": 3,\r\n \"dataTransferred\": 571231961088,\r\n \"objectLogicalSize\": 193955119497216,\r\n \"eventSeriesId\": \"Zaaaaaa-123a-456b-123a-12345abcd\",\r\n \"duration\": 38534973,\r\n \"nodeId\": \"AAAABBBBCCCCDDD\",\r\n \"warningCount\": 0,\r\n \"lastUpdatedTime\": \"2024-07-19T06:42:16.721Z\",\r\n \"isLogTask\": false,\r\n \"isOnDemand\": false,\r\n \"retryStatus\": \"NotRetried\"\r\n },\r\n {\r\n \"jobMonitoringState\": \"Scheduled\",\r\n \"jobStatus\": \"Scheduled\",\r\n \"jobType\": \"Backup\",\r\n \"objectId\": \"VolumeGroup:::123a456-123a-456b-789c-123456789\",\r\n \"objectType\": \"WindowsVolumeGroup\",\r\n \"objectName\": \"centreon.groupe.active volumes\",\r\n \"locationId\": \"Host:::123c456-a123-b456-c789-123a456\",\r\n \"locationName\": \"centreon.groupe.active\",\r\n \"slaDomainId\": \"1234a456-123a-456b-aaaa-12345\",\r\n \"slaDomainName\": \"CENTREON-DOMAIN\",\r\n \"startTime\": \"2024-07-18T20:00:00.000Z\",\r\n \"lastSuccessfulJobTime\": \"2024-07-18T20:00:01.382Z\",\r\n \"isFirstFullSnapshot\": false,\r\n \"sourceClusterName\": \"LOCAL\",\r\n \"sourceClusterId\": \"aaaaaa-123a-456b-aaaa-12345\",\r\n \"retryCount\": 0,\r\n \"maximumAttemptsForJob\": 3,\r\n \"objectLogicalSize\": 193955119497216,\r\n \"eventSeriesId\": \"afba57d8-efb3-452e-892b-157acc6b6069\",\r\n \"nodeId\": \"AAAABBBBCCCCDDD\",\r\n \"warningCount\": 0,\r\n \"lastUpdatedTime\": \"2024-07-18T06:42:16.894Z\",\r\n \"isLogTask\": false,\r\n \"isOnDemand\": false,\r\n \"retryStatus\": \"NotRetried\"\r\n }\r\n ],\r\n \"jobType\": \"Backup\",\r\n \"shouldIncludeLogRelatedJob\": false,\r\n \"objectName\": \"CENTREON\",\r\n \"hasMore\": false\r\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
}
],
"rootChildren": [
{
"type": "route",
"uuid": "b9fdb329-671b-48d0-a906-d58e45a70527"
}
],
"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": []
}
39 changes: 39 additions & 0 deletions tests/apps/backup/rubrik/restapi/cache.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
*** Settings ***
Documentation Check Rubrik REST API jobs cache file creation

Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource

Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s


*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}applications-rubrik-restapi.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::backup::rubrik::restapi::plugin
... --hostname=${HOSTNAME}
... --api-username='username'
... --api-password='password'
... --proto='http'
... --port=${APIPORT}


*** Test Cases ***
cache ${tc}/1
[Tags] apps backup rubrik restapi cache

${command} Catenate
... ${cmd}
... --mode=cache

${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... \nWrong output result for command:\n${command}\n\nExpected:\n${expected_result}\nCommand output:\n${output}\n

Examples: tc extra_options expected_result --
... 1 ${EMPTY} OK: Cache files created successfully

47 changes: 47 additions & 0 deletions tests/apps/backup/rubrik/restapi/jobs.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
*** Settings ***
Documentation Check Rubrik REST API jobs

Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource

Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s


*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}applications-rubrik-restapi.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::backup::rubrik::restapi::plugin
... --hostname=${HOSTNAME}
... --api-username='username'
... --api-password='password'
... --proto='http'
... --port=${APIPORT}

*** Test Cases ***
jobs ${tc}/11
[Tags] apps backup rubrik restapi jobs

${command} Catenate
... ${cmd}
... --mode=jobs
... ${extraoptions}

Log ${command}

${output} Run ${command}

Should Match Regexp ${output} ${expected_result}

Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % - last execution .* - last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*s;;;0;
... 2 --unknown-execution-status='\\%\{status\} eq "Success"' UNKNOWN: job 'centreon.groupe.active volumes' \[type: backup\] last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*s;;;0;
... 3 --warning-execution-status='\\%\{status\} eq "Success"' WARNING: job 'centreon.groupe.active volumes' \[type: backup\] last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*s;;;0;
... 4 --critical-execution-status='\\%\{status\} eq "Success"' CRITICAL: job 'centreon.groupe.active volumes' \[type: backup\] last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*s;;;0;
... 5 --warning-jobs-executions-detected=1 --critical-jobs-executions-detected=3 WARNING: Number of jobs executions detected: 2 \| 'jobs.executions.detected.count'=2;0:2;0:5;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;;;0;
... 6 --warning-jobs-executions-detected=1 --critical-jobs-executions-detected=1 CRITICAL: Number of jobs executions detected: 2 \| 'jobs.executions.detected.count'=2;0:2;0:3;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;;;0;
... 7 --warning-job-executions-failed-prct=1:1 --critical-job-executions-failed-prct=1 WARNING: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;1:1;0:1;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;;;0;
... 8 --warning-job-executions-failed-prct=1 --critical-job-executions-failed-prct=1:1 CRITICAL: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;0:1;1:1;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;;;0;
... 9 --warning-job-execution-last=315360000 --critical-job-execution-last=315360000 OK: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % - last execution .* - last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;0:315360000;0:315360000;0;
... 10 --warning-job-execution-last=1 --critical-job-execution-last=315360000 WARNING: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % - last execution .* - last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;0:1;0:315360000;0;
... 11 --warning-job-execution-last=315360000 --critical-job-execution-last=315360000 CRITICAL: job 'centreon.groupe.active volumes' \[type: backup\] number of failed executions: 0.00 % - last execution .* - last execution started: 2024-07-18T20:00:01.382Z status: Success \| 'jobs.executions.detected.count'=2;;;0; 'centreon.groupe.active volumes~backup#job.executions.failed.percentage'=0.00%;;;0;100 'centreon.groupe.active volumes~backup#job.execution.last.seconds'=.*;0:315360000;0:315360000;0;
Loading