From 41f313570e27da20f28694b0a9e2ae0a014a9d2f Mon Sep 17 00:00:00 2001 From: "Khaled Henidak(Kal)" Date: Wed, 17 Jul 2019 17:12:06 +0000 Subject: [PATCH] fix panic in ResourceLocation in case of empty pod ip list --- pkg/registry/core/pod/strategy.go | 20 +++++-- pkg/registry/core/pod/strategy_test.go | 77 ++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/pkg/registry/core/pod/strategy.go b/pkg/registry/core/pod/strategy.go index 5e3e289a8e7..b028bbc99ad 100644 --- a/pkg/registry/core/pod/strategy.go +++ b/pkg/registry/core/pod/strategy.go @@ -239,6 +239,18 @@ func getPod(getter ResourceGetter, ctx context.Context, name string) (*api.Pod, return pod, nil } +// returns primary IP for a Pod +func getPodIP(pod *api.Pod) string { + if pod == nil { + return "" + } + if len(pod.Status.PodIPs) > 0 { + return pod.Status.PodIPs[0].IP + } + + return "" +} + // ResourceLocation returns a URL to which one can send traffic for the specified pod. func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx context.Context, id string) (*url.URL, http.RoundTripper, error) { // Allow ID as "podname" or "podname:port" or "scheme:podname:port". @@ -262,8 +274,8 @@ func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx context.C } } } - - if err := proxyutil.IsProxyableIP(pod.Status.PodIPs[0].IP); err != nil { + podIP := getPodIP(pod) + if err := proxyutil.IsProxyableIP(podIP); err != nil { return nil, nil, errors.NewBadRequest(err.Error()) } @@ -271,9 +283,9 @@ func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx context.C Scheme: scheme, } if port == "" { - loc.Host = pod.Status.PodIPs[0].IP + loc.Host = podIP } else { - loc.Host = net.JoinHostPort(pod.Status.PodIPs[0].IP, port) + loc.Host = net.JoinHostPort(podIP, port) } return loc, rt, nil } diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index 6402af4f80f..611c4e9e099 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -487,3 +487,80 @@ func TestPortForwardLocation(t *testing.T) { } } } + +func TestGetPodIP(t *testing.T) { + testCases := []struct { + name string + pod *api.Pod + expectedIP string + }{ + { + name: "nil pod", + pod: nil, + expectedIP: "", + }, + { + name: "no status object", + pod: &api.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod1"}, + Spec: api.PodSpec{}, + }, + expectedIP: "", + }, + { + name: "no pod ips", + pod: &api.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod1"}, + Spec: api.PodSpec{}, + Status: api.PodStatus{}, + }, + expectedIP: "", + }, + { + name: "empty list", + pod: &api.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod1"}, + Spec: api.PodSpec{}, + Status: api.PodStatus{ + PodIPs: []api.PodIP{}, + }, + }, + expectedIP: "", + }, + { + name: "1 ip", + pod: &api.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod1"}, + Spec: api.PodSpec{}, + Status: api.PodStatus{ + PodIPs: []api.PodIP{ + {IP: "10.0.0.10"}, + }, + }, + }, + expectedIP: "10.0.0.10", + }, + { + name: "multiple ips", + pod: &api.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod1"}, + Spec: api.PodSpec{}, + Status: api.PodStatus{ + PodIPs: []api.PodIP{ + {IP: "10.0.0.10"}, + {IP: "10.0.0.20"}, + }, + }, + }, + expectedIP: "10.0.0.10", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + podIP := getPodIP(tc.pod) + if podIP != tc.expectedIP { + t.Errorf("expected pod ip:%v does not match actual %v", tc.expectedIP, podIP) + } + }) + } +}