mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #3115 from thockin/proxy-pods
Add apiserver proxy support for pods.
This commit is contained in:
commit
8824e46340
@ -18,6 +18,7 @@ package pod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
@ -175,3 +176,46 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
return rs.registry.GetPod(ctx, pod.Name)
|
||||
}), nil
|
||||
}
|
||||
|
||||
// ResourceLocation returns a URL to which one can send traffic for the specified pod.
|
||||
func (rs *REST) ResourceLocation(ctx api.Context, id string) (string, error) {
|
||||
// Allow ID as "podname" or "podname:port". If port is not specified,
|
||||
// try to use the first defined port on the pod.
|
||||
parts := strings.Split(id, ":")
|
||||
if len(parts) > 2 {
|
||||
return "", errors.NewBadRequest(fmt.Sprintf("invalid pod request %q", id))
|
||||
}
|
||||
name := parts[0]
|
||||
port := ""
|
||||
if len(parts) == 2 {
|
||||
// TODO: if port is not a number but a "(container)/(portname)", do a name lookup.
|
||||
port = parts[1]
|
||||
}
|
||||
|
||||
obj, err := rs.Get(ctx, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pod := obj.(*api.Pod)
|
||||
if pod == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Try to figure out a port.
|
||||
if port == "" {
|
||||
for i := range pod.Spec.Containers {
|
||||
if len(pod.Spec.Containers[i].Ports) > 0 {
|
||||
port = fmt.Sprintf("%d", pod.Spec.Containers[i].Ports[0].ContainerPort)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We leave off the scheme ('http://') because we have no idea what sort of server
|
||||
// is listening at this endpoint.
|
||||
loc := pod.Status.PodIP
|
||||
if port != "" {
|
||||
loc += fmt.Sprintf(":%s", port)
|
||||
}
|
||||
return loc, nil
|
||||
}
|
||||
|
@ -443,15 +443,6 @@ func TestCreatePod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type FakePodInfoGetter struct {
|
||||
info api.PodInfo
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *FakePodInfoGetter) GetPodInfo(host, podNamespace string, podID string) (api.PodContainerInfo, error) {
|
||||
return api.PodContainerInfo{ContainerInfo: f.info}, f.err
|
||||
}
|
||||
|
||||
func TestCreatePodWithConflictingNamespace(t *testing.T) {
|
||||
storage := REST{}
|
||||
pod := &api.Pod{
|
||||
@ -487,3 +478,108 @@ func TestUpdatePodWithConflictingNamespace(t *testing.T) {
|
||||
t.Errorf("Expected 'Pod.Namespace does not match the provided context' error, got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceLocation(t *testing.T) {
|
||||
expectedIP := "1.2.3.4"
|
||||
testCases := []struct {
|
||||
pod api.Pod
|
||||
query string
|
||||
location string
|
||||
}{
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
},
|
||||
query: "foo",
|
||||
location: expectedIP,
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
},
|
||||
query: "foo:12345",
|
||||
location: expectedIP + ":12345",
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr"},
|
||||
},
|
||||
},
|
||||
},
|
||||
query: "foo",
|
||||
location: expectedIP,
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr", Ports: []api.Port{{ContainerPort: 9376}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
query: "foo",
|
||||
location: expectedIP + ":9376",
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr", Ports: []api.Port{{ContainerPort: 9376}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
query: "foo:12345",
|
||||
location: expectedIP + ":12345",
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr1"},
|
||||
{Name: "ctr2", Ports: []api.Port{{ContainerPort: 9376}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
query: "foo",
|
||||
location: expectedIP + ":9376",
|
||||
},
|
||||
{
|
||||
pod: api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "ctr1", Ports: []api.Port{{ContainerPort: 9376}}},
|
||||
{Name: "ctr2", Ports: []api.Port{{ContainerPort: 1234}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
query: "foo",
|
||||
location: expectedIP + ":9376",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
podRegistry := registrytest.NewPodRegistry(nil)
|
||||
podRegistry.Pod = &tc.pod
|
||||
storage := &REST{
|
||||
registry: podRegistry,
|
||||
podCache: &fakeCache{statusToReturn: &api.PodStatus{PodIP: expectedIP}},
|
||||
}
|
||||
|
||||
redirector := apiserver.Redirector(storage)
|
||||
location, err := redirector.ResourceLocation(api.NewDefaultContext(), tc.query)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if location != tc.location {
|
||||
t.Errorf("Expected %v, but got %v", tc.location, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user