debian-mirror-gitlab/lib/gitlab/background_migration/populate_vulnerability_dismissal_fields.rb
2023-07-09 08:55:56 +05:30

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