posit-dev / posit-dev/team-operator

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

Open
#159 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
10
Forks
1
Avg merge
1d 8h
Merged PRs (30d)
4

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with internal/controller/core/site_controller_keycloak.go and the host comparison around line 448 of internal/controller/core/postgresdatabase_controller.go. Reproduce with keycloak enabled and main-database-url set to postgresql://host:5432/db?sslmode=require, then trace the usernameSecret path as well. Done means explicit ports no longer trigger a host mismatch and the provisioned database role matches the username used by Keycloak.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes, postgresql
Domain
backend, database, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.