A perforce trigger script written in Perl to enforce JIRA ID on Perforce changelist submission. This script also connects to JIRA server to make sure the submitted JIRA ID is a valid one.
Create a properties file p4trigger.properties with required information
cat p4trigger.properties
# Perforce pre-commit trigger to check jira-id configuration file
# %serverport% It comes from trigger
p4user = ****
p4port = ****:1666
p4passwd = ************************************
jiraProjects = AAAA BBBB
jiraURL = https://jira.com:8443
jiraLogin = ******
jiraPWD = /export/*****/******/****.txt
Now a perl module Utilities.pm, which consists re-usable functions.
cat Utilities.pm
package Utilities;
use strict;
use Exporter;
use Data::Dumper;
use JIRA::Client;
use P4;
use Crypt::Rijndael;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = (); #list of functions that we export by default
@EXPORT_OK = qw(ReadConfig GetP4Description CheckJiraID ProcessJiraID); #list of functions that we export on demand
%EXPORT_TAGS = ( DEFAULT => [qw(&ReadConfig)],
ALL => [qw(&ReadConfig &GetP4Description &CheckJiraID &ProcessJiraID)]);
sub ReadConfig {
my ($config) = @_;
my %userPreferences;
open(CONFIG,"$config") or die "[ERROR] Couldn't read $config: $!";
while (<CONFIG>) {
chomp; # no newline
s/#.*//; # no comments
s/^\s+//; # no leading white
s/\s+$//; # no trailing white
next unless length; # anything left ?
my ($var, $value) = split(/\s*=\s*/, $_, 2);
$userPreferences{$var}=$value;
}
return \%userPreferences;
}
sub GetP4Description {
my ($P4port,$P4user,$P4cl,$P4passwd)=@_;
my %changelistDesc;
#Establish p4 connection
my $p4 = new P4;
$p4->SetPort ( $P4port );
$p4->SetUser( $P4user );
$p4->SetPassword( $P4passwd );
$p4->Connect() or die( "Failed to connect to Perforce Server" );
#my $info = ($p4->Run("info"))[0];
#print Dumper($info);
#Get perforce description for the given changelist number
my $descCmdOut=$p4->RunDescribe( "-s", $P4cl );
#print "USER=$descCmdOut->[0]->{user}\n";
$changelistDesc{"user"}=$descCmdOut->[0]->{user};
#my $p4ChangeUser= $descCmdOut->[0]->{user};
$changelistDesc{"desc"}=$descCmdOut->[0]->{desc};
#my $desc="$descCmdOut->[0]->{desc}";
$changelistDesc{"files"}=\@{$descCmdOut->[0]->{depotFile}};
#my @files=@{$descCmdOut->[0]->{depotFile}};
return (\%changelistDesc);
}
sub CheckJiraID {
my ($jiraProjs,$desc)=@_;
my %getJiraIDs;
my (@jira_idlist,$found);
$found=0;
my @jiraProjects = split / /, $jiraProjs;
#print "desc=$desc\n";
foreach (@jiraProjects) {
my @matches = $desc =~ /($_-\d+)/gi;
push(@jira_idlist,@matches);
}
#print "@jira_idlist\n";
if(scalar(@jira_idlist) != 0)
{
$found=1;
}
$getJiraIDs{"found"}=$found;
$getJiraIDs{"ids"}=\@jira_idlist;
return(\%getJiraIDs);
}
sub ProcessJiraID {
my ($jiraID,$jiraURL,$jiraLogin,$jiraPWD)=@_;
my $jiraPasswd=&hide_passwd($jiraPWD);
$jiraPasswd =~ s/\s*$//gi;
my $jira = JIRA::Client->new("$jiraURL", "$jiraLogin", "$jiraPasswd");
my $issue = eval { $jira->getIssue("$jiraID") };
die "[ERROR] Jira ID $jiraID doesn't exist: Provide valid jira ID" if $@;
my $jiraUser=$issue->{assignee};
my $fixVer=$issue->{fixVersions}->[0]->{name};
return($fixVer,$jiraUser);
}
sub hide_passwd(){
my $app_secret = 'this_is_the_key_the_app_uses....';
my $passwd_file_name = shift;
my $passwd_file;
# Setup the encryption system
my $crypto = Crypt::Rijndael->new( $app_secret, Crypt::Rijndael::MODE_CBC() );
unless ( open ( $passwd_file, '<', $passwd_file_name) ) {
open ( $passwd_file, '>', $passwd_file_name);
# Ask the user to enter the password the first time
#my $password = prompt "password: ", -echo => '*'; # from IO::Prompter
print "Enter the password";
my $password = <STDIN>;
my $pass_length = 16;
chomp($password);
#If password is to short we complete with blank
$password = $password." "x ($pass_length - length ( $password ) ) if ( length ( $password ) < $pass_length );
#If password is to long we cut it
$password = substr ( $password, 0, $pass_length ) if ( length ( $password ) > $pass_length );
# Encrypt the password. You can save this off into a file however you need to
my $enc_password = $crypto->encrypt($password);
open (FH, '>', $passwd_file_name);
print FH $enc_password;
close FH;
}
#Later load it from the file and decrypt it:
open (FH, '<', "$passwd_file_name");
my $data=<FH>;
close FH;
my $newpassword = $crypto->decrypt($data);
#$newpassword =~ s/\s*$//gi;
#$newpassword =~ s/^\s*//gi;
return $newpassword;
}
1;
The top level trigger script AssureJiraID.pl
cat AssureJiraID.pl
#!/usr/bin/perl -w
use strict;
use Cwd 'abs_path';
use File::Basename qw( dirname );
use lib '/export/build/p4triggers';
use Data::Dumper;
use Utilities qw(:ALL);
#Globals
my ($properties,$configFile,$P4port,$P4user,$P4cl,$P4passwd);
my $CurWD = dirname(abs_path($0));
$configFile="$CurWD/p4trigger.properties";
#Read configuration file
$properties=ReadConfig($configFile);
$P4port=$properties->{"p4port"};
$P4user=$properties->{"p4user"};
$P4passwd=$properties->{"p4passwd"};
$P4cl=$ARGV[0]; #%change%
#Check mandatory arguments
usage() unless $P4port;
usage() unless $P4cl;
usage() unless $P4user;
my $descRef=GetP4Description($P4port,$P4user,$P4cl,$P4passwd);
my $desc=$descRef->{"desc"};
#print "P4user = $P4user \n desc-orig=$desc \n";
my $getJiraIDRef=CheckJiraID($properties->{jiraProjects},$desc);
if ( $getJiraIDRef->{"found"} == 0 ) {
print "[ERROR] Jira ID not provided in description \n";
exit 1;
}
foreach my $jira_id (@{$getJiraIDRef->{"ids"}}) {
my ($fix_version,$jirauser)=ProcessJiraID($jira_id,$properties->{jiraURL},$properties->{jiraLogin},$properties->{jiraPWD});
#print "Fixversion=$fix_version \nJiraUser=$jirauser\n";
}
sub usage {
print "-----------------------------------\n";
print "[ERROR] Mandatory arguments missing\n";
print "-----------------------------------\n";
print "[SYNOPSIS] $0 P4PORT P4_CHANGELIST P4USER\n";
print "[EXAMPLE] $0 p4:1666 280459 siddesh\n";
print "-----------------------------------\n";
exit(1)
}
Configure p4 triggers with below info
p4 triggers
EnforceJiraID change-submit //depot/*****/... "/export/****/p4triggers/AssureJiraID.pl %changelist%"
Create a properties file p4trigger.properties with required information
cat p4trigger.properties
# Perforce pre-commit trigger to check jira-id configuration file
# %serverport% It comes from trigger
p4user = ****
p4port = ****:1666
p4passwd = ************************************
jiraProjects = AAAA BBBB
jiraURL = https://jira.com:8443
jiraLogin = ******
jiraPWD = /export/*****/******/****.txt
Now a perl module Utilities.pm, which consists re-usable functions.
cat Utilities.pm
package Utilities;
use strict;
use Exporter;
use Data::Dumper;
use JIRA::Client;
use P4;
use Crypt::Rijndael;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = (); #list of functions that we export by default
@EXPORT_OK = qw(ReadConfig GetP4Description CheckJiraID ProcessJiraID); #list of functions that we export on demand
%EXPORT_TAGS = ( DEFAULT => [qw(&ReadConfig)],
ALL => [qw(&ReadConfig &GetP4Description &CheckJiraID &ProcessJiraID)]);
sub ReadConfig {
my ($config) = @_;
my %userPreferences;
open(CONFIG,"$config") or die "[ERROR] Couldn't read $config: $!";
while (<CONFIG>) {
chomp; # no newline
s/#.*//; # no comments
s/^\s+//; # no leading white
s/\s+$//; # no trailing white
next unless length; # anything left ?
my ($var, $value) = split(/\s*=\s*/, $_, 2);
$userPreferences{$var}=$value;
}
return \%userPreferences;
}
sub GetP4Description {
my ($P4port,$P4user,$P4cl,$P4passwd)=@_;
my %changelistDesc;
#Establish p4 connection
my $p4 = new P4;
$p4->SetPort ( $P4port );
$p4->SetUser( $P4user );
$p4->SetPassword( $P4passwd );
$p4->Connect() or die( "Failed to connect to Perforce Server" );
#my $info = ($p4->Run("info"))[0];
#print Dumper($info);
#Get perforce description for the given changelist number
my $descCmdOut=$p4->RunDescribe( "-s", $P4cl );
#print "USER=$descCmdOut->[0]->{user}\n";
$changelistDesc{"user"}=$descCmdOut->[0]->{user};
#my $p4ChangeUser= $descCmdOut->[0]->{user};
$changelistDesc{"desc"}=$descCmdOut->[0]->{desc};
#my $desc="$descCmdOut->[0]->{desc}";
$changelistDesc{"files"}=\@{$descCmdOut->[0]->{depotFile}};
#my @files=@{$descCmdOut->[0]->{depotFile}};
return (\%changelistDesc);
}
sub CheckJiraID {
my ($jiraProjs,$desc)=@_;
my %getJiraIDs;
my (@jira_idlist,$found);
$found=0;
my @jiraProjects = split / /, $jiraProjs;
#print "desc=$desc\n";
foreach (@jiraProjects) {
my @matches = $desc =~ /($_-\d+)/gi;
push(@jira_idlist,@matches);
}
#print "@jira_idlist\n";
if(scalar(@jira_idlist) != 0)
{
$found=1;
}
$getJiraIDs{"found"}=$found;
$getJiraIDs{"ids"}=\@jira_idlist;
return(\%getJiraIDs);
}
sub ProcessJiraID {
my ($jiraID,$jiraURL,$jiraLogin,$jiraPWD)=@_;
my $jiraPasswd=&hide_passwd($jiraPWD);
$jiraPasswd =~ s/\s*$//gi;
my $jira = JIRA::Client->new("$jiraURL", "$jiraLogin", "$jiraPasswd");
my $issue = eval { $jira->getIssue("$jiraID") };
die "[ERROR] Jira ID $jiraID doesn't exist: Provide valid jira ID" if $@;
my $jiraUser=$issue->{assignee};
my $fixVer=$issue->{fixVersions}->[0]->{name};
return($fixVer,$jiraUser);
}
sub hide_passwd(){
my $app_secret = 'this_is_the_key_the_app_uses....';
my $passwd_file_name = shift;
my $passwd_file;
# Setup the encryption system
my $crypto = Crypt::Rijndael->new( $app_secret, Crypt::Rijndael::MODE_CBC() );
unless ( open ( $passwd_file, '<', $passwd_file_name) ) {
open ( $passwd_file, '>', $passwd_file_name);
# Ask the user to enter the password the first time
#my $password = prompt "password: ", -echo => '*'; # from IO::Prompter
print "Enter the password";
my $password = <STDIN>;
my $pass_length = 16;
chomp($password);
#If password is to short we complete with blank
$password = $password." "x ($pass_length - length ( $password ) ) if ( length ( $password ) < $pass_length );
#If password is to long we cut it
$password = substr ( $password, 0, $pass_length ) if ( length ( $password ) > $pass_length );
# Encrypt the password. You can save this off into a file however you need to
my $enc_password = $crypto->encrypt($password);
open (FH, '>', $passwd_file_name);
print FH $enc_password;
close FH;
}
#Later load it from the file and decrypt it:
open (FH, '<', "$passwd_file_name");
my $data=<FH>;
close FH;
my $newpassword = $crypto->decrypt($data);
#$newpassword =~ s/\s*$//gi;
#$newpassword =~ s/^\s*//gi;
return $newpassword;
}
1;
The top level trigger script AssureJiraID.pl
cat AssureJiraID.pl
#!/usr/bin/perl -w
use strict;
use Cwd 'abs_path';
use File::Basename qw( dirname );
use lib '/export/build/p4triggers';
use Data::Dumper;
use Utilities qw(:ALL);
#Globals
my ($properties,$configFile,$P4port,$P4user,$P4cl,$P4passwd);
my $CurWD = dirname(abs_path($0));
$configFile="$CurWD/p4trigger.properties";
#Read configuration file
$properties=ReadConfig($configFile);
$P4port=$properties->{"p4port"};
$P4user=$properties->{"p4user"};
$P4passwd=$properties->{"p4passwd"};
$P4cl=$ARGV[0]; #%change%
#Check mandatory arguments
usage() unless $P4port;
usage() unless $P4cl;
usage() unless $P4user;
my $descRef=GetP4Description($P4port,$P4user,$P4cl,$P4passwd);
my $desc=$descRef->{"desc"};
#print "P4user = $P4user \n desc-orig=$desc \n";
my $getJiraIDRef=CheckJiraID($properties->{jiraProjects},$desc);
if ( $getJiraIDRef->{"found"} == 0 ) {
print "[ERROR] Jira ID not provided in description \n";
exit 1;
}
foreach my $jira_id (@{$getJiraIDRef->{"ids"}}) {
my ($fix_version,$jirauser)=ProcessJiraID($jira_id,$properties->{jiraURL},$properties->{jiraLogin},$properties->{jiraPWD});
#print "Fixversion=$fix_version \nJiraUser=$jirauser\n";
}
sub usage {
print "-----------------------------------\n";
print "[ERROR] Mandatory arguments missing\n";
print "-----------------------------------\n";
print "[SYNOPSIS] $0 P4PORT P4_CHANGELIST P4USER\n";
print "[EXAMPLE] $0 p4:1666 280459 siddesh\n";
print "-----------------------------------\n";
exit(1)
}
Configure p4 triggers with below info
p4 triggers
EnforceJiraID change-submit //depot/*****/... "/export/****/p4triggers/AssureJiraID.pl %changelist%"
No comments:
Post a Comment