From b0488259d0388cc9a165f1411365b2f729b150d5 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 27 Apr 2020 12:40:11 +0200 Subject: [PATCH] azuremonitor: fix for app insights azure china url (#23877) --- .../applicationinsights-datasource.go | 48 +++++++++---- .../applicationinsights-datasource_test.go | 69 +++++++++++++++++++ 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/pkg/tsdb/azuremonitor/applicationinsights-datasource.go b/pkg/tsdb/azuremonitor/applicationinsights-datasource.go index 9fb203ec6f2..d47baa851f7 100644 --- a/pkg/tsdb/azuremonitor/applicationinsights-datasource.go +++ b/pkg/tsdb/azuremonitor/applicationinsights-datasource.go @@ -5,6 +5,13 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" + "net/http" + "net/url" + "path" + "strings" + "time" + "github.com/grafana/grafana/pkg/api/pluginproxy" "github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/simplejson" @@ -14,12 +21,6 @@ import ( "github.com/grafana/grafana/pkg/tsdb" "github.com/opentracing/opentracing-go" "golang.org/x/net/context/ctxhttp" - "io/ioutil" - "net/http" - "net/url" - "path" - "strings" - "time" ) // ApplicationInsightsDatasource calls the application insights query API's @@ -237,19 +238,17 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf return nil, errors.New("Unable to find datasource plugin Azure Application Insights") } - var appInsightsRoute *plugins.AppPluginRoute - for _, route := range plugin.Routes { - if route.Path == "appinsights" { - appInsightsRoute = route - break - } + cloudName := dsInfo.JsonData.Get("cloudName").MustString("azuremonitor") + appInsightsRoute, pluginRouteName, err := e.getPluginRoute(plugin, cloudName) + if err != nil { + return nil, err } - appInsightsAppId := dsInfo.JsonData.Get("appInsightsAppId").MustString() - proxyPass := fmt.Sprintf("appinsights/v1/apps/%s", appInsightsAppId) + appInsightsAppID := dsInfo.JsonData.Get("appInsightsAppId").MustString() + proxyPass := fmt.Sprintf("%s/v1/apps/%s", pluginRouteName, appInsightsAppID) 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) if err != nil { @@ -264,6 +263,25 @@ func (e *ApplicationInsightsDatasource) createRequest(ctx context.Context, dsInf 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) { var data ApplicationInsightsQueryResponse err := json.Unmarshal(body, &data) diff --git a/pkg/tsdb/azuremonitor/applicationinsights-datasource_test.go b/pkg/tsdb/azuremonitor/applicationinsights-datasource_test.go index 0e72bb11f1d..3cccf7808ae 100644 --- a/pkg/tsdb/azuremonitor/applicationinsights-datasource_test.go +++ b/pkg/tsdb/azuremonitor/applicationinsights-datasource_test.go @@ -7,9 +7,13 @@ import ( "testing" "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/models" + "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/tsdb" + "github.com/stretchr/testify/require" . "github.com/smartystreets/goconvey/convey" ) @@ -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) + } + }) + } + +}