Initial proxy tunnelling.

This commit is contained in:
Brendan Burns
2015-05-27 21:38:21 -07:00
committed by CJ Cullen
parent 631cf34d40
commit 30a89968a4
6 changed files with 244 additions and 37 deletions

View File

@@ -18,6 +18,7 @@ package apiserver
import (
"fmt"
"net"
"net/http"
"net/url"
gpath "path"
@@ -55,14 +56,14 @@ type action struct {
var errEmptyName = errors.NewBadRequest("name must be provided")
// Installs handlers for API resources.
func (a *APIInstaller) Install() (ws *restful.WebService, errors []error) {
func (a *APIInstaller) Install(proxyDialer func(network, addr string) (net.Conn, error)) (ws *restful.WebService, errors []error) {
errors = make([]error, 0)
// Create the WebService.
ws = a.newWebService()
redirectHandler := (&RedirectHandler{a.group.Storage, a.group.Codec, a.group.Context, a.info})
proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info})
proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info, proxyDialer})
// Register the paths in a deterministic (sorted) order to get a deterministic swagger spec.
paths := make([]string, len(a.group.Storage))

View File

@@ -22,6 +22,7 @@ import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"path"
"strconv"
@@ -149,7 +150,7 @@ type RestContainer struct {
// InstallREST registers the REST handlers (storage, watch, proxy and redirect) into a restful Container.
// It is expected that the provided path root prefix will serve all operations. Root MUST NOT end
// in a slash. A restful WebService is created for the group and version.
func (g *APIGroupVersion) InstallREST(container *RestContainer) error {
func (g *APIGroupVersion) InstallREST(container *RestContainer, proxyDialer func(network, addr string) (net.Conn, error)) error {
info := &APIRequestInfoResolver{util.NewStringSet(strings.TrimPrefix(g.Root, "/")), g.Mapper}
prefix := path.Join(g.Root, g.Version)
@@ -159,7 +160,7 @@ func (g *APIGroupVersion) InstallREST(container *RestContainer) error {
prefix: prefix,
minRequestTimeout: container.MinRequestTimeout,
}
ws, registrationErrors := installer.Install()
ws, registrationErrors := installer.Install(proxyDialer)
container.Add(ws)
return errors.NewAggregate(registrationErrors)
}

View File

@@ -49,6 +49,8 @@ type ProxyHandler struct {
codec runtime.Codec
context api.RequestContextMapper
apiRequestInfoResolver *APIRequestInfoResolver
dial func(network, addr string) (net.Conn, error)
}
func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
@@ -119,9 +121,9 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
httpCode = http.StatusNotFound
return
}
// TODO: make this dynamic
location.Host = "localhost"
location.Scheme = "http"
if r.dial != nil {
transport = &http.Transport{Dial: r.dial}
}
// Default to http
if location.Scheme == "" {