From 785298e6b9d16bcb87d8c1b5eed13c47c0f84572 Mon Sep 17 00:00:00 2001 From: Tan Jiang Date: Tue, 2 May 2017 19:14:47 +0800 Subject: [PATCH] create reverseproxy --- make/common/templates/nginx/nginx.http.conf | 3 +- make/common/templates/nginx/nginx.https.conf | 3 +- src/ui/controllers/controllers_test.go | 11 ++++- src/ui/controllers/proxy.go | 27 +++++++++++++ src/ui/main.go | 4 ++ src/ui/proxy/proxy.go | 42 ++++++++++++++++++++ src/ui/router.go | 2 + 7 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 src/ui/controllers/proxy.go create mode 100644 src/ui/proxy/proxy.go diff --git a/make/common/templates/nginx/nginx.http.conf b/make/common/templates/nginx/nginx.http.conf index b776f7436..213f3afd5 100644 --- a/make/common/templates/nginx/nginx.http.conf +++ b/make/common/templates/nginx/nginx.http.conf @@ -52,7 +52,7 @@ http { } location /v2/ { - proxy_pass http://registry/v2/; + proxy_pass http://ui/registryproxy/v2/; proxy_set_header Host $$http_host; proxy_set_header X-Real-IP $$remote_addr; proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for; @@ -62,7 +62,6 @@ http { proxy_buffering off; proxy_request_buffering off; - } location /service/ { diff --git a/make/common/templates/nginx/nginx.https.conf b/make/common/templates/nginx/nginx.https.conf index 131aec466..3e3c829e5 100644 --- a/make/common/templates/nginx/nginx.https.conf +++ b/make/common/templates/nginx/nginx.https.conf @@ -71,7 +71,7 @@ http { } location /v2/ { - proxy_pass http://registry/v2/; + proxy_pass http://ui/registryproxy/v2/; proxy_set_header Host $$http_host; proxy_set_header X-Real-IP $$remote_addr; proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for; @@ -81,7 +81,6 @@ http { proxy_buffering off; proxy_request_buffering off; - } location /service/ { diff --git a/src/ui/controllers/controllers_test.go b/src/ui/controllers/controllers_test.go index c41cb2bf5..7d1953687 100644 --- a/src/ui/controllers/controllers_test.go +++ b/src/ui/controllers/controllers_test.go @@ -25,10 +25,10 @@ import ( "strings" "github.com/astaxie/beego" - //"github.com/dghubble/sling" "github.com/stretchr/testify/assert" "github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/ui/config" + "github.com/vmware/harbor/src/ui/proxy" ) //const ( @@ -48,6 +48,10 @@ func init() { log.Fatalf("failed to initialize configurations: %v", err) } + if err := proxy.Init(); err != nil { + log.Fatalf("Failed to initialize the proxy: %v", err) + } + _, file, _, _ := runtime.Caller(1) apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator)))) beego.BConfig.WebConfig.Session.SessionOn = true @@ -61,6 +65,7 @@ func init() { beego.Router("/reset", &CommonController{}, "post:ResetPassword") beego.Router("/userExists", &CommonController{}, "post:UserExists") beego.Router("/sendEmail", &CommonController{}, "get:SendEmail") + beego.Router("/registryproxy/*", &RegistryProxy{}, "*:Handle") //Init user Info //admin = &usrInfo{adminName, adminPwd} @@ -106,4 +111,8 @@ func TestMain(t *testing.T) { beego.BeeApp.Handlers.ServeHTTP(w, r) assert.Equal(int(400), w.Code, "'/sendEmail' httpStatusCode should be 400") + r, _ = http.NewRequest("GET", "/registryproxy/v2/", nil) + w = httptest.NewRecorder() + beego.BeeApp.Handlers.ServeHTTP(w, r) + assert.Equal(int(200), w.Code, "ping v2 should get a 200 response") } diff --git a/src/ui/controllers/proxy.go b/src/ui/controllers/proxy.go new file mode 100644 index 000000000..862ce080e --- /dev/null +++ b/src/ui/controllers/proxy.go @@ -0,0 +1,27 @@ +package controllers + +import ( + "strings" + + "github.com/astaxie/beego" + "github.com/vmware/harbor/src/ui/proxy" +) + +// RegistryProxy is the endpoint on UI for a reverse proxy pointing to registry +type RegistryProxy struct { + beego.Controller +} + +// Handle is the only entrypoint for incoming requests, all requests must go through this func. +func (p *RegistryProxy) Handle() { + req := p.Ctx.Request + rw := p.Ctx.ResponseWriter + req.URL.Path = strings.TrimPrefix(req.URL.Path, proxy.RegistryProxyPrefix) + //TODO interceptors + proxy.Proxy.ServeHTTP(rw, req) +} + +// Render ... +func (p *RegistryProxy) Render() error { + return nil +} diff --git a/src/ui/main.go b/src/ui/main.go index aa52fae8d..6b9912024 100644 --- a/src/ui/main.go +++ b/src/ui/main.go @@ -31,6 +31,7 @@ import ( _ "github.com/vmware/harbor/src/ui/auth/ldap" "github.com/vmware/harbor/src/ui/config" "github.com/vmware/harbor/src/ui/filter" + "github.com/vmware/harbor/src/ui/proxy" "github.com/vmware/harbor/src/ui/service/token" ) @@ -103,5 +104,8 @@ func main() { if err := api.SyncRegistry(); err != nil { log.Error(err) } + log.Info("Init proxy") + proxy.Init() + //go proxy.StartProxy() beego.Run() } diff --git a/src/ui/proxy/proxy.go b/src/ui/proxy/proxy.go new file mode 100644 index 000000000..c77f274af --- /dev/null +++ b/src/ui/proxy/proxy.go @@ -0,0 +1,42 @@ +package proxy + +import ( + "github.com/vmware/harbor/src/ui/config" + + "fmt" + "net/http/httputil" + "net/url" +) + +// Proxy is the instance of the reverse proxy in this package. +var Proxy *httputil.ReverseProxy + +// RegistryProxyPrefix is the prefix of url on UI. +const RegistryProxyPrefix = "/registryproxy" + +// Init initialize the Proxy instance. +func Init(urls ...string) error { + var err error + var registryURL string + if len(urls) > 1 { + return fmt.Errorf("the parm, urls should have only 0 or 1 elements") + } + if len(urls) == 0 { + registryURL, err = config.RegistryURL() + if err != nil { + return err + } + } else { + registryURL = urls[0] + } + targetURL, err := url.Parse(registryURL) + if err != nil { + return err + } + Proxy = httputil.NewSingleHostReverseProxy(targetURL) + return nil +} + +//func StartProxy(registryURL string) { +//http.ListenAndServe(":5000", Proxy) +//} diff --git a/src/ui/router.go b/src/ui/router.go index 52e593f25..90447cb3b 100644 --- a/src/ui/router.go +++ b/src/ui/router.go @@ -107,6 +107,8 @@ func initRouters() { beego.Router("/service/notifications", &service.NotificationHandler{}) beego.Router("/service/token", &token.Handler{}) + beego.Router("/registryproxy/*", &controllers.RegistryProxy{}, "*:Handle") //Error pages beego.ErrorController(&controllers.ErrorController{}) + }