func TestServiceRegistryResourceLocation(t *testing.T) { ctx := api.NewDefaultContext() endpoints := &api.EndpointsList{ Items: []api.Endpoints{ { ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Subsets: []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, }}, }, { ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, Subsets: []api.EndpointSubset{{ Addresses: []api.EndpointAddress{}, Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, }, { Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, }, { Addresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, Ports: []api.EndpointPort{}, }}, }, }, } storage, registry := NewTestREST(t, endpoints) registry.CreateService(ctx, &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, }, }) redirector := rest.Redirector(storage) // Test a simple id. location, _, err := redirector.ResourceLocation(ctx, "foo") if err != nil { t.Errorf("Unexpected error: %v", err) } if location == nil { t.Errorf("Unexpected nil: %v", location) } if e, a := "//1.2.3.4:80", location.String(); e != a { t.Errorf("Expected %v, but got %v", e, a) } // Test a name + port. location, _, err = redirector.ResourceLocation(ctx, "foo:p") if err != nil { t.Errorf("Unexpected error: %v", err) } if location == nil { t.Errorf("Unexpected nil: %v", location) } if e, a := "//1.2.3.4:93", location.String(); e != a { t.Errorf("Expected %v, but got %v", e, a) } // Test a scheme + name + port. location, _, err = redirector.ResourceLocation(ctx, "https:foo:p") if err != nil { t.Errorf("Unexpected error: %v", err) } if location == nil { t.Errorf("Unexpected nil: %v", location) } if e, a := "https://1.2.3.4:93", location.String(); e != a { t.Errorf("Expected %v, but got %v", e, a) } // Test a non-existent name + port. location, _, err = redirector.ResourceLocation(ctx, "foo:q") if err == nil { t.Errorf("Unexpected nil error") } // Test error path if _, _, err = redirector.ResourceLocation(ctx, "bar"); err == nil { t.Errorf("unexpected nil error") } }
statusStore.UpdateStrategy = pod.StatusStrategy return PodStorage{ Pod: &REST{store, proxyTransport}, Binding: &BindingREST{store: store}, Status: &StatusREST{store: &statusStore}, Log: &LogREST{store: store, kubeletConn: k}, Proxy: &ProxyREST{store: store, proxyTransport: proxyTransport}, Exec: &ExecREST{store: store, kubeletConn: k}, Attach: &AttachREST{store: store, kubeletConn: k}, PortForward: &PortForwardREST{store: store, kubeletConn: k}, } } // Implement Redirector. var _ = rest.Redirector(&REST{}) // ResourceLocation returns a pods location from its HostIP func (r *REST) ResourceLocation(ctx api.Context, name string) (*url.URL, http.RoundTripper, error) { return pod.ResourceLocation(r, r.proxyTransport, ctx, name) } // BindingREST implements the REST endpoint for binding pods to nodes when etcd is in use. type BindingREST struct { store *etcdgeneric.Etcd } // New creates a new binding resource func (r *BindingREST) New() runtime.Object { return &api.Binding{} }
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"}, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP, }, { pod: api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo:12345", location: expectedIP + ":12345", }, { pod: api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "ctr"}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP, }, { pod: api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "ctr", Ports: []api.ContainerPort{{ContainerPort: 9376}}}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP + ":9376", }, { pod: api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "ctr", Ports: []api.ContainerPort{{ContainerPort: 9376}}}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, 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.ContainerPort{{ContainerPort: 9376}}}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP + ":9376", }, { pod: api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "ctr1", Ports: []api.ContainerPort{{ContainerPort: 9376}}}, {Name: "ctr2", Ports: []api.ContainerPort{{ContainerPort: 1234}}}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP + ":9376", }, } ctx := api.NewDefaultContext() for _, tc := range testCases { storage, _, _, fakeClient := newStorage(t) key, _ := storage.KeyFunc(ctx, tc.pod.Name) key = etcdtest.AddPrefix(key) if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &tc.pod), 0); err != nil { t.Fatalf("unexpected error: %v", err) } redirector := rest.Redirector(storage) location, _, err := redirector.ResourceLocation(api.NewDefaultContext(), tc.query) if err != nil { t.Errorf("Unexpected error: %v", err) } if location == nil { t.Errorf("Unexpected nil: %v", location) } if location.Scheme != "" { t.Errorf("Expected '%v', but got '%v'", "", location.Scheme) } if location.Host != tc.location { t.Errorf("Expected %v, but got %v", tc.location, location.Host) } } }