Skip to content

Keycloak DB provisioning fails when main-database-url has an explicit port (Hostname/Host compare asymmetry) #159

Description

@mariosmith90

Found standing up a Keycloak-enabled Site on team-operator v1.30.2 (workshop rebuild, rstudio/rstudio-ide-automation#5619).

Symptom: the Site's <site>-keycloak PostgresDatabase never reconciles — postgres database mismatched db host — so the keycloak role/database are never created and the Keycloak StatefulSet crashloops on FATAL: password authentication failed for user "keycloak".

Cause: an asymmetry in how the keycloak path builds its PostgresDatabase versus how the reconciler compares hosts:

  • internal/controller/core/site_controller_keycloak.go builds the config with Host: dbUrl.Hostname()port stripped.
  • internal/controller/core/postgresdatabase_controller.go (~L448) compares specDbUrl.Host != mainDBURL.Hosturl.Host includes the port.

So whenever the workload secret's main-database-url carries an explicit :5432, the keycloak compare fails unconditionally (spec side is portless), while connect/pm/workbench pass because their spec URLs retain the port. Deployments with portless URLs (the PTD convention) never hit it, which is presumably why it went unnoticed.

Repro: Site with keycloak.enabled: true and a workload secret main-database-url of postgresql://host:5432/db?sslmode=require.

Workaround: write main-database-url without the explicit port (postgres defaults to 5432).

Suggested fix: compare hostnames consistently — either specDbUrl.Hostname() != mainDBURL.Hostname() in the reconciler, or keep the port in the keycloak path (Host: dbUrl.Host).


Addendum — second asymmetry in the same path (username): the reconciler provisions the role from the PostgresDatabase URL username (<site>_keycloak, e.g. workshop_site_keycloak), but the Keycloak CR wires usernameSecret to the site secret's keycloak-db-user key, which nothing forces to match. A deployment supplying keycloak there gets a Keycloak that can never authenticate (FATAL: password authentication failed for user "keycloak") while the actual role sits unused. Suggested fix: derive both from one source — either provision the role from usernameSecret, or render usernameSecret from the URL username.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions