// TODO: Remove the conversion. Consider only return the NodeAddresses externalNode := &v1.Node{} err = v1.Convert_api_Node_To_v1_Node(node, externalNode, nil) if err != nil { return nil, fmt.Errorf("failed to convert to v1.Node: %v", err) } return externalNode, nil }) connectionInfoGetter, err := client.NewNodeConnectionInfoGetter(nodeGetter, kubeletClientConfig) if err != nil { return nil, err } nodeREST.connection = connectionInfoGetter proxyREST.Connection = connectionInfoGetter return &NodeStorage{ Node: nodeREST, Status: statusREST, Proxy: proxyREST, KubeletConnectionInfo: connectionInfoGetter, }, nil } // Implement Redirector. var _ = rest.Redirector(&REST{}) // ResourceLocation returns a URL to which one can send traffic for the specified node. func (r *REST) ResourceLocation(ctx genericapirequest.Context, id string) (*url.URL, http.RoundTripper, error) { return node.ResourceLocation(r, r.connection, r.proxyTransport, ctx, id) }
func TestServiceRegistryResourceLocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() endpoints := &api.EndpointsList{ Items: []api.Endpoints{ { ObjectMeta: metav1.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: metav1.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: metav1.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, Ports: []api.ServicePort{ // Service port 9393 should route to endpoint port "p", which is port 93 {Name: "p", Port: 9393, TargetPort: intstr.FromString("p")}, // Service port 93 should route to unnamed endpoint port, which is port 80 // This is to test that the service port definition is used when determining resource location {Name: "", Port: 93, TargetPort: intstr.FromInt(80)}, }, }, }) 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 name + port number (service port 93 -> target port 80) location, _, err = redirector.ResourceLocation(ctx, "foo:93") 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 number (service port 9393 -> target port "p" -> endpoint port 93) location, _, err = redirector.ResourceLocation(ctx, "foo:9393") 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") } }
func TestResourceLocation(t *testing.T) { expectedIP := "1.2.3.4" testCases := []struct { pod api.Pod query string location string }{ { pod: api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP, }, { pod: api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo:12345", location: expectedIP + ":12345", }, { pod: api.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "ctr"}, }, }, Status: api.PodStatus{PodIP: expectedIP}, }, query: "foo", location: expectedIP, }, { pod: api.Pod{ ObjectMeta: metav1.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: metav1.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: metav1.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: metav1.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 := genericapirequest.NewDefaultContext() for _, tc := range testCases { storage, _, _, server := newStorage(t) key, _ := storage.KeyFunc(ctx, tc.pod.Name) if err := storage.Storage.Create(ctx, key, &tc.pod, nil, 0); err != nil { t.Fatalf("unexpected error: %v", err) } redirector := rest.Redirector(storage) location, _, err := redirector.ResourceLocation(genericapirequest.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) } server.Terminate(t) } }