* refactor(errors): centralize fatal error handling
Detect wrapped PanicError values consistently and preserve their underlying causes when adding fatal context. Apply the helpers to manager, cluster, and IPVS error paths.
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
* fix(watchers): restart after terminal watch failures
Propagate fatal endpoint watcher failures through the owning service watcher so kube-vip releases leadership instead of remaining active with a stale watch. Treat terminal service, node, and annotation watch failures as errors while preserving clean context cancellation.
Return exhausted authorization failures to RetryWatcher, safely decode watch error objects, and replace direct go-spew diagnostics with structured logging.
Fixes#1685
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
* fix(services): replace state after traffic policy changes
Recreate the service context and instance as one generation when a Service change requires teardown. Ignore delayed leadership cleanup from superseded contexts so it cannot remove replacement state.
This prevents a stale Cluster-policy endpoint watcher from winning the service lease after externalTrafficPolicy changes to Local.
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
* fix(cli): return command errors to container runtime
Propagate manager and service command failures through Cobra so the process exits with status 1. Show usage for invocation errors while keeping runtime failures concise.
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
* refactor(logging): use structured errors
Replace direct stdout error output with slog records for command failures and traffic mirror qdisc lookup failures.
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
* fix(watchers): continue after endpoint deletion
Keep EndpointSlice watchers active when an individual endpoint object is deleted so replacement objects can be observed and service traffic can recover.
Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
---------
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
AddOrModify only calls leaseMgr.Add inside its `if svcCtx == nil` branch, but
the in-memory lease is removed independently: the cleanup goroutine started by
StartServicesLeaderElection calls leaseMgr.Delete once svcCtx.Ctx is done, and
Manager.Delete drops the lease once its last object goes away.
Several paths cancel the service context without also removing it from svcMap -
the deferred close(stopChan) in watchEndpoint, and the utils.PanicError branch
in AddOrModify. Afterwards svcMap still holds a cancelled context for that UID,
so every later watch event reuses it, skips leaseMgr.Add, and
StartServicesLeaderElection fails on
no existing lease found for service %q with UID %q
for the lifetime of the process. Leader election never restarts and the address
is never re-advertised; only restarting the pod clears it.
This is distinct from #1650, which removed the wg.Wait() deadlock but not this
svcMap <-> leaseMgr desync. Both v1.2.1 and v1.2.2 are affected.
Drop a cancelled service context so the existing code path creates a fresh
context and a fresh lease, restoring the invariant that a service context in
svcMap always has a matching lease in the lease manager.
The alternative - having StartServicesLeaderElection call leaseMgr.Add when Get
returns nil - was rejected because it would attach the lease lifetime to the
service context rather than the watcher context, inverting the intended
ownership model.
Signed-off-by: MaxRink <github@maxrink.de>