93 lines
2.4 KiB
Ruby
93 lines
2.4 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
class GenerateMissingRoutesForBots < ActiveRecord::Migration[6.0]
|
||
|
DOWNTIME = false
|
||
|
|
||
|
disable_ddl_transaction!
|
||
|
|
||
|
class User < ActiveRecord::Base
|
||
|
self.table_name = 'users'
|
||
|
|
||
|
USER_TYPES = {
|
||
|
human: nil,
|
||
|
support_bot: 1,
|
||
|
alert_bot: 2,
|
||
|
visual_review_bot: 3,
|
||
|
service_user: 4,
|
||
|
ghost: 5,
|
||
|
project_bot: 6,
|
||
|
migration_bot: 7
|
||
|
}.with_indifferent_access.freeze
|
||
|
|
||
|
BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot].freeze
|
||
|
|
||
|
scope :bots, -> { where(user_type: USER_TYPES.values_at(*BOT_USER_TYPES)) }
|
||
|
end
|
||
|
|
||
|
class Route < ActiveRecord::Base
|
||
|
self.table_name = 'routes'
|
||
|
|
||
|
validates :path,
|
||
|
uniqueness: { case_sensitive: false }
|
||
|
end
|
||
|
|
||
|
class Namespace < ActiveRecord::Base
|
||
|
self.table_name = 'namespaces'
|
||
|
|
||
|
belongs_to :owner, class_name: 'GenerateMissingRoutesForBots::User'
|
||
|
|
||
|
scope :for_user, -> { where('type IS NULL') }
|
||
|
scope :for_bots, -> { for_user.joins(:owner).merge(GenerateMissingRoutesForBots::User.bots) }
|
||
|
|
||
|
scope :without_routes, -> do
|
||
|
where(
|
||
|
'NOT EXISTS (
|
||
|
SELECT 1
|
||
|
FROM routes
|
||
|
WHERE source_type = ?
|
||
|
AND source_id = namespaces.id
|
||
|
)',
|
||
|
self.source_type_for_route
|
||
|
)
|
||
|
end
|
||
|
|
||
|
def self.source_type_for_route
|
||
|
'Namespace'
|
||
|
end
|
||
|
|
||
|
def attributes_for_insert
|
||
|
{
|
||
|
source_type: self.class.source_type_for_route,
|
||
|
source_id: id,
|
||
|
name: name,
|
||
|
path: path
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def up
|
||
|
# Reset the column information of all the models that update the database
|
||
|
# to ensure the Active Record's knowledge of the table structure is current
|
||
|
Route.reset_column_information
|
||
|
|
||
|
logger = Gitlab::BackgroundMigration::Logger.build
|
||
|
attributes_to_be_logged = %w(id path name)
|
||
|
|
||
|
GenerateMissingRoutesForBots::Namespace.for_bots.without_routes.each do |namespace|
|
||
|
route = GenerateMissingRoutesForBots::Route.create(namespace.attributes_for_insert)
|
||
|
namespace_details = namespace.as_json.slice(*attributes_to_be_logged)
|
||
|
|
||
|
if route.persisted?
|
||
|
logger.info namespace_details.merge(message: 'a new route was created for the namespace')
|
||
|
else
|
||
|
errors = route.errors.full_messages.join(',')
|
||
|
logger.info namespace_details.merge(message: 'route creation failed for the namespace', errors: errors)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def down
|
||
|
# no op
|
||
|
end
|
||
|
end
|