90 lines
2.7 KiB
Ruby
90 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module BackgroundMigration
|
|
# Populates missing dismissal information for vulnerabilities.
|
|
class PopulateVulnerabilityDismissalFields < BatchedMigrationJob
|
|
feature_category :vulnerability_management
|
|
scope_to ->(relation) { relation.where('state = 2 AND (dismissed_at IS NULL OR dismissed_by_id IS NULL)') }
|
|
operation_name :populate_vulnerability_dismissal_fields
|
|
|
|
# rubocop:disable Style/Documentation
|
|
class Vulnerability < ApplicationRecord
|
|
self.table_name = 'vulnerabilities'
|
|
|
|
has_one :finding, class_name: 'Finding'
|
|
|
|
def copy_dismissal_information
|
|
return unless finding&.dismissal_feedback
|
|
|
|
update_columns(
|
|
dismissed_at: finding.dismissal_feedback.created_at,
|
|
dismissed_by_id: finding.dismissal_feedback.author_id
|
|
)
|
|
end
|
|
end
|
|
|
|
class Finding < ApplicationRecord
|
|
self.table_name = 'vulnerability_occurrences'
|
|
|
|
validates :details, json_schema: { filename: "filename" }
|
|
|
|
def dismissal_feedback
|
|
Feedback.dismissal.where(finding_uuid: uuid).first
|
|
end
|
|
end
|
|
|
|
class Feedback < ApplicationRecord
|
|
DISMISSAL_TYPE = 0 # dismissal
|
|
|
|
self.table_name = 'vulnerability_feedback'
|
|
|
|
scope :dismissal, -> { where(feedback_type: DISMISSAL_TYPE) }
|
|
end
|
|
# rubocop:enable Style/Documentation
|
|
|
|
def perform
|
|
each_sub_batch do |sub_batch|
|
|
vulnerability_ids = sub_batch.pluck(:id)
|
|
Vulnerability.includes(:finding).where(id: vulnerability_ids).each do |vulnerability|
|
|
populate_for(vulnerability)
|
|
end
|
|
|
|
log_info(vulnerability_ids)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def populate_for(vulnerability)
|
|
log_warning(vulnerability) unless vulnerability.copy_dismissal_information
|
|
rescue StandardError => error
|
|
log_error(error, vulnerability)
|
|
end
|
|
|
|
def log_info(vulnerability_ids)
|
|
::Gitlab::BackgroundMigration::Logger.info(
|
|
migrator: self.class.name,
|
|
message: 'Dismissal information has been copied',
|
|
count: vulnerability_ids.length
|
|
)
|
|
end
|
|
|
|
def log_warning(vulnerability)
|
|
::Gitlab::BackgroundMigration::Logger.warn(
|
|
migrator: self.class.name,
|
|
message: 'Could not update vulnerability!',
|
|
vulnerability_id: vulnerability.id
|
|
)
|
|
end
|
|
|
|
def log_error(error, vulnerability)
|
|
::Gitlab::BackgroundMigration::Logger.error(
|
|
migrator: self.class.name,
|
|
message: error.message,
|
|
vulnerability_id: vulnerability.id
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|