#!/usr/bin/perl
use
lib
qw(/opt/rt3/local/lib /opt/rt3/lib)
;
RT::LoadConfig;
RT::Init;
our
$cmd
=
'usage'
;
our
$opts
= {};
sub
parse_args
{
my
$tmp
;
Getopt::Long::Configure(
"pass_through"
);
if
( GetOptions(
'list'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'list'
;
}
elsif
( GetOptions(
'create=s'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'create'
;
$opts
->{
'name'
} =
$tmp
;
$opts
->{
'groups'
} = [];
$opts
->{
'users'
} = [];
GetOptions(
'comment'
=> \
$opts
->{
'comment'
} );
GetOptions(
'group:s@'
=>
$opts
->{
'groups'
} );
GetOptions(
'user:s@'
=>
$opts
->{
'users'
} );
unless
( @{
$opts
->{
'users'
} } + @{
$opts
->{
'groups'
} } ) {
usage();
exit
(-1);
}
}
elsif
( GetOptions(
'add=s'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'add'
;
$opts
->{
'name'
} =
$tmp
;
$opts
->{
'groups'
} = [];
$opts
->{
'users'
} = [];
GetOptions(
'group:s@'
=>
$opts
->{
'groups'
} );
GetOptions(
'user:s@'
=>
$opts
->{
'users'
} );
unless
( @{
$opts
->{
'users'
} } + @{
$opts
->{
'groups'
} } ) {
usage();
exit
(-1);
}
}
elsif
( GetOptions(
'switch=s'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'switch'
;
$opts
->{
'name'
} =
$tmp
;
}
elsif
( GetOptions(
'rename=s'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'rename'
;
$opts
->{
'name'
} =
$tmp
;
GetOptions(
'newname=s'
=> \
$opts
->{
'newname'
} );
unless
(
$opts
->{
'newname'
} ) {
usage();
exit
(-1);
}
}
elsif
( GetOptions(
'delete=s'
=> \
$tmp
) &&
$tmp
) {
$cmd
=
'delete'
;
$opts
->{
'name'
} =
$tmp
;
}
else
{
$cmd
=
'usage'
;
}
return
;
}
sub
usage
{
eval
"require Pod::PlainText;"
;
if
( $@ ) {
print
"see `perldoc $0`\n"
;
}
else
{
my
$parser
= Pod::PlainText->new (
sentence
=> 0,
width
=> 78);
$parser
->parse_from_file( $0 );
}
}
parse_args();
{
eval
"main::$cmd()"
;
if
( $@ ) {
print
STDERR $@ .
"\n"
;
}
}
exit
(0);
sub
list
{
my
$actions
= _get_our_actions();
while
(
my
$a
=
$actions
->Next ) {
_list(
$a
);
}
return
;
}
sub
_list
{
my
$action
=
shift
;
print
"Name: "
.
$action
->Name() .
"\n"
;
print
"Module: "
.
$action
->ExecModule() .
"\n"
;
my
$arg
=
$action
->Argument;
my
$old
=
eval
{ Storable::thaw(
$arg
) };
unless
( $@ ) {
$arg
= __convert_old(
$old
);
}
my
@princ
= _split_arg(
$arg
);
print
"Members: \n"
;
foreach
(
@princ
) {
my
$obj
= RT::Principal->new(
$RT::SystemUser
);
$obj
->Load(
$_
);
next
unless
(
$obj
->id );
print
"\t"
.
$obj
->PrincipalType;
print
"\t=> "
.
$obj
->Object->Name;
print
"(Disabled!!!)"
if
$obj
->Disabled;
print
"\n"
;
}
print
"\n"
;
return
;
}
sub
create
{
my
$actions
= RT::ScripActions->new(
$RT::SystemUser
);
$actions
->Limit(
FIELD
=>
'Name'
,
VALUE
=>
$opts
->{
'name'
} );
if
(
$actions
->Count ) {
print
STDERR
"ScripAction '"
.
$opts
->{'name
'} ."'
allready
exists
\n";
exit
(-1);
}
my
@groups
= _check_groups( @{
$opts
->{
'groups'
} } );
my
@users
= _check_users( @{
$opts
->{
'users'
} } );
unless
(
@users
+
@groups
) {
print
STDERR
"List of groups and users is empty\n"
;
exit
(-1);
}
my
$action
= __create_empty(
$opts
->{
'name'
},
$opts
->{
'comment'
} );
__add(
$action
,
$_
)
foreach
(
@users
);
__add(
$action
,
$_
)
foreach
(
@groups
);
return
;
}
sub
__create_empty
{
my
$name
=
shift
;
my
$as_comment
=
shift
|| 0;
my
$action
= RT::ScripAction->new(
$RT::SystemUser
);
$action
->Create(
Name
=>
$name
,
Description
=>
"Created with rt-notify-group-admin script"
,
ExecModule
=>
$as_comment
?
'NotifyGroupAsComment'
:
'NotifyGroup'
,
Argument
=>
''
,
);
return
$action
;
}
sub
_check_groups
{
return
grep
{
$_
? 1:
do
{
print
STDERR
"Group '$_' skipped, doesn't exist\n"
; 0; } }
map
{ __check_group(
$_
) }
@_
;
}
sub
__check_group
{
my
$instance
=
shift
;
my
$obj
= RT::Group->new(
$RT::SystemUser
);
$obj
->LoadUserDefinedGroup(
$instance
);
return
$obj
->id ?
$obj
:
undef
;
}
sub
_check_users
{
return
grep
{
$_
? 1:
do
{
print
STDERR
"User '$_' skipped, doesn't exist\n"
; 0; } }
map
{ __check_user(
$_
) }
@_
;
}
sub
__check_user
{
my
$instance
=
shift
;
my
$obj
= RT::User->new(
$RT::SystemUser
);
$obj
->Load(
$instance
);
return
$obj
->id ?
$obj
:
undef
;
}
sub
add
{
my
$action
= _get_action_by_name(
$opts
->{
'name'
} );
unless
(
$action
) {
print
STDERR
"ScripAction '"
.
$opts
->{'name
'} ."'
doesn't exist\n";
exit
(-1);
}
my
@groups
= _check_groups( @{
$opts
->{
'groups'
} } );
my
@users
= _check_users( @{
$opts
->{
'users'
} } );
unless
(
@users
+
@groups
) {
print
STDERR
"List of groups and users is empty\n"
;
exit
(-1);
}
__add(
$action
,
$_
)
foreach
(
@users
);
__add(
$action
,
$_
)
foreach
(
@groups
);
return
;
}
sub
__add
{
my
$action
=
shift
;
my
$obj
=
shift
;
my
$arg
=
$action
->Argument;
my
$old
=
eval
{ Storable::thaw(
$arg
) };
unless
( $@ ) {
$arg
= __convert_old(
$old
);
}
my
@cur
= _split_arg(
$arg
);
my
$id
=
$obj
->id;
foreach
(
@cur
) {
return
if
(
$_
==
$id
);
}
push
(
@cur
,
$id
);
$action
->__Set(
Field
=>
'Argument'
,
Value
=>
join
(
';'
,
@cur
) );
return
;
}
sub
delete
{
my
$action
= _get_action_by_name(
$opts
->{
'name'
} );
unless
(
$action
) {
print
STDERR
"ScripAction '"
.
$opts
->{'name
'} ."'
doesn't exist\n";
exit
(-1);
}
my
$scrips
= RT::Scrips->new(
$RT::SystemUser
);
$scrips
->Limit(
FIELD
=>
'ScripAction'
,
VALUE
=>
$action
->id );
if
(
$scrips
->Count ) {
my
@sid
;
while
(
my
$s
=
$scrips
->Next ) {
push
@sid
,
$s
->id;
}
print
STDERR
"ScripAction '"
.
$opts
->{
'name'
}
.
"' is in use by Scrip(s) #"
.
join
(
";"
,
@sid
)
.
"\n"
;
exit
(-1);
}
return
__delete(
$action
);
}
sub
__delete
{
DBIx::SearchBuilder::Record::Delete(
shift
);
}
sub
_get_action_by_name
{
my
$name
=
shift
;
my
$actions
= _get_our_actions();
$actions
->Limit(
FIELD
=>
'Name'
,
VALUE
=>
$name
);
if
(
$actions
->Count > 1 ) {
print
STDERR
"More then one ScripAction with name '$name'\n"
;
}
return
$actions
->First;
}
sub
switch
{
my
$action
= _get_action_by_name(
$opts
->{
'name'
} );
unless
(
$action
) {
print
STDERR
"ScripAction '"
.
$opts
->{'name
'} ."'
doesn't exist\n";
exit
(-1);
}
my
%h
= (
'NotifyGroup'
=>
'NotifyGroupAsComment'
,
'NotifyGroupAsComment'
=>
'NotifyGroup'
);
$action
->__Set(
Field
=>
'ExecModule'
,
Value
=>
$h
{
$action
->ExecModule } );
}
sub
rename
{
my
$action
= _get_action_by_name(
$opts
->{
'name'
} );
unless
(
$action
) {
print
STDERR
"ScripAction '"
.
$opts
->{'name
'} ."'
doesn't exist\n";
exit
(-1);
}
my
$actions
= RT::ScripActions->new(
$RT::SystemUser
);
$actions
->Limit(
FIELD
=>
'Name'
,
VALUE
=>
$opts
->{
'newname'
} );
if
(
$actions
->Count ) {
print
STDERR
"ScripAction '"
.
$opts
->{'newname
'} ."'
allready
exists
\n";
exit
(-1);
}
$action
->__Set(
Field
=>
'Name'
,
Value
=>
$opts
->{
'newname'
} );
}
sub
_split_arg
{
return
split
/[^0-9]+/,
$_
[0];
}
sub
__convert_old
{
my
$arg
=
shift
;
my
@res
;
foreach
my
$r
( @{
$arg
} ) {
my
$obj
;
next
unless
$r
->{
'Type'
};
if
(
lc
$r
->{
'Type'
} eq
'user'
) {
$obj
= RT::User->new(
$RT::SystemUser
);
}
elsif
(
lc
$r
->{
'Type'
} eq
'user'
) {
$obj
= RT::Group->new(
$RT::SystemUser
);
}
else
{
next
;
}
$obj
->Load(
$r
->{
'Instance'
} );
my
$id
=
$obj
->id;
next
unless
(
$id
);
push
@res
,
$id
;
}
return
join
';'
,
@res
;
}
sub
_get_our_actions
{
my
$actions
= RT::ScripActions->new(
$RT::SystemUser
);
$actions
->Limit(
FIELD
=>
'ExecModule'
,
VALUE
=>
'NotifyGroup'
,
ENTRYAGGREGATOR
=>
'OR'
);
$actions
->Limit(
FIELD
=>
'ExecModule'
,
VALUE
=>
'NotifyGroupAsComment'
,
ENTRYAGGREGATOR
=>
'OR'
);
return
$actions
;
}