mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
AzureMonitor: build azure portal deep link with resource uri (#47947)
* AzureMonitor: build azure portal deep link with resource uri * extract resource name from the metrics api query * extract func for getting resource name from metrics url * add additional valid characters to regex
This commit is contained in:
parent
e0aeb83786
commit
eef22c05e1
@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@ -32,7 +33,8 @@ type AzureMonitorDatasource struct {
|
||||
|
||||
var (
|
||||
// Used to convert the aggregation value to the Azure enum for deep linking
|
||||
aggregationTypeMap = map[string]int{"None": 0, "Total": 1, "Minimum": 2, "Maximum": 3, "Average": 4, "Count": 7}
|
||||
aggregationTypeMap = map[string]int{"None": 0, "Total": 1, "Minimum": 2, "Maximum": 3, "Average": 4, "Count": 7}
|
||||
resourceNameLandmark = regexp.MustCompile(`(?i)(/(?P<resourceName>[\w-\.]+)/providers/Microsoft\.Insights/metrics)`)
|
||||
)
|
||||
|
||||
const azureMonitorAPIVersion = "2018-01-01"
|
||||
@ -74,12 +76,6 @@ func (e *AzureMonitorDatasource) buildQueries(queries []backend.DataQuery, dsInf
|
||||
|
||||
azJSONModel := queryJSONModel.AzureMonitor
|
||||
|
||||
urlComponents := map[string]string{}
|
||||
urlComponents["subscription"] = queryJSONModel.Subscription
|
||||
urlComponents["resourceGroup"] = azJSONModel.ResourceGroup
|
||||
urlComponents["metricDefinition"] = azJSONModel.MetricDefinition
|
||||
urlComponents["resourceName"] = azJSONModel.ResourceName
|
||||
|
||||
ub := urlBuilder{
|
||||
ResourceURI: azJSONModel.ResourceURI,
|
||||
// Legacy, used to reconstruct resource URI if it's not present
|
||||
@ -91,6 +87,19 @@ func (e *AzureMonitorDatasource) buildQueries(queries []backend.DataQuery, dsInf
|
||||
}
|
||||
azureURL := ub.BuildMetricsURL()
|
||||
|
||||
resourceName := azJSONModel.ResourceName
|
||||
if resourceName == "" {
|
||||
resourceName = extractResourceNameFromMetricsURL(azureURL)
|
||||
}
|
||||
|
||||
urlComponents := map[string]string{}
|
||||
urlComponents["resourceURI"] = azJSONModel.ResourceURI
|
||||
// Legacy fields used for constructing a deep link to display the query in Azure Portal.
|
||||
urlComponents["subscription"] = queryJSONModel.Subscription
|
||||
urlComponents["resourceGroup"] = azJSONModel.ResourceGroup
|
||||
urlComponents["metricDefinition"] = azJSONModel.MetricDefinition
|
||||
urlComponents["resourceName"] = resourceName
|
||||
|
||||
alias := azJSONModel.Alias
|
||||
|
||||
timeGrain := azJSONModel.TimeGrain
|
||||
@ -338,12 +347,18 @@ func getQueryUrl(query *types.AzureMonitorQuery, azurePortalUrl string) (string,
|
||||
}
|
||||
escapedTime := url.QueryEscape(string(timespan))
|
||||
|
||||
id := fmt.Sprintf("/subscriptions/%v/resourceGroups/%v/providers/%v/%v",
|
||||
query.UrlComponents["subscription"],
|
||||
query.UrlComponents["resourceGroup"],
|
||||
query.UrlComponents["metricDefinition"],
|
||||
query.UrlComponents["resourceName"],
|
||||
)
|
||||
id := query.UrlComponents["resourceURI"]
|
||||
|
||||
if id == "" {
|
||||
ub := urlBuilder{
|
||||
Subscription: query.UrlComponents["subscription"],
|
||||
ResourceGroup: query.UrlComponents["resourceGroup"],
|
||||
MetricDefinition: query.UrlComponents["metricDefinition"],
|
||||
ResourceName: query.UrlComponents["resourceName"],
|
||||
}
|
||||
id = ub.buildResourceURIFromLegacyQuery()
|
||||
}
|
||||
|
||||
chartDef, err := json.Marshal(map[string]interface{}{
|
||||
"v2charts": []interface{}{
|
||||
map[string]interface{}{
|
||||
@ -467,3 +482,20 @@ func toGrafanaUnit(unit string) string {
|
||||
// 1. Do not have a corresponding unit in Grafana's current list.
|
||||
// 2. Do not have the unit listed in any of Azure Monitor's supported metrics anyways.
|
||||
}
|
||||
|
||||
func extractResourceNameFromMetricsURL(url string) string {
|
||||
matches := resourceNameLandmark.FindStringSubmatch(url)
|
||||
resourceName := ""
|
||||
|
||||
if matches == nil {
|
||||
return resourceName
|
||||
}
|
||||
|
||||
for i, name := range resourceNameLandmark.SubexpNames() {
|
||||
if name == "resourceName" {
|
||||
resourceName = matches[i]
|
||||
}
|
||||
}
|
||||
|
||||
return resourceName
|
||||
}
|
||||
|
@ -38,19 +38,22 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorVariedProperties map[string]interface{}
|
||||
azureMonitorQueryTarget string
|
||||
expectedInterval string
|
||||
resourceURI string
|
||||
queryInterval time.Duration
|
||||
}{
|
||||
{
|
||||
name: "Parse queries from frontend and build AzureMonitor API queries",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"top": "10",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
"timeGrain": "PT1M",
|
||||
"top": "10",
|
||||
},
|
||||
resourceURI: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
expectedInterval: "PT1M",
|
||||
azureMonitorQueryTarget: "aggregation=Average&api-version=2018-01-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z",
|
||||
},
|
||||
{
|
||||
name: "time grain set to auto",
|
||||
name: "legacy query without resourceURI and time grain set to auto",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "auto",
|
||||
"top": "10",
|
||||
@ -60,7 +63,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "aggregation=Average&api-version=2018-01-01&interval=PT15M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z",
|
||||
},
|
||||
{
|
||||
name: "time grain set to auto",
|
||||
name: "legacy query without resourceURI and time grain set to auto",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "auto",
|
||||
"allowedTimeGrainsMs": []int64{60000, 300000},
|
||||
@ -71,7 +74,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "aggregation=Average&api-version=2018-01-01&interval=PT5M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z",
|
||||
},
|
||||
{
|
||||
name: "has a dimension filter",
|
||||
name: "legacy query without resourceURI and has a dimension filter",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"dimension": "blob",
|
||||
@ -83,7 +86,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "%24filter=blob+eq+%27%2A%27&aggregation=Average&api-version=2018-01-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30",
|
||||
},
|
||||
{
|
||||
name: "has a dimension filter and none Dimension",
|
||||
name: "legacy query without resourceURI and has a dimension filter and none Dimension",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"dimension": "None",
|
||||
@ -95,7 +98,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "aggregation=Average&api-version=2018-01-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z",
|
||||
},
|
||||
{
|
||||
name: "has dimensionFilter*s* property with one dimension",
|
||||
name: "legacy query without resourceURI and has dimensionFilter*s* property with one dimension",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"dimensionFilters": []types.AzureMonitorDimensionFilter{{Dimension: "blob", Operator: "eq", Filter: "*"}},
|
||||
@ -106,7 +109,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "%24filter=blob+eq+%27%2A%27&aggregation=Average&api-version=2018-01-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30",
|
||||
},
|
||||
{
|
||||
name: "has dimensionFilter*s* property with two dimensions",
|
||||
name: "legacy query without resourceURI and has dimensionFilter*s* property with two dimensions",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"dimensionFilters": []types.AzureMonitorDimensionFilter{{Dimension: "blob", Operator: "eq", Filter: "*"}, {Dimension: "tier", Operator: "eq", Filter: "*"}},
|
||||
@ -117,7 +120,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQueryTarget: "%24filter=blob+eq+%27%2A%27+and+tier+eq+%27%2A%27&aggregation=Average&api-version=2018-01-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute-virtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30",
|
||||
},
|
||||
{
|
||||
name: "has a dimension filter without specifying a top",
|
||||
name: "legacy query without resourceURI and has a dimension filter without specifying a top",
|
||||
azureMonitorVariedProperties: map[string]interface{}{
|
||||
"timeGrain": "PT1M",
|
||||
"dimension": "blob",
|
||||
@ -165,6 +168,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
azureMonitorQuery := &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceURI": tt.resourceURI,
|
||||
"metricDefinition": "Microsoft.Compute/virtualMachines",
|
||||
"resourceGroup": "grafanastaging",
|
||||
"resourceName": "grafana",
|
||||
@ -214,19 +218,19 @@ func makeTestDataLink(url string) data.DataLink {
|
||||
func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
// datalinks for the test frames
|
||||
averageLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F%2FresourceGroups%2F%2Fproviders%2F%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
totalLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F%2FresourceGroups%2F%2Fproviders%2F%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
maxLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F%2FresourceGroups%2F%2Fproviders%2F%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
minLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F%2FresourceGroups%2F%2Fproviders%2F%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
countLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F%2FresourceGroups%2F%2Fproviders%2F%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
|
||||
tests := []struct {
|
||||
@ -242,6 +246,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
@ -263,6 +268,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
@ -284,6 +290,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Maximum"},
|
||||
@ -305,6 +312,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Minimum"},
|
||||
@ -326,6 +334,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Count"},
|
||||
@ -347,6 +356,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
@ -382,6 +392,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
@ -404,6 +415,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Alias: "{{dimensionname}}={{DimensionValue}}",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
@ -441,6 +453,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Alias: "{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{Tier}}}",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
@ -479,6 +492,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Alias: "custom",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceName": "grafana",
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
@ -494,6 +508,57 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
}).SetConfig(&data.FieldConfig{DisplayName: "custom", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with legacy azure monitor query properties and without a resource uri",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
UrlComponents: map[string]string{
|
||||
"subscription": "12345678-aaaa-bbbb-cccc-123456789abc",
|
||||
"resourceGroup": "grafanastaging",
|
||||
"metricDefinition": "Microsoft.Compute/virtualMachines",
|
||||
"resourceName": "grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
ptr.Float64(8.26), ptr.Float64(8.7), ptr.Float64(14.82), ptr.Float64(10.07), ptr.Float64(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", DisplayName: "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with legacy azure monitor query properties and with a resource uri it should use the resource uri",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
UrlComponents: map[string]string{
|
||||
"resourceURI": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana",
|
||||
"subscription": "12345678-aaaa-bbbb-cccc-123456789abc-nope",
|
||||
"resourceGroup": "grafanastaging-nope",
|
||||
"metricDefinition": "Microsoft.Compute/virtualMachines-nope",
|
||||
"resourceName": "grafana",
|
||||
},
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
ptr.Float64(8.26), ptr.Float64(8.7), ptr.Float64(14.82), ptr.Float64(10.07), ptr.Float64(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", DisplayName: "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
datasource := &AzureMonitorDatasource{}
|
||||
@ -609,3 +674,21 @@ func TestAzureMonitorCreateRequest(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractResourceNameFromMetricsURL(t *testing.T) {
|
||||
t.Run("it should extract the resourceName from a well-formed Metrics URL", func(t *testing.T) {
|
||||
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/providers/microsoft.insights/metrics"
|
||||
expected := "Grafana-Test.VM"
|
||||
require.Equal(t, expected, extractResourceNameFromMetricsURL((url)))
|
||||
})
|
||||
t.Run("it should extract the resourceName from a well-formed Metrics URL in a case insensitive manner", func(t *testing.T) {
|
||||
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/pRoViDeRs/MiCrOsOfT.iNsIgHtS/mEtRiCs"
|
||||
expected := "Grafana-Test.VM"
|
||||
require.Equal(t, expected, extractResourceNameFromMetricsURL((url)))
|
||||
})
|
||||
t.Run("it should return an empty string if no match is found", func(t *testing.T) {
|
||||
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/providers/microsoft.insights/nope-this-part-does-not-match"
|
||||
expected := ""
|
||||
require.Equal(t, expected, extractResourceNameFromMetricsURL((url)))
|
||||
})
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ type urlBuilder struct {
|
||||
ResourceName string
|
||||
}
|
||||
|
||||
func (params *urlBuilder) buildMetricsURLFromLegacyQuery() string {
|
||||
func (params *urlBuilder) buildResourceURIFromLegacyQuery() string {
|
||||
subscription := params.Subscription
|
||||
|
||||
if params.Subscription == "" {
|
||||
@ -54,7 +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 == "" {
|
||||
resourceURI = params.buildMetricsURLFromLegacyQuery()
|
||||
resourceURI = params.buildResourceURIFromLegacyQuery()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/providers/microsoft.insights/metrics", resourceURI)
|
||||
|
Loading…
Reference in New Issue
Block a user