diff --git a/vspc_backup_checks/2.3/local/lib/python3/cmk_addons/plugins/vspc_backup_checks/libexec/agent_vspc_backup_checks b/vspc_backup_checks/2.3/local/lib/python3/cmk_addons/plugins/vspc_backup_checks/libexec/agent_vspc_backup_checks index e58ccc9..d083213 100755 --- a/vspc_backup_checks/2.3/local/lib/python3/cmk_addons/plugins/vspc_backup_checks/libexec/agent_vspc_backup_checks +++ b/vspc_backup_checks/2.3/local/lib/python3/cmk_addons/plugins/vspc_backup_checks/libexec/agent_vspc_backup_checks @@ -12,6 +12,9 @@ CRIT = 2 SECONDS_PER_DAY = 24 * 60 * 60 +DAILY = "Daily" +WEEKLY = "Weekly" + # GET HTTP with Bearer auth. Returns data structure parsed from JSON. # @@ -121,7 +124,7 @@ def parse_arguments(): # ], # ... # } -def process(mAgents, bAgents, jobs, restores): +def process(mAgents, bAgents, jobs, restores, policies): mToB = {} for agent in bAgents: mToB[agent["managementAgentUid"]] = agent @@ -139,12 +142,12 @@ def process(mAgents, bAgents, jobs, restores): # for every (backup agent ID, job ID) pair. bToR = defaultdict(dict) for r in restores: - bId = r["backupAgentUid"] - jId = r["jobUid"] + bId = r["backupAgentUid"] + jId = r["jobUid"] - most_recent = bToR[bId].get(jId) - if not most_recent or most_recent["creationDate"] < r["creationDate"]: - bToR[bId][jId] = r + most_recent = bToR[bId].get(jId) + if not most_recent or most_recent["creationDate"] < r["creationDate"]: + bToR[bId][jId] = r results = defaultdict(list) for mAgent in mAgents: @@ -194,6 +197,7 @@ def process(mAgents, bAgents, jobs, restores): jobId = job["instanceUid"] last = job["lastEndTime"] sched = job["scheduleType"] + polId = job["backupPolicyUid"] daysSinceLastRun = None if last: @@ -222,12 +226,24 @@ def process(mAgents, bAgents, jobs, restores): warnDays = 0 critDays = 0 - if sched == "Daily": - # We use 1.2 & 2.2 here to give wiggle room for jobs to complete if - # they take longer than expected. - warnDays = 1.2 - critDays = 2.2 - elif sched == "Weekly": + if sched == DAILY: + policyType = policies.get(polId) + if policyType == WEEKLY: + # It may seem silly to check for WEEKLY under a DAILY section, + # but the scheduling allows for this, and we actually use this + # in prod due to backups being performed on a specific day in + # the week. + # + # We use 7.2 & 8.2 here to give wiggle room for jobs to + # complete if they take longer than expected. + warnDays = 7.2 + critDays = 8.2 + else: + # We use 1.2 & 2.2 here to give wiggle room for jobs to + # complete if they take longer than expected. + warnDays = 1.2 + critDays = 2.2 + elif sched == WEEKLY: # Ditto, but for a week warnDays = 7.2 critDays = 8.2 @@ -288,6 +304,54 @@ def process(mAgents, bAgents, jobs, restores): return results +# Alas, although VSPC's job data does specify whether a job runs "daily", it +# does not tell you which days. Veeam allows "daily" jobs to be configured to +# run on specific days of the week, which is something we use in production to +# run certain backup jobs only on a Saturday. +# +# So we need to filter through VSPC's somewhat inconsistent policy API to find +# daily settings. If a job is supposed to run on exactly one day a week, we +# treat it as weekly, otherwise daily. +# +# NB: if we ever use more than one day during the week (e.g. two), the logic in +# this plugin will need to be changed. The logic here, and in process() above, +# match what we currently do in prod, since a "better" approach will require a +# lot more code for a system we might phase out for something else. +def mergePolicies(linuxPolicies, windowsPolicies, macPolicies): + policies = {} + schedules = {} + + for policy in linuxPolicies + macPolicies: + schedule = policy["jobConfiguration"]["scheduleSettings"] + schedules[policy["instanceUid"]] = schedule + + for policy in windowsPolicies: + config = policy["jobConfiguration"] + + workstationSched = config.get("workstationModeSettings") + serverSched = config.get("serverModeSettings") + schedule = workstationSched or serverSched + if not schedule: + continue + schedule = schedule["scheduleSetting"] + schedule = schedule.get("periodicalScheduleSettings") or schedule + + schedules[policy["instanceUid"]] = schedule + + for polId, sched in schedules.items(): + dailySched = sched.get("dailyScheduleSettings") + if not dailySched: + continue + + days = dailySched.get("specificDays") + if days and len(days) == 1: + policies[polId] = WEEKLY + else: + policies[polId] = DAILY + + return policies + + def print_demo(): print(""" <<<>>> @@ -337,12 +401,18 @@ def main(argv=None): if args.demo: return print_demo() + linuxPolicies = get_paginated_json_url(args.hostname, args.port, '/api/v3/configuration/backupPolicies/linux', args.token, args.insecure) + windowsPolicies = get_paginated_json_url(args.hostname, args.port, '/api/v3/configuration/backupPolicies/windows', args.token, args.insecure) + macPolicies = get_paginated_json_url(args.hostname, args.port, '/api/v3/configuration/backupPolicies/mac', args.token, args.insecure) + mAgents = get_paginated_json_url(args.hostname, args.port, '/api/v3/infrastructure/managementAgents', args.token, args.insecure) bAgents = get_paginated_json_url(args.hostname, args.port, '/api/v3/infrastructure/backupAgents', args.token, args.insecure) jobs = get_paginated_json_url(args.hostname, args.port, '/api/v3/infrastructure/backupAgents/jobs', args.token, args.insecure) restores = get_paginated_json_url(args.hostname, args.port, '/api/v3/protectedWorkloads/computersManagedByConsole/restorePoints', args.token, args.insecure) - results = process(mAgents, bAgents, jobs, restores) + policies = mergePolicies(linuxPolicies, windowsPolicies, macPolicies) + + results = process(mAgents, bAgents, jobs, restores, policies) print_out(results) diff --git a/vspc_backup_checks/2.3/vspc_backup_checks-0.4.0.mkp b/vspc_backup_checks/2.3/vspc_backup_checks-0.4.0.mkp deleted file mode 100755 index 362eb09..0000000 Binary files a/vspc_backup_checks/2.3/vspc_backup_checks-0.4.0.mkp and /dev/null differ diff --git a/vspc_backup_checks/2.3/vspc_backup_checks-0.5.0.mkp b/vspc_backup_checks/2.3/vspc_backup_checks-0.5.0.mkp new file mode 100755 index 0000000..700bd73 Binary files /dev/null and b/vspc_backup_checks/2.3/vspc_backup_checks-0.5.0.mkp differ