mgr-tenant-entitlements

Overview

The mgr-tenant-entitlements component manages application installations for each tenant. It can configure Keycloak resources, set up Kong routes, and install application modules through the Tenant API. All installed modules are recorded within the entitlement information. All additional data, such as capabilities, system user information, and system scheduler timers, is supplied asynchronously through a message bus, specifically Apache Kafka.

Additionally, it maintains a record of tenant entitlements flow to enhance observability.

Application Flows

Entitlement Flow (Installation Flow)

Application entitlement flow can be performed using rollback or not. It is controlled using ignoreErrors query parameter.

If rollbacks (stage cancellation) are enabled, they can result in the loss of existing database information if the environment was built using a database snapshot. This situation can only occur if one of the module installation stages fails, triggering a call to the Tenant API for all installed modules.

Main purpose of entitlement flows with rollbacks is to return environment to a state where entitlement never happened before.

If the environment is build on the database snapshot - it is recommended to use ignoreErrors=true in query parameters to avoid purging tenant data.

Failed entitlement flows can be repeated several times until sucess.

Revoke Flow (Uninstallation Flow)

Applications can be disabled or deleted for the tenant. It is controlled by a query parameterpurge=true

If purge is set to true - all tenant data for the application will be removed:

  • Keycloak authorization resources

    • It will lead to cascade removal of created user and role permissions

    • Users, roles, and policies will remain in Keycloak

  • Kong tenant routes

  • All sidecars for application will be disabled for the requested tenant

  • Modules data - Tenant API will be called with parameter purge=true

If purge parameter is set to false, only Keycloak routes and sidecars will be affected.

Upgrade Flow

Upgrade operation is only performed to the modules with changed modified modules in the application descriptor

For example:

Updating application[mod-foo-1.0.0, mod-bar-1.0.0, mod-deprecated-1.0.0] to application[mod-foo-1.1.0, mod-new-1.0.0, mod-bar-1.0.0] will produces the following actions:

  1. mod-foo-1.1.0 will be enabled using Tenant API

  2. Sidecar for mod-foo-1.0.0 will be disabled, and sidecar for mod-foo-1.1.0 will be enabled through the Kafka events

  3. Kong routes and Keycloak resources will be updated for mod-foo-1.1.0

  4. Sidecar for mod-deprecated-1.0.0 will be disabled, no Tenant API call will be performed for deprecated module

  5. Kong routes and Keycloak resources will be removed for mod-deprecated-1.0.0

  6. mod-new-1.0.0 will be enabled using Tenant API

  7. Kong routes and Keycloak resources will be created for mod-new-1.0.0

  8. Sidecar for mod-new-1.0.0 will be enabled through the Kafka event

Database Schema

image-20241029-145053.png
@startuml hide empty methods left to right direction !procedure $schema($name, $slug) package "$name" as $slug <<Rectangle>> !endprocedure !procedure $table($name, $slug) entity "<b>$name</b>" as $slug << (T, Orange) table >> !endprocedure !procedure $view($name, $slug) entity "<b>$name</b>" as $slug << (V, Aquamarine) view >> !endprocedure !procedure $pk($name) <color:#GoldenRod><&key></color> <b>$name</b> !endprocedure !procedure $fk($name) <color:#Silver><&key></color> $name !endprocedure !procedure $column($name) {field} <color:#White><&media-record></color> $name !endprocedure $schema("public", "mgr_tenant_entitlement_db") { $table("application_dependency", "application_dependency") { $pk("application_id"): varchar $pk("tenant_id"): uuid $pk("parent_name"): varchar $pk("parent_version"): varchar $column("application_name"): varchar $column("application_version"): varchar } $table("application_flow", "application_flow") { $pk("application_flow_id"): uuid $column("application_id"): varchar $column("tenant_id"): uuid $column("flow_id"): uuid $column("type"): entitlement_flow_type $column("status"): entitlement_flow_status_type $column("started_at"): timestamp $column("finished_at"): timestamp $column("application_name"): varchar $column("application_version"): varchar } $table("entitlement", "entitlement") { $pk("tenant_id"): uuid $pk("application_id"): varchar $column("application_name"): varchar $column("application_version"): varchar } $table("entitlement_module", "entitlement_module") { $pk("module_id"): varchar $pk("tenant_id"): uuid $pk("application_id"): varchar } $table("flow", "flow") { $pk("flow_id"): uuid $column("tenant_id"): uuid $column("type"): entitlement_flow_type $column("status"): entitlement_flow_status_type $column("started_at"): timestamp $column("finished_at"): timestamp } $table("flow_stage", "flow_stage") { $pk("flow_id"): uuid $pk("stage"): varchar $column("status"): entitlement_stage_status_type $column("error_message"): text $column("started_at"): timestamp $column("finished_at"): timestamp $column("error_type"): varchar } } @enduml