diff options
author | Jesse Vincent <jesse@bestpractical.com> | 2002-08-09 02:35:31 +0400 |
---|---|---|
committer | Jesse Vincent <jesse@bestpractical.com> | 2002-08-09 02:35:31 +0400 |
commit | 0d2e11fe4f5d61279dab8492c11d6596dd079c89 (patch) | |
tree | a4c875aaea003564e1f830e3399387a516db0a99 | |
parent | 21f4bd38d6ed13f263e6460f1bc2721edeb90e9d (diff) |
Adding in the new rt cron toolrt-2.1.30
-rwxr-xr-x | Makefile | 6 | ||||
-rw-r--r-- | bin/rt-crontool | 178 | ||||
-rwxr-xr-x | lib/RT/Action/EscalatePriority.pm | 114 | ||||
-rwxr-xr-x | lib/RT/Action/SetPriority.pm | 32 | ||||
-rwxr-xr-x | lib/RT/Condition/Generic.pm | 1 | ||||
-rwxr-xr-x | lib/RT/Condition/Overdue.pm | 38 | ||||
-rwxr-xr-x | lib/RT/Condition/PriorityExceeds.pm | 28 | ||||
-rwxr-xr-x | lib/RT/Scrip_Overlay.pm | 2 | ||||
-rwxr-xr-x | lib/RT/Ticket_Overlay.pm | 14 | ||||
-rw-r--r-- | sbin/cron_shim | 124 |
10 files changed, 406 insertions, 131 deletions
@@ -11,7 +11,7 @@ GETPARAM = $(PERL) -e'require "$(CONFIG_FILE)"; print $${$$RT::{$$ARGV[0]}};' RT_VERSION_MAJOR = 2 RT_VERSION_MINOR = 1 -RT_VERSION_PATCH = 29 +RT_VERSION_PATCH = 30 RT_VERSION = $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH) TAG = rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH) @@ -75,6 +75,8 @@ RT_CLI_BIN = $(RT_BIN_PATH)/rt RT_CLI_ADMIN_BIN = $(RT_BIN_PATH)/rtadmin # RT's mail gateway RT_MAILGATE_BIN = $(RT_BIN_PATH)/rt-mailgate +# RT's cron tool +RT_CRON_BIN = $(RT_BIN_PATH)/rt-crontool # }}} @@ -84,6 +86,7 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_MAILGATE_BIN) \ $(DESTDIR)/$(RT_CLI_ADMIN_BIN) BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \ + $(DESTDIR)/$(RT_CRON_BIN) \ $(SETGID_BINARIES) SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ @@ -346,6 +349,7 @@ bin-install: bin/mason_handler.fcgi \ bin/mason_handler.svc \ bin/webmux.pl \ + bin/rt-crontool \ bin/rt-commit-handler \ $(DESTDIR)/$(RT_BIN_PATH) $(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\ diff --git a/bin/rt-crontool b/bin/rt-crontool new file mode 100644 index 0000000000..ae771b671f --- /dev/null +++ b/bin/rt-crontool @@ -0,0 +1,178 @@ +#!/usr/bin/perl + +use strict; +use Carp; + +use lib "!!RT_LIB_PATH!!"; + +package RT; + +use Getopt::Long; + +use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc); +use RT::Tickets; + +#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(); + +#Drop setgid permissions +RT::DropSetGIDPermissions(); + +#Get the current user all loaded +my $CurrentUser = GetCurrentUser(); + +unless ( $CurrentUser->Id ) { + print loc("No RT user found. Please consult your RT administrator.\n"); + exit(1); +} + +my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg, + $help, $verbose ); +GetOptions( "search=s" => \$search, + "search-arg=s" => \$search_arg, + "condition=s" => \$condition, + "condition-arg=s" => \$condition_arg, + "action-arg=s" => \$action_arg, + "action=s" => \$action, + "help" => \$help, + "verbose|v" => \$verbose ); + +help() if $help; + +# We _must_ have a search object +load_module($search); +load_module($action) if ($action); +load_module($condition) if ($condition); + +#At the appointed time: + +#find a bunch of tickets +my $tickets = RT::Tickets->new($CurrentUser); +my $search = $search->new( TicketsObj => $tickets, Argument => $search_arg ); + +$search->Prepare(); + +# TicketsFound is an RT::Tickets object +my $tickets = $search->TicketsObj; + +#for each ticket we've found +while ( my $ticket = $tickets->Next() ) { + print "\n" . $ticket->Id() . ": " if ($verbose); + + # perform some more advanced check + if ($condition) { + my $condition_obj = $condition->new( TicketObj => $ticket, + Argument => $condition_arg ); + + # if the condition doesn't apply, get out of here + + next unless ( $condition_obj->IsApplicable ); + print loc("Condition matches...") if ($verbose); + } + + #prepare our action + my $action_obj = $action->new( TicketObj => $ticket, + Argument => $action_arg ); + + #if our preparation, move onto the next ticket + next unless ( $action_obj->Prepare ); + print loc("Action prepared...") if ($verbose); + + #commit our action. + next unless ( $action_obj->Commit ); + print loc("Action committed.") if ($verbose); +} + +# {{{ load_module + +=head2 load_module + +Loads a perl module, dying nicely if it can't find it. + +=cut + +sub load_module { + my $modname = shift; + eval "require $modname"; + if ($@) { + die loc( "Failed to load module [_1]. ([_2])", $modname, $@ ); + } + +} + +# }}} + +# {{{ loc + +=head2 loc LIST + +Localize this string, with the current user's currentuser object + +=cut + +sub loc { + $CurrentUser->loc(@_); +} + +# }}} + +sub help { + + print loc( "[_1] is a tool to act on tickets from an external scheduling tool, such as cron.", $0 ) + . "\n"; + print loc("It takes several arguments:") . "\n\n"; + + print " " + . loc( "[_1] - Specify the search module you want to use", "--search" ) + . "\n"; + print " " + . loc( "[_1] - An argument to pass to [_2]", "--search-argument", "--search" ) + . "\n"; + + print " " + . loc( "[_1] - Specify the condition module you want to use", "--condition" ) + . "\n"; + print " " + . loc( "[_1] - An argument to pass to [_2]", "--condition-argument", "--condition" ) + . "\n"; + print " " + . loc( "[_1] - Specify the action module you want to use", "--action" ) + . "\n"; + print " " + . loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" ) + . "\n"; + print " " + . loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n"; + print "\n"; + print "\n"; + print loc("Security:")."\n"; + print loc("This tool allows the user to run arbitrary perl modules from within RT.")." ". + loc("If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT.")." ". + loc("It is incredibly important that nonprivileged users not be +allowed to run this tool."). " " . + loc("It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool.")."\n"; + print "\n"; + print loc("Example:"); + print "\n"; + print " " + . loc( "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:" + ) + . "\n\n"; + + print " sbin/cron_shim \\\n"; + print + " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; + print + " --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n"; + print " --action RT::Action::SetPriority --action-arg 99 \\\n"; + print " --verbose\n"; + + + exit(0); +} diff --git a/lib/RT/Action/EscalatePriority.pm b/lib/RT/Action/EscalatePriority.pm new file mode 100755 index 0000000000..37269dcd45 --- /dev/null +++ b/lib/RT/Action/EscalatePriority.pm @@ -0,0 +1,114 @@ +# $Header: /raid/cvsroot/rt-addons/ScripActions/EscalatePriority/EscalatePriority.pm,v 1.2 2001/06/22 23:50:37 jesse Exp $ + + +=head1 NAME + + RT::Action::EscalatePriority + +=description + +EscalatePriority is a ScripAction which is NOT intended to be called per +transaction. It's intended to be called by an RT escalation daemon. + (The daemon is called escalator). + +EsclatePriority uses the following formula to change a ticket's priority: + + +Priority = Priority + (( FinalPriority - Priority ) / ( DueDate-Today)) + +unless the duedate is past, in which case priority gets bumped straight +to final priority. + +In this way, priority is either increased or decreased toward the final priority +as the ticket heads toward its due date. + + +=cut + + +package RT::Action::EscalatePriority; +require RT::Action::Generic; +@ISA=qw(RT::Action::Generic); + +#Do what we need to do and send it out. + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self . " will move a ticket's priority toward its final priority."); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + my $self = shift; + + if ($self->TicketObj->Priority() == $self->TicketObj->FinalPriority()) { + # no update necessary. + return 0; + } + + #compute the number of days until the ticket is due + my $due = $self->TicketObj->DueObj(); + + + # If we don't have a due date, adjust the priority by one + # until we hit the final priority + if ($due->Unix() < 1) { + if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){ + $self->{'prio'} = ($self->TicketObj->Priority - 1); + return 1; + } + elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){ + $self->{'prio'} = ($self->TicketObj->Priority + 1); + return 1; + } + # otherwise the priority is at the final priority. we don't need to + # Continue + else { + return 0; + } + } + + # we've got a due date. now there are other things we should do + else { + my $diff_in_seconds = $due->Diff(time()); + my $diff_in_days = int( $diff_in_seconds / 86400); + + #if we haven't hit the due date yet + if ($diff_in_days > 0 ) { + + # compute the difference between the current priority and the + # final priority + + my $prio_delta = + $self->TicketObj->FinalPriority() - $self->TicketObj->Priority; + + my $inc_priority_by = int( $prio_delta / $diff_in_days ); + + #set the ticket's priority to that amount + $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by; + + } + #if $days is less than 1, set priority to final_priority + else { + $self->{'prio'} = $self->TicketObj->FinalPriority(); + } + + } + return 1; +} +# }}} + +sub Commit { + my $self = shift; + my ($val, $msg) = $self->TicketObj->SetPriority($self->{'prio'}); + + unless ($val) { + $RT::Logger->debug($self . " $msg\n"); + } +} +1; diff --git a/lib/RT/Action/SetPriority.pm b/lib/RT/Action/SetPriority.pm new file mode 100755 index 0000000000..af31b0b98b --- /dev/null +++ b/lib/RT/Action/SetPriority.pm @@ -0,0 +1,32 @@ +# $Header: /raid/cvsroot/rt-addons/ScripActions/SetPriority/SetPriority.pm,v 1.1 2001/06/22 21:46:33 jesse Exp $ + +package RT::Action::SetPriority; +require RT::Action::Generic; +@ISA=qw(RT::Action::Generic); + +#Do what we need to do and send it out. + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self . " will set a ticket's priority to the argument provided."); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + # nothing to prepare + return 1; +} +# }}} + +sub Commit { + my $self = shift; + $self->TicketObj->SetPriority($self->Argument); + +} + +1; diff --git a/lib/RT/Condition/Generic.pm b/lib/RT/Condition/Generic.pm index cb51c4dd19..14a6923a8b 100755 --- a/lib/RT/Condition/Generic.pm +++ b/lib/RT/Condition/Generic.pm @@ -63,7 +63,6 @@ sub _Init { ApplicableTransTypes => undef, @_ ); - $self->{'Argument'} = $args{'Argument'}; $self->{'ScripObj'} = $args{'ScripObj'}; $self->{'TicketObj'} = $args{'TicketObj'}; diff --git a/lib/RT/Condition/Overdue.pm b/lib/RT/Condition/Overdue.pm new file mode 100755 index 0000000000..b7e598da11 --- /dev/null +++ b/lib/RT/Condition/Overdue.pm @@ -0,0 +1,38 @@ +# $Header: /raid/cvsroot/rt-addons/ScripConditions/IfTicketPriorityExceeds/PriorityExceeds.pm,v 1.2 2001/06/24 20:04:44 jesse Exp $ +# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com> +# Released under the terms of the GNU General Public License + +=head1 NAME + +RT::Condition::Overdue + +=head1 DESCRIPTION + +Returns true if the ticket we're operating on is overdue + +=cut + +package RT::Condition::Overdue; +require RT::Condition::Generic; + +@ISA = qw(RT::Condition::Generic); + + +=head2 IsApplicable + +If the due date is before "now" return true + +=cut + +sub IsApplicable { + my $self = shift; + if ($self->TicketObj->DueObj->Unix < time()) { + return(1); + } + else { + return(undef); + } +} + +1; + diff --git a/lib/RT/Condition/PriorityExceeds.pm b/lib/RT/Condition/PriorityExceeds.pm new file mode 100755 index 0000000000..30e02e8dd0 --- /dev/null +++ b/lib/RT/Condition/PriorityExceeds.pm @@ -0,0 +1,28 @@ +# $Header: /raid/cvsroot/rt-addons/ScripConditions/IfTicketPriorityExceeds/PriorityExceeds.pm,v 1.2 2001/06/24 20:04:44 jesse Exp $ +# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com> +# Released under the terms of the GNU General Public License + +package RT::Condition::PriorityExceeds; +require RT::Condition::Generic; + +@ISA = qw(RT::Condition::Generic); + + +=head2 IsApplicable + +If the priority exceeds the argument value + +=cut + +sub IsApplicable { + my $self = shift; + if ($self->TicketObj->Priority > $self->Argument) { + return(1); + } + else { + return(undef); + } +} + +1; + diff --git a/lib/RT/Scrip_Overlay.pm b/lib/RT/Scrip_Overlay.pm index 956de6d3d4..f51c34e42f 100755 --- a/lib/RT/Scrip_Overlay.pm +++ b/lib/RT/Scrip_Overlay.pm @@ -56,8 +56,6 @@ ok ($ticket2->Priority != '87', "Ticket priority is set right"); =cut no warnings qw(redefine); -/-/-/-/-/-/-/-/-/-/ BEGIN CONFLICT [O60 A60 B59] /-/-/-/-/-/-/-/-/-/-/ -/-/-/-/-/-/-/-/-/-/-/-/-/ END CONFLICT /-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ # {{{ sub Create diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm index 03a8c80ac4..460d30983a 100755 --- a/lib/RT/Ticket_Overlay.pm +++ b/lib/RT/Ticket_Overlay.pm @@ -818,6 +818,7 @@ AddWatcher takes a parameter hash. The keys are as follows: Type One of Requestor, Cc, AdminCc PrinicpalId The RT::Principal id of the user or group that's being added as a watcher + Email The email address of the new watcher. If a user with this email address can't be found, a new nonprivileged user will be created. @@ -984,14 +985,21 @@ sub DeleteWatcher { my %args = ( Type => undef, PrincipalId => undef, + Email => undef, @_ ); - unless ($args{'PrincipalId'} ) { + unless ($args{'PrincipalId'} || $args{'Email'} ) { return(0, $self->loc("No principal specified")); } my $principal = RT::Principal->new($self->CurrentUser); - $principal->Load($args{'PrincipalId'}); + if ($args{'PrincipalId'} ) { + $principal->Load($args{'PrincipalId'}); + } else { + my $user = RT::Useer->new($self->CurrentUser); + $user->LoadByEmail($args{'Email'}); + $principal->Load($user->Id); + } # If we can't find this watcher, we need to bail. unless ($principal->Id) { return(0, $self->loc("Could not find that principal")); @@ -1024,7 +1032,7 @@ sub DeleteWatcher { } } else { - $RT::Logger->warn( "$self -> DelWatcher got passed a bogus type"); + $RT::Logger->warn( "$self -> DeleteWatcher got passed a bogus type"); return ( 0, $self->loc('Error in parameters to Ticket->DelWatcher') ); } } diff --git a/sbin/cron_shim b/sbin/cron_shim deleted file mode 100644 index 5cd33255e8..0000000000 --- a/sbin/cron_shim +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/perl - - -use strict; -use Carp; - -#use lib "!!RT_LIB_PATH!!"; -use lib "/opt/rt22/lib"; - -package RT; - -use Getopt::Long; - -use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc); -use RT::Tickets; - -#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(); - -#Drop setgid permissions -RT::DropSetGIDPermissions(); - -#Get the current user all loaded -my $CurrentUser = GetCurrentUser(); - -unless ($CurrentUser->Id) { - print loc("No RT user found. Please consult your RT administrator.\n"); - exit(1); -} - - - -my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg ); -GetOptions( "search=s" => \$search, - "search-arg=s" => \$search_arg, - "condition=s" => \$condition, - "condition-arg=s" => \$condition_arg, - "action-arg=s" => \$action_arg, - "action=s" => \$action, - ); - -# We _must_ have a search object -load_module($search); -load_module($action) if ($action); -load_module($condition) if ($condition); - -#At the appointed time: - -#find a bunch of tickets -my $tickets = RT::Tickets->new($CurrentUser); -my $search = $search->new( TicketsObj => $tickets, Argument => $search_arg); - -$search->Prepare(); - -# TicketsFound is an RT::Tickets object -my $tickets = $search->TicketsObj; - -#for each ticket we've found -while ( my $ticket = $tickets->Next() ) { - print $ticket->Id()."\n"; - # perform some more advanced check - if ($condition) { - my $condition_obj = $condition->new( - TicketObj => $ticket, - Argument => $condition_arg - ); - - # if the condition doesn't apply, get out of here - - next unless ( $condition->IsApplicable ); - - } - - #prepare our action - my $action_obj = $action->new( TicketObj => $ticket, - Argument => $action_arg ); - - #if our preparation, move onto the next ticket - next unless ( $action_obj->Prepare ); - - #commit our action. - $action_obj->Commit; -} - -# {{{ load_module - -=head2 load_module - -Loads a perl module, dying nicely if it can't find it. - -=cut - -sub load_module { - my $modname = shift; - eval "require $modname"; - if ($@) { - die loc( "Failed to load module [_1]. ([_2])", $modname, $@ ); - } - -} - -# }}} - -# {{{ loc - -=head2 loc LIST - -Localize this string, with the current user's currentuser object - -=cut - -sub loc { - print join ( '', @_ ); - - # $CurrentUser->loc(@_); -} - -# }}} |