Commit b0488259 by Daniel Lee Committed by GitHub

azuremonitor: fix for app insights azure china url (#23877)

parent f31f17d5
...@@ -5,6 +5,13 @@ import ( ...@@ -5,6 +5,13 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"net/http"
"net/url"
"path"
"strings"
"time"
"github.com/grafana/grafana/pkg/api/pluginproxy" "github.com/grafana/grafana/pkg/api/pluginproxy"
"github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
...@@ -14,12 +21,6 @@ import ( ...@@ -14,12 +21,6 @@ import (
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
"github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go"
"golang.org/x/net/context/ctxhttp" "golang.org/x/net/context/ctxhttp"
"io/ioutil"
"net/http"
"net/url"
"path"
"strings"
"time"
) )
// ApplicationInsightsDatasource calls the application insights query API's // ApplicationInsightsDatasource calls the application insights query API's
...@@ -237,19 +238,17 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf ...@@ -237,19 +238,17 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf
return nil, errors.New("Unable to find datasource plugin Azure Application Insights") return nil, errors.New("Unable to find datasource plugin Azure Application Insights")
} }
var appInsightsRoute *plugins.AppPluginRoute cloudName := dsInfo.JsonData.Get("cloudName").MustString("azuremonitor")
for _, route := range plugin.Routes { appInsightsRoute, pluginRouteName, err := e.getPluginRoute(plugin, cloudName)
if route.Path == "appinsights" { if err != nil {
appInsightsRoute = route return nil, err
break
}
} }
appInsightsAppId := dsInfo.JsonData.Get("appInsightsAppId").MustString() appInsightsAppID := dsInfo.JsonData.Get("appInsightsAppId").MustString()
proxyPass := fmt.Sprintf("appinsights/v1/apps/%s", appInsightsAppId) proxyPass := fmt.Sprintf("%s/v1/apps/%s", pluginRouteName, appInsightsAppID)
u, _ := url.Parse(dsInfo.Url) u, _ := url.Parse(dsInfo.Url)
u.Path = path.Join(u.Path, fmt.Sprintf("/v1/apps/%s", appInsightsAppId)) u.Path = path.Join(u.Path, fmt.Sprintf("/v1/apps/%s", appInsightsAppID))
req, err := http.NewRequest(http.MethodGet, u.String(), nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil { if err != nil {
...@@ -264,6 +263,25 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf ...@@ -264,6 +263,25 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf
return req, nil return req, nil
} }
func (e *ApplicationInsightsDatasource) getPluginRoute(plugin *plugins.DataSourcePlugin, cloudName string) (*plugins.AppPluginRoute, string, error) {
pluginRouteName := "appinsights"
if cloudName == "chinaazuremonitor" {
pluginRouteName = "chinaappinsights"
}
var pluginRoute *plugins.AppPluginRoute
for _, route := range plugin.Routes {
if route.Path == pluginRouteName {
pluginRoute = route
break
}
}
return pluginRoute, pluginRouteName, nil
}
func (e *ApplicationInsightsDatasource) parseTimeSeriesFromQuery(body []byte, query *ApplicationInsightsQuery) (tsdb.TimeSeriesSlice, *simplejson.Json, error) { func (e *ApplicationInsightsDatasource) parseTimeSeriesFromQuery(body []byte, query *ApplicationInsightsQuery) (tsdb.TimeSeriesSlice, *simplejson.Json, error) {
var data ApplicationInsightsQueryResponse var data ApplicationInsightsQueryResponse
err := json.Unmarshal(body, &data) err := json.Unmarshal(body, &data)
......
...@@ -7,9 +7,13 @@ import ( ...@@ -7,9 +7,13 @@ import (
"testing" "testing"
"time" "time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
"github.com/stretchr/testify/require"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
) )
...@@ -314,3 +318,68 @@ func TestApplicationInsightsDatasource(t *testing.T) { ...@@ -314,3 +318,68 @@ func TestApplicationInsightsDatasource(t *testing.T) {
}) })
}) })
} }
func TestPluginRoutes(t *testing.T) {
datasource := &ApplicationInsightsDatasource{}
plugin := &plugins.DataSourcePlugin{
Routes: []*plugins.AppPluginRoute{
{
Path: "appinsights",
Method: "GET",
URL: "https://api.applicationinsights.io",
Headers: []plugins.AppPluginRouteHeader{
{Name: "X-API-Key", Content: "{{.SecureJsonData.appInsightsApiKey}}"},
{Name: "x-ms-app", Content: "Grafana"},
},
},
{
Path: "chinaappinsights",
Method: "GET",
URL: "https://api.applicationinsights.azure.cn",
Headers: []plugins.AppPluginRouteHeader{
{Name: "X-API-Key", Content: "{{.SecureJsonData.appInsightsApiKey}}"},
{Name: "x-ms-app", Content: "Grafana"},
},
},
},
}
tests := []struct {
name string
cloudName string
expectedRouteName string
expectedRouteURL string
Err require.ErrorAssertionFunc
}{
{
name: "plugin proxy route for the Azure public cloud",
cloudName: "azuremonitor",
expectedRouteName: "appinsights",
expectedRouteURL: "https://api.applicationinsights.io",
Err: require.NoError,
},
{
name: "plugin proxy route for the Azure China cloud",
cloudName: "chinaazuremonitor",
expectedRouteName: "chinaappinsights",
expectedRouteURL: "https://api.applicationinsights.azure.cn",
Err: require.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
route, routeName, err := datasource.getPluginRoute(plugin, tt.cloudName)
tt.Err(t, err)
if diff := cmp.Diff(tt.expectedRouteURL, route.URL, cmpopts.EquateNaNs()); diff != "" {
t.Errorf("Result mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tt.expectedRouteName, routeName, cmpopts.EquateNaNs()); diff != "" {
t.Errorf("Result mismatch (-want +got):\n%s", diff)
}
})
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment