- Go 67.1%
- Shell 28.9%
- Makefile 3%
- Go Template 1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
setup-go reads go-version-file: go.mod, so the release binary was compiled with Go 1.26.0 stdlib (22 HIGH Trivy findings). Pin go directive to 1.26.6 (patched); verified gobinary scan is clean. |
||
| .forgejo/workflows | ||
| adapters/karmada-headroom | ||
| apis/prediction/v1 | ||
| chart | ||
| cmd | ||
| contracts | ||
| core | ||
| deploy | ||
| docs | ||
| service | ||
| test | ||
| .gitattributes | ||
| .gitignore | ||
| .goreleaser.yaml | ||
| CITATION.cff | ||
| CODE_OF_CONDUCT.md | ||
| CODEOWNERS | ||
| CONTRIBUTING.md | ||
| Dockerfile.goreleaser | ||
| EU-DISCLAIMER.md | ||
| go.mod | ||
| go.sum | ||
| LICENSE-CODE | ||
| LICENSE-DOCS | ||
| Makefile | ||
| NOTICE | ||
| PSA-REMEDIATION.md | ||
| README.md | ||
| renovate.json | ||
| SECURITY.md | ||
| THIRD-PARTY-NOTICES.md | ||
| VERSION | ||
forecasting-engine
A domain-agnostic time-series forecasting capability for the Edge Connect (8ra / IPCEI-CIS) platform, plus thin adapters that map a specific platform signal onto it. The engine knows nothing about clusters, carbon, or Karmada; the adapters do.
Status: Implemented (v0.1.0). The specification for this repo (ADR, invariants, plan) is authored with the Edge Connect architecture methodology and lives canonically in
edge-connect-architectureon branchfeat/forecasting-engineas scope XO-11 (see Planning artifacts). The forecastingcore, the statelessservice, the sharedClusterPredictionStatecontract, and thekarmada-headroomadapter are implemented, tested, packaged as a Helm chart, and wired for CI/CD (Forgejo Actions + Renovate + GoReleaser). See Build & test, Deploy, and Open-source compliance.
Why this exists
The previous prediction-service determined application load by scraping APISIX
gateway traffic and federating it via Thanos, then forecasting per-workload
request rate. Those assumptions do not hold under the target provider-federation
architecture. The v1 signal is instead Karmada's own control-plane
Cluster.status.resourceSummary (allocatable vs. allocated) — live headroom that
already reaches the scheduler, with no new producer and no provider-data-plane
scrape. See ADR-0062 (in edge-connect-architecture) for the full re-scope
rationale.
This repo extracts the reusable part — the forecasting math and its service wrapper — and decouples it from any signal source so it can serve capacity, carbon, and cost forecasting alike.
Decomposition
| Component | Responsibility | Knows about |
|---|---|---|
core/ |
Pure forecasting: EWMA, linear trend, seasonal; pluggable model registry. In → series + horizons; out → forecasts + confidence. No I/O. | Nothing but numbers |
service/ |
Stateless API wrapping core. Forecast any series. |
The core only |
contracts/ |
Language-neutral API contract (OpenAPI, optional proto) + ClusterPredictionState CRD schema. Single source of truth for every boundary. |
Wire shapes only |
apis/prediction/v1/ |
Generated Go CRD types (ClusterPredictionState) shared with the Karmada scheduler. |
K8s API types |
adapters/karmada-headroom/ |
The only cluster-aware piece: watches Karmada Cluster.status.resourceSummary, derives per-resource headroom series, calls service, writes ClusterPredictionState. Fail-open. |
Karmada Cluster + service |
Future signals (carbon, cost, latency) are new adapters/*; core and service
never change.
Repository layout
forecasting-engine/
├── core/ # importable forecasting library (no I/O)
├── service/ # stateless forecasting HTTP API
├── cmd/forecast-service/ # service entrypoint
├── cmd/karmada-headroom-adapter/ # adapter entrypoint
├── contracts/ # openapi/ + crd/ (source of truth)
├── apis/prediction/v1/ # generated Go CRD types (shared w/ scheduler)
├── adapters/karmada-headroom/ # controller: resourceSummary → forecast → CPS
├── chart/ # umbrella Helm chart (CRD + service + adapter)
├── deploy/ # Dockerfiles + argocd/ Application
├── test/ # go-in-docker, integration, karmada-local harness
├── .forgejo/workflows/ # ci · release · release-charts
├── .goreleaser.yaml · Dockerfile.goreleaser · Makefile · VERSION
├── renovate.json
└── <compliance set> # LICENSE-CODE/DOCS, NOTICE, CONTRIBUTING, SECURITY, …
Planning artifacts
This scope is tracked as XO-11 (cross-cutting operational) in the Edge
Connect artifact matrix. The canonical specs live in edge-connect-architecture
on branch feat/forecasting-engine (not duplicated here — duplication is a listed
methodology anti-pattern):
- ADR:
adr/0062-forecasting-engine.md - Invariants (spine):
invariants/XO-11.md - Plan:
plans/16-forecasting-engine.md - Matrix row:
MATRIX.md→ XO-11
Method
Authored with the Edge Connect methodology: Scope → ADR → Invariants → Plan → Controllers/CRDs → Tests → Jira. Invariants are the permanent spine; every plan declares the invariants it preserves; every test names the invariant it asserts.
Documentation map
- docs/README.md - documentation index and navigation
- docs/OPERATIONS.md - deployment and runtime operations
- docs/TESTING.md - unit, integration, and cross-repo end-to-end testing
- contracts/openapi/forecast.yaml - HTTP forecast API contract
- contracts/crd/clusterpredictionstate.yaml -
ClusterPredictionStateCRD contract
Build & test
You can run commands either locally (requires Go) or in pinned containers.
# Unit tests (core + service + adapter) with race + coverage
make test # local Go toolchain
bash test/go-in-docker.sh # containerized alternative
# envtest-backed adapter integration tests (spins a fake API server)
make test-integration # containerized (recommended)
bash test/integration-in-docker.sh
# Build both binaries locally
make build # -> bin/forecast-service, bin/karmada-headroom-adapter
# Build both container images
make docker-build
If you prefer a single local-toolchain check in CI parity order, run:
make fmt && make vet && make test && make build
Two binaries are produced:
| Binary | Image | Role |
|---|---|---|
forecast-service |
forecast-service |
Stateless HTTP forecasting API (POST /v1/forecast, /healthz, /readyz, /metrics). No cluster access. |
karmada-headroom-adapter |
karmada-headroom-adapter |
Watches Karmada Cluster.status.resourceSummary, forecasts headroom, writes ClusterPredictionState. Fail-open. |
Deploy
The umbrella Helm chart in chart/ installs the ClusterPredictionState
CRD (from chart/crds), the forecast-service, and the karmada-headroom-adapter
(with its read-only Karmada RBAC).
# Install onto the Karmada host cluster
helm install forecasting-engine ./chart -n karmada-system --create-namespace
# Toggle components / point at a pinned release
helm upgrade forecasting-engine ./chart -n karmada-system \
--set image.tag=0.1.0 \
--set adapter.enabled=true --set forecastService.enabled=true
The adapter reads Karmada control-plane objects on the karmada-apiserver, so it
needs a kubeconfig. By default the chart mounts a karmada-kubeconfig secret and
sets KUBECONFIG; set adapter.runsInControlPlane=true to use the in-cluster
ServiceAccount instead.
GitOps / ArgoCD: apply deploy/argocd/application.yaml.
The chart is also published as an OCI Helm chart on release
(oci://edp.buildth.ing/devfw-cicd/forecasting-engine).
CI/CD
Forgejo Actions under .forgejo/workflows/:
| Workflow | Trigger | Does |
|---|---|---|
ci.yaml |
push / PR to main |
make test + make vet, helm lint/template, Trivy fs + image scan, GoReleaser snapshot |
release.yaml |
tag v* |
tests, GPG-signed GoReleaser release, publishes both signed images |
release-charts.yaml |
tag v* |
packages + pushes the Helm chart to the OCI registry |
Dependencies are kept current by Renovate (grouped k8s/karmada, weekly schedule, auto-merge for non-major updates).
End-to-end test scenario
The test/karmada-local harness stands up a local kind-based
Karmada with member clusters and drives the adapter against real
Cluster.status.resourceSummary, watching ClusterPredictionState react. The
downstream scheduling value of these forecasts is demonstrated by the
prediction-vs-standard placement showcase in the
karmada-scheduler-edge-connect
repo (test/showcase). See docs/TESTING.md for the full
cross-repo scenario.
Open-source compliance
This repository is prepared for publication under the IPCEI-CIS / Edge Connect open-source governance:
| Aspect | File |
|---|---|
| Code license (Apache-2.0) | LICENSE-CODE |
| Docs license (CC BY 4.0) | LICENSE-DOCS |
| Attribution / EU funding | NOTICE, EU-DISCLAIMER.md |
| Third-party attribution | THIRD-PARTY-NOTICES.md |
| Contribution policy | CONTRIBUTING.md |
| Security policy | SECURITY.md |
| Code of conduct | CODE_OF_CONDUCT.md |
| Citation metadata | CITATION.cff |
| Code owners (team) | CODEOWNERS |
- Source code is licensed under Apache-2.0; documentation under CC BY 4.0.
- Contact:
contact@edge-connect.eu; security:security@edge-connect.eu. - Funded by the European Union — NextGenerationEU under Grant Agreement No. 13IPC005.