You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cartodb/lib/tasks/user_migrator.rake

200 lines
7.6 KiB

require_relative '../../services/user-mover/export_user.rb'
require_relative '../../services/user-mover/import_user.rb'
require_relative '../../app/services/carto/organization_metadata_export_service'
require_relative '../../app/services/carto/redis_export_service'
namespace :cartodb do
namespace :user_migrator do
namespace :export do
def run_user_migrator_export_job(ume)
if ume.organization
puts "Exporting organization #{ume.organization.name}"
else
puts "Exporting user #{ume.user.username}"
end
if ume.export_metadata
puts "Including metadata (moving between clouds)"
else
puts "Without metadata (moving inside a single cloud)"
end
puts 'Control + C to cancel (will continue in 5 seconds)'
sleep 5
ume.save!
puts "Running export with id = #{ume.id}"
ume.run_export
puts "Export finished with status #{ume.state}"
if ume.state == Carto::UserMigrationExport::STATE_COMPLETE
import_params = {
org_import: ume.organization.present?,
import_metadata: ume.export_metadata,
import_data: ume.export_data?,
exported_file: ume.exported_file,
json_file: ume.json_file,
dry: false,
database_host: '<destination db host>'
}
import_params[:user_id] = ume.user_id if !ume.export_metadata && ume.user_id
import_params[:organization_id] = ume.organization_id if !ume.export_metadata && ume.organization_id
config_filename = "/tmp/import_for_#{ume.id}.json"
puts "Pass the following parameters to the import task"
puts JSON.pretty_generate(import_params)
File.write(config_filename, JSON.pretty_generate(import_params))
puts "Written to #{config_filename}"
puts "Don't forget to update the database host"
else
puts ume.log.entries
raise 'Failed Export!'
end
end
desc 'Export an organization'
task :organization, [:orgname, :metadata, :metadata_only] => :environment do |_task, args|
organization = Carto::Organization.find_by_name(args[:orgname])
raise 'Organization not found' unless organization
export_metadata = args[:metadata] == 'true'
metadata_only = args[:metadata_only] == 'true'
ume = Carto::UserMigrationExport.new(
organization: organization,
export_metadata: export_metadata,
export_data: !metadata_only
)
run_user_migrator_export_job(ume)
end
desc 'Export a user'
task :user, [:username, :metadata, :metadata_only] => :environment do |_task, args|
user = Carto::User.find_by_username(args[:username])
raise 'User not found' unless user
export_metadata = args[:metadata] == 'true'
metadata_only = args[:metadata_only] == 'true'
ume = Carto::UserMigrationExport.new(
user: user,
export_metadata: export_metadata,
export_data: !metadata_only
)
run_user_migrator_export_job(ume)
end
end
desc 'Import a user migrator dump'
task :import, [:config_file] => :environment do |_task, args|
config = JSON.parse(File.read(args[:config_file])).symbolize_keys
raise 'Set a database host' if config[:database_host].blank? || config[:database_host].include?('<')
umi = Carto::UserMigrationImport.new(config)
umi.save!
puts "Running import with id = #{umi.id}"
umi.run_import
puts "Import finished with status #{umi.state}"
puts umi.log.entries unless umi.state == Carto::UserMigrationImport::STATE_COMPLETE
end
namespace :cleanup do
module OrganizationMigrationCleanup
def clean_user_metadata(user)
return unless user.present? && user.persisted?
carto_user = Carto::User.find(user.id)
carto_user.assets.each(&:delete)
user.destroy
end
def clean_organization_metadata(organization)
return unless organization.persisted?
organization.assets.each(&:delete)
organization.users.each { |u| u.assets.each(&:delete) }
organization.destroy_cascade
end
def clean_redis_user(user)
remove_keys(
$users_metadata,
$users_metadata.keys("user:#{user.username}*")
)
remove_keys(
$tables_metadata,
["map_tpl|#{user.username}"]
)
end
def clean_redis_organization(organization)
remove_keys(
$users_metadata,
$users_metadata.keys("org:#{organization.name}*")
)
organization.users.each { |u| clean_redis_user(u) }
end
def clean_organization(organization)
puts "Cleaning organization #{organization.name}"
clean_redis_organization(organization)
clean_organization_metadata(organization)
end
def clean_user(user)
puts "Cleaning user #{user.username}"
clean_redis_user(user)
clean_user_metadata(user)
end
end
desc 'Cleans all organizations data and metadata matching filter in config file'
task :organizations_from_file, [:config_file] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
Carto::Organization.where(File.read(args[:config_file]).to_s).each { |org| clean_organization(org) }
end
desc 'Cleans all user data and metadata matching filter in config file'
task :users_from_file, [:config_file] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
User.where(File.read(args[:config_file]).to_s).each { |u| clean_user(u) }
end
desc 'Cleans all data for organization with given name'
task :organization, [:name] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
organization = Carto::Organization.where("name = '#{args[:name]}'").first ||
Carto::Organization.new(name: args[:orgname])
clean_organization(organization)
end
desc 'Cleans all data for user with given username'
task :user, [:username] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
user = User.where("username = '#{args[:username]}'").first || User.new(username: args[:username])
clean_user(user)
end
desc 'Cleans redis keys for org with given name'
task :redis_for_orgname, [:orgname] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
organization = Carto::Organization.where("name = '#{args[:orgname]}'").first ||
Carto::Organization.new(name: args[:orgname])
clean_redis_organization(organization)
end
desc 'Cleans all redis keys for given username'
task :redis_for_username, [:username] => :environment do |_, args|
include CartoDB::DataMover::Utils
include OrganizationMigrationCleanup
include ::Carto::RedisExportServiceImporter
user = User.where("username = '#{args[:username]}'").first || User.new(username: args[:username])
clean_redis_user(user)
end
end
end
end