mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DataSourceProxy: Fix url validation error handling (#73087)
* DataSourceProxy: Fix url validation error handling * DataSourceProxy: Add unit test for proxyDatasourceRequest * DataSourceProxy: Fix lint error
This commit is contained in:
parent
4f2dd94bce
commit
8ec4c1bdc8
@ -122,7 +122,8 @@ func (p *DataSourceProxyService) proxyDatasourceRequest(c *contextmodel.ReqConte
|
|||||||
proxy, err := pluginproxy.NewDataSourceProxy(ds, plugin.Routes, c, proxyPath, p.Cfg, p.HTTPClientProvider,
|
proxy, err := pluginproxy.NewDataSourceProxy(ds, plugin.Routes, c, proxyPath, p.Cfg, p.HTTPClientProvider,
|
||||||
p.OAuthTokenService, p.DataSourcesService, p.tracer)
|
p.OAuthTokenService, p.DataSourcesService, p.tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, datasource.URLValidationError{}) {
|
var urlValidationError datasource.URLValidationError
|
||||||
|
if errors.As(err, &urlValidationError) {
|
||||||
c.JsonApiErr(http.StatusBadRequest, fmt.Sprintf("Invalid data source URL: %q", ds.URL), err)
|
c.JsonApiErr(http.StatusBadRequest, fmt.Sprintf("Invalid data source URL: %q", ds.URL), err)
|
||||||
} else {
|
} else {
|
||||||
c.JsonApiErr(http.StatusInternalServerError, "Failed creating data source proxy", err)
|
c.JsonApiErr(http.StatusInternalServerError, "Failed creating data source proxy", err)
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
package datasourceproxy
|
package datasourceproxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||||
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
|
"github.com/grafana/grafana/pkg/web"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDataProxy(t *testing.T) {
|
func TestDataProxy(t *testing.T) {
|
||||||
@ -52,3 +65,72 @@ func TestDataProxy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests request to datasource proxy service
|
||||||
|
func TestDatasourceProxy_proxyDatasourceRequest(t *testing.T) {
|
||||||
|
tcs := []struct {
|
||||||
|
name string
|
||||||
|
dsURL string
|
||||||
|
expectedErrorMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Empty datasource URL will return a 400 HTTP status code",
|
||||||
|
dsURL: "",
|
||||||
|
expectedErrorMsg: "validation of data source URL \"\" failed: empty URL string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid datasource URL will return a 400 HTTP status code",
|
||||||
|
dsURL: "://host/path",
|
||||||
|
expectedErrorMsg: "validation of data source URL \"://host/path\" failed: parse \"://host/path\": missing protocol scheme",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tcs {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
pluginID := datasources.DS_PROMETHEUS
|
||||||
|
|
||||||
|
pluginStore := &fakes.FakePluginStore{PluginList: []plugins.PluginDTO{
|
||||||
|
{JSONData: plugins.JSONData{ID: pluginID}},
|
||||||
|
}}
|
||||||
|
|
||||||
|
p := DataSourceProxyService{
|
||||||
|
PluginRequestValidator: &fakePluginRequestValidator{},
|
||||||
|
pluginStore: pluginStore,
|
||||||
|
}
|
||||||
|
|
||||||
|
responseRecorder := httptest.NewRecorder()
|
||||||
|
c := &contextmodel.ReqContext{
|
||||||
|
Context: &web.Context{
|
||||||
|
Req: &http.Request{URL: &url.URL{}},
|
||||||
|
Resp: web.NewResponseWriter("GET", responseRecorder),
|
||||||
|
},
|
||||||
|
Logger: log.NewNopLogger(),
|
||||||
|
}
|
||||||
|
|
||||||
|
p.proxyDatasourceRequest(c, &datasources.DataSource{
|
||||||
|
Type: pluginID,
|
||||||
|
URL: tc.dsURL,
|
||||||
|
})
|
||||||
|
|
||||||
|
resp := responseRecorder.Result()
|
||||||
|
body := resp.Body
|
||||||
|
|
||||||
|
b, err := io.ReadAll(body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, body.Close())
|
||||||
|
|
||||||
|
jsonBody := make(map[string]string)
|
||||||
|
err = json.Unmarshal(b, &jsonBody)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
||||||
|
require.Equal(t, fmt.Sprintf("Invalid data source URL: %q", tc.dsURL), jsonBody["message"])
|
||||||
|
require.Equal(t, tc.expectedErrorMsg, jsonBody["error"])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakePluginRequestValidator struct{}
|
||||||
|
|
||||||
|
func (rv *fakePluginRequestValidator) Validate(_ string, _ *http.Request) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user