mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
"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)
|
return rs.registry.GetPod(ctx, pod.Name)
|
||||||
}), nil
|
}), 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) {
|
func TestCreatePodWithConflictingNamespace(t *testing.T) {
|
||||||
storage := REST{}
|
storage := REST{}
|
||||||
pod := &api.Pod{
|
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())
|
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