File vicidial-serverscrub of Package vicibox-install
#!/usr/bin/perl
#
# vicidial-serverscrub.pl - Scrubs the vicidial database for removed servers
#
# Copyright (C) 2012 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
#
# CHANGES
# All my lovely little modules
use warnings;
use DBI;
# Globals
$PATHconf = "/etc/astguiclient.conf";
$DEBUG=0;
$DEBUGX=0;
$TEST=0;
$dbuser='cron';
$dbpass='1234';
$dbport=3306;
$dbname='asterisk';
$dbhost='localhost';
my $clidbpass=0;
my $clidbuser=0;
my $clidbhost=0;
my $clidbport=0;
my $clidbname=0;
my $someinput; # Keep this specific to main since it's my little trash variable
my $myprompt; # Another trash variable used for user input
print "\n\nViciDial Server Scrub\n\n";
# Parse our run-times, cleaned up from matt-matt code so the rest of us can read it
$args = "";
if ( defined $ARGV[0] && length($ARGV[0])>1) {
$i=0;
while ($#ARGV >= $i) {
$args = "$args $ARGV[$i]";
$i++;
}
if ($args =~ /--help/i) {
print "allowed run time options:\n";
print " [--dbhost=HOSTNAME] = Manually specify the database hostname or IP to use\n";
print " [--dbname=DBNAME] = Manually specify the database name to use\n";
print " [--dbuser=USERNAME] = Manually specify the database username to use\n";
print " [--dbpass=PASSWORD] = Manually specify the database password to use\n";
print " [--dbport=PORT] = Manually specify the database port to use\n";
print " [--test] = Test Run Only, no commits\n";
print " [--debug] = debug\n";
print " [--debugX] = debug extended\n\n";
exit;
} else {
# Check for debug flag
if ($args =~ /--debug/i) {
$DEBUG=1;
print "\n----- DEBUG Enabled -----\n\n";
}
# Check for debug extended flag
if ($args =~ /--debugX/i) {
$DEBUG=1;
$DEBUGX=1;
print "----- DEBUG Extended Enabled -----\n\n";
}
# Run a test run without commits, kind of needs at least debug to make sense
if ($args =~ /--test/i) {
$TEST=1;
print "\n----- Test Run Enabled -----\n\n";
}
# DB Host
if ($args =~ /--dbhost=/i) {
@CLIlocaldbhostARY = split(/--dbhost=/,$args);
@CLIlocaldbhostARX = split(/ /,$CLIlocaldbhostARY[1]);
if (length($CLIlocaldbhostARX[0])>2) {
$dbhost = $CLIlocaldbhostARX[0];
$dbhost =~ s/\/$| |\r|\n|\t//gi;
debugoutput(" CLI DB hostname : $dbhost",0);
$clidbhost=1;
}
}
# DB user
if ($args =~ /--dbuser=/i) {
@CLIlocaldbuserARY = split(/--dbuser=/,$args);
@CLIlocaldbuserARX = split(/ /,$CLIlocaldbuserARY[1]);
if (length($CLIlocaldbuserARX[0])>2) {
$dbuser = $CLIlocaldbuserARX[0];
$dbuser =~ s/\/$| |\r|\n|\t//gi;
debugoutput(" CLI DB username : $dbuser",0);
$clidbuser=1;
}
}
# DB Pass
if ($args =~ /--dbpass=/i) {
@CLIlocaldbpassARY = split(/--dbpass=/,$args);
@CLIlocaldbpassARX = split(/ /,$CLIlocaldbpassARY[1]);
if (length($CLIlocaldbpassARX[0])>2) {
$dbpass = $CLIlocaldbpassARX[0];
$dbpass =~ s/\/$| |\r|\n|\t//gi;
debugoutput(" CLI DB password : $dbpass",0);
$clidbpass=1;
}
}
# DB port
if ($args =~ /--dbport=/i) {
@CLIlocaldbportARY = split(/--dbport=/,$args);
@CLIlocaldbportARX = split(/ /,$CLIlocaldbportARY[1]);
if (length($CLIlocaldbportARX[0])>2) {
$dbport = $CLIlocaldbportARX[0];
$dbport =~ s/\/$| |\r|\n|\t//gi;
debugoutput(" CLI DB port : $dbport",0);
$clidbport=1;
}
}
# DB name
if ($args =~ /--dbname=/i) {
@CLIlocaldbnameARY = split(/--dbname=/,$args);
@CLIlocaldbnameARX = split(/ /,$CLIlocaldbnameARY[1]);
if (length($CLIlocaldbnameARX[0])>2) {
$dbname = $CLIlocaldbnameARX[0];
$dbname =~ s/\/$| |\r|\n|\t//gi;
debugoutput(" CLI DB name : $dbname",0);
$clidbname=1;
}
}
}
}
# Parse the config file if it's present, command line args get precedence
if ( -e $PATHconf ) {
open(CONF, "$PATHconf");
@conf = <CONF>;
close(CONF);
$i=0;
foreach(@conf)
{
$line = $conf[$i];
$line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi;
if ( ($line =~ /^VARDB_server/) && ($clidbhost < 1) )
{$dbhost = $line; $dbhost =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_user/) && ($clidbuser < 1) )
{$dbuser = $line; $dbuser =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_pass/) && ($clidbpass < 1) )
{$dbpass = $line; $dbpass =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_port/) && ($clidbport < 1) )
{$dbport = $line; $dbport =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_database/) && ($clidbname < 1) )
{$dbname = $line; $dbname =~ s/.*=//gi;}
$i++;
}
}
# Give run-time output if we don't have a CLI entered value here
if ($clidbhost==0) { print " ViciDial DB hostname : $dbhost\n"; }
if ($clidbuser==0) { print " ViciDial DB username : $dbuser\n"; }
if ($clidbpass==0) { print " ViciDial DB password : $dbpass\n"; }
if ($clidbport==0) { print " ViciDial DB port : $dbport\n"; }
if ($clidbname==0) { print " ViciDial DB name : $dbname\n"; }
print "\n";
sub debugoutput {
# I got tired of repeating this code snippet, so this gives debug output, with optional critical die
my $debugline = shift;
my $debugdie = 0;
$debugdie = shift;
if ($DEBUG==1 and $debugdie==0) {
# We are just giving output, nothing more
print "$debugline\n";
} elsif ($DEBUG==1 and $debugdie==1) {
# Evidently it was a critical error, so we die on output
die("$debugline\n");
}
}
sub debugxoutput {
# I got tired of repeating this code snippet, so this gives debug output, with optional critical die
my $debugline = shift;
my $debugdie = 0;
$debugdie = shift;
if ($DEBUGX==1 and $debugdie==0) {
# We are just giving output, nothing more
print "$debugline\n";
} elsif ($DEBUGX==1 and $debugdie==1) {
# Evidently it was a critical error, so we die on output
die("$debugline\n");
}
}
# Connect to vicidial database
$dbhVD = DBI->connect("DBI:mysql:$dbname:$dbhost:$dbport", "$dbuser", "$dbpass") or die "Couldn't connect to database: " . DBI->errstr;
# Get list of servers in the cluster
$stmtSRVcheck = "select server_ip from servers;";
$sthSRVcheck = $dbhVD->prepare($stmtSRVcheck) or die "Preparing stmtSRVcheck: ",$dbhVD->errstr;
$sthSRVcheck->execute or die "Executing sthSRVcheck: ",$dbhVD->errstr;
$i=0;
while (@arySRVCheck=$sthSRVcheck->fetchrow_array()) {
print "Found server $arySRVCheck[0];\n";
if ($i==0) { $serverSQLstring="('$arySRVCheck[0]'"; } else { $serverSQLstring=$serverSQLstring . ",'$arySRVCheck[0]'"; }
$i++;
}
print "--Found $i valid servers\n";
$sthSRVcheck->finish;
$serverSQLstring=$serverSQLstring . ", '0.0.0.0')";
debugoutput("Server String: $serverSQLstring",0);
# wipe out conferences that aren't in our server list
$stmtCONFdelete = "delete from conferences where server_ip not in $serverSQLstring;";
debugxoutput("Conference delete SQL: $stmtCONFdelete",0);
if ($TEST==0) {
$sthCONFdelete = $dbhVD->prepare($stmtCONFdelete) or die "Preparing stmtCONFdelete: ",$dbhVD->errstr;
$sthCONFdelete->execute or die "Executing sthCONFdelete: ",$dbhVD->errstr;
print "\nDeleted " . $sthCONFdelete->rows . " conference entries\n";
$sthCONFdelete->finish;
}
# wipe out vicidial conferences too
$stmtVDCONFdelete = "delete from vicidial_conferences where server_ip not in $serverSQLstring;";
debugxoutput("VD Conference delete SQL: $stmtVDCONFdelete",0);
if ($TEST==0) {
$sthVDCONFdelete = $dbhVD->prepare($stmtVDCONFdelete) or die "Preparing stmtVDCONFdelete: ",$dbhVD->errstr;
$sthVDCONFdelete->execute or die "Executing sthVDCONFdelete: ",$dbhVD->errstr;
print "Deleted " . $sthVDCONFdelete->rows . " ViciDial conference entries\n";
$sthVDCONFdelete->finish;
}
# Clear remote agent entries without a server
$stmtREMOTEdelete = "delete from vicidial_remote_agents where server_ip not in $serverSQLstring;";
debugxoutput("Remove Agent delete SQL: $stmtREMOTEdelete",0);
if ($TEST==0) {
$sthREMOTEdelete = $dbhVD->prepare($stmtREMOTEdelete) or die "Preparing stmtREMOTEdelete: ",$dbhVD->errstr;
$sthREMOTEdelete->execute or die "Executing sthREMOTEdelete: ",$dbhVD->errstr;
print "Deleted " . $sthREMOTEdelete->rows . " remote agent entries\n";
$sthREMOTEdelete->finish;
}
# Clear carrier entries without a server
$stmtCARRIERdelete = "delete from vicidial_server_carriers where server_ip not in $serverSQLstring;";
debugxoutput("Carrier delete SQL: $stmtCARRIERdelete",0);
if ($TEST==0) {
$sthCARRIERdelete = $dbhVD->prepare($stmtCARRIERdelete) or die "Preparing stmtCARRIERdelete: ",$dbhVD->errstr;
$sthCARRIERdelete->execute or die "Executing sthCARRIERdelete: ",$dbhVD->errstr;
print "Deleted " . $sthCARRIERdelete->rows . " carrier entries\n";
$sthCARRIERdelete->finish;
}
# Clear phone entries without a server
$stmtPHONEdelete = "delete from phones where server_ip not in $serverSQLstring;";
debugxoutput("Phone delete SQL: $stmtPHONEdelete",0);
if ($TEST==0) {
$sthPHONEdelete = $dbhVD->prepare($stmtPHONEdelete) or die "Preparing stmtPHONEdelete: ",$dbhVD->errstr;
$sthPHONEdelete->execute or die "Executing sthPHONEdelete: ",$dbhVD->errstr;
print "Deleted " . $sthPHONEdelete->rows . " phone entries\n";
$sthPHONEdelete->finish;
}
# Create a hash of all valid phone entries
$stmtPHONEactive = "select distinct login from phones;";
$sthPHONEactive = $dbhVD->prepare($stmtPHONEactive) or die "Preparing stmtPHONEactive: ",$dbhVD->errstr;
$sthPHONEactive->execute or die "Executing sthPHONEactive: ",$dbhVD->errstr;
while (@aryPHONEactive=$sthPHONEactive->fetchrow_array()) { $hshPHONEactive{$aryPHONEactive[0]}=1; }
print "-- Found " . $sthPHONEactive->rows . " active phones to check against aliases\n";
$sthPHONEactive->finish;
# Get the list of phone alises and process them
$stmtALIASlist = "select alias_id, logins_list from phones_alias;";
$sthALIASlist = $dbhVD->prepare($stmtALIASlist) or die "Preparing stmtALIASlist: ",$dbhVD->errstr;
$sthALIASlist->execute or die "Executing sthALIASlist: ",$dbhVD->errstr;
print "-- Found " . $sthALIASlist->rows . " phone aliases to process\n";
# Loop through each alias and see if it is valid or needs adjusting
while (@aryALIASlist=$sthALIASlist->fetchrow_array()) {
$alias_id=$aryALIASlist[0];
$orig_logins_list=$aryALIASlist[1];
$new_logins_list='';
$alias_update=0; # Flag to update alias, assuming it is valid
$alias_valid=0; # If not set to 1 then alias contains no valid phone entries, so delete
# Split the logins for the alias into individual phones and check against the phone hash
@aryLOGINlist=split(',',$orig_logins_list);
$numLOGINlist=@aryLOGINlist;
$numLOGINlist--;
debugoutput("------Number of logins for alias ID $alias_id - $numLOGINlist",0);
$j=0;
for my $i (0 .. $numLOGINlist) {
$tmpPHONE = $aryLOGINlist[$i];
if (exists $hshPHONEactive{$tmpPHONE}) {
# Found the phone entry, add it to the new login list
$alias_valid=1;
if ($j==0) { $new_logins_list="$aryLOGINlist[$i]"; $j++; } else { $new_logins_list.=",$aryLOGINlist[$i]"; $j++; }
}
}
# Give output for what just happened, and check flags for update
if ($alias_valid==1) {
if (length($orig_logins_list) == length($new_logins_list)) {
print "----Alias ID $alias_id processed, No update needed - $new_logins_list\n";
} else {
print "----Alias ID $alias_id processed, update needed - $new_logins_list\n";
$alias_update=1;
}
}
# generate any relevant SQL if needed
if ($alias_valid==1 && $alias_update==1) {
# Update the DB
$stmtALIASupd = "update phones_alias set logins_list='$new_logins_list' where alias_id='$alias_id';";
debugoutput("Alias update SQL: $stmtALIASupd",0);
if ($TEST==0) {
$sthALIASupd = $dbhVD->prepare($stmtALIASupd) or die "Preparing stmtALIASupd: ",$dbhVD->errstr;
$sthALIASupd->execute or die "Executing sthALIASupd: ",$dbhVD->errstr;
$sthALIASupd->finish;
}
} elsif ($alias_valid==0) {
# It's a non-valid alias, so delete it
$stmtALIASdel = "delete from phones_alias where alias_id='$alias_id';";
debugoutput("Alias delete SQL: $stmtALIASdel",0);
if ($TEST==0) {
$sthALIASdel = $dbhVD->prepare($stmtALIASdel) or die "Preparing stmtALIASdel: ",$dbhVD->errstr;
$sthALIASdel->execute or die "Executing sthALIASdel: ",$dbhVD->errstr;
$sthALIASdel->finish;
}
}
}