diff --git a/pkg/registry/core/service/storage/rest.go b/pkg/registry/core/service/storage/rest.go index ee7adec0961..e393234d1ad 100644 --- a/pkg/registry/core/service/storage/rest.go +++ b/pkg/registry/core/service/storage/rest.go @@ -599,10 +599,12 @@ func isValidAddress(ctx context.Context, addr *api.EndpointAddress, pods rest.Ge if pod == nil { return fmt.Errorf("pod is missing, skipping (%s/%s)", addr.TargetRef.Namespace, addr.TargetRef.Name) } - if pod.Status.PodIPs[0].IP != addr.IP { - return fmt.Errorf("pod ip doesn't match endpoint ip, skipping: %s vs %s (%s/%s)", pod.Status.PodIPs[0].IP, addr.IP, addr.TargetRef.Namespace, addr.TargetRef.Name) + for _, podIP := range pod.Status.PodIPs { + if podIP.IP == addr.IP { + return nil + } } - return nil + return fmt.Errorf("pod ip(s) doesn't match endpoint ip, skipping: %v vs %s (%s/%s)", pod.Status.PodIPs, addr.IP, addr.TargetRef.Namespace, addr.TargetRef.Name) } // This is O(N), but we expect haystack to be small; diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 8d20cb22716..4d811ecda4f 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -1336,6 +1336,16 @@ func TestServiceRegistryResourceLocation(t *testing.T) { Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, }}, }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-second-ip", + Namespace: metav1.NamespaceDefault, + }, + Subsets: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "2001:db7::", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}}, + Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, + }}, + }, }, } pods := &api.PodList{ @@ -1402,6 +1412,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) { t.Errorf("Expected %v, but got %v", e, a) } + // Test a simple id (using second ip). + location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if location == nil { + t.Errorf("Unexpected nil: %v", location) + } + if e, a := "//[2001:db7::]:80", location.String(); e != a { + t.Errorf("Expected %v, but got %v", e, a) + } + // Test a name + port. location, _, err = redirector.ResourceLocation(ctx, "foo:p") if err != nil { @@ -1414,6 +1436,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) { t.Errorf("Expected %v, but got %v", e, a) } + // Test a name + port (using second ip). + location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:p") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if location == nil { + t.Errorf("Unexpected nil: %v", location) + } + if e, a := "//[2001:db7::]:93", location.String(); e != a { + t.Errorf("Expected %v, but got %v", e, a) + } + // Test a name + port number (service port 93 -> target port 80) location, _, err = redirector.ResourceLocation(ctx, "foo:93") if err != nil { @@ -1426,6 +1460,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) { t.Errorf("Expected %v, but got %v", e, a) } + // Test a name + port number (service port 93 -> target port 80, using second ip) + location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:93") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if location == nil { + t.Errorf("Unexpected nil: %v", location) + } + if e, a := "//[2001:db7::]:80", location.String(); e != a { + t.Errorf("Expected %v, but got %v", e, a) + } + // Test a name + port number (service port 9393 -> target port "p" -> endpoint port 93) location, _, err = redirector.ResourceLocation(ctx, "foo:9393") if err != nil { @@ -1438,6 +1484,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) { t.Errorf("Expected %v, but got %v", e, a) } + // Test a name + port number (service port 9393 -> target port "p" -> endpoint port 93, using second ip) + location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:9393") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if location == nil { + t.Errorf("Unexpected nil: %v", location) + } + if e, a := "//[2001:db7::]:93", location.String(); e != a { + t.Errorf("Expected %v, but got %v", e, a) + } + // Test a scheme + name + port. location, _, err = redirector.ResourceLocation(ctx, "https:foo:p") if err != nil { @@ -1450,12 +1508,30 @@ func TestServiceRegistryResourceLocation(t *testing.T) { t.Errorf("Expected %v, but got %v", e, a) } + // Test a scheme + name + port (using second ip). + location, _, err = redirector.ResourceLocation(ctx, "https:foo-second-ip:p") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if location == nil { + t.Errorf("Unexpected nil: %v", location) + } + if e, a := "https://[2001:db7::]:93", location.String(); e != a { + t.Errorf("Expected %v, but got %v", e, a) + } + // Test a non-existent name + port. location, _, err = redirector.ResourceLocation(ctx, "foo:q") if err == nil { t.Errorf("Unexpected nil error") } + // Test a non-existent name + port (using second ip). + location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:q") + if err == nil { + t.Errorf("Unexpected nil error") + } + // Test error path if _, _, err = redirector.ResourceLocation(ctx, "bar"); err == nil { t.Errorf("unexpected nil error")