Live otech103: Step-8 (egress-block-test) failed because Cilium 1.16's CiliumNetworkPolicy schema doesn't support 'spec.egressDeny[].toFQDNs' — strict-decoding error 'unknown field'. FQDN-based matching in Cilium is only allowed in 'egress' (allow), not 'egressDeny'. Pivot: Step-8 now asserts the architectural pivots from Steps 5-7 are actually live (GitRepository.url + all HelmRepositories + catalyst-api env all point at local Gitea/Harbor) BEFORE entering the durationSeconds survival window during which Flux Kustomization + HelmRelease readiness is polled. Same sovereignty proof, expressed in a form Cilium can evaluate. Bumps 0.1.10 → 0.1.11 + slot 06a pin lockstep. Co-authored-by: Hatice Yildiz <hatice.yildiz@openova.io>
141 lines
6.3 KiB
YAML
141 lines
6.3 KiB
YAML
# bp-self-sovereign-cutover — Catalyst bootstrap-kit Blueprint, slot 06a.
|
|
#
|
|
# Post-handover Self-Sovereignty Cutover. Installs DORMANT — see chart
|
|
# README + ADR-0002. Eight step PodSpec ConfigMaps + the registry-pivot
|
|
# DaemonSet land on the new Sovereign at HelmRelease apply time; the
|
|
# catalyst-api cutover endpoint (issue #792) reads them by label
|
|
# selector and stamps Jobs only on operator action.
|
|
#
|
|
# Slot 06a sits between the existing post-handover slots in the
|
|
# bootstrap-kit ordering. It depends on bp-gitea + bp-harbor so the
|
|
# step ConfigMaps reference real, healthy local Gitea + Harbor
|
|
# Services at trigger time.
|
|
#
|
|
# Wrapper chart: platform/self-sovereign-cutover/chart/
|
|
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
|
#
|
|
# Why disableWait: true
|
|
# The chart is dormant — no Job is created at install time. The only
|
|
# workload that actually runs is the registry-pivot DaemonSet, which
|
|
# never converges on its own (it waits for the cutover-status
|
|
# ConfigMap to flip registriesYamlActive=v2). disableWait: true makes
|
|
# Helm exit when the manifests apply rather than waiting on a Ready
|
|
# condition that never fires.
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: catalyst
|
|
labels:
|
|
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
|
---
|
|
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
|
kind: HelmRepository
|
|
metadata:
|
|
name: bp-self-sovereign-cutover
|
|
namespace: flux-system
|
|
spec:
|
|
type: oci
|
|
interval: 15m
|
|
# Pre-cutover (Phase-1) — sources from openova-io GHCR, identical to
|
|
# every other bootstrap-kit slot. The cutover itself (step 06,
|
|
# helmrepository-patches) is what flips this URL to the local Harbor
|
|
# post-handover; until then this Sovereign is soft-tethered like the
|
|
# rest of the kit.
|
|
url: oci://ghcr.io/openova-io
|
|
secretRef:
|
|
name: ghcr-pull
|
|
---
|
|
apiVersion: helm.toolkit.fluxcd.io/v2
|
|
kind: HelmRelease
|
|
metadata:
|
|
name: bp-self-sovereign-cutover
|
|
namespace: flux-system
|
|
spec:
|
|
interval: 15m
|
|
releaseName: self-sovereign-cutover
|
|
# targetNamespace = catalyst because the catalyst-api cutover endpoint
|
|
# defaults its discovery namespace to "catalyst"
|
|
# (CATALYST_CUTOVER_NAMESPACE in
|
|
# products/catalyst/bootstrap/api/internal/handler/cutover.go). Keeping
|
|
# the chart resources colocated with catalyst-api avoids a cross-
|
|
# namespace selector + a CATALYST_CUTOVER_NAMESPACE env override on
|
|
# every Sovereign.
|
|
targetNamespace: catalyst
|
|
dependsOn:
|
|
# Both bp-gitea and bp-harbor must be Ready before the chart's
|
|
# PodSpec ConfigMaps reference real Services. The chart itself is
|
|
# dormant so an early apply is benign — but operator workflow
|
|
# ordering puts cutover after these two come up.
|
|
- name: bp-gitea
|
|
- name: bp-harbor
|
|
chart:
|
|
spec:
|
|
chart: bp-self-sovereign-cutover
|
|
# 0.1.1: Step-1 gitea-mirror script uses BusyBox-wget-compatible
|
|
# Authorization: Basic <b64> header instead of --user/--password
|
|
# which alpine/git's BusyBox wget does not support.
|
|
# 0.1.2: Step-1 explicitly creates the Gitea org BEFORE the repo —
|
|
# POST /orgs/<org>/repos returns 404 if the org is missing, the
|
|
# /user/repos fallback would create under gitea_admin (wrong path
|
|
# for the subsequent push). Caught live on otech103 2026-05-04.
|
|
# 0.1.3: replace `git push --mirror` with `git push --all + --tags`
|
|
# so Gitea's hooks don't decline GitHub-specific refs/pull/<n>
|
|
# refs (which --mirror would try to push). Branches+tags are what
|
|
# Flux GitRepository needs; PR refs are upstream-only metadata.
|
|
# 0.1.4: Step-1 uses `git clone --bare` (not --mirror) + explicit
|
|
# refspec push of refs/heads/* and refs/tags/* only. --all in a
|
|
# mirror clone still pushed refs/pull/* — caught live otech103.
|
|
# 0.1.5: harborInternalURL fix — bp-harbor service is `harbor-core`
|
|
# not `harbor-harbor-core` (release name doesn't double-prefix).
|
|
# Caught live otech103 — Step-2 curl exit 6 (couldn't resolve).
|
|
# 0.1.6: proxy-ghcr registryType "github" → "github-ghcr" (the
|
|
# canonical Harbor adapter name for GHCR proxy-cache, per Harbor
|
|
# 2.x docs). Caught live otech103 — Harbor 500 "adapter factory
|
|
# for github not found".
|
|
# 0.1.7: proxy-quay registryType "quay" → "docker-registry" —
|
|
# Harbor's "quay" adapter rejects project metadata.proxy_cache
|
|
# with HTTP 400. Quay speaks plain v2 so generic docker-registry
|
|
# is correct. Caught live otech103 — 4/7 proxy-cache projects
|
|
# were created OK, blocked at proxy-quay.
|
|
# 0.1.8: bitnami/kubectl tag :1.31 → :1.31.4 (bitnami doesn't tag
|
|
# at minor-version, only patch). Caught live otech103 — Step-5
|
|
# Pod hit DeadlineExceeded after 10m of ImagePullBackOff for
|
|
# docker.io/bitnami/kubectl:1.31 (404 not found).
|
|
# 0.1.9: bitnami/kubectl :1.31.4 ALSO 404 (Bitnami deprecated
|
|
# public Docker Hub in 2025). Switched to alpine/k8s:1.31.4 —
|
|
# canonical alpine-based image with kubectl + helm + k8s CLI
|
|
# surface, actively maintained.
|
|
# 0.1.10: catalystAPI.namespace `catalyst-platform` → `catalyst-
|
|
# system` (the actual Sovereign-side namespace). Caught live
|
|
# otech103 — Step-7 `deployment catalyst-api not found`.
|
|
# 0.1.11: Step-8 egress-block-test pivoted from CiliumNetworkPolicy
|
|
# (egressDeny + toFQDNs unsupported in Cilium 1.16) to a passive
|
|
# architectural-state assertion + ${durationSeconds}s survival
|
|
# window. Same proof shape, valid Cilium policy. Caught live
|
|
# otech103 — strict-decoding error 'unknown field toFQDNs'.
|
|
version: 0.1.11
|
|
sourceRef:
|
|
kind: HelmRepository
|
|
name: bp-self-sovereign-cutover
|
|
namespace: flux-system
|
|
install:
|
|
disableWait: true
|
|
remediation:
|
|
retries: 3
|
|
upgrade:
|
|
disableWait: true
|
|
remediation:
|
|
retries: 3
|
|
# Per-Sovereign overrides — the chart's values.yaml carries
|
|
# placeholders so smoke renders pass; the real coordinates land
|
|
# here via Flux postBuild ${SOVEREIGN_FQDN} substitution.
|
|
values:
|
|
sovereign:
|
|
fqdn: ${SOVEREIGN_FQDN}
|
|
harborInternalURL: http://harbor-core.harbor.svc.cluster.local
|
|
harborPublicURL: https://harbor.${SOVEREIGN_FQDN}
|
|
giteaInternalURL: http://gitea-http.gitea.svc.cluster.local:3000
|
|
giteaPublicURL: https://gitea.${SOVEREIGN_FQDN}
|