From 3b030ceb896cb743fb2c33fdd872c621f21af33e Mon Sep 17 00:00:00 2001
From: Richard Fuchs <rfuchs@sipwise.com>
Date: Fri, 23 Jan 2015 09:53:09 -0500
Subject: [PATCH] MT#10059 support configurable rtp interfaces

adds get_all_rtp_for_host helper script

update sync-db to process rtp_interface preference

Squashed commit of the following:

commit f2be1ea221cd9da2e4d400bcfcac4baf914563db
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Thu Jan 22 11:59:27 2015 -0500

    implement db syncing for rtp_interface enum prefs

commit 584f52c6b0094c2ca01641cdac898436f3efce86
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Thu Jan 22 10:32:08 2015 -0500

    change name of generated.yml

commit b980dff6a106256264c81ae1bf74aba20bf32383
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Wed Jan 21 12:46:07 2015 -0500

    MT#10059 make sync-db load generated yml

commit 92d17d8c1895f4b04663a3e485be80402382522d
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Wed Jan 21 12:32:58 2015 -0500

    fix comment syntax error

commit af8500dc315b6c142250ab0119179cb1adc67e8c
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Wed Jan 21 12:04:25 2015 -0500

    MT#10059 support undefined hostname

commit 84b8a91de59ad8ae8ad944a784850e8ac08d94fe
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Wed Jan 21 11:57:16 2015 -0500

    MT#10059 support plain list output format

commit 2b9ec081c27842dc6839218f4e5c22b761d38550
Author: Richard Fuchs <rfuchs@sipwise.com>
Date:   Wed Jan 21 11:38:04 2015 -0500

    MT#10059 adding get_all_rtp_for_host helper
---
 etc/ngcp-config/ngcpcfg.cfg |  1 +
 helper/sync-db              | 48 ++++++++++++++++++-----------
 lib/get_all_rtp_for_host    | 60 +++++++++++++++++++++++++++++++++++++
 scripts/commit              |  2 +-
 4 files changed, 92 insertions(+), 19 deletions(-)
 create mode 100644 lib/get_all_rtp_for_host

diff --git a/etc/ngcp-config/ngcpcfg.cfg b/etc/ngcp-config/ngcpcfg.cfg
index a8a8add2..ec48b863 100644
--- a/etc/ngcp-config/ngcpcfg.cfg
+++ b/etc/ngcp-config/ngcpcfg.cfg
@@ -9,6 +9,7 @@ HOST_CONFIG="${NGCPCTL_MAIN}/config.$(hostname).yml"
 LOCAL_CONFIG="${NGCPCTL_MAIN}/config.local.yml"
 CONSTANTS_CONFIG="${NGCPCTL_MAIN}/constants.yml"
 NETWORK_CONFIG="${NGCPCTL_MAIN}/network.yml"
+GENERATED_CONFIG="${NGCPCTL_MAIN}/generated.yml"
 EXTRA_CONFIG_DIR="${NGCPCTL_MAIN}/config.d/"
 
 # configuration dirs that should be managed
diff --git a/helper/sync-db b/helper/sync-db
index 295f1050..fe3a0d09 100755
--- a/helper/sync-db
+++ b/helper/sync-db
@@ -58,6 +58,9 @@ $dbh = db_connect();
 exit 1 unless(sync_extra_sockets($dbh,
   $config->{kamailio}->{lb}->{extra_sockets}));
 
+exit 1 unless(sync_rtp_interfaces($dbh,
+  { map {$_, $_} @{$config->{rtp_interfaces}} } ));
+
 $dbh->disconnect;
 
 # this part sync with kamailio db
@@ -96,11 +99,10 @@ sub db_connect
 	return $dbh;
 }
 
-## kamailio.lb.extra_sockets handling: ##############################
-sub sync_extra_sockets {
+sub generic_enum_sync {
 	my $dbh = shift;
-	my $sockets = shift;
-	my $pref_name = 'outbound_socket';
+	my $config_hash = 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();
@@ -117,27 +119,27 @@ sub sync_extra_sockets {
 	$sth = $dbh->prepare("select id, label, value from voip_preferences_enum where preference_id=?");
 	$sth->execute($pref_id);
 
-	my $dbsockets = $sth->fetchall_hashref('label');
+	my $db_hash = $sth->fetchall_hashref('label');
 	$sth->finish;
 
-	foreach my $row (keys %{$dbsockets}) {
-	  $row = $dbsockets->{$row};
+	foreach my $row (keys %{$db_hash}) {
+	  $row = $db_hash->{$row};
 	  next if($row->{label} eq 'default');
-	  if(!exists $sockets->{$row->{label}}) {
-	    print "socket $row->{label} does not exist anymore in config, delete from db\n";
+	  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($sockets->{$row->{label}} ne $row->{value}) {
-	    print "update $row->{label}=$row->{value} to $row->{label}=$sockets->{$row->{label}} in db\n";
-	    $enum_update_sth->execute($sockets->{$row->{label}}, $row->{id});
-	    delete $sockets->{$row->{label}};
+	  } 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 "socket $row->{label}=$row->{value} is sync between config and db\n";
-	    delete $sockets->{$row->{label}};
+	    print "$pref_name $row->{label}=$row->{value} is sync between config and db\n";
+	    delete $config_hash->{$row->{label}};
 	  }
 	}
-	foreach my $sock(keys %{$sockets}) {
-	  print "insert new socket $sock=$sockets->{$sock} from config into db\n";
-	  $enum_insert_sth->execute($pref_id, $sock, $sockets->{$sock});
+	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});
 	}
 
 	$enum_insert_sth->finish;
@@ -146,6 +148,16 @@ sub sync_extra_sockets {
 	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');
+}
+
 ## faxserver.hw_fax_gateways handling: ##############################
 sub sync_faxserver_uris {
 	my $dbh = shift;
diff --git a/lib/get_all_rtp_for_host b/lib/get_all_rtp_for_host
new file mode 100644
index 00000000..754c618f
--- /dev/null
+++ b/lib/get_all_rtp_for_host
@@ -0,0 +1,60 @@
+[%
+
+  # Returns a list of RTP-enabled interfaces for rtpengine
+  #
+  # @param argv.host	The host to get interfaces for. If blank, helper
+  #			script will be called.
+  # @param argv.format	"list" for plain list of interfaces, blank or
+  #			"rtpengine" for full CLI options
+  # @return out		The array of interfaces
+
+X_host = argv.host;
+X_format = argv.format;
+
+IF ! X_host.defined;
+	PROCESS '/usr/lib/ngcp-ngcpcfg/get_hostname'
+	X_host = out;
+END;
+
+IF ! X_format.defined || X_format == '';
+	X_format = 'rtpengine';
+END;
+
+IF ! hosts.$X_host.defined;
+	X_host = 'self';
+END;
+
+out = [];
+
+FOREACH X_iface IN hosts.$X_host.interfaces;
+	X_ifc = hosts.$X_host.$X_iface;
+	X_types = X_ifc.type.grep('^rtp_.');
+	IF X_types.size();
+		X_type = X_types.0;
+		X_type = X_type.remove('^rtp_');
+
+		IF X_format == 'list';
+			out.push(X_type);
+			NEXT;
+		END;
+
+		X_ips = X_ifc.shared_ip.list;
+		IF !X_ips.size() || !X_ips.0.defined;
+			X_ips = X_ifc.ip;
+		END;
+		X_adv_ips = X_ifc.advertised_ip.list;
+		FOREACH X_ip IN X_ips;
+			X_adv_ip = X_adv_ips.shift();
+			out.push(X_type _ '/' _ X_ip _ (X_adv_ip ? ('!' _ X_adv_ip) : ''));
+		END;
+
+		X_ips = X_ifc.shared_v6ip.list;
+		IF !X_ips.size() || !X_ips.0.defined;
+			X_ips = X_ifc.v6ip;
+		END;
+		FOREACH X_ip IN X_ips;
+			out.push(X_type _ '/' _ X_ip);
+		END;
+	END;
+END
+-%]
diff --git a/scripts/commit b/scripts/commit
index aa6affe9..1fb4598c 100755
--- a/scripts/commit
+++ b/scripts/commit
@@ -18,7 +18,7 @@ HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
 cd "$NGCPCTL_MAIN"
 
 if [ -z "${NO_DB_SYNC:-}" ] ; then
-    "${HELPER}/sync-db" "$NGCPCTL_CONFIG" "$CONSTANTS_CONFIG" || true
+    "${HELPER}/sync-db" "$NGCPCTL_CONFIG" "$CONSTANTS_CONFIG" "$GENERATED_CONFIG" || true
 else
     log_debug "no-db-sync: skipping 'sync-db'"
 fi