mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor: Add data links to deep link to Azure Portal Azure Resource Graph (#35591)
* Add deep link in ARG * add soverigh clouds * add query to Azure portal link * move deep link to backend * cloud specific to ARG * Add unit test * fix lint * fix escape issue * use constant & fix test * fix constant & use pathEscape * use cmp.Equal for test
This commit is contained in:
@@ -179,15 +179,38 @@ func (e *AzureResourceGraphDatasource) executeQuery(ctx context.Context, query *
|
||||
if err != nil {
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
if frame.Meta == nil {
|
||||
frame.Meta = &data.FrameMeta{}
|
||||
}
|
||||
frame.Meta.ExecutedQueryString = req.URL.RawQuery
|
||||
|
||||
dataResponse.Frames = data.Frames{frame}
|
||||
azurePortalUrl, err := getAzurePortalUrl(dsInfo.Cloud)
|
||||
if err != nil {
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
|
||||
url := azurePortalUrl + "/#blade/HubsExtension/ArgQueryBlade/query/" + url.PathEscape(query.InterpolatedQuery)
|
||||
frameWithLink := addConfigData(*frame, url)
|
||||
if frameWithLink.Meta == nil {
|
||||
frameWithLink.Meta = &data.FrameMeta{}
|
||||
}
|
||||
frameWithLink.Meta.ExecutedQueryString = req.URL.RawQuery
|
||||
|
||||
dataResponse.Frames = data.Frames{&frameWithLink}
|
||||
return dataResponse
|
||||
}
|
||||
|
||||
func addConfigData(frame data.Frame, dl string) data.Frame {
|
||||
for i := range frame.Fields {
|
||||
if frame.Fields[i].Config == nil {
|
||||
frame.Fields[i].Config = &data.FieldConfig{}
|
||||
}
|
||||
deepLink := data.DataLink{
|
||||
Title: "View in Azure Portal",
|
||||
TargetBlank: true,
|
||||
URL: dl,
|
||||
}
|
||||
frame.Fields[i].Config.Links = append(frame.Fields[i].Config.Links, deepLink)
|
||||
}
|
||||
return frame
|
||||
}
|
||||
|
||||
func (e *AzureResourceGraphDatasource) createRequest(ctx context.Context, dsInfo datasourceInfo, reqBody []byte, url string) (*http.Request, error) {
|
||||
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqBody))
|
||||
if err != nil {
|
||||
@@ -228,3 +251,18 @@ func (e *AzureResourceGraphDatasource) unmarshalResponse(res *http.Response) (Az
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func getAzurePortalUrl(azureCloud string) (string, error) {
|
||||
switch azureCloud {
|
||||
case setting.AzurePublic:
|
||||
return "https://portal.azure.com", nil
|
||||
case setting.AzureChina:
|
||||
return "https://portal.azure.cn", nil
|
||||
case setting.AzureUSGovernment:
|
||||
return "https://portal.azure.us", nil
|
||||
case setting.AzureGermany:
|
||||
return "https://portal.microsoftazure.de", nil
|
||||
default:
|
||||
return "", fmt.Errorf("the cloud is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -110,3 +113,42 @@ func TestAzureResourceGraphCreateRequest(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddConfigData(t *testing.T) {
|
||||
field := data.Field{}
|
||||
dataLink := data.DataLink{Title: "View in Azure Portal", TargetBlank: true, URL: "http://ds"}
|
||||
frame := data.Frame{
|
||||
Fields: []*data.Field{&field},
|
||||
}
|
||||
frameWithLink := addConfigData(frame, "http://ds")
|
||||
expectedFrameWithLink := data.Frame{
|
||||
Fields: []*data.Field{
|
||||
{
|
||||
Config: &data.FieldConfig{
|
||||
Links: []data.DataLink{dataLink},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if !cmp.Equal(frameWithLink, expectedFrameWithLink, data.FrameTestCompareOptions()...) {
|
||||
t.Errorf("unexpepcted frame: %v", cmp.Diff(frameWithLink, expectedFrameWithLink, data.FrameTestCompareOptions()...))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAzurePortalUrl(t *testing.T) {
|
||||
clouds := []string{setting.AzurePublic, setting.AzureChina, setting.AzureUSGovernment, setting.AzureGermany}
|
||||
expectedAzurePortalUrl := map[string]interface{}{
|
||||
setting.AzurePublic: "https://portal.azure.com",
|
||||
setting.AzureChina: "https://portal.azure.cn",
|
||||
setting.AzureUSGovernment: "https://portal.azure.us",
|
||||
setting.AzureGermany: "https://portal.microsoftazure.de",
|
||||
}
|
||||
|
||||
for _, cloud := range clouds {
|
||||
azurePortalUrl, err := getAzurePortalUrl(cloud)
|
||||
if err != nil {
|
||||
t.Errorf("The cloud not supported")
|
||||
}
|
||||
assert.Equal(t, expectedAzurePortalUrl[cloud], azurePortalUrl)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user