kubeslice / kubeslice/worker-operator
Reconcile hub-and-spoke peer intents (create/update/delete) (Partial Mesh MVP)
- Dominant language
- Go
- Stars
- 62
- Forks
- 33
- Avg merge
- 3d 10h
- Merged PRs (30d)
- 3
Description
## Summary
Implement worker-side reconciliation to enforce Hub-and-Spoke peer connectivity based on controller-published peer intents. Workers must create, maintain, and remove tunnel links to match the desired peer list exactly.
**Depends on:** kubeslice-controller #300 (ADR merged — defines `desiredPeers` field location and schema)
---
## What the worker receives from the controller
The controller (after implementing the `TopologyResolver`) writes a desired peer list into `WorkerSliceConfig` (or the field decided in ADR-002 Decision 6). The exact field path must match what the controller writes — confirm before coding.
Proposed schema addition to `WorkerSliceConfig`:
```yaml
spec:
peers: # list of cluster names this worker should connect to
- hub-cluster-1
- spoke-cluster-a # only present if this worker IS the hub
```
If `spec.peers` is absent or empty and no `topology` is set → full mesh behavior unchanged (backward compat).
---
## Reconcile algorithm
```
func ReconcilePeers(desired []string) error:
current = listActiveTunnelLinks() // existing peer connections on this worker
toCreate = desired - current // in desired, not yet connected
toDelete = current - desired // connected, no longer desired
for each peer in toCreate:
establishTunnelLink(peer)
for each peer in toDelete:
tearDownTunnelLink(peer)
return nil
```
**Idempotency requirement:** Calling `ReconcilePeers` twice with identical `desired` and `current` must produce **zero writes** on the second call. Test this explicitly.
**Restart safety:** After worker operator restart, `listActiveTunnelLinks()` must accurately reflect the actual state of tunnel links — not in-memory cache. If state is read from the cluster (CRs, OS network state), document which is authoritative.
---
## Hub change handling
When `spec.peers` changes (e.g., hub changes from cluster-A to cluster-B):
```
1. toCreate = [cluster-B] — establish new link first
2. Wait for cluster-B link to report Connected (or proceed after timeout)
3. toDelete = [cluster-A] — tear down old link
```
The controller enforces the add-first-then-remove ordering at the intent level (see ADR-002 Decision 4). The worker must apply intents in the order received and must not reverse this order.
---
## No-op for non-topology slices
If `WorkerSliceConfig.spec.peers` is absent → use existing full-mesh behavior unchanged. The new reconcile path must be gated on the presence of this field, not on a mode flag.
---
## Acceptance Criteria
- [ ] Worker creates tunnel links for all peers in `spec.peers`
- [ ] Worker tears down tunnel links for peers removed from `spec.peers`
- [ ] Idempotency unit test: reconcile called twice, same state → zero writes on second call
- [ ] Restart safety: worker restarts, re-reads existing tunnel state, converges without flap
- [ ] Hub change: new link established before old link is removed — order verified by test
- [ ] No behavior change when `spec.peers` is absent — existing test suite passes unchanged
- [ ] Demo in Kind: 3-cluster setup (hub + 2 spokes), verify no spoke↔spoke tunnel link is created
Contributor guide
Assessment
This issue has not been assessed yet.