Cloudwatch: Fix deeplink with default region (#60260) (#60274)

Cloudwatch: fix deeplink with default region
(cherry picked from commit d6bb2a7493)
This commit is contained in:
Isabella Siu
2022-12-13 17:14:45 -05:00
committed by GitHub
parent 04aded642e
commit 1437520da2
3 changed files with 84 additions and 42 deletions
@@ -41,6 +41,8 @@ const (
GMDApiModeSQLExpression
)
const defaultRegion = "default"
type CloudWatchQuery struct {
RefId string
Region string
@@ -227,7 +229,7 @@ type metricsDataQuery struct {
// ParseMetricDataQueries decodes the metric data queries json, validates, sets default values and returns an array of CloudWatchQueries.
// The CloudWatchQuery has a 1 to 1 mapping to a query editor row
func ParseMetricDataQueries(dataQueries []backend.DataQuery, startTime time.Time, endTime time.Time, dynamicLabelsEnabled,
func ParseMetricDataQueries(dataQueries []backend.DataQuery, startTime time.Time, endTime time.Time, defaultRegion string, dynamicLabelsEnabled,
crossAccountQueryingEnabled bool) ([]*CloudWatchQuery, error) {
var metricDataQueries = make(map[string]metricsDataQuery)
for _, query := range dataQueries {
@@ -260,7 +262,7 @@ func ParseMetricDataQueries(dataQueries []backend.DataQuery, startTime time.Time
Expression: mdq.Expression,
}
if err := cwQuery.validateAndSetDefaults(refId, mdq, startTime, endTime, crossAccountQueryingEnabled); err != nil {
if err := cwQuery.validateAndSetDefaults(refId, mdq, startTime, endTime, defaultRegion, crossAccountQueryingEnabled); err != nil {
return nil, &QueryError{Err: err, RefID: refId}
}
@@ -278,7 +280,7 @@ func (q *CloudWatchQuery) migrateLegacyQuery(query metricsDataQuery, dynamicLabe
}
func (q *CloudWatchQuery) validateAndSetDefaults(refId string, metricsDataQuery metricsDataQuery, startTime, endTime time.Time,
crossAccountQueryingEnabled bool) error {
defaultRegionValue string, crossAccountQueryingEnabled bool) error {
if metricsDataQuery.Statistic == nil && metricsDataQuery.Statistics == nil {
return fmt.Errorf("query must have either statistic or statistics field")
}
@@ -337,6 +339,10 @@ func (q *CloudWatchQuery) validateAndSetDefaults(refId string, metricsDataQuery
}
}
if q.Region == defaultRegion {
q.Region = defaultRegionValue
}
return nil
}
@@ -316,7 +316,7 @@ func TestRequestParser(t *testing.T) {
},
}
migratedQueries, err := ParseMetricDataQueries(oldQuery, time.Now(), time.Now(), false, false)
migratedQueries, err := ParseMetricDataQueries(oldQuery, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
require.Len(t, migratedQueries, 1)
require.NotNil(t, migratedQueries[0])
@@ -347,7 +347,7 @@ func TestRequestParser(t *testing.T) {
},
}
results, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
results, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, results, 1)
res := results[0]
@@ -390,7 +390,7 @@ func TestRequestParser(t *testing.T) {
},
}
results, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
results, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
assert.NoError(t, err)
require.Len(t, results, 1)
res := results[0]
@@ -423,7 +423,7 @@ func TestRequestParser(t *testing.T) {
},
}
_, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
_, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.Error(t, err)
assert.Equal(t, `error parsing query "", failed to parse dimensions: unknown type as dimension value`, err.Error())
@@ -452,7 +452,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
assert.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -484,7 +484,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.Local().Add(time.Minute * time.Duration(5))
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 60, res[0].Period)
@@ -494,7 +494,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(0, 0, -1)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 60, res[0].Period)
@@ -503,7 +503,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
t.Run("Time range is 2 days", func(t *testing.T) {
to := time.Now()
from := to.AddDate(0, 0, -2)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 300, res[0].Period)
@@ -513,7 +513,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(0, 0, -7)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 900, res[0].Period)
@@ -523,7 +523,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(0, 0, -30)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 3600, res[0].Period)
@@ -533,7 +533,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(0, 0, -90)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 21600, res[0].Period)
@@ -543,7 +543,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(-1, 0, 0)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.Nil(t, err)
require.Len(t, res, 1)
assert.Equal(t, 21600, res[0].Period)
@@ -553,7 +553,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
to := time.Now()
from := to.AddDate(-2, 0, 0)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 86400, res[0].Period)
@@ -562,7 +562,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
t.Run("Time range is 2 days, but 16 days ago", func(t *testing.T) {
to := time.Now().AddDate(0, 0, -14)
from := to.AddDate(0, 0, -2)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 300, res[0].Period)
@@ -571,7 +571,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
t.Run("Time range is 2 days, but 90 days ago", func(t *testing.T) {
to := time.Now().AddDate(0, 0, -88)
from := to.AddDate(0, 0, -2)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 3600, res[0].Period)
@@ -580,7 +580,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
t.Run("Time range is 2 days, but 456 days ago", func(t *testing.T) {
to := time.Now().AddDate(0, 0, -454)
from := to.AddDate(0, 0, -2)
res, err := ParseMetricDataQueries(query, from, to, false, false)
res, err := ParseMetricDataQueries(query, from, to, "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
assert.Equal(t, 21600, res[0].Period)
@@ -595,7 +595,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
}`),
},
}
_, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
_, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.Error(t, err)
assert.Equal(t, `error parsing query "", failed to parse period as duration: time: invalid duration "invalid"`, err.Error())
})
@@ -610,7 +610,7 @@ func Test_ParseMetricDataQueries_periods(t *testing.T) {
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
assert.NoError(t, err)
require.Len(t, res, 1)
@@ -697,7 +697,7 @@ func Test_ParseMetricDataQueries_query_type_and_metric_editor_mode_and_GMD_query
),
},
}
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), false, false)
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -723,7 +723,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -744,7 +744,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -765,7 +765,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -784,7 +784,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -805,7 +805,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -826,7 +826,7 @@ func Test_ParseMetricDataQueries_hide_and_ReturnData(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -849,7 +849,7 @@ func Test_ParseMetricDataQueries_ID(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -870,7 +870,7 @@ func Test_ParseMetricDataQueries_ID(t *testing.T) {
}`),
},
}
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), false, false)
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), "us-east-2", false, false)
require.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -897,7 +897,7 @@ func Test_ParseMetricDataQueries_sets_label_when_label_is_present_in_json_query(
},
}
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), true, false)
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), "us-east-2", true, false)
assert.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
@@ -961,7 +961,7 @@ func Test_ParseMetricDataQueries_migrate_alias_to_label(t *testing.T) {
},
}
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), true, false)
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), "us-east-2", true, false)
assert.NoError(t, err)
require.Len(t, res, 1)
@@ -1008,7 +1008,7 @@ func Test_ParseMetricDataQueries_migrate_alias_to_label(t *testing.T) {
},
}
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), true, false)
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), "us-east-2", true, false)
assert.NoError(t, err)
require.Len(t, res, 2)
@@ -1078,7 +1078,7 @@ func Test_ParseMetricDataQueries_migrate_alias_to_label(t *testing.T) {
}`, tc.labelJson)),
},
}
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), tc.dynamicLabelsFeatureToggleEnabled, false)
res, err := ParseMetricDataQueries(query, time.Now(), time.Now(), "us-east-2", tc.dynamicLabelsFeatureToggleEnabled, false)
assert.NoError(t, err)
require.Len(t, res, 1)
@@ -1105,7 +1105,7 @@ func Test_ParseMetricDataQueries_statistics_and_query_type_validation_and_MatchE
{
JSON: []byte("{}"),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.Error(t, err)
assert.Equal(t, `error parsing query "", query must have either statistic or statistics field`, err.Error())
@@ -1118,7 +1118,7 @@ func Test_ParseMetricDataQueries_statistics_and_query_type_validation_and_MatchE
{
JSON: []byte(`{"type":"some other type", "statistic":"Average", "matchExact":false}`),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
assert.Empty(t, actual)
@@ -1130,7 +1130,7 @@ func Test_ParseMetricDataQueries_statistics_and_query_type_validation_and_MatchE
{
JSON: []byte(`{"statistic":"Average"}`),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
assert.NotEmpty(t, actual)
@@ -1142,7 +1142,7 @@ func Test_ParseMetricDataQueries_statistics_and_query_type_validation_and_MatchE
{
JSON: []byte(`{"statistic":"Average"}`),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
assert.Len(t, actual, 1)
@@ -1156,7 +1156,7 @@ func Test_ParseMetricDataQueries_statistics_and_query_type_validation_and_MatchE
{
JSON: []byte(`{"statistic":"Average","matchExact":false}`),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
assert.Len(t, actual, 1)
@@ -1172,7 +1172,7 @@ func Test_ParseMetricDataQueries_account_Id(t *testing.T) {
{
JSON: []byte(`{"accountId":"some account id", "statistic":"Average"}`),
},
}, time.Now(), time.Now(), false, true)
}, time.Now(), time.Now(), "us-east-2", false, true)
assert.NoError(t, err)
require.Len(t, actual, 1)
@@ -1187,7 +1187,7 @@ func Test_ParseMetricDataQueries_account_Id(t *testing.T) {
{
JSON: []byte(`{"accountId":"some account id", "statistic":"Average"}`),
},
}, time.Now(), time.Now(), false, false)
}, time.Now(), time.Now(), "us-east-2", false, false)
assert.NoError(t, err)
require.Len(t, actual, 1)
@@ -1196,4 +1196,35 @@ func Test_ParseMetricDataQueries_account_Id(t *testing.T) {
})
}
func Test_ParseMetricDataQueries_default_region(t *testing.T) {
t.Run("default region is used when when region not set", func(t *testing.T) {
query := []backend.DataQuery{
{
JSON: json.RawMessage(`{
"refId":"ref1",
"region":"default",
"namespace":"ec2",
"metricName":"CPUUtilization",
"id": "",
"expression": "",
"dimensions":{
"InstanceId":["test"],
"InstanceType":["test2"]
},
"statistic":"Average",
"period":"900",
"hide":false
}`),
},
}
region := "us-east-2"
res, err := ParseMetricDataQueries(query, time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour), region, false, false)
assert.NoError(t, err)
require.Len(t, res, 1)
require.NotNil(t, res[0])
assert.Equal(t, region, res[0].Region)
})
}
func pointer[T any](arg T) *T { return &arg }
+6 -1
View File
@@ -31,7 +31,12 @@ func (e *cloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, logger
return nil, fmt.Errorf("invalid time range: start time must be before end time")
}
requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime,
instance, err := e.getInstance(req.PluginContext)
if err != nil {
return nil, err
}
requestQueries, err := models.ParseMetricDataQueries(req.Queries, startTime, endTime, instance.Settings.Region,
e.features.IsEnabled(featuremgmt.FlagCloudWatchDynamicLabels),
e.features.IsEnabled(featuremgmt.FlagCloudWatchCrossAccountQuerying))
if err != nil {