diff --git a/pkg/registry/core/pod/storage/storage_test.go b/pkg/registry/core/pod/storage/storage_test.go index f91158351ff..978b467d794 100644 --- a/pkg/registry/core/pod/storage/storage_test.go +++ b/pkg/registry/core/pod/storage/storage_test.go @@ -18,6 +18,7 @@ package storage import ( "context" + "net/url" "strings" "testing" "time" @@ -251,7 +252,7 @@ func TestCreateSetsFields(t *testing.T) { func TestResourceLocation(t *testing.T) { expectedIP := "1.2.3.4" - expectedIP6 := "2001:db8::" + expectedIP6 := "fd00:10:244:0:2::6b" testCases := []struct { pod api.Pod query string @@ -286,6 +287,19 @@ func TestResourceLocation(t *testing.T) { query: "foo", location: expectedIP, }, + { + pod: api.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Name: "ctr"}, + }, + }, + Status: api.PodStatus{PodIPs: []api.PodIP{{IP: expectedIP6}}}, + }, + query: "foo", + location: "[" + expectedIP6 + "]", + }, { pod: api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, @@ -354,6 +368,20 @@ func TestResourceLocation(t *testing.T) { query: "foo", location: expectedIP + ":9376", }, + { + pod: api.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Name: "ctr1", Ports: []api.ContainerPort{{ContainerPort: 9376}}}, + {Name: "ctr2", Ports: []api.ContainerPort{{ContainerPort: 1234}}}, + }, + }, + Status: api.PodStatus{PodIPs: []api.PodIP{{IP: expectedIP6}, {IP: expectedIP}}}, + }, + query: "foo", + location: "[" + expectedIP6 + "]:9376", + }, } ctx := genericapirequest.NewDefaultContext() @@ -379,6 +407,10 @@ func TestResourceLocation(t *testing.T) { if location.Host != tc.location { t.Errorf("Expected %v, but got %v", tc.location, location.Host) } + if _, err := url.Parse(location.String()); err != nil { + t.Errorf("could not parse returned location %s: %v", location.String(), err) + } + server.Terminate(t) } } diff --git a/pkg/registry/core/pod/strategy.go b/pkg/registry/core/pod/strategy.go index ea4476200b3..8c671e35070 100644 --- a/pkg/registry/core/pod/strategy.go +++ b/pkg/registry/core/pod/strategy.go @@ -26,7 +26,7 @@ import ( "strings" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" @@ -317,7 +317,13 @@ func ResourceLocation(ctx context.Context, getter ResourceGetter, rt http.RoundT Scheme: scheme, } if port == "" { - loc.Host = podIP + // when using an ipv6 IP as a hostname in a URL, it must be wrapped in [...] + // net.JoinHostPort does this for you. + if strings.Contains(podIP, ":") { + loc.Host = "[" + podIP + "]" + } else { + loc.Host = podIP + } } else { loc.Host = net.JoinHostPort(podIP, port) }