Skip to content

Instantly share code, notes, and snippets.

@ruhnet
Last active April 27, 2024 19:23
Show Gist options
  • Save ruhnet/9993b26b305c368dda8b6d8b16ca48a6 to your computer and use it in GitHub Desktop.
Save ruhnet/9993b26b305c368dda8b6d8b16ca48a6 to your computer and use it in GitHub Desktop.
2600Hz Kazoo 4.3 Notes

RuhNet: 2600Hz Kazoo Notes

Cluster Topology Possibilities

Any service can be separated and run on its own server. Commonly used config:

  • Kazoo Servers: HAProxy, RabbitMQ, Kamailio SIP Proxy, Kazoo eCall Manager, Kazoo Applications, (Monster UI)
  • Freeswitch Servers: HAProxy, Freeswitch
  • Bigcouch Database Servers: Bigcouch or CouchDB (I use CouchDB v3.0)

Single Zone Cluster

# Zone1 (SINGLE ZONE)
8 Kazoo/Kam/RaMQ/HAP         Freeswitch/HAP Kazoo/Kam/RaMQ/HAP   Freeswitch/HAP Couch Couch Couch RaMQ
7 Kazoo/Kam/RaMQ/HAP Freeswitch/RaMQ/HAP Kazoo/Kam/RaMQ/HAP Freeswitch/HAP Couch Couch Couch
5 Kazoo/Kam/FS/RaMQ/HAP - Kazoo/Kam/FS/RaMQ/HAP - Couch Couch Couch
4 Kazoo/Kam/RaMQ/HAP/Couch Freeswitch/HAP/Couch Kazoo/Kam/HAP/Couch FS/HAP/Couch - - -
3 Kazoo/Kam/RaMQ Freeswitch - - Couch - -
1 Kazoo/Kam/FS/RaMQ/HAP/Couch - - - - - -

Multi Zone Cluster

# Zone1 (Multi Zone) Zone1 Z1 Z1 Z1 Zone2 Z2 Z2 Z2 Z2 DB
3 Kazoo/Kam/FS/RaMQ/HAP/Couch - - - - - Kazoo/Kam/FS/RaMQ/HAP/Couch - - - - - Couch
7 Kazoo/Kam/RaMQ/HAProxy Freeswitch/HAP - - - Kazoo/Kam/RaMQ/HAP FS/HAP - - - Couch Couch Couch
11 Kazoo/Kam/RaMQ/HAProxy Kazoo/Kam/RaMQ/HAP FS/HAP/RaMQ FS/HAP Kazoo/Kam/RaMQ/HAP Kazoo/Kam/RaMQ/HAP FS/HAP/RaMQ FS/HAP Couch Couch Couch
13 Kazoo/Kam/RaMQ/HAProxy Kazoo/Kam/RaMQ/HAP RaMQ FS/HAP FS/HAP Kazoo/Kam/RaMQ/HAP Kazoo/Kam/RaMQ/HAP RaMQ FS/HAP FS/HAP Couch Couch Couch

Config

All Servers

Install some things (some of these are my personal preference):

yum update && yum install epel-release
yum remove sendmail samba
yum install mosh screen postfix firewalld git deltarpm vim htop curl wget dnsutils zip unzip net-tools bind-utils psmisc yum-utils ntp zip unzip htmldoc sox ilbc jq
systemctl enable postfix

Firewall

(Firewall may not be installed on some minimal CentOS installations

systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=mosh  # Optional (but you do use mosh, right???)
firewall-cmd --reload

Enable NTP to synchronize clock

systemctl enable ntpd

Set timezone to UTC (Kazoo wants it this way)

timedatectl set-timezone UTC

Fix /etc/hosts file

export IP_ADDR=111.111.111.111
export _HOSTNAME=hawk.mydomain.net
export _HOST=hawk

echo "127.0.0.1 localhost.localdomain localhost" > /etc/hosts
echo "::1 localhost.localdomain localhost" >> /etc/hosts
echo "$IP_ADDR $_HOSTNAME $_HOST" >> /etc/hosts
chattr +i /etc/hosts

CouchDB [Cluster] Installation (v3)

Follow official docs for initial installation. You are not required to use CentOS for Couch---it will run fine on Debian or other distros, and does not require config specific to 2600Hz.

Setup admin user

Couch v3 and above require an admin user to be setup BEFORE couch will start successfully Edit /opt/couchdb/etc/local.ini or /opt/couchdb/etc/local.d/10-admins.ini:

[admins]
admin = pa$$w0rd

Couch will hash the password here upon restart

Listen on all IP addresses, not just localhost

Edit /opt/couchdb/etc/local.ini or /opt/couchdb/etc/local.d/10-bind-address.ini:

[chttpd]
bind_address = 0.0.0.0

Set CouchDB node name

Edit /opt/couchdb/etc/vm.args: Set FQDN: -name couchdb@db1.mydomain.net

You can do something like this if you like (but double check the file in case of default config format changes):

sed -i 's/name couchdb@127.0.0.1/name couchdb@db3.mydomain.net/g' /opt/couchdb/etc/vm.args

Set cookie (for intra-cluster communication):

Edit /opt/couchdb/etc/vm.args: -setcookie xcBRstw-5XoMLrmKEGf_N2SnMZ NOTE use your own cookie string, NOT this one.

You can do something like this if you like (again, double check the file in case of default config format changes):

sed -i 's/setcookie monster/setcookie xcBRstw-5XoMLrmKEGf_N2SnMZ/g' /opt/couchdb/etc/vm.args

systemctl restart couchdb

Check and create cluster nodes (this is only done on one node):

curl http://admin:password@localhost:5984/_membership | jq .

Should show:

{
  "all_nodes": [
    "couchdb@thishost.domain.tld"
  ],
  "cluster_nodes": [
    "couchdb@thishost.domain.tld"
  ]
}

If it instead (it may on Debian) shows something like this:

{
  "all_nodes": [
    "couchdb@thishost.domain.tld"
  ],
  "cluster_nodes": [
    "couchdb@thishost.domain.tld",
    "couchdb@127.0.0.1
  ]
}

In that case you will need to delete the 127.0.0.1 cluster node. (You will do this on each CouchDB machine that shows the localhost node.) Get the cluster node entry with revision (you need the revision to delete it):

curl -X GET http://admin:password@localhost:5984/_node/_local/_nodes/couchdb@127.0.0.1

Output:

{"_id":"couchdb@127.0.0.1","_rev":"1-967a00dff5e02add41819138abb3491a"}

Delete the localhost node:

curl -X DELETE http://admin:password@localhost:5984/_node/_local/_nodes/couchdb@127.0.0.1?rev=1-967a00dff5e02add41819138abb3491a | jq .

Now, proceed as normal.

Add other nodes

curl -X PUT http://admin:password@localhost:5984/_node/_local/_nodes/couchdb@db2.mydomain.net -d {} | jq .
curl -X PUT http://admin:password@localhost:5984/_node/_local/_nodes/couchdb@db3.mydomain.net -d {} | jq .
curl http://admin:password@localhost:5984/_membership | jq .

Create user DB:

curl -X PUT http://localhost:5984/_users -user admin -password pa$$w0rd

CouchDB Install is Done

Get the 2600Hz release package:

wget https://packages.2600hz.com/centos/7/stable/2600hz-release/4.3/2600hz-release-4.3-0.el7.centos.noarch.rpm

and install it:

rpm -Uvh 2600hz-release-4.3-0.el7.centos.noarch.rpm

HAPROXY

Haproxy needs to be installed on all FS and Kazoo nodes.

Install Haproxy

yum install kazoo-haproxy

edit /etc/kazoo/haproxy/haproxy.cfg

global
        log /dev/log local0 info
        maxconn 4096
        user haproxy
        group daemon
        stats socket    /var/run/haproxy/haproxy.sock mode 777

defaults
        log global
        mode http
        option httplog
        option dontlognull
	option log-health-checks
        option redispatch
        option httpchk GET /_up
        option allbackups
        option http-server-close
        maxconn 2000
        retries 3
        timeout connect 6000ms
        timeout client 12000ms
        timeout server 12000ms
        
listen couch-data 127.0.0.1:15984
  balance roundrobin
	server db1.mydomain.net 123.123.123.123:5984 check
	server db2.mydomain.net 124.124.124.124:5984 check
	server db3.mydomain.net 125.125.125.125:5984 check
	##FOR TLS BACKEND:
	#server db1.mydomain.net 123.123.123.123:6984 check ssl ca-file /etc/pki/tls/certs/ca-bundle.crt
        #server db2.mydomain.net 124.124.124.124:6984 check ssl ca-file /etc/pki/tls/certs/ca-bundle.crt
        #server db3.mydomain.net 125.125.125.125:6984 check ssl ca-file /etc/pki/tls/certs/ca-bundle.crt

listen haproxy-stats 127.0.0.1:22002
  mode http
  stats uri /

Enable haproxy

systemctl enable kazoo-haproxy
systemctl start kazoo-haproxy

Verify HAPROXY is working and seeing the Couch cluster:

curl http://localhost:15984
kazoo-haproxy status

Generate random Erlang cookie:

export RANDOMJUNK=`head -c 32 /dev/urandom`
export SEED=`date +%s`
export COOKIE=`echo $RANDOMJUNK $SEED | sha256sum | base64 | head -c 32`
echo $COOKIE

Disable SELINUX

sed -i 's/\(^SELINUX=\).*/\SELINUX=disabled/' /etc/selinux/config

Install Sngrep (optional)

Create file /etc/yum.repos.d/sngrep.repo and insert the following:

[irontec]
name=Irontec RPMs repository
baseurl=http://packages.irontec.com/centos/$releasever/$basearch/

Then run:

rpm --import http://packages.irontec.com/public.key
yum update
yum install sngrep

Freeswitch

Freeswitch Installation

yum install kazoo-freeswitch

Open RTP Ports:

firewall-cmd --permanent --zone=public --add-port=16384-32768/udp

Allow ALL connections from kazoo server[s]:

firewall-cmd --permanent --zone=trusted --add-source=222.222.222.222/32
firewall-cmd --permanent --zone=trusted --add-source=111.111.111.111/32

edit Freeswitch config /etc/kazoo/freeswitch/autoload_configs/kazoo.conf.xml to add Erlang cookie

sed -i "s/change_me/$COOKIE/g" /etc/kazoo/freeswitch/autoload_configs/kazoo.conf.xml

Enable Freeswitch

systemctl disable freeswitch
systemctl enable kazoo-freeswitch
systemctl start kazoo-freeswitch

Verify Freeswitch

kazoo-freeswitch status

Kazoo Installation

Open needed ports on Kazoo/Kamailio server[s]:

firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-service=sip
firewall-cmd --permanent --zone=public --add-service=sips
firewall-cmd --permanent --zone=public --add-port=7000/udp
firewall-cmd --permanent --zone=public --add-port=7000/tcp
firewall-cmd --permanent --zone=public --add-port=5060/udp  # for some reason firewalld didn't open 5060 with service sip for me
firewall-cmd --permanent --zone=public --add-port=5060/tcp  # for some reason firewalld didn't open 5060 with service sip for me
Allow ALL connections from other kazoo server[s]:
firewall-cmd --permanent --zone=trusted --add-source=222.222.222.222/32
firewall-cmd --permanent --zone=trusted --add-source=111.111.111.111/32
And ALL freeswitch servers (even those not in zone, in case of failover):
firewall-cmd --permanent --zone=trusted --add-source=144.144.144.144/32
firewall-cmd --permanent --zone=trusted --add-source=244.244.244.244/32
Restart FirewallD
systemctl restart firewalld

OR

firewall-cmd --reload

Install some kazoo pieces

yum install kazoo-haproxy socat kazoo-kamailio kazoo-rabbitmq 

RABBITMQ

Enable RabbitMQ

systemctl enable kazoo-rabbitmq
systemctl start kazoo-rabbitmq

Verify RabbitMQ

ss -lpn | egrep "5672"
curl -i -u guest:guest http://localhost:15672/api/aliveness-test/%2F
kazoo-rabbitmq status

KAMAILIO

Edit /etc/kazoo/kamailio/local.cfg

(Sample config file below.)

NOTE: After these sed commands, you still have to uncomment the appropriate lines in the file!:

sed -i "s/kamailio\.2600hz\.com/${_HOSTNAME}/g" /etc/kazoo/kamailio/local.cfg
sed -i "s/127\.0\.0\.1/${IP_ADDR}/g" /etc/kazoo/kamailio/local.cfg
For a cluster, also input secondary/tertiary RabbitMQ servers in the SECONDARY_AMQP_SERVER fields, either with or without the zone= parameter, depending on whether this is a zoned cluster or not.

NOTE: You MUST NOT use the string "kazoo" anywhere in this line!

#!substdef "!MY_AMQP_SECONDARY_URL!zone=z200;amqp://guest:guest@111.111.111.111:5672!g"

Enable Kamailio

systemctl disable kamailio
systemctl enable kazoo-kamailio
systemctl start kazoo-kamailio

Verify Kamailio

ss -ln | egrep "5060|7000"
kazoo-kamailio status

should give "error: 500 - No Destination Sets"

Enable Rsyslog

(Kamailio logs through rsyslog.)

systemctl enable rsyslog
systemctl start rsyslog

Get the sipify script for SIP log parsing (optional)

curl -o /usr/bin/sipify.sh https://raw.githubusercontent.com/2600hz/community-scripts/master/FreeSWITCH/sipify.sh
chmod 755 /usr/bin/sipify.sh

KAZOO CORE

Install Kazoo apps and extras

yum install kazoo-application*

edit /etc/kazoo/core/config.ini

; section are between [] = [section]
; key = value
; to comment add ";" in front of the line

;;Single zone:
;[amqp]
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"
;uri = "amqp://guest:guest@3.2.3.4:5672

;;If you are saturating TCP conn to RabbitMQ you may specify same URI again:
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"

;;Cluster with multiple zones:
[zone]
name = "z100"
amqp_uri = "amqp://guest:guest@222.222.222.222"

[zone]
name = "z200"
amqp_uri = "amqp://guest:guest@111.111.111.111"

[bigcouch]
compact_automatically = true
cookie = change_me
ip = "127.0.0.1"
port = 15984
username = "admin"
password = "DBPas$dbw0rd"
admin_port = 15984

[kazoo_apps]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z100"
host = "eagle.mydomain.net"

[kazoo_apps]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z200"
host = "hawk.mydomain.net"

[ecallmgr]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z100"
host = "eagle.mydomain.net"

[ecallmgr]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z200"
host = "hawk.mydomain.net"

[log]
syslog = info
console = notice
file = error

Enable Kazoo Applications

systemctl enable kazoo-applications
systemctl start kazoo-applications

Verify Kazoo Applications

 kazoo-applications status 
Running Ecallmgr Separately from Kazoo Apps

If the following is left out, ecallmgr will run on the kazoo-applications erlang vm, along with the other kapps. Separating it prevents ecallmgr (call processing) from being bogged down by heavy API (crossbar) usage or something else going awry.

systemctl enable kazoo-ecallmgr
systemctl start kazoo-ecallmgr
Verify Ecallmgr
kazoo-ecallmgr status

WAIT, and then check that DB creation has finished (this will take several minutes)

curl -s -u admin:pa$$w0rd localhost:15984/_all_dbs 
curl -s -u admin:pa$$w0rd localhost:15984/_all_dbs | python -mjson.tool | wc -l

Should show 25+ DBs

Add freeswitch server[s] FOR THIS ZONE (do this on each Kazoo node)

sup ecallmgr_maintenance add_fs_node freeswitch@parrot.mydomain.net 'false'

OR Use this if starting ecallmgr on its own with systemd:

sup -necallmgr ecallmgr_maintenance add_fs_node freeswitch@parrot.mydomain.net 'false'

Refresh from CouchDB to apply these changes:

sup kapps_maintenance refresh "system_config"

Verify on Kazoo in each zone that only and all FreeSWITCH for this zone are listed

sup ecallmgr_maintenance list_fs_nodes

Or if ecallmgr is started on its own with systemd:

sup -necallmgr ecallmgr_maintenance list_fs_nodes

Verify that all kamailio servers are allowed to talk to Freeswitch server[s]

sup -necallmgr ecallmgr_maintenance sbc_acls list_acls

If required Kamailio server[s] are not listed, add them:

sup -necallmgr ecallmgr_maintenance allow_sbc hawk.mydomain.net 111.111.111.111
sup -necallmgr ecallmgr_maintenance allow_sbc eagle.mydomain.net 222.222.222.222

get sounds installed

sup kazoo_media_maintenance import_prompts /opt/kazoo/sounds/en/us/
sup kapps_maintenance refresh

create the top level account:

sup crossbar_maintenance create_account {ACCOUNT_NAME} {REALM} {USERNAME} {PASSWORD}

sup crossbar_maintenance create_account john_acct buggerrealm johnuser Pa$$w0rd

Test the Crossbar API:

curl http://localhost:8000/v2

MONSTER-UI

yum install monster-ui* httpd
sed -i "s/localhost/$IP_ADDR/" /var/www/html/monster-ui/js/config.js

Edit config.js to whitelabel (if required)

initialize monster-ui:

sup crossbar_maintenance init_apps /var/www/html/monster-ui/apps http://$IP_ADDR:8000/v2

Create the virtual host (if using Apache...)

echo "<VirtualHost *:80>
  DocumentRoot \"/var/www/html/monster-ui\"
  ServerName ${_HOSTNAME}
</VirtualHost>
" > /etc/httpd/conf.d/${_HOSTNAME}.conf
systemctl reload httpd

You're DONE!


Kazoo Core config.ini

; section are between [] = [section]
; key = value
; to comment add ";" in front of the line

;;Single zone:
;[amqp]
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"
;uri = "amqp://guest:guest@3.2.3.4:5672

;;If you are saturating TCP conn to RabbitMQ you may specify same URI again:
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@1.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"
;uri = "amqp://guest:guest@2.2.3.4:5672"

;;Cluster with multiple zones:
[zone]
name = "z100"
amqp_uri = "amqp://guest:guest@222.222.222.222"

[zone]
name = "z200"
amqp_uri = "amqp://guest:guest@111.111.111.111"

[bigcouch]
compact_automatically = true
cookie = change_me
ip = "127.0.0.1"
port = 15984
username = "admin"
password = "DBPas$dbw0rd"
admin_port = 15984

[kazoo_apps]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z100"
host = "eagle.mydomain.net"

[kazoo_apps]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z200"
host = "hawk.mydomain.net"

[ecallmgr]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z100"
host = "eagle.mydomain.net"

[ecallmgr]
cookie = kljsdlifjalsjfliejslfijsliejflsijeflsiejflsiefj
zone = "z200"
host = "hawk.mydomain.net"

[log]
syslog = info
console = notice
file = error

Kamailio local.cfg for eagle.mydomain.net

################################################################################
## ROLES
################################################################################
## Enabled Roles
#!trydef DISPATCHER_ROLE
#!trydef NAT_TRAVERSAL_ROLE
#!trydef REGISTRAR_ROLE
#!trydef PRESENCE_ROLE
#!trydef RESPONDER_ROLE
#!trydef NODES_ROLE

## Disabled Roles - remove all but the last '#' to enable
# # #!trydef TRAFFIC_FILTER_ROLE
# # #!trydef WEBSOCKETS_ROLE
# # #!trydef TLS_ROLE
# # #!trydef ANTIFLOOD_ROLE
# # #!trydef RATE_LIMITER_ROLE
# # #!trydef ACL_ROLE
# # #!trydef MESSAGE_ROLE
# # #!trydef PUSHER_ROLE
# # #!trydef REGISTRAR_SYNC_ROLE
# # #!trydef PRESENCE_NOTIFY_SYNC_ROLE
# # #!trydef SIP_TRACE_ROLE

################################################################################
## SERVER INFORMATION
################################################################################
## UNCOMMENT & CHANGE "kamailio.2600hz.com" TO YOUR SERVERS HOSTNAME
#!substdef "!MY_HOSTNAME!eagle.mydomain.net!g"

## UNCOMMENT & CHANGE "127.0.0.1" TO YOUR SERVERS IP ADDRESS
##     Usually your public IP.  If you need
##     to listen on addtional ports or IPs
##     add them in "BINDINGS" at the bottom.
#!substdef "!MY_IP_ADDRESS!222.222.222.222!g"

## CHANGE "kazoo://guest:guest@127.0.0.1:5672" TO THE AMQP URL
##     This should be the primary RabbitMQ server
##     in the zone that this server will service.
#!substdef "!MY_AMQP_URL!amqp://guest:guest@222.222.222.222:5672!g"

## CHANGE "kazoo://guest:guest@127.0.0.1:5672" TO THE AMQP URL for the other zone.
##     This uses the existing MY_AMQP_SECONDARY_URL variable defined in default.cfg
##     Note the addition of the "zone=" part in the middle
## Use the following line for an un-zoned cluster:
##!substdef "!MY_AMQP_SECONDARY_URL!amqp://guest:guest@111.111.111.111:5672!g"
## Use the following line for an zoned cluster:
#!substdef "!MY_AMQP_SECONDARY_URL!zone=z200;amqp://guest:guest@111.111.111.111:5672!g"

################################################################################
## WEBSOCKETS
################################################################################
##
## These parameters are only required if you are using websockets
##
##   MY_WEBSOCKET_DOMAIN
##     This value must be present in the HTTP
##     Origin header on a new websocket request
##     or it will be rejected. default value is
##     domain of this server.
#!substdef "!MY_WEBSOCKET_DOMAIN!4x5.co!g"
##
##   WEBSOCKET_NO_ORIGIN_RESTRICTION
##     if defined, it will disable the origin validation.
##
##   #!trydef WEBSOCKET_NO_ORIGIN_RESTRICTION
##

################################################################################
## DATABASE
################################################################################
## This parameter is OPTIONAL
##     If you would like to use an external database
##     remove all but the last '#' and configure the connector
##     accordingly.  The example shows how to use postgres.
##     See the kamailio documentation for more details.
# # #!substdef "!KAMAILIO_DBMS!postgres!g"
# # #!substdef "!KAZOO_DB_URL!postgres://kamailio:kamailio@127.0.0.1/kamailio!g"

################################################################################
## UDP PARAMETERS
################################################################################
## This parameter is OPTIONAL
##     If large UDP packets are dropped by the
##     interface try uncommenting this option.
##     However, you MUST match this to your
##     network adapter!  If they do not match,
##     all UDP packets over this limit WILL FAIL!
##     E.g.: Add MTU=1472 to the /etc/sysconfig/network-scripts/XXX
# udp4_raw_mtu = 1472

################################################################################
## BINDINGS
################################################################################
## This parameter is OPTIONAL.
##     when set to 1,
##     It will try to locate outbound interface
##     on multihomed host.  By default forward
##     requests use the incoming socket disregarding
##     the destination location. When enabled Kamailio
##     will select a socket that can reach the
##     destination. This reduces performance.
##!define KZ_MULTI_HOMED 1

################################################################################
## KZ_DISABLE_REGISTRAR_PORTS
################################################################################
## This parameter is OPTIONAL.
##     It will disable publishing single proxy port on registrar success messages
##     By default single port proxy is send on registrar success messages
##     for websockets/tls protocols. the default port is 7000
##     which enables config less in freeswitch for handling webrtc/tls
##     ie, no certs in freeswitch, no webrtc/tls listeners on freeswitch
##     by disabling single port proxy, ecallmgr needs to be started with
##     'use_transport_for_fs_path' set to true in its environment configuration
##
###!define KZ_DISABLE_WEBSOCKETS_REGISTRAR_PORT 1
###!define KZ_DISABLE_TLS_REGISTRAR_PORT 1
##
## you can also change the ports used for single port redirect
##!define KZ_WEBSOCKETS_REGISTRAR_PORT 5060
##!define KZ_TLS_REGISTRAR_PORT 5060
##
## also available for udp/tcp if it works for you
##!define KZ_UDP_REGISTRAR_PORT 7000
##!define KZ_TCP_REGISTRAR_PORT 7000

################################################################################
## SIP traffic mirroring to SIP_TRACE server
################################################################################
## This parameter is OPTIONAL.
##     If you have installed SIP_TRACE server (Homer as example),
##     then you can mirror INVITE and MESSAGE here
# # #!define SIP_TRACE_URI "sip:222.222.222.222:9060"
# # #!define HEP_CAPTURE_ID 1

## YOU SHOULD NOT HAVE TO CHANGE THESE!
##     By setting MY_IP_ADDRESS above these will resolve
##     to the proper bindings.  These are here
##     for those with complex layouts who know
##     what they are doing :)
#!substdef "!UDP_SIP!udp:MY_IP_ADDRESS:5060!g"
#!substdef "!TCP_SIP!tcp:MY_IP_ADDRESS:5060!g"
#!substdef "!TLS_SIP!tls:MY_IP_ADDRESS:5061!g"
#!substdef "!UDP_ALG_SIP!udp:MY_IP_ADDRESS:7000!g"
#!substdef "!TCP_ALG_SIP!tcp:MY_IP_ADDRESS:7000!g"
#!substdef "!TLS_ALG_SIP!tls:MY_IP_ADDRESS:7001!g"
#!substdef "!TCP_WS!tcp:MY_IP_ADDRESS:5064!g"
#!substdef "!UDP_WS_SIP!udp:MY_IP_ADDRESS:5064!g"
#!substdef "!TLS_WSS!tls:MY_IP_ADDRESS:5065!g"
#!substdef "!UDP_WSS_SIP!udp:MY_IP_ADDRESS:5065!g"

## YOU SHOULD NOT HAVE TO CHANGE THESE!
##     This will bind the default SIP listeners
##     as determined above.  The tls-role and
##     websocket-role will use the appropriate
##     definitions if enabled.  These are here
##     for those with complex layouts who know
##     what they are doing :)
listen=UDP_SIP
listen=TCP_SIP
listen=UDP_ALG_SIP
listen=TCP_ALG_SIP

Haproxy haproxy.cfg

global
        log /dev/log local0 info
        maxconn 4096
        user haproxy
        group daemon
        stats socket    /var/run/haproxy/haproxy.sock mode 777

defaults
        log global
        mode http
        option httplog
        option dontlognull
	option log-health-checks
        option redispatch
        option httpchk GET /_up
        option allbackups
        option http-server-close
        maxconn 2000
        retries 3
        timeout connect 6000ms
        timeout client 12000ms
        timeout server 12000ms
        
listen couch-data 127.0.0.1:15984
  balance roundrobin
	server db1.mydomain.net 123.123.123.123:5984 check
	server db2.mydomain.net 124.124.124.124:5984 check
	server db3.mydomain.net 125.125.125.125:5984 check


listen haproxy-stats 127.0.0.1:22002
  mode http
  stats uri /


SUP

All SUP Commands:

https://gist.github.com/bugger/42a211d60b1c4b1abdcc001f2df67095

sup maintenance commands

sup kazoo_media_maintenance import_prompts /opt/kazoo/sounds/en/us/

sup kapps_maintenance refresh

sup kapps_maintenance refresh "system_config"

sup ACL commands

sup -necallmgr ecallmgr_maintenance allow_carrier CarrierName CarrierIP

sup -necallmgr ecallmgr_maintenance allow_carrier CarrierName CIDR

sup -necallmgr ecallmgr_maintenance allow_sbc SBCName SBCIP

sup -necallmgr ecallmgr_maintenance deny_carrier CarrierName CarrierIP

sup -necallmgr ecallmgr_maintenance deny_sbc SBCName SBCIP

sup -necallmgr ecallmgr_maintenance remove_acl CarrierName|SBCName

sup -necallmgr ecallmgr_maintenance carrier_acls list_acls

sup -necallmgr ecallmgr_maintenance sbc_acls list_acls

sup -necallmgr ecallmgr_maintenance list_fs_nodes

sup -necallmgr ecallmgr_maintenance add_fs_node freeswitch@parrot.mydomain.net

sup -necallmgr ecallmgr_maintenance reload_acls # -issues a reloadacl on all **FreeSWITCH** servers

sup -necallmgr ecallmgr_maintenance flush_acls # -just flushes the caches, not **FreeSWITCH**

sup AMQP commands

sup kazoo_amqp_maintenance primary_broker

sup kazoo_amqp_maintenance broker_summary

sup kazoo_amqp_maintenance connection_summary

Flush all cached docs for all accounts:

sup couch_mgr flush_cache_docs

Flush all cached docs for a specific account:

sup couch_mgr flush_cache_docs account%2Fab%2Fcd%2Fefghi

sup couch_mgr flush_cache_docs accounts

sup kapps_config get kapps_controller kapps

sup kapps_controller running_apps

Get the configured KApps for this node:

sup kapps_config get kapps_controller kapps

Get the currently running KApps:

sup kapps_controller running_apps

Get list of FreeSWITCH nodes that ecallmgr is configured to connect to:

sup -n ecallmgr ecallmgr_config get fs_nodes

Get list of FreeSWITCH nodes that ecallmgr is connected to:

sup -n ecallmgr ecallmgr_maintenance list_fs_nodes

On Freeswitch server: (shows connected Kazoo instances)

fs_cli -x 'erlang nodes list'

Restart a KApp on a remote host: (this may not be supported anymore)

sup -h apps002-dev-vb.2600hz.com -c change_me kapps_controller restart_app crossbar

Check the running KApps on a remote host: (this may not be supported anymore)

sup -h apps002-dev-vb.2600hz.com -c change_me kapps_controller running_apps

Check which AMQP host this server is connected to:

sup amqp_mgr get_host

Flush the kapps_config cache: (in case you modified some settings such as FS nodes)

sup kapps_config flush

You can also use this command for any document in the system_config database, for example:

sup kapps_config flush number_manager

Flush the ecallmgr_config cache:(in case you modified some settings such as FS nodes)

sup -n ecallmgr ecallmgr_config flush

Add FS nodes to ecallmgr:

This command adds a FreeSWITCH node to the currently running ecallmgr, but it does not update the persistent configuration:

sup -n ecallmgr ecallmgr_maintenance add_fs_node freeswitch@hostname.mydomain.com

Migrate (update) database documents:

sup -t 3600 kapps_maintenance migrate

Flush kazoo_apps couch cache:

sup kazoo_couch_maintenance flush

Restart conference WhApp:

sup kapps_controller restart_app conference

Stop the kazoo_apps Erlang VM:

sup erlang halt or sup -n kazoo_apps erlang halt

Stop the ecallmgr Erlang VM:

sup -n ecallmgr erlang halt

Alias the sup command: (for the user you are logged as)

/opt/kazoo/utils/sup/add_alias.sh

Manually create the first account on a Kazoo system:

(change the values for ACCOUNT_NAME, REALM, USERNAME, PASSWORD)

sup crossbar_maintenance create_account ACCOUNT_NAME REALM USERNAME PASSWORD

Lookup an account via the realm:

sup crossbar_maintenance find_account_by_realm 83a99b.sip.mydomain.com

Lookup an account via the phone number:

sup crossbar_maintenance find_account_by_number 4158867900

Find out which carrier will be used for a DID:

sup stepswitch_maintenance process_number 4158867900

Flush the kz_cache (to refresh the schemas for example):

sup kz_cache flush

Reload stepswitch to update carriers manually:

sup stepswitch_maintenance reload_resources

Reload a module:

sup crossbar_maintenance start_module cb_braintree

List all crossbar running modules:

sup crossbar_maintenance running_modules

List crossbar bindings:

sup crossbar_bindings modules_loaded

Refresh kapps after update:

NOTE: kapps_maintenance refresh can not be done in some circumstances from the foreground, it will try to output status info to a shell that has already closed and will error. The command is valid but not via sup if the command needs to output data. In this case use blocking_refresh. (Not sure if this is true anymore...)

sup kapps_maintenance refresh

Blocking Refresh KApps:

(doesn't work??)

sup kapps_maintenance blocking_refresh

Only refresh the "system_config" database

sup kapps_maintenance refresh "system_config"

Only refresh the "offnet" database

sup kapps_maintenance refresh "offnet"

Change the log level for KApps:

sup kazoo_maintenance syslog_level debug

sup kazoo_maintenance syslog_level info

Increase the log level for ecallmgr:

sup -n ecallmgr kazoo_maintenance syslog_level debug You can use any of the syslog severity levels to change what is logged.

Show the nodes sharing the same Rabbitmq:

sup kazoo_maintenance nodes

Display Registrations status:

sup -n ecallmgr ecallmgr_maintenance registrar_summary (Should be identical on all clustered Kazoo servers)

Enable normalization for this particular server:

sup kapps_config set crossbar.media normalize_media true

Enable media normalization for all servers:

sup kapps_config set_default crossbar.media normalize_media true

Set Google as TTS provider

sup kapps_config set_default speech tts_provider google

sup kapps_config set_default speech.google tts_url https://texttospeech.googleapis.com/v1/text:synthesize

sup kapps_config set_default speech.google tts_api_key AIzaSyCTHFo...........

Set Default Voicemail MWI Prefix

sup kapps_config set_default callflow dialog_subscribed_mwi_prefix *97


API

Overview API Methods Examples

Verb Function Example
GET Duh curl -X GET http://{SERVER}:8000/v2/phone_numbers?prefix=865&quantity=2
PUT Create curl -X PUT
POST Change curl -X POST (REPLACE whole data)
PATCH Patch curl -X PATCH (Replace or append given key:value)
DELETE Delete curl -X DELETE -H http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/phone_numbers/{PHONE_NUMBER}
-------- ---------- -----------------------------------------------------------------------------------------------

Auth

echo -n 'junk@john.us:pA$$w0rd' | md5sum

curl -X PUT -H "Content-Type: application/json" -H "X-Pretty-Print:true" -d \
 '{"data":{"credentials":"961fb0a1540be506cad41adacda6297c", "account_name":"john_user", "method":"md5"}}' http://localhost:8000/v2/user_auth

(The "method":"md5" is optional, as md5 is the default.)

OR with SHA1:

echo -n 'junk@john.us:pA$$w0rd' | sha1sum

curl -X PUT -H "Content-Type: application/json" -H "X-Pretty-Print:true" -d \
 '{"data":{"credentials":"b6fd5f3e8b72883529d3c1e57449b187137f4145", "account_name":"john_user", "method":"sha"}}' http://localhost:8000/v2/user_auth

Will output:

{
  "page_size" : 1,
  "data" : {
    "owner_id" : "c7972fa82053042b1432fb0c32bc20fd",
    "account_id" : "2c423d32b569423d55f112e1c9362d5f",
    "ui_config" : {
      
    },
    "capabilities" : {
      "voicemail" : {
        "transcription" : {
          "default" : false,
          "available" : false
        }
      }
    },
    "is_master_account" : false,
    "is_reseller" : false,
    "reseller_id" : "ce93b633ad462c64f1d96828cb88da26",
    "cluster_id" : "e8c631632341325eeb3f9d70dcfa46da",
    "account_name" : "john_user",
    "language" : "en-US",
    "apps" : [
      {
        "id" : "212782a7ae2926155bc2f2ef03152ad9",
        "name" : "accounts",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Accounts"
      },
      {
        "id" : "0b7f2882503fcc48172fc030ed4c8c85",
        "name" : "callflows",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Callflows"
      },
      {
        "id" : "20e56d6d3a5ba8279981cff5a8d0e8d9",
        "name" : "csv-onboarding",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "CSV Onboarding"
      },
      {
        "id" : "c831a6c769b9fbb241ee0c4105f8fe98",
        "name" : "fax",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Faxes"
      },
      {
        "id" : "2a1dd7fcd2ee8156921ad73c3ad1736e",
        "name" : "numbers",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Numbers"
      },
      {
        "id" : "fab5209d433cdeb7da853bca17926197",
        "name" : "pbxs",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "PBX Connector"
      },
      {
        "id" : "d857fa70ae84787e24ac548493f9e344",
        "name" : "voicemails",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Voicemails"
      },
      {
        "id" : "bd989eb37f9d4f3b69f47548fd247e36",
        "name" : "voip",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "SmartPBX"
      },
      {
        "id" : "b5018d75ead09146b0e309ab65ca1485",
        "name" : "webhooks",
        "api_url" : "https://eagle.mydomain.net:8800/v2",
        "label" : "Webhooks"
      }
    ]
  },
  "revision" : "automatic",
  "timestamp" : "2020-03-20T21:39:58Z",
  "version" : "4.3.90",
  "node" : "jCN0LUcrZGgx6OUi8fpHxQ",
  "request_id" : "a625d4b996613a85199ed386a9c814b3",
  "status" : "success",
  "auth_token" : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjI3ZTMwYWQ4NDZsOWJkNzcyY2EwZm22OWUxMzk5MjU5In0.eyJpc3MiOiJrYXpvby8sImlkZW50aXR5X3NpZyI6InlzWjZrWUxyUlVaalV6cThSc2JJSz3hcEg1ZmExTjlVNbVyN0VrbUhsdVkiLCJhY2NvdW50X2lkIjoiNWM3NTNkMzRiNTY5NDIzZDU1ZjExZGUxYzkzNjhkNWYiLCJvd25lcl9lZCh6ImM3OTcxZmh4MTA1MzA0ZWIxNDh5ZmIwYzMwYmMyMGZkIiwibWV0aG9kIjoiY2JfdXNlcl9hdXRoIiwiZXhwIjoxNQzOTk4fQ.D5hdrK0cnbXMv5YjGUvZU46VABJsiDSXJGbGcYYGgVoJHJ91KopPnjD72Il3zSOWSFRiUPElQ3E4Hl9UGSrQFH757639ce_WuroU0bCV99xd2XPnlrnm1PKq5W2bBJM3s45Bi921EBgvbkclkKQtrGINgzLRgFic3fyW8Oo5fcVAkx_ueHpeut9wHIPtJehL8X3m_V-OeXBUlVFQgwRFhXbtbM0ryk9bAB0r_7rtQGJmBpXqrfMq14Hr3_26yUmGoD5hYw3X4OZA63IK5kwWuIGjuh7Pcvz8d0ccHFSU5GQxelPyWOxzwB08hmSNUzSFrzTYiB6falAXBSiYzGWyAw"
}

Store a variable with the AUTH_TOKEN:

export AUTH_TOKEN=asdfgfsajlfkjsadlfjlsakakdjhiufashieugiygsihfsauhdfkh....

Get an account's 64 character API key to use to get the AUTH_TOKEN instead of user/pass hash for future requests:

curl -s -X GET -H "X-Auth-Token: ${AUTH_TOKEN}" http://localhost:8000/v2/accounts/4b659d34c935423d55f11de1c9368d5f/api_key | jq .

Use API key to authenticate and get AUTH_TOKEN:

curl -X PUT -H "Content-Type: application/json" -H "X-Pretty-Print:true" -d '{"data":{"api_key":"abcdef012345678987654321234567890987654321abcdef0123456789abcdef"}}' http://localhost:8000/v2/api_auth | jq .

Here is my auth script:

#!/bin/sh
export AUTH_TOKEN=`curl -sX PUT -H "Content-Type: application/json" -d '{"data":{"credentials":"abcdefabcdef1234567890abcdefabcdef", "account_name":"ruel_user", "method":"sha"}}' http://localhost:8000/v2/user_auth | jq -r .auth_token`
echo $AUTH_TOKEN

Replace the credentials value with your sha string for this user's credentials that you want to use:

echo -n 'junk@john.us:pA$$w0rd' | sha1sum

Then you can use this in curl requests like so:

curl -s -X GET -H "X-Auth-Token: `path_to_auth_script.sh`" http://localhost:8000/v2/accounts/{ACCOUNT_ID}

Accounts

Create new account (will be child of AUTH_TOKEN's account)

curl -v -X PUT -H "X-Auth-Token: {AUTH_TOKEN}" -H "Content-Type: application/json" http://localhost:8000/v2/accounts -d 
'{ "data":
    {
        "name": "child account",
        "is_reseller": false,
        "realm": "myrealm.com",
        "language": "en-us",
        "reseller_id": "RESELLER_ID",
        "timezone": "America/Los_Angeles"
    }
}'

Patch account:

curl -s -X PATCH -H "X-Auth-Token: {AUTH_TOKEN}" -d '{"data":{"some_key":"value"}}'  http://localhost:8000/v2/accounts/{ACCOUNT_ID}

Fetch account tree (upwards)

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/tree

Fetch the parent account IDs

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/parents

Fetch the parent account IDs

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/parents

Fetch sibling accounts (if allowed in system_config/crossbar.accounts)

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/siblings

Fetch child accounts

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/children

Fetch descendant accounts (including grandchildren)

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/descendants

Promote Reseller:

curl -s -X PUT -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/reseller

Demote Reseller:

curl -s -X DELETE -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/reseller

MOVE account (super duper admin):

curl -v -X POST -H "X-Auth-Token: {AUTH_TOKEN}" -d '{"data": {"to": "{ACCOUNT_ID_DESTINATION}"}}' http://localhost:8000/v2/accounts/{ACCOUNT_ID}/move

Webhooks

Webhook events

  • notifications
  • channel_create
  • channel_destroy
  • channel_bridge
  • channel_answer
  • parking

List available webhooks on the system

curl -v -X GET -H "Content-Type:application/json" -H "X-Auth-Token: {AUTH_TOKEN}" http://{SERVER}:8000/v2/webhooks

Create a webhook

curl -v -X PUT -H "X-Auth-Token: {AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"data": {
    "name": "New Calls",
    "uri": "http://{YOUR_SERVER}/calls/new.php",
    "http_verb": "post",
    "hook": "channel_create",
    "retries":3
}}' \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/webhooks

Get webhook details

curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/webhooks/{WEBHOOK_ID}

Edit webhook

curl -v -X POST -H "X-Auth-Token: {AUTH_TOKEN}" -H "Content-Type: application/json" \
    -d '{"data": {
        "name": "New Calls",
        "uri": "http://my.server.com/calls/new_calls.php",
        "http_verb": "post",
        "hook": "channel_create",
        "retries": 3
    }}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/webhooks/{WEBHOOK_ID}

Patch webhook

curl -v -X PATCH -H "X-Auth-Token: {AUTH_TOKEN}" -H "Content-Type: application/json" \
    -d '{"data":{"enabled":true}}' http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/webhooks/{WEBHOOK_ID}

Websockets (uses blackhole application)

List bindings

curl -v -X GET http://{SERVER}:8000/v2/websockets | python -mjson.tool

Media

Get a listing of all system media files:
curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/media
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server.com:8000/v2/media?filter_language=en
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server.com:8000/v2/media?filter_language=en-US
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server.com:8000/v2/media?filter_language=fr-FR

Enable normalization (this server):

sup kapps_config set crossbar.media normalize_media true

Enable normalization for all servers:

sup kapps_config set_default crossbar.media normalize_media true

Set target format (this server):

sup kapps_config set crossbar.media normalization_format ogg

Set target format for all servers:

sup kapps_config set_default crossbar.media normalization_format ogg

Image file:

curl -X POST -s -H "X-Auth-Token: `/root/auth_sadm.sh`" -H 'Content-Type: image/png' --data-binary "@/var/www/html/monster-ui/logos/Bugger_logo_blue.png" http://localhost:8000/v2/accounts/4b659d34c935423d55f11de1c9368d5f/whitelabel/logo

Create a new media object (required before uploading the actual media data)

curl -s -X PUT -H "X-Auth-Token: {AUTH_TOKEN}" -d '{"data":{"streamable":true, "name": "File", "description": "My Test Media File"}}' http://localhost:8000/v2/accounts/{ACCOUNT_ID}/media

Upload the media file itself:

curl -s -X POST -H "X-Auth-Token: {AUTH_TOKEN}" -H 'Content-Type: audio/mp3' --data-binary @/path/to/file.mp3 http://localhost:8000/v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID}/

POST overwrites/modifies existing data

curl -X GET /v2/accounts/{ACCOUNT_ID}/media/languages

Get media metadata

curl -X GET /v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID} -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID}/

Get raw media file (Accept header)

curl -X GET /v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID} -H "X-Auth-Token: {AUTH_TOKEN}" -H 'Accept: audio/mp3' http://localhost:8000/v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID}/

Get prompts

curl -s -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://localhost:8000/v2/accounts/{ACCOUNT_ID}/media/prompts

Get languages

GET /v2/accounts/{ACCOUNT_ID}/media/languages

Whitelabel

Create a Whitelabel for an Account

PUT /v2/accounts/{ACCOUNT_ID}/whitelabel

curl -v -X PUT \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -d '{"data": {"company_name":"My VoIP Reseller Company", "domain":"mydomain.com"} }' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel

You may fetch the whitelabel with GET:

GET /v2/accounts/{ACCOUNT_ID}/whitelabel

Delete it:

DELETE /v2/accounts/{ACCOUNT_ID}/whitelabel

Or modify it:

POST /v2/accounts/{ACCOUNT_ID}/whitelabel

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -d '{"data": {"company_name":"My VoIP Reseller Company", "domain":"mydomain.com"} }' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel

Fetch Domains

GET /v2/accounts/{ACCOUNT_ID}/whitelabel/domains

When you white label Kazoo's services, DNS settings are needed to make sure your hostname maps appropriate for the various DNS entries (CNAM, A, NAPTR, etc). If the system admin has configured their settings on the backend, you can query Crossbar to show you what your settings should map to.

You have two options on the request for what domain to use:

  1. If you've already configured your whitelabel domain for the account, the API will use that value.
  2. If you specify domain=some.realm.com on the request, some.realm.com will be used instead.
curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/domains?domain=some.realm.com

OR

curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -d '{"data": {"domain": "some.realm.com"}}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/domains

Uploading a Custom Logo

POST /v2/accounts/{ACCOUNT_ID}/whitelabel/logo

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H 'Content-Type: image/png' \
    --data-binary "@/local/path/to/logo.png" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/logo

To tie the logo to a specific domain, rather than the account, use:

POST /v2/accounts/{ACCOUNT_ID}/whitelabel/{domain}/logo

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H 'Content-Type: image/png' \
    --data-binary "@/local/path/to/logo.png" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/mydomain.com/logo

Fetch Custom Logo

This returns the logo image file data.

GET /v2/accounts/{ACCOUNT_ID}/whitelabel/logo

Or domain specific:

GET /v2/accounts/{ACCOUNT_ID}/whitelabel/{domain}/logo

Uploading a Custom Icon

POST /v2/accounts/{ACCOUNT_ID}/whitelabel/icon

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H 'Content-Type: image/png' \
    --data-binary "@/local/path/to/icon.png" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/icon

To tie the icon to a specific domain, rather than the account, use:

POST /v2/accounts/{ACCOUNT_ID}/whitelabel/{domain}/icon

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H 'Content-Type: image/png' \
    --data-binary "@/local/path/to/icon.png" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/whitelabel/mydomain.com/icon

Fetch Custom Icon

This returns the icon image file.

GET /v2/accounts/{ACCOUNT_ID}/whitelabel/icon

Or domain specific:

GET /v2/accounts/{ACCOUNT_ID}/whitelabel/{domain}/icon

Carriers

Global Carrier

Create document in offnet DB like:

curl -X POST -H "Content-Type: application/json" -d '{"name":"AnveoDirect", "enabled":true, "pvt_type":"resource", "weight_cost":10, "rules":[ "^\\+?1?\\d{10}" ], "gateways":[ {"enabled":true, "server":"sbc.anveo.com", "prefix":"03252"} ], "type":"global" } ' http://localhost:5984/offnetb | jq .

Should return:

{
    "name":"AnveoDirect", 
    "enabled":true, 
    "pvt_type":"resource", 
    "weight_cost":10, 
    "emergency": false,
    "caller_id_options": {
        "type": "external"
    },
    "rules":[ "^\\+?1?\\d{10}" ], 
    "gateways":[ 
        {
            "enabled":true, 
            "codecs": ["PCMU", "PCMA"],
            "custom_sip_headers": {},
            "emergency": false,
            "endpoint_type": "sip",
            "server":"sbc.anveo.com", 
            "progress_timeout": "6",
            "username": "blazemore",
            "password": "DrWoody",
            "prefix":"24523"
        } 
    ], 
    "type":"global" 
} 

Account Level

This carrier will be account specific, and will have to be enabled in the account settings (rather than using reseller or global carrier):

curl -sX PUT -H "Content-Type: application/json" -H "X-Auth-Token: $AUTH_TOKEN" -d '{ "data":{"name":"Telnyx", "enabled":true, "weight_cost":10, "rules":[ "^\\+?1?\\d{10}" ], "gateways":[ {"enabled":true, "server":"sip.telnyx.com", "prefix":"",  "username":"voip42390", "password":"Paszzzw0rd" }] } }' http://localhost:8000/v2/accounts/4b659d34c935423d55f11de1c9368d5f/resources

For IP auth, merely leave off username/password. But note that all FS boxes have to be allowed in the carrier's IP auth settings. You can add something in the prefix field if you want to use a tech prefix.

Fax

If you enable faxbox in user features in SmartPBX, you can send an email from the user's address to 18884732963@eagle.mydomain.net Send fax using the API:

curl -s -X PUT -H "X-Auth-Token: ${AUTH_TOKEN}" -d '{"data":{"document":{"url":"https://raven.mydomain.net/test.pdf","method":"get"},"retries":3,"from_name":"Test Fax","from_number":"18655909600","to_name":"To Name","to_number":"18884732963"}}' http://localhost:8000/v2/accounts/4b659d34c935423d55f11de1c9368d5f/faxes | jq .

You can also use {account_id}/faxes/outgoing endpoint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment