gitlab-org--gitlab-foss/lib/gitlab/import_export/group/legacy_tree_restorer.rb

133 lines
4.0 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module ImportExport
module Group
class LegacyTreeRestorer
include Gitlab::Utils::StrongMemoize
attr_reader :user
attr_reader :shared
attr_reader :group
def initialize(user:, shared:, group:, group_hash:)
@user = user
@shared = shared
@group = group
@group_hash = group_hash
end
def restore
@group_attributes = relation_reader.consume_attributes(nil)
@group_members = relation_reader.consume_relation(nil, 'members')
.map(&:first)
# We need to remove `name` and `path` as we did consume it in previous pass
@group_attributes.delete('name')
@group_attributes.delete('path')
@children = @group_attributes.delete('children')
if members_mapper.map && restorer.restore
@children&.each do |group_hash|
group = create_group(group_hash: group_hash, parent_group: @group)
shared = Gitlab::ImportExport::Shared.new(group)
self.class.new(
user: @user,
shared: shared,
group: group,
group_hash: group_hash
).restore
end
end
return false if @shared.errors.any?
true
rescue StandardError => e
@shared.error(e)
false
end
private
def relation_reader
strong_memoize(:relation_reader) do
if @group_hash.present?
ImportExport::Json::LegacyReader::Hash.new(
@group_hash,
relation_names: reader.group_relation_names)
else
ImportExport::Json::LegacyReader::File.new(
File.join(shared.export_path, 'group.json'),
relation_names: reader.group_relation_names)
end
end
end
def restorer
@relation_tree_restorer ||= RelationTreeRestorer.new(
user: @user,
shared: @shared,
relation_reader: relation_reader,
members_mapper: members_mapper,
object_builder: object_builder,
relation_factory: relation_factory,
reader: reader,
importable: @group,
importable_attributes: @group_attributes,
importable_path: nil
)
end
def create_group(group_hash:, parent_group:)
group_params = {
name: group_hash['name'],
path: group_hash['path'],
parent_id: parent_group&.id,
visibility_level: sub_group_visibility_level(group_hash, parent_group)
}
::Groups::CreateService.new(@user, group_params).execute
end
def sub_group_visibility_level(group_hash, parent_group)
original_visibility_level = group_hash['visibility_level'] || Gitlab::VisibilityLevel::PRIVATE
if parent_group && parent_group.visibility_level < original_visibility_level
Gitlab::VisibilityLevel.closest_allowed_level(parent_group.visibility_level)
else
original_visibility_level
end
end
def members_mapper
@members_mapper ||= Gitlab::ImportExport::MembersMapper.new(
exported_members: @group_members,
user: @user,
importable: @group
)
end
def relation_factory
Gitlab::ImportExport::Group::RelationFactory
end
def object_builder
Gitlab::ImportExport::Group::ObjectBuilder
end
def reader
@reader ||= Gitlab::ImportExport::Reader.new(
shared: @shared,
config: Gitlab::ImportExport::Config.new(
config: Gitlab::ImportExport.legacy_group_config_file
).to_h
)
end
end
end
end
end