Plugins: Support templated urls in routes (#16599)

This adds support for using templated/dynamic urls in routes.
* refactor interpolateString into utils and add interpolation support for app plugin routes.
* cleanup and add error check for url parse failure
* add docs for interpolated route urls

Closes #16835
This commit is contained in:
Brian Gann
2019-05-07 11:55:39 -05:00
committed by Marcus Efraimsson
parent 336655a46a
commit b07d0b1026
8 changed files with 202 additions and 32 deletions

View File

@ -53,6 +53,7 @@ func TestPluginProxy(t *testing.T) {
},
},
&setting.Cfg{SendUserHeader: true},
nil,
)
Convey("Should add header with username", func() {
@ -69,6 +70,7 @@ func TestPluginProxy(t *testing.T) {
},
},
&setting.Cfg{SendUserHeader: false},
nil,
)
Convey("Should not add header with username", func() {
// Get will return empty string even if header is not set
@ -82,6 +84,7 @@ func TestPluginProxy(t *testing.T) {
SignedInUser: &m.SignedInUser{IsAnonymous: true},
},
&setting.Cfg{SendUserHeader: true},
nil,
)
Convey("Should not add header with username", func() {
@ -89,14 +92,59 @@ func TestPluginProxy(t *testing.T) {
So(req.Header.Get("X-Grafana-User"), ShouldEqual, "")
})
})
Convey("When getting templated url", t, func() {
route := &plugins.AppPluginRoute{
Url: "{{.JsonData.dynamicUrl}}",
Method: "GET",
}
bus.AddHandler("test", func(query *m.GetPluginSettingByIdQuery) error {
query.Result = &m.PluginSetting{
JsonData: map[string]interface{}{
"dynamicUrl": "https://dynamic.grafana.com",
},
}
return nil
})
req := getPluginProxiedRequest(
&m.ReqContext{
SignedInUser: &m.SignedInUser{
Login: "test_user",
},
},
&setting.Cfg{SendUserHeader: true},
route,
)
Convey("Headers should be updated", func() {
header, err := getHeaders(route, 1, "my-app")
So(err, ShouldBeNil)
So(header.Get("X-Grafana-User"), ShouldEqual, "")
})
Convey("Should set req.URL to be interpolated value from jsonData", func() {
So(req.URL.String(), ShouldEqual, "https://dynamic.grafana.com")
})
Convey("Route url should not be modified", func() {
So(route.Url, ShouldEqual, "{{.JsonData.dynamicUrl}}")
})
})
}
// getPluginProxiedRequest is a helper for easier setup of tests based on global config and ReqContext.
func getPluginProxiedRequest(ctx *m.ReqContext, cfg *setting.Cfg) *http.Request {
route := &plugins.AppPluginRoute{}
func getPluginProxiedRequest(ctx *m.ReqContext, cfg *setting.Cfg, route *plugins.AppPluginRoute) *http.Request {
// insert dummy route if none is specified
if route == nil {
route = &plugins.AppPluginRoute{
Path: "api/v4/",
Url: "https://www.google.com",
ReqRole: m.ROLE_EDITOR,
}
}
proxy := NewApiPluginProxy(ctx, "", route, "", cfg)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
req, err := http.NewRequest(http.MethodGet, route.Url, nil)
So(err, ShouldBeNil)
proxy.Director(req)
return req