Need LDAP scrip help: using a switch statement

Hey everyone,

I’m trying to adapt the “set custom field with LDAP query” scrip example from the RT book, and I’m stuck. I’m hoping someone has a suggestion. The main problem, I’m afraid, is a lack of perl experience.

I’ve created a new scrip called “Set Building CF from LDAP on Create” with Condition “On Create” and Action “User Defined”. Here’s my custom action preparation code:

my $email = ($self->TicketObj->RequestorAddresses)[0];
my $ldap = Net::LDAP->new( 'my.ldap.server );
$ldap->bind;
my $msg = $ldap->search( base => ‘ou=Staff,o=My-ldap-org’,
filter => ‘(email=$email)’,
);
my $entry = $msg->entry(0);
my $ou = $entry->get_value(‘ou’);

Fix up the CF names based on LDAP results

switch ($ou) {
case “DISTRICT SERVICES” { $building = “DO” }
case “HIGH SCHOOL” { $building = “HS” }
case “JEFFERSON” { $building = “JES” }
else { $building = “DO” }
};

my $cf = RT::CustomField->new( $RT::SystemUser );
$cf->LoadByName( Name => ‘Building’ );
$self->TicketObj->AddCustomFieldValue( Field => $cf, Value => $building );

return 1;

I don’t have anything in the Custom action cleanup code box.

I’m trying to use a switch because the field in our LDAP records doesn’t match the custom field text in RT. Rather than changing everything in the LDAP, I was hoping to make the translation here in the scrip action.

Anyone see a problem with this scrip? It doesn’t seem to break anything, but neither does the custom field get set when a new ticket comes in.

Running RT 3.6.3 on Ubuntu with MySQL 5.0.22 and apache-ssl 1.3.34

-Tim

Tim Wilson, Director of Technology
Buffalo-Hanover-Montrose Schools
214 1st Ave NE Buffalo, MN 55313
ph: 763.682.8740 fax: 763.682.8743 http://www.buffalo.k12.mn.us

“switch” isn’t really built into Perl, you have to “use Switch;”. I’ve
never tried using Perl modules from within the scrip custom
condition/action/etc, though. I don’t know of a reason, off hand, that
it wouldn’t work though.

Jacob Helwig
PC Technician
Busch’s Help Desk
Desk: x35221
Direct: 734-214-8221-----Original Message-----
From: rt-users-bounces@lists.bestpractical.com
[mailto:rt-users-bounces@lists.bestpractical.com] On Behalf Of Tim
Wilson
Sent: Monday, August 20, 2007 8:35 PM
To: rt-users@lists.bestpractical.com
Subject: [rt-users] Need LDAP scrip help: using a switch statement

Hey everyone,

I’m trying to adapt the “set custom field with LDAP query” scrip example
from the RT book, and I’m stuck. I’m hoping someone has a suggestion.
The main problem, I’m afraid, is a lack of perl experience.

I’ve created a new scrip called "Set Building CF from LDAP on Create"
with Condition “On Create” and Action “User Defined”. Here’s my custom
action preparation code:

my $email = ($self->TicketObj->RequestorAddresses)[0];
my $ldap = Net::LDAP->new( 'my.ldap.server );
$ldap->bind;
my $msg = $ldap->search( base => ‘ou=Staff,o=My-ldap-org’,
filter => ‘(email=$email)’,
);
my $entry = $msg->entry(0);
my $ou = $entry->get_value(‘ou’);

Fix up the CF names based on LDAP results

switch ($ou) {
case “DISTRICT SERVICES” { $building = “DO” }
case “HIGH SCHOOL” { $building = “HS” }
case “JEFFERSON” { $building = “JES” }
else { $building = “DO” }
};

my $cf = RT::CustomField->new( $RT::SystemUser );
$cf->LoadByName( Name => ‘Building’ );
$self->TicketObj->AddCustomFieldValue( Field => $cf, Value => $building
);

return 1;

I don’t have anything in the Custom action cleanup code box.

I’m trying to use a switch because the field in our LDAP records doesn’t
match the custom field text in RT. Rather than changing everything in
the LDAP, I was hoping to make the translation here in the scrip action.

Anyone see a problem with this scrip? It doesn’t seem to break anything,
but neither does the custom field get set when a new ticket comes in.

Running RT 3.6.3 on Ubuntu with MySQL 5.0.22 and apache-ssl 1.3.34

-Tim

Tim Wilson, Director of Technology
Buffalo-Hanover-Montrose Schools
214 1st Ave NE Buffalo, MN 55313
ph: 763.682.8740 fax: 763.682.8743 http://www.buffalo.k12.mn.us

http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-users

Community help: http://wiki.bestpractical.com
Commercial support: sales@bestpractical.com

Discover RT’s hidden secrets with RT Essentials from O’Reilly Media.
Buy a copy at http://rtbook.bestpractical.com

Hey everyone,

I’m trying to adapt the “set custom field with LDAP query” scrip example from the RT book, and I’m stuck. I’m hoping someone has a suggestion. The main problem, I’m afraid, is a lack of perl experience.

I’ve created a new scrip called “Set Building CF from LDAP on Create” with Condition “On Create” and Action “User Defined”. Here’s my custom action preparation code:

my $email = ($self->TicketObj->RequestorAddresses)[0];
my $ldap = Net::LDAP->new( 'my.ldap.server );
$ldap->bind;
my $msg = $ldap->search( base => ‘ou=Staff,o=My-ldap-org’,
filter => ‘(email=$email)’,
);
my $entry = $msg->entry(0);
my $ou = $entry->get_value(‘ou’);

Fix up the CF names based on LDAP results

switch ($ou) {
case “DISTRICT SERVICES” { $building = “DO” }
case “HIGH SCHOOL” { $building = “HS” }
case “JEFFERSON” { $building = “JES” }
else { $building = “DO” }
};

my $cf = RT::CustomField->new( $RT::SystemUser );
$cf->LoadByName( Name => ‘Building’ );
$self->TicketObj->AddCustomFieldValue( Field => $cf, Value => $building );

return 1;

I don’t have anything in the Custom action cleanup code box.

I’m trying to use a switch because the field in our LDAP records doesn’t match the custom field text in RT. Rather than changing everything in the LDAP, I was hoping to make the translation here in the scrip action.

Anyone see a problem with this scrip? It doesn’t seem to break anything, but neither does the custom field get set when a new ticket comes in.

Running RT 3.6.3 on Ubuntu with MySQL 5.0.22 and apache-ssl 1.3.34

-Tim

Instead of using switch, try using a hash lookup. For example:

my $ou = $entry->get_value(‘ou’);

my %building_for = (
‘DISTRICT SERVICES’ => ‘DO’,
‘HIGH SCHOOL’ => ‘HS’,
‘JEFFERSON’ => ‘JES’,
DEFAULT => ‘DO’,
);

Lookup building. If there was no LDAP entry, use the default

my $building = $building_for{$ou} || $building_for{DEFAULT};

This essentially does the same thing as your switch statement but it
doesn’t require an additional module.

-David

I’m trying to adapt the “set custom field with LDAP query” scrip example
from the RT book, and I’m stuck. I’m hoping someone has a suggestion. The
main problem, I’m afraid, is a lack of perl experience.

Instead of using switch, try using a hash lookup. For example:

my $ou = $entry- >get_value(‘ou’);

my %building_for = (
‘DISTRICT SERVICES’ => ‘DO’,
‘HIGH SCHOOL’ => ‘HS’,
‘JEFFERSON’ => ‘JES’,
DEFAULT => ‘DO’,
);

Lookup building. If there was no LDAP entry, use the default

my $building = $building_for{$ou} || $building_for{DEFAULT};

David,

Thanks for the suggestion. That approach seems very straightforward. Unfortunately, RT logs the following when the scrip is executed:

Aug 21 16:08:35 support RT: About to think about scrips for transaction #7940
Aug 21 16:08:36 support RT: Scrip 31 Commit failed: Can’t call method “get_value” on an undefined value at (eval 1139) line 11. Stack: [(eval 1139):11] [/usr/local/rt3/lib/RT/ScripAction_Overlay.pm:240] [/usr/local/rt3/lib/RT/Scrip_Overlay.pm:505] [/usr/local/rt3/lib/RT/Scrips_Overlay.pm:193] [/usr/local/rt3/lib/RT/Transaction_Overlay.pm:179] [/usr/local/rt3/lib/RT/Record.pm:1444] [/usr/local/rt3/lib/RT/Ticket_Overlay.pm:744] [/usr/local/rt3/lib/RT/Interface/Email.pm:719] [/usr/local/rt3/share/html/REST/1.0/NoAuth/mail-gateway:59] (/usr/local/rt3/lib/RT/Action/UserDefined.pm:81)

Here’s what I have my custom action cleanup code set to now (anonymized):

my $mail = ($self->TicketObj->RequestorAddresses)[0];
my $ldap = Net::LDAP->new( ‘my.ldap.server’ );
$ldap->bind;

Do the LDAP search. Note: Our eDirectory server uses “mail” for the

user’s email address.

my $msg = $ldap->search( base => ‘o=myOrg’,
filter => ‘(mail=$mail)’,
);
my $entry = $msg->entry(0);
my $ou = $entry->get_value(‘ou’);

Fix up the CF values based on LDAP results

my %building_for = (
‘DISTRICT SERVICES’ => ‘DO’,
‘HIGH SCHOOL’ => ‘HS’,
‘JEFFERSON’ => ‘JES’,
DEFAULT’ => ‘DO’,
);
my $building = $building_for{$ou} || $building_for{DEFAULT};

my $cf = RT::CustomField->new( $RT::SystemUser );
$cf->LoadByName( Name => ‘Building’ );
$self->TicketObj->AddCustomFieldValue( Field => $cf, Value => $building );

return 1;

It looks like the LDAP search is failing. I get this in my eDirectory logs:

(10.1.10.224:59620) (0x002b:0x63) Search request:
base: "o=myOrg"
scope: 2 dereference:2 sizelimit:0 timelimit:0 attrsonly:0
filter: "(mail=$mail)"
no attributes

So it appears that the contents of the $mail variable is not getting put into that LDAP search. If I hardcode the filter in the scrip with my email address then it works perfectly. The LDAP is retrieved, and the custom field gets set properly.

I took most of this code right from the RT book, and I don’t understand why $mail isn’t getting sent in the LDAP search. So I tried one more thing. I changed to the code to the following, creating the $filter variable in whole before passing it to the LDAP search:

my $filter = “(mail=$mail)”;
my $msg = $ldap->search( base => ‘o=myOrg’,
filter => $filter,
);

This worked! Now… why?

-Tim

Tim Wilson, Director of Technology
Buffalo-Hanover-Montrose Schools
214 1st Ave NE Buffalo, MN 55313
ph: 763.682.8740 fax: 763.682.8743 http://www.buffalo.k12.mn.us

I’m trying to adapt the “set custom field with LDAP query” scrip example
from the RT book, and I’m stuck. I’m hoping someone has a suggestion. The
main problem, I’m afraid, is a lack of perl experience.

Instead of using switch, try using a hash lookup. For example:

my $ou = $entry- >get_value(‘ou’);

my %building_for = (
‘DISTRICT SERVICES’ => ‘DO’,
‘HIGH SCHOOL’ => ‘HS’,
‘JEFFERSON’ => ‘JES’,
DEFAULT => ‘DO’,
);

Lookup building. If there was no LDAP entry, use the default

my $building = $building_for{$ou} || $building_for{DEFAULT};

David,

Thanks for the suggestion. That approach seems very straightforward. Unfortunately, RT logs the following when the scrip is executed:

Aug 21 16:08:35 support RT: About to think about scrips for transaction #7940
Aug 21 16:08:36 support RT: Scrip 31 Commit failed: Can’t call method “get_value” on an undefined value at (eval 1139) line 11. Stack: [(eval 1139):11] [/usr/local/rt3/lib/RT/ScripAction_Overlay.pm:240] [/usr/local/rt3/lib/RT/Scrip_Overlay.pm:505] [/usr/local/rt3/lib/RT/Scrips_Overlay.pm:193] [/usr/local/rt3/lib/RT/Transaction_Overlay.pm:179] [/usr/local/rt3/lib/RT/Record.pm:1444] [/usr/local/rt3/lib/RT/Ticket_Overlay.pm:744] [/usr/local/rt3/lib/RT/Interface/Email.pm:719] [/usr/local/rt3/share/html/REST/1.0/NoAuth/mail-gateway:59] (/usr/local/rt3/lib/RT/Action/UserDefined.pm:81)

Here’s what I have my custom action cleanup code set to now (anonymized):

my $mail = ($self->TicketObj->RequestorAddresses)[0];
my $ldap = Net::LDAP->new( ‘my.ldap.server’ );
$ldap->bind;

Do the LDAP search. Note: Our eDirectory server uses “mail” for the

user’s email address.

my $msg = $ldap->search( base => ‘o=myOrg’,
filter => ‘(mail=$mail)’,
);
my $entry = $msg->entry(0);
my $ou = $entry->get_value(‘ou’);

Fix up the CF values based on LDAP results

my %building_for = (
‘DISTRICT SERVICES’ => ‘DO’,
‘HIGH SCHOOL’ => ‘HS’,
‘JEFFERSON’ => ‘JES’,
DEFAULT’ => ‘DO’,
);
my $building = $building_for{$ou} || $building_for{DEFAULT};

my $cf = RT::CustomField->new( $RT::SystemUser );
$cf->LoadByName( Name => ‘Building’ );
$self->TicketObj->AddCustomFieldValue( Field => $cf, Value => $building );

return 1;

It looks like the LDAP search is failing. I get this in my eDirectory logs:

(10.1.10.224:59620) (0x002b:0x63) Search request:
base: "o=myOrg"
scope: 2 dereference:2 sizelimit:0 timelimit:0 attrsonly:0
filter: "(mail=$mail)"
no attributes

So it appears that the contents of the $mail variable is not getting put into that LDAP search. If I hardcode the filter in the scrip with my email address then it works perfectly. The LDAP is retrieved, and the custom field gets set properly.

I took most of this code right from the RT book, and I don’t understand why $mail isn’t getting sent in the LDAP search. So I tried one more thing. I changed to the code to the following, creating the $filter variable in whole before passing it to the LDAP search:

my $filter = “(mail=$mail)”;
my $msg = $ldap->search( base => ‘o=myOrg’,
filter => $filter,
);

This worked! Now… why?

In the first case you’re using ‘(mail = $mail)’ – with single quotes.
The single quotes prevent $mail from being interpolated. To make sure
$mail is interpolated correctly, use double quotes (as you’re doing in
the second case when you use the separate $filter variable):

my $msg = $ldap->search( base => ‘o=myOrg’,
filter => “(mail=$mail)”,
);

-David