openova/docs
e3mrah 0511efbdac
feat(bp-harbor): vendor-agnostic Object Storage backend (closes #383) (#437)
Reworks bp-harbor to write blobs DIRECTLY to the cloud-provider's
native S3 endpoint (Hetzner Object Storage on Hetzner Sovereigns)
per ADR-0001 §13. Mirrors the post-#425 vendor-agnostic seam shipped
in bp-velero:1.2.0 (PR #435 / SHA 0172b9a8) 1:1.

Canonical seam used (per anti-duplication rule + docs/omantel-
handover-wbs.md §3a):
  - Sealed Secret name:   flux-system/object-storage  (NOT hetzner-prefixed)
  - Chart values block:   .Values.objectStorage.s3.{enabled,credentialsSecretName,s3.{accessKey,secretKey}}
  - Template filename:    templates/objectstorage-credentials.yaml
  - Reference impl:       platform/velero/chart/ (PR #435)

Chart changes (platform/harbor/chart/):
  - Chart.yaml: 1.0.0 → 1.1.0; description rewritten to emphasise
    cloud-direct architecture + remove SeaweedFS hard-dep claim.
  - values.yaml: REMOVED hardcoded SeaweedFS endpoint
    (http://seaweedfs-s3.seaweedfs.svc.cluster.local:8333) from
    persistence.imageChartStorage.s3.regionendpoint. Default
    type flipped to `filesystem` so contabo/dev render is clean.
    Added vendor-agnostic objectStorage block:
      objectStorage:
        enabled: false
        useExistingSecret: false
        credentialsSecretName: ""
        s3: { accessKey: "", secretKey: "" }
  - templates/objectstorage-credentials.yaml (NEW): synthesises a
    harbor-namespace Secret with REGISTRY_STORAGE_S3_ACCESSKEY +
    REGISTRY_STORAGE_S3_SECRETKEY keys (the upstream chart's
    persistence.imageChartStorage.s3.existingSecret consumption
    shape — envFrom on the registry pod). Skip-render branch
    when objectStorage.enabled=false (default).
  - templates/_helpers.tpl: added bp-harbor.objectStorageCredentialsSecretName
    helper.
  - templates/networkpolicy.yaml: egress rule retargeted from
    SeaweedFS service-namespace selector → external HTTPS:443
    (works for any cloud-native S3 endpoint without vendor coupling).
    Gated on `.Values.objectStorage.enabled`. Removed
    seaweedfsNamespace + seaweedfsS3Port overlay keys.

Per-Sovereign overlays (clusters/{_template,omantel,otech}/bootstrap-
kit/19-harbor.yaml):
  - Chart version reference bumped 1.0.0 → 1.1.0.
  - dependsOn: bp-seaweedfs REMOVED. New dependsOn = bp-cnpg + bp-cert-manager.
  - Added valuesFrom block mapping the 5 keys of flux-system/object-
    storage Secret:
      s3-bucket     → harbor.persistence.imageChartStorage.s3.bucket
      s3-region     → harbor.persistence.imageChartStorage.s3.region
      s3-endpoint   → harbor.persistence.imageChartStorage.s3.regionendpoint
      s3-access-key → objectStorage.s3.accessKey
      s3-secret-key → objectStorage.s3.secretKey
  - Inline values flip objectStorage.enabled=true,
    harbor.persistence.imageChartStorage.type=s3, and
    harbor.persistence.imageChartStorage.s3.existingSecret=harbor-
    objectstorage-credentials.

UI catalog (products/catalyst/bootstrap/ui/src/shared/constants/components.ts):
  - Harbor's `dependencies` array drops `seaweedfs`. Now ['cnpg', 'valkey'].

Validation:
  helm template default render →
    1448 lines, 5 Secrets (Harbor internal: core/jobservice/registry/
    registry-htpasswd/database — NO objectstorage-credentials),
    type=filesystem, 0 SeaweedFS references.
  helm template overlay render with objectStorage.enabled=true +
  type=s3 + bucket=omantel-harbor + region=fsn1 +
  regionendpoint=https://fsn1.your-objectstorage.com +
  existingSecret=harbor-objectstorage-credentials →
    1452 lines, 6 Secrets (5 internal + 1 objectstorage-credentials),
    type=s3 with Hetzner endpoint, registry pod envFrom wired to the
    new Secret, 0 SeaweedFS references.
  scripts/check-vendor-coupling.sh → exit 0 (no violations across
    platform/, clusters/, products/catalyst/bootstrap/{api,ui}/).
  helm lint → 0 failures.

WBS:
  §2 row 18 → 🟢 chart-released (#383).
  §9 #383 row → 🟢 chart-released narrative.
  §6 DAG: T383 moved from `class blocked` → `class done`.

Hetzner-S3 E2E deferred to Phase 8 (first omantel run).

Co-authored-by: hatiyildiz <hatiyildiz@noreply.github.com>
2026-05-01 18:18:37 +04:00
..
adr docs(adr): 0001 — Catalyst control-plane architecture (#354) 2026-05-01 10:37:47 +04:00
lessons-learned fix(bp-flux): catalyst-cluster-reconciler ClusterRoleBinding overlay (closes #338) (#393) 2026-05-01 15:56:45 +04:00
proposals feat(wizard): job dependencies SVG DAG + (stretch) timeline view (closes #206) (#212) 2026-04-29 21:40:43 +02:00
ARCHITECTURE.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
AUDIT-PROCEDURE.md docs(component-count): update 53 → 56 anchors after Pass 105 (spire + nats-jetstream + sealed-secrets) 2026-04-28 13:48:24 +02:00
BLUEPRINT-AUTHORING.md fix(bp-*): observability toggles default false — break circular CRD dependency 2026-04-29 19:23:52 +02:00
BOOTSTRAP-KIT-EXPANSION-PLAN.md docs(bootstrap-kit): expansion plan to 40+ HRs (Wave 2 dispatch reference) (#255) 2026-04-30 17:08:16 +04:00
BUSINESS-STRATEGY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
CHART-AUTHORING.md fix(catalyst-chart): annotate api-deployment for Flux strategy-flip recovery 2026-04-29 18:04:07 +02:00
COMPONENT-LOGOS.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
DEMO-RUNBOOK.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
FRANCHISE-MODEL.md docs(franchise),test(billing): voucher CRD propagation invariant 2026-04-28 13:59:31 +02:00
GLOSSARY.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
IMPLEMENTATION-STATUS.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
INVIOLABLE-PRINCIPLES.md docs(principles): canonical INVIOLABLE-PRINCIPLES.md — 10 non-negotiable rules 2026-04-28 13:28:11 +02:00
MULTI-REGION-DNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
NAMING-CONVENTION.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
omantel-handover-wbs.md feat(bp-harbor): vendor-agnostic Object Storage backend (closes #383) (#437) 2026-05-01 18:18:37 +04:00
ORCHESTRATOR-STATE.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
PERSONAS-AND-JOURNEYS.md docs(unified-repo-model): collapse SME and corporate to one shape — Application = Gitea Repo 2026-04-28 10:13:02 +02:00
PLATFORM-POWERDNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PLATFORM-TECH-STACK.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PRODUCT-FAMILIES.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
PROVISIONING-PLAN.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
RUNBOOK-OPERATIONS.md docs(ops): comprehensive operator runbook + remediation playbook + idempotent recovery script 2026-04-29 19:26:29 +02:00
RUNBOOK-PROVISIONING.md merge: keep k3s local-path-provisioner; mark StorageClass default before Flux runs (closes #189) 2026-04-29 19:43:59 +02:00
SECRET-ROTATION.md fix(cloudinit): create flux-system/ghcr-pull secret on Sovereign so private bp-* charts pull cleanly 2026-04-29 18:07:27 +02:00
SECURITY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
SOVEREIGN-PROVISIONING.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
SRE.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
TECHNOLOGY-FORECAST-2027-2030.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
UI-REGRESSION-GUARDS.md fix(platform): sync blueprint.yaml versions with Chart.yaml (#199) 2026-04-29 22:07:55 +04:00
VALIDATION-LOG.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00