Skip to content

fix: extract LoadBalancer IP from Status.LoadBalancer.Ingress - #9

Merged
ryanmcafee merged 3 commits into
mainfrom
fix/loadbalancer-ip-extraction
Jan 27, 2026
Merged

ryanmcafee merged 3 commits into
mainfrom
fix/loadbalancer-ip-extraction

Conversation

@ryanmcafee

Copy link
Copy Markdown
Owner

Summary

  • Fix IP extraction for modern LoadBalancer controllers (Cilium, MetalLB, cloud providers)
  • These controllers populate Status.LoadBalancer.Ingress[].IP instead of Spec.LoadBalancerIP
  • Add graceful handling for empty ExternalIPs

Problem

Services with LoadBalancer IPs assigned via Status result in empty IP values, causing port forwarding creation to fail with:

invalid response code 400: {"meta":{"rc":"error","msg":"api.err.InvalidPayload"},"data":[{"validationError":{"field":"fwd","pattern":"..."}}]}

The log shows "ip":"" because ipFromService() only checked Spec.LoadBalancerIP.

Solution

Update ipFromService() to:

  1. First check Status.LoadBalancer.Ingress[].IP (modern approach)
  2. Fall back to Spec.LoadBalancerIP (legacy/deprecated)
  3. Handle empty ExternalIPs gracefully

Test plan

  • Added test for LoadBalancer with only Status IP
  • Added test for Status IP taking precedence over Spec IP
  • Unit tests pass (make test)

Closes #7 (related to UDM support - the 400 errors occurred after UDM auth was fixed)

Modern LoadBalancer controllers (Cilium, MetalLB, cloud providers) populate
the assigned IP in Status.LoadBalancer.Ingress rather than Spec.LoadBalancerIP
(which is deprecated).

This fix updates ipFromService() to:
1. First check Status.LoadBalancer.Ingress[].IP (modern approach)
2. Fall back to Spec.LoadBalancerIP (legacy/deprecated)
3. Handle empty ExternalIPs gracefully

Without this fix, services with LoadBalancer IPs assigned via Status
would result in empty IP values, causing port forwarding creation to fail
with "invalid response code 400" due to invalid fwd field.

Adds tests for:
- LoadBalancer with only Status IP (no Spec.LoadBalancerIP)
- LoadBalancer with both Status and Spec IP (Status takes precedence)
Re-fetch Service object before updating Status to get the latest
resourceVersion, avoiding optimistic locking conflicts when the
controller has already added a finalizer during reconciliation.
@ryanmcafee
ryanmcafee merged commit 2843577 into main Jan 27, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for UniFi Dream Machine (UDM/UDR) API paths

1 participant