Skip to content

Commit

Permalink
Merge pull request #508 from dOpensource/v0.721
Browse files Browse the repository at this point in the history
V0.721
  • Loading branch information
mackhendricks committed Apr 28, 2023
2 parents 6cd2148 + dba9090 commit 362b436
Show file tree
Hide file tree
Showing 39 changed files with 1,643 additions and 620 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# dSIPRouter Project Specific Ignored Files
.idea
/resources/terraform/do/*.tfstate
/resources/terraform/do/*.backup
/resources/terraform/do/.terraform
/resources/terraform/do/*.hcl
/resources/terraform/do/terraform.tfvars
*/__pycache__/
# TODO: these following files could be generated elsewhere
# adding them to python path where needed to cleanup project dir
docs/build/
gui/modules/fusionpbx/certs/cert.key
gui/modules/fusionpbx/certs/cert_combined.crt
29 changes: 19 additions & 10 deletions docs/source/user/upgrade.rst
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
Upgrading dSIPRouter
============================================

Auto Upgrade Feature (Released 0.72)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The dSIPRouter auto upgrade feature was released in 0.72. It allows you to upgrade dSIPRouter from the User Interface(UI) and the command line. If you are upgrading from 0.70 you will need to use the command line option since the 0.70 version doesn't have the upgrade feature builtin. Upgrading from 0.70 doesn't require a dSIPRouter Core Subscription license because this is the first release of the upgrade framework unless you need support during the upgrade process. However, future releases of dSIPRouter will require a Core Subscription License, which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.
Auto Upgrade Feature
^^^^^^^^^^^^^^^^^^^^
The dSIPRouter auto upgrade feature was released in 0.72.
It allows you to upgrade dSIPRouter from the User Interface(UI) and the command line.
If you are upgrading from 0.70 you will need to use the command line option since the 0.70 version doesn't have the upgrade feature builtin.
Upgrading from 0.70 doesn't require a dSIPRouter Core Subscription license because this is the first release of the upgrade framework unless you need support during the upgrade process.
However, future releases of dSIPRouter will require a Core Subscription License, which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.

.. image:: images/upgrade_up_to_date.png
:align: center

Upgrade 0.70 to 0.72
^^^^^^^^^^^^^^^^^^^^
Upgrade 0.70 to 0.721
^^^^^^^^^^^^^^^^^^^^^
You can upgrade from 0.70 by doing the following

1. SSH to your dSIPRouter Instance
2. Run the following command

.. code-block:: bash
curl -s https://raw.githubusercontent.com/dOpensource/dsiprouter/v0.72/resources/upgrade/v0.72/scripts/bootstrap.sh | bash
curl -s https://raw.githubusercontent.com/dOpensource/dsiprouter/v0.721/resources/upgrade/v0.721/scripts/bootstrap.sh | bash
3. Login to the dSIPRouter UI to validate that the upgrade was successful.

Note, if the upgrade fails you can purchase a dSIPRouter Core Subscription which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.This will provide you with support hours so that we can help with the upgrade.
Note, if the upgrade fails you can purchase a dSIPRouter Core Subscription which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.
This will provide you with support hours so that we can help with the upgrade.

Upgrade 0.644 to 0.72
^^^^^^^^^^^^^^^^^^^^^
There is no automated upgrade available from 0.644 to 0.72. Support is available via a dSIPRouter Core Subscription which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.This will provide you with support hours so that we can help with the upgrade.
Upgrade 0.70 to 0.72
^^^^^^^^^^^^^^^^^^^^
This upgrade path is deprecated. Upgrade to the **0.721** release instead.

Upgrade 0.644 to 0.70
^^^^^^^^^^^^^^^^^^^^^
There is no automated upgrade available from 0.644 to 0.70.
Support is available via a dSIPRouter Core Subscription which can be purchased from the `dSIPRouter Marketplace <https://dopensource.com/product/dsiprouter-core/>`_.This will provide you with support hours so that we can help with the upgrade.

Upgrade 0.621 to 0.63
^^^^^^^^^^^^^^^^^^^^^
Expand Down
43 changes: 24 additions & 19 deletions dsiprouter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -798,8 +798,8 @@ function renewSSLCert() {
# Don't try to renew if using wildcard certs
openssl x509 -in ${DSIP_SSL_CERT} -noout -subject | grep "CN\s\?=\s\?*." &>/dev/null
if (( $? == 0 )); then
printwarn "Wildcard certifcates are being used! LetsEncrypt certifcates can't automatically renew wildcard certificates"
return
printwarn "Wildcard certifcates are being used! LetsEncrypt certifcates can't automatically renew wildcard certificates"
return
fi

# Don't renew if a default cert was uploaded
Expand Down Expand Up @@ -845,7 +845,8 @@ function configureSSL() {

# Try to create cert using LetsEncrypt's first
printdbg "Generating Certs for ${EXTERNAL_FQDN} using LetsEncrypt"
certbot certonly --standalone --non-interactive --agree-tos -d ${EXTERNAL_FQDN} -m ${DSIP_SSL_EMAIL}
certbot certonly --standalone --non-interactive --agree-tos -d ${EXTERNAL_FQDN} -m ${DSIP_SSL_EMAIL} \
--server https://acme-v02.api.letsencrypt.org/directory --force-renewal --preferred-chain "ISRG Root X1"
if (( $? == 0 )); then
rm -f ${DSIP_CERTS_DIR}/dsiprouter*
cp -f /etc/letsencrypt/live/${EXTERNAL_FQDN}/fullchain.pem ${DSIP_SSL_CERT}
Expand Down Expand Up @@ -2117,6 +2118,7 @@ DefaultDependencies=no
Type=forking
PIDFile=/run/dnsmasq/dnsmasq.pid
Environment='RUN_DIR=/run/dnsmasq'
Environment='IGNORE_RESOLVCONF=yes'
# make sure everything is setup correctly before starting
ExecStartPre=!-/usr/bin/dsiprouter chown -dnsmasq
ExecStartPre=/usr/sbin/dnsmasq --test
Expand Down Expand Up @@ -2294,15 +2296,7 @@ function start() {
updatePermissions -dsiprouter
# keep dSIPRouter in the foreground, only used for debugging issues (blocking)
sudo -u dsiprouter -g dsiprouter ${PYTHON_CMD} ${DSIP_PROJECT_DIR}/gui/dsiprouter.py
# # Make sure process is still running
# PID=$!
# if ! ps -p ${PID} &>/dev/null; then
# printerr "Unable to start dSIPRouter"
# cleanupAndExit 1
# else
# pprint "dSIPRouter was started under pid ${PID}"
# echo "$PID" > ${DSIP_RUN_DIR}/dsiprouter.pid
# fi
cleanupAndExit $?
else
# normal startup, fork dSIPRouter as background process
systemctl start dsiprouter
Expand Down Expand Up @@ -2351,8 +2345,8 @@ function stop() {
systemctl stop nginx
# if started in debug mode we have to manually kill the process
if ! systemctl is-active --quiet dsiprouter; then
pkill -SIGTERM -f dsiprouter
if pgrep -f 'nginx|dsiprouter' &>/dev/null; then
pkill -SIGTERM -f dsiprouter.py
if pgrep -f 'nginx|dsiprouter.py' &>/dev/null; then
printerr "Unable to stop dSIPRouter"
cleanupAndExit 1
else
Expand Down Expand Up @@ -2390,16 +2384,21 @@ function displayLoginInfo() {
echo -ne '\n'

printdbg "You can access the dSIPRouter WEB GUI here"
pprint "External IP: ${DSIP_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
pprint "Domain Name: ${DSIP_PROTO}://${EXTERNAL_FQDN}:${DSIP_PORT}"
if [ "$EXTERNAL_IP_ADDR" != "$INTERNAL_IP_ADDR" ];then
pprint "External IP: ${DSIP_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
pprint "Internal IP: ${DSIP_PROTO}://${INTERNAL_IP_ADDR}:${DSIP_PORT}"
else
pprint "IP Address: ${DSIP_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
fi
echo -ne '\n'

printdbg "You can access the dSIPRouter REST API here"
pprint "External IP: ${DSIP_API_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
if [ "$EXTERNAL_IP_ADDR" != "$INTERNAL_IP_ADDR" ];then
pprint "External IP: ${DSIP_API_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
pprint "Internal IP: ${DSIP_API_PROTO}://${INTERNAL_IP_ADDR}:${DSIP_PORT}"
else
pprint "IP Address: ${DSIP_API_PROTO}://${EXTERNAL_IP_ADDR}:${DSIP_PORT}"
fi
echo -ne '\n'

Expand Down Expand Up @@ -2435,6 +2434,8 @@ function setCredentials() {
local SET_ROOT_DB_NAME="${SET_ROOT_DB_NAME}"
local LOAD_SETTINGS_FROM=${LOAD_SETTINGS_FROM:-$(getConfigAttrib 'LOAD_SETTINGS_FROM' ${DSIP_CONFIG_FILE})}
local DSIP_ID=${DSIP_ID:-$(getConfigAttrib 'DSIP_ID' ${DSIP_CONFIG_FILE})}
local DSIP_CLUSTER_ID=${DSIP_CLUSTER_ID:-$(getConfigAttrib 'DSIP_CLUSTER_ID' ${DSIP_CONFIG_FILE})}
local DSIP_CLUSTER_SYNC=${DSIP_CLUSTER_SYNC:-$([[ "$(getConfigAttrib 'DSIP_CLUSTER_SYNC' ${DSIP_CONFIG_FILE})" == "True" ]] && echo '1' || echo '0')}
# the commands to execute for these updates
local SHELL_CMDS=() SQL_STATEMENTS=() DEFERRED_SQL_STATEMENTS=()
# how settings will be propagated to live systems
Expand Down Expand Up @@ -2469,11 +2470,13 @@ function setCredentials() {

# update non-encrypted settings locally and gather statements for updating DB
if [[ -n "${SET_DSIP_GUI_USER}" ]]; then
SQL_STATEMENTS+=("update kamailio.dsip_settings set DSIP_USERNAME='${SET_DSIP_GUI_USER}' where DSIP_ID=${DSIP_ID};")
SQL_STATEMENTS+=("update kamailio.dsip_settings SET DSIP_USERNAME='$SET_DSIP_GUI_USER' WHERE DSIP_ID='$DSIP_ID';")
SQL_STATEMENTS+=("update kamailio.dsip_settings SET DSIP_USERNAME='$SET_DSIP_GUI_USER' WHERE DSIP_CLUSTER_ID='$DSIP_CLUSTER_ID' AND DSIP_CLUSTER_SYNC='1' AND DSIP_ID!='$DSIP_ID';")
SHELL_CMDS+=("setConfigAttrib 'DSIP_USERNAME' '$SET_DSIP_GUI_USER' ${DSIP_CONFIG_FILE} -q;")
fi
if [[ -n "${SET_DSIP_MAIL_USER}" ]]; then
SQL_STATEMENTS+=("update kamailio.dsip_settings set MAIL_USERNAME='${SET_DSIP_MAIL_USER}' where DSIP_ID=${DSIP_ID};")
SQL_STATEMENTS+=("update kamailio.dsip_settings SET MAIL_USERNAME='$SET_DSIP_MAIL_USER' WHERE DSIP_ID='$DSIP_ID';")
SQL_STATEMENTS+=("update kamailio.dsip_settings SET MAIL_USERNAME='$SET_DSIP_MAIL_USER' WHERE DSIP_CLUSTER_ID='$DSIP_CLUSTER_ID' AND DSIP_CLUSTER_SYNC='1' AND DSIP_ID!='$DSIP_ID';")
SHELL_CMDS+=("'MAIL_USERNAME' '$SET_DSIP_MAIL_USER' ${DSIP_CONFIG_FILE} -q;")
fi
if [[ -n "${SET_DSIP_API_TOKEN}" ]]; then
Expand Down Expand Up @@ -2517,7 +2520,8 @@ function setCredentials() {
DEFERRED_SQL_STATEMENTS+=("CREATE USER '$SET_KAM_DB_USER'@'%' IDENTIFIED BY '${SET_KAM_DB_PASS:-$KAM_DB_PASS}';")
DEFERRED_SQL_STATEMENTS+=("GRANT ALL PRIVILEGES ON $KAM_DB_NAME.* TO '$SET_KAM_DB_USER'@'%';")
fi
SQL_STATEMENTS+=("UPDATE kamailio.dsip_settings SET KAM_DB_USER='${SET_KAM_DB_USER}' WHERE DSIP_ID=${DSIP_ID};")
SQL_STATEMENTS+=("UPDATE kamailio.dsip_settings SET KAM_DB_USER='$SET_KAM_DB_USER' WHERE DSIP_ID='$DSIP_ID';")
SQL_STATEMENTS+=("UPDATE kamailio.dsip_settings SET KAM_DB_USER='$SET_KAM_DB_USER' WHERE DSIP_CLUSTER_ID='$DSIP_CLUSTER_ID' AND DSIP_CLUSTER_SYNC='1' AND DSIP_ID!='$DSIP_ID';")
SHELL_CMDS+=("setConfigAttrib 'KAM_DB_USER' '$SET_KAM_DB_USER' ${DSIP_CONFIG_FILE} -q;")

DSIP_RELOAD_TYPE=2
Expand Down Expand Up @@ -3282,6 +3286,7 @@ function updatePermissions() {

return 0
}
export -f updatePermissions

function usageOptions() {
linebreak() {
Expand Down
2 changes: 1 addition & 1 deletion dsiprouter/dsip_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ function getInternalCIDR() {
if [[ -n "$INTERFACE" ]]; then
DEF_IFACE=$INTERFACE
else
DEF_IFACE=$(ip -4 route list scope global 2>/dev/null | perl -e 'while (<>) { if (s%^(?:0\.0\.0\.0|default).*dev (\w+).*$%\1%) { print; exit; } }')
DEF_IFACE=$(ip -4 route list scope global 2>/dev/null | perl -e 'while (<>) { if (s%^(?:0\.0\.0\.0|default).*dev (\w+).*$%\1%) { print; exit; } }')
fi
PREFIX_LEN=$(ip -4 route list | grep "$INTERNAL_IP" | perl -e 'while (<>) { if (s%^(?!0\.0\.0\.0|default).*/(\d+) .*src [\w/.]*.*$%\1%) { print; exit; } }')
fi
Expand Down
98 changes: 95 additions & 3 deletions gui/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
sys.path.insert(0, '/etc/dsiprouter/gui')

import os
from collections import OrderedDict
from enum import Enum
from datetime import datetime, timedelta
from sqlalchemy import create_engine, MetaData, Table, Column, String, exc as sql_exceptions
Expand Down Expand Up @@ -752,6 +753,97 @@ def query_property(self, *args, **kwargs):
pass


def settingsToTableFormat(settings):
# convert db specific fields
if isinstance(settings.KAM_DB_HOST, (list, tuple)):
kam_db_host = ','.join(settings.KAM_DB_HOST)
else:
kam_db_host = settings.KAM_DB_HOST

return OrderedDict([
('DSIP_ID', settings.DSIP_ID),
('DSIP_CLUSTER_ID', settings.DSIP_CLUSTER_ID),
('DSIP_CLUSTER_SYNC', settings.DSIP_CLUSTER_SYNC),
('DSIP_PROTO', settings.DSIP_PROTO),
('DSIP_PORT', settings.DSIP_PORT),
('DSIP_USERNAME', settings.DSIP_USERNAME),
('DSIP_PASSWORD', settings.DSIP_PASSWORD),
('DSIP_IPC_PASS', settings.DSIP_IPC_PASS),
('DSIP_API_PROTO', settings.DSIP_API_PROTO),
('DSIP_API_PORT', settings.DSIP_API_PORT),
('DSIP_PRIV_KEY', settings.DSIP_PRIV_KEY),
('DSIP_PID_FILE', settings.DSIP_PID_FILE),
('DSIP_IPC_SOCK', settings.DSIP_IPC_SOCK),
('DSIP_UNIX_SOCK', settings.DSIP_UNIX_SOCK),
('DSIP_API_TOKEN', settings.DSIP_API_TOKEN),
('DSIP_LOG_LEVEL', settings.DSIP_LOG_LEVEL),
('DSIP_LOG_FACILITY', settings.DSIP_LOG_FACILITY),
('DSIP_SSL_KEY', settings.DSIP_SSL_KEY),
('DSIP_SSL_CERT', settings.DSIP_SSL_CERT),
('DSIP_SSL_CA', settings.DSIP_SSL_CA),
('DSIP_SSL_EMAIL', settings.DSIP_SSL_EMAIL),
('DSIP_CERTS_DIR', settings.DSIP_CERTS_DIR),
('VERSION', settings.VERSION),
('DEBUG', settings.DEBUG),
('ROLE', settings.ROLE),
('GUI_INACTIVE_TIMEOUT', settings.GUI_INACTIVE_TIMEOUT),
('KAM_DB_HOST', kam_db_host),
('KAM_DB_DRIVER', settings.KAM_DB_DRIVER),
('KAM_DB_TYPE', settings.KAM_DB_TYPE),
('KAM_DB_PORT', settings.KAM_DB_PORT),
('KAM_DB_NAME', settings.KAM_DB_NAME),
('KAM_DB_USER', settings.KAM_DB_USER),
('KAM_DB_PASS', settings.KAM_DB_PASS),
('KAM_KAMCMD_PATH', settings.KAM_KAMCMD_PATH),
('KAM_CFG_PATH', settings.KAM_CFG_PATH),
('KAM_TLSCFG_PATH', settings.KAM_TLSCFG_PATH),
('RTP_CFG_PATH', settings.RTP_CFG_PATH),
('FLT_CARRIER', settings.FLT_CARRIER),
('FLT_PBX', settings.FLT_PBX),
('FLT_MSTEAMS', settings.FLT_MSTEAMS),
('FLT_OUTBOUND', settings.FLT_OUTBOUND),
('FLT_INBOUND', settings.FLT_INBOUND),
('FLT_LCR_MIN', settings.FLT_LCR_MIN),
('FLT_FWD_MIN', settings.FLT_FWD_MIN),
('DEFAULT_AUTH_DOMAIN', settings.DEFAULT_AUTH_DOMAIN),
('TELEBLOCK_GW_ENABLED', settings.TELEBLOCK_GW_ENABLED),
('TELEBLOCK_GW_IP', settings.TELEBLOCK_GW_IP),
('TELEBLOCK_GW_PORT', settings.TELEBLOCK_GW_PORT),
('TELEBLOCK_MEDIA_IP', settings.TELEBLOCK_MEDIA_IP),
('TELEBLOCK_MEDIA_PORT', settings.TELEBLOCK_MEDIA_PORT),
('FLOWROUTE_ACCESS_KEY', settings.FLOWROUTE_ACCESS_KEY),
('FLOWROUTE_SECRET_KEY', settings.FLOWROUTE_SECRET_KEY),
('FLOWROUTE_API_ROOT_URL', settings.FLOWROUTE_API_ROOT_URL),
('HOMER_ID', settings.HOMER_ID),
('HOMER_HEP_HOST', settings.HOMER_HEP_HOST),
('HOMER_HEP_PORT', settings.HOMER_HEP_PORT),
('NETWORK_MODE', settings.NETWORK_MODE),
('IPV6_ENABLED', settings.IPV6_ENABLED),
('INTERNAL_IP_ADDR', settings.INTERNAL_IP_ADDR),
('INTERNAL_IP_NET', settings.INTERNAL_IP_NET),
('INTERNAL_IP6_ADDR', settings.INTERNAL_IP6_ADDR),
('INTERNAL_IP6_NET', settings.INTERNAL_IP6_NET),
('INTERNAL_FQDN', settings.INTERNAL_FQDN),
('EXTERNAL_IP_ADDR', settings.EXTERNAL_IP_ADDR),
('EXTERNAL_IP6_ADDR', settings.EXTERNAL_IP6_ADDR),
('EXTERNAL_FQDN', settings.EXTERNAL_FQDN),
('PUBLIC_IFACE', settings.PUBLIC_IFACE),
('PRIVATE_IFACE', settings.PRIVATE_IFACE),
('UPLOAD_FOLDER', settings.UPLOAD_FOLDER),
('MAIL_SERVER', settings.MAIL_SERVER),
('MAIL_PORT', settings.MAIL_PORT),
('MAIL_USE_TLS', settings.MAIL_USE_TLS),
('MAIL_USERNAME', settings.MAIL_USERNAME),
('MAIL_PASSWORD', settings.MAIL_PASSWORD),
('MAIL_ASCII_ATTACHMENTS', settings.MAIL_ASCII_ATTACHMENTS),
('MAIL_DEFAULT_SENDER', settings.MAIL_DEFAULT_SENDER),
('MAIL_DEFAULT_SUBJECT', settings.MAIL_DEFAULT_SUBJECT),
('DSIP_CORE_LICENSE', settings.DSIP_CORE_LICENSE),
('DSIP_STIRSHAKEN_LICENSE', settings.DSIP_STIRSHAKEN_LICENSE),
('DSIP_TRANSNEXUS_LICENSE', settings.DSIP_TRANSNEXUS_LICENSE),
('DSIP_MSTEAMS_LICENSE', settings.DSIP_MSTEAMS_LICENSE),
])

def updateDsipSettingsTable(fields):
"""
Update the dsip_settings table using our stored procedure
Expand All @@ -765,11 +857,11 @@ def updateDsipSettingsTable(fields):

db = DummySession()
try:
field_mapping = ', '.join(['{}=:{}'.format(x, x) for x in fields.keys()])
field_mapping = ', '.join([':{}'.format(x, x) for x in fields.keys()])
db = SessionLoader()
db.execute(
text('UPDATE dsip_settings SET {} WHERE DSIP_ID=:dsip_id'.format(field_mapping)),
dict(fields, dsip_id=settings.DSIP_ID)
text('CALL update_dsip_settings({})'.format(field_mapping)),
fields
)
db.commit()
except sql_exceptions.SQLAlchemyError:
Expand Down

0 comments on commit 362b436

Please sign in to comment.