85 lines
2.6 KiB
Ruby
85 lines
2.6 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Gitlab
|
||
|
module BackgroundMigration
|
||
|
# rubocop:disable Style/Documentation
|
||
|
class PopulateVulnerabilityReads
|
||
|
include Gitlab::Database::DynamicModelHelpers
|
||
|
|
||
|
PAUSE_SECONDS = 0.1
|
||
|
|
||
|
def perform(start_id, end_id, sub_batch_size)
|
||
|
vulnerability_model.where(id: start_id..end_id).each_batch(of: sub_batch_size) do |sub_batch|
|
||
|
first, last = sub_batch.pluck(Arel.sql('min(id), max(id)')).first
|
||
|
connection.execute(insert_query(first, last))
|
||
|
|
||
|
sleep PAUSE_SECONDS
|
||
|
end
|
||
|
|
||
|
mark_job_as_succeeded(start_id, end_id, sub_batch_size)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def vulnerability_model
|
||
|
define_batchable_model('vulnerabilities', connection: connection)
|
||
|
end
|
||
|
|
||
|
def connection
|
||
|
ActiveRecord::Base.connection
|
||
|
end
|
||
|
|
||
|
def insert_query(start_id, end_id)
|
||
|
<<~SQL
|
||
|
INSERT INTO vulnerability_reads (
|
||
|
vulnerability_id,
|
||
|
project_id,
|
||
|
scanner_id,
|
||
|
report_type,
|
||
|
severity,
|
||
|
state,
|
||
|
has_issues,
|
||
|
resolved_on_default_branch,
|
||
|
uuid,
|
||
|
location_image
|
||
|
)
|
||
|
SELECT
|
||
|
vulnerabilities.id,
|
||
|
vulnerabilities.project_id,
|
||
|
vulnerability_scanners.id,
|
||
|
vulnerabilities.report_type,
|
||
|
vulnerabilities.severity,
|
||
|
vulnerabilities.state,
|
||
|
CASE
|
||
|
WHEN
|
||
|
vulnerability_issue_links.vulnerability_id IS NOT NULL
|
||
|
THEN
|
||
|
true
|
||
|
ELSE
|
||
|
false
|
||
|
END
|
||
|
has_issues,
|
||
|
vulnerabilities.resolved_on_default_branch,
|
||
|
vulnerability_occurrences.uuid::uuid,
|
||
|
vulnerability_occurrences.location ->> 'image'
|
||
|
FROM
|
||
|
vulnerabilities
|
||
|
INNER JOIN vulnerability_occurrences ON vulnerability_occurrences.vulnerability_id = vulnerabilities.id
|
||
|
INNER JOIN vulnerability_scanners ON vulnerability_scanners.id = vulnerability_occurrences.scanner_id
|
||
|
LEFT JOIN vulnerability_issue_links ON vulnerability_issue_links.vulnerability_id = vulnerabilities.id
|
||
|
WHERE vulnerabilities.id BETWEEN #{start_id} AND #{end_id}
|
||
|
ON CONFLICT(vulnerability_id) DO NOTHING;
|
||
|
SQL
|
||
|
end
|
||
|
|
||
|
def mark_job_as_succeeded(*arguments)
|
||
|
Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
|
||
|
self.class.name.demodulize,
|
||
|
arguments
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
# rubocop:enable Style/Documentation
|
||
|
end
|
||
|
end
|