Skip to content

Commit

Permalink
Add apiserver proxy support for pods.
Browse files Browse the repository at this point in the history
This is useful for testing mostly.
  • Loading branch information
thockin committed Dec 23, 2014
1 parent 8cdaab5 commit fb0a7a9
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 9 deletions.
44 changes: 44 additions & 0 deletions pkg/registry/pod/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package pod

import (
"fmt"
"strings"

"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
Expand Down Expand Up @@ -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
}
114 changes: 105 additions & 9 deletions pkg/registry/pod/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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)
}
}
}

0 comments on commit fb0a7a9

Please sign in to comment.