.. SPDX-FileCopyrightText: 2024 - 2025 Univention GmbH
..
.. SPDX-License-Identifier: AGPL-3.0-only

.. _ics-deployment:

******************************
Deployment of Intercom Service
******************************

The *Intercom Service* is an intermediary for communication between applications
like :spelling:ignore:`Nextcloud`, OX App Suite, and Matrix.
It's part of the Nubus for Kubernetes architecture, but not part of the default deployment.

This section describes the deployment of the *Intercom Service* in a Kubernetes cluster for Nubus.
It covers the mandatory configuration settings and the deployment commands.

.. seealso::

   :external+uv-nubus-kubernetes-architecture:ref:`overview-components-intercom-service`
      in :cite:t:`uv-nubus-kubernetes-architecture`
      for information about purpose and architecture of the *Intercom Service*.

   `univention_ics Repository <https://gitlab.opencode.de/bmi/opendesk/component-code/crossfunctional/univention/univention_ics>`_ at OpenCoDE
      for the repository of the Helm Chart.

.. _ics-deployment-mandatory-settings:

Mandatory settings for Intercom Service
=======================================

*Intercom Service* needs various settings for the Helm Chart for its deployment.
The Helm Chart key-value pairs listed are mandatory.
You need to define them in your :file:`custom_values_ics.yaml` values file before you can deploy
*Intercom Service*.
You also need to ensure that you use a separate values file than for Nubus.

:numref:`ics-deployment-mandatory-settings-example-listing` shows an example that you can copy as basis for your adjustments.
It's recommended that you deactivate all services in *Intercom Service*
and only activate the ones, you really use.
*Intercom Service* has enabled all services by default.

For a reference list about the Helm Chart values for *Intercom Service*,
see :ref:`ics-helm-chart-reference`.

.. code-block:: yaml
   :caption: Example :file:`custom_values_ics.yaml` values file
   :name: ics-deployment-mandatory-settings-example-listing

   ics:
     default:
       domain: "ics.example.com"
     secrets: "some_secret_for_ics"
     oidc:
       secret: "some_secret_for_ics_OIDC_client"
     portal:
       apiKey:
         name: "nubus-portal-server-central-navigation-shared-secret"
         key: "authenticator.secret"
       url: "portal.example.com"
     redis:
       password: "some_password_for_redis"
     ingress:
       host: "ics.example.com"
     provisioning:
       config:
         nubusBaseUrl: "ics.example.com"
         keycloak:
           username: "kcadmin"
           credentialSecret:
             name: "nubus-keycloak-credentials"
             key: "admin_password"
         ics_client:
           credentialSecret:
             name: ""
             key: ""
     keycloak:
       enabled: true
       realm: "nubus"
       subdomain: "id.example.com"
     matrix:
       enabled: false
     nordeck:
       enabled: false
     portal:
       enabled: false
     openxchange:
       enabled: false
     nextcloud:
       enabled: false

.. _ics-deployment-encrypted-key-value-db-connection:

Encrypted connection to key-value database
==========================================

*Intercom Service* uses the *Redis* key-value database
to silently manage authenticated sessions in the background.
For example, you can use *Intercom Service* with an encrypted connection to *Redis*
in clusters that don't allow unencrypted connections.
This section describes how to configure an encrypted connection to *Redis* through the Helm Chart,
and how to optionally also configure a custom CA.

To configure an encrypted connection to *Redis*, follow these steps:

#. To enable SSL,
   add the respective lines in
   :numref:`ics-deployment-encrypted-key-value-db-connection-enable-listing`
   in your :file:`custom_values_ics.yaml` values file.

   .. code-block:: yaml
      :caption: Enable encrypted connection to the *Redis* database
      :name: ics-deployment-encrypted-key-value-db-connection-enable-listing

      ics:
        redis:
          host: "<your-redis-connection-host>"
          port: "<your-redis-connection-port>"
          password: "<your-redis-connection-password>"
          ssl:
            enabled: true

#. Optional: To use a custom CA when validating the server's TLS certificate,
   add the lines from
   :numref:`ics-deployment-encrypted-key-value-db-connection-custom-ca-listing`
   to your :file:`custom_values_ics.yaml` values file.

   .. code-block:: yaml
      :caption: Add custom CA for the encrypted connection to *Redis*
      :name: ics-deployment-encrypted-key-value-db-connection-custom-ca-listing

      ics:
        redis:
          ssl:
            enabled: true
            customca: |
              -----BEGIN CERTIFICATE-----
              <your-custom-CA>
              -----END CERTIFICATE-----

#. Optional: To provide a client certificate for mTLS authentication,
   add the lines from
   :numref:`ics-deployment-encrypted-key-value-db-connection-mtls-listing`
   to your :file:`custom_values_ics.yaml` values file.

   .. code-block:: yaml
      :caption: Activate mTLS and add certificate
      :name: ics-deployment-encrypted-key-value-db-connection-mtls-listing

      ics:
        redis:
          ssl:
            mTLS:
              enabled: true
              clientCert: |
                -----BEGIN CERTIFICATE-----
                <client-certificate>
                -----END CERTIFICATE-----
              clientKey: |
                -----BEGIN PRIVATE KEY-----
                <client-certificate-key>
                -----END PRIVATE KEY-----

   If you have a Kubernetes secret containing the mTLS certificate and its key,
   you can use that one instead.
   See :numref:`ics-deployment-encrypted-key-value-db-connection-mtls-secret-listing`.

   .. code-block:: yaml
      :caption: Activate mTLS and use existing TLS secret
      :name: ics-deployment-encrypted-key-value-db-connection-mtls-secret-listing

      ics:
        redis:
          ssl:
            mTLS:
              enabled: true
              existingSecret:
                name: "<your-tls-secret-name>"

   .. seealso::

      `TLS Secret in Secrets | Kubernetes <https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets>`_
         for more information about the Kubernetes TLS secret object.

#. To apply the configuration, follow the steps in :ref:`ics-deployment-deploy`.

.. _ics-helm-chart-reference:

Helm Chart reference for Intercom Service
=========================================

This section provides a reference for the Helm Chart values available for *Intercom Service*.

.. envvar:: ics.default.domain

   Defines the base domain for the subdomains of the apps.

.. envvar:: ics.secrets

   Defines the value of the shared secret with other services.
   Intercom Service also uses this setting to sign the session cookie.

   It needs to have the same value as :envvar:`provisioning.config.ics_client.clientSecret`.

.. envvar:: ics.issuerBaseUrl

   Defines the base URL of the issuer.
   You either define :envvar:`ics.keycloak.url` and :envvar:`ics.keycloak.realm`
   or :envvar:`ics.issuerBaseUrl`.

.. envvar:: ics.keycloak.url

   Defines the URL to Keycloak as FQDN.
   It's mutual exclusive with :envvar:`ics.keycloak.subdomain`.

   Example:
      ``https://id.example.com``

.. envvar:: ics.keycloak.realm

   Defines the Keycloak realm for *Intercom Service*.

.. envvar:: ics.keycloak.subdomain

   Defines the subdomain where *Intercom Service* can reach Keycloak.
   Set the value to combined values of :envvar:`global.subDomains.keycloak` and :envvar:`global.domain`.

   Example:
      ``id.example.com``.

.. envvar:: ics.oidc.secret

   *Intercom Service* registers itself as OIDC client to Keycloak.
   This setting defines the secret for the *Intercom Service* OIDC client.

.. envvar:: ics.portal.apiKey

   Defines the API key to the Nubus Portal Service.
   Provide a mapping with the following content:

   * ``name``: ``<release-name>-portal-server-central-navigation-shared-secret``
   * ``key``: ``authenticator.secret``

.. envvar:: ics.portal.url

   Defines the URL of the Nubus Portal Service.
   Set the value to the combined values of :envvar:`global.subDomains.portal` and
   :envvar:`global.domain`

   Example:
      ``portal.example.com``

.. envvar:: ics.redis.host

   Defines the FQDN for the *Redis* database that *Intercom Service* connects to.

.. envvar:: ics.redis.port

   Defines the TCP port for the *Redis* database connection.
   According to `Install Redis <https://redis.io/docs/latest/operate/oss_and_stack/install/archive/install-redis/>`_
   the default port number is ``6379``.

.. envvar:: ics.redis.password

   Defines the password for the :program:`Redis` cache service.
   You need to define the password in the values file.

.. envvar:: ics.redis.ssl.enabled

   Controls if *Intercom Service* uses an encrypted connection to the *Redis* database.
   The default value is ``false``.

   When you set the value to ``true``,
   also read :ref:`ics-deployment-encrypted-key-value-db-connection`
   for information about the setup around an encrypted connection.

.. envvar:: ics.redis.ssl.customca

   Holds a custom CA certificate for the connection to the *Redis* database
   so that *Intercom Service* can validate the TLS certificate.

.. envvar:: ics.redis.ssl.mTLS.enabled

   Controls if *Intercom Service* uses mTLS for the encrypted connection to the *Redis* database.
   The default value is ``false``.

   When you set the value to ``true``,
   also read :ref:`ics-deployment-encrypted-key-value-db-connection`
   for information about the setup around an encrypted connection.

.. envvar:: ics.redis.ssl.mTLS.clientCert

   Holds the client certificate for the mTLS configuration for the connection to the *Redis* database.

.. envvar:: ics.redis.ssl.mTLS.clientKey

   Holds the client key for the mTLS configuration for the connection to the *Redis* database.

.. envvar:: ics.redis.ssl.mTLS.existingSecret.name

   Defines the secret name to an existing Secret object
   that contains the mTLS certificate and the mTLS key.
   For the required keys in the secret,
   see
   `TLS Secret in Secrets | Kubernetes <https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets>`_.

.. envvar:: ics.ingress.host

   Defines the FQDN for *Intercom Service*.
   The user's browser must resolve it,
   because the browser is the client that uses *Intercom Service* functionality.

   Example:
      ``ics.example.com``

   Mostly, the client to the services is the user's browser and not the services in the cluster network themselves.

.. envvar:: provisioning.config.nubusBaseUrl

   Set it to the same value as :envvar:`ics.ingress.host` in URL format.

   Example:
      ``https://ics.example.com``

.. envvar:: provisioning.config.keycloak.username

   The username to a user account in Keycloak that has permission to create a client in Keycloak.
   *Intercom Service* uses this user account to create the client in Keycloak on its own.

.. envvar:: provisioning.config.keycloak.credentialSecret

   In Nubus the secret ``<release-name>-keycloak-credentials`` contains the value in the key ``admin_password``.
   You can either set the value here or provide a pointer to the secret in the secret map.
   Provide a map with ``name`` and ``key``,
   as shown in the example in :numref:`ics-deployment-mandatory-settings-example-listing`.

.. envvar:: provisioning.config.keycloak.password

   Define the value for the :envvar:`provisioning.config.keycloak.username` in this setting
   or use :envvar:`provisioning.config.keycloak.credentialSecret`.

   Recommendation:
      Use :envvar:`provisioning.config.keycloak.credentialSecret`.

.. envvar:: provisioning.config.ics_client.credentialSecret

   Defines where to find the secret for the *Intercom Service* client.
   Provide a map with ``name`` and ``key``,
   as shown in the example in :numref:`ics-deployment-mandatory-settings-example-listing`.

   It needs to have the same value as :envvar:`ics.secrets`
   and :envvar:`provisioning.config.ics_client.clientSecret`.

.. envvar:: provisioning.config.ics_client.clientSecret

   Define the value for the *Intercom Service* client secret.

   It needs to have the same value as :envvar:`ics.secrets`.

   Recommendation:
      Use :envvar:`provisioning.config.ics_client.credentialSecret`.

.. _ics-deployment-deploy:

Deploy Intercom Service
=======================

To deploy *Intercom Service*, use the following steps:

#. Make sure you :ref:`configured the mandatory settings <ics-deployment-mandatory-settings>`
   in your :file:`custom_values_ics.yaml` values file for *Intercom Service*.

#. Define the environment variables for the Helm chart command,
   as shown in :numref:`ics-deployment-deploy-environment-listing`.
   For the current version,
   see the :external+uv-ics-app:ref:`changelog <app-changelog>`
   of the *Intercom Service*.

   .. code-block:: console
      :caption: Define environment variables for *Intercom Service* deployment
      :name: ics-deployment-deploy-environment-listing

      $ export RELEASE_NAME="nubus-ics"
      $ export VERSION="<the-ics-version>"

   .. TODO: The deployment doesn't mention the version for ICS. Where can the reader find version information?

#. Deploy *Intercom Service* with Helm using the command in :numref:`ics-deployment-deploy-helm-listing`.

   .. code-block:: console
      :caption: Deploy *Intercom Service* through Helm
      :name: ics-deployment-deploy-helm-listing

      $ helm upgrade \
         --install \
         --values custom_values_ics.yaml \
         --version "$VERSION" \
         "$RELEASE_NAME" \
         oci://artifacts.software-univention.de/nubus/charts/intercom-service
