mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure Monitor: allow metrics call to use resource uri (#46858)
* Azure Monitor: allow metrics call to use resource uri * test case when only resource uri is provided * remove logs * Rename json field name from resource to resourceUri * Group legacy URL builder params test cases * move comment to the correct position * Add clarifications in comments Co-authored-by: Sarah Zinger <sarah.zinger@grafana.com> Co-authored-by: Sarah Zinger <sarah.zinger@grafana.com>
This commit is contained in:
parent
65fdc51052
commit
1a4b1184bd
@ -81,13 +81,15 @@ func (e *AzureMonitorDatasource) buildQueries(queries []backend.DataQuery, dsInf
|
|||||||
urlComponents["resourceName"] = azJSONModel.ResourceName
|
urlComponents["resourceName"] = azJSONModel.ResourceName
|
||||||
|
|
||||||
ub := urlBuilder{
|
ub := urlBuilder{
|
||||||
|
ResourceURI: azJSONModel.ResourceURI,
|
||||||
|
// Legacy, used to reconstruct resource URI if it's not present
|
||||||
DefaultSubscription: dsInfo.Settings.SubscriptionId,
|
DefaultSubscription: dsInfo.Settings.SubscriptionId,
|
||||||
Subscription: queryJSONModel.Subscription,
|
Subscription: queryJSONModel.Subscription,
|
||||||
ResourceGroup: queryJSONModel.AzureMonitor.ResourceGroup,
|
ResourceGroup: azJSONModel.ResourceGroup,
|
||||||
MetricDefinition: azJSONModel.MetricDefinition,
|
MetricDefinition: azJSONModel.MetricDefinition,
|
||||||
ResourceName: azJSONModel.ResourceName,
|
ResourceName: azJSONModel.ResourceName,
|
||||||
}
|
}
|
||||||
azureURL := ub.Build()
|
azureURL := ub.BuildMetricsURL()
|
||||||
|
|
||||||
alias := azJSONModel.Alias
|
alias := azJSONModel.Alias
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ import (
|
|||||||
|
|
||||||
// urlBuilder builds the URL for calling the Azure Monitor API
|
// urlBuilder builds the URL for calling the Azure Monitor API
|
||||||
type urlBuilder struct {
|
type urlBuilder struct {
|
||||||
|
ResourceURI string
|
||||||
|
|
||||||
|
// Following fields will be deprecated in grafana 9 and will not included in new queries.
|
||||||
|
// For backwards compat, we recreate the ResourceURI using these fields
|
||||||
DefaultSubscription string
|
DefaultSubscription string
|
||||||
Subscription string
|
Subscription string
|
||||||
ResourceGroup string
|
ResourceGroup string
|
||||||
@ -14,26 +18,39 @@ type urlBuilder struct {
|
|||||||
ResourceName string
|
ResourceName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build checks the metric definition property to see which form of the url
|
// BuildMetricsURL checks the metric definition property to see which form of the url
|
||||||
// should be returned
|
// should be returned
|
||||||
func (ub *urlBuilder) Build() string {
|
func (params *urlBuilder) BuildMetricsURL() string {
|
||||||
subscription := ub.Subscription
|
resourceURI := params.ResourceURI
|
||||||
|
|
||||||
if ub.Subscription == "" {
|
// Prior to Grafana 9, we had a legacy query object rather than a resourceURI, so we manually create the resource URI
|
||||||
subscription = ub.DefaultSubscription
|
if resourceURI == "" {
|
||||||
|
subscription := params.Subscription
|
||||||
|
|
||||||
|
if params.Subscription == "" {
|
||||||
|
subscription = params.DefaultSubscription
|
||||||
}
|
}
|
||||||
|
|
||||||
metricDefinitionArray := strings.Split(ub.MetricDefinition, "/")
|
metricDefinitionArray := strings.Split(params.MetricDefinition, "/")
|
||||||
resourceNameArray := strings.Split(ub.ResourceName, "/")
|
resourceNameArray := strings.Split(params.ResourceName, "/")
|
||||||
provider := metricDefinitionArray[0]
|
provider := metricDefinitionArray[0]
|
||||||
metricDefinitionArray = metricDefinitionArray[1:]
|
metricDefinitionArray = metricDefinitionArray[1:]
|
||||||
|
|
||||||
urlArray := []string{subscription, "resourceGroups", ub.ResourceGroup, "providers", provider}
|
urlArray := []string{
|
||||||
|
subscription,
|
||||||
|
"resourceGroups",
|
||||||
|
params.ResourceGroup,
|
||||||
|
"providers",
|
||||||
|
provider,
|
||||||
|
}
|
||||||
|
|
||||||
for i := range metricDefinitionArray {
|
for i := range metricDefinitionArray {
|
||||||
urlArray = append(urlArray, metricDefinitionArray[i])
|
urlArray = append(urlArray, metricDefinitionArray[i])
|
||||||
urlArray = append(urlArray, resourceNameArray[i])
|
urlArray = append(urlArray, resourceNameArray[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s/providers/microsoft.insights/metrics", strings.Join(urlArray[:], "/"))
|
resourceURI = strings.Join(urlArray[:], "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s/providers/microsoft.insights/metrics", resourceURI)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,29 @@ import (
|
|||||||
|
|
||||||
func TestURLBuilder(t *testing.T) {
|
func TestURLBuilder(t *testing.T) {
|
||||||
t.Run("AzureMonitor URL Builder", func(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",
|
||||||
|
}
|
||||||
|
|
||||||
|
url := ub.BuildMetricsURL()
|
||||||
|
require.Equal(t, url, "resource/uri/providers/microsoft.insights/metrics")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("when resource uri and legacy fields are provided the legacy fields are ignored", func(t *testing.T) {
|
||||||
|
ub := &urlBuilder{
|
||||||
|
ResourceURI: "resource/uri",
|
||||||
|
DefaultSubscription: "default-sub",
|
||||||
|
ResourceGroup: "rg",
|
||||||
|
MetricDefinition: "Microsoft.NetApp/netAppAccounts/capacityPools/volumes",
|
||||||
|
ResourceName: "rn1/rn2/rn3",
|
||||||
|
}
|
||||||
|
|
||||||
|
url := ub.BuildMetricsURL()
|
||||||
|
require.Equal(t, url, "resource/uri/providers/microsoft.insights/metrics")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Legacy URL Builder params", func(t *testing.T) {
|
||||||
t.Run("when metric definition is in the short form", func(t *testing.T) {
|
t.Run("when metric definition is in the short form", func(t *testing.T) {
|
||||||
ub := &urlBuilder{
|
ub := &urlBuilder{
|
||||||
DefaultSubscription: "default-sub",
|
DefaultSubscription: "default-sub",
|
||||||
@ -16,7 +39,7 @@ func TestURLBuilder(t *testing.T) {
|
|||||||
ResourceName: "rn",
|
ResourceName: "rn",
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ub.Build()
|
url := ub.BuildMetricsURL()
|
||||||
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
|
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -29,7 +52,7 @@ func TestURLBuilder(t *testing.T) {
|
|||||||
ResourceName: "rn",
|
ResourceName: "rn",
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ub.Build()
|
url := ub.BuildMetricsURL()
|
||||||
require.Equal(t, url, "specified-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
|
require.Equal(t, url, "specified-sub/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/rn/providers/microsoft.insights/metrics")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -41,7 +64,7 @@ func TestURLBuilder(t *testing.T) {
|
|||||||
ResourceName: "rn1/default",
|
ResourceName: "rn1/default",
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ub.Build()
|
url := ub.BuildMetricsURL()
|
||||||
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/providers/microsoft.insights/metrics")
|
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/providers/microsoft.insights/metrics")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -53,7 +76,7 @@ func TestURLBuilder(t *testing.T) {
|
|||||||
ResourceName: "rn1/default",
|
ResourceName: "rn1/default",
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ub.Build()
|
url := ub.BuildMetricsURL()
|
||||||
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/providers/microsoft.insights/metrics")
|
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/providers/microsoft.insights/metrics")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -65,8 +88,9 @@ func TestURLBuilder(t *testing.T) {
|
|||||||
ResourceName: "rn1/rn2/rn3",
|
ResourceName: "rn1/rn2/rn3",
|
||||||
}
|
}
|
||||||
|
|
||||||
url := ub.Build()
|
url := ub.BuildMetricsURL()
|
||||||
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/providers/microsoft.insights/metrics")
|
require.Equal(t, url, "default-sub/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/providers/microsoft.insights/metrics")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -109,21 +109,26 @@ type AzureResponseTable struct {
|
|||||||
// AzureMonitorJSONQuery is the frontend JSON query model for an Azure Monitor query.
|
// AzureMonitorJSONQuery is the frontend JSON query model for an Azure Monitor query.
|
||||||
type AzureMonitorJSONQuery struct {
|
type AzureMonitorJSONQuery struct {
|
||||||
AzureMonitor struct {
|
AzureMonitor struct {
|
||||||
|
ResourceURI string `json:"resourceUri"`
|
||||||
|
MetricNamespace string `json:"metricNamespace"`
|
||||||
|
MetricName string `json:"metricName"`
|
||||||
|
|
||||||
Aggregation string `json:"aggregation"`
|
Aggregation string `json:"aggregation"`
|
||||||
Alias string `json:"alias"`
|
Alias string `json:"alias"`
|
||||||
|
DimensionFilters []AzureMonitorDimensionFilter `json:"dimensionFilters"` // new model
|
||||||
|
TimeGrain string `json:"timeGrain"`
|
||||||
|
Top string `json:"top"`
|
||||||
|
|
||||||
|
// 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
|
||||||
|
MetricDefinition string `json:"metricDefinition"`
|
||||||
|
ResourceGroup string `json:"resourceGroup"`
|
||||||
|
ResourceName string `json:"resourceName"`
|
||||||
|
|
||||||
AllowedTimeGrainsMs []int64 `json:"allowedTimeGrainsMs"`
|
AllowedTimeGrainsMs []int64 `json:"allowedTimeGrainsMs"`
|
||||||
Dimension string `json:"dimension"` // old model
|
Dimension string `json:"dimension"` // old model
|
||||||
DimensionFilter string `json:"dimensionFilter"` // old model
|
DimensionFilter string `json:"dimensionFilter"` // old model
|
||||||
Format string `json:"format"`
|
Format string `json:"format"`
|
||||||
MetricDefinition string `json:"metricDefinition"`
|
|
||||||
MetricName string `json:"metricName"`
|
|
||||||
MetricNamespace string `json:"metricNamespace"`
|
|
||||||
ResourceGroup string `json:"resourceGroup"`
|
|
||||||
ResourceName string `json:"resourceName"`
|
|
||||||
TimeGrain string `json:"timeGrain"`
|
|
||||||
Top string `json:"top"`
|
|
||||||
|
|
||||||
DimensionFilters []AzureMonitorDimensionFilter `json:"dimensionFilters"` // new model
|
|
||||||
} `json:"azureMonitor"`
|
} `json:"azureMonitor"`
|
||||||
Subscription string `json:"subscription"`
|
Subscription string `json:"subscription"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user