mirror of https://github.com/sipwise/ngcpcfg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
7.7 KiB
267 lines
7.7 KiB
#!/usr/bin/perl -CSD
|
|
# Purpose: template toolkit helper script
|
|
################################################################################
|
|
|
|
use strict;
|
|
use warnings;
|
|
use English;
|
|
use YAML::XS qw(LoadFile);
|
|
use Hash::Merge qw(merge);
|
|
use DBI;
|
|
use Capture::Tiny qw(capture);
|
|
|
|
sub sync_extra_sockets;
|
|
sub db_connect;
|
|
my $dbh;
|
|
|
|
my $config = {};
|
|
foreach my $file (@ARGV) {
|
|
$config = merge($config, LoadFile($file));
|
|
}
|
|
# rw connection to central node
|
|
my $dbhost = $config->{database}->{central}->{dbhost};
|
|
my $dbport = $config->{database}->{central}->{dbport};
|
|
|
|
open my $SWFH, '<', '/etc/mysql/sipwise.cnf';
|
|
my $dbpass = join ' ', <$SWFH>;
|
|
close $SWFH;
|
|
$dbpass =~ s/^\s*SIPWISE_DB_PASSWORD=\'([^\']+)\'.*$/$1/;
|
|
chomp $dbpass;
|
|
my $dbuser = 'sipwise';
|
|
my $dbname = $config->{ossbss}->{provisioning}->{database}->{name};
|
|
|
|
unless(defined $dbhost) {
|
|
print "Error: Could not determine provisioning db hostname\n";
|
|
exit 1;
|
|
}
|
|
unless(defined $dbport) {
|
|
print "Error: Could not determine provisioning db port\n";
|
|
exit 1;
|
|
}
|
|
unless(defined $dbname) {
|
|
print "Error: Could not determine provisioning db name\n";
|
|
exit 1;
|
|
}
|
|
unless(defined $dbuser) {
|
|
print "Error: Could not determine provisioning db user\n";
|
|
exit 1;
|
|
}
|
|
unless(defined $dbpass) {
|
|
print "Error: Could not determine provisioning db password\n";
|
|
exit 1;
|
|
}
|
|
|
|
$dbh = db_connect();
|
|
|
|
exit 1 unless(sync_extra_sockets($dbh,
|
|
$config->{kamailio}->{lb}->{extra_sockets},
|
|
1, 1, 1));
|
|
|
|
exit 1 unless(sync_rtp_interfaces($dbh,
|
|
{ map {my $tmp = $_; $tmp =~ s/:.*//; ($_ => $_, $tmp => $tmp)} @{$config->{rtp_interfaces}} },
|
|
1, 1, 1));
|
|
|
|
exit 1 unless(sync_smsc_peers($dbh,
|
|
{ map { ($_->{id} => $_->{id}) } @{$config->{sms}->{smsc}} },
|
|
0, 1, 0));
|
|
|
|
exit 1 unless(sync_general_timezone($dbh,
|
|
$config->{general}->{timezone}));
|
|
|
|
exit 1 unless(sync_db_timezones($dbh));
|
|
|
|
$dbh->disconnect;
|
|
|
|
exit 0;
|
|
|
|
sub db_connect
|
|
{
|
|
my $dbh = DBI->connect("DBI:mysql:database=${dbname};host=${dbhost};port=${dbport}",
|
|
$dbuser, $dbpass, { PrintError => 1 });
|
|
unless(defined $dbh) {
|
|
print "Error: Could not connect to database '$dbname' at '$dbhost:$dbport' as '${dbuser}': $DBI::errstr\n";
|
|
exit 1;
|
|
}
|
|
return $dbh;
|
|
}
|
|
|
|
sub generic_enum_sync {
|
|
my $dbh = shift;
|
|
my $config_hash = shift;
|
|
my $usr_pref = shift;
|
|
my $dom_pref = shift;
|
|
my $peer_pref = shift;
|
|
my $pref_name = shift;
|
|
my $sth = $dbh->prepare("select id from voip_preferences where attribute=?");
|
|
$sth->execute($pref_name);
|
|
my $res = $sth->fetchrow_hashref();
|
|
unless(defined $res) {
|
|
print "Error: Could not find preference '$pref_name' in db\n";
|
|
return;
|
|
}
|
|
my $pref_id = $res->{id};
|
|
$sth->finish;
|
|
|
|
my $enum_insert_sth = $dbh->prepare("insert into voip_preferences_enum (preference_id, label, value, usr_pref, dom_pref, peer_pref) values(?, ?, ?, ?, ?, ?)");
|
|
my $enum_update_sth = $dbh->prepare("update voip_preferences_enum set value=? where id=?");
|
|
my $enum_delete_sth = $dbh->prepare("delete from voip_preferences_enum where id=?");
|
|
$sth = $dbh->prepare("select id, label, value from voip_preferences_enum where preference_id=?");
|
|
$sth->execute($pref_id);
|
|
|
|
my $db_hash = $sth->fetchall_hashref('label');
|
|
$sth->finish;
|
|
|
|
foreach my $row (keys %{$db_hash}) {
|
|
$row = $db_hash->{$row};
|
|
next if($row->{label} eq 'default');
|
|
if(!exists $config_hash->{$row->{label}}) {
|
|
print "$pref_name $row->{label} does not exist anymore in config, delete from db\n";
|
|
$enum_delete_sth->execute($row->{id});
|
|
} elsif($config_hash->{$row->{label}} ne $row->{value}) {
|
|
print "update $pref_name $row->{label}=$row->{value} to $row->{label}=$config_hash->{$row->{label}} in db\n";
|
|
$enum_update_sth->execute($config_hash->{$row->{label}}, $row->{id});
|
|
delete $config_hash->{$row->{label}};
|
|
} else {
|
|
print "$pref_name $row->{label}=$row->{value} is sync between config and db\n";
|
|
delete $config_hash->{$row->{label}};
|
|
}
|
|
}
|
|
foreach my $label(keys %{$config_hash}) {
|
|
print "insert new $pref_name $label=$config_hash->{$label} from config into db\n";
|
|
$enum_insert_sth->execute($pref_id, $label, $config_hash->{$label},
|
|
$usr_pref ? 1 : 0, $dom_pref ? 1 : 0, $peer_pref ? 1: 0);
|
|
}
|
|
|
|
$enum_insert_sth->finish;
|
|
$enum_update_sth->finish;
|
|
$enum_delete_sth->finish;
|
|
return 1;
|
|
}
|
|
|
|
## kamailio.lb.extra_sockets handling: ##############################
|
|
sub sync_extra_sockets {
|
|
return generic_enum_sync(@_, 'outbound_socket');
|
|
}
|
|
|
|
## rtp_* interfaces handling: ##############################
|
|
sub sync_rtp_interfaces {
|
|
return generic_enum_sync(@_, 'rtp_interface');
|
|
}
|
|
#
|
|
## smsc_* interfaces handling: ##############################
|
|
sub sync_smsc_peers {
|
|
return generic_enum_sync(@_, 'smsc_peer');
|
|
}
|
|
|
|
## general.timezone handling: ##############################
|
|
sub sync_general_timezone {
|
|
my $dbh = shift;
|
|
my $tz = shift;
|
|
my $ok = 1;
|
|
my $pe = $dbh->{PrintError};
|
|
my ($sql_log_bin) = $dbh->selectrow_array('SELECT @@sql_log_bin');
|
|
|
|
eval {
|
|
die "Error: general.timezone value is not set\n" unless $tz;
|
|
|
|
$dbh->do("SET sql_log_bin=0");
|
|
$dbh->{PrintError} = 0;
|
|
|
|
my ($current_tz) = $dbh->selectrow_array(<<SQL);
|
|
SELECT name FROM ngcp.timezone
|
|
SQL
|
|
if ($DBI::err) {
|
|
die "Error: Could not select from ngcp.timezone: $DBI::errstr\n";
|
|
}
|
|
|
|
return $ok if $current_tz && $current_tz eq $tz;
|
|
|
|
$dbh->do(<<SQL, undef, $tz, $tz);
|
|
INSERT INTO ngcp.timezone SET name = ?
|
|
ON DUPLICATE KEY UPDATE name = ?, modified_at = CURRENT_TIMESTAMP
|
|
SQL
|
|
if ($DBI::err) {
|
|
die "Error: Could not insert into ngcp.timezone: $DBI::errstr\n";
|
|
}
|
|
};
|
|
if ($@) {
|
|
print $@;
|
|
$ok = 0;
|
|
}
|
|
$dbh->{PrintError} = $pe;
|
|
$dbh->do("SET sql_log_bin=$sql_log_bin");
|
|
|
|
return $ok;
|
|
}
|
|
|
|
## /usr/share/zoneinfo into MariaDB ##############################
|
|
sub sync_db_timezones {
|
|
my $dbh = shift;
|
|
|
|
my ($out, $err, $rc) = capture {
|
|
system('/usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo');
|
|
};
|
|
|
|
if ($rc) {
|
|
print "Error: $err\n";
|
|
return;
|
|
}
|
|
|
|
my ($tzinfo_version, undef, undef) = capture {
|
|
system('dpkg -s tzdata | grep Version:');
|
|
};
|
|
|
|
unless ($tzinfo_version && $tzinfo_version =~ /Version:\s*(\S+)/) {
|
|
print "Error: Could not retrieve tzdata package version\n";
|
|
return;
|
|
}
|
|
$tzinfo_version = $1;
|
|
|
|
my $pe = $dbh->{PrintError};
|
|
$dbh->{PrintError} = 0;
|
|
my $sql = '';
|
|
my $p_rs = $RS;
|
|
eval {
|
|
$dbh->begin_work() or die "Cannot start tx: ".$DBI::errstr;
|
|
my ($cur_tzinfo_version) = $dbh->selectrow_array(<<SQL)
|
|
SELECT version
|
|
FROM ngcp.tzinfo_version
|
|
SQL
|
|
or die "Cannot select from ngcp.tzinfo_version: $DBI::errstr\n";
|
|
if ($cur_tzinfo_version eq $tzinfo_version) {
|
|
return;
|
|
}
|
|
open(my $sql_stream, "<", \$out)
|
|
or die "Cannot open sql stream: $ERRNO\n";
|
|
binmode($sql_stream);
|
|
local $RS = ";\n";
|
|
$dbh->do('USE mysql')
|
|
or die "Cannot use mysql database: $DBI::errstr\n";
|
|
while ($sql = <$sql_stream>) {
|
|
map {
|
|
$dbh->do($_) or die "Cannot insert timezone data: $DBI::errstr\n";
|
|
} split /;\s+/, $sql; # multiple one line statements
|
|
}
|
|
close $sql_stream;
|
|
$dbh->do(<<SQL, undef, $tzinfo_version, $tzinfo_version)
|
|
INSERT INTO ngcp.tzinfo_version SET version = ?
|
|
ON DUPLICATE KEY UPDATE version = ?, modified_at = CURRENT_TIMESTAMP
|
|
SQL
|
|
or die "Cannot insert into ngcp.tzinfo_version: $DBI::errstr\n";
|
|
};
|
|
local $RS = $p_rs;
|
|
$err = $EVAL_ERROR;
|
|
$dbh->{PrintError} = $pe;
|
|
if ($err) {
|
|
print $err,"sql: $sql\n";
|
|
$dbh->rollback();
|
|
return;
|
|
}
|
|
$dbh->commit();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
## END OF FILE #################################################################
|