Dashboard: Validate refId when generating id for cloudwatch query (#46182)

* Validate refId when generating id for cloudwatch query

* add test case when refId is a valid metric data id
This commit is contained in:
Kevin Yu 2022-03-14 09:44:04 -07:00 committed by GitHub
parent 04409799fb
commit 99b4dfc27d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 1 deletions

View File

@ -10,10 +10,13 @@ import (
"strings"
"time"
"github.com/google/uuid"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
)
var validMetricDataID = regexp.MustCompile(`^[a-z][a-zA-Z0-9_]*$`)
// parseQueries parses the json queries and returns a map of cloudWatchQueries by region. The cloudWatchQuery has a 1 to 1 mapping to a query editor row
func (e *cloudWatchExecutor) parseQueries(queries []backend.DataQuery, startTime time.Time, endTime time.Time) (map[string][]*cloudWatchQuery, error) {
requestQueries := make(map[string][]*cloudWatchQuery)
@ -140,7 +143,12 @@ func parseRequestQuery(model *simplejson.Json, refId string, startTime time.Time
// Why not just use refId if id is not specified in the frontend? When specifying an id in the editor,
// and alphabetical must be used. The id must be unique, so if an id like for example a, b or c would be used,
// it would likely collide with some ref id. That's why the `query` prefix is used.
id = fmt.Sprintf("query%s", refId)
suffix := refId
if !validMetricDataID.MatchString(suffix) {
uuid := uuid.NewString()
suffix = strings.Replace(uuid, "-", "", -1)
}
id = fmt.Sprintf("query%s", suffix)
}
expression := model.Get("expression").MustString("")
sqlExpression := model.Get("sqlExpression").MustString("")

View File

@ -293,6 +293,23 @@ func TestRequestParser(t *testing.T) {
assert.Equal(t, GMDApiModeMathExpression, res.getGMDAPIMode())
})
})
t.Run("ID is the string `query` appended with refId if refId is a valid MetricData ID", func(t *testing.T) {
query := getBaseJsonQuery()
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, "ref1", res.RefId)
assert.Equal(t, "queryref1", res.Id)
})
t.Run("Valid id is generated if ID is not provided and refId is not a valid MetricData ID", func(t *testing.T) {
query := getBaseJsonQuery()
query.Set("refId", "$$")
res, err := parseRequestQuery(query, "$$", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, "$$", res.RefId)
assert.Regexp(t, validMetricDataID, res.Id)
})
}
func getBaseJsonQuery() *simplejson.Json {