Polycrate API 0.14.13¶
Release-Datum: 16. März 2026
Typ: Feature-Patch
Highlights¶
- PostgreSQL Full-Text-Search – Globale Suche direkt in PostgreSQL, kein externer Dienst nötig: SearchIndex, API-Endpoint, Alpine.js-Komponente in der Topbar
- API Query Optimierungen – N+1-Fixes für Organizations, CatalogueApps und Workspaces via Django Silk identifiziert und behoben
- CatalogueApp List Pricing-Felder – Eliminiert ~97 unnötige Detail-API-Calls im externen Pricing-Calculator
- Production Performance – Gunicorn preload, Seed Job als eigene Action, Dockerfile Build-Time Assets
- Workspace Reconciliation Fix – „Commit info is missing" bei CLI-erstellten Workspaces behoben
Artefakte¶
Docker Image¶
Block¶
Neue Features¶
PostgreSQL Full-Text-Search¶
Globale Suche über alle relevanten Objekte (Workspaces, Hosts, K8sClusters, S3Buckets etc.) direkt in PostgreSQL – ohne externen Suchdienst.
Bestandteile:
SearchIndexModel (migrations/0067_searchindex.py) – speichert vorberechnetetsvector-Felder pro Objekt; wird via Celery-Task undsearch_reindexManagement Command befülltPostgresSearchService(polycrate_api/search.py) – kapselt Suche viaSearchVector/SearchQuery;search_type="plain"(korrekt für Infrastruktur-Bezeichner mit Bindestrichen)GlobalSearchAPIView– DRF-Endpoint mit Rate-Limiting (GlobalSearchThrottle,throttles.py)globalSearchAlpine.js-Komponente – Eingabefeld in der Topbar mit Debounce, Ergebnisliste mit Objekt-Typ und Link
Datenbankvoraussetzung: pg_trgm + unaccent Extensions (siehe nächster Punkt).
CNPG: pg_trgm + unaccent Extension¶
Die pg_trgm und unaccent Extensions sind in den offiziellen CNPG-Images bereits enthalten (PostgreSQL contrib-Paket). Aktivierung auf zwei Ebenen:
- CNPG
postInitTemplateSQL– Extension beim Cluster-Init intemplate1(vererbt sich an neue Datenbanken) - Django Migration
RunSQL(0066_enable_pg_trgm.py) –CREATE EXTENSION IF NOT EXISTSals idempotente Absicherung für bestehende Datenbanken
CatalogueApp List: Pricing-Felder im List-Serializer¶
Der externe Pricing-Calculator des Customer Portals verursachte bisher ~104 API-Calls pro Lauf, da für jede App ein separater Detail-Call nötig war.
Fix: product_regular und product_ha werden als vollständige Nested-Objekte (via ProductSimpleSerializer) im CatalogueAppListSerializer geliefert. Die ~97 Detail-Calls entfallen.
ManagedObject-Formulare: Submit-Indicator¶
Die generischen Create/Edit-Formulare (object_form_page.html) zeigen jetzt einen klaren Submitting/Creating/Saving-Indicator während des Absendvorgangs:
- Alpine.js-basiert:
x-data="{ submitting: false }"auf dem<form>-Element - Submit-Button wechselt zu „Saving…" + deaktiviert (verhindert Doppelklick)
Seed Job als eigene Action¶
Neues polycrate run polycrate-api seed – ein idempotenter Kubernetes Job, der statische Lookup-Daten (Provider, PoPs, Datasources) befüllt. Sicher gegen laufende API ausführbar.
install.yml+migrate.yml: seed Job wird automatisch nach migrate ausgeführtstart.sh: migrate + seed aus Prod-Startskript entfernt (nur noch Dev-Branch)
Fixes¶
S3Bucket: PROVIDER_API_SERVER_UNREACHABLE Fehlerdetail propagiert¶
S3Buckets zeigten die Condition PROVIDER_API_SERVER_UNREACHABLE ohne nachvollziehbare Ursache im Bucket-Log. Die tatsächliche Fehlerursache (SSL-Fehler, DNS, Timeout) stand nur im S3Cluster-Log.
Fix: S3Bucket.run_reconciliation() liest die reason aus der S3Cluster-Condition aus und propagiert sie in die eigene Condition sowie den Log.
Workspace Reconciliation: „Commit info is missing"¶
Bei CLI-erstellten Workspaces schlug die Reconciliation mit "Commit info is missing" fehl, wenn das verknüpfte GitLab-Projekt noch keine Commits enthielt.
Fixes:
git_commit_shawird jetzt aus den Submission-Metadaten gesetzt, wenn der Workspace via CLI Action Run Submission erstellt wirdpull_or_clone()enthält einen Guard, der leere Repositories erkennt und überspringt statt abzubrechen
Sidebar FOUC Fix¶
Beim Seitenreload erschien die Navigationssidebar kurz im aufgeklappten Zustand, bevor Alpine.js den Collapsed-Status aus localStorage anwenden konnte.
Fix:
- Inline-Script (ohne
defer) inbase.htmlliestsidebarCollapsedaus localStorage und schreibt die Grid-Spaltenbreite direkt alsstyle-Attribut – vor Alpine-Init - Alpine's
:class-Binding durch:style-Binding ersetzt
Performance & Developer Experience¶
API Query Optimierungen¶
Via Django Silk identifizierte N+1-Probleme behoben:
/api/v1/organizations/–has_active_downtimeviaprefetch_related(statt 1 EXISTS-Query pro Organization)/api/v1/catalogue-apps/– Pricing-Felder direkt im List-Serializer (eliminiert ~97 Detail-Calls)/api/v1/workspaces/– Wide-SELECT-Reduktion, Prefetch für Status-/Condition-Felder
Production Startup Optimierungen¶
- Gunicorn (
start.sh):--preload,--max-requests,--max-requests-jitter,--timeout,--graceful-timeout,--keep-alive - Dockerfile:
collectstatic+spectacularin Build-Zeit verschoben (CompressedManifestStaticFilesStorage) – spart Startzeit - Celery Beat (
start-beat.sh): Log-Leveldebug→warning - Flower: Aus Prod-Block entfernt
Django Silk API Profiling (Development)¶
Django Silk ist in der Development-Umgebung aktiv und erfasst alle HTTP-Requests inklusive DRF API Calls.
Silk-Dashboard: /silk/
Migration¶
Zwei neue Datenbank-Migrationen sind enthalten:
0066_enable_pg_trgm– Aktiviertpg_trgmundunaccentExtensions0067_searchindex– Erstellt dasSearchIndex-Model
Nach dem Update search_reindex ausführen, um den initialen Suchindex zu befüllen:
Oder via Celery Task (wird automatisch getriggert).
Direktes Update von 0.14.12 möglich. polycrate run polycrate-api migrate ausführen.