diff --git a/go.mod b/go.mod index a6edebb..bf6042b 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,9 @@ require ( github.com/prometheus/client_golang v1.2.1 github.com/restic/calens v0.2.0 github.com/spf13/viper v1.6.2 + github.com/stretchr/testify v1.5.1 // indirect go.opencensus.io v0.22.2 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 // indirect + golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index 844f388..7ff2397 100644 --- a/go.sum +++ b/go.sum @@ -589,6 +589,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -776,6 +778,8 @@ golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4 h1:Hynbrlo6LbYI3H1IqXpkVDOcX golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -897,6 +901,8 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/command/server.go b/pkg/command/server.go index 51bd4d6..cb23d14 100644 --- a/pkg/command/server.go +++ b/pkg/command/server.go @@ -31,6 +31,18 @@ func Server(cfg *config.Config) *cli.Command { Usage: "Start integrated server", Flags: flagset.ServerWithConfig(cfg), Before: func(c *cli.Context) error { + logger := NewLogger(cfg) + if !cfg.Tracing.Enabled { + logger.Info(). + Str("tracing", "disabled"). + Msg("init") + } else { + logger.Info(). + Str("tracing", "enabled"). + Str("collector", cfg.Tracing.Collector). + Msg("init") + } + if cfg.HTTP.Root != "/" { cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/") } diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index a34772d..eb141c9 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -1,6 +1,7 @@ package proxy import ( + "context" "net/http" "net/http/httputil" "net/url" @@ -8,13 +9,22 @@ import ( "github.com/owncloud/ocis-pkg/v2/log" "github.com/owncloud/ocis-proxy/pkg/config" + + "go.opencensus.io/plugin/ochttp/propagation/tracecontext" + "go.opencensus.io/trace" ) +// Directors map strings to httputil ReverseProxy Director +type Directors map[string]func(req *http.Request) + // MultiHostReverseProxy extends httputil to support multiple hosts with diffent policies type MultiHostReverseProxy struct { httputil.ReverseProxy - Directors map[string]map[string]func(req *http.Request) - logger log.Logger + DirMap map[string]Directors + + propagator tracecontext.HTTPFormat + logger log.Logger + config config.Config } // NewMultiHostReverseProxy undocummented @@ -22,8 +32,9 @@ func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy { options := newOptions(opts...) reverseProxy := &MultiHostReverseProxy{ - Directors: make(map[string]map[string]func(req *http.Request)), - logger: options.Logger, + DirMap: make(map[string]Directors), + logger: options.Logger, + config: *options.Config, } for _, policy := range options.Config.Policies { @@ -63,10 +74,11 @@ func singleJoiningSlash(a, b string) string { // AddHost undocumented func (p *MultiHostReverseProxy) AddHost(policy string, target *url.URL, rt config.Route) { targetQuery := target.RawQuery - if p.Directors[policy] == nil { - p.Directors[policy] = make(map[string]func(req *http.Request)) + if p.DirMap[policy] == nil { + p.DirMap[policy] = make(map[string]func(req *http.Request)) } - p.Directors[policy][rt.Endpoint] = func(req *http.Request) { + + p.DirMap[policy][rt.Endpoint] = func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host if rt.ApacheVHost { @@ -87,34 +99,38 @@ func (p *MultiHostReverseProxy) AddHost(policy string, target *url.URL, rt confi } func (p *MultiHostReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // TODO need to fetch from the accounts service - var hit bool + // ============ policy := "reva" + // ============ + + ctx := context.Background() + var span *trace.Span - if _, ok := p.Directors[policy]; !ok { - p.logger. - Error(). - Msgf("policy %v is not configured", policy) + // Start a root span + if p.config.Tracing.Enabled { + ctx, span = trace.StartSpan(context.Background(), r.URL.String()) + defer span.End() + p.propagator.SpanContextToRequest(span.SpanContext(), r) } - for k := range p.Directors[policy] { - if strings.HasPrefix(r.URL.Path, k) && k != "/" { - p.Director = p.Directors[policy][k] - hit = true - p.logger. - Debug(). - Str("policy", policy). - Str("prefix", k). - Str("path", r.URL.Path). - Msg("director found") - } + if _, ok := p.DirMap[policy]; !ok { + p.logger.Fatal().Msgf("policy %v is not configured", policy) + } + + // override default director with root. TODO this is a design flaw, as we need a catch-all director + if p.DirMap[policy]["/"] != nil { + p.Director = p.DirMap[policy]["/"] } - // override default director with root. If any - if !hit && p.Directors[policy]["/"] != nil { - p.Director = p.Directors[policy]["/"] + for k := range p.DirMap[policy] { + if strings.HasPrefix(r.URL.Path, k) && k != "/" { + p.Director = p.DirMap[policy][k] + p.logger.Debug().Str("policy", policy).Str("prefix", k).Str("path", r.URL.Path).Msg("director found") + } } // Call upstream ServeHTTP - p.ReverseProxy.ServeHTTP(w, r) + p.ReverseProxy.ServeHTTP(w, r.WithContext(ctx)) }