fix panic in ResourceLocation in case of empty pod ip list

This commit is contained in:
Khaled Henidak(Kal) 2019-07-17 17:12:06 +00:00
parent 29669a5e21
commit 41f313570e
2 changed files with 93 additions and 4 deletions

View File

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

View File

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