openova/platform/newapi/chart/Chart.yaml
e3mrah 74d23ab3dc
fix(charts): explicit harbor.openova.io/proxy-dockerhub prefix on all chart-hook images (#163) (#1367)
Per CLAUDE.md MIRROR-EVERYTHING inviolable rule: every chart-hook
image reference (pre/post-install Jobs, helper Pods) must use the
explicit Harbor proxy-cache form. Fix #158's bitnami → bitnamilegacy
swap was a band-aid; the architecturally correct fix is to defeat
upstream-deletion blast radius entirely by routing through Harbor.

The node-level containerd mirror in infra/hetzner/cloudinit-control-
plane.tftpl (line 706) already redirects docker.io/* →
harbor.openova.io/proxy-dockerhub/* implicitly, but implicit routing:
  - Hides the routing from SBOM scans
  - Bypasses the Kyverno harbor-proxy-pull ClusterPolicy
  - Means a chart audit (`grep docker.io`) misses a real dependency
  - Was the proximate cause of prov #27 wedging when Bitnami deleted
    docker.io/bitnami/kubectl:1.30.4 (Fix #158 had to chase the
    deletion mid-flight instead of being insulated by Harbor cache)

19 chart-hook image: refs + 5 chart values.yaml repository: defaults
now carry the explicit harbor.openova.io/proxy-dockerhub prefix.
Application/subchart images (keycloak, postgresql, mongodb in
keycloak+litmus subcharts) are intentionally out of scope for this
PR — those go through the node-level containerd mirror still.

Affected blueprints + chart version bumps:
  bp-cert-manager            1.2.1  -> 1.2.2
  bp-external-secrets-stores 1.0.4  -> 1.0.5
  bp-crossplane-claims       1.1.4  -> 1.1.5
  bp-flux                    1.2.1  -> 1.2.2
  bp-guacamole               0.1.16 -> 0.1.17
  bp-self-sovereign-cutover  0.1.28 -> 0.1.29
  bp-k8s-ws-proxy            0.1.9  -> 0.1.10
  bp-harbor                  1.2.15 -> 1.2.16
  bp-gitea                   1.2.5  -> 1.2.6
  bp-newapi                  1.4.5  -> 1.4.6
  bp-wordpress-tenant        0.2.0  -> 0.2.1
  catalyst-platform          1.4.138 -> 1.4.139

Co-authored-by: e3mrah <1234567+e3mrah@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 11:32:21 +04:00

167 lines
8.6 KiB
YAML

apiVersion: v2
name: bp-newapi
# 1.4.4 (qa-loop bounded-cycle audit prov #20 Fix #138, 2026-05-11): add
# pre-install/pre-upgrade hook (templates/000-external-secrets-webhook-
# readiness-job.yaml) that polls the external-secrets validating-
# admission webhook (`external-secrets-webhook.external-secrets-system.
# svc:443/validate-external-secrets-io-v1beta1-externalsecret`) until
# it returns a structured HTTP response (200/400/405/415/422). Closes
# the race between bp-external-secrets reaching HR Ready=True (Pods
# Ready) and the apiserver-side EndpointSlice for the webhook Service
# being observable by the validating admission controller.
#
# ROOT CAUSE (prov #20):
# bp-newapi 1.4.2 HR FAILED with the chart's templates/external-
# secret.yaml apply rejected by the apiserver:
# Internal error occurred: failed calling webhook
# "validate.externalsecret.external-secrets.io": ...
# no endpoints available for service "external-secrets-webhook"
# bp-external-secrets satisfies Flux dependsOn the moment its
# Deployments report Ready, but Pod Ready ≠ webhook EndpointSlice
# reachable. The chart immediately tried to apply ExternalSecret and
# the webhook returned 503/connect-error.
#
# CANONICAL SEAM (Inviolable Principle #16):
# The chart that CONSUMES the webhook owns the readiness gate — NOT
# the upstream external-secrets chart (owned by Fix #137 territory)
# and NOT a Flux HR-level dependsOn (which checks the wrong layer).
# Fix #138 mirrors Fix #137's pattern but probes a different
# validation endpoint (ExternalSecret vs ClusterSecretStore).
#
# TEMPLATABILITY (Inviolable Principle #4):
# Every knob (webhook service name, namespace, port, path, timeout,
# interval, gate-enabled flag) is operator-tunable from per-
# Sovereign overlays via .Values.externalSecretsWebhookGate.*.
#
# 1.4.3: deploy-only bump (a9861f94 — no semantic change beyond
# carrying the v0.13.2 image-tag fix to the bootstrap-kit).
#
# 1.4.2 (qa-loop bounded-cycle audit prov #7 Gap F, 2026-05-10): point
# `.Values.newapi.image.tag` at a tag that ACTUALLY EXISTS in GHCR. Pre-
# 1.4.2 the chart referenced `ghcr.io/openova-io/openova/newapi-mirror:
# v0.4.5` — a tag that was never built by any CI workflow and never
# pushed to GHCR (the package itself didn't exist; the original commit
# 44d0200a invented the tag with no matching CI build). Every fresh
# Sovereign's NewAPI Pod ImagePullBackOff'd, blocking alice signup
# gate 5 (LLM).
#
# Fix:
# - NEW .github/workflows/build-bp-newapi.yaml — mirrors
# `docker.io/calciumion/new-api:<UPSTREAM_VER>` to
# `ghcr.io/openova-io/openova/newapi-mirror:<UPSTREAM_VER>` on every
# push to platform/newapi/chart/**. Mirrors the bp-guacamole CI
# pattern: capture upstream repo digest, re-tag into GHCR, bump
# values.yaml + Chart.yaml + dispatch blueprint-release.
# - values.yaml — bump `newapi.image.tag` from `v0.4.5` (fictitious)
# to `v0.13.2` (latest stable Calcium-Ion/new-api on Docker Hub
# at the authoring date, 2026-04-27 upstream publish). The
# v1.0.0-rc.x line is gated on upstream stabilising the schema
# migration; the channel-seed Job uses the legacy admin-API request
# shape, so do NOT auto-roll past v0.13.x without re-running the
# channel-seed integration smoke.
# - appVersion bumped from `0.4.5` to `0.13.2` to match the mirrored
# upstream (Helm convention: appVersion = upstream version without
# the `v` prefix; consumers reading `helm list` see the actual
# NewAPI release running).
#
# 1.4.1 (issue #952, 2026-05-05): templatize spec.imagePullSecrets on the
# Deployment + channel-seed Job and default `imagePullSecrets:
# [{name: ghcr-pull}]` in values.yaml. Pre-1.4.1 the Pod template emitted
# no imagePullSecrets, so kubelet pulled the PRIVATE
# `ghcr.io/openova-io/openova/newapi-mirror` and
# `ghcr.io/openova-io/openova/services-metering-sidecar` images
# anonymously and got 403 Forbidden on every fresh Sovereign — blocking
# alice signup gate 5 (LLM). The cloud-init `flux-system/ghcr-pull`
# Secret is reflected into the `newapi` namespace via bp-reflector
# annotations (paired with #952 cloud-init update adding `newapi` to the
# `reflection-auto-namespaces` list).
#
# 1.4.0 (issue #943, 2026-05-05): auto-provision CNPG-backed Postgres +
# in-chart credentials Secret so a Sovereign install at bootstrap-kit
# slot 80 lands a real Pod without operator intervention.
#
# Pre-#943 the deployment.yaml gate REQUIRED operator-supplied
# `database.existingSecret` AND `credentials.existingSecret` — the Pod
# silently skipped render whenever either was empty. On a freshly
# franchised Sovereign nothing populated those values, so NewAPI never
# came up and alice signup gate 5 (LLM) timed out waiting for the
# customer-facing /v1/* API to respond.
#
# Fix:
# - NEW templates/cnpg-cluster.yaml — when .Values.cnpg.enabled
# (DEFAULT true), renders postgresql.cnpg.io/v1.Cluster
# `<release>-newapi-pg` + a Helm-`lookup`-persistent DSN Secret
# `<release>-newapi-db-dsn` (key: SQL_DSN) read by the deployment.
# Capabilities-gated on postgresql.cnpg.io/v1 so a cold install
# before bp-cnpg is Ready surfaces as "no Cluster yet" rather
# than a hard install error (mirrors platform/powerdns/chart/
# templates/cnpg-cluster.yaml's pattern).
# - NEW templates/credentials-secret.yaml — when
# .Values.credentials.autoProvision (DEFAULT true) AND
# .Values.credentials.existingSecret is empty, renders
# `<release>-app-creds` carrying SESSION_SECRET + CRYPTO_SECRET
# (each 64-char randAlphaNum, persistent across reconciles via
# Helm `lookup`). helm.sh/resource-policy: keep so a re-install
# recovers the same bytes (otherwise an upgrade silently rotates
# the keys, invalidating every active session cookie + every
# encrypted token).
# - deployment.yaml — Secret name resolution now picks the chart-
# emitted defaults when the operator hasn't supplied an override.
# The Pod-render gate accepts EITHER an explicit existingSecret
# OR the auto-provisioned one.
# - values.yaml — adds .Values.cnpg.* and .Values.credentials.
# {autoProvision,autoSecretName} blocks; every knob is operator-
# overridable per Inviolable Principle #4.
#
# 1.3.0: defaultChannels.qwenBankDhofar (channel #1 = Qwen3.6 @
# https://llm-api.omtd.bankdhofar.com) + post-install/post-upgrade
# `channel-seed` Helm hook Job that idempotently POSTs default
# channels into NewAPI's admin API at /api/channel/. Bridges the
# previous documentation-only channels.yaml ConfigMap → the actual
# Postgres-backed channel rows the upstream binary reads at runtime.
# Issue #915 (epic SME tenant integration DoD: alice → OpenClaw →
# NewAPI → Qwen3.6@BankDhofar end-to-end).
# 1.2.0: Traefik Middleware gated behind ingress.middleware.enabled.
# 1.4.6 (Fix #163, 2026-05-11, MIRROR-EVERYTHING): 000-external-secrets-
# webhook-readiness-job hook image switched from curlimages/curl:8.10.1
# to harbor.openova.io/proxy-dockerhub/curlimages/curl:8.10.1 per
# CLAUDE.md inviolable rule.
version: 1.4.6
appVersion: "0.13.2"
description: |
Catalyst Blueprint scratch chart for NewAPI — multi-tenant LLM
marketplace gateway.
No first-party Helm chart is published by the NewAPI upstream
(https://github.com/Calcium-Ion/new-api ships a docker-compose only).
This chart hand-wires the upstream container image as a
Deployment + Service + Ingress (split customer-API vs ops-admin) +
ConfigMap + ServiceAccount + NetworkPolicy + ExternalSecret consumers.
Connects to:
- bp-cnpg (Postgres for users, credits, channels, audit log)
- bp-valkey (session and rate-limit cache)
- bp-keycloak (OIDC for ops-staff admin UI)
- bp-external-secrets (DB DSN, master key, per-channel provider keys)
- bp-vllm (in-cluster cheap-tier inference channel; optional)
Customer surface is NOT this chart — Catalyst is the customer-facing
UI. This chart's customer surface is the OpenAI-compatible API at
`api.<host>/v1/*`. The upstream's portal UI is intentionally disabled
via the ingress configuration.
Pairs with bp-cnpg, bp-keycloak, bp-external-secrets, bp-valkey,
bp-vllm (depends.list in blueprint.yaml).
type: application
keywords: [catalyst, blueprint, newapi, llm, gateway, marketplace, multi-tenant, credits, byok, openai-compatible, reseller]
maintainers:
- name: OpenOva Catalyst
email: catalyst@openova.io
# Scratch chart — see comments in bp-librechat/chart/Chart.yaml for the
# rationale on the `common` library subchart dependency (issue #181
# hollow-chart gate).
dependencies:
- name: common
version: "0.1.3"
repository: "https://sigstore.github.io/helm-charts"