package main // The repair against a real Keycloak (issue 179's procedure, run by the guard). Skipped unless // MESH_KEYCLOAK_LIVE_CONTAINER names a throwaway Keycloak 26 container whose realm was created with // another admin password than "new", and MESH_KEYCLOAK_LIVE_URL reaches it, e.g.: // // docker network create kc-live // docker run -d --name kc-live-db --network kc-live -e POSTGRES_PASSWORD=pg -e POSTGRES_DB=keycloak postgres:17-alpine // docker run -d --name kc-live --network kc-live -p 127.0.0.1:18080:8080 \ // -e KC_DB=postgres -e KC_DB_URL=jdbc:postgresql://kc-live-db/keycloak -e KC_DB_USERNAME=postgres \ // -e KC_DB_PASSWORD=pg -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=old \ // quay.io/keycloak/keycloak:26.0.8 start-dev // MESH_KEYCLOAK_LIVE_CONTAINER=kc-live MESH_KEYCLOAK_LIVE_URL=http://127.0.0.1:18080 go test -run Live ./... // // A database whose admin kept an older password than the mesh's is exactly that container. import ( "os" "strings" "testing" "time" ) func TestLiveRepair(t *testing.T) { container, base := os.Getenv("MESH_KEYCLOAK_LIVE_CONTAINER"), os.Getenv("MESH_KEYCLOAK_LIVE_URL") if container == "" || base == "" { t.Skip("no MESH_KEYCLOAK_LIVE_CONTAINER / MESH_KEYCLOAK_LIVE_URL") } kc := NewClient(base, "admin", func() (string, error) { return "new", nil }, "master") var said, events []string g := &Guard{KC: kc, Container: container, Log: func(f string, a ...any) { said = append(said, f) }, Announce: func(e string, _ map[string]any) { events = append(events, e) }} if s, err := g.Check(ctx); s != AdminRejected { t.Fatalf("the container's admin should refuse the mesh's password first: %s %v", s, err) } start := time.Now() r := g.Ensure(ctx, true, false) if !r.Repaired { t.Fatalf("not repaired after %s: %+v %+v", time.Since(start), r, r.LastRepair) } t.Logf("repaired in %s", time.Since(start).Round(time.Second)) users, err := kc.ListUsers(ctx, "master", "", 100) if err != nil { t.Fatal(err) } for _, u := range users { if name, _ := u["username"].(string); strings.HasPrefix(name, "mesh-repair-") { t.Fatalf("the temporary admin %s is still there", name) } } if strings.Join(events, ",") != EventRepaired { t.Fatal(events) } // And a second pass changes nothing. if r := g.Ensure(ctx, true, false); r.Repaired || r.State != AdminOK { t.Fatalf("%+v", r) } }