dual-stack: fix the bug that isValidAddress only checks the first IP even a Pod has more than one address

Signed-off-by: SataQiu <1527062125@qq.com>
This commit is contained in:
SataQiu 2020-04-09 16:17:34 +08:00
parent 7b20442513
commit e71f84b1c4
2 changed files with 81 additions and 3 deletions

View File

@ -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 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;

View File

@ -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")