-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathparse_report_job.rb
118 lines (97 loc) · 3.19 KB
/
parse_report_job.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# frozen_string_literal: true
# Saves all of the information we can parse from a Xccdf report into db
class ParseReportJob
include Sidekiq::Worker
include Notifications
# https://github.com/yabeda-rb/yabeda-sidekiq#custom-tags
def yabeda_tags(_idx, message, *_args)
{ qe: OpenshiftEnvironment.qe_account?(message['org_id']) }
end
def perform(idx, message)
return if cancelled?
@msg_value = message
Sidekiq.logger.info(
"Parsing report for account #{@msg_value['org_id']}, " \
"system #{@msg_value['id']}"
)
@file = retrieve_file(idx)
parse_and_save_report
end
def cancelled?
Sidekiq.redis { |c| c.exists?("cancelled-#{jid}") }
end
def self.cancel!(jid)
Sidekiq.redis { |c| c.setex("cancelled-#{jid}", 86_400, 1) }
end
private
def retrieve_file(idx)
@file = SafeDownloader.download_reports(
@msg_value['url'],
ssl_only: Settings.report_download_ssl_only
)[idx]
rescue SafeDownloader::DownloadError => e
handle_error(e)
end
def parse_and_save_report
notify_payload_tracker(:processing, "Job #{jid} is now processing")
compliance_notification_wrapper { parser.save_all }
notify_remediation
audit_success
notify_payload_tracker(:success, "Job #{jid} has completed successfully")
rescue *XccdfReportParser::ERRORS => e
handle_error(e)
end
def parser
@parser ||= XccdfReportParser.new(@file, @msg_value)
end
def handle_error(exc)
msg = error_message(exc)
msg_with_values = "#{msg} \n #{JSON.pretty_generate(@msg_value)}"
notify_payload_tracker(:error, msg_with_values)
ReportUploadFailed.deliver(host: Host.find_by(id: @msg_value['id'], account: @msg_value['account']),
request_id: @msg_value['request_id'], error: notification_message(exc),
org_id: @msg_value['org_id'])
Sidekiq.logger.error(msg_with_values)
Rails.logger.audit_fail("[#{@msg_value['org_id']}] #{msg}")
end
def error_message(exc)
"#{error_msg_base}: #{exc.class}: #{exc.message}"
end
def notification_message(exc)
"#{error_msg_base}: #{exc.class.to_s.demodulize}"
end
def error_msg_base
msg = "Failed to parse report #{report_profile_id}"
msg += " from host #{@msg_value['id']}" if @msg_value['id'].present?
msg
end
def report_profile_id
@parser&.test_result_file&.test_result&.profile_id
end
def notify_payload_tracker(status, status_msg = '')
PayloadTracker.deliver(
account: @msg_value['account'], system_id: @msg_value['id'],
request_id: @msg_value['request_id'], status: status,
status_msg: status_msg, org_id: @msg_value['org_id']
)
end
def notify_remediation
RemediationUpdates.deliver(
host_id: @msg_value['id'],
issue_ids: remediation_issue_ids
)
end
def remediation_issue_ids
parser.failed_rules
.includes(profiles: :benchmark)
.collect(&:remediation_issue_id)
.compact
end
def audit_success
Rails.logger.audit_success(
"[#{@msg_value['org_id']}] Successful report of #{report_profile_id} " \
"policy #{parser.host_profile.policy_id} " \
"from host #{@msg_value['id']}"
)
end
end