[rt-devel] Failure report : RT 2.0.60 / Data migration
Jesse Vincent
jesse at bestpractical.com
Tue Jan 21 16:52:43 EST 2003
Attached is a new 2to3 tool. It sucessfully imports the ACL you were
having trouble with. Send me the next error ;)
--
»|« http://www.bestpractical.com/rt -- Trouble Ticketing. Free.
-------------- next part --------------
#!/usr/bin/perl -w
package RT;
use strict;
use Data::Dumper;
BEGIN {$RT::DontCacheSearchBuilderRecords = 1;}
use vars qw($dbh $debug);
$debug = 0;
my $import_users = 1;
my $import_groups = 1;
my $import_tickets = 1;
use lib ( "/opt/rt3/lib", "" );
use Getopt::Long;
use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
use RT::Tickets;
use RT::Template;
use RT::CustomFields;
use RT::Principals;
#*RT::Principal::HasRight = sub { 1 };;
#Clean out all the nasties from the environment
CleanEnv();
# Load the config file
RT::LoadConfig();
#Connect to the database and get RT::SystemUser and RT::Nobody loaded
RT::Init();
require shift @ARGV;
my $VAR1 = Data();
my $user_map;
my $group_map;
my $queue_map;
my $cf_map;
my @errors;
foreach my $scrip (@{$VAR1->{'Global'}->{'Scrip'}}) {
my $so = RT::Scrip->new($RT::SystemUser);
my $t = $scrip->{'Template'} || undef;
my $c = $scrip->{'Condition'} || undef;
my $a = $scrip->{'Action'} || undef;
$t =~ s/(.)([A-Z])/$1 $2/g;
$c =~ s/(.)([A-Z])/$1 $2/g;
$a =~ s/(.)([A-Z])/$1 $2/g;
$a =~ s/Admin Watchers/AdminCcs/;
my %params =
(Template => $t ,
ScripAction => $a,
ScripCondition => $c,
Description => "Imported from RT 2.0");
$so->Create(%params);
unless ($so->Id) {
push @errors, "Could not create scrip: ".Dumper($scrip);
}
}
if ($import_users) {
my $users = $VAR1->{'User'};
$RT::Handle->SimpleQuery("DELETE FROM Users where Name='root'");
foreach my $user ( @{$users} ) {
if ($user->{'Name'} eq 'Nobody') {
$user_map->{$user->{'id'}} = $RT::Nobody->Id;
next;
}
if ($user->{'Name'} eq 'RT_System') {
$user_map->{$user->{'id'}} = $RT::SystemUser->Id;
next;
}
# import user
my $user_obj = RT::User->new($RT::SystemUser);
delete $user->{'Disabled'};
my $old_id = $user->{'id'};
delete $user->{'id'};
$user->{'CryptedPassword'} = $user->{'Password'} unless ($user->{'Password'} =~ '^\*');
delete $user->{'Password'};
print "Creating $old_id - " . $user->{'Name'} . "\n";
$user_obj->Create( %{ $user } );
my $id = $user_obj->Id();
die "Failed to create user for" . Dumper $user unless ($id);
$user_map->{$old_id} = $id;
}
}
# find all groups
if ($import_groups) {
my $groups = $VAR1->{'Group'};
# foreach group
foreach my $group ( @{$groups} ) {
# create group
my $g = RT::Group->new($RT::SystemUser);
my $old_id = $group->{'id'};
delete $group->{'id'};
my $members = $group->{'Member'};
delete $group->{'Member'};
$g->CreateUserDefinedGroup( %{$group} );
my $id = $g->Id();
die "Failed to create group for" . Dumper $groups->{$group} unless ($id);
$group_map->{$old_id} = $id;
# import members
foreach my $member ( @{$members} ) {
print "Adding $member to ".$g->Id."\n";
$g->AddMember( $user_map->{ $member} );
}
}
}
#print scalar Dumper $groups;
#
#
# for global
#
# import custom fields
#
# import templates
#
# import acls
foreach my $right ( @{ $VAR1->{'Global'}->{'Right'} } ) {
my $princ = RT::Principal->new($RT::SystemUser);
my $id;
if ( $right->{'PrincipalId'} ) {
if ( $right->{'PrincipalType'} eq 'User' ) {
$id = $user_map->{ $right->{'PrincipalId'} };
}
else {
$id = $group_map->{ $right->{'PrincipalId'} };
}
$princ->Load($id);
}
elsif ( $right->{'Role'} ) {
my $g = RT::Group->new($RT::SystemUser);
$g->LoadSystemInternalGroup( $right->{'Role'} );
$id = $g->Id;
$princ = $g->PrincipalObj;
}
$princ->Id || die "Couldn't load principal $id to grant them " . $right->{'Name'} . " globally\n" . Dumper($right);
$princ->GrantRight( Object => $RT::System,
Right => $right->{'Name'} );
}
foreach my $cf (@{$VAR1->{'Global'}->{'CustomField'}}) {
my $type;
my $cfobj = RT::CustomField->new($RT::SystemUser);
if ($cf->{'Single'}) {
$type = 'SelectSingle';
} else {
$type = 'SelectMultiple';
}
$cfobj->Create (Name => $cf->{'Name'}, Type => $type, Queue => '0');
unless ($cfobj->Id) {
die "Couldn't create custom field ".$cf->{'Name'};
}
$cf_map->{$cf->{'id'}} = $cfobj->Id;
foreach my $val (@{$cf->{'Value'}}) {
$cfobj->AddValue(Name => $val);
}
}
# find all queues in RT 2.0
#
# for each queue
$RT::Handle->SimpleQuery("DELETE FROM Queues where id = 1");
my $queues = $VAR1->{'Queue'};
foreach my $queue ( @{$queues} ) {
my %temp;
foreach my $attr qw(id CustomField Watchers Scrip Right) {
$temp{$attr} = $queue->{$attr};
delete $queue->{$attr};
}
my $queue_obj = RT::Queue->new($RT::SystemUser);
$queue_obj->Create( %{ $queue } );
my $id = $queue_obj->Id();
die "Failed to create queue for" . Dumper $queue unless ($id);
$queue_map->{$temp{'id'}} = $id;
foreach my $watcher (@{$temp{Watchers}}) {
$queue_obj->AddWatcher($watcher);
}
foreach my $right ( @{ $temp{'Right'} } ) {
my $princ = RT::Principal->new($RT::SystemUser);
my $id;
if ( $right->{'PrincipalId'} ) {
if ( $right->{'PrincipalType'} eq 'User' ) {
$id = $user_map->{ $right->{'PrincipalId'} };
}
else {
$id = $group_map->{ $right->{'PrincipalId'} };
}
$princ->Load($id);
}
elsif ( $right->{'Role'} ) {
my $g = RT::Group->new($RT::SystemUser);
$g->LoadQueueGroup( Type => $right->{'Role'},
Queue => $queue_obj->Id );
unless ( $g->Id ) {
$g->LoadSystemInternalGroup( $right->{'Role'} );
}
$id = $g->Id;
$princ = $g->PrincipalObj;
}
$princ->Load($id);
$princ->Id || die "Couldn't load principal $id to grant them " . $right->{'Name'} . " on queue " . $queue_obj->Name . "\n" . Dumper($right);
$princ->GrantRight( Object => $queue_obj,
Right => $right->{'Name'} );
}
foreach my $cf (@{$temp{'CustomField'}}) {
my $type;
my $cfobj = RT::CustomField->new($RT::SystemUser);
if ($cf->{'Single'}) {
$type = 'SelectSingle';
} else {
$type = 'SelectMultiple';
}
$cfobj->Create (Name => $cf->{'Name'}, Type => $type, Queue => $queue_obj->Id);
unless ($cfobj->Id) {
die "Couldn't create custom field ".$cf->{'Name'};
}
$cf_map->{$cf->{'id'}} = $cfobj->Id;
foreach my $val (@{$cf->{'Value'}}) {
$cfobj->AddValue(Name => $val);
}
}
foreach my $scrip (@{$temp{'Scrip'}}) {
$scrip->{'Template'} =~ s/(.)([A-Z])/$1 $2/g;
$scrip->{'Condition'} =~ s/(.)([A-Z])/$1 $2/g;
$scrip->{'Action'} =~ s/(.)([A-Z])/$1 $2/g;
$scrip->{'Action'} =~ s/Admin Watchers/AdminCcs/;
my $so = RT::Scrip->new($RT::SystemUser);
$so->Create(Template => $scrip->{'Template'},
ScripAction => $scrip->{'Action'},
ScripCondition => $scrip->{'Condition'},
Description => "Imported from RT 2.0",
Queue => $queue_obj->Id );
unless ($so->Id) {
push @errors, "Could not create scrip: ".Dumper($scrip);
}
}
}
#
# import watchers
#
# import templates
#
# import acls
#
# import scrips
#
#Find all links
#
# for each ticke
if ($import_tickets) {
foreach my $ticket ( @{$VAR1->{'Ticket'}}) {
my %temp;
print "Importing ticket ".$ticket->{'id'} ."\n";
my $tick_object = RT::Ticket->new($RT::SystemUser);
$ticket->{'Status'} = 'deleted' if ( $ticket->{'Status'} eq 'dead' );
$ticket->{'Queue'} = $queue_map->{ $ticket->{'Queue'} };
$ticket->{'Owner'} = $user_map->{ $ticket->{'Owner'} };
$ticket->{'Creator'} = $user_map->{ $ticket->{'Creator'} };
$ticket->{'LastUpdatedBy'} = $user_map->{ $ticket->{'LastUpdatedBy'} };
$ticket->{'_RecordTransaction'} = 0;
foreach my $attr qw(Watchers Transaction CustomFields) {
$temp{$attr} = $ticket->{$attr};
delete $ticket->{$attr};
}
foreach my $watcher ( @{$temp{'Watchers'}} ) {
my $val;
$val = $watcher->{'Email'};
push ( @{ $ticket->{ $watcher->{'Type'} }}, $val );
}
foreach my $cf (keys %{$temp{'CustomFields'}}) {
my $cfid = $cf_map->{$cf};
$ticket->{'CustomField-'.$cfid} = $temp{'CustomFields'}->{$cf};
}
$tick_object->Create( %{$ticket} );
unless ( $tick_object->Id == $ticket->{id} ) {
die "Couldn't create ticket $ticket " . Dumper( $ticket);
}
# import ticket keywords
#import ticket transactions
foreach my $t ( @{$temp{Transaction}} ) {
print " transaction ".$t->{'id'} ."\n";
$t->{'ActivateScrips'} = 0;
if ( $t->{'Type'} eq 'Status' ) {
if ( $t->{'NewValue'} eq 'dead' ) {
$t->{'NewValue'} = 'deleted';
}
if ( $t->{'OldValue'} eq 'dead' ) {
$t->{'OldValue'} = 'deleted';
}
}
if ( $t->{'Type'} =~ /^AddWatcher$/ ) {
my $u = RT::User->new($RT::SystemUser);
$u->Load( $t->{'NewValue'} );
unless ( $u->Id ) {
$u->LoadByEmail( $t->{'NewValue'} );
}
unless ( $u->Id ) {
my $new_user = RT::User->new($RT::SystemUser);
my ( $Val, $Message ) = $new_user->Create(
Name => $t->{'NewValue'},
EmailAddress => $t->{'NewValue'},
RealName => $t->{'NewValue'},
Privileged => 0,
Comments => 'Autocreated when added as a watcher'
);
unless ($Val) {
$RT::Logger->error( "Failed to create user "
. $t->{'NewValue'} . ": "
. $Message );
# Deal with the race condition of two account creations at once
$new_user->LoadByEmail( $t->{'NewValue'} );
}
$u->Load( $new_user->PrincipalId );
}
$t->{'NewValue'} = $u->Id;
}
if ( $t->{'Type'} =~ /^DelWatcher$/ ) {
my $u = RT::User->new($RT::SystemUser);
$u->Load( $t->{'OldValue'} );
unless ( $u->Id ) {
$u->LoadByEmail( $t->{'OldValue'} );
}
unless ( $u->Id ) {
my $new_user = RT::User->new($RT::SystemUser);
my ( $Val, $Message ) = $new_user->Create(
Name => $t->{'OldValue'},
EmailAddress => $t->{'OldValue'},
RealName => $t->{'OldValue'},
Privileged => 0,
Comments => 'Autocreated when added as a watcher'
);
unless ($Val) {
$RT::Logger->error( "Failed to create user "
. $t->{'OldValue'} . ": "
. $Message );
# Deal with the race condition of two account creations at once
$new_user->LoadByEmail( $t->{'OldValue'} );
}
$u->Load( $new_user->PrincipalId );
}
$t->{'OldValue'} = $u->Id;
}
if ( $t->{'Type'} =~ /^(Force|Give|Take|Untake)$/ ) {
$t->{'OldValue'} = $user_map->{ $t->{OldValue} };
$t->{'NewValue'} = $user_map->{ $t->{NewValue} };
}
my $trans_obj = RT::Transaction->new($RT::SystemUser);
$t->{'Creator'} = $user_map->{ $t->{'Creator'} };
my $attach = $t->{'Attachment'};
delete $t->{'Attachment'};
$trans_obj->Create( %{ $t } );
unless ( $trans_obj->Id == $t->{'id'} ) {
die "Couldn't create trans ".$t->{'id'}." " . Dumper( $t);
}
foreach my $a (@{$attach}) {
my $att = RT::Attachment->new($RT::SystemUser);
$att->Import(%{$a});
print " attachment ".$att->Id ."\n";
unless( $att->Id) {
die "Couldn't create attachment $a " . Dumper( $a);
}
}
}
}
}
foreach my $link (@{$VAR1->{'Link'}}) {
my $l = RT::Link->new($RT::SystemUser);
$link->{'Base'} =~ s#/(.*?)/ticket/#/ticket/#;
$link->{'Target'} =~ s#/(.*?)/ticket/#/ticket/#;
my ($val, $msg) = $l->Create(Type=> $link->{'Type'},
Target => ($link->{'LocalTarget'} || $link->{'Target'}),
Base => ($link->{'LocalBase'} || $link->{'Base'})
);
unless ($l->Id ) {
if ($link->{'LocalBase'} != $link->{'LocalTarget'}) {
push (@errors, "Couldn't create link ".$msg.Dumper($link));
}
}
}
print join("\n", at errors);
More information about the Rt-devel
mailing list