AzureMonitor: Use Resource Picker in Metrics Query Editor (#47164)

* wip: new metrics query editor

* prepend subscriptions to url path

* remove duplicated setQueryValue file

* add tests for new metrics query editor

* wip start extracting resource field into a shared component

* fix query editor test

* fix up backend tests

* move azure monitor specific getters to azure_monitor_datasource

* use existing useAsyncState hook

* extract useAsyncState into separate file

* add datahooks tests

* extract resource field component

* cleanup

* clarify variable names

* remove logs query specific resource field component

* add url_builder test

* add azure_monitor_datasources tests

* address comments

* add types

* pass resourceUri to resource field component

* add test to check we reset the query fields when changing resources
This commit is contained in:
Kevin Yu
2022-04-08 08:49:46 -07:00
committed by GitHub
parent e3b123c3fc
commit ebe5f3646f
28 changed files with 1668 additions and 675 deletions

View File

@@ -217,7 +217,6 @@ func (e *AzureMonitorDatasource) createRequest(ctx context.Context, dsInfo types
azlog.Debug("Failed to create request", "error", err)
return nil, errutil.Wrap("Failed to create request", err)
}
req.URL.Path = "/subscriptions"
req.Header.Set("Content-Type", "application/json")
return req, nil

View File

@@ -163,7 +163,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
}
azureMonitorQuery := &types.AzureMonitorQuery{
URL: "12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
UrlComponents: map[string]string{
"metricDefinition": "Microsoft.Compute/virtualMachines",
"resourceGroup": "grafanastaging",
@@ -587,7 +587,7 @@ func TestAzureMonitorCreateRequest(t *testing.T) {
}{
{
name: "creates a request",
expectedURL: "http://ds/subscriptions",
expectedURL: "http://ds/",
expectedHeaders: http.Header{
"Content-Type": []string{"application/json"},
},

View File

@@ -18,6 +18,35 @@ type urlBuilder struct {
ResourceName string
}
func (params *urlBuilder) buildMetricsURLFromLegacyQuery() string {
subscription := params.Subscription
if params.Subscription == "" {
subscription = params.DefaultSubscription
}
metricDefinitionArray := strings.Split(params.MetricDefinition, "/")
resourceNameArray := strings.Split(params.ResourceName, "/")
provider := metricDefinitionArray[0]
metricDefinitionArray = metricDefinitionArray[1:]
urlArray := []string{
"/subscriptions",
subscription,
"resourceGroups",
params.ResourceGroup,
"providers",
provider,
}
for i, metricDefinition := range metricDefinitionArray {
urlArray = append(urlArray, metricDefinition, resourceNameArray[i])
}
resourceURI := strings.Join(urlArray, "/")
return resourceURI
}
// BuildMetricsURL checks the metric definition property to see which form of the url
// should be returned
func (params *urlBuilder) BuildMetricsURL() string {
@@ -25,31 +54,7 @@ func (params *urlBuilder) BuildMetricsURL() string {
// Prior to Grafana 9, we had a legacy query object rather than a resourceURI, so we manually create the resource URI
if resourceURI == "" {
subscription := params.Subscription
if params.Subscription == "" {
subscription = params.DefaultSubscription
}
metricDefinitionArray := strings.Split(params.MetricDefinition, "/")
resourceNameArray := strings.Split(params.ResourceName, "/")
provider := metricDefinitionArray[0]
metricDefinitionArray = metricDefinitionArray[1:]
urlArray := []string{
subscription,
"resourceGroups",
params.ResourceGroup,
"providers",
provider,
}
for i := range metricDefinitionArray {
urlArray = append(urlArray, metricDefinitionArray[i])
urlArray = append(urlArray, resourceNameArray[i])
}
resourceURI = strings.Join(urlArray[:], "/")
resourceURI = params.buildMetricsURLFromLegacyQuery()
}
return fmt.Sprintf("%s/providers/microsoft.insights/metrics", resourceURI)

View File

@@ -3,23 +3,23 @@ package metrics
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
)
func TestURLBuilder(t *testing.T) {
t.Run("AzureMonitor URL Builder", func(t *testing.T) {
t.Run("when only resource uri is provided it returns resource/uri/providers/microsoft.insights/metrics", func(t *testing.T) {
ub := &urlBuilder{
ResourceURI: "resource/uri",
ResourceURI: "/subscriptions/sub/resource/uri",
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "resource/uri/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/sub/resource/uri/providers/microsoft.insights/metrics", url)
})
t.Run("when resource uri and legacy fields are provided the legacy fields are ignored", func(t *testing.T) {
ub := &urlBuilder{
ResourceURI: "resource/uri",
ResourceURI: "/subscriptions/sub/resource/uri",
DefaultSubscription: "default-sub",
ResourceGroup: "rg",
MetricDefinition: "Microsoft.NetApp/netAppAccounts/capacityPools/volumes",
@@ -27,7 +27,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "resource/uri/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/sub/resource/uri/providers/microsoft.insights/metrics", url)
})
t.Run("Legacy URL Builder params", func(t *testing.T) {
@@ -40,7 +40,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/default-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics", url)
})
t.Run("when metric definition is in the short form and a subscription is defined", func(t *testing.T) {
@@ -53,7 +53,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "specified-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/specified-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics", url)
})
t.Run("when metric definition is Microsoft.Storage/storageAccounts/blobServices", func(t *testing.T) {
@@ -65,7 +65,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/providers/microsoft.insights/metrics", url)
})
t.Run("when metric definition is Microsoft.Storage/storageAccounts/fileServices", func(t *testing.T) {
@@ -77,7 +77,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/providers/microsoft.insights/metrics", url)
})
t.Run("when metric definition is Microsoft.NetApp/netAppAccounts/capacityPools/volumes", func(t *testing.T) {
@@ -89,7 +89,7 @@ func TestURLBuilder(t *testing.T) {
}
url := ub.BuildMetricsURL()
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/providers/microsoft.insights/metrics")
assert.Equal(t, "/subscriptions/default-sub/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/providers/microsoft.insights/metrics", url)
})
})
})

View File

@@ -121,9 +121,12 @@ type AzureMonitorJSONQuery struct {
// Legecy "resource" fields from before the resource picker provided just a single ResourceURI
// These are used for pre-resource picker queries to reconstruct a resource URI
// Deprecated
MetricDefinition string `json:"metricDefinition"`
ResourceGroup string `json:"resourceGroup"`
ResourceName string `json:"resourceName"`
// Deprecated
ResourceGroup string `json:"resourceGroup"`
// Deprecated
ResourceName string `json:"resourceName"`
AllowedTimeGrainsMs []int64 `json:"allowedTimeGrainsMs"`
Dimension string `json:"dimension"` // old model