mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor and GCM: Replace deprecated experimental/errorsource (#97360)
* Update cloud monitoring * Update azure monitor * Update test
This commit is contained in:
parent
1fc9b4bfc1
commit
9a3f8c93dc
@ -18,7 +18,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
@ -142,12 +141,12 @@ func (e *AzureLogAnalyticsDatasource) ExecuteTimeSeriesQuery(ctx context.Context
|
||||
for _, query := range originalQueries {
|
||||
logsQuery, err := e.buildQuery(ctx, query, dsInfo, fromAlert)
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
||||
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
continue
|
||||
}
|
||||
res, err := e.executeQuery(ctx, logsQuery, dsInfo, client, url)
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
||||
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
continue
|
||||
}
|
||||
result.Responses[query.RefID] = *res
|
||||
@ -252,7 +251,7 @@ func (e *AzureLogAnalyticsDatasource) buildQuery(ctx context.Context, query back
|
||||
cfg := backend.GrafanaConfigFromContext(ctx)
|
||||
hasPromExemplarsToggle := cfg.FeatureToggles().IsEnabled("azureMonitorPrometheusExemplars")
|
||||
if !hasPromExemplarsToggle {
|
||||
return nil, errorsource.DownstreamError(fmt.Errorf("query type unsupported as azureMonitorPrometheusExemplars feature toggle is not enabled"), false)
|
||||
return nil, backend.DownstreamError(fmt.Errorf("query type unsupported as azureMonitorPrometheusExemplars feature toggle is not enabled"))
|
||||
}
|
||||
}
|
||||
azureAppInsightsQuery, err := buildAppInsightsQuery(ctx, query, dsInfo, appInsightsRegExp, e.Logger)
|
||||
@ -269,7 +268,7 @@ func (e *AzureLogAnalyticsDatasource) buildQuery(ctx context.Context, query back
|
||||
func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *AzureLogAnalyticsQuery, dsInfo types.DatasourceInfo, client *http.Client, url string) (*backend.DataResponse, error) {
|
||||
// If azureLogAnalyticsSameAs is defined and set to false, return an error
|
||||
if sameAs, ok := dsInfo.JSONData["azureLogAnalyticsSameAs"]; ok && !sameAs.(bool) {
|
||||
return nil, errorsource.DownstreamError(fmt.Errorf("credentials for Log Analytics are no longer supported. Go to the data source configuration to update Azure Monitor credentials"), false)
|
||||
return nil, backend.DownstreamError(fmt.Errorf("credentials for Log Analytics are no longer supported. Go to the data source configuration to update Azure Monitor credentials"))
|
||||
}
|
||||
|
||||
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||
@ -280,7 +279,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
|
||||
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
|
||||
if query.ResultFormat == dataquery.ResultFormatTrace && query.Query == "" {
|
||||
return nil, errorsource.DownstreamError(fmt.Errorf("cannot visualise trace events using the trace visualiser"), false)
|
||||
return nil, backend.DownstreamError(fmt.Errorf("cannot visualise trace events using the trace visualiser"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,7 +300,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, errorsource.DownstreamError(err, false)
|
||||
return nil, backend.DownstreamError(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@ -597,11 +596,11 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
|
||||
|
||||
res, err := azMonService.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
|
||||
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
|
||||
}
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return AzureCorrelationAPIResponse{}, errorsource.DownstreamError(err, false)
|
||||
return AzureCorrelationAPIResponse{}, backend.DownstreamError(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@ -611,7 +610,7 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
return AzureCorrelationAPIResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
|
||||
return AzureCorrelationAPIResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
|
||||
}
|
||||
var data AzureCorrelationAPIResponse
|
||||
d := json.NewDecoder(bytes.NewReader(body))
|
||||
@ -675,7 +674,7 @@ func (e *AzureLogAnalyticsDatasource) unmarshalResponse(res *http.Response) (Azu
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
return AzureLogAnalyticsResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
|
||||
return AzureLogAnalyticsResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
|
||||
}
|
||||
|
||||
var data AzureLogAnalyticsResponse
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
)
|
||||
|
||||
@ -47,18 +47,18 @@ func AddConfigLinks(frame data.Frame, dl string, title *string) data.Frame {
|
||||
// 4. the ds toggle is set to true
|
||||
func meetsBasicLogsCriteria(resources []string, fromAlert bool, basicLogsEnabled bool) (bool, error) {
|
||||
if fromAlert {
|
||||
return false, errorsource.DownstreamError(fmt.Errorf("basic Logs queries cannot be used for alerts"), false)
|
||||
return false, backend.DownstreamError(fmt.Errorf("basic Logs queries cannot be used for alerts"))
|
||||
}
|
||||
if len(resources) != 1 {
|
||||
return false, errorsource.DownstreamError(fmt.Errorf("basic logs queries cannot be run against multiple resources"), false)
|
||||
return false, backend.DownstreamError(fmt.Errorf("basic logs queries cannot be run against multiple resources"))
|
||||
}
|
||||
|
||||
if !strings.Contains(strings.ToLower(resources[0]), "microsoft.operationalinsights/workspaces") {
|
||||
return false, errorsource.DownstreamError(fmt.Errorf("basic logs queries may only be run against Log Analytics workspaces"), false)
|
||||
return false, backend.DownstreamError(fmt.Errorf("basic logs queries may only be run against Log Analytics workspaces"))
|
||||
}
|
||||
|
||||
if !basicLogsEnabled {
|
||||
return false, errorsource.DownstreamError(fmt.Errorf("basic Logs queries are disabled for this data source"), false)
|
||||
return false, backend.DownstreamError(fmt.Errorf("basic Logs queries are disabled for this data source"))
|
||||
}
|
||||
|
||||
return true, nil
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
@ -25,6 +24,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/loganalytics"
|
||||
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/utils"
|
||||
)
|
||||
|
||||
// AzureMonitorDatasource calls the Azure Monitor API - one of the four API's supported
|
||||
@ -55,12 +55,12 @@ func (e *AzureMonitorDatasource) ExecuteTimeSeriesQuery(ctx context.Context, ori
|
||||
for _, query := range originalQueries {
|
||||
azureQuery, err := e.buildQuery(query, dsInfo)
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
||||
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
continue
|
||||
}
|
||||
res, err := e.executeQuery(ctx, azureQuery, dsInfo, client, url)
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(query.RefID, result, err)
|
||||
result.Responses[query.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
continue
|
||||
}
|
||||
result.Responses[query.RefID] = *res
|
||||
@ -284,7 +284,7 @@ func (e *AzureMonitorDatasource) retrieveSubscriptionDetails(cli *http.Client, c
|
||||
}
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
return "", errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, error: %s", res.Status, string(body)), false)
|
||||
return "", utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
|
||||
}
|
||||
|
||||
var data types.SubscriptionsResponse
|
||||
@ -321,7 +321,7 @@ func (e *AzureMonitorDatasource) executeQuery(ctx context.Context, query *types.
|
||||
|
||||
res, err := cli.Do(req)
|
||||
if err != nil {
|
||||
return nil, errorsource.DownstreamError(err, false)
|
||||
return nil, backend.DownstreamError(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@ -366,7 +366,7 @@ func (e *AzureMonitorDatasource) unmarshalResponse(res *http.Response) (types.Az
|
||||
}
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
return types.AzureMonitorResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body)), false)
|
||||
return types.AzureMonitorResponse{}, utils.CreateResponseErrorFromStatusCode(res.StatusCode, res.Status, body)
|
||||
}
|
||||
|
||||
var data types.AzureMonitorResponse
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
@ -78,3 +79,11 @@ func ApplySourceFromError(errorMessage error, err error) error {
|
||||
}
|
||||
return errorMessage
|
||||
}
|
||||
|
||||
func CreateResponseErrorFromStatusCode(statusCode int, status string, body []byte) error {
|
||||
statusErr := fmt.Errorf("request failed, status: %s, body: %s", status, string(body))
|
||||
if backend.ErrorSourceFromHTTPStatus(statusCode) == backend.ErrorSourceDownstream {
|
||||
return backend.DownstreamError(statusErr)
|
||||
}
|
||||
return backend.PluginError(statusErr)
|
||||
}
|
||||
|
59
pkg/tsdb/azuremonitor/utils/utils_test.go
Normal file
59
pkg/tsdb/azuremonitor/utils/utils_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateResponseErrorFromStatusCode(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
statusCode int
|
||||
status string
|
||||
body []byte
|
||||
expectedErrMessage string
|
||||
expectedType backend.ErrorSource
|
||||
}{
|
||||
{
|
||||
name: "Downstream error for 500 status",
|
||||
statusCode: 500,
|
||||
status: "500 Internal Server Error",
|
||||
body: []byte("body bytes"),
|
||||
expectedErrMessage: "request failed, status: 500 Internal Server Error, body: body bytes",
|
||||
expectedType: backend.ErrorSourceDownstream,
|
||||
},
|
||||
{
|
||||
name: "Plugin error for 501 status",
|
||||
statusCode: 501,
|
||||
status: "501 Not Implemented",
|
||||
body: []byte("body bytes"),
|
||||
expectedErrMessage: "request failed, status: 501 Not Implemented, body: body bytes",
|
||||
expectedType: backend.ErrorSourcePlugin,
|
||||
},
|
||||
{
|
||||
name: "Downstream error for 502 status",
|
||||
statusCode: 502,
|
||||
status: "502 Gateway Error",
|
||||
body: []byte("body bytes"),
|
||||
expectedErrMessage: "request failed, status: 502 Gateway Error, body: body bytes",
|
||||
expectedType: backend.ErrorSourceDownstream,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := CreateResponseErrorFromStatusCode(tt.statusCode, tt.status, tt.body)
|
||||
assert.Error(t, err)
|
||||
// Check if error is of type ErrorWithSource
|
||||
var errorWithSource backend.ErrorWithSource
|
||||
assert.True(t, errors.As(err, &errorWithSource))
|
||||
|
||||
// Validate the source of the error
|
||||
assert.Equal(t, tt.expectedType, errorWithSource.ErrorSource())
|
||||
assert.Contains(t, err.Error(), tt.expectedErrMessage)
|
||||
})
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
)
|
||||
|
||||
type annotationEvent struct {
|
||||
@ -25,10 +24,10 @@ func (s *Service) executeAnnotationQuery(ctx context.Context, req *backend.Query
|
||||
resp := backend.NewQueryDataResponse()
|
||||
dr, queryRes, _, err := queries[0].run(ctx, req, s, dsInfo, logger)
|
||||
if dr.Error != nil {
|
||||
errorsource.AddErrorToResponse(queries[0].getRefID(), resp, dr.Error)
|
||||
resp.Responses[queries[0].getRefID()] = backend.ErrorResponseWithErrorSource(dr.Error)
|
||||
}
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(queries[0].getRefID(), resp, err)
|
||||
resp.Responses[queries[0].getRefID()] = backend.ErrorResponseWithErrorSource(err)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@ -43,7 +42,7 @@ func (s *Service) executeAnnotationQuery(ctx context.Context, req *backend.Query
|
||||
err = json.Unmarshal(firstQuery.JSON, &tslq)
|
||||
if err != nil {
|
||||
logger.Error("error unmarshaling query", "error", err, "statusSource", backend.ErrorSourceDownstream)
|
||||
errorsource.AddErrorToResponse(firstQuery.RefID, resp, err)
|
||||
resp.Responses[firstQuery.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@ -52,7 +51,7 @@ func (s *Service) executeAnnotationQuery(ctx context.Context, req *backend.Query
|
||||
resp.Responses[firstQuery.RefID] = *dr
|
||||
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(firstQuery.RefID, resp, err)
|
||||
resp.Responses[firstQuery.RefID] = backend.ErrorResponseWithErrorSource(err)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloud-monitoring/kinds/dataquery"
|
||||
)
|
||||
@ -363,16 +362,16 @@ func (s *Service) executeTimeSeriesQuery(ctx context.Context, req *backend.Query
|
||||
for _, queryExecutor := range queries {
|
||||
dr, queryRes, executedQueryString, err := queryExecutor.run(ctx, req, s, dsInfo, logger)
|
||||
if err != nil {
|
||||
errorsource.AddErrorToResponse(queryExecutor.getRefID(), resp, err)
|
||||
resp.Responses[queryExecutor.getRefID()] = backend.ErrorResponseWithErrorSource(err)
|
||||
return resp, err
|
||||
}
|
||||
err = queryExecutor.parseResponse(dr, queryRes, executedQueryString, logger)
|
||||
if err != nil {
|
||||
dr.Error = err
|
||||
// // Default to a plugin error if there's no source
|
||||
errWithSource := errorsource.SourceError(backend.ErrorSourcePlugin, err, false)
|
||||
dr.Error = errWithSource.Unwrap()
|
||||
dr.ErrorSource = errWithSource.ErrorSource()
|
||||
// If the error is a downstream error, set the error source
|
||||
if backend.IsDownstreamError(err) {
|
||||
dr.ErrorSource = backend.ErrorSourceDownstream
|
||||
}
|
||||
}
|
||||
|
||||
resp.Responses[queryExecutor.getRefID()] = *dr
|
||||
@ -592,7 +591,7 @@ func (s *Service) getDefaultProject(ctx context.Context, dsInfo datasourceInfo)
|
||||
if dsInfo.authenticationType == gceAuthentication {
|
||||
project, err := s.gceDefaultProjectGetter(ctx, cloudMonitorScope)
|
||||
if err != nil {
|
||||
return project, errorsource.DownstreamError(err, false)
|
||||
return project, backend.DownstreamError(err)
|
||||
}
|
||||
return project, nil
|
||||
}
|
||||
@ -613,7 +612,11 @@ func unmarshalResponse(res *http.Response, logger log.Logger) (cloudMonitoringRe
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
logger.Error("Request failed", "status", res.Status, "body", string(body), "statusSource", backend.ErrorSourceDownstream)
|
||||
return cloudMonitoringResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("query failed: %s", string(body)), false)
|
||||
statusErr := fmt.Errorf("query failed: %s", string(body))
|
||||
if backend.ErrorSourceFromHTTPStatus(res.StatusCode) == backend.ErrorSourceDownstream {
|
||||
return cloudMonitoringResponse{}, backend.DownstreamError(statusErr)
|
||||
}
|
||||
return cloudMonitoringResponse{}, backend.PluginError(statusErr)
|
||||
}
|
||||
|
||||
var data cloudMonitoringResponse
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloud-monitoring/converter"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
@ -68,7 +67,7 @@ func doRequestProm(r *http.Request, dsInfo datasourceInfo, body map[string]any)
|
||||
}
|
||||
res, err := dsInfo.services[cloudMonitor].client.Do(r)
|
||||
if err != nil {
|
||||
return res, errorsource.DownstreamError(err, false)
|
||||
return res, backend.DownstreamError(err)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
@ -85,7 +84,7 @@ func doRequestPage(_ context.Context, r *http.Request, dsInfo datasourceInfo, pa
|
||||
}
|
||||
res, err := dsInfo.services[cloudMonitor].client.Do(r)
|
||||
if err != nil {
|
||||
return cloudMonitoringResponse{}, errorsource.DownstreamError(err, false)
|
||||
return cloudMonitoringResponse{}, backend.DownstreamError(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
|
Loading…
Reference in New Issue
Block a user