Cloudwatch: Accept empty string for logstimeout and mark errors downstream (#96947)

This commit is contained in:
Isabella Siu 2024-12-03 15:02:52 -05:00 committed by GitHub
parent 7fd8877439
commit f4e108c34f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 36 additions and 5 deletions

View File

@ -59,7 +59,8 @@ func (e *cloudWatchExecutor) executeAnnotationQuery(ctx context.Context, pluginC
cli, err := e.getCWClient(ctx, pluginCtx, region) cli, err := e.getCWClient(ctx, pluginCtx, region)
if err != nil { if err != nil {
return nil, err result = errorsource.AddDownstreamErrorToResponse(query.RefID, result, fmt.Errorf("%v: %w", "failed to get client", err))
return result, nil
} }
var alarmNames []*string var alarmNames []*string

View File

@ -24,7 +24,8 @@ var executeSyncLogQuery = func(ctx context.Context, e *cloudWatchExecutor, req *
instance, err := e.getInstance(ctx, req.PluginContext) instance, err := e.getInstance(ctx, req.PluginContext)
if err != nil { if err != nil {
return nil, err errorsource.AddErrorToResponse(req.Queries[0].RefID, resp, err)
return resp, nil
} }
for _, q := range req.Queries { for _, q := range req.Queries {

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana-aws-sdk/pkg/awsds" "github.com/grafana/grafana-aws-sdk/pkg/awsds"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
) )
type Duration struct { type Duration struct {
@ -61,13 +62,16 @@ func (duration *Duration) UnmarshalJSON(b []byte) error {
case float64: case float64:
*duration = Duration{time.Duration(value)} *duration = Duration{time.Duration(value)}
case string: case string:
if value == "" {
return nil
}
dur, err := time.ParseDuration(value) dur, err := time.ParseDuration(value)
if err != nil { if err != nil {
return err return errorsource.DownstreamError(err, false)
} }
*duration = Duration{dur} *duration = Duration{dur}
default: default:
return fmt.Errorf("invalid duration: %#v", unmarshalledJson) return errorsource.DownstreamError(fmt.Errorf("invalid duration: %#v", unmarshalledJson), false)
} }
return nil return nil

View File

@ -2,12 +2,14 @@ package models
import ( import (
"context" "context"
"errors"
"testing" "testing"
"time" "time"
"github.com/grafana/grafana-aws-sdk/pkg/awsds" "github.com/grafana/grafana-aws-sdk/pkg/awsds"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/proxy" "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -114,6 +116,24 @@ func Test_Settings_LoadCloudWatchSettings(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, time.Minute*30, s.LogsTimeout.Duration) assert.Equal(t, time.Minute*30, s.LogsTimeout.Duration)
}) })
t.Run("Should set logsTimeout to default duration if it is empty string", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": ""
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
s, err := LoadCloudWatchSettings(settingCtx, settings)
require.NoError(t, err)
assert.Equal(t, time.Minute*30, s.LogsTimeout.Duration)
})
t.Run("Should correctly parse logsTimeout duration string", func(t *testing.T) { t.Run("Should correctly parse logsTimeout duration string", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{ settings := backend.DataSourceInstanceSettings{
ID: 33, ID: 33,
@ -184,6 +204,10 @@ func Test_Settings_LoadCloudWatchSettings(t *testing.T) {
_, err := LoadCloudWatchSettings(context.Background(), settings) _, err := LoadCloudWatchSettings(context.Background(), settings)
require.Error(t, err) require.Error(t, err)
var sourceErr errorsource.Error
ok := errors.As(err, &sourceErr)
require.True(t, ok)
require.Equal(t, sourceErr.ErrorSource().String(), "downstream")
}) })
t.Run("Should throw error if logsTimeout is an invalid type", func(t *testing.T) { t.Run("Should throw error if logsTimeout is an invalid type", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{ settings := backend.DataSourceInstanceSettings{

View File

@ -35,7 +35,8 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, req *ba
instance, err := e.getInstance(ctx, req.PluginContext) instance, err := e.getInstance(ctx, req.PluginContext)
if err != nil { if err != nil {
return nil, err errorsource.AddErrorToResponse(req.Queries[0].RefID, resp, err)
return resp, nil
} }
requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime, instance.Settings.Region, e.logger.FromContext(ctx), requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime, instance.Settings.Region, e.logger.FromContext(ctx),