Files
git.stella-ops.org/docs/ops/concelier-mirror-operations.md
master 5fd4032c7c
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add channel test providers for Email, Slack, Teams, and Webhook
- Implemented EmailChannelTestProvider to generate email preview payloads.
- Implemented SlackChannelTestProvider to create Slack message previews.
- Implemented TeamsChannelTestProvider for generating Teams Adaptive Card previews.
- Implemented WebhookChannelTestProvider to create webhook payloads.
- Added INotifyChannelTestProvider interface for channel-specific preview generation.
- Created ChannelTestPreviewContracts for request and response models.
- Developed NotifyChannelTestService to handle test send requests and generate previews.
- Added rate limit policies for test sends and delivery history.
- Implemented unit tests for service registration and binding.
- Updated project files to include necessary dependencies and configurations.
2025-10-19 23:29:34 +03:00

8.3 KiB
Raw Blame History

Concelier & Excititor Mirror Operations

This runbook describes how StellaOps operates the managed mirrors under *.stella-ops.org. It covers Docker Compose and Helm deployment overlays, secret handling for multi-tenant authn, CDN fronting, and the recurring sync pipeline that keeps mirror bundles current.

1. Prerequisites

  • Authority access client credentials (client_id + secret) authorised for concelier.mirror.read and excititor.mirror.read scopes. Secrets live outside git.
  • Signed TLS certificates wildcard or per-domain (mirror-primary, mirror-community). Store them under deploy/compose/mirror-gateway/tls/ or in Kubernetes secrets.
  • Mirror gateway credentials Basic Auth htpasswd files per domain. Generate with htpasswd -B. Operators distribute credentials to downstream consumers.
  • Export artifact source read access to the canonical S3 buckets (or rsync share) that hold concelier JSON bundles and excititor VEX exports.
  • Persistent volumes storage for Concelier job metadata and mirror export trees. For Helm, provision PVCs (concelier-mirror-jobs, concelier-mirror-exports, excititor-mirror-exports, mirror-mongo-data, mirror-minio-data) before rollout.

2. Secret & certificate layout

Docker Compose (deploy/compose/docker-compose.mirror.yaml)

  • deploy/compose/env/mirror.env.example copy to .env and adjust quotas or domain IDs.
  • deploy/compose/mirror-secrets/ mount read-only into /run/secrets. Place:
    • concelier-authority-client Authority client secret.
    • excititor-authority-client (optional) reserve for future authn.
  • deploy/compose/mirror-gateway/tls/ PEM-encoded cert/key pairs:
    • mirror-primary.crt, mirror-primary.key
    • mirror-community.crt, mirror-community.key
  • deploy/compose/mirror-gateway/secrets/ htpasswd files:
    • mirror-primary.htpasswd
    • mirror-community.htpasswd

Helm (deploy/helm/stellaops/values-mirror.yaml)

Create secrets in the target namespace:

kubectl create secret generic concelier-mirror-auth \
  --from-file=concelier-authority-client=concelier-authority-client

kubectl create secret generic excititor-mirror-auth \
  --from-file=excititor-authority-client=excititor-authority-client

kubectl create secret tls mirror-gateway-tls \
  --cert=mirror-primary.crt --key=mirror-primary.key

kubectl create secret generic mirror-gateway-htpasswd \
  --from-file=mirror-primary.htpasswd --from-file=mirror-community.htpasswd

Keep Basic Auth lists short-lived (rotate quarterly) and document credential recipients.

3. Deployment

3.1 Docker Compose (edge mirrors, lab validation)

  1. cp deploy/compose/env/mirror.env.example deploy/compose/env/mirror.env
  2. Populate secrets/tls directories as described above.
  3. Sync mirror bundles (see §4) into deploy/compose/mirror-data/… and ensure they are mounted on the host path backing the concelier-exports and excititor-exports volumes.
  4. Run the profile validator: deploy/tools/validate-profiles.sh.
  5. Launch: docker compose --env-file env/mirror.env -f docker-compose.mirror.yaml up -d.

3.2 Helm (production mirrors)

  1. Provision PVCs sized for mirror bundles (baseline: 20GiB per domain).
  2. Create secrets/tls config maps (§2).
  3. helm upgrade --install mirror deploy/helm/stellaops -f deploy/helm/stellaops/values-mirror.yaml.
  4. Annotate the stellaops-mirror-gateway service with ingress/LoadBalancer metadata required by your CDN (e.g., AWS load balancer scheme internal + NLB idle timeout).

4. Artifact sync workflow

Mirrors never generate exports—they ingest signed bundles produced by the Concelier and Excititor export jobs. Recommended sync pattern:

4.1 Compose host (systemd timer)

/usr/local/bin/mirror-sync.sh:

#!/usr/bin/env bash
set -euo pipefail
export AWS_ACCESS_KEY_ID=export AWS_SECRET_ACCESS_KEY=…

aws s3 sync s3://mirror-stellaops/concelier/latest \
  /opt/stellaops/mirror-data/concelier --delete --size-only

aws s3 sync s3://mirror-stellaops/excititor/latest \
  /opt/stellaops/mirror-data/excititor --delete --size-only

Schedule with a systemd timer every 5minutes. The Compose volumes mount /opt/stellaops/mirror-data/* into the containers read-only, matching CONCELIER__MIRROR__EXPORTROOT=/exports/json and EXCITITOR__ARTIFACTS__FILESYSTEM__ROOT=/exports.

4.2 Kubernetes (CronJob)

Create a CronJob running the AWS CLI (or rclone) in the same namespace, writing into the PVCs:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: mirror-sync
spec:
  schedule: "*/5 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: sync
            image: public.ecr.aws/aws-cli/aws-cli@sha256:5df5f52c29f5e3ba46d0ad9e0e3afc98701c4a0f879400b4c5f80d943b5fadea
            command:
              - /bin/sh
              - -c
              - >
                aws s3 sync s3://mirror-stellaops/concelier/latest /exports/concelier --delete --size-only &&
                aws s3 sync s3://mirror-stellaops/excititor/latest /exports/excititor --delete --size-only
            volumeMounts:
              - name: concelier-exports
                mountPath: /exports/concelier
              - name: excititor-exports
                mountPath: /exports/excititor
            envFrom:
              - secretRef:
                  name: mirror-sync-aws
          restartPolicy: OnFailure
          volumes:
            - name: concelier-exports
              persistentVolumeClaim:
                claimName: concelier-mirror-exports
            - name: excititor-exports
              persistentVolumeClaim:
                claimName: excititor-mirror-exports

5. CDN integration

  1. Point the CDN origin at the mirror gateway (Compose host or Kubernetes LoadBalancer).
  2. Honour the response headers emitted by the gateway and Concelier/Excititor: Cache-Control: public, max-age=300, immutable for mirror payloads.
  3. Configure origin shields in the CDN to prevent cache stampedes. Recommended TTLs:
    • Index (/concelier/exports/index.json, /excititor/mirror/*/index) → 60s.
    • Bundle/manifest payloads → 300s.
  4. Forward the Authorization header—Basic Auth terminates at the gateway.
  5. Enforce per-domain rate limits at the CDN (matching gateway budgets) and enable logging to SIEM for anomaly detection.

6. Smoke tests

After each deployment or sync cycle:

# Index with Basic Auth
curl -u $PRIMARY_CREDS https://mirror-primary.stella-ops.org/concelier/exports/index.json | jq 'keys'

# Mirror manifest signature
curl -u $PRIMARY_CREDS -I https://mirror-primary.stella-ops.org/concelier/exports/mirror/primary/manifest.json

# Excititor consensus bundle metadata
curl -u $COMMUNITY_CREDS https://mirror-community.stella-ops.org/excititor/mirror/community/index \
  | jq '.exports[].exportKey'

# Signed bundle + detached JWS (spot check digests)
curl -u $PRIMARY_CREDS https://mirror-primary.stella-ops.org/concelier/exports/mirror/primary/bundle.json.jws \
  -o bundle.json.jws
cosign verify-blob --signature bundle.json.jws --key mirror-key.pub bundle.json

Watch the gateway metrics (nginx_vts or access logs) for cache hits. In Kubernetes, kubectl logs deploy/stellaops-mirror-gateway should show X-Cache-Status: HIT/MISS.

7. Maintenance & rotation

  • Bundle freshness alert if sync job lag exceeds 15minutes or if concelier logs Mirror export root is not configured.
  • Secret rotation change Authority client secrets and Basic Auth credentials quarterly. Update the mounted secrets and restart deployments (docker compose restart concelier or kubectl rollout restart deploy/stellaops-concelier).
  • TLS renewal reissue certificates, place new files, and reload gateway (docker compose exec mirror-gateway nginx -s reload).
  • Quota tuning adjust per-domain MAXDOWNLOADREQUESTSPERHOUR in .env or values file. Align CDN rate limits and inform downstreams.

8. References

  • Deployment profiles: deploy/compose/docker-compose.mirror.yaml, deploy/helm/stellaops/values-mirror.yaml
  • Mirror architecture dossiers: docs/ARCHITECTURE_CONCELIER.md, docs/ARCHITECTURE_EXCITITOR_MIRRORS.md
  • Export bundling: docs/ARCHITECTURE_DEVOPS.md §3, docs/ARCHITECTURE_EXCITITOR.md §7