Files
headlamp-kube-vip-plugin/docs/architecture/adr/001-react-context-state.md
T
DevContainer User 6940acc780 docs: add architecture decision records
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 13:50:01 +00:00

67 lines
2.7 KiB
Markdown

# ADR 001: React Context for Centralized State
**Status**: Accepted
**Date**: 2026-03-05
**Deciders**: Development Team
---
## Context
The kube-vip plugin shares data across 4 page views (Overview, Services, Nodes, Config) and 1 detail view section (Service). Data comes from standard Kubernetes resources:
- **Services** (via `useList()`)
- **Nodes** (via `useList()`)
- **DaemonSet** (via `ApiProxy.request()`)
- **Pods** (with fallback, via `ApiProxy.request()`)
- **Leases** (`coordination.k8s.io/v1`, via `ApiProxy.request()`)
- **ConfigMap** (via `ApiProxy.request()`)
The context exposes 12 fields: `kubeVipInstalled`, `daemonSetStatus`, `kubeVipPods`, `cloudProviderPods`, `loadBalancerServices`, `nodes`, `leases`, `ipPools`, `configMapData`, `kubeVipConfig`, `loading`, `error`, and `refresh`.
The plugin uses dual-track fetching: Headlamp `useList()` for Services and Nodes, `ApiProxy.request()` for everything else.
---
## Decision
Use a single `KubeVipDataProvider` React Context wrapping all routes and the Service detail section registration. All kube-vip state is computed in the provider and made available to consumers via the `useKubeVipData()` hook.
---
## Consequences
### Positive
- ✅ Single fetch location eliminates duplicate API calls across views
- ✅ Consistent data across all views at any point in time
- ✅ Derived state (e.g., `ipPools` from ConfigMap) computed once in the provider
-`refresh()` function updates everything in a single call
### Negative
- ⚠️ All consumers re-render on any change to any of the 12 fields
- ⚠️ Complex provider component managing 12 fields and multiple fetch strategies
These negatives are mitigated by the fact that kube-vip state changes infrequently (VIP assignments and pool configurations are relatively stable), so unnecessary re-renders are rare in practice.
---
## Alternatives Considered
1. **Per-page fetching** — Rejected. Would duplicate DaemonSet, ConfigMap, and Lease fetching across multiple pages, leading to redundant API calls and potential data inconsistency between views.
2. **Multiple contexts** (e.g., separate contexts for pods, services, config) — Rejected. Data is heavily cross-referenced: `kubeVipInstalled` depends on the DaemonSet, pod discovery depends on labels from the DaemonSet, and IP pool utilization requires both ConfigMap data and Service annotations. Splitting contexts would require complex inter-context dependencies.
3. **External state library** (e.g., Redux, Zustand) — Rejected. External state management libraries are not available in the Headlamp plugin runtime environment.
---
## Changelog
| Date | Change |
| ---- | ------ |
| 2026-03-05 | Initial decision recorded |