kubeslice / kubeslice/worker-operator
Worker: Report per-peer connectivity status and reasons (Partial Mesh MVP)
- Dominant language
- Go
- Stars
- 62
- Forks
- 33
- Avg merge
- 3d 10h
- Merged PRs (30d)
- 3
Description
## Summary
Add per-peer connectivity status reporting to the worker operator so the controller can aggregate it into a Slice-level topology readiness condition.
**Depends on:** #470 (peer reconciliation implemented — provides the connection state to report)
---
## Status schema
Add to the worker CR status (confirm exact CR with ADR-002 Decision 6):
```yaml
status:
topology:
peerStatuses:
- peer: hub-cluster-1
state: Connected # Connected | NotConnected | Pending
lastTransitionTime: "2026-06-24T10:05:00Z"
reason: TunnelEstablished
message: ""
- peer: spoke-cluster-a
state: NotConnected
lastTransitionTime: "2026-06-24T10:04:30Z"
reason: DialTimeout
message: "failed to reach spoke-cluster-a:51820 after 30s"
summary:
desiredPeers: 3
readyPeers: 2
failingPeers: 1
```
**State definitions:**
| State | Meaning |
|---|---|
| `Connected` | Tunnel link established and health-checked |
| `NotConnected` | Link attempted but failed; see reason/message |
| `Pending` | Link creation in progress (first attempt not yet complete) |
**Reason codes:**
| Reason | State | Meaning |
|---|---|---|
| `TunnelEstablished` | Connected | Tunnel up and passing health check |
| `DialTimeout` | NotConnected | Peer endpoint unreachable within timeout |
| `PeerNotReady` | NotConnected | Peer reported not ready in its own status |
| `Reconciling` | Pending | Worker is actively establishing the link |
| `RemovedByTopology` | — | Peer removed from desired list; link torn down |
---
## Controller aggregation
The controller's SliceConfig reconciler reads all worker `topology.peerStatuses` and computes:
```yaml
# SliceConfig status
status:
conditions:
- type: TopologyConverged
status: "False"
reason: PeersNotReady
message: "1/3 desired edges not connected: spoke-cluster-a on worker-1 (DialTimeout)"
lastTransitionTime: "2026-06-24T10:04:35Z"
```
`TopologyConverged=True` when all workers report `summary.failingPeers = 0` and `summary.readyPeers = summary.desiredPeers`.
---
## Update behavior
- Status must be updated within one reconcile loop of a peer state change
- Stale `peerStatuses` entries (for peers no longer in `spec.peers`) must be removed — no orphaned entries
- `summary` counts must always equal `len(peerStatuses)` broken down by state — enforce this invariant in a unit test
---
## Acceptance Criteria
- [ ] `peerStatuses` list is accurate after worker reconciles peer connections
- [ ] `summary.desiredPeers`, `readyPeers`, `failingPeers` always sum correctly — unit test verifies invariant
- [ ] Stale entries (peer removed from `spec.peers`) are cleaned up in the same reconcile loop
- [ ] `lastTransitionTime` only updates when `state` changes — not on every reconcile
- [ ] Controller reads worker statuses and produces `TopologyConverged` condition on SliceConfig
- [ ] Unit test: two workers, one peer Connected and one NotConnected → controller sets `TopologyConverged=False` with correct message
- [ ] Demo: in Kind, confirm `TopologyConverged=True` after all hub↔spoke links connect
Contributor guide
Assessment
This issue has not been assessed yet.