Cloudwatch Logs: Set Alerting timeout to datasource config's logsTimeout (#72611)

This commit is contained in:
Ida Štambuk
2023-08-03 19:35:30 +02:00
committed by GitHub
parent b1ef145442
commit abff6e20e9
6 changed files with 211 additions and 24 deletions
+37 -2
View File
@@ -3,15 +3,20 @@ package models
import (
"encoding/json"
"fmt"
"time"
"github.com/grafana/grafana-aws-sdk/pkg/awsds"
"github.com/grafana/grafana-plugin-sdk-go/backend"
)
type Duration struct {
time.Duration
}
type CloudWatchSettings struct {
awsds.AWSDatasourceSettings
Namespace string `json:"customMetricsNamespaces"`
SecureSocksProxyEnabled bool `json:"enableSecureSocksProxy"` // this can be removed when https://github.com/grafana/grafana/issues/39089 is implemented
Namespace string `json:"customMetricsNamespaces"`
SecureSocksProxyEnabled bool `json:"enableSecureSocksProxy"` // this can be removed when https://github.com/grafana/grafana/issues/39089 is implemented
LogsTimeout Duration `json:"logsTimeout"`
}
func LoadCloudWatchSettings(config backend.DataSourceInstanceSettings) (CloudWatchSettings, error) {
@@ -30,8 +35,38 @@ func LoadCloudWatchSettings(config backend.DataSourceInstanceSettings) (CloudWat
instance.Profile = config.Database
}
// logs timeout default is 30 minutes, the same as timeout in frontend logs query
// note: for alerting queries, the context will be cancelled before that unless evaluation_timeout_seconds in defaults.ini is increased (default: 30s)
if instance.LogsTimeout.Duration == 0 {
instance.LogsTimeout = Duration{30 * time.Minute}
}
instance.AccessKey = config.DecryptedSecureJSONData["accessKey"]
instance.SecretKey = config.DecryptedSecureJSONData["secretKey"]
return instance, nil
}
func (duration *Duration) UnmarshalJSON(b []byte) error {
var unmarshalledJson interface{}
err := json.Unmarshal(b, &unmarshalledJson)
if err != nil {
return err
}
switch value := unmarshalledJson.(type) {
case float64:
*duration = Duration{time.Duration(value)}
case string:
dur, err := time.ParseDuration(value)
if err != nil {
return err
}
*duration = Duration{dur}
default:
return fmt.Errorf("invalid duration: %#v", unmarshalledJson)
}
return nil
}
+124
View File
@@ -2,6 +2,7 @@ package models
import (
"testing"
"time"
"github.com/grafana/grafana-aws-sdk/pkg/awsds"
"github.com/grafana/grafana-plugin-sdk-go/backend"
@@ -10,6 +11,24 @@ import (
)
func Test_Settings_LoadCloudWatchSettings(t *testing.T) {
t.Run("Should return error for invalid json", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": fluffles^.^,
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": "10m"
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
_, err := LoadCloudWatchSettings(settings)
assert.Error(t, err)
})
t.Run("Should parse keys query type", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
@@ -71,4 +90,109 @@ func Test_Settings_LoadCloudWatchSettings(t *testing.T) {
assert.Equal(t, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", s.SecretKey)
assert.Equal(t, "AKIAIOSFODNN7EXAMPLE", s.AccessKey)
})
t.Run("Should set logsTimeout to default duration if it is not defined", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana"
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
s, err := LoadCloudWatchSettings(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) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": "10m"
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
s, err := LoadCloudWatchSettings(settings)
require.NoError(t, err)
assert.Equal(t, time.Minute*10, s.LogsTimeout.Duration)
})
t.Run("Should correctly parse logsTimeout string with float number", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": "1.5s"
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
s, err := LoadCloudWatchSettings(settings)
require.NoError(t, err)
assert.Equal(t, time.Duration(1500000000), s.LogsTimeout.Duration)
})
t.Run("Should correctly parse logsTimeout duration in nanoseconds", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": 1500000000
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
s, err := LoadCloudWatchSettings(settings)
require.NoError(t, err)
assert.Equal(t, 1500*time.Millisecond, s.LogsTimeout.Duration)
})
t.Run("Should throw error if logsTimeout is an invalid duration format", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": "10mm"
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
_, err := LoadCloudWatchSettings(settings)
require.Error(t, err)
})
t.Run("Should throw error if logsTimeout is an invalid type", func(t *testing.T) {
settings := backend.DataSourceInstanceSettings{
ID: 33,
JSONData: []byte(`{
"authType": "arn",
"assumeRoleArn": "arn:aws:iam::123456789012:role/grafana",
"logsTimeout": true
}`),
DecryptedSecureJSONData: map[string]string{
"accessKey": "AKIAIOSFODNN7EXAMPLE",
"secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
}
_, err := LoadCloudWatchSettings(settings)
require.Error(t, err)
})
}