From 96b6463f2587f8c3da1031bfd5bc6b9aca575733 Mon Sep 17 00:00:00 2001 From: gotjosh Date: Tue, 18 Apr 2023 16:26:21 +0100 Subject: [PATCH] review comments Signed-off-by: gotjosh --- web/api/v1/api.go | 42 ++++++++++++++++++++++++++++++------------ web/api/v1/api_test.go | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/web/api/v1/api.go b/web/api/v1/api.go index d95595804..9a13e09d9 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -1292,20 +1292,26 @@ type RecordingRule struct { } func (api *API) rules(r *http.Request) apiFuncResult { + if err := r.ParseForm(); err != nil { + return apiFuncResult{nil, &apiError{errorBadData, errors.Wrapf(err, "error parsing form values")}, nil, nil} + } + + queryFormToSet := func(values []string) map[string]struct{} { + set := make(map[string]struct{}, len(values)) + for _, v := range values { + set[v] = struct{}{} + } + return set + } + + rnSet := queryFormToSet(r.Form["rule_name[]"]) + rgSet := queryFormToSet(r.Form["rule_group[]"]) + fSet := queryFormToSet(r.Form["file[]"]) + ruleGroups := api.rulesRetriever(r.Context()).RuleGroups() res := &RuleDiscovery{RuleGroups: make([]*RuleGroup, len(ruleGroups))} typ := strings.ToLower(r.URL.Query().Get("type")) - // Parse the rule names into a comma separated list of rule names, then create a set. - rulesQuery := r.URL.Query().Get("rules") - ruleNamesSet := map[string]struct{}{} - if rulesQuery != "" { - names := strings.Split(rulesQuery, ",") - for _, rn := range names { - ruleNamesSet[strings.TrimSpace(rn)] = struct{}{} - } - } - if typ != "" && typ != "alert" && typ != "record" { return invalidParamError(errors.Errorf("not supported value %q", typ), "type") } @@ -1314,6 +1320,18 @@ func (api *API) rules(r *http.Request) apiFuncResult { returnRecording := typ == "" || typ == "record" for i, grp := range ruleGroups { + if len(rgSet) > 0 { + if _, ok := rgSet[grp.Name()]; !ok { + continue + } + } + + if len(fSet) > 0 { + if _, ok := fSet[grp.File()]; !ok { + continue + } + } + apiRuleGroup := &RuleGroup{ Name: grp.Name(), File: grp.File(), @@ -1326,8 +1344,8 @@ func (api *API) rules(r *http.Request) apiFuncResult { for _, rr := range grp.Rules() { var enrichedRule Rule - if len(ruleNamesSet) > 0 { - if _, ok := ruleNamesSet[rr.Name()]; !ok { + if len(rnSet) > 0 { + if _, ok := rnSet[rr.Name()]; !ok { continue } } diff --git a/web/api/v1/api_test.go b/web/api/v1/api_test.go index e354bf298..c3e1bf59d 100644 --- a/web/api/v1/api_test.go +++ b/web/api/v1/api_test.go @@ -1975,7 +1975,39 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, es storage.E }, { endpoint: api.rules, - query: url.Values{"rules": []string{"test_metric4"}}, + query: url.Values{"rule_name[]": []string{"test_metric4"}}, + response: &RuleDiscovery{ + RuleGroups: []*RuleGroup{ + { + Name: "grp", + File: "/path/to/file", + Interval: 1, + Limit: 0, + Rules: []Rule{ + AlertingRule{ + State: "inactive", + Name: "test_metric4", + Query: "up == 1", + Duration: 1, + Labels: labels.Labels{}, + Annotations: labels.Labels{}, + Alerts: []*Alert{}, + Health: "unknown", + Type: "alerting", + }, + }, + }, + }, + }, + }, + { + endpoint: api.rules, + query: url.Values{"rule_group[]": []string{"respond-with-nothing"}}, + response: &RuleDiscovery{RuleGroups: []*RuleGroup{nil}}, + }, + { + endpoint: api.rules, + query: url.Values{"file[]": []string{"/path/to/file"}, "rule_name[]": []string{"test_metric4"}}, response: &RuleDiscovery{ RuleGroups: []*RuleGroup{ {