Upgrade process

Upgrading from v4.2 to v4.3

Release components

This is the list of component versions selected for Quobis Communication Platform v4.3. These components can be downloaded from the Quobis registry site located at Gitlab.

Component versions for v4.3

Element

Version

teal

1.2.0

sippo server

21.10.0

qss

4.17.0

oauth2-proxy

1.16.2

xmpp-server

2.4.2

janus-dispatcher

1.5.2

erebus

1.6.1

janus-wrapper

1.18.1

recording-watchdog

3.4.1

sippoSDK-JS

29.0.1

sippoSDK-Android

0.14.0

sippoSDK-iOS

3.0.0

sippoSDK-cpp

0.1.0

webphone

5.23.4

c2c

0.9.2

sippo-manager

stable-2.1.2

sippo-maintainer

1.2.6-rc1-kubernetes1.15.3

sippo-exporter

1.6.0

sippo-k8s

2.13.1

kapi

1.5.2

The validated 3rd party software dependencies are:

Third-party components version for v4.3

3rd party element

Version

NodeJS runtime

8.0

message-broker (RabbitMQ)

3.8

database (MongoDB)

4.2

reverse-proxy (Nginx)

1.18.0

cluster-ingress (Nginx-ingress)

0.33.0

chat-database (PostgresSQL)

12-alpine

audiomixer (Asterisk)

18.2.0

sfu (Janus)

0.9.5

sip-proxy (Kamailio)

5.4.4

sip-proxy-db (MySQL)

5.7

turn-server (CoTURN)

4.5.1.1

monitoring.ui (Grafana)

7.3.7

log-database (Loki)

1.4.0

monitoring-database (Prometheus)

v2.22.2

Migration steps

  1. Create a backup of the Kubernetes folder, in order to keep the previous configuration.

  2. Update the inventory associated with the deployment, including the inventory/group_vars/all/main.yml and inventory/group_vars/all/vault.yml. Default inventory can be taken as reference to update both files.

  3. Run the following ansible tags using the sippo-k8s tag described in the following list:
    1. mesage-broker-redeploy
      • New version and new port added to get metrics from prometheus

    2. dabasa-cluster-operator-deploy (optional)
      • mongodump -o /tmp/mongoBackup

      • kubectl cp -r <dabase-primery-node>:/tmp/mongoBackup /tmp/mongoBackup

      • kubectl cp -r /tmp/mongoBackup <dabase-operator-primery-node>:/tmp

      • mongorestore –username <mongo_user> –password <mongo-password> –authenticationDatabase admin /tmp/mongoBackup

    3. routing-deploy

    4. erebus-redeploy

    5. oauth2-proxy-redeploy

    6. qss-redeploy

    7. sfu-dispatcher-redeploy

    8. sfu-wrapper-redeploy

    9. sippo-server-redeploy

    10. postgresql-deploy
      • Migrations postgresql database

    11. xmpp-server-redeploy

    12. webphone-redeploy

    13. recording-redeploy (If needed)

    14. sippo-exporter-destroy

    15. sippo-exporter-deploy

    16. sippo-maintainer-destroy

    17. sippo-maintainer-deploy

    18. kapi-redeploy

  4. Update media server.
    • sfu-redeploy

    • audiomixer-redeploy

    • sip-proxy-redeploy

Architecture changes

PostgreSQL database deployment

The PostgreSQL database is now deployed in its own pod. This way it can be shared for both the XMPP and teal.

XMPP over TLS

We now have an additional nginx HTTP proxy in front of xmpp-server for the TLS termination of the XMPP sockets. This is needed for native apps connecting via XMPP (without websockets).

Teal for Blue/Green Environments

This new release includes a new feature affecting the deployment architecture, providing the way to balance users between Blue and Green environments in function of a cookie set by Teal, using the canary-by-cookie nginx-ingress feature. Here is a diagram representing how the Teal component set the cookie in order to manage the balancing users.

Mongo operator deployment

Those environments where Mongo database is inside the cluster, mongo operator provides the following advantages:

  • Create Mongo replica sets

  • Deploy MongoDB as Statefulset <https://kubernetes.io/es/docs/concepts/workloads/controllers/statefulset/>`_

  • Upgrade and downgrade MongoDB server version

  • Scale replica sets up and down

  • Read from and write to the replica set while scaling, upgrading, and downgrading. These operations are done in an “always up” manner.

  • Report MongoDB server state via the MongoDB resource status field

  • Use any of the available Docker MongoDB images

  • Connect to the replica set from inside the Kubernetes cluster (no external connectivity)

  • Secure client-to-server and server-to-server connections with TLS

  • Create users with SCARM authentication

Configuration changes

xmpp-server

The following configuration parameter is required in file prosody.cfg.lua in order to show the new matrix layout:

1     modules_enabled = {
2         -- other modules
3         “quobis_muc_db_mapper”;
4     }

and this change is required in file quobis.cfg.lua:

1   modules_enabled={
2         -- other modules
3        “quobis_muc_tracker”;
4   }

Static contacts service

The new StaticContacts service must be added to the wac.ini file as the other services. Note that the static contacts must be provisioned via REST using this new service, the old JSON file will not be used anymore.

Code to add into wac.ini file:

1 [staticcontacts]

Licensing service

The new Licensing service must be added to the wac.ini file as the other services in wac.ini:

1 [licensing]

Permissions service

New service Permissions.

Code to add into wac.ini file:

1[permissions]

MessageWaitingIndicator service

This service requires to set two configuration parameters: baseUrl and kamailioRabbitTopic. The first one is the URL where the register and unregister HTTP requests should be perform and the second one is the RabbitMQ topic where the VoiceMail events will be published by the Kamailio. The next lines must be added to wac.ini in order to run the service:

1 [messagewaitingindicator]
2 baseURL=”http://kamailio:5060”
3 kamailioRabbitTopic=”kamailio”

As a fix for Users removed from the system remain listed as members of the chat groups to which they belonged, it is necessary to provide new configuration parameters under xmpp.toml.

1 leaveAllMucsUrl = "http://xmpp:5280/quobis_muc_tracker/leaveAllMucs"

The services start up timeout is now configurable via wac.ini. In order to configure this value add the following line:

1 [global]
2 startUpTimeout = 150001

Recording service

The following parameters in the QSS config.json configuration file defines what to do regarding recording when there are no permissions defined in the system:

  • Default value for “record” parameter none.

  • Default value for “recordIncomingPSTN” parameter is false

// skipped code

"rooms": {
    "record": all,video,audio,none
  },

“trunk”:{
    “recordIncomingPSTN”: true
 }

The following parameter is needed in the audiomixer confbridge.conf configuration files:

// skipped code
  record_file_timestamp = no
// skipped code

The following parameter is needed in the audiomixer modules.conf configuration files:

// skipped code
  load = app_mixmonitor.so
// skipped code

The following parameters are needed in the recording service configuration file recording.toml located at sippo-recording/config/:

{
  "recordings_path": "/sippo-recording/raw_files/",
  "audio_path": "/sippo-recording/raw_audio/",
  "destination_path": "/sippo-recording/postprocessed/",
  "processing_queue": "processing_queue",
  "failure_queue": "failure_queue",
  "processed_queue": "processed_queue",
  "webm_codec": "vp8",
  "quality": "low",
  "clean_temporary_files": false,
  "fileformat": "rec-{{year}}{{month}}{{day}}-{{hours}}{{minutes}}{{seconds}}-{{uuid}}-{{confbridgeid}}",
  "should_encrypt"  : true,
  "encryption_key"  : "/sippo-recording/encryption/key.asc",
  "encryption_mail" : "mail@domain.com",
  "split_recording_output" : true,
  "mix_limit" : 9
}

The default.toml config file needs to have the following fields:

[log] level = “debug” relativePaths = true

[rabbitmq] address = “amqp://rabbitmq”

The meaning and default values of each field is explained in the table below:

Configuration options for the recording service recording.toml

Field

Comment

Default value

fileformat

Available fields that will compose the filename of the recordings, must be placed between double brackets: year, month, day, hours, minutes, seconds, uuid and confbridgeid

rec-{{year}}{{month}}{{day}}-{{hours}}{{minutes}}{{seconds}}-{{uuid}}-{{confbridgeid}}

logs_path

Path where the logs of the post-process will be saved.

/sippo-recording/logs/

recordings_path

Path where the raw video recordings will be stored.

/sippo-recording/raw_files/

audio_path

Path where the raw audio recordings will be stored.

/sippo-recording/raw_audio/

destination_path

Path where the post-processed file will be saved

/sippo-recording/postprocessed/

webm_codec

Codec that will be used when processing a video that has been recorded in VP8 or VP9. Choices: vp8 or vp9. Please note that the final codec is always WEBM

vp8

quality

Quality of the processed videos. Choices: low, medium or high

low

processing_queue

Name of the queue used for receive processing events

processing_queue

processed_queue

Queue where correctly processed messages will be placed

processed_queue

failure_queue

Name of the queue used for failures events

failure_queue

clean_temporary_files

Boolean field. If it is true, when a recording is processed correctly, all clean_temporary_files related with this conference will be deleted.

true

should_encrypt

Boolean field. If it is true, encryption is applied to the final processed recording files.

false

encryption_key

Path of the PGP encryption key.

/sippo-recording/encryption/key.asc”,

encryption_mail

Email address used for the encryption process.

Voicemail

New permission was added to give VoiceMail support to users or domains. By default is setted to false, if we want to configure VoiceMail for a user or domain we have to give them manually through the permissions REST API. Is documented in: http://ci.internal.quobis.com:8080/job/WAC/job/dev/OpenAPI_20REST_20documentation/index.html#operation/addUserPermissions It is necessary to configure the voicemail extension at config.json file, in the invites section

1 {
2     "service": {
3                  //other services
4              "invites": {
5              //other param configs
6              "voiceMailExtension": "XXXXXX"
7                  }
8     }
9}

Audiomixer

To enable ‘Who is talking’ detection the following configuration should be set in the Asterisk’s confbridge.conf:

Add the next context to the confbridge.conf file:

1 [quobis_user]
2 dsp_talking_threshold=128; default = 160
3 dsp_silence_threshold=2000; default = 2500
4 talk_detection_events=yes

SIP proxy

In a registration scenario, sip-proxy sends a REGISTER and SUBSCRIBE when it receives an http request to endpoint /register and /subscribe. Additionally, it also send the unREGISTER (register with expires to 0) and unSUBSCRIBE (subscribe with expires to 0) in order to remove the register and event subscription in the customer PBX :

 1 ####### Routing Logic ########
 2 event_route[xhttp:request] {
 3     xlog("L_INFO","PATH: $(hu{url.path})\n\r");
 4
 5
 6     #Check URL path
 7     if($(hu{url.path})=="/register"){
 8            sl_send_reply("200","OK");
 9             $var(x) = $(hu{url.querystring});
10             $var(user) = $(var(x){s.select,0,&});
11             $var(pass) = $(var(x){s.select,1,&});
12             $var(user_val)=$(var(user){s.select,1,=});
13             $var(pass_val)=$(var(pass){s.select,1,=});
14            usleep("500");
15 ##!ifdef WITH_REGISTRATION
16             sql_xquery("ca", "insert into uacreg (l_uuid, l_username, l_domain, r_username, r_domain,realm ,auth_username,auth_password,auth_ha1,auth_proxy,expires,flags,reg_delay) values ('$(var(user){s.select,1,=})' ,'$(var(user){s.select,1,=})', '$sel(cfg_get.pbx.svc_ip)', '$(var(user){s.select,1,=})', '$sel(cfg_get.pbx.svc_ip)', '$sel(cfg_get.pbx.svc_ip)', '$(var(user){s.select,1,=})','$(var(pass){s.select,1,=})', '', 'sip:$sel(cfg_get.pbx.svc_ip):$sel(cfg_get.pbx.svc_port)', 1800, 16, 600)", "ra");
17             uac_reg_enable("l_username", "$(var(user){s.select,1,=})");
18             uac_reg_refresh("$(var(user){s.select,1,=})");
19             route(REGISTER);
20 ##!endif
21     }
22 #!ifdef WITH_MWI
23     else if($(hu{url.path})=="/subscribe") {
24             $var(x) = $(hu{url.querystring});
25             $var(user) = $(var(x){s.select,0,&});
26             $var(pass) = $(var(x){s.select,1,&});
27             #Send SUBSCRIBE
28             route(SUBSCRIBEMWI);
29     }
30 #!endif
31 ##!ifdef WITH_REGISTRATION
32     else if($(hu{url.path})=="/unregister") {
33             $var(x) = $(hu{url.querystring});
34             $var(user) = $(var(x){s.select,0,&});
35             $var(pass) = $(var(x){s.select,1,&});
36             uac_reg_disable("l_username", "$(var(user){s.select,1,=})");
37             #uac_reg_refresh("$(var(user){s.select,1,=})");
38             sql_xquery("ca", "delete from uacreg where l_username='$(var(user){s.select,1,=})'", "ra");
39             route(UNREGISTER);
40     }
41 ##!endif
42 #!ifdef WITH_MWI
43     else if($(hu{url.path})=="/unsubscribe") {
44             #Send SUBSCRIBE
45             $var(x) = $(hu{url.querystring});
46             $var(user) = $(var(x){s.select,0,&});
47             $var(pass) = $(var(x){s.select,1,&});
48             route(UNSUBSCRIBEMWI);
49     }
50 #!endif
51     else if($(hu{url.path})=="/metrics") {
52             #Push prometheus metrics
53                         prom_dispatch();
54     }
55  exit;
56}

Change kamailio-sip-proxy-2.conf file too if it exists. The first register and subscribe are built by the UAC kamailio module, so that the following branches must be added.

 1#Send subscribe to voicemail event
 2route[SUBSCRIBEMWI]{
 3
 4    # SENDING MWI SUBSCRIBE
 5
 6    sl_send_reply("200","OK");
 7
 8    $var(rip) = $sel(cfg_get.pbx.svc_ip);
 9    $var(rport) = $sel(cfg_get.pbx.svc_port);
10        $var(userid) = $(var(user){s.select,1,=});
11
12    $uac_req(auser)=$(var(user){s.select,1,=});
13    $uac_req(apasswd)=$(var(pass){s.select,1,=});
14
15    $uac_req(method)="SUBSCRIBE";
16    $uac_req(ruri)="sip:" + $var(rip); #+":"+$var(rport);
17    #$uac_req(ruri)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
18    $uac_req(furi)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
19    $uac_req(turi)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
20    $uac_req(hdrs)="Event: message-summary\r\nAccept: application/sample-message-summary\r\nContact: <sip:"+$var(userid)+"@10.1.27.62:"+$var(rport)+">\r\n";
21    $uac_req(hdrs)= $uac_req(hdrs) + "Expires: 1800 \r\n";
22    uac_req_send();
23    return;
24
25 }
26
27#Send unsubscribe to voicemail event
28route[UNSUBSCRIBEMWI]{
29
30    # SENDING MWI UNSUBSCRIBE
31
32    sl_send_reply("200","OK");
33
34    $var(rip) = $sel(cfg_get.pbx.svc_ip);
35    $var(rport) = $sel(cfg_get.pbx.svc_port);
36        $var(userid) = $(var(user){s.select,1,=});
37
38    $uac_req(auser)=$(var(user){s.select,1,=});
39    $uac_req(apasswd)=$(var(pass){s.select,1,=});
40
41    $uac_req(method)="SUBSCRIBE";
42    $uac_req(ruri)="sip:" + $var(rip); #+":"+$var(rport);
43    #$uac_req(ruri)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
44    $uac_req(furi)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
45    $uac_req(turi)="sip:"+$var(userid)+"@" + $var(rip);# + ":" + $var(rport);
46    $uac_req(hdrs)="Event: message-summary\r\nAccept: application/sample-message-summary\r\nContact: <sip:"+$var(userid)+"@10.1.27.62:"+$var(rport)+">\r\n";
47    $uac_req(hdrs)= $uac_req(hdrs) + "Expires: 0 \r\n";
48    uac_req_send();
49    return;
50
51}
52
53#Register user against customer environment
54route[REGISTER]{
55    # Sending REGISTER
56
57    $var(rip) = $sel(cfg_get.pbx.svc_ip);
58    $var(rport) = $sel(cfg_get.pbx.svc_port);
59    $var(userid) = $(var(user){s.select,1,=});
60    xlog("L_INFO", "User: $(var(user){s.select,1,=}) and pass: $(var(pass){s.select,1,=}) \n");
61
62    $uac_req(auser)=$(var(user){s.select,1,=});
63    $uac_req(apasswd)=$(var(pass){s.select,1,=});
64    $uac_req(method)="REGISTER";
65    $uac_req(ruri)="sip:" + $var(rip); #+":"+$var(rport);
66    $uac_req(furi)="sip:"+$var(userid)+"@" + $var(rip); #+":"+$var(rport);
67    $uac_req(turi)="sip:"+$var(userid)+"@" + $var(rip); #+":"+$var(rport);
68    $uac_req(hdrs)="Contact: <sip:"+$var(userid)+"@10.1.27.62:5060>\r\n";
69    $uac_req(hdrs)= $uac_req(hdrs) + "Expires: 1800 \r\n";
70    uac_req_send();
71    return;
72
73}
74
75#Unregister user against customer environment
76route[UNREGISTER]{
77
78    # Sending REGISTER
79    sl_send_reply("200","OK");
80
81
82    $var(rip) = $sel(cfg_get.pbx.svc_ip);
83    $var(rport) = $sel(cfg_get.pbx.svc_port);
84    $var(userid) = $(var(user){s.select,1,=});
85    xlog("L_INFO", "User: $(var(user){s.select,1,=}) and pass: $(var(pass){s.select,1,=}) \n");
86
87    $uac_req(auser)=$(var(user){s.select,1,=});
88    $uac_req(apasswd)=$(var(pass){s.select,1,=});
89    $uac_req(method)="REGISTER";
90    $uac_req(ruri)="sip:" + $var(rip); #+":"+$var(rport);
91    $uac_req(furi)="sip:"+$var(userid)+"@" + $var(rip); #+":"+$var(rport);
92    $uac_req(turi)="sip:"+$var(userid)+"@" + $var(rip); #+":"+$var(rport);
93    $uac_req(hdrs)="Contact: <sip:"+$var(userid)+"@10.1.27.62:5060>\r\n";
94    $uac_req(hdrs)= $uac_req(hdrs) + "Expires: 0 \r\n";
95    uac_req_send();
96    return;
97}

When the SIP proxy is subscribed to a voicemail event, it receives the number of voicemails thought a NOTIFY message, so that another new branch must be added to manage the NOTIFY, get the needed information and push it to a Rabbitmq queue.

 1 route[NOTIFYMWI]{
 2     $var(voiceMails)=$(rb{s.select,4,:});
 3     $var(voiceMails)=$(var(voiceMails){re.subst,/\(([0-9])\/([0-9])\)/\r/g});
 4     $var(newVoiceMails)=$(var(voiceMails){s.select,0,/});
 5     $var(newVoiceMails)=$(var(newVoiceMails){s.ltrim});
 6     $var(totalVoiceMails)=$(var(voiceMails){s.select,1,/});
 7     $var(totalVoiceMails)=$(var(totalVoiceMails){s.rtrim});
 8     xlog("L_INFO", "JSON: {'userSipMapping': '$tU', 'newMessages': '$var(newVoiceMails)', 'totalMessages': '$var(totalVoiceMails)'} \n");
 9     $var(result)=rabbitmq_publish("sippo", "producer.kamailio","application/json","{\"payload\" : {\"userSipMapping\": \"$tU\", \"newMessages\": $var(newVoiceMails), \"totalMessages\": $var(totalVoiceMails)}, \"correlation\" : \"1234\"}");
10     sl_send_reply("200", "OK");
11     exit;
12 }

The previous new features need to include new modules.

 1 ####### Modules Section ########
 2
 3 /* set paths to location of modules */
 4 # mpath="/usr/local/lib/kamailio/modules/"
 5
 6 #!ifdef WITH_MYSQL
 7 loadmodule "db_mysql.so"
 8 #!endif
 9
10 loadmodule "xhttp.so"
11 loadmodule "xhttp_rpc.so"
12 loadmodule "xhttp_prom.so"
13
14
15 #!ifdef WITH_MWI
16 loadmodule "rabbitmq.so"
17 #!endif
18
19 loadmodule "cfgutils.so"
20
21 # ----------------- setting module-specific parameters ---------------
22 modparam("xhttp_rpc", "xhttp_rpc_root", "http_rpc")
23
24
25 #!ifdef WITH_MWI
26 modparam("rabbitmq", "url", "amqp://message-broker.dev-nightly.svc.cluster.local:5672")
27 #!endif

This version also exposes an endpoint to push metrics to Prometheus, so the following configuration must be included:

1 modparam("xhttp_prom", "xhttp_prom_stats", "all")
2
3 ####### Routing Logic ########
4 event_route[xhttp:request] {
5       else if($(hu{url.path})=="/metrics") {
6             #Push prometheus metrics
7                      prom_dispatch();
8     }
9 }

CoTURN

Turn deployment has been added to sippo-k8s:

  • Enable “[Turn]” in the host file.

  • Execute tag “passwords-deploy” to get the password command.

  • Execute tag “turn-deploy” to install.

  • Remember to configure Dispatcher service using that password.

Quobis collaborator

Webphone

  • The DISPLAY_WARNING_CLOSING_TAB parameter has been added in the CONF.js file (false by default). If its value is true, a warning pop-up is going to be opened when the user tries to close or reload the collaborator tab (browser).

  • Changed Conf file: Now we have pt_BR and pt_PT in previously pt for the language parameter ex:

LANGUAGES: ['de', ‘en', 'es', 'fr', 'it', 'pt-BR', 'pt-PT']
  • The following configuration parameter is required into CONF.js to use the new matrix layout:

1 CONFERENCE:{
2        MATRIX: true,
3 }
  • We have a new capability that comes from the domain screen-sharing true by default. If you want to disable a certain user use -screen-sharing

Upgrading from v4.1 to v4.2

Release components

Component versions for v4.2

Element

Version

sippo server

21.1.9

qss

4.12.4

oauth2-proxy

1.15.1

xmpp-server

2.2.3

Migration steps

Architecture changes

Configuration changes

Upgrading from previous version to v4.0

The upgrade from versions prior to v4.0 is not possible and a new blank installation must be done. Please contact the support team for a specific migration tool.