|
|
|
@ -11,7 +11,6 @@ import ( |
|
|
|
|
"net/url" |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
"text/template" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/opentracing/opentracing-go" |
|
|
|
@ -210,7 +209,7 @@ func (proxy *DataSourceProxy) getDirector() func(req *http.Request) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if proxy.route != nil { |
|
|
|
|
proxy.applyRoute(req) |
|
|
|
|
applyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, proxy.route, proxy.ds) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -302,80 +301,3 @@ func checkWhiteList(c *m.ReqContext, host string) bool { |
|
|
|
|
|
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (proxy *DataSourceProxy) applyRoute(req *http.Request) { |
|
|
|
|
proxy.proxyPath = strings.TrimPrefix(proxy.proxyPath, proxy.route.Path) |
|
|
|
|
|
|
|
|
|
data := templateData{ |
|
|
|
|
JsonData: proxy.ds.JsonData.Interface().(map[string]interface{}), |
|
|
|
|
SecureJsonData: proxy.ds.SecureJsonData.Decrypt(), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interpolatedURL, err := interpolateString(proxy.route.Url, data) |
|
|
|
|
if err != nil { |
|
|
|
|
logger.Error("Error interpolating proxy url", "error", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
routeURL, err := url.Parse(interpolatedURL) |
|
|
|
|
if err != nil { |
|
|
|
|
logger.Error("Error parsing plugin route url", "error", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
req.URL.Scheme = routeURL.Scheme |
|
|
|
|
req.URL.Host = routeURL.Host |
|
|
|
|
req.Host = routeURL.Host |
|
|
|
|
req.URL.Path = util.JoinUrlFragments(routeURL.Path, proxy.proxyPath) |
|
|
|
|
|
|
|
|
|
if err := addHeaders(&req.Header, proxy.route, data); err != nil { |
|
|
|
|
logger.Error("Failed to render plugin headers", "error", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tokenProvider := NewAccessTokenProvider(proxy.ds.Id, proxy.route) |
|
|
|
|
|
|
|
|
|
if proxy.route.TokenAuth != nil { |
|
|
|
|
if token, err := tokenProvider.getAccessToken(data); err != nil { |
|
|
|
|
logger.Error("Failed to get access token", "error", err) |
|
|
|
|
} else { |
|
|
|
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if proxy.route.JwtTokenAuth != nil { |
|
|
|
|
if token, err := tokenProvider.getJwtAccessToken(proxy.ctx.Req.Context(), data); err != nil { |
|
|
|
|
logger.Error("Failed to get access token", "error", err) |
|
|
|
|
} else { |
|
|
|
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
logger.Info("Requesting", "url", req.URL.String()) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func interpolateString(text string, data templateData) (string, error) { |
|
|
|
|
t, err := template.New("content").Parse(text) |
|
|
|
|
if err != nil { |
|
|
|
|
return "", fmt.Errorf("could not parse template %s", text) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var contentBuf bytes.Buffer |
|
|
|
|
err = t.Execute(&contentBuf, data) |
|
|
|
|
if err != nil { |
|
|
|
|
return "", fmt.Errorf("failed to execute template %s", text) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return contentBuf.String(), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func addHeaders(reqHeaders *http.Header, route *plugins.AppPluginRoute, data templateData) error { |
|
|
|
|
for _, header := range route.Headers { |
|
|
|
|
interpolated, err := interpolateString(header.Content, data) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
reqHeaders.Add(header.Name, interpolated) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|