Compare commits
No commits in common. "chore/310-bootstrap-trim-prep" and "fix/provision-as-spa-route" have entirely different histories.
chore/310-
...
fix/provis
291
.github/workflows/blueprint-release.yaml
vendored
@ -13,35 +13,6 @@
|
||||
# original 11 plus bp-powerdns added at #167) plus every other Catalyst-
|
||||
# curated wrapper chart. Application-Blueprint charts (cnpg, valkey, etc.)
|
||||
# follow the same shape once authored.
|
||||
#
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
# Hollow-chart guard (issue #181)
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
# Every umbrella Blueprint chart MUST declare its upstream chart(s) under
|
||||
# `dependencies:` in Chart.yaml so `helm dependency build` pulls the
|
||||
# upstream payload into the OCI artifact at publish time. Earlier in this
|
||||
# cycle, bp-cert-manager:1.0.0 shipped as a "hollow chart" — only an
|
||||
# overlay (ClusterIssuer template) with no upstream cert-manager subchart
|
||||
# bytes — and Phase 1 broke on every Sovereign because cert-manager
|
||||
# itself was never installed. See docs/BLUEPRINT-AUTHORING.md
|
||||
# §"Umbrella shape".
|
||||
#
|
||||
# This workflow now structurally verifies the upstream payload is present
|
||||
# at every stage of the publish pipeline:
|
||||
#
|
||||
# 1. After `helm dependency build` — assert the working-tree
|
||||
# chart/charts/<dep>-<ver>.tgz (or unpacked chart/charts/<dep>/) exists
|
||||
# for every entry in Chart.yaml `dependencies:`.
|
||||
# 2. After `helm package` — `tar -tzf` the produced .tgz and assert
|
||||
# every declared dep is inside the package's charts/ directory.
|
||||
# 3. After `helm push` — `helm pull` the artifact back from GHCR and
|
||||
# re-verify the deps survived the round-trip.
|
||||
# 4. `helm template` smoke render — chart MUST render with default
|
||||
# values; rendered manifests are uploaded as a workflow artifact for
|
||||
# forensics.
|
||||
#
|
||||
# Any one of those steps failing fails the whole build — hollow charts
|
||||
# can never reach a Sovereign.
|
||||
|
||||
name: Blueprint Release
|
||||
|
||||
@ -129,16 +100,6 @@ jobs:
|
||||
- name: Install Syft
|
||||
uses: anchore/sbom-action/download-syft@v0
|
||||
|
||||
- name: Install yq (declared-deps parser)
|
||||
run: |
|
||||
# We need a streaming YAML parser to read Chart.yaml's dependencies:
|
||||
# block reliably; awk/grep on YAML is fragile and would let a
|
||||
# subtly malformed Chart.yaml slip past the hollow-chart guard.
|
||||
sudo wget -qO /usr/local/bin/yq \
|
||||
https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64
|
||||
sudo chmod +x /usr/local/bin/yq
|
||||
yq --version
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@ -180,207 +141,11 @@ jobs:
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
run: helm dependency build "${{ matrix.path }}/chart"
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# GUARD 1 — hollow-chart check on the working tree
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# After `helm dependency build`, every entry in Chart.yaml's
|
||||
# `dependencies:` block MUST have a corresponding artifact under
|
||||
# chart/charts/. Helm accepts either form:
|
||||
# chart/charts/<dep-name>-<dep-version>.tgz (packed)
|
||||
# chart/charts/<dep-name>/Chart.yaml (unpacked vendored)
|
||||
# Either is fine; ZERO of them is a hollow chart and we fail loudly.
|
||||
- name: "Verify upstream subcharts present in working tree (post-dependency-build)"
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: verify_workdir
|
||||
run: |
|
||||
set -euo pipefail
|
||||
chart_dir="${{ matrix.path }}/chart"
|
||||
chart_yaml="$chart_dir/Chart.yaml"
|
||||
# Some Blueprints legitimately ship NO upstream subchart — their
|
||||
# entire payload is Catalyst-authored CRs (e.g.
|
||||
# bp-crossplane-claims, which carries only XRDs + Compositions
|
||||
# for the compose.openova.io/v1alpha1 family). Those charts opt
|
||||
# out of the dependencies-required rule by setting the
|
||||
# annotation:
|
||||
# annotations:
|
||||
# catalyst.openova.io/no-upstream: "true"
|
||||
# in their Chart.yaml. The hollow-chart rule remains in force
|
||||
# for every other umbrella chart — the original failure
|
||||
# (bp-cert-manager:1.0.0 silently shipping without cert-manager)
|
||||
# cannot recur unless an author explicitly adds the annotation.
|
||||
no_upstream=$(yq '.annotations["catalyst.openova.io/no-upstream"] // ""' "$chart_yaml")
|
||||
dep_count=$(yq '.dependencies | length // 0' "$chart_yaml")
|
||||
echo "Declared dependencies: $dep_count"
|
||||
echo "no-upstream annotation: '$no_upstream'"
|
||||
if [ "$dep_count" -eq 0 ]; then
|
||||
if [ "$no_upstream" = "true" ]; then
|
||||
echo "Chart marked catalyst.openova.io/no-upstream=true — skipping upstream-subchart presence check."
|
||||
exit 0
|
||||
fi
|
||||
echo "::error title=Hollow chart::Chart $chart_yaml declares NO dependencies. Every Blueprint umbrella chart at platform/<name>/chart/ MUST declare its upstream chart under \`dependencies:\` per docs/BLUEPRINT-AUTHORING.md §11.1 Umbrella shape. See issue #181. (To opt out for charts that legitimately ship only Catalyst-authored CRs, set annotations.catalyst.openova.io/no-upstream: \"true\".)"
|
||||
exit 1
|
||||
fi
|
||||
missing=0
|
||||
for i in $(seq 0 $((dep_count - 1))); do
|
||||
dep_name=$(yq ".dependencies[$i].name" "$chart_yaml")
|
||||
dep_ver=$(yq ".dependencies[$i].version" "$chart_yaml")
|
||||
dep_repo=$(yq ".dependencies[$i].repository" "$chart_yaml")
|
||||
packed="$chart_dir/charts/${dep_name}-${dep_ver}.tgz"
|
||||
unpacked="$chart_dir/charts/${dep_name}/Chart.yaml"
|
||||
if [ -f "$packed" ]; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $packed"
|
||||
elif [ -f "$unpacked" ]; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $unpacked (unpacked)"
|
||||
else
|
||||
echo "::error title=Subchart not pulled::Declared dependency '${dep_name}' (version='${dep_ver}', repo='${dep_repo}') was not pulled by \`helm dependency build\`. Expected $packed OR $unpacked. Investigate the dependency repository / Chart.lock; do NOT publish a hollow chart."
|
||||
missing=$((missing + 1))
|
||||
fi
|
||||
done
|
||||
if [ "$missing" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "All $dep_count declared upstream subcharts present in working tree."
|
||||
|
||||
- name: Helm package
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
run: |
|
||||
mkdir -p /tmp/charts
|
||||
helm package "${{ matrix.path }}/chart" --destination /tmp/charts
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# GUARD 2 — hollow-chart check inside the packaged tgz
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# `helm package` builds the OCI payload from the working tree, but
|
||||
# we don't trust transitive bugs / .helmignore mishaps to leave
|
||||
# chart/charts/ behind. Crack the produced .tgz and assert every
|
||||
# declared dep is inside <chart_name>/charts/ in the package.
|
||||
- name: "Verify upstream subcharts present in packaged tgz (post-helm-package)"
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: verify_package
|
||||
run: |
|
||||
set -euo pipefail
|
||||
chart_yaml="${{ matrix.path }}/chart/Chart.yaml"
|
||||
name="${{ steps.chart.outputs.name }}"
|
||||
version="${{ steps.chart.outputs.version }}"
|
||||
tgz="/tmp/charts/${name}-${version}.tgz"
|
||||
if [ ! -f "$tgz" ]; then
|
||||
echo "::error title=Package missing::Expected $tgz from helm package."
|
||||
exit 1
|
||||
fi
|
||||
echo "Inspecting $tgz"
|
||||
listing="/tmp/${name}-${version}.listing.txt"
|
||||
tar -tzf "$tgz" > "$listing"
|
||||
echo " total entries: $(wc -l < "$listing")"
|
||||
dep_count=$(yq '.dependencies | length // 0' "$chart_yaml")
|
||||
missing=0
|
||||
for i in $(seq 0 $((dep_count - 1))); do
|
||||
dep_name=$(yq ".dependencies[$i].name" "$chart_yaml")
|
||||
dep_ver=$(yq ".dependencies[$i].version" "$chart_yaml")
|
||||
packed_in_tgz="${name}/charts/${dep_name}-${dep_ver}.tgz"
|
||||
unpacked_in_tgz="${name}/charts/${dep_name}/Chart.yaml"
|
||||
if grep -qx "$packed_in_tgz" "$listing"; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $packed_in_tgz"
|
||||
elif grep -qx "$unpacked_in_tgz" "$listing"; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $unpacked_in_tgz (unpacked)"
|
||||
else
|
||||
echo "::error title=Hollow package::Packaged tgz $tgz does NOT contain upstream subchart '${dep_name}' (version='${dep_ver}'). Refusing to publish a hollow chart."
|
||||
missing=$((missing + 1))
|
||||
fi
|
||||
done
|
||||
if [ "$missing" -gt 0 ]; then
|
||||
echo "── package listing (first 200 lines) ──"
|
||||
head -200 "$listing"
|
||||
exit 1
|
||||
fi
|
||||
echo "All $dep_count declared upstream subcharts present inside packaged tgz."
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# SMOKE — `helm template` must render with default values
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# A chart can be structurally complete but render-broken (bad
|
||||
# template, missing required value, schema violation). Render the
|
||||
# packaged chart with defaults; on render failure the build dies
|
||||
# and the rendered output (if any) ships as a workflow artifact
|
||||
# for forensics.
|
||||
- name: "Helm template smoke render (default values)"
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: smoke
|
||||
run: |
|
||||
set -euo pipefail
|
||||
name="${{ steps.chart.outputs.name }}"
|
||||
version="${{ steps.chart.outputs.version }}"
|
||||
tgz="/tmp/charts/${name}-${version}.tgz"
|
||||
mkdir -p /tmp/render
|
||||
render_out="/tmp/render/${name}-${version}.default.yaml"
|
||||
# `helm template` against the packaged tgz exercises the same
|
||||
# bytes Flux will install at runtime — including subchart
|
||||
# rendering. A leaf umbrella with the upstream subchart
|
||||
# present should produce upstream resources here.
|
||||
if ! helm template "smoke-${name}" "$tgz" \
|
||||
--namespace "smoke-${name}" \
|
||||
> "$render_out" 2> /tmp/render/stderr.log; then
|
||||
echo "::error title=helm template failed::Default-values render of $tgz failed; see uploaded artifact and stderr below."
|
||||
cat /tmp/render/stderr.log >&2
|
||||
exit 1
|
||||
fi
|
||||
lines=$(wc -l < "$render_out")
|
||||
echo "Rendered $lines lines to $render_out"
|
||||
if [ "$lines" -lt 5 ]; then
|
||||
echo "::error title=Empty render::Rendered output is suspiciously short ($lines lines). A working umbrella with an upstream subchart should produce many more resources."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: "Upload smoke render as workflow artifact"
|
||||
if: ${{ always() && steps.chart.outputs.skip != 'true' && steps.smoke.conclusion != 'skipped' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blueprint-smoke-render-${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}
|
||||
path: /tmp/render/
|
||||
if-no-files-found: warn
|
||||
retention-days: 30
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# GATE — Per-chart integration tests under chart/tests/*.sh
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# Every chart under platform/<name>/chart/tests/ that ships a *.sh
|
||||
# script gets executed here against the working-tree chart. Tests
|
||||
# SHOULD be self-contained `helm template` assertions (no kind
|
||||
# cluster); kind-based tests live in a separate workflow that we
|
||||
# don't gate publish on.
|
||||
#
|
||||
# Canonical example: tests/observability-toggle.sh — verifies the
|
||||
# docs/BLUEPRINT-AUTHORING.md §11.2 rule (observability toggles
|
||||
# default false). A chart authoring regression that re-introduces
|
||||
# a hardcoded `serviceMonitor.enabled: true` fails this gate and
|
||||
# the publish job dies BEFORE the OCI artifact is pushed (issue
|
||||
# #182).
|
||||
- name: "Run chart integration tests (chart/tests/*.sh)"
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: chart_tests
|
||||
run: |
|
||||
set -euo pipefail
|
||||
chart_dir="${{ matrix.path }}/chart"
|
||||
tests_dir="$chart_dir/tests"
|
||||
if [ ! -d "$tests_dir" ]; then
|
||||
echo "No tests/ directory at $tests_dir — skipping chart tests."
|
||||
exit 0
|
||||
fi
|
||||
shopt -s nullglob
|
||||
scripts=( "$tests_dir"/*.sh )
|
||||
if [ "${#scripts[@]}" -eq 0 ]; then
|
||||
echo "tests/ directory present at $tests_dir but no *.sh scripts — skipping."
|
||||
exit 0
|
||||
fi
|
||||
echo "Running ${#scripts[@]} chart-test script(s) under $tests_dir:"
|
||||
for s in "${scripts[@]}"; do
|
||||
echo " → $s"
|
||||
done
|
||||
for s in "${scripts[@]}"; do
|
||||
echo "── $(basename "$s") ──"
|
||||
bash "$s" "$chart_dir"
|
||||
done
|
||||
echo "All chart-test scripts passed."
|
||||
|
||||
- name: Helm push to GHCR
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: push
|
||||
@ -395,61 +160,6 @@ jobs:
|
||||
echo "ref=ghcr.io/openova-io/${name}:${version}" >> "$GITHUB_OUTPUT"
|
||||
echo "digest=$digest" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# GUARD 3 — hollow-chart check after round-trip through GHCR
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# Pull the just-pushed artifact back from GHCR and re-verify deps
|
||||
# survived. This catches any registry-side stripping, manifest
|
||||
# rewriting, or path mangling — and proves end consumers (Flux
|
||||
# helm-controller on every Sovereign) will see the upstream
|
||||
# subchart bytes.
|
||||
- name: "Verify upstream subcharts present in pulled OCI artifact (post-helm-push)"
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
id: verify_pull
|
||||
run: |
|
||||
set -euo pipefail
|
||||
name="${{ steps.chart.outputs.name }}"
|
||||
version="${{ steps.chart.outputs.version }}"
|
||||
# `chart_yaml` is referenced relative to $GITHUB_WORKSPACE — DO NOT
|
||||
# cd elsewhere before reading it. We pin `helm pull` output via
|
||||
# --destination so the read of the source-tree Chart.yaml stays
|
||||
# rooted at the checked-out repo root.
|
||||
chart_yaml="${GITHUB_WORKSPACE}/${{ matrix.path }}/chart/Chart.yaml"
|
||||
mkdir -p /tmp/pulled
|
||||
helm pull "oci://ghcr.io/openova-io/${name}" --version "${version}" \
|
||||
--destination /tmp/pulled
|
||||
pulled_tgz="/tmp/pulled/${name}-${version}.tgz"
|
||||
if [ ! -f "$pulled_tgz" ]; then
|
||||
echo "::error title=Pull failed::helm pull did not produce $pulled_tgz; cannot verify GHCR contents."
|
||||
ls -la /tmp/pulled
|
||||
exit 1
|
||||
fi
|
||||
listing="/tmp/pulled/${name}-${version}.pulled.listing.txt"
|
||||
tar -tzf "$pulled_tgz" > "$listing"
|
||||
echo " pulled entries: $(wc -l < "$listing")"
|
||||
dep_count=$(yq '.dependencies | length // 0' "$chart_yaml")
|
||||
missing=0
|
||||
for i in $(seq 0 $((dep_count - 1))); do
|
||||
dep_name=$(yq ".dependencies[$i].name" "$chart_yaml")
|
||||
dep_ver=$(yq ".dependencies[$i].version" "$chart_yaml")
|
||||
packed_in_tgz="${name}/charts/${dep_name}-${dep_ver}.tgz"
|
||||
unpacked_in_tgz="${name}/charts/${dep_name}/Chart.yaml"
|
||||
if grep -qx "$packed_in_tgz" "$listing"; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $packed_in_tgz (in GHCR artifact)"
|
||||
elif grep -qx "$unpacked_in_tgz" "$listing"; then
|
||||
echo " ✓ ${dep_name} ${dep_ver} → $unpacked_in_tgz (in GHCR artifact, unpacked)"
|
||||
else
|
||||
echo "::error title=Hollow OCI artifact::GHCR-pulled $pulled_tgz does NOT contain upstream subchart '${dep_name}' (version='${dep_ver}'). The artifact at ghcr.io/openova-io/${name}:${version} is hollow — Flux will install it but the upstream payload will be missing on every Sovereign. Refusing to leave this published."
|
||||
missing=$((missing + 1))
|
||||
fi
|
||||
done
|
||||
if [ "$missing" -gt 0 ]; then
|
||||
echo "── pulled-artifact listing (first 200 lines) ──"
|
||||
head -200 "$listing"
|
||||
exit 1
|
||||
fi
|
||||
echo "All $dep_count declared upstream subcharts present in pulled GHCR artifact."
|
||||
|
||||
- name: Cosign keyless sign
|
||||
if: steps.chart.outputs.skip != 'true'
|
||||
env:
|
||||
@ -490,4 +200,3 @@ jobs:
|
||||
echo "- **Digest:** \`${{ steps.push.outputs.digest }}\`" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- **Cosigned:** ✓ (keyless via GitHub OIDC)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- **SBOM attested:** ✓ (SPDX-JSON)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- **Subchart guards:** ✓ working tree, ✓ packaged tgz, ✓ pulled OCI artifact, ✓ helm template smoke" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
@ -1,135 +0,0 @@
|
||||
name: Build cert-manager-dynadot-webhook
|
||||
|
||||
# cert-manager-dynadot-webhook — Catalyst-built Go binary that satisfies
|
||||
# cert-manager's DNS-01 webhook contract against the Dynadot api3.json.
|
||||
# Closes openova#159. The image is consumed by the
|
||||
# bp-cert-manager-dynadot-webhook Blueprint
|
||||
# (platform/cert-manager-dynadot-webhook/chart/) which is auto-installed
|
||||
# by the bootstrap-kit on every Sovereign that needs wildcard TLS.
|
||||
#
|
||||
# Per docs/INVIOLABLE-PRINCIPLES.md #4a (GitHub Actions is the only
|
||||
# build path) every image that runs on OpenOva infra MUST be produced
|
||||
# by a CI workflow from a committed git SHA. This workflow mirrors
|
||||
# pool-domain-manager-build.yaml — same auth flow, same cosign signing,
|
||||
# same SBOM attestation.
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
# Build whenever the binary, the shared Dynadot client, or the
|
||||
# workflow itself changes. The chart at platform/.../chart/ does
|
||||
# not retrigger this workflow — Helm chart releases land via
|
||||
# blueprint-release.yaml and consume the image tag this workflow
|
||||
# publishes.
|
||||
- 'core/cmd/cert-manager-dynadot-webhook/**'
|
||||
- 'core/pkg/dynadot-client/**'
|
||||
- '.github/workflows/build-cert-manager-dynadot-webhook.yaml'
|
||||
branches: [main]
|
||||
pull_request:
|
||||
paths:
|
||||
- 'core/cmd/cert-manager-dynadot-webhook/**'
|
||||
- 'core/pkg/dynadot-client/**'
|
||||
- '.github/workflows/build-cert-manager-dynadot-webhook.yaml'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE: ghcr.io/openova-io/openova/cert-manager-dynadot-webhook
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
# id-token write is required by cosign keyless signing (Sigstore).
|
||||
# Per docs/INVIOLABLE-PRINCIPLES.md #3 every Catalyst image is
|
||||
# cosign-signed + SBOM-attested.
|
||||
id-token: write
|
||||
outputs:
|
||||
sha_short: ${{ steps.vars.outputs.sha_short }}
|
||||
digest: ${{ steps.build.outputs.digest }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set short SHA
|
||||
id: vars
|
||||
run: echo "sha_short=$(echo $GITHUB_SHA | head -c 7)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
cache-dependency-path: |
|
||||
core/cmd/cert-manager-dynadot-webhook/go.sum
|
||||
|
||||
- name: Run unit tests — webhook
|
||||
working-directory: core/cmd/cert-manager-dynadot-webhook
|
||||
run: go test -count=1 -race ./...
|
||||
|
||||
- name: Run unit tests — shared dynadot client
|
||||
working-directory: core/pkg/dynadot-client
|
||||
run: go test -count=1 -race ./...
|
||||
|
||||
# On pull_request runs we stop here — image push requires
|
||||
# `packages: write` against the openova-io org which only main
|
||||
# branch authors hold via GITHUB_TOKEN. Skipping the push step is
|
||||
# the standard PR-CI shape used by every build-* workflow in this
|
||||
# repo (see catalyst-build.yaml).
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
# Build context is the repository root so the Dockerfile's
|
||||
# COPY paths can reach both core/cmd/.../ and core/pkg/.../.
|
||||
# The shared dynadot-client module is consumed via go.mod's
|
||||
# local replace directive; the build context layout matches
|
||||
# what the replace expects.
|
||||
context: .
|
||||
file: core/cmd/cert-manager-dynadot-webhook/Containerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.IMAGE }}:${{ steps.vars.outputs.sha_short }}
|
||||
${{ env.IMAGE }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/openova-io/openova
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.title=cert-manager-dynadot-webhook
|
||||
org.opencontainers.image.description=cert-manager DNS-01 external webhook for Dynadot (closes openova#159)
|
||||
provenance: true
|
||||
sbom: true
|
||||
|
||||
- name: Install cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@v3
|
||||
|
||||
- name: Sign image with cosign (keyless)
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
cosign sign --yes "${IMAGE}@${DIGEST}"
|
||||
|
||||
- name: Generate and attest SBOM
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
cosign attest --yes \
|
||||
--predicate <(echo '{"sbom":"in-toto-spdx attached at build time"}') \
|
||||
--type spdx \
|
||||
"${IMAGE}@${DIGEST}"
|
||||
128
.github/workflows/catalyst-build.yaml
vendored
@ -42,11 +42,7 @@ jobs:
|
||||
- name: Build UI image (test)
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
# Build context is the repo root so the Vite prebuild script can
|
||||
# walk platform/, products/, clusters/_template/bootstrap-kit/ to
|
||||
# populate the catalog + BOOTSTRAP_KIT. The Containerfile fails
|
||||
# the build if any of those dirs is missing.
|
||||
context: openova-src
|
||||
context: openova-src/products/catalyst/bootstrap/ui
|
||||
file: openova-src/products/catalyst/bootstrap/ui/Containerfile
|
||||
push: false
|
||||
load: true
|
||||
@ -89,8 +85,8 @@ jobs:
|
||||
component-logos/cnpg.svg \
|
||||
component-logos/loki.png \
|
||||
component-logos/mimir.png \
|
||||
component-logos/tempo.svg \
|
||||
component-logos/ntfy.svg \
|
||||
component-logos/tempo.png \
|
||||
component-logos/ntfy.png \
|
||||
component-logos/ferretdb.png \
|
||||
component-logos/openmeter.png \
|
||||
component-logos/coraza.png \
|
||||
@ -109,54 +105,13 @@ jobs:
|
||||
echo "Logo smoke OK: /${path} HTTP $CODE"
|
||||
done
|
||||
|
||||
# Bootstrap-kit regression guard: the Provision page reads
|
||||
# BOOTSTRAP_KIT from the bundled catalog.generated.ts to render
|
||||
# the per-Blueprint bubbles. An earlier revision shipped with a
|
||||
# docker context that didn't include clusters/_template/bootstrap-kit/
|
||||
# so the prebuild script silently produced an empty array — the
|
||||
# page rendered only the 2 supernodes. Asserting the bundle
|
||||
# contains every bp-* id makes that regression impossible.
|
||||
#
|
||||
# Implementation note: we extract the entire bundle once via
|
||||
# `tar c -C ... --transform`, then grep locally. Earlier we ran
|
||||
# `grep` inside docker run -c "..." and the nested quote escaping
|
||||
# produced false negatives (bp-cilium was in the bundle but the
|
||||
# grep argument matched a literal `"bp-cilium"` whose surrounding
|
||||
# quotes were eaten by shell expansion). Local grep on the
|
||||
# extracted file removes that whole class of escaping bugs.
|
||||
BUNDLE_TMP=$(mktemp)
|
||||
docker run --rm --entrypoint sh ${{ env.UI_IMAGE }}:test \
|
||||
-c 'cat $(find /usr/share/nginx/html/assets -name "index-*.js" | head -1)' \
|
||||
> "$BUNDLE_TMP"
|
||||
BUNDLE_BYTES=$(wc -c < "$BUNDLE_TMP")
|
||||
echo "Bundle size: $BUNDLE_BYTES bytes"
|
||||
if [ "$BUNDLE_BYTES" -lt 100000 ]; then
|
||||
echo "Bootstrap-kit smoke FAILED: bundle suspiciously small ($BUNDLE_BYTES bytes)"
|
||||
docker stop smoke-ui
|
||||
exit 1
|
||||
fi
|
||||
for bp in bp-cilium bp-cert-manager bp-flux bp-crossplane bp-sealed-secrets \
|
||||
bp-spire bp-nats-jetstream bp-openbao bp-keycloak bp-gitea ; do
|
||||
if ! grep -q -F "$bp" "$BUNDLE_TMP" ; then
|
||||
echo "Bootstrap-kit smoke FAILED: ${bp} missing from bundle"
|
||||
docker stop smoke-ui
|
||||
exit 1
|
||||
fi
|
||||
echo "Bootstrap-kit smoke OK: ${bp}"
|
||||
done
|
||||
rm -f "$BUNDLE_TMP"
|
||||
|
||||
docker stop smoke-ui
|
||||
echo "All smoke tests passed."
|
||||
|
||||
- name: Push UI image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
# Build context is the repo root so the Vite prebuild script can
|
||||
# walk platform/, products/, clusters/_template/bootstrap-kit/ to
|
||||
# populate the catalog + BOOTSTRAP_KIT. The Containerfile fails
|
||||
# the build if any of those dirs is missing.
|
||||
context: openova-src
|
||||
context: openova-src/products/catalyst/bootstrap/ui
|
||||
file: openova-src/products/catalyst/bootstrap/ui/Containerfile
|
||||
push: true
|
||||
tags: |
|
||||
@ -192,81 +147,10 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Build context is the public openova repo root (openova-src/), not just
|
||||
# products/catalyst/bootstrap/api/, because the runtime image bundles the
|
||||
# canonical OpenTofu module from infra/hetzner/. The Containerfile's
|
||||
# COPY paths are written relative to the repo root accordingly. Without
|
||||
# this, /infra/hetzner/ is missing inside the image and every Launch
|
||||
# fails with `stage tofu module: open /infra/hetzner: no such file or
|
||||
# directory`.
|
||||
- name: Build API image (test)
|
||||
- name: Build and push API image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: openova-src
|
||||
file: openova-src/products/catalyst/bootstrap/api/Containerfile
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.API_IMAGE }}:test
|
||||
|
||||
# Smoke test — the catalyst-api Pod is the OpenTofu runner, so the .tf
|
||||
# sources MUST be present at /infra/hetzner/ inside the image. Anything
|
||||
# less ships a broken image that fails on every Launch with `stage tofu
|
||||
# module: open /infra/hetzner: no such file or directory`. Failure of
|
||||
# this step fails the build.
|
||||
- name: Smoke test API — verify infra/hetzner/ is bundled
|
||||
run: |
|
||||
set -euo pipefail
|
||||
LISTING=$(docker run --rm --entrypoint sh ${{ env.API_IMAGE }}:test \
|
||||
-c 'ls -la /infra/hetzner/')
|
||||
echo "$LISTING"
|
||||
for f in main.tf variables.tf outputs.tf versions.tf \
|
||||
cloudinit-control-plane.tftpl cloudinit-worker.tftpl ; do
|
||||
if ! echo "$LISTING" | grep -q " ${f}\$"; then
|
||||
echo "Smoke test FAILED: /infra/hetzner/${f} missing from image"
|
||||
exit 1
|
||||
fi
|
||||
echo "Smoke test OK: /infra/hetzner/${f} present"
|
||||
done
|
||||
echo "All API smoke tests passed."
|
||||
|
||||
# tofu CLI smoke test — the runtime image bundles the OpenTofu CLI
|
||||
# because internal/provisioner execs `tofu init / plan / apply` (see
|
||||
# internal/provisioner/provisioner.go runTofu()). Without the binary
|
||||
# every Launch SSE stream returns:
|
||||
# tofu init: exec: "tofu": executable file not found in $PATH
|
||||
# We assert (a) `tofu version` succeeds inside the image and (b) the
|
||||
# output matches the EXPECTED_TOFU_VERSION pinned here, which must
|
||||
# stay in lockstep with the TOFU_VERSION ARG in the Containerfile.
|
||||
# When you bump the version in the Containerfile, bump it here too.
|
||||
- name: Smoke test API — verify OpenTofu CLI is installed
|
||||
env:
|
||||
EXPECTED_TOFU_VERSION: 1.11.6
|
||||
run: |
|
||||
set -euo pipefail
|
||||
OUT=$(docker run --rm --entrypoint sh ${{ env.API_IMAGE }}:test \
|
||||
-c 'tofu version')
|
||||
echo "$OUT"
|
||||
if ! echo "$OUT" | grep -q "^OpenTofu v${EXPECTED_TOFU_VERSION}\$"; then
|
||||
echo "Smoke test FAILED: expected 'OpenTofu v${EXPECTED_TOFU_VERSION}', got:"
|
||||
echo "$OUT"
|
||||
exit 1
|
||||
fi
|
||||
echo "Smoke test OK: OpenTofu v${EXPECTED_TOFU_VERSION} present on PATH."
|
||||
|
||||
# Re-assert the binary is executable for the actual runtime UID
|
||||
# (65534, set in api-deployment.yaml securityContext.runAsUser).
|
||||
# `--user` overrides the image USER directive, simulating the K8s
|
||||
# securityContext: a missing exec bit or wrong owner here would
|
||||
# surface as a Launch failure in production, never in CI, so we
|
||||
# gate it at build time.
|
||||
docker run --rm --user 65534:65534 --entrypoint sh \
|
||||
${{ env.API_IMAGE }}:test -c 'tofu version | head -1'
|
||||
echo "Smoke test OK: tofu executable as UID 65534."
|
||||
|
||||
- name: Push API image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: openova-src
|
||||
context: openova-src/products/catalyst/bootstrap/api
|
||||
file: openova-src/products/catalyst/bootstrap/api/Containerfile
|
||||
push: true
|
||||
tags: |
|
||||
|
||||
112
.github/workflows/cosmetic-guards.yaml
vendored
@ -1,112 +0,0 @@
|
||||
name: Cosmetic + step-flow regression guards
|
||||
|
||||
# Narrow, fast Playwright suite that protects the Catalyst bootstrap UI
|
||||
# against the specific cosmetic + step-flow defects the user has called
|
||||
# out repeatedly. Lives ALONGSIDE (not inside) the broader Group L
|
||||
# Playwright smoke at .github/workflows/playwright-smoke.yaml — the two
|
||||
# suites are independently triggered, both run on PRs that touch UI
|
||||
# files. See docs/UI-REGRESSION-GUARDS.md for the test-to-complaint map.
|
||||
#
|
||||
# Per docs/INVIOLABLE-PRINCIPLES.md #4a (GitHub Actions is the only
|
||||
# build path), this workflow does NOT build any container images — it
|
||||
# only runs UI regression guards against a freshly-installed dev tree.
|
||||
#
|
||||
# Triggers:
|
||||
# - pull_request when files under products/catalyst/bootstrap/ui/**
|
||||
# change, OR core/console/** (canonical sidebar / appdetail /
|
||||
# jobspage references) change, OR this workflow itself changes.
|
||||
# - push to main on the same paths so a rolled-back regression on
|
||||
# main also triggers a fresh run.
|
||||
# - workflow_dispatch for ad-hoc runs.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'products/catalyst/bootstrap/ui/**'
|
||||
- 'core/console/**'
|
||||
- '.github/workflows/cosmetic-guards.yaml'
|
||||
- 'docs/UI-REGRESSION-GUARDS.md'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'products/catalyst/bootstrap/ui/**'
|
||||
- 'core/console/**'
|
||||
- '.github/workflows/cosmetic-guards.yaml'
|
||||
- 'docs/UI-REGRESSION-GUARDS.md'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
guards:
|
||||
name: Playwright cosmetic + step-flow guards
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: products/catalyst/bootstrap/ui/package-lock.json
|
||||
|
||||
- name: Install Catalyst UI dependencies
|
||||
working-directory: products/catalyst/bootstrap/ui
|
||||
run: npm ci
|
||||
|
||||
- name: Install Playwright browser (chromium)
|
||||
working-directory: products/catalyst/bootstrap/ui
|
||||
run: npx playwright install --with-deps chromium
|
||||
|
||||
- name: Boot Catalyst UI in background
|
||||
working-directory: products/catalyst/bootstrap/ui
|
||||
env:
|
||||
HOST: 0.0.0.0
|
||||
run: |
|
||||
# Vite binds the port from vite.config.ts (server.port = 5173)
|
||||
# under base /sovereign/. Tests reach the wizard at
|
||||
# http://localhost:5173/sovereign/wizard.
|
||||
nohup npm run dev > /tmp/catalyst-ui-dev.log 2>&1 &
|
||||
echo $! > /tmp/catalyst-ui.pid
|
||||
|
||||
- name: Wait for Catalyst UI to be ready
|
||||
run: |
|
||||
for i in $(seq 1 60); do
|
||||
if curl -sf -o /dev/null http://localhost:5173/sovereign/wizard; then
|
||||
echo "UI ready after ${i}s"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "UI failed to start in 60s — log follows:"
|
||||
cat /tmp/catalyst-ui-dev.log || true
|
||||
exit 1
|
||||
|
||||
- name: Run cosmetic + step-flow regression guards
|
||||
working-directory: products/catalyst/bootstrap/ui
|
||||
env:
|
||||
PLAYWRIGHT_HOST: http://localhost:5173
|
||||
PLAYWRIGHT_BASEPATH: /sovereign
|
||||
# --grep filters by the @cosmetic-guard annotation that every
|
||||
# test in the suite carries. If a future test in the same file
|
||||
# is added without the tag, this command will skip it — that's
|
||||
# by design (the tag IS the contract).
|
||||
run: npx playwright test e2e/cosmetic-guards.spec.ts --grep "@cosmetic-guard" --reporter=list
|
||||
|
||||
- name: Stop Catalyst UI
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f /tmp/catalyst-ui.pid ]; then
|
||||
kill "$(cat /tmp/catalyst-ui.pid)" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
- name: Upload Playwright report
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cosmetic-guards-report
|
||||
path: |
|
||||
products/catalyst/bootstrap/ui/playwright-report/
|
||||
products/catalyst/bootstrap/ui/test-results/
|
||||
retention-days: 7
|
||||
27
.github/workflows/test-bootstrap-kit.yaml
vendored
@ -13,8 +13,6 @@ on:
|
||||
- 'platform/**/blueprint.yaml'
|
||||
- 'platform/**/chart/**'
|
||||
- 'clusters/**'
|
||||
- 'scripts/check-bootstrap-deps.sh'
|
||||
- 'scripts/expected-bootstrap-deps.yaml'
|
||||
- '.github/workflows/test-bootstrap-kit.yaml'
|
||||
branches: [main]
|
||||
pull_request:
|
||||
@ -23,39 +21,14 @@ on:
|
||||
- 'platform/**/blueprint.yaml'
|
||||
- 'platform/**/chart/**'
|
||||
- 'clusters/**'
|
||||
- 'scripts/check-bootstrap-deps.sh'
|
||||
- 'scripts/expected-bootstrap-deps.yaml'
|
||||
- '.github/workflows/test-bootstrap-kit.yaml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
dependency-graph-audit:
|
||||
# Audit the bootstrap-kit dependency graph against the expected DAG declared
|
||||
# in scripts/expected-bootstrap-deps.yaml. Mechanically verifies every HR's
|
||||
# spec.dependsOn matches the design contract in
|
||||
# docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2 + §3, and detects cycles. Runs on
|
||||
# every PR that touches a bootstrap-kit HR or the audit data files. Owned by
|
||||
# W2.K0; consumed by W2.K1-K4 PRs to validate slot 15-48 additions.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install yq
|
||||
run: |
|
||||
sudo wget -qO /usr/local/bin/yq \
|
||||
https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
|
||||
sudo chmod +x /usr/local/bin/yq
|
||||
yq --version
|
||||
|
||||
- name: Run bootstrap-kit dependency audit
|
||||
run: bash scripts/check-bootstrap-deps.sh
|
||||
|
||||
manifest-validation:
|
||||
# Static-only validation: blueprint.yaml + chart Chart.yaml + clusters/_template
|
||||
# parsing + dependency order check. Runs on every push.
|
||||
runs-on: ubuntu-latest
|
||||
needs: dependency-graph-audit
|
||||
defaults:
|
||||
run:
|
||||
working-directory: tests/e2e/bootstrap-kit
|
||||
|
||||
84
.github/workflows/test-strategy-flip.yaml
vendored
@ -1,84 +0,0 @@
|
||||
name: Test — Strategy flip regression (RollingUpdate -> Recreate)
|
||||
|
||||
# Defends the Catalyst chart against the contabo-mkt outage of
|
||||
# 2026-04-29. See docs/CHART-AUTHORING.md §"Strategy flips on
|
||||
# existing Deployments" for the full failure-mode analysis. The
|
||||
# integration test runner at tests/integration/strategy-flip.sh
|
||||
# encodes the contract; this workflow gives it a kind cluster and
|
||||
# kubectl.
|
||||
#
|
||||
# This is a chart-authoring gate. It runs whenever:
|
||||
# - the catalyst-api Deployment manifest changes (the canonical
|
||||
# resource that triggered the regression)
|
||||
# - the strategy-flip integration test changes
|
||||
# - the chart-authoring documentation changes
|
||||
#
|
||||
# Keep the trigger list tight; a chart-author touching unrelated
|
||||
# files should not pay this gate's cold-start cost.
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'products/catalyst/chart/templates/api-deployment.yaml'
|
||||
- 'tests/integration/strategy-flip.yaml'
|
||||
- 'tests/integration/strategy-flip.sh'
|
||||
- 'docs/CHART-AUTHORING.md'
|
||||
- '.github/workflows/test-strategy-flip.yaml'
|
||||
branches: [main]
|
||||
pull_request:
|
||||
paths:
|
||||
- 'products/catalyst/chart/templates/api-deployment.yaml'
|
||||
- 'tests/integration/strategy-flip.yaml'
|
||||
- 'tests/integration/strategy-flip.sh'
|
||||
- 'docs/CHART-AUTHORING.md'
|
||||
- '.github/workflows/test-strategy-flip.yaml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
strategy-flip-regression:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up kind cluster
|
||||
uses: helm/kind-action@v1
|
||||
with:
|
||||
# Pinned kind version so a kind release that ships with a
|
||||
# different K8s server cannot silently change the regression's
|
||||
# error string. Bumping the kind version is a deliberate
|
||||
# chart-authoring decision — re-run the local test, update
|
||||
# the assertion ConfigMap if needed, and PR together.
|
||||
cluster_name: strategy-flip-test
|
||||
version: v0.25.0
|
||||
# K8s 1.30+ enforces strict-decoding on apps/v1 Deployment by
|
||||
# default — that is the version where `$patch: replace`
|
||||
# inline in a base resource started failing CREATE with
|
||||
# "unknown field" errors. Locking to 1.30.6 ensures the test
|
||||
# exercises the same decoding path Flux's contabo-mkt cluster
|
||||
# runs (k3s 1.30 series).
|
||||
node_image: kindest/node:v1.30.6
|
||||
|
||||
- name: Verify kind cluster ready
|
||||
run: |
|
||||
kubectl cluster-info
|
||||
kubectl get nodes
|
||||
kubectl version --short || kubectl version
|
||||
|
||||
- name: Run strategy-flip integration test
|
||||
run: bash tests/integration/strategy-flip.sh
|
||||
|
||||
- name: Show kubectl events on failure
|
||||
if: failure()
|
||||
run: |
|
||||
# Surface anything the test runner did not already print.
|
||||
# The test cleans up its namespaces in a trap, so this only
|
||||
# fires when the runner errored mid-flight before the trap
|
||||
# had a chance to log full context.
|
||||
echo "=== test namespace events ==="
|
||||
kubectl get events -n strategy-flip-test --sort-by=.lastTimestamp 2>&1 || true
|
||||
echo "=== fresh-install namespace events ==="
|
||||
kubectl get events -n strategy-flip-fresh --sort-by=.lastTimestamp 2>&1 || true
|
||||
echo "=== chart manifest under test ==="
|
||||
cat products/catalyst/chart/templates/api-deployment.yaml || true
|
||||
14
.gitignore
vendored
@ -1,14 +0,0 @@
|
||||
# Helm dependency-build artifacts. Generated by `helm dependency build` in CI
|
||||
# and locally for validation. Subcharts are downloaded into chart/charts/ and
|
||||
# locked via chart/Chart.lock; both are reproducible from chart/Chart.yaml's
|
||||
# `dependencies:` block, so we don't track them.
|
||||
**/charts/*.tgz
|
||||
platform/*/chart/charts/
|
||||
platform/*/chart/Chart.lock
|
||||
products/*/chart/charts/
|
||||
products/*/chart/Chart.lock
|
||||
|
||||
# Node + dev artifacts (untracked already, listed here for clarity).
|
||||
**/node_modules/
|
||||
**/dist/
|
||||
**/.astro/
|
||||
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 575 KiB |
|
Before Width: | Height: | Size: 381 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 147 KiB |
@ -5,13 +5,13 @@
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
# kube-system is built into every Kubernetes cluster — never re-declare it.
|
||||
# Earlier revisions of 01-cilium.yaml AND 05-sealed-secrets.yaml both
|
||||
# declared it, which collided when kustomize tried to merge the two:
|
||||
# "may not add resource with an already registered id:
|
||||
# Namespace.v1.[noGrp]/kube-system.[noNs]"
|
||||
# This Blueprint installs Cilium INTO kube-system; the HelmRelease's
|
||||
# targetNamespace field below is sufficient.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kube-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-cilium
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -36,40 +34,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cilium
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cilium
|
||||
namespace: flux-system
|
||||
# Event-driven install: Helm completes when manifests apply, not when
|
||||
# cilium-agent reaches Ready (agent waits for envoyconfig CRDs that the
|
||||
# SAME chart installs — legitimate slow-Ready). Replaces blanket
|
||||
# spec.timeout: 15m band-aid from PR #221.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cilium:
|
||||
# Enable L7 proxy so Cilium's chart installs the
|
||||
# ciliumenvoyconfigs / ciliumclusterwideenvoyconfigs CRDs that the
|
||||
# cilium-agent waits for at startup. Without this, agent crash-loops
|
||||
# forever and the node.cilium.io/agent-not-ready taint never lifts.
|
||||
l7Proxy: true
|
||||
prometheus:
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
hubble:
|
||||
metrics:
|
||||
enabled: null
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
relay:
|
||||
enabled: false
|
||||
ui:
|
||||
enabled: false
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: cert-manager
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-cert-manager
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,27 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cert-manager
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cert-manager
|
||||
namespace: flux-system
|
||||
# Event-driven install: cert-manager installs CRDs + 3 deployments
|
||||
# (controller, webhook, cainjector). Webhook readiness depends on the
|
||||
# cainjector mutating the Secret — multi-minute path on cold start.
|
||||
# Helm install completes when manifests apply; subsequent dependsOn
|
||||
# checks Ready=True independently. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cert-manager:
|
||||
prometheus:
|
||||
enabled: false
|
||||
servicemonitor:
|
||||
enabled: false
|
||||
|
||||
@ -3,35 +3,14 @@
|
||||
# Wrapper chart: platform/flux/chart/
|
||||
# Catalyst-curated values: platform/flux/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# DOUBLE-INSTALL SAFETY (omantel.omani.works incident, 2026-04-29)
|
||||
# ----------------------------------------------------------------
|
||||
# Cloud-init pre-installs Flux core via
|
||||
# curl https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml
|
||||
# so that this very HelmRelease can be reconciled. helm-controller then
|
||||
# runs `helm install` for bp-flux on top of the already-running Flux. If
|
||||
# the chart's subchart `flux2` version disagrees with the cloud-init
|
||||
# install (different upstream Flux release), CRD `storedVersions`
|
||||
# mismatches → Helm install fails → rollback → rollback DELETES the
|
||||
# running Flux controllers → cluster has no GitOps engine and is
|
||||
# unrecoverable in-place.
|
||||
#
|
||||
# Mitigations applied here:
|
||||
# 1. bp-flux:1.1.2 pins the `flux2` subchart at 2.14.1 (= appVersion
|
||||
# 2.4.0) which matches cloud-init's v2.4.0 install.yaml.
|
||||
# 2. spec.upgrade.preserveValues: true — never silently overwrite
|
||||
# operator overlays on upgrade.
|
||||
# controller adopts the cloud-init-installed objects rather than
|
||||
# re-creating, so install is non-destructive when objects already
|
||||
# exist with matching apiVersion/kind/name.
|
||||
# See docs/RUNBOOK-PROVISIONING.md §"bp-flux double-install".
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: flux-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -41,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-flux
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -59,30 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-flux
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-flux
|
||||
namespace: flux-system
|
||||
# Event-driven install: bp-flux adopts the cloud-init-installed Flux
|
||||
# controllers; the helm-controller pod that reconciles THIS HR is itself
|
||||
# a target of the chart, so blocking on Ready=True is structurally
|
||||
# impossible. disableWait avoids the deadlock. Replaces PR #221 timeout.
|
||||
install:
|
||||
disableWait: true
|
||||
# Adopt cloud-init-installed Flux objects rather than fail on
|
||||
# ownership conflict (the objects exist before the HelmRelease ever
|
||||
# reconciles). Without this, the very first reconcile would error
|
||||
# with "object already exists" on every Flux controller Deployment.
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
# Keep operator-supplied values (e.g. resource overrides applied via
|
||||
# helm-controller out-of-band, or dry-run patches during incident
|
||||
# response) on chart upgrades. Without this, every upgrade would
|
||||
# reset the chart to default values, masking operator state.
|
||||
preserveValues: true
|
||||
# Match install behaviour — adopt rather than fail on conflict.
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: crossplane-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-crossplane
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -31,7 +29,6 @@ metadata:
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: crossplane
|
||||
targetNamespace: crossplane-system
|
||||
dependsOn:
|
||||
@ -39,7 +36,7 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-crossplane
|
||||
version: 1.1.3
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-crossplane
|
||||
|
||||
@ -5,9 +5,13 @@
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
# kube-system is built into every Kubernetes cluster — never re-declare it.
|
||||
# See 01-cilium.yaml for the full incident note. Sealed-Secrets installs
|
||||
# INTO kube-system; the HelmRelease's targetNamespace below is sufficient.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kube-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
@ -16,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-sealed-secrets
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -34,18 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-sealed-secrets
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-sealed-secrets
|
||||
namespace: flux-system
|
||||
# Event-driven install: single-replica controller + CRD; install
|
||||
# completes when manifests apply. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: spire-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-spire
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,23 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-spire
|
||||
version: 1.1.4
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-spire
|
||||
namespace: flux-system
|
||||
# Event-driven install: Helm completes when manifests apply, not when
|
||||
# pods reach Ready. spire-server StatefulSet has a multi-minute Ready
|
||||
# path (controller-manager waits for CRD informer cache sync, which is
|
||||
# itself triggered by the spire-crds subchart's CRD install). Flux's
|
||||
# `dependsOn` on downstream HRs (bp-nats-jetstream, bp-openbao) checks
|
||||
# Ready=True on this HR independently, so disableWait is the correct
|
||||
# shape — replaces the blanket spec.timeout: 15m band-aid from PR #221.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: nats-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-nats-jetstream
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,20 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-nats-jetstream
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-nats-jetstream
|
||||
namespace: flux-system
|
||||
# Event-driven install: NATS StatefulSet with JetStream raft initialisation
|
||||
# — quorum formation across N replicas is legitimately multi-minute on
|
||||
# cold start. Helm install completes when manifests apply; downstream
|
||||
# dependsOn checks Ready=True independently. Replaces PR #221 timeout.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: openbao
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-openbao
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,21 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-openbao
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-openbao
|
||||
namespace: flux-system
|
||||
# Event-driven install: OpenBao 3-node Raft cluster requires manual
|
||||
# unseal via `bao operator init` — pods stay sealed (Ready=False) until
|
||||
# an operator runs the unseal flow. Blocking Helm install on Ready=True
|
||||
# is structurally wrong for a sealed-by-default secret backend.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -10,7 +10,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: keycloak
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-keycloak
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,21 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-keycloak
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-keycloak
|
||||
namespace: flux-system
|
||||
# Event-driven install: Keycloak DB schema migration + realm import is
|
||||
# legitimately multi-minute on first install (PostgreSQL backend +
|
||||
# 100+ Liquibase changesets). Helm install completes when manifests
|
||||
# apply; downstream dependsOn checks Ready=True independently.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -11,7 +11,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: gitea
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -21,9 +21,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-gitea
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -39,31 +37,25 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-gitea
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-gitea
|
||||
namespace: flux-system
|
||||
# Event-driven install: Gitea PostgreSQL DB init + admin user creation +
|
||||
# public Blueprint catalog mirror seeding is legitimately multi-minute.
|
||||
# Helm install completes when manifests apply; downstream dependsOn
|
||||
# checks Ready=True independently. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
global:
|
||||
sovereignFQDN: ${SOVEREIGN_FQDN}
|
||||
# gitea hostname is gitea.${SOVEREIGN_FQDN}. The DNS A record
|
||||
sovereignFQDN: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
# gitea hostname is gitea.SOVEREIGN_FQDN_PLACEHOLDER. The DNS A record
|
||||
# was already published by the Phase-0 catalyst-dns helper.
|
||||
ingress:
|
||||
hosts:
|
||||
- host: gitea.${SOVEREIGN_FQDN}
|
||||
- host: gitea.SOVEREIGN_FQDN_PLACEHOLDER
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
# bp-catalyst-platform — Catalyst Blueprint #13 of 13. The umbrella
|
||||
# bp-catalyst-platform — Catalyst Blueprint #11 of 11. The umbrella
|
||||
# Blueprint that brings up the Catalyst control plane: console, marketplace,
|
||||
# admin, catalog-svc, projector, provisioning, environment-controller,
|
||||
# blueprint-controller, billing.
|
||||
#
|
||||
# Per docs/ARCHITECTURE.md §11 (Catalyst-on-Catalyst): once this is Ready,
|
||||
# the Sovereign is fully self-sufficient — sovereign-admin can log into
|
||||
# console.otech.omani.works and proceed with Phase 2 day-1 setup.
|
||||
# console.SOVEREIGN_FQDN_PLACEHOLDER and proceed with Phase 2 day-1 setup.
|
||||
#
|
||||
# Wrapper chart: products/catalyst/chart/
|
||||
|
||||
@ -15,7 +15,7 @@ kind: Namespace
|
||||
metadata:
|
||||
name: catalyst-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: otech.omani.works
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
@ -25,9 +25,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-catalyst-platform
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -43,22 +41,15 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-catalyst-platform
|
||||
version: 1.1.8
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-catalyst-platform
|
||||
namespace: flux-system
|
||||
# Event-driven install: umbrella chart deploys ~10 Catalyst services
|
||||
# (console, marketplace, admin, catalog-svc, projector, provisioning,
|
||||
# environment-controller, blueprint-controller, billing). Inter-service
|
||||
# readiness via OTel/NATS subjects is multi-minute and not Helm's
|
||||
# concern. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
# Per-Sovereign overrides for the umbrella — sovereign-FQDN-derived hostnames
|
||||
@ -66,14 +57,14 @@ spec:
|
||||
# OTel endpoints, NATS subjects) lives in products/catalyst/chart/values.yaml.
|
||||
values:
|
||||
global:
|
||||
sovereignFQDN: otech.omani.works
|
||||
sovereignFQDN: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
ingress:
|
||||
hosts:
|
||||
console:
|
||||
host: console.otech.omani.works
|
||||
host: console.SOVEREIGN_FQDN_PLACEHOLDER
|
||||
admin:
|
||||
host: admin.otech.omani.works
|
||||
host: admin.SOVEREIGN_FQDN_PLACEHOLDER
|
||||
marketplace:
|
||||
host: otech.omani.works
|
||||
host: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
api:
|
||||
host: api.otech.omani.works
|
||||
host: api.SOVEREIGN_FQDN_PLACEHOLDER
|
||||
@ -1,104 +0,0 @@
|
||||
# bp-powerdns — Catalyst Blueprint #11 of 13. Per-Sovereign authoritative
|
||||
# DNS. Every Sovereign owns its own PowerDNS Authoritative server with the
|
||||
# Sovereign's zones loaded into a CNPG-backed gpgsql backend; per-zone
|
||||
# DNSSEC (ECDSAP256SHA256), lua-records for geo + health-checked failover,
|
||||
# and a dnsdist companion for query rate-limiting + DDoS posture.
|
||||
#
|
||||
# Architectural anchor — per-Sovereign PowerDNS, NOT a shared instance:
|
||||
# This file was added so each Sovereign has its own bp-powerdns release
|
||||
# alongside bp-external-dns (#12). The original Phase-0 dial-tone
|
||||
# PowerDNS used to live as a singleton in the openova-system namespace
|
||||
# on contabo-mkt; #168 ("per-Sovereign PowerDNS zones") flipped that
|
||||
# model so a Sovereign's zones never leave the Sovereign's own cluster.
|
||||
# bp-external-dns's `dependsOn: [bp-powerdns]` therefore must be
|
||||
# satisfied by an in-cluster sibling release — this file IS that
|
||||
# sibling.
|
||||
#
|
||||
# Wrapper chart: platform/powerdns/chart/
|
||||
# Catalyst-curated values: platform/powerdns/chart/values.yaml
|
||||
# - 3 PowerDNS Authoritative replicas behind dnsdist
|
||||
# - CNPG-managed `pdns-pg` Postgres cluster for zone storage
|
||||
# - DNSSEC ON by default (ECDSAP256SHA256)
|
||||
# - Lua-records ON (geo + health-checked failover patterns)
|
||||
# - REST API at pdns.<sovereign>/api behind Traefik basicAuth
|
||||
#
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — the REST API ingress requests a TLS cert from
|
||||
# the cluster's letsencrypt-prod ClusterIssuer; without bp-cert-manager
|
||||
# reconciled first the Certificate resource sits Pending.
|
||||
#
|
||||
# Hard-but-implicit dependencies (CRDs, NOT sibling Blueprints):
|
||||
# - postgresql.cnpg.io/v1.Cluster — provided by the CNPG operator. The
|
||||
# chart's templates/cnpg-cluster.yaml renders this CR; if CNPG isn't
|
||||
# yet installed on the Sovereign, the HelmRelease will wait. CNPG is
|
||||
# a fixture of Catalyst-Zero (FABRIC group, componentGroups.ts `cnpg`)
|
||||
# and is installed alongside this kit by the bootstrap installer.
|
||||
# - traefik.io/v1alpha1.Middleware — Traefik is the Catalyst-Zero
|
||||
# ingress controller and is a fixture of every Sovereign.
|
||||
#
|
||||
# Per-Sovereign overrides intentionally NOT set here:
|
||||
# - Zones, API basic-auth credentials, anycast Floating-IP target — all
|
||||
# of those are provisioned by Crossplane / pool-domain-manager (PDM)
|
||||
# after the cluster comes up, NOT baked into the bootstrap kit. This
|
||||
# file installs the chart with defaults so the Sovereign has a working
|
||||
# authoritative DNS surface that PDM can then load zones into.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: powerdns
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: powerdns
|
||||
targetNamespace: powerdns
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-powerdns
|
||||
version: 1.1.3
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
# disableWait: a Sovereign without bp-cnpg yet reconciled has no
|
||||
# `pdns-pg-app` Secret (the chart's CNPG Cluster template is gated
|
||||
# behind the `postgresql.cnpg.io/v1` CRD via Capabilities.APIVersions
|
||||
# check — see chart/templates/cnpg-cluster.yaml). Without disableWait,
|
||||
# Helm's `--wait` would hold until the powerdns Deployment is Ready,
|
||||
# which can't happen until CNPG comes up and synthesises the Secret.
|
||||
# The HelmRelease itself reports Ready as soon as the manifests apply
|
||||
# cleanly; runtime convergence (powerdns pods becoming Ready once
|
||||
# CNPG lands) is observed via kubectl, not gated on Helm.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,80 +0,0 @@
|
||||
# bp-external-dns — Catalyst Blueprint #12 of 13. Per-Sovereign DNS sync —
|
||||
# ExternalDNS reconciles Service/Ingress hostnames into the per-Sovereign
|
||||
# PowerDNS authoritative server via the native `pdns` provider. Geo +
|
||||
# health-checked failover responses are owned by PowerDNS lua-records,
|
||||
# NOT by ExternalDNS.
|
||||
#
|
||||
# Wrapper chart: platform/external-dns/chart/
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — ExternalDNS HelmRelease only after TLS issuers
|
||||
# are reconciled, so any cert-manager-fronted webhook endpoints in
|
||||
# downstream overlays come up cleanly.
|
||||
# - bp-powerdns — native `pdns` provider points at the in-cluster
|
||||
# bp-powerdns Service and reads the `powerdns-api-credentials` Secret
|
||||
# it renders. Without bp-powerdns the ExternalDNS pod CrashLoops
|
||||
# trying to dial a non-existent DNS API.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: external-dns
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: external-dns
|
||||
targetNamespace: external-dns
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
- name: bp-powerdns
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-external-dns
|
||||
version: 1.1.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
# Event-driven install: ExternalDNS pod readiness depends on a
|
||||
# successful initial reconcile against the per-Sovereign PowerDNS API
|
||||
# (which itself stabilises after pdns-pg CNPG bootstraps) — legitimate
|
||||
# slow-Ready cascade. Helm install completes when manifests apply.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
# Per-Sovereign overrides — txtOwnerId MUST be the Sovereign FQDN so two
|
||||
# Sovereigns sharing a parent zone don't fight over the same record set.
|
||||
# domainFilters narrow the zones ExternalDNS will manage; per-Sovereign
|
||||
# cluster overlays patch this with the actual zone list.
|
||||
values:
|
||||
external-dns:
|
||||
txtOwnerId: ${SOVEREIGN_FQDN}
|
||||
txtPrefix: _externaldns.
|
||||
domainFilters:
|
||||
- ${SOVEREIGN_FQDN}
|
||||
@ -1,79 +0,0 @@
|
||||
# bp-catalyst-platform — Catalyst Blueprint #13 of 13. The umbrella
|
||||
# Blueprint that brings up the Catalyst control plane: console, marketplace,
|
||||
# admin, catalog-svc, projector, provisioning, environment-controller,
|
||||
# blueprint-controller, billing.
|
||||
#
|
||||
# Per docs/ARCHITECTURE.md §11 (Catalyst-on-Catalyst): once this is Ready,
|
||||
# the Sovereign is fully self-sufficient — sovereign-admin can log into
|
||||
# console.${SOVEREIGN_FQDN} and proceed with Phase 2 day-1 setup.
|
||||
#
|
||||
# Wrapper chart: products/catalyst/chart/
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: catalyst-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-catalyst-platform
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-catalyst-platform
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: catalyst-platform
|
||||
targetNamespace: catalyst-system
|
||||
dependsOn:
|
||||
- name: bp-gitea
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-catalyst-platform
|
||||
version: 1.1.8
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-catalyst-platform
|
||||
namespace: flux-system
|
||||
# Event-driven install: umbrella chart deploys ~10 Catalyst services
|
||||
# (console, marketplace, admin, catalog-svc, projector, provisioning,
|
||||
# environment-controller, blueprint-controller, billing). Inter-service
|
||||
# readiness via OTel/NATS subjects is multi-minute and not Helm's
|
||||
# concern. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
# Per-Sovereign overrides for the umbrella — sovereign-FQDN-derived hostnames
|
||||
# for console/admin/api. All chart-level Catalyst service config (image refs,
|
||||
# OTel endpoints, NATS subjects) lives in products/catalyst/chart/values.yaml.
|
||||
values:
|
||||
global:
|
||||
sovereignFQDN: ${SOVEREIGN_FQDN}
|
||||
ingress:
|
||||
hosts:
|
||||
console:
|
||||
host: console.${SOVEREIGN_FQDN}
|
||||
admin:
|
||||
host: admin.${SOVEREIGN_FQDN}
|
||||
marketplace:
|
||||
host: ${SOVEREIGN_FQDN}
|
||||
api:
|
||||
host: api.${SOVEREIGN_FQDN}
|
||||
@ -1,58 +0,0 @@
|
||||
# bp-crossplane-claims — Catalyst Day-2 CRUD XRDs (compose.openova.io/v1alpha1)
|
||||
# + default Hetzner-backed Compositions. Split out of bp-crossplane at
|
||||
# release 1.1.3 to resolve intra-chart CRD-ordering: a single Helm release
|
||||
# cannot install a CRD AND a CR of that CRD's kind in one apply pass —
|
||||
# the apiserver rejects the CR because the CRD is not yet registered.
|
||||
#
|
||||
# Wrapper chart: platform/crossplane-claims/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-crossplane is Ready (dependsOn below) — at which point
|
||||
# the apiextensions.crossplane.io/v1 CRDs that the upstream
|
||||
# crossplane subchart registers are live.
|
||||
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: crossplane-claims
|
||||
targetNamespace: crossplane-system
|
||||
# bp-crossplane installs the apiextensions.crossplane.io/v1 CRDs
|
||||
# (CompositeResourceDefinition, Composition) via the upstream subchart's
|
||||
# CRD payload. We MUST wait until that HelmRelease reports Ready=True
|
||||
# before applying the XRDs+Compositions in this chart, otherwise the
|
||||
# apiserver returns:
|
||||
# no matches for kind "CompositeResourceDefinition" in version
|
||||
# "apiextensions.crossplane.io/v1" -- ensure CRDs are installed first
|
||||
dependsOn:
|
||||
- name: bp-crossplane
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-crossplane-claims
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
install:
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,75 +0,0 @@
|
||||
# bp-external-secrets — Catalyst bootstrap-kit Blueprint, W2.K1 slot 15.
|
||||
# External Secrets Operator (ESO). Day-2 secret pipeline from OpenBao →
|
||||
# Kubernetes Secret materialization. Takes over from bp-sealed-secrets
|
||||
# (slot 05, transient) once OpenBao is Ready and ESO is reconciling.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §1.2 (Tier 0/3 — host-layer
|
||||
# secret distribution) and §2.3 (W2.K1 dependency graph): ESO is sequenced
|
||||
# at slot 15 (first slot in the W2.K1 contiguous range) but its
|
||||
# dependsOn is [bp-openbao(08), bp-cert-manager(02)] — Flux gates install
|
||||
# on Ready=True for both, regardless of slot order. ESO's webhook
|
||||
# requests a TLS cert from the cluster's letsencrypt-prod / cluster-ca
|
||||
# ClusterIssuer; without bp-cert-manager Ready, the Certificate stays
|
||||
# Pending and the operator never reaches Running.
|
||||
#
|
||||
# Wrapper chart: platform/external-secrets/chart/
|
||||
# Catalyst-curated values: platform/external-secrets/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: external-secrets-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: external-secrets
|
||||
targetNamespace: external-secrets-system
|
||||
# ESO depends on:
|
||||
# - bp-openbao(08): the secret backend ESO pulls from. ClusterSecretStore
|
||||
# resources reference the in-cluster OpenBao service; without OpenBao
|
||||
# Ready those CRs land but every ExternalSecret reconcile fails.
|
||||
# - bp-cert-manager(02): ESO's admission webhook needs a TLS cert.
|
||||
# bp-cert-manager provides the ClusterIssuer that signs it.
|
||||
dependsOn:
|
||||
- name: bp-openbao
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-external-secrets
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3 (Flux
|
||||
# dependsOn is the gate, not Helm timeout). Replaces blanket
|
||||
# spec.timeout: 15m band-aid pattern from PR #221, removed in PR #250.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-cnpg — Catalyst bootstrap-kit Blueprint, W2.K1 slot 16.
|
||||
# CloudNativePG operator. Per-Sovereign Postgres-as-a-service via
|
||||
# postgresql.cnpg.io/v1.Cluster CRs. Required by every PG-backed bootstrap
|
||||
# component: bp-powerdns (pdns-pg-app), bp-keycloak HA, bp-gitea metadata,
|
||||
# bp-langfuse, bp-grafana config DB, bp-temporal, bp-matrix synapse,
|
||||
# bp-llm-gateway, bp-bge, bp-nemo-guardrails, bp-openmeter (cnpg profile),
|
||||
# pool-domain-manager (PDM).
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) — cnpg gates the entire downstream observability/AI/relay
|
||||
# stack; placing it in the bootstrap-kit (instead of as an Application
|
||||
# Blueprint) is what unblocks the omantel-1 day-1 control plane.
|
||||
#
|
||||
# Resolves issue #254 (bp-powerdns pod stuck in CreateContainerConfigError
|
||||
# because pdns-pg-app Secret is generated by a CNPG Cluster CR; without
|
||||
# the operator the secret never materializes).
|
||||
#
|
||||
# Wrapper chart: platform/cnpg/chart/
|
||||
# Catalyst-curated values: platform/cnpg/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cnpg-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: cnpg
|
||||
targetNamespace: cnpg-system
|
||||
# CNPG only needs Flux Ready (its own CRDs ship in the same chart;
|
||||
# consumers of postgresql.cnpg.io/v1.Cluster gate themselves on bp-cnpg).
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cnpg
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,62 +0,0 @@
|
||||
# bp-valkey — Catalyst bootstrap-kit Blueprint, W2.K1 slot 17.
|
||||
# Redis-compatible cache (Valkey is the BSD-licensed Redis fork). Used by
|
||||
# Catalyst control-plane services for ephemeral session/state, and by
|
||||
# downstream Apps that need a Redis wire-protocol cache.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) — Valkey runs alongside CNPG so Apps can pick the right
|
||||
# storage shape per workload (relational vs cache).
|
||||
#
|
||||
# Wrapper chart: platform/valkey/chart/
|
||||
# Catalyst-curated values: platform/valkey/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: valkey
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: valkey
|
||||
targetNamespace: valkey
|
||||
# Valkey is a self-contained cache — only needs Flux Ready.
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-valkey
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-seaweedfs — Catalyst bootstrap-kit Blueprint, W2.K1 slot 18.
|
||||
# S3-compatible object storage encapsulation. Pre-requisite for every
|
||||
# blob-storage consumer in the bootstrap-kit:
|
||||
# - bp-velero (slot 34) — backups
|
||||
# - bp-loki (slot 22) — log chunks
|
||||
# - bp-mimir (slot 23) — metric blocks
|
||||
# - bp-tempo (slot 24) — trace blocks
|
||||
# - bp-harbor (slot 19) — registry blob storage
|
||||
# and downstream Apps that need cheap S3-compatible blob storage.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) and PROVISIONING-PLAN.md §3 — every Sovereign owns its own
|
||||
# SeaweedFS so blob data never leaves the Sovereign's cluster.
|
||||
#
|
||||
# Wrapper chart: platform/seaweedfs/chart/
|
||||
# Catalyst-curated values: platform/seaweedfs/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: seaweedfs
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: seaweedfs
|
||||
targetNamespace: seaweedfs
|
||||
# SeaweedFS depends on:
|
||||
# - bp-flux(03): standard GitOps prerequisite.
|
||||
# - bp-cert-manager(02): the S3 Filer endpoint terminates TLS via a
|
||||
# Certificate the chart requests from the cluster ClusterIssuer.
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-seaweedfs
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,69 +0,0 @@
|
||||
# bp-harbor — Catalyst bootstrap-kit Blueprint, W2.K1 slot 19.
|
||||
# Per-Sovereign OCI registry. Mirrors blueprint chart artifacts and
|
||||
# container images so the Sovereign isn't dependent on ghcr.io for
|
||||
# day-2 image pulls; also hosts Org-private images per Application.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §6.7 — Harbor sits in the
|
||||
# storage cohort (W2.K1) rather than apps cohort because it is a
|
||||
# consumer of CNPG (registry metadata DB) and SeaweedFS (blob backend),
|
||||
# and its presence gates Cosign signing in bp-sigstore (slot 32) and
|
||||
# image pinning across all later HRs.
|
||||
#
|
||||
# Wrapper chart: platform/harbor/chart/
|
||||
# Catalyst-curated values: platform/harbor/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: harbor
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: harbor
|
||||
targetNamespace: harbor
|
||||
# Harbor depends on:
|
||||
# - bp-cnpg(16): registry metadata DB (postgresql.cnpg.io/v1.Cluster).
|
||||
# - bp-seaweedfs(18): registry blob backend (S3-compatible).
|
||||
# - bp-cert-manager(02): registry endpoint TLS via ClusterIssuer.
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-seaweedfs
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-harbor
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,74 +0,0 @@
|
||||
# bp-opentelemetry — Catalyst Blueprint #20 (W2.K2 Observability batch).
|
||||
# OpenTelemetry Collector — pipeline source for the LGTM stack
|
||||
# (Loki / Mimir / Tempo). Receives OTLP from workloads and fans out
|
||||
# logs → Loki, metrics → Mimir, traces → Tempo.
|
||||
#
|
||||
# Wrapper chart: platform/opentelemetry/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cert-manager is Ready (the Collector's webhook /
|
||||
# OTLP-HTTPS receiver request TLS certs from the cluster
|
||||
# ClusterIssuer).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager (slot 02) — TLS for OTLP-HTTPS receiver and any
|
||||
# Collector webhooks.
|
||||
#
|
||||
# Hard-but-implicit dependencies (CRDs, NOT sibling Blueprints):
|
||||
# - opentelemetry.io/v1beta1.OpenTelemetryCollector — provided by the
|
||||
# OpenTelemetry Operator subchart bundled in this Blueprint.
|
||||
#
|
||||
# disableWait: the OTel Collector chart deploys multiple components
|
||||
# (operator, collector DaemonSet/Deployment, instrumentation CR). Helm
|
||||
# `--wait` would block on every Pod becoming Ready, which can't happen
|
||||
# until downstream backends (Loki/Mimir/Tempo, slots 22–24) are up to
|
||||
# accept exports. The HelmRelease itself reports Ready as soon as
|
||||
# manifests apply cleanly; runtime convergence is observed via kubectl.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: opentelemetry
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: opentelemetry
|
||||
targetNamespace: opentelemetry
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-opentelemetry
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-alloy — Catalyst Blueprint #21 (W2.K2 Observability batch).
|
||||
# Grafana Alloy — the unified telemetry collector for the LGTM stack.
|
||||
# Runs as a DaemonSet on every node; tails container logs, scrapes
|
||||
# Prometheus metrics, and forwards traces. Co-resident with bp-opentelemetry
|
||||
# (slot 20) — Alloy handles host-level collection (kubelet, journald,
|
||||
# node_exporter) while OTel handles app-level OTLP.
|
||||
#
|
||||
# Wrapper chart: platform/alloy/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-opentelemetry is Ready (Alloy's default config
|
||||
# forwards OTLP to the Collector's gRPC endpoint).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-opentelemetry (slot 20) — Alloy forwards OTLP to the Collector.
|
||||
# Without the Collector Service in place, Alloy retries forever on a
|
||||
# non-existent upstream.
|
||||
#
|
||||
# disableWait: Alloy is a DaemonSet — Helm `--wait` would block on
|
||||
# every node's Alloy Pod becoming Ready. On larger Sovereigns this can
|
||||
# legitimately take >5min during a cold-start image pull; the HelmRelease
|
||||
# reports Ready when manifests apply, runtime convergence observed via
|
||||
# kubectl.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: alloy
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: alloy
|
||||
targetNamespace: alloy
|
||||
dependsOn:
|
||||
- name: bp-opentelemetry
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-alloy
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-loki — Catalyst Blueprint #22 (W2.K2 Observability batch).
|
||||
# Grafana Loki — log storage tier of the LGTM stack. Default deployment
|
||||
# shape is SingleBinary (one Loki StatefulSet) — minimum operational
|
||||
# cost for a Solo Sovereign; per-Sovereign overlays scale to
|
||||
# distributor/ingester/querier StatefulSets when load warrants.
|
||||
#
|
||||
# Wrapper chart: platform/loki/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Loki chunks/index live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Loki uses SeaweedFS S3 for chunks and
|
||||
# index storage. Without SeaweedFS Ready, Loki cannot persist logs.
|
||||
#
|
||||
# disableWait: Loki SingleBinary becomes Ready only after creating the
|
||||
# S3 bucket and writing the first WAL block — both of which require
|
||||
# bp-seaweedfs to be fully reconciled (not just HelmRelease=Ready).
|
||||
# Helm `--wait` would block waiting for the StatefulSet rollout, which
|
||||
# the HelmRelease cannot influence.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: loki
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: loki
|
||||
targetNamespace: loki
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-loki
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-mimir — Catalyst Blueprint #23 (W2.K2 Observability batch).
|
||||
# Grafana Mimir — metrics storage tier of the LGTM stack. SeaweedFS-backed
|
||||
# blocks-storage; Prometheus-compatible remote-write endpoint.
|
||||
#
|
||||
# Wrapper chart: platform/mimir/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Mimir blocks live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Mimir blocks-storage uses SeaweedFS S3.
|
||||
# Without SeaweedFS Ready, Mimir compactor/ingester StatefulSets
|
||||
# cannot persist metric blocks.
|
||||
#
|
||||
# disableWait: Mimir is a multi-component distributed system (distributor,
|
||||
# ingester, querier, store-gateway, compactor, alertmanager, ruler).
|
||||
# Helm `--wait` would block on every StatefulSet rollout, which can
|
||||
# legitimately take >5min during a cold-start. The HelmRelease reports
|
||||
# Ready when manifests apply; runtime convergence is observed via
|
||||
# kubectl rollout status.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mimir
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: mimir
|
||||
targetNamespace: mimir
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-mimir
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,66 +0,0 @@
|
||||
# bp-tempo — Catalyst Blueprint #24 (W2.K2 Observability batch).
|
||||
# Grafana Tempo — distributed tracing storage tier of the LGTM stack.
|
||||
# Default deployment shape is single-binary (one Tempo StatefulSet) —
|
||||
# minimum operational cost for a Solo Sovereign.
|
||||
#
|
||||
# Wrapper chart: platform/tempo/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Tempo trace blocks live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Tempo blocks live on SeaweedFS S3.
|
||||
# Without SeaweedFS Ready, Tempo cannot persist spans.
|
||||
#
|
||||
# disableWait: Tempo single-binary StatefulSet becomes Ready after
|
||||
# creating the S3 bucket and initialising the WAL — both require
|
||||
# bp-seaweedfs to be fully reconciled. Helm `--wait` would block on
|
||||
# the rollout, which the HelmRelease cannot influence.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: tempo
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: tempo
|
||||
targetNamespace: tempo
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-tempo
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,75 +0,0 @@
|
||||
# bp-grafana — Catalyst Blueprint #25 (W2.K2 Observability batch).
|
||||
# Grafana — visualization layer of the LGTM stack. Pairs with bp-loki
|
||||
# (logs), bp-mimir (metrics), bp-tempo (traces); CNPG-backed Postgres
|
||||
# for dashboard/folder/alert state; Keycloak OIDC for SSO.
|
||||
#
|
||||
# Wrapper chart: platform/grafana/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cnpg, bp-loki, bp-mimir, bp-tempo, bp-keycloak are
|
||||
# all Ready.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cnpg (slot 16) — Postgres backend for Grafana state.
|
||||
# - bp-loki (slot 22) — datasource for logs.
|
||||
# - bp-mimir (slot 23) — datasource for metrics.
|
||||
# - bp-tempo (slot 24) — datasource for traces.
|
||||
# - bp-keycloak (slot 09) — OIDC IdP for SSO.
|
||||
#
|
||||
# disableWait: Grafana waits for its CNPG-managed `grafana-app` Secret
|
||||
# (synthesised by bp-cnpg via the chart's Cluster CR), and for upstream
|
||||
# datasource endpoints to answer. Helm `--wait` would block on the
|
||||
# Deployment rollout, which the HelmRelease cannot influence; runtime
|
||||
# convergence is observed via kubectl rollout status.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: grafana
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: grafana
|
||||
targetNamespace: grafana
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-loki
|
||||
- name: bp-mimir
|
||||
- name: bp-tempo
|
||||
- name: bp-keycloak
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-grafana
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,84 +0,0 @@
|
||||
# bp-langfuse — Catalyst Blueprint #26 (W2.K2 Observability batch).
|
||||
# Langfuse — LLM observability platform (traces, evaluations, prompt
|
||||
# management, cost attribution). Hooks into the Catalyst LLM gateway
|
||||
# (slot 40) once W2.K4 lands. CNPG-backed Postgres; Keycloak OIDC SSO.
|
||||
#
|
||||
# Wrapper chart: platform/langfuse/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cnpg, bp-keycloak, bp-cert-manager are all Ready.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cnpg (slot 16) — Postgres backend for Langfuse traces /
|
||||
# prompts / evaluations.
|
||||
# - bp-keycloak (slot 09) — OIDC IdP for SSO.
|
||||
# - bp-cert-manager (slot 02) — TLS for the Langfuse Ingress.
|
||||
#
|
||||
# disableWait: Langfuse waits for its CNPG-managed `langfuse-app` Secret
|
||||
# and for upstream Bitnami subcharts to be filtered out at template time
|
||||
# (the chart sets `postgresql.deploy=false`, `redis.deploy=false`,
|
||||
# `clickhouse.deploy=false`, `s3.deploy=false` to route to bp-cnpg /
|
||||
# bp-valkey / bp-clickhouse / bp-seaweedfs respectively). Helm `--wait`
|
||||
# would block on the Deployment rollout, which the HelmRelease cannot
|
||||
# influence.
|
||||
#
|
||||
# Forward-prep notice — issue #215 (bp-langfuse:1.0.0 GHCR publish 500):
|
||||
# At the time this HR file was authored, bp-langfuse:1.0.0 had not
|
||||
# published to oci://ghcr.io/openova-io due to a Helm v3.16 + GHCR
|
||||
# manifest interaction with langfuse's nested OCI subchart deps. W1.G
|
||||
# is the concurrent track fixing the publish path. Until that lands,
|
||||
# this HelmRelease will fail to install with a chart-pull error; this
|
||||
# is expected and tracked in #215. The HR file is committed now so
|
||||
# the moment the artifact is published, Flux reconciles the SeaweedFS-
|
||||
# /CNPG-/Keycloak-Ready Sovereign to bring Langfuse online without a
|
||||
# second deploy gate.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: langfuse
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: langfuse
|
||||
targetNamespace: langfuse
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-keycloak
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-langfuse
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,73 +0,0 @@
|
||||
# bp-kyverno — Catalyst bootstrap-kit Blueprint #27 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Kubernetes-native admission policy engine. Validating/mutating/generating
|
||||
# admission control via ClusterPolicy/Policy CRDs. HA mode with separate
|
||||
# admission/background/cleanup/reports controllers. The first guardrail
|
||||
# downstream Catalyst Apps land behind once the platform is bootstrapped.
|
||||
#
|
||||
# Wrapper chart: platform/kyverno/chart/ (umbrella over upstream
|
||||
# kyverno/kyverno chart, Catalyst-curated values under the `kyverno:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Kyverno admission webhooks need a working CNI + Service
|
||||
# mesh substrate to receive AdmissionReview requests from the apiserver.
|
||||
# Cilium is the root of the Catalyst-Zero DAG; until it is Ready the
|
||||
# apiserver→webhook path is not reachable and Kyverno install is racy.
|
||||
#
|
||||
# No further dependsOn: Kyverno installs its own CRDs and does not require
|
||||
# cert-manager (it auto-generates admission webhook TLS via its built-in
|
||||
# certificate controller).
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kyverno
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: kyverno
|
||||
targetNamespace: kyverno
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-kyverno
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
# Event-driven install: Kyverno HA mode brings up four controller
|
||||
# Deployments (admission, background, cleanup, reports) plus the
|
||||
# admission webhook TLS bootstrap. Pod Ready is multi-minute on a
|
||||
# cold cluster; Helm `--wait` would hold the HR's Ready=True signal
|
||||
# past the point where downstream HRs could legitimately reconcile.
|
||||
# disableWait lets Flux mark this Ready as soon as manifests apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,67 +0,0 @@
|
||||
# bp-reloader — Catalyst bootstrap-kit Blueprint #28 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Stakater Reloader watches ConfigMap/Secret changes and triggers rolling
|
||||
# restarts of dependent Deployments/StatefulSets/DaemonSets that opt in
|
||||
# via annotations. The secret/configmap-rotation glue across Catalyst —
|
||||
# bp-* workloads pick up rotated TLS material and rotated bootstrap
|
||||
# credentials without manual rollouts.
|
||||
#
|
||||
# Wrapper chart: platform/reloader/chart/ (umbrella over upstream
|
||||
# stakater/reloader chart, Catalyst-curated values under the `reloader:`
|
||||
# key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn: (none) — Reloader is independent infrastructure. It only
|
||||
# watches Kubernetes API resources and triggers rollouts; it does not
|
||||
# require any sibling Blueprint. Listed at slot 28 for numeric grouping
|
||||
# with the security/policy cohort but Flux will install it as soon as
|
||||
# the cluster is reachable.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: reloader
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: reloader
|
||||
targetNamespace: reloader
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-reloader
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
# Event-driven install (Catalyst convention) — Reloader's single
|
||||
# Deployment Ready path is fast in practice but disableWait keeps the
|
||||
# HR Ready signal aligned with manifest apply rather than runtime
|
||||
# convergence, matching the rest of the bootstrap-kit.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,66 +0,0 @@
|
||||
# bp-vpa — Catalyst bootstrap-kit Blueprint #29 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Vertical Pod Autoscaler. Per-host-cluster automated resource right-sizing
|
||||
# (Recommender + Updater + Admission Controller). Pairs with HPA/KEDA on
|
||||
# the horizontal axis. Provides recommendations even if not auto-applying;
|
||||
# Catalyst-default mode is `Off` (recommend only) until SRE opts a
|
||||
# workload into `Auto` via VerticalPodAutoscaler resources.
|
||||
#
|
||||
# Wrapper chart: platform/vpa/chart/ (umbrella over upstream
|
||||
# autoscaler/vertical-pod-autoscaler chart, Catalyst-curated values under
|
||||
# the `vertical-pod-autoscaler:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn: (none) — VPA is independent infrastructure. The Recommender
|
||||
# reads from metrics-server (a k3s fixture) and Prometheus/Mimir when
|
||||
# present, but neither is a hard sibling-Blueprint dep at install time;
|
||||
# the controllers tolerate metrics endpoints appearing late. Listed at
|
||||
# slot 29 for numeric grouping with the security/policy cohort.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: vpa
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: vpa
|
||||
targetNamespace: vpa
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-vpa
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
# Event-driven install: VPA brings up three Deployments (recommender,
|
||||
# updater, admission-controller) plus admission webhook TLS bootstrap.
|
||||
# disableWait keeps Flux's Ready signal aligned with manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-trivy — Catalyst bootstrap-kit Blueprint #30 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Trivy Operator. Static-scanning half of the Catalyst security stack:
|
||||
# vulnerability + misconfiguration scanning of running workloads, images,
|
||||
# RBAC, and rendered manifests. Pairs with bp-falco (runtime, slot 31)
|
||||
# and bp-kyverno (admission, slot 27).
|
||||
#
|
||||
# Wrapper chart: platform/trivy/chart/ (umbrella over upstream
|
||||
# aquasecurity/trivy-operator chart, Catalyst-curated values under the
|
||||
# `trivy-operator:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — Trivy Operator's admission webhook (and its
|
||||
# ConfigAuditReport mutating-webhook in HA mode) requires a TLS cert
|
||||
# from the cluster's letsencrypt-prod / internal CA ClusterIssuer
|
||||
# before the apiserver will route AdmissionReview traffic. Without
|
||||
# bp-cert-manager Ready, the Certificate resource sits Pending and
|
||||
# the webhook serves stale or no certs.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: trivy-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: trivy
|
||||
targetNamespace: trivy-system
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-trivy
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
# Event-driven install: Trivy Operator pulls a multi-hundred-MB
|
||||
# vulnerability database on first run; pod Ready is dominated by
|
||||
# initial DB hydration, not manifest apply. disableWait lets Flux
|
||||
# mark this Ready as soon as manifests apply; runtime convergence
|
||||
# (DB hydration, first scan reports landing) is observed via kubectl.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,69 +0,0 @@
|
||||
# bp-falco — Catalyst bootstrap-kit Blueprint #31 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Runtime threat detection (CNCF Graduated). eBPF kernel-level syscall
|
||||
# monitoring for container escapes, privilege escalation, anomalous
|
||||
# behavior. Runs as a DaemonSet on every host of the Sovereign;
|
||||
# Falcosidekick fans events into the SIEM pipeline (Loki/JetStream).
|
||||
#
|
||||
# Wrapper chart: platform/falco/chart/ (umbrella over upstream
|
||||
# falcosecurity/falco chart, Catalyst-curated values under the `falco:`
|
||||
# key — modern_ebpf driver, falcosidekick enabled).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Falco's modern_ebpf probe loads alongside Cilium's
|
||||
# eBPF programs on the same kernel hook points. Bringing Falco up
|
||||
# before the CNI is finalised has produced flaky probe-load races
|
||||
# in field testing; sequencing after bp-cilium Ready avoids that.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: falco
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: falco
|
||||
targetNamespace: falco
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-falco
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
# Event-driven install: Falco's DaemonSet rolls out per-node and the
|
||||
# eBPF probe load is sensitive to kernel headers / module presence.
|
||||
# Per-node Ready is properly observed via DaemonSet status, not via
|
||||
# Helm `--wait`. disableWait keeps Flux's signal aligned with
|
||||
# manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-sigstore — Catalyst bootstrap-kit Blueprint #32 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Sigstore Policy Controller. Admission gate for signed-image enforcement —
|
||||
# verifies Cosign signatures + attestations on container images before
|
||||
# admission. Pairs with bp-harbor (registry, slot 19) and the CI-side
|
||||
# Cosign signing path to close the supply-chain trust loop on the
|
||||
# Sovereign.
|
||||
#
|
||||
# Wrapper chart: platform/sigstore/chart/ (umbrella over upstream
|
||||
# sigstore/policy-controller chart, Catalyst-curated values under the
|
||||
# `policy-controller:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — Policy Controller is an admission webhook; the
|
||||
# apiserver requires a valid TLS cert on the webhook Service before
|
||||
# it will route AdmissionReview traffic. Without bp-cert-manager
|
||||
# Ready, the Certificate sits Pending and admission fails open or
|
||||
# fails closed (depending on FailurePolicy), neither of which is
|
||||
# the intended security posture.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: sigstore-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: sigstore
|
||||
targetNamespace: sigstore-system
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-sigstore
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
# Event-driven install: Policy Controller bootstraps its admission
|
||||
# webhook TLS via cert-manager and reaches Ready only after the
|
||||
# Certificate is issued + bound. disableWait avoids holding the HR
|
||||
# signal on a runtime-convergence event.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-syft-grype — Catalyst bootstrap-kit Blueprint #33 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Anchore Syft + Grype as a scheduled CronJob. SBOM generation (Syft)
|
||||
# paired with vulnerability matching (Grype) — the offline / scheduled
|
||||
# half of the supply-chain stack. Anchore does not publish a Helm chart
|
||||
# for the open-source CLIs, so this Blueprint is a scratch chart that
|
||||
# wires the official ghcr.io/anchore/syft and ghcr.io/anchore/grype
|
||||
# containers into a CronJob that scans the Sovereign's image inventory.
|
||||
#
|
||||
# Wrapper chart: platform/syft-grype/chart/ (Catalyst-authored scratch
|
||||
# chart — no upstream subchart).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — the result-export sidecar publishes SBOMs over
|
||||
# mTLS to the central scan-result store; cert-manager issues the
|
||||
# workload's TLS material via the cluster's ClusterIssuer.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: syft-grype
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: syft-grype
|
||||
targetNamespace: syft-grype
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-syft-grype
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
# Event-driven install: the Blueprint is mostly a CronJob + RBAC
|
||||
# surface. There is no long-running Deployment whose Ready=True is
|
||||
# meaningful — disableWait is the correct shape so Flux marks Ready
|
||||
# as soon as manifests apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,72 +0,0 @@
|
||||
# bp-velero — Catalyst bootstrap-kit Blueprint #34 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Per-host-cluster backup engine. Catalyst-Zero pins backups to SeaweedFS
|
||||
# (the unified S3 layer, slot 18) so backup data never leaves the
|
||||
# Sovereign at install time; per-Sovereign archival to a cloud backend
|
||||
# is wired in post-bootstrap via Crossplane.
|
||||
#
|
||||
# Wrapper chart: platform/velero/chart/ (umbrella over upstream
|
||||
# vmware-tanzu/velero chart, Catalyst-curated values under the `velero:`
|
||||
# key — `seaweedfs` BackupStorageLocation provider, no cloud plugin
|
||||
# pinned at install time).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs — Velero's BackupStorageLocation points at the
|
||||
# in-cluster SeaweedFS S3 endpoint (`seaweedfs.seaweedfs.svc:8333`)
|
||||
# and reads the `seaweedfs-s3-credentials` Secret SeaweedFS renders
|
||||
# during install. Without bp-seaweedfs Ready, the BSL Phase sits
|
||||
# `Unavailable` and Velero's first reconcile fails — every backup
|
||||
# CR queues with the same error until the dep lands.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: velero
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: velero
|
||||
targetNamespace: velero
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-velero
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
# Event-driven install: Velero's Deployment Ready depends on the
|
||||
# node-agent DaemonSet rolling out and the BackupStorageLocation
|
||||
# reaching `Available` — both runtime-convergence events that Flux
|
||||
# observes via the BSL CR phase, not via Helm `--wait`. disableWait
|
||||
# keeps the HR's Ready signal aligned with manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,70 +0,0 @@
|
||||
# bp-coraza — Catalyst bootstrap-kit Blueprint #35 (W2.K4 — Tier 8: edge).
|
||||
# OWASP-licensed Web Application Firewall, ModSecurity-rule-compatible.
|
||||
# Speaks the HAProxy SPOE protocol; sits in front of Cilium Gateway / HAProxy
|
||||
# fronts to enforce WAF policies on inbound traffic to Sovereign-facing
|
||||
# services (keycloak, grafana, stalwart, marketplace).
|
||||
#
|
||||
# Wrapper chart: platform/coraza/chart/
|
||||
# Catalyst-curated values: platform/coraza/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Coraza enforces L7 policy via Cilium L7 proxy / Gateway
|
||||
# API; Cilium must be Ready (CNI + Gateway controller) before WAF
|
||||
# evaluation hooks become reachable.
|
||||
# - bp-cert-manager — Issuers must be reconciled so any TLS-fronted SPOA
|
||||
# listeners (per-Sovereign overlays) come up with valid certs.
|
||||
#
|
||||
# install/upgrade.disableWait: true — Coraza-spoa Deployment Ready signal
|
||||
# is event-driven via the Flux dependsOn graph (downstream HRs check
|
||||
# Ready=True on this HR). Per session-2026-04-30 architectural decision,
|
||||
# we never use blanket `spec.timeout: Nm` watchdogs.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: coraza
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: coraza
|
||||
targetNamespace: coraza
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-coraza
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -15,28 +15,4 @@ resources:
|
||||
- 08-openbao.yaml
|
||||
- 09-keycloak.yaml
|
||||
- 10-gitea.yaml
|
||||
- 11-powerdns.yaml
|
||||
- 12-external-dns.yaml
|
||||
- 13-bp-catalyst-platform.yaml
|
||||
- 14-crossplane-claims.yaml
|
||||
- 15-external-secrets.yaml
|
||||
- 16-cnpg.yaml
|
||||
- 17-valkey.yaml
|
||||
- 18-seaweedfs.yaml
|
||||
- 19-harbor.yaml
|
||||
- 20-opentelemetry.yaml
|
||||
- 21-alloy.yaml
|
||||
- 22-loki.yaml
|
||||
- 23-mimir.yaml
|
||||
- 24-tempo.yaml
|
||||
- 25-grafana.yaml
|
||||
- 26-langfuse.yaml
|
||||
- 27-kyverno.yaml
|
||||
- 28-reloader.yaml
|
||||
- 29-vpa.yaml
|
||||
- 30-trivy.yaml
|
||||
- 31-falco.yaml
|
||||
- 32-sigstore.yaml
|
||||
- 33-syft-grype.yaml
|
||||
- 34-velero.yaml
|
||||
- 35-coraza.yaml
|
||||
- 11-bp-catalyst-platform.yaml
|
||||
|
||||
@ -1,19 +1,10 @@
|
||||
# Shared Sovereign Flux Kustomization root.
|
||||
# Per-Sovereign Flux Kustomization root.
|
||||
#
|
||||
# Issue #218: this directory is the canonical bootstrap tree for EVERY
|
||||
# Sovereign. The Sovereign's FQDN is interpolated into the manifests at
|
||||
# Flux apply time via the cloud-init Kustomization's
|
||||
# `postBuild.substitute.SOVEREIGN_FQDN` envsubst hook (see
|
||||
# infra/hetzner/cloudinit-control-plane.tftpl). No per-Sovereign copy
|
||||
# of this tree is committed to the repo before provisioning.
|
||||
#
|
||||
# The Sovereign's k3s control plane (cloud-init bootstrap) installs
|
||||
# Flux core, then applies a GitRepository selecting this _template
|
||||
# tree (`!/clusters/_template`) plus two Kustomizations whose `path`
|
||||
# fields point at `clusters/_template/bootstrap-kit` and
|
||||
# `clusters/_template/infrastructure`. Flux's envsubst replaces
|
||||
# `${SOVEREIGN_FQDN}` in the rendered manifests with the Sovereign's
|
||||
# FQDN. From there Flux owns everything.
|
||||
# Copied from clusters/_template/ → clusters/<sovereign-fqdn>/ at provisioning
|
||||
# time, with SOVEREIGN_FQDN_PLACEHOLDER substituted. The Sovereign's k3s
|
||||
# control plane (cloud-init bootstrap) installs Flux core, then applies a
|
||||
# GitRepository pointing at this Sovereign's directory. From there Flux owns
|
||||
# everything.
|
||||
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
# kube-system is built into every Kubernetes cluster — never re-declare it.
|
||||
# Earlier revisions of 01-cilium.yaml AND 05-sealed-secrets.yaml both
|
||||
# declared it, which collided when kustomize tried to merge the two:
|
||||
# "may not add resource with an already registered id:
|
||||
# Namespace.v1.[noGrp]/kube-system.[noNs]"
|
||||
# This Blueprint installs Cilium INTO kube-system; the HelmRelease's
|
||||
# targetNamespace field below is sufficient.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kube-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-cilium
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -36,40 +34,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cilium
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cilium
|
||||
namespace: flux-system
|
||||
# Event-driven install: Helm completes when manifests apply, not when
|
||||
# cilium-agent reaches Ready (agent waits for envoyconfig CRDs that the
|
||||
# SAME chart installs — legitimate slow-Ready). Replaces blanket
|
||||
# spec.timeout: 15m band-aid from PR #221.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cilium:
|
||||
# Enable L7 proxy so Cilium's chart installs the
|
||||
# ciliumenvoyconfigs / ciliumclusterwideenvoyconfigs CRDs that the
|
||||
# cilium-agent waits for at startup. Without this, agent crash-loops
|
||||
# forever and the node.cilium.io/agent-not-ready taint never lifts.
|
||||
l7Proxy: true
|
||||
prometheus:
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
hubble:
|
||||
metrics:
|
||||
enabled: null
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
relay:
|
||||
enabled: false
|
||||
ui:
|
||||
enabled: false
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-cert-manager
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,27 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cert-manager
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cert-manager
|
||||
namespace: flux-system
|
||||
# Event-driven install: cert-manager installs CRDs + 3 deployments
|
||||
# (controller, webhook, cainjector). Webhook readiness depends on the
|
||||
# cainjector mutating the Secret — multi-minute path on cold start.
|
||||
# Helm install completes when manifests apply; subsequent dependsOn
|
||||
# checks Ready=True independently. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cert-manager:
|
||||
prometheus:
|
||||
enabled: false
|
||||
servicemonitor:
|
||||
enabled: false
|
||||
|
||||
@ -3,28 +3,7 @@
|
||||
# Wrapper chart: platform/flux/chart/
|
||||
# Catalyst-curated values: platform/flux/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# DOUBLE-INSTALL SAFETY (omantel.omani.works incident, 2026-04-29)
|
||||
# ----------------------------------------------------------------
|
||||
# Cloud-init pre-installs Flux core via
|
||||
# curl https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml
|
||||
# so that this very HelmRelease can be reconciled. helm-controller then
|
||||
# runs `helm install` for bp-flux on top of the already-running Flux. If
|
||||
# the chart's subchart `flux2` version disagrees with the cloud-init
|
||||
# install (different upstream Flux release), CRD `storedVersions`
|
||||
# mismatches → Helm install fails → rollback → rollback DELETES the
|
||||
# running Flux controllers → cluster has no GitOps engine and is
|
||||
# unrecoverable in-place.
|
||||
#
|
||||
# Mitigations applied here:
|
||||
# 1. bp-flux:1.1.2 pins the `flux2` subchart at 2.14.1 (= appVersion
|
||||
# 2.4.0) which matches cloud-init's v2.4.0 install.yaml.
|
||||
# 2. spec.upgrade.preserveValues: true — never silently overwrite
|
||||
# operator overlays on upgrade.
|
||||
# controller adopts the cloud-init-installed objects rather than
|
||||
# re-creating, so install is non-destructive when objects already
|
||||
# exist with matching apiVersion/kind/name.
|
||||
# See docs/RUNBOOK-PROVISIONING.md §"bp-flux double-install".
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
@ -41,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-flux
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -59,30 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-flux
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-flux
|
||||
namespace: flux-system
|
||||
# Event-driven install: bp-flux adopts the cloud-init-installed Flux
|
||||
# controllers; the helm-controller pod that reconciles THIS HR is itself
|
||||
# a target of the chart, so blocking on Ready=True is structurally
|
||||
# impossible. disableWait avoids the deadlock. Replaces PR #221 timeout.
|
||||
install:
|
||||
disableWait: true
|
||||
# Adopt cloud-init-installed Flux objects rather than fail on
|
||||
# ownership conflict (the objects exist before the HelmRelease ever
|
||||
# reconciles). Without this, the very first reconcile would error
|
||||
# with "object already exists" on every Flux controller Deployment.
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
# Keep operator-supplied values (e.g. resource overrides applied via
|
||||
# helm-controller out-of-band, or dry-run patches during incident
|
||||
# response) on chart upgrades. Without this, every upgrade would
|
||||
# reset the chart to default values, masking operator state.
|
||||
preserveValues: true
|
||||
# Match install behaviour — adopt rather than fail on conflict.
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-crossplane
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -31,7 +29,6 @@ metadata:
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: crossplane
|
||||
targetNamespace: crossplane-system
|
||||
dependsOn:
|
||||
@ -39,7 +36,7 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-crossplane
|
||||
version: 1.1.3
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-crossplane
|
||||
|
||||
@ -5,9 +5,13 @@
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
# kube-system is built into every Kubernetes cluster — never re-declare it.
|
||||
# See 01-cilium.yaml for the full incident note. Sealed-Secrets installs
|
||||
# INTO kube-system; the HelmRelease's targetNamespace below is sufficient.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kube-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
@ -16,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-sealed-secrets
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -34,18 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-sealed-secrets
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-sealed-secrets
|
||||
namespace: flux-system
|
||||
# Event-driven install: single-replica controller + CRD; install
|
||||
# completes when manifests apply. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-spire
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,23 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-spire
|
||||
version: 1.1.4
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-spire
|
||||
namespace: flux-system
|
||||
# Event-driven install: Helm completes when manifests apply, not when
|
||||
# pods reach Ready. spire-server StatefulSet has a multi-minute Ready
|
||||
# path (controller-manager waits for CRD informer cache sync, which is
|
||||
# itself triggered by the spire-crds subchart's CRD install). Flux's
|
||||
# `dependsOn` on downstream HRs (bp-nats-jetstream, bp-openbao) checks
|
||||
# Ready=True on this HR independently, so disableWait is the correct
|
||||
# shape — replaces the blanket spec.timeout: 15m band-aid from PR #221.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-nats-jetstream
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,20 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-nats-jetstream
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-nats-jetstream
|
||||
namespace: flux-system
|
||||
# Event-driven install: NATS StatefulSet with JetStream raft initialisation
|
||||
# — quorum formation across N replicas is legitimately multi-minute on
|
||||
# cold start. Helm install completes when manifests apply; downstream
|
||||
# dependsOn checks Ready=True independently. Replaces PR #221 timeout.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-openbao
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,21 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-openbao
|
||||
version: 1.1.1
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-openbao
|
||||
namespace: flux-system
|
||||
# Event-driven install: OpenBao 3-node Raft cluster requires manual
|
||||
# unseal via `bao operator init` — pods stay sealed (Ready=False) until
|
||||
# an operator runs the unseal flow. Blocking Helm install on Ready=True
|
||||
# is structurally wrong for a sealed-by-default secret backend.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -20,9 +20,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-keycloak
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -38,21 +36,14 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-keycloak
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-keycloak
|
||||
namespace: flux-system
|
||||
# Event-driven install: Keycloak DB schema migration + realm import is
|
||||
# legitimately multi-minute on first install (PostgreSQL backend +
|
||||
# 100+ Liquibase changesets). Helm install completes when manifests
|
||||
# apply; downstream dependsOn checks Ready=True independently.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
|
||||
@ -21,9 +21,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-gitea
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -39,21 +37,15 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-gitea
|
||||
version: 1.1.2
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-gitea
|
||||
namespace: flux-system
|
||||
# Event-driven install: Gitea PostgreSQL DB init + admin user creation +
|
||||
# public Blueprint catalog mirror seeding is legitimately multi-minute.
|
||||
# Helm install completes when manifests apply; downstream dependsOn
|
||||
# checks Ready=True independently. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# bp-catalyst-platform — Catalyst Blueprint #13 of 13. The umbrella
|
||||
# bp-catalyst-platform — Catalyst Blueprint #11 of 11. The umbrella
|
||||
# Blueprint that brings up the Catalyst control plane: console, marketplace,
|
||||
# admin, catalog-svc, projector, provisioning, environment-controller,
|
||||
# blueprint-controller, billing.
|
||||
@ -25,9 +25,7 @@ metadata:
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
url: oci://ghcr.io/openova-io/bp-catalyst-platform
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
@ -43,22 +41,15 @@ spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-catalyst-platform
|
||||
version: 1.1.8
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-catalyst-platform
|
||||
namespace: flux-system
|
||||
# Event-driven install: umbrella chart deploys ~10 Catalyst services
|
||||
# (console, marketplace, admin, catalog-svc, projector, provisioning,
|
||||
# environment-controller, blueprint-controller, billing). Inter-service
|
||||
# readiness via OTel/NATS subjects is multi-minute and not Helm's
|
||||
# concern. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
# Per-Sovereign overrides for the umbrella — sovereign-FQDN-derived hostnames
|
||||
@ -1,104 +0,0 @@
|
||||
# bp-powerdns — Catalyst Blueprint #11 of 13. Per-Sovereign authoritative
|
||||
# DNS. Every Sovereign owns its own PowerDNS Authoritative server with the
|
||||
# Sovereign's zones loaded into a CNPG-backed gpgsql backend; per-zone
|
||||
# DNSSEC (ECDSAP256SHA256), lua-records for geo + health-checked failover,
|
||||
# and a dnsdist companion for query rate-limiting + DDoS posture.
|
||||
#
|
||||
# Architectural anchor — per-Sovereign PowerDNS, NOT a shared instance:
|
||||
# This file was added so each Sovereign has its own bp-powerdns release
|
||||
# alongside bp-external-dns (#12). The original Phase-0 dial-tone
|
||||
# PowerDNS used to live as a singleton in the openova-system namespace
|
||||
# on contabo-mkt; #168 ("per-Sovereign PowerDNS zones") flipped that
|
||||
# model so a Sovereign's zones never leave the Sovereign's own cluster.
|
||||
# bp-external-dns's `dependsOn: [bp-powerdns]` therefore must be
|
||||
# satisfied by an in-cluster sibling release — this file IS that
|
||||
# sibling.
|
||||
#
|
||||
# Wrapper chart: platform/powerdns/chart/
|
||||
# Catalyst-curated values: platform/powerdns/chart/values.yaml
|
||||
# - 3 PowerDNS Authoritative replicas behind dnsdist
|
||||
# - CNPG-managed `pdns-pg` Postgres cluster for zone storage
|
||||
# - DNSSEC ON by default (ECDSAP256SHA256)
|
||||
# - Lua-records ON (geo + health-checked failover patterns)
|
||||
# - REST API at pdns.<sovereign>/api behind Traefik basicAuth
|
||||
#
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — the REST API ingress requests a TLS cert from
|
||||
# the cluster's letsencrypt-prod ClusterIssuer; without bp-cert-manager
|
||||
# reconciled first the Certificate resource sits Pending.
|
||||
#
|
||||
# Hard-but-implicit dependencies (CRDs, NOT sibling Blueprints):
|
||||
# - postgresql.cnpg.io/v1.Cluster — provided by the CNPG operator. The
|
||||
# chart's templates/cnpg-cluster.yaml renders this CR; if CNPG isn't
|
||||
# yet installed on the Sovereign, the HelmRelease will wait. CNPG is
|
||||
# a fixture of Catalyst-Zero (FABRIC group, componentGroups.ts `cnpg`)
|
||||
# and is installed alongside this kit by the bootstrap installer.
|
||||
# - traefik.io/v1alpha1.Middleware — Traefik is the Catalyst-Zero
|
||||
# ingress controller and is a fixture of every Sovereign.
|
||||
#
|
||||
# Per-Sovereign overrides intentionally NOT set here:
|
||||
# - Zones, API basic-auth credentials, anycast Floating-IP target — all
|
||||
# of those are provisioned by Crossplane / pool-domain-manager (PDM)
|
||||
# after the cluster comes up, NOT baked into the bootstrap kit. This
|
||||
# file installs the chart with defaults so the Sovereign has a working
|
||||
# authoritative DNS surface that PDM can then load zones into.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: powerdns
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: powerdns
|
||||
targetNamespace: powerdns
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-powerdns
|
||||
version: 1.1.3
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-powerdns
|
||||
namespace: flux-system
|
||||
# disableWait: a Sovereign without bp-cnpg yet reconciled has no
|
||||
# `pdns-pg-app` Secret (the chart's CNPG Cluster template is gated
|
||||
# behind the `postgresql.cnpg.io/v1` CRD via Capabilities.APIVersions
|
||||
# check — see chart/templates/cnpg-cluster.yaml). Without disableWait,
|
||||
# Helm's `--wait` would hold until the powerdns Deployment is Ready,
|
||||
# which can't happen until CNPG comes up and synthesises the Secret.
|
||||
# The HelmRelease itself reports Ready as soon as the manifests apply
|
||||
# cleanly; runtime convergence (powerdns pods becoming Ready once
|
||||
# CNPG lands) is observed via kubectl, not gated on Helm.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,80 +0,0 @@
|
||||
# bp-external-dns — Catalyst Blueprint #12 of 13. Per-Sovereign DNS sync —
|
||||
# ExternalDNS reconciles Service/Ingress hostnames into the per-Sovereign
|
||||
# PowerDNS authoritative server via the native `pdns` provider. Geo +
|
||||
# health-checked failover responses are owned by PowerDNS lua-records,
|
||||
# NOT by ExternalDNS.
|
||||
#
|
||||
# Wrapper chart: platform/external-dns/chart/
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — ExternalDNS HelmRelease only after TLS issuers
|
||||
# are reconciled, so any cert-manager-fronted webhook endpoints in
|
||||
# downstream overlays come up cleanly.
|
||||
# - bp-powerdns — native `pdns` provider points at the in-cluster
|
||||
# bp-powerdns Service and reads the `powerdns-api-credentials` Secret
|
||||
# it renders. Without bp-powerdns the ExternalDNS pod CrashLoops
|
||||
# trying to dial a non-existent DNS API.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: external-dns
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: external-dns
|
||||
targetNamespace: external-dns
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
- name: bp-powerdns
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-external-dns
|
||||
version: 1.1.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-external-dns
|
||||
namespace: flux-system
|
||||
# Event-driven install: ExternalDNS pod readiness depends on a
|
||||
# successful initial reconcile against the per-Sovereign PowerDNS API
|
||||
# (which itself stabilises after pdns-pg CNPG bootstraps) — legitimate
|
||||
# slow-Ready cascade. Helm install completes when manifests apply.
|
||||
# Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
# Per-Sovereign overrides — txtOwnerId MUST be the Sovereign FQDN so two
|
||||
# Sovereigns sharing a parent zone don't fight over the same record set.
|
||||
# domainFilters narrow the zones ExternalDNS will manage; per-Sovereign
|
||||
# cluster overlays patch this with the actual zone list.
|
||||
values:
|
||||
external-dns:
|
||||
txtOwnerId: omantel.omani.works
|
||||
txtPrefix: _externaldns.
|
||||
domainFilters:
|
||||
- omantel.omani.works
|
||||
@ -1,58 +0,0 @@
|
||||
# bp-crossplane-claims — Catalyst Day-2 CRUD XRDs (compose.openova.io/v1alpha1)
|
||||
# + default Hetzner-backed Compositions. Split out of bp-crossplane at
|
||||
# release 1.1.3 to resolve intra-chart CRD-ordering: a single Helm release
|
||||
# cannot install a CRD AND a CR of that CRD's kind in one apply pass —
|
||||
# the apiserver rejects the CR because the CRD is not yet registered.
|
||||
#
|
||||
# Wrapper chart: platform/crossplane-claims/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-crossplane is Ready (dependsOn below) — at which point
|
||||
# the apiextensions.crossplane.io/v1 CRDs that the upstream
|
||||
# crossplane subchart registers are live.
|
||||
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: crossplane-claims
|
||||
targetNamespace: crossplane-system
|
||||
# bp-crossplane installs the apiextensions.crossplane.io/v1 CRDs
|
||||
# (CompositeResourceDefinition, Composition) via the upstream subchart's
|
||||
# CRD payload. We MUST wait until that HelmRelease reports Ready=True
|
||||
# before applying the XRDs+Compositions in this chart, otherwise the
|
||||
# apiserver returns:
|
||||
# no matches for kind "CompositeResourceDefinition" in version
|
||||
# "apiextensions.crossplane.io/v1" -- ensure CRDs are installed first
|
||||
dependsOn:
|
||||
- name: bp-crossplane
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-crossplane-claims
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-crossplane-claims
|
||||
namespace: flux-system
|
||||
install:
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,75 +0,0 @@
|
||||
# bp-external-secrets — Catalyst bootstrap-kit Blueprint, W2.K1 slot 15.
|
||||
# External Secrets Operator (ESO). Day-2 secret pipeline from OpenBao →
|
||||
# Kubernetes Secret materialization. Takes over from bp-sealed-secrets
|
||||
# (slot 05, transient) once OpenBao is Ready and ESO is reconciling.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §1.2 (Tier 0/3 — host-layer
|
||||
# secret distribution) and §2.3 (W2.K1 dependency graph): ESO is sequenced
|
||||
# at slot 15 (first slot in the W2.K1 contiguous range) but its
|
||||
# dependsOn is [bp-openbao(08), bp-cert-manager(02)] — Flux gates install
|
||||
# on Ready=True for both, regardless of slot order. ESO's webhook
|
||||
# requests a TLS cert from the cluster's letsencrypt-prod / cluster-ca
|
||||
# ClusterIssuer; without bp-cert-manager Ready, the Certificate stays
|
||||
# Pending and the operator never reaches Running.
|
||||
#
|
||||
# Wrapper chart: platform/external-secrets/chart/
|
||||
# Catalyst-curated values: platform/external-secrets/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: external-secrets-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: external-secrets
|
||||
targetNamespace: external-secrets-system
|
||||
# ESO depends on:
|
||||
# - bp-openbao(08): the secret backend ESO pulls from. ClusterSecretStore
|
||||
# resources reference the in-cluster OpenBao service; without OpenBao
|
||||
# Ready those CRs land but every ExternalSecret reconcile fails.
|
||||
# - bp-cert-manager(02): ESO's admission webhook needs a TLS cert.
|
||||
# bp-cert-manager provides the ClusterIssuer that signs it.
|
||||
dependsOn:
|
||||
- name: bp-openbao
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-external-secrets
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-external-secrets
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3 (Flux
|
||||
# dependsOn is the gate, not Helm timeout). Replaces blanket
|
||||
# spec.timeout: 15m band-aid pattern from PR #221, removed in PR #250.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-cnpg — Catalyst bootstrap-kit Blueprint, W2.K1 slot 16.
|
||||
# CloudNativePG operator. Per-Sovereign Postgres-as-a-service via
|
||||
# postgresql.cnpg.io/v1.Cluster CRs. Required by every PG-backed bootstrap
|
||||
# component: bp-powerdns (pdns-pg-app), bp-keycloak HA, bp-gitea metadata,
|
||||
# bp-langfuse, bp-grafana config DB, bp-temporal, bp-matrix synapse,
|
||||
# bp-llm-gateway, bp-bge, bp-nemo-guardrails, bp-openmeter (cnpg profile),
|
||||
# pool-domain-manager (PDM).
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) — cnpg gates the entire downstream observability/AI/relay
|
||||
# stack; placing it in the bootstrap-kit (instead of as an Application
|
||||
# Blueprint) is what unblocks the omantel-1 day-1 control plane.
|
||||
#
|
||||
# Resolves issue #254 (bp-powerdns pod stuck in CreateContainerConfigError
|
||||
# because pdns-pg-app Secret is generated by a CNPG Cluster CR; without
|
||||
# the operator the secret never materializes).
|
||||
#
|
||||
# Wrapper chart: platform/cnpg/chart/
|
||||
# Catalyst-curated values: platform/cnpg/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cnpg-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: cnpg
|
||||
targetNamespace: cnpg-system
|
||||
# CNPG only needs Flux Ready (its own CRDs ship in the same chart;
|
||||
# consumers of postgresql.cnpg.io/v1.Cluster gate themselves on bp-cnpg).
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cnpg
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cnpg
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,62 +0,0 @@
|
||||
# bp-valkey — Catalyst bootstrap-kit Blueprint, W2.K1 slot 17.
|
||||
# Redis-compatible cache (Valkey is the BSD-licensed Redis fork). Used by
|
||||
# Catalyst control-plane services for ephemeral session/state, and by
|
||||
# downstream Apps that need a Redis wire-protocol cache.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) — Valkey runs alongside CNPG so Apps can pick the right
|
||||
# storage shape per workload (relational vs cache).
|
||||
#
|
||||
# Wrapper chart: platform/valkey/chart/
|
||||
# Catalyst-curated values: platform/valkey/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: valkey
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: valkey
|
||||
targetNamespace: valkey
|
||||
# Valkey is a self-contained cache — only needs Flux Ready.
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-valkey
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-valkey
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-seaweedfs — Catalyst bootstrap-kit Blueprint, W2.K1 slot 18.
|
||||
# S3-compatible object storage encapsulation. Pre-requisite for every
|
||||
# blob-storage consumer in the bootstrap-kit:
|
||||
# - bp-velero (slot 34) — backups
|
||||
# - bp-loki (slot 22) — log chunks
|
||||
# - bp-mimir (slot 23) — metric blocks
|
||||
# - bp-tempo (slot 24) — trace blocks
|
||||
# - bp-harbor (slot 19) — registry blob storage
|
||||
# and downstream Apps that need cheap S3-compatible blob storage.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §2.3 (Tier 5 storage+DB
|
||||
# foundation) and PROVISIONING-PLAN.md §3 — every Sovereign owns its own
|
||||
# SeaweedFS so blob data never leaves the Sovereign's cluster.
|
||||
#
|
||||
# Wrapper chart: platform/seaweedfs/chart/
|
||||
# Catalyst-curated values: platform/seaweedfs/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: seaweedfs
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: seaweedfs
|
||||
targetNamespace: seaweedfs
|
||||
# SeaweedFS depends on:
|
||||
# - bp-flux(03): standard GitOps prerequisite.
|
||||
# - bp-cert-manager(02): the S3 Filer endpoint terminates TLS via a
|
||||
# Certificate the chart requests from the cluster ClusterIssuer.
|
||||
dependsOn:
|
||||
- name: bp-flux
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-seaweedfs
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-seaweedfs
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,69 +0,0 @@
|
||||
# bp-harbor — Catalyst bootstrap-kit Blueprint, W2.K1 slot 19.
|
||||
# Per-Sovereign OCI registry. Mirrors blueprint chart artifacts and
|
||||
# container images so the Sovereign isn't dependent on ghcr.io for
|
||||
# day-2 image pulls; also hosts Org-private images per Application.
|
||||
#
|
||||
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §6.7 — Harbor sits in the
|
||||
# storage cohort (W2.K1) rather than apps cohort because it is a
|
||||
# consumer of CNPG (registry metadata DB) and SeaweedFS (blob backend),
|
||||
# and its presence gates Cosign signing in bp-sigstore (slot 32) and
|
||||
# image pinning across all later HRs.
|
||||
#
|
||||
# Wrapper chart: platform/harbor/chart/
|
||||
# Catalyst-curated values: platform/harbor/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: harbor
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: harbor
|
||||
targetNamespace: harbor
|
||||
# Harbor depends on:
|
||||
# - bp-cnpg(16): registry metadata DB (postgresql.cnpg.io/v1.Cluster).
|
||||
# - bp-seaweedfs(18): registry blob backend (S3-compatible).
|
||||
# - bp-cert-manager(02): registry endpoint TLS via ClusterIssuer.
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-seaweedfs
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-harbor
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-harbor
|
||||
namespace: flux-system
|
||||
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,74 +0,0 @@
|
||||
# bp-opentelemetry — Catalyst Blueprint #20 (W2.K2 Observability batch).
|
||||
# OpenTelemetry Collector — pipeline source for the LGTM stack
|
||||
# (Loki / Mimir / Tempo). Receives OTLP from workloads and fans out
|
||||
# logs → Loki, metrics → Mimir, traces → Tempo.
|
||||
#
|
||||
# Wrapper chart: platform/opentelemetry/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cert-manager is Ready (the Collector's webhook /
|
||||
# OTLP-HTTPS receiver request TLS certs from the cluster
|
||||
# ClusterIssuer).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager (slot 02) — TLS for OTLP-HTTPS receiver and any
|
||||
# Collector webhooks.
|
||||
#
|
||||
# Hard-but-implicit dependencies (CRDs, NOT sibling Blueprints):
|
||||
# - opentelemetry.io/v1beta1.OpenTelemetryCollector — provided by the
|
||||
# OpenTelemetry Operator subchart bundled in this Blueprint.
|
||||
#
|
||||
# disableWait: the OTel Collector chart deploys multiple components
|
||||
# (operator, collector DaemonSet/Deployment, instrumentation CR). Helm
|
||||
# `--wait` would block on every Pod becoming Ready, which can't happen
|
||||
# until downstream backends (Loki/Mimir/Tempo, slots 22–24) are up to
|
||||
# accept exports. The HelmRelease itself reports Ready as soon as
|
||||
# manifests apply cleanly; runtime convergence is observed via kubectl.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: opentelemetry
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: opentelemetry
|
||||
targetNamespace: opentelemetry
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-opentelemetry
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-opentelemetry
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-alloy — Catalyst Blueprint #21 (W2.K2 Observability batch).
|
||||
# Grafana Alloy — the unified telemetry collector for the LGTM stack.
|
||||
# Runs as a DaemonSet on every node; tails container logs, scrapes
|
||||
# Prometheus metrics, and forwards traces. Co-resident with bp-opentelemetry
|
||||
# (slot 20) — Alloy handles host-level collection (kubelet, journald,
|
||||
# node_exporter) while OTel handles app-level OTLP.
|
||||
#
|
||||
# Wrapper chart: platform/alloy/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-opentelemetry is Ready (Alloy's default config
|
||||
# forwards OTLP to the Collector's gRPC endpoint).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-opentelemetry (slot 20) — Alloy forwards OTLP to the Collector.
|
||||
# Without the Collector Service in place, Alloy retries forever on a
|
||||
# non-existent upstream.
|
||||
#
|
||||
# disableWait: Alloy is a DaemonSet — Helm `--wait` would block on
|
||||
# every node's Alloy Pod becoming Ready. On larger Sovereigns this can
|
||||
# legitimately take >5min during a cold-start image pull; the HelmRelease
|
||||
# reports Ready when manifests apply, runtime convergence observed via
|
||||
# kubectl.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: alloy
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: alloy
|
||||
targetNamespace: alloy
|
||||
dependsOn:
|
||||
- name: bp-opentelemetry
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-alloy
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-alloy
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-loki — Catalyst Blueprint #22 (W2.K2 Observability batch).
|
||||
# Grafana Loki — log storage tier of the LGTM stack. Default deployment
|
||||
# shape is SingleBinary (one Loki StatefulSet) — minimum operational
|
||||
# cost for a Solo Sovereign; per-Sovereign overlays scale to
|
||||
# distributor/ingester/querier StatefulSets when load warrants.
|
||||
#
|
||||
# Wrapper chart: platform/loki/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Loki chunks/index live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Loki uses SeaweedFS S3 for chunks and
|
||||
# index storage. Without SeaweedFS Ready, Loki cannot persist logs.
|
||||
#
|
||||
# disableWait: Loki SingleBinary becomes Ready only after creating the
|
||||
# S3 bucket and writing the first WAL block — both of which require
|
||||
# bp-seaweedfs to be fully reconciled (not just HelmRelease=Ready).
|
||||
# Helm `--wait` would block waiting for the StatefulSet rollout, which
|
||||
# the HelmRelease cannot influence.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: loki
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: loki
|
||||
targetNamespace: loki
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-loki
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-loki
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-mimir — Catalyst Blueprint #23 (W2.K2 Observability batch).
|
||||
# Grafana Mimir — metrics storage tier of the LGTM stack. SeaweedFS-backed
|
||||
# blocks-storage; Prometheus-compatible remote-write endpoint.
|
||||
#
|
||||
# Wrapper chart: platform/mimir/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Mimir blocks live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Mimir blocks-storage uses SeaweedFS S3.
|
||||
# Without SeaweedFS Ready, Mimir compactor/ingester StatefulSets
|
||||
# cannot persist metric blocks.
|
||||
#
|
||||
# disableWait: Mimir is a multi-component distributed system (distributor,
|
||||
# ingester, querier, store-gateway, compactor, alertmanager, ruler).
|
||||
# Helm `--wait` would block on every StatefulSet rollout, which can
|
||||
# legitimately take >5min during a cold-start. The HelmRelease reports
|
||||
# Ready when manifests apply; runtime convergence is observed via
|
||||
# kubectl rollout status.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mimir
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: mimir
|
||||
targetNamespace: mimir
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-mimir
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-mimir
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,66 +0,0 @@
|
||||
# bp-tempo — Catalyst Blueprint #24 (W2.K2 Observability batch).
|
||||
# Grafana Tempo — distributed tracing storage tier of the LGTM stack.
|
||||
# Default deployment shape is single-binary (one Tempo StatefulSet) —
|
||||
# minimum operational cost for a Solo Sovereign.
|
||||
#
|
||||
# Wrapper chart: platform/tempo/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-seaweedfs is Ready (Tempo trace blocks live on S3).
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs (slot 18) — Tempo blocks live on SeaweedFS S3.
|
||||
# Without SeaweedFS Ready, Tempo cannot persist spans.
|
||||
#
|
||||
# disableWait: Tempo single-binary StatefulSet becomes Ready after
|
||||
# creating the S3 bucket and initialising the WAL — both require
|
||||
# bp-seaweedfs to be fully reconciled. Helm `--wait` would block on
|
||||
# the rollout, which the HelmRelease cannot influence.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: tempo
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: tempo
|
||||
targetNamespace: tempo
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-tempo
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-tempo
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,75 +0,0 @@
|
||||
# bp-grafana — Catalyst Blueprint #25 (W2.K2 Observability batch).
|
||||
# Grafana — visualization layer of the LGTM stack. Pairs with bp-loki
|
||||
# (logs), bp-mimir (metrics), bp-tempo (traces); CNPG-backed Postgres
|
||||
# for dashboard/folder/alert state; Keycloak OIDC for SSO.
|
||||
#
|
||||
# Wrapper chart: platform/grafana/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cnpg, bp-loki, bp-mimir, bp-tempo, bp-keycloak are
|
||||
# all Ready.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cnpg (slot 16) — Postgres backend for Grafana state.
|
||||
# - bp-loki (slot 22) — datasource for logs.
|
||||
# - bp-mimir (slot 23) — datasource for metrics.
|
||||
# - bp-tempo (slot 24) — datasource for traces.
|
||||
# - bp-keycloak (slot 09) — OIDC IdP for SSO.
|
||||
#
|
||||
# disableWait: Grafana waits for its CNPG-managed `grafana-app` Secret
|
||||
# (synthesised by bp-cnpg via the chart's Cluster CR), and for upstream
|
||||
# datasource endpoints to answer. Helm `--wait` would block on the
|
||||
# Deployment rollout, which the HelmRelease cannot influence; runtime
|
||||
# convergence is observed via kubectl rollout status.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: grafana
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: grafana
|
||||
targetNamespace: grafana
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-loki
|
||||
- name: bp-mimir
|
||||
- name: bp-tempo
|
||||
- name: bp-keycloak
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-grafana
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-grafana
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,84 +0,0 @@
|
||||
# bp-langfuse — Catalyst Blueprint #26 (W2.K2 Observability batch).
|
||||
# Langfuse — LLM observability platform (traces, evaluations, prompt
|
||||
# management, cost attribution). Hooks into the Catalyst LLM gateway
|
||||
# (slot 40) once W2.K4 lands. CNPG-backed Postgres; Keycloak OIDC SSO.
|
||||
#
|
||||
# Wrapper chart: platform/langfuse/chart/
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane, AFTER
|
||||
# bp-cnpg, bp-keycloak, bp-cert-manager are all Ready.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cnpg (slot 16) — Postgres backend for Langfuse traces /
|
||||
# prompts / evaluations.
|
||||
# - bp-keycloak (slot 09) — OIDC IdP for SSO.
|
||||
# - bp-cert-manager (slot 02) — TLS for the Langfuse Ingress.
|
||||
#
|
||||
# disableWait: Langfuse waits for its CNPG-managed `langfuse-app` Secret
|
||||
# and for upstream Bitnami subcharts to be filtered out at template time
|
||||
# (the chart sets `postgresql.deploy=false`, `redis.deploy=false`,
|
||||
# `clickhouse.deploy=false`, `s3.deploy=false` to route to bp-cnpg /
|
||||
# bp-valkey / bp-clickhouse / bp-seaweedfs respectively). Helm `--wait`
|
||||
# would block on the Deployment rollout, which the HelmRelease cannot
|
||||
# influence.
|
||||
#
|
||||
# Forward-prep notice — issue #215 (bp-langfuse:1.0.0 GHCR publish 500):
|
||||
# At the time this HR file was authored, bp-langfuse:1.0.0 had not
|
||||
# published to oci://ghcr.io/openova-io due to a Helm v3.16 + GHCR
|
||||
# manifest interaction with langfuse's nested OCI subchart deps. W1.G
|
||||
# is the concurrent track fixing the publish path. Until that lands,
|
||||
# this HelmRelease will fail to install with a chart-pull error; this
|
||||
# is expected and tracked in #215. The HR file is committed now so
|
||||
# the moment the artifact is published, Flux reconciles the SeaweedFS-
|
||||
# /CNPG-/Keycloak-Ready Sovereign to bring Langfuse online without a
|
||||
# second deploy gate.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: langfuse
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
timeout: 15m
|
||||
releaseName: langfuse
|
||||
targetNamespace: langfuse
|
||||
dependsOn:
|
||||
- name: bp-cnpg
|
||||
- name: bp-keycloak
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-langfuse
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-langfuse
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,73 +0,0 @@
|
||||
# bp-kyverno — Catalyst bootstrap-kit Blueprint #27 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Kubernetes-native admission policy engine. Validating/mutating/generating
|
||||
# admission control via ClusterPolicy/Policy CRDs. HA mode with separate
|
||||
# admission/background/cleanup/reports controllers. The first guardrail
|
||||
# downstream Catalyst Apps land behind once the platform is bootstrapped.
|
||||
#
|
||||
# Wrapper chart: platform/kyverno/chart/ (umbrella over upstream
|
||||
# kyverno/kyverno chart, Catalyst-curated values under the `kyverno:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Kyverno admission webhooks need a working CNI + Service
|
||||
# mesh substrate to receive AdmissionReview requests from the apiserver.
|
||||
# Cilium is the root of the Catalyst-Zero DAG; until it is Ready the
|
||||
# apiserver→webhook path is not reachable and Kyverno install is racy.
|
||||
#
|
||||
# No further dependsOn: Kyverno installs its own CRDs and does not require
|
||||
# cert-manager (it auto-generates admission webhook TLS via its built-in
|
||||
# certificate controller).
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kyverno
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: kyverno
|
||||
targetNamespace: kyverno
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-kyverno
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-kyverno
|
||||
namespace: flux-system
|
||||
# Event-driven install: Kyverno HA mode brings up four controller
|
||||
# Deployments (admission, background, cleanup, reports) plus the
|
||||
# admission webhook TLS bootstrap. Pod Ready is multi-minute on a
|
||||
# cold cluster; Helm `--wait` would hold the HR's Ready=True signal
|
||||
# past the point where downstream HRs could legitimately reconcile.
|
||||
# disableWait lets Flux mark this Ready as soon as manifests apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,67 +0,0 @@
|
||||
# bp-reloader — Catalyst bootstrap-kit Blueprint #28 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Stakater Reloader watches ConfigMap/Secret changes and triggers rolling
|
||||
# restarts of dependent Deployments/StatefulSets/DaemonSets that opt in
|
||||
# via annotations. The secret/configmap-rotation glue across Catalyst —
|
||||
# bp-* workloads pick up rotated TLS material and rotated bootstrap
|
||||
# credentials without manual rollouts.
|
||||
#
|
||||
# Wrapper chart: platform/reloader/chart/ (umbrella over upstream
|
||||
# stakater/reloader chart, Catalyst-curated values under the `reloader:`
|
||||
# key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn: (none) — Reloader is independent infrastructure. It only
|
||||
# watches Kubernetes API resources and triggers rollouts; it does not
|
||||
# require any sibling Blueprint. Listed at slot 28 for numeric grouping
|
||||
# with the security/policy cohort but Flux will install it as soon as
|
||||
# the cluster is reachable.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: reloader
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: reloader
|
||||
targetNamespace: reloader
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-reloader
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-reloader
|
||||
namespace: flux-system
|
||||
# Event-driven install (Catalyst convention) — Reloader's single
|
||||
# Deployment Ready path is fast in practice but disableWait keeps the
|
||||
# HR Ready signal aligned with manifest apply rather than runtime
|
||||
# convergence, matching the rest of the bootstrap-kit.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,66 +0,0 @@
|
||||
# bp-vpa — Catalyst bootstrap-kit Blueprint #29 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Vertical Pod Autoscaler. Per-host-cluster automated resource right-sizing
|
||||
# (Recommender + Updater + Admission Controller). Pairs with HPA/KEDA on
|
||||
# the horizontal axis. Provides recommendations even if not auto-applying;
|
||||
# Catalyst-default mode is `Off` (recommend only) until SRE opts a
|
||||
# workload into `Auto` via VerticalPodAutoscaler resources.
|
||||
#
|
||||
# Wrapper chart: platform/vpa/chart/ (umbrella over upstream
|
||||
# autoscaler/vertical-pod-autoscaler chart, Catalyst-curated values under
|
||||
# the `vertical-pod-autoscaler:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn: (none) — VPA is independent infrastructure. The Recommender
|
||||
# reads from metrics-server (a k3s fixture) and Prometheus/Mimir when
|
||||
# present, but neither is a hard sibling-Blueprint dep at install time;
|
||||
# the controllers tolerate metrics endpoints appearing late. Listed at
|
||||
# slot 29 for numeric grouping with the security/policy cohort.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: vpa
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: vpa
|
||||
targetNamespace: vpa
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-vpa
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-vpa
|
||||
namespace: flux-system
|
||||
# Event-driven install: VPA brings up three Deployments (recommender,
|
||||
# updater, admission-controller) plus admission webhook TLS bootstrap.
|
||||
# disableWait keeps Flux's Ready signal aligned with manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-trivy — Catalyst bootstrap-kit Blueprint #30 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Trivy Operator. Static-scanning half of the Catalyst security stack:
|
||||
# vulnerability + misconfiguration scanning of running workloads, images,
|
||||
# RBAC, and rendered manifests. Pairs with bp-falco (runtime, slot 31)
|
||||
# and bp-kyverno (admission, slot 27).
|
||||
#
|
||||
# Wrapper chart: platform/trivy/chart/ (umbrella over upstream
|
||||
# aquasecurity/trivy-operator chart, Catalyst-curated values under the
|
||||
# `trivy-operator:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — Trivy Operator's admission webhook (and its
|
||||
# ConfigAuditReport mutating-webhook in HA mode) requires a TLS cert
|
||||
# from the cluster's letsencrypt-prod / internal CA ClusterIssuer
|
||||
# before the apiserver will route AdmissionReview traffic. Without
|
||||
# bp-cert-manager Ready, the Certificate resource sits Pending and
|
||||
# the webhook serves stale or no certs.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: trivy-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: trivy
|
||||
targetNamespace: trivy-system
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-trivy
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-trivy
|
||||
namespace: flux-system
|
||||
# Event-driven install: Trivy Operator pulls a multi-hundred-MB
|
||||
# vulnerability database on first run; pod Ready is dominated by
|
||||
# initial DB hydration, not manifest apply. disableWait lets Flux
|
||||
# mark this Ready as soon as manifests apply; runtime convergence
|
||||
# (DB hydration, first scan reports landing) is observed via kubectl.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,69 +0,0 @@
|
||||
# bp-falco — Catalyst bootstrap-kit Blueprint #31 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Runtime threat detection (CNCF Graduated). eBPF kernel-level syscall
|
||||
# monitoring for container escapes, privilege escalation, anomalous
|
||||
# behavior. Runs as a DaemonSet on every host of the Sovereign;
|
||||
# Falcosidekick fans events into the SIEM pipeline (Loki/JetStream).
|
||||
#
|
||||
# Wrapper chart: platform/falco/chart/ (umbrella over upstream
|
||||
# falcosecurity/falco chart, Catalyst-curated values under the `falco:`
|
||||
# key — modern_ebpf driver, falcosidekick enabled).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Falco's modern_ebpf probe loads alongside Cilium's
|
||||
# eBPF programs on the same kernel hook points. Bringing Falco up
|
||||
# before the CNI is finalised has produced flaky probe-load races
|
||||
# in field testing; sequencing after bp-cilium Ready avoids that.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: falco
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: falco
|
||||
targetNamespace: falco
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-falco
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-falco
|
||||
namespace: flux-system
|
||||
# Event-driven install: Falco's DaemonSet rolls out per-node and the
|
||||
# eBPF probe load is sensitive to kernel headers / module presence.
|
||||
# Per-node Ready is properly observed via DaemonSet status, not via
|
||||
# Helm `--wait`. disableWait keeps Flux's signal aligned with
|
||||
# manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,71 +0,0 @@
|
||||
# bp-sigstore — Catalyst bootstrap-kit Blueprint #32 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Sigstore Policy Controller. Admission gate for signed-image enforcement —
|
||||
# verifies Cosign signatures + attestations on container images before
|
||||
# admission. Pairs with bp-harbor (registry, slot 19) and the CI-side
|
||||
# Cosign signing path to close the supply-chain trust loop on the
|
||||
# Sovereign.
|
||||
#
|
||||
# Wrapper chart: platform/sigstore/chart/ (umbrella over upstream
|
||||
# sigstore/policy-controller chart, Catalyst-curated values under the
|
||||
# `policy-controller:` key).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — Policy Controller is an admission webhook; the
|
||||
# apiserver requires a valid TLS cert on the webhook Service before
|
||||
# it will route AdmissionReview traffic. Without bp-cert-manager
|
||||
# Ready, the Certificate sits Pending and admission fails open or
|
||||
# fails closed (depending on FailurePolicy), neither of which is
|
||||
# the intended security posture.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: sigstore-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: sigstore
|
||||
targetNamespace: sigstore-system
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-sigstore
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-sigstore
|
||||
namespace: flux-system
|
||||
# Event-driven install: Policy Controller bootstraps its admission
|
||||
# webhook TLS via cert-manager and reaches Ready only after the
|
||||
# Certificate is issued + bound. disableWait avoids holding the HR
|
||||
# signal on a runtime-convergence event.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,68 +0,0 @@
|
||||
# bp-syft-grype — Catalyst bootstrap-kit Blueprint #33 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Anchore Syft + Grype as a scheduled CronJob. SBOM generation (Syft)
|
||||
# paired with vulnerability matching (Grype) — the offline / scheduled
|
||||
# half of the supply-chain stack. Anchore does not publish a Helm chart
|
||||
# for the open-source CLIs, so this Blueprint is a scratch chart that
|
||||
# wires the official ghcr.io/anchore/syft and ghcr.io/anchore/grype
|
||||
# containers into a CronJob that scans the Sovereign's image inventory.
|
||||
#
|
||||
# Wrapper chart: platform/syft-grype/chart/ (Catalyst-authored scratch
|
||||
# chart — no upstream subchart).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cert-manager — the result-export sidecar publishes SBOMs over
|
||||
# mTLS to the central scan-result store; cert-manager issues the
|
||||
# workload's TLS material via the cluster's ClusterIssuer.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: syft-grype
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: syft-grype
|
||||
targetNamespace: syft-grype
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-syft-grype
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-syft-grype
|
||||
namespace: flux-system
|
||||
# Event-driven install: the Blueprint is mostly a CronJob + RBAC
|
||||
# surface. There is no long-running Deployment whose Ready=True is
|
||||
# meaningful — disableWait is the correct shape so Flux marks Ready
|
||||
# as soon as manifests apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,72 +0,0 @@
|
||||
# bp-velero — Catalyst bootstrap-kit Blueprint #34 (W2.K3, Tier 7 — Security/Policy).
|
||||
# Per-host-cluster backup engine. Catalyst-Zero pins backups to SeaweedFS
|
||||
# (the unified S3 layer, slot 18) so backup data never leaves the
|
||||
# Sovereign at install time; per-Sovereign archival to a cloud backend
|
||||
# is wired in post-bootstrap via Crossplane.
|
||||
#
|
||||
# Wrapper chart: platform/velero/chart/ (umbrella over upstream
|
||||
# vmware-tanzu/velero chart, Catalyst-curated values under the `velero:`
|
||||
# key — `seaweedfs` BackupStorageLocation provider, no cloud plugin
|
||||
# pinned at install time).
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-seaweedfs — Velero's BackupStorageLocation points at the
|
||||
# in-cluster SeaweedFS S3 endpoint (`seaweedfs.seaweedfs.svc:8333`)
|
||||
# and reads the `seaweedfs-s3-credentials` Secret SeaweedFS renders
|
||||
# during install. Without bp-seaweedfs Ready, the BSL Phase sits
|
||||
# `Unavailable` and Velero's first reconcile fails — every backup
|
||||
# CR queues with the same error until the dep lands.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: velero
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: omantel.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: velero
|
||||
targetNamespace: velero
|
||||
dependsOn:
|
||||
- name: bp-seaweedfs
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-velero
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-velero
|
||||
namespace: flux-system
|
||||
# Event-driven install: Velero's Deployment Ready depends on the
|
||||
# node-agent DaemonSet rolling out and the BackupStorageLocation
|
||||
# reaching `Available` — both runtime-convergence events that Flux
|
||||
# observes via the BSL CR phase, not via Helm `--wait`. disableWait
|
||||
# keeps the HR's Ready signal aligned with manifest apply.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -1,70 +0,0 @@
|
||||
# bp-coraza — Catalyst bootstrap-kit Blueprint #35 (W2.K4 — Tier 8: edge).
|
||||
# OWASP-licensed Web Application Firewall, ModSecurity-rule-compatible.
|
||||
# Speaks the HAProxy SPOE protocol; sits in front of Cilium Gateway / HAProxy
|
||||
# fronts to enforce WAF policies on inbound traffic to Sovereign-facing
|
||||
# services (keycloak, grafana, stalwart, marketplace).
|
||||
#
|
||||
# Wrapper chart: platform/coraza/chart/
|
||||
# Catalyst-curated values: platform/coraza/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# dependsOn:
|
||||
# - bp-cilium — Coraza enforces L7 policy via Cilium L7 proxy / Gateway
|
||||
# API; Cilium must be Ready (CNI + Gateway controller) before WAF
|
||||
# evaluation hooks become reachable.
|
||||
# - bp-cert-manager — Issuers must be reconciled so any TLS-fronted SPOA
|
||||
# listeners (per-Sovereign overlays) come up with valid certs.
|
||||
#
|
||||
# install/upgrade.disableWait: true — Coraza-spoa Deployment Ready signal
|
||||
# is event-driven via the Flux dependsOn graph (downstream HRs check
|
||||
# Ready=True on this HR). Per session-2026-04-30 architectural decision,
|
||||
# we never use blanket `spec.timeout: Nm` watchdogs.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: coraza
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: coraza
|
||||
targetNamespace: coraza
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-coraza
|
||||
version: 1.0.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-coraza
|
||||
namespace: flux-system
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
@ -15,28 +15,4 @@ resources:
|
||||
- 08-openbao.yaml
|
||||
- 09-keycloak.yaml
|
||||
- 10-gitea.yaml
|
||||
- 11-powerdns.yaml
|
||||
- 12-external-dns.yaml
|
||||
- 13-bp-catalyst-platform.yaml
|
||||
- 14-crossplane-claims.yaml
|
||||
- 15-external-secrets.yaml
|
||||
- 16-cnpg.yaml
|
||||
- 17-valkey.yaml
|
||||
- 18-seaweedfs.yaml
|
||||
- 19-harbor.yaml
|
||||
- 20-opentelemetry.yaml
|
||||
- 21-alloy.yaml
|
||||
- 22-loki.yaml
|
||||
- 23-mimir.yaml
|
||||
- 24-tempo.yaml
|
||||
- 25-grafana.yaml
|
||||
- 26-langfuse.yaml
|
||||
- 27-kyverno.yaml
|
||||
- 28-reloader.yaml
|
||||
- 29-vpa.yaml
|
||||
- 30-trivy.yaml
|
||||
- 31-falco.yaml
|
||||
- 32-sigstore.yaml
|
||||
- 33-syft-grype.yaml
|
||||
- 34-velero.yaml
|
||||
- 35-coraza.yaml
|
||||
- 11-bp-catalyst-platform.yaml
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
# bp-cilium — Catalyst bootstrap-kit Blueprint. CNI must come first; k3s started with --flannel-backend=none precisely so Cilium can take over.
|
||||
#
|
||||
# Wrapper chart: platform/cilium/chart/
|
||||
# Catalyst-curated values: platform/cilium/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
# kube-system is built into every Kubernetes cluster — never re-declare it.
|
||||
# Earlier revisions of 01-cilium.yaml AND 05-sealed-secrets.yaml both
|
||||
# declared it, which collided when kustomize tried to merge the two:
|
||||
# "may not add resource with an already registered id:
|
||||
# Namespace.v1.[noGrp]/kube-system.[noNs]"
|
||||
# This Blueprint installs Cilium INTO kube-system; the HelmRelease's
|
||||
# targetNamespace field below is sufficient.
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-cilium
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-cilium
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: cilium
|
||||
targetNamespace: kube-system
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cilium
|
||||
version: 1.1.1
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cilium
|
||||
namespace: flux-system
|
||||
# Event-driven install: Helm completes when manifests apply, not when
|
||||
# cilium-agent reaches Ready (agent waits for envoyconfig CRDs that the
|
||||
# SAME chart installs — legitimate slow-Ready). Replaces blanket
|
||||
# spec.timeout: 15m band-aid from PR #221.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cilium:
|
||||
# Enable L7 proxy so Cilium's chart installs the
|
||||
# ciliumenvoyconfigs / ciliumclusterwideenvoyconfigs CRDs that the
|
||||
# cilium-agent waits for at startup. Without this, agent crash-loops
|
||||
# forever and the node.cilium.io/agent-not-ready taint never lifts.
|
||||
l7Proxy: true
|
||||
prometheus:
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
hubble:
|
||||
metrics:
|
||||
enabled: null
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
relay:
|
||||
enabled: false
|
||||
ui:
|
||||
enabled: false
|
||||
@ -1,64 +0,0 @@
|
||||
# bp-cert-manager — Catalyst bootstrap-kit Blueprint. TLS for everything below — Lets Encrypt issuer with Dynadot DNS-01 (omani.works pool) or HTTP-01 (BYO domains).
|
||||
#
|
||||
# Wrapper chart: platform/cert-manager/chart/
|
||||
# Catalyst-curated values: platform/cert-manager/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cert-manager
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: otech.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-cert-manager
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-cert-manager
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: cert-manager
|
||||
targetNamespace: cert-manager
|
||||
dependsOn:
|
||||
- name: bp-cilium
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-cert-manager
|
||||
version: 1.1.1
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-cert-manager
|
||||
namespace: flux-system
|
||||
# Event-driven install: cert-manager installs CRDs + 3 deployments
|
||||
# (controller, webhook, cainjector). Webhook readiness depends on the
|
||||
# cainjector mutating the Secret — multi-minute path on cold start.
|
||||
# Helm install completes when manifests apply; subsequent dependsOn
|
||||
# checks Ready=True independently. Replaces PR #221 spec.timeout: 15m.
|
||||
install:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
cert-manager:
|
||||
prometheus:
|
||||
enabled: false
|
||||
servicemonitor:
|
||||
enabled: false
|
||||
@ -1,88 +0,0 @@
|
||||
# bp-flux — Catalyst bootstrap-kit Blueprint. Host-level Flux. Per-vcluster Flux is bootstrapped later by environment-controller.
|
||||
#
|
||||
# Wrapper chart: platform/flux/chart/
|
||||
# Catalyst-curated values: platform/flux/chart/values.yaml
|
||||
# Reconciled by: Flux on the new Sovereign's k3s control plane.
|
||||
#
|
||||
# DOUBLE-INSTALL SAFETY (omantel.omani.works incident, 2026-04-29)
|
||||
# ----------------------------------------------------------------
|
||||
# Cloud-init pre-installs Flux core via
|
||||
# curl https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml
|
||||
# so that this very HelmRelease can be reconciled. helm-controller then
|
||||
# runs `helm install` for bp-flux on top of the already-running Flux. If
|
||||
# the chart's subchart `flux2` version disagrees with the cloud-init
|
||||
# install (different upstream Flux release), CRD `storedVersions`
|
||||
# mismatches → Helm install fails → rollback → rollback DELETES the
|
||||
# running Flux controllers → cluster has no GitOps engine and is
|
||||
# unrecoverable in-place.
|
||||
#
|
||||
# Mitigations applied here:
|
||||
# 1. bp-flux:1.1.2 pins the `flux2` subchart at 2.14.1 (= appVersion
|
||||
# 2.4.0) which matches cloud-init's v2.4.0 install.yaml.
|
||||
# 2. spec.upgrade.preserveValues: true — never silently overwrite
|
||||
# operator overlays on upgrade.
|
||||
# controller adopts the cloud-init-installed objects rather than
|
||||
# re-creating, so install is non-destructive when objects already
|
||||
# exist with matching apiVersion/kind/name.
|
||||
# See docs/RUNBOOK-PROVISIONING.md §"bp-flux double-install".
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: flux-system
|
||||
labels:
|
||||
catalyst.openova.io/sovereign: otech.omani.works
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bp-flux
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: oci
|
||||
interval: 15m
|
||||
url: oci://ghcr.io/openova-io
|
||||
secretRef:
|
||||
name: ghcr-pull
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: bp-flux
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 15m
|
||||
releaseName: flux
|
||||
targetNamespace: flux-system
|
||||
dependsOn:
|
||||
- name: bp-cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: bp-flux
|
||||
version: 1.1.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bp-flux
|
||||
namespace: flux-system
|
||||
# Event-driven install: bp-flux adopts the cloud-init-installed Flux
|
||||
# controllers; the helm-controller pod that reconciles THIS HR is itself
|
||||
# a target of the chart, so blocking on Ready=True is structurally
|
||||
# impossible. disableWait avoids the deadlock. Replaces PR #221 timeout.
|
||||
install:
|
||||
disableWait: true
|
||||
# Adopt cloud-init-installed Flux objects rather than fail on
|
||||
# ownership conflict (the objects exist before the HelmRelease ever
|
||||
# reconciles). Without this, the very first reconcile would error
|
||||
# with "object already exists" on every Flux controller Deployment.
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
disableWait: true
|
||||
# Keep operator-supplied values (e.g. resource overrides applied via
|
||||
# helm-controller out-of-band, or dry-run patches during incident
|
||||
# response) on chart upgrades. Without this, every upgrade would
|
||||
# reset the chart to default values, masking operator state.
|
||||
preserveValues: true
|
||||
# Match install behaviour — adopt rather than fail on conflict.
|
||||
remediation:
|
||||
retries: 3
|
||||