Grafana Backend Proxy Mechanism

Hi there, I’m new to Grafana and am developing a datasource plugin based on a third party API. To avoid CORS, I’m aware that I have to use the proxy mode for all my request. However, I’m struggling to get it to work.

The intention of my plugin is pretty simple, as shown below:

testDatasource() {
    const test_url = "https://api.foo.com/authorize?api_key=123123"
    return this.backendSrv.datasourceRequest({
          url: test_url,
          method: "GET",
        })
}

I have found the implementation of grafana’s proxy under grafana/pkg/api/pluginproxy/ds_proxy.go and it seems that for a request to be proxied, one has to send the request to backend at /datasources/proxy/:id/*, as the server routing sets it below

apiRoute.Any("/datasources/proxy/:id/*", reqSignedIn, hs.ProxyDataSourceRequest)
apiRoute.Any("/datasources/proxy/:id", reqSignedIn, hs.ProxyDataSourceRequest)

From there I thought there’s going to be some url manipulation in the frontend code that transforms my external url request to a request to backend. However, it seems what backendSrv.datasourceRequest does is basically calling the Angular$http service, which is instantiated in grafana/public/app/app.ts (codesnippet here https://pastebin.com/xnNV2BkM). Since there’s no any hooks like angularjs interceptors set up, I didn’t quite understand how calling backendSrv.datasourceRequest would proxy the request, as the doc (http://docs.grafana.org/plugins/developing/auth-for-datasources/) suggests.

Obviously I’ve missed something here but I thought I’d post it here after two days of searching to see if I can get some help. Thanks!

NVM, turns out the url manipulation happened in the backend in frontendsettings.go. For the record, the way I understood it, once a plugin is updated with current.access set to proxy, the following happens,

1.frontend makes a PUT call to /api/datasources/:id to update the settings for the datasource in backend
2. backend prepends the datasource’s url with “/api/datasources/proxy/:id”, stored it in db
3. right after that, frontend makes another GET call to /api/frontend/settings to get the processed datasource settings
4. from then on, all external calls made from the datasource plugin will be routed to “{backend_server}/api/datasources/proxy/:id/{actual http destination}”, and will be proxied by the backend

Hope this could help someone having the same confusion :slight_smile:

1 Like