mirror of
https://github.com/grafana/grafana.git
synced 2026-08-11 05:34:53 -05:00
AzureMonitor: Support querying any Resource for Logs queries (#33879)
* wip * wip: * ui work for resource picker * disable rows when others are selected * resource picker open button * Azure Monitor: Connect to backend with real data (#34024) * Connect to backend with real data * Fixes from code review. * WIP:Begin thinking about how to make queries with scope determined by the resource picker * More fixes post code review. * Fixes after rebasing * Remove outdated todo * AzureMonitor: Support any resource for Logs queries (#33762) * Apply button for resource picker * scroll table body * secondary cancel button * loading state for nested rows * Display resource components in picker button * fix tests * fix icons * move route function * Migrate from workspace to resource uri for log analytics (#34337) * reword backwards compat comment * remove base url suffix * fix lint error * move migrations to seperate file * cleanup * update regex * cleanup * update plugin routes to use new azure auth type * use AzureDataSourceInstanceSettings alias Co-authored-by: Sarah Zinger <sarahzinger@users.noreply.github.com>
This commit is contained in:
co-authored by
Sarah Zinger
parent
c61dd82163
commit
5dca9fd4d8
@@ -89,9 +89,13 @@ func (e *AzureLogAnalyticsDatasource) buildQueries(queries []plugins.DataSubQuer
|
||||
resultFormat = timeSeries
|
||||
}
|
||||
|
||||
urlComponents := map[string]string{}
|
||||
urlComponents["workspace"] = azureLogAnalyticsTarget.Workspace
|
||||
apiURL := fmt.Sprintf("%s/query", urlComponents["workspace"])
|
||||
// Handle legacy queries without a Resource
|
||||
var apiURL string
|
||||
if azureLogAnalyticsTarget.Resource != "" {
|
||||
apiURL = fmt.Sprintf("v1%s/query", azureLogAnalyticsTarget.Resource)
|
||||
} else {
|
||||
apiURL = fmt.Sprintf("v1/workspaces/%s/query", azureLogAnalyticsTarget.Workspace)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
rawQuery, err := KqlInterpolate(query, timeRange, azureLogAnalyticsTarget.Query, "TimeGenerated")
|
||||
|
||||
@@ -32,6 +32,45 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(34*time.Minute).Unix()*1000),
|
||||
},
|
||||
queryModel: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{}),
|
||||
},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"queryType": "Azure Log Analytics",
|
||||
"azureLogAnalytics": map[string]interface{}{
|
||||
"resource": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace",
|
||||
"query": "query=Perf | where $__timeFilter() | where $__contains(Computer, 'comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer",
|
||||
"resultFormat": timeSeries,
|
||||
},
|
||||
}),
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: timeSeries,
|
||||
URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query",
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"azureLogAnalytics": map[string]interface{}{
|
||||
"query": "query=Perf | where $__timeFilter() | where $__contains(Computer, 'comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer",
|
||||
"resultFormat": timeSeries,
|
||||
"workspace": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
||||
},
|
||||
}),
|
||||
Params: url.Values{"query": {"query=Perf | where ['TimeGenerated'] >= datetime('2018-03-15T13:00:00Z') and ['TimeGenerated'] <= datetime('2018-03-15T13:34:00Z') | where ['Computer'] in ('comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, 34000ms), Computer"}},
|
||||
Target: "query=query%3DPerf+%7C+where+%5B%27TimeGenerated%27%5D+%3E%3D+datetime%28%272018-03-15T13%3A00%3A00Z%27%29+and+%5B%27TimeGenerated%27%5D+%3C%3D+datetime%28%272018-03-15T13%3A34%3A00Z%27%29+%7C+where+%5B%27Computer%27%5D+in+%28%27comp1%27%2C%27comp2%27%29+%7C+summarize+avg%28CounterValue%29+by+bin%28TimeGenerated%2C+34000ms%29%2C+Computer",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
}, {
|
||||
name: "Legacy workspace queries should use workspace query endpoint",
|
||||
timeRange: plugins.DataTimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(34*time.Minute).Unix()*1000),
|
||||
},
|
||||
queryModel: []plugins.DataSubQuery{
|
||||
{
|
||||
DataSource: &models.DataSource{
|
||||
@@ -52,7 +91,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: timeSeries,
|
||||
URL: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/query",
|
||||
URL: "v1/workspaces/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/query",
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"azureLogAnalytics": map[string]interface{}{
|
||||
"query": "query=Perf | where $__timeFilter() | where $__contains(Computer, 'comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer",
|
||||
@@ -92,7 +131,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
{
|
||||
Path: "loganalyticsazure",
|
||||
Method: "GET",
|
||||
URL: "https://api.loganalytics.io/v1/workspaces",
|
||||
URL: "https://api.loganalytics.io/",
|
||||
Headers: []plugins.AppPluginRouteHeader{
|
||||
{Name: "x-ms-app", Content: "Grafana"},
|
||||
},
|
||||
@@ -100,7 +139,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
{
|
||||
Path: "chinaloganalyticsazure",
|
||||
Method: "GET",
|
||||
URL: "https://api.loganalytics.azure.cn/v1/workspaces",
|
||||
URL: "https://api.loganalytics.azure.cn/",
|
||||
Headers: []plugins.AppPluginRouteHeader{
|
||||
{Name: "x-ms-app", Content: "Grafana"},
|
||||
},
|
||||
@@ -108,7 +147,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
{
|
||||
Path: "govloganalyticsazure",
|
||||
Method: "GET",
|
||||
URL: "https://api.loganalytics.us/v1/workspaces",
|
||||
URL: "https://api.loganalytics.us/",
|
||||
Headers: []plugins.AppPluginRouteHeader{
|
||||
{Name: "x-ms-app", Content: "Grafana"},
|
||||
},
|
||||
@@ -135,7 +174,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedProxypass: "loganalyticsazure",
|
||||
expectedRouteURL: "https://api.loganalytics.io/v1/workspaces",
|
||||
expectedRouteURL: "https://api.loganalytics.io/",
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
@@ -150,7 +189,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedProxypass: "chinaloganalyticsazure",
|
||||
expectedRouteURL: "https://api.loganalytics.azure.cn/v1/workspaces",
|
||||
expectedRouteURL: "https://api.loganalytics.azure.cn/",
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
@@ -165,7 +204,7 @@ func TestPluginRoutes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedProxypass: "govloganalyticsazure",
|
||||
expectedRouteURL: "https://api.loganalytics.us/v1/workspaces",
|
||||
expectedRouteURL: "https://api.loganalytics.us/",
|
||||
Err: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -138,7 +138,10 @@ type logJSONQuery struct {
|
||||
AzureLogAnalytics struct {
|
||||
Query string `json:"query"`
|
||||
ResultFormat string `json:"resultFormat"`
|
||||
Workspace string `json:"workspace"`
|
||||
Resource string `json:"resource"`
|
||||
|
||||
// Deprecated: Queries should be migrated to use Resource instead
|
||||
Workspace string `json:"workspace"`
|
||||
} `json:"azureLogAnalytics"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user