mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor: Support multi-resource aliases and subscription aliases (#68648)
Update legend aliases - Add subscription response type - Update AzureMonitorQuery type - Update docs - Update tests - Add function to retrieve subscription display name if not present
This commit is contained in:
@@ -42,6 +42,8 @@ func (e *AzureMonitorDatasource) ResourceRequest(rw http.ResponseWriter, req *ht
|
||||
e.Proxy.Do(rw, req, cli)
|
||||
}
|
||||
|
||||
var subscriptions = map[string]string{}
|
||||
|
||||
// executeTimeSeriesQuery does the following:
|
||||
// 1. build the AzureMonitor url and querystring for each query
|
||||
// 2. executes each query by calling the Azure Monitor API
|
||||
@@ -112,6 +114,7 @@ func (e *AzureMonitorDatasource) buildQueries(logger log.Logger, queries []backe
|
||||
params.Add("region", azJSONModel.Region)
|
||||
}
|
||||
resourceIDs := []string{}
|
||||
resourceMap := map[string]types.AzureMonitorResource{}
|
||||
if hasOne, resourceGroup, resourceName := hasOneResource(queryJSONModel); hasOne {
|
||||
ub := urlBuilder{
|
||||
ResourceURI: azJSONModel.ResourceURI,
|
||||
@@ -125,6 +128,7 @@ func (e *AzureMonitorDatasource) buildQueries(logger log.Logger, queries []backe
|
||||
azureURL = ub.BuildMetricsURL()
|
||||
// POST requests are only supported at the subscription level
|
||||
filterInBody = false
|
||||
resourceMap[ub.buildResourceURI()] = types.AzureMonitorResource{ResourceGroup: resourceGroup, ResourceName: resourceName}
|
||||
} else {
|
||||
for _, r := range azJSONModel.Resources {
|
||||
ub := urlBuilder{
|
||||
@@ -134,7 +138,9 @@ func (e *AzureMonitorDatasource) buildQueries(logger log.Logger, queries []backe
|
||||
MetricNamespace: azJSONModel.MetricNamespace,
|
||||
ResourceName: r.ResourceName,
|
||||
}
|
||||
resourceIDs = append(resourceIDs, fmt.Sprintf("Microsoft.ResourceId eq '%s'", ub.buildResourceURI()))
|
||||
resourceUri := ub.buildResourceURI()
|
||||
resourceMap[resourceUri] = r
|
||||
resourceIDs = append(resourceIDs, fmt.Sprintf("Microsoft.ResourceId eq '%s'", resourceUri))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,13 +186,15 @@ func (e *AzureMonitorDatasource) buildQueries(logger log.Logger, queries []backe
|
||||
}
|
||||
|
||||
query := &types.AzureMonitorQuery{
|
||||
URL: azureURL,
|
||||
Target: target,
|
||||
Params: params,
|
||||
RefID: query.RefID,
|
||||
Alias: alias,
|
||||
TimeRange: query.TimeRange,
|
||||
Dimensions: azJSONModel.DimensionFilters,
|
||||
URL: azureURL,
|
||||
Target: target,
|
||||
Params: params,
|
||||
RefID: query.RefID,
|
||||
Alias: alias,
|
||||
TimeRange: query.TimeRange,
|
||||
Dimensions: azJSONModel.DimensionFilters,
|
||||
Resources: resourceMap,
|
||||
Subscription: queryJSONModel.Subscription,
|
||||
}
|
||||
if filterString != "" {
|
||||
if filterInBody {
|
||||
@@ -201,6 +209,51 @@ func (e *AzureMonitorDatasource) buildQueries(logger log.Logger, queries []backe
|
||||
return azureMonitorQueries, nil
|
||||
}
|
||||
|
||||
func retrieveSubscriptionDetails(e *AzureMonitorDatasource, cli *http.Client, ctx context.Context, logger log.Logger, tracer tracing.Tracer, subscriptionId string, baseUrl string, dsId int64, orgId int64) {
|
||||
req, err := e.createRequest(ctx, logger, fmt.Sprintf("%s/subscriptions/%s", baseUrl, subscriptionId))
|
||||
if err != nil {
|
||||
logger.Error("failed to retrieve subscription details for subscription %s: %s", subscriptionId, err)
|
||||
}
|
||||
values := req.URL.Query()
|
||||
values.Add("api-version", "2022-12-01")
|
||||
req.URL.RawQuery = values.Encode()
|
||||
|
||||
ctx, span := tracer.Start(ctx, "azuremonitor query")
|
||||
span.SetAttributes("subscription", subscriptionId, attribute.Key("subscription").String(subscriptionId))
|
||||
span.SetAttributes("datasource_id", dsId, attribute.Key("datasource_id").Int64(dsId))
|
||||
span.SetAttributes("org_id", orgId, attribute.Key("org_id").Int64(orgId))
|
||||
|
||||
defer span.End()
|
||||
tracer.Inject(ctx, req.Header, span)
|
||||
logger.Debug("AzureMonitor", "Subscription Details Req")
|
||||
res, err := cli.Do(req)
|
||||
if err != nil {
|
||||
logger.Warn("failed to request subscription details: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
logger.Warn("failed to read response body: %s", err)
|
||||
}
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
logger.Warn("request failed, status: %s, error: %s", res.Status, string(body))
|
||||
}
|
||||
|
||||
var data types.SubscriptionsResponse
|
||||
err = json.Unmarshal(body, &data)
|
||||
if err != nil {
|
||||
logger.Warn("Failed to unmarshal subscription detail response", "error", err, "status", res.Status, "body", string(body))
|
||||
}
|
||||
|
||||
subscriptions[data.SubscriptionID] = data.DisplayName
|
||||
}
|
||||
|
||||
func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, logger log.Logger, query *types.AzureMonitorQuery, dsInfo types.DatasourceInfo, cli *http.Client,
|
||||
url string, tracer tracing.Tracer) backend.DataResponse {
|
||||
dataResponse := backend.DataResponse{}
|
||||
@@ -253,6 +306,10 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, logger log.Lo
|
||||
return dataResponse
|
||||
}
|
||||
|
||||
if _, ok := subscriptions[query.Subscription]; !ok {
|
||||
retrieveSubscriptionDetails(e, cli, ctx, logger, tracer, query.Subscription, dsInfo.Routes["Azure Monitor"].URL, dsInfo.DatasourceID, dsInfo.OrgID)
|
||||
}
|
||||
|
||||
dataResponse.Frames, err = e.parseResponse(data, query, azurePortalUrl)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
@@ -340,8 +397,9 @@ func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, q
|
||||
labels["resourceName"] = resourceName
|
||||
}
|
||||
|
||||
currentResource := query.Resources[resourceID]
|
||||
if query.Alias != "" {
|
||||
displayName := formatAzureMonitorLegendKey(query.Alias, resourceName,
|
||||
displayName := formatAzureMonitorLegendKey(query.Alias, query.Subscription, currentResource,
|
||||
amr.Value[0].Name.LocalizedValue, "", "", amr.Namespace, amr.Value[0].ID, labels)
|
||||
|
||||
if dataField.Config != nil {
|
||||
@@ -379,7 +437,6 @@ func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, q
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frameWithLink := loganalytics.AddConfigLinks(*frame, queryUrl, nil)
|
||||
frames = append(frames, &frameWithLink)
|
||||
}
|
||||
@@ -495,12 +552,8 @@ func getQueryUrl(query *types.AzureMonitorQuery, azurePortalUrl, resourceID, res
|
||||
|
||||
// formatAzureMonitorLegendKey builds the legend key or timeseries name
|
||||
// Alias patterns like {{resourcename}} are replaced with the appropriate data values.
|
||||
func formatAzureMonitorLegendKey(alias string, resourceName string, metricName string, metadataName string,
|
||||
func formatAzureMonitorLegendKey(alias string, subscriptionId string, resource types.AzureMonitorResource, metricName string, metadataName string,
|
||||
metadataValue string, namespace string, seriesID string, labels data.Labels) string {
|
||||
startIndex := strings.Index(seriesID, "/resourceGroups/") + 16
|
||||
endIndex := strings.Index(seriesID, "/providers")
|
||||
resourceGroup := seriesID[startIndex:endIndex]
|
||||
|
||||
// Could be a collision problem if there were two keys that varied only in case, but I don't think that would happen in azure.
|
||||
lowerLabels := data.Labels{}
|
||||
for k, v := range labels {
|
||||
@@ -517,8 +570,20 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
|
||||
metaPartName = strings.Replace(metaPartName, "}}", "", 1)
|
||||
metaPartName = strings.ToLower(strings.TrimSpace(metaPartName))
|
||||
|
||||
if metaPartName == "subscriptionid" {
|
||||
return []byte(subscriptionId)
|
||||
}
|
||||
|
||||
if metaPartName == "subscription" {
|
||||
if subscription, ok := subscriptions[subscriptionId]; ok {
|
||||
return []byte(subscription)
|
||||
} else {
|
||||
return []byte{}
|
||||
}
|
||||
}
|
||||
|
||||
if metaPartName == "resourcegroup" {
|
||||
return []byte(resourceGroup)
|
||||
return []byte(resource.ResourceGroup)
|
||||
}
|
||||
|
||||
if metaPartName == "namespace" {
|
||||
@@ -526,7 +591,7 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
|
||||
}
|
||||
|
||||
if metaPartName == "resourcename" {
|
||||
return []byte(resourceName)
|
||||
return []byte(resource.ResourceName)
|
||||
}
|
||||
|
||||
if metaPartName == "metric" {
|
||||
|
||||
@@ -49,6 +49,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
expectedBodyFilter string
|
||||
expectedParamFilter string
|
||||
expectedPortalURL *string
|
||||
resources map[string]types.AzureMonitorResource
|
||||
}{
|
||||
{
|
||||
name: "Parse queries from frontend and build AzureMonitor API queries",
|
||||
@@ -296,6 +297,16 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
queries, err := datasource.buildQueries(log.New("test"), tsdbQuery, dsInfo)
|
||||
require.NoError(t, err)
|
||||
|
||||
resources := map[string]types.AzureMonitorResource{}
|
||||
if tt.azureMonitorVariedProperties["resources"] != nil {
|
||||
resourceSlice := tt.azureMonitorVariedProperties["resources"].([]types.AzureMonitorResource)
|
||||
for _, resource := range resourceSlice {
|
||||
resources[fmt.Sprintf("/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", resource.ResourceGroup, resource.ResourceName)] = resource
|
||||
}
|
||||
} else {
|
||||
resources["/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana"] = types.AzureMonitorResource{ResourceGroup: "grafanastaging", ResourceName: "grafana"}
|
||||
}
|
||||
|
||||
azureMonitorQuery := &types.AzureMonitorQuery{
|
||||
URL: tt.expectedURL,
|
||||
Target: tt.azureMonitorQueryTarget,
|
||||
@@ -305,7 +316,9 @@ func TestAzureMonitorBuildQueries(t *testing.T) {
|
||||
From: fromStart,
|
||||
To: fromStart.Add(34 * time.Minute),
|
||||
},
|
||||
BodyFilter: tt.expectedBodyFilter,
|
||||
BodyFilter: tt.expectedBodyFilter,
|
||||
Subscription: "12345678-aaaa-bbbb-cccc-123456789abc",
|
||||
Resources: resources,
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.expectedParamFilter, queries[0].Params.Get("$filter"))
|
||||
@@ -354,6 +367,10 @@ func TestCustomNamespace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
resources := map[string]types.AzureMonitorResource{}
|
||||
resources["/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana"] = types.AzureMonitorResource{ResourceGroup: "grafanastaging", ResourceName: "grafana"}
|
||||
subscription := "12345678-aaaa-bbbb-cccc-123456789abc"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
responseFile string
|
||||
@@ -369,6 +386,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -379,6 +398,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -389,6 +410,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Maximum"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -399,6 +422,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Minimum"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -409,6 +434,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Count"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -419,6 +446,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -430,6 +459,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -441,17 +472,21 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple dimension time series response with label alias",
|
||||
responseFile: "azuremonitor/7-azure-monitor-response-multi-dimension.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanatest/providers/Microsoft.Storage/storageAccounts/testblobaccount/blobServices/default/providers/Microsoft.Insights/metrics",
|
||||
Alias: "{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{Tier}}}",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: map[string]types.AzureMonitorResource{"/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanatest/providers/Microsoft.Storage/storageAccounts/testblobaccount/blobServices/default/providers/Microsoft.Insights/metrics": {ResourceGroup: "grafanatest", ResourceName: "testblobaccount"}},
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -463,6 +498,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -474,6 +511,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -485,6 +524,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -495,6 +536,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -505,6 +548,8 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
Resources: resources,
|
||||
Subscription: subscription,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"interval": "PT1H",
|
||||
"value": [
|
||||
{
|
||||
"id": "/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/danieltest/providers/Microsoft.Storage/storageAccounts/danieltestdiag187/blobServices/default/providers/Microsoft.Insights/metrics/BlobCapacity",
|
||||
"id": "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanatest/providers/Microsoft.Storage/storageAccounts/testblobaccount/blobServices/default/providers/Microsoft.Insights/metrics/BlobCapacity",
|
||||
"type": "Microsoft.Insights/metrics",
|
||||
"name": {
|
||||
"value": "BlobCapacity",
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -79,13 +79,13 @@
|
||||
"tier": "Standard"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=PageBlob, Tier=Standard}",
|
||||
"displayName": "grafanatest {Blob Type=PageBlob, Tier=Standard}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -121,7 +121,7 @@
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -138,13 +138,13 @@
|
||||
"tier": "Hot"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=BlockBlob, Tier=Hot}",
|
||||
"displayName": "grafanatest {Blob Type=BlockBlob, Tier=Hot}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -180,7 +180,7 @@
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -197,13 +197,13 @@
|
||||
"tier": "Cool"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=Azure Data Lake Storage, Tier=Cool}",
|
||||
"displayName": "grafanatest {Blob Type=Azure Data Lake Storage, Tier=Cool}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "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%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"
|
||||
"url": "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%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanatest%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Ftestblobaccount%2FblobServices%2Fdefault%2Fproviders%2FMicrosoft.Insights%2Fmetrics%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%22default%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -65,14 +65,16 @@ type DatasourceInfo struct {
|
||||
// AzureMonitorQuery is the query for all the services as they have similar queries
|
||||
// with a url, a querystring and an alias field
|
||||
type AzureMonitorQuery struct {
|
||||
URL string
|
||||
Target string
|
||||
Params url.Values
|
||||
RefID string
|
||||
Alias string
|
||||
TimeRange backend.TimeRange
|
||||
BodyFilter string
|
||||
Dimensions []AzureMonitorDimensionFilter
|
||||
URL string
|
||||
Target string
|
||||
Params url.Values
|
||||
RefID string
|
||||
Alias string
|
||||
TimeRange backend.TimeRange
|
||||
BodyFilter string
|
||||
Dimensions []AzureMonitorDimensionFilter
|
||||
Resources map[string]AzureMonitorResource
|
||||
Subscription string
|
||||
}
|
||||
|
||||
// AzureMonitorResponse is the json response from the Azure Monitor API
|
||||
@@ -274,4 +276,11 @@ type LogAnalyticsWorkspaceResponse struct {
|
||||
RetentionInDays int `json:"retentionInDays"`
|
||||
}
|
||||
|
||||
type SubscriptionsResponse struct {
|
||||
ID string `json:"id"`
|
||||
SubscriptionID string `json:"subscriptionId"`
|
||||
TenantID string `json:"tenantId"`
|
||||
DisplayName string `json:"displayName"`
|
||||
}
|
||||
|
||||
var ErrorAzureHealthCheck = errors.New("health check failed")
|
||||
|
||||
Reference in New Issue
Block a user