Alerting: modify ruler endpoints for proxying using the datasource UID (#48046)

* Modify ruler endpoints to expect the data source UID

* Update frontend

* Apply suggestion from code review
This commit is contained in:
Sofia Papagiannaki 2022-05-05 14:58:32 +03:00 committed by GitHub
parent 65d7d466d7
commit 610247d52a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 200 additions and 199 deletions

View File

@ -74,18 +74,18 @@ func (api *API) authorize(method, path string) web.Handler {
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
// Lotex Paths
case http.MethodDelete + "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodDelete + "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodGet + "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodGet + "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodGet + "/api/ruler/{DatasourceID}/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodPost + "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeProvider.GetResourceScope(ac.Parameter(":DatasourceID")))
case http.MethodDelete + "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
case http.MethodDelete + "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
case http.MethodGet + "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
case http.MethodGet + "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
case http.MethodGet + "/api/ruler/{DatasourceUID}/api/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
case http.MethodPost + "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}":
eval = ac.EvalPermission(ac.ActionAlertingInstancesExternalWrite, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
// Lotex Prometheus-compatible Paths
case http.MethodGet + "/api/prometheus/{DatasourceID}/api/v1/rules":

View File

@ -26,7 +26,7 @@ func NewForkedRuler(datasourceCache datasources.CacheService, lotex *LotexRuler,
}
func (f *ForkedRulerApi) forkRouteDeleteNamespaceRulesConfig(ctx *models.ReqContext) response.Response {
t, err := backendType(ctx, f.DatasourceCache)
t, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}
@ -39,7 +39,7 @@ func (f *ForkedRulerApi) forkRouteDeleteNamespaceRulesConfig(ctx *models.ReqCont
}
func (f *ForkedRulerApi) forkRouteDeleteRuleGroupConfig(ctx *models.ReqContext) response.Response {
t, err := backendType(ctx, f.DatasourceCache)
t, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}
@ -52,7 +52,7 @@ func (f *ForkedRulerApi) forkRouteDeleteRuleGroupConfig(ctx *models.ReqContext)
}
func (f *ForkedRulerApi) forkRouteGetNamespaceRulesConfig(ctx *models.ReqContext) response.Response {
t, err := backendType(ctx, f.DatasourceCache)
t, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}
@ -65,7 +65,7 @@ func (f *ForkedRulerApi) forkRouteGetNamespaceRulesConfig(ctx *models.ReqContext
}
func (f *ForkedRulerApi) forkRouteGetRulegGroupConfig(ctx *models.ReqContext) response.Response {
t, err := backendType(ctx, f.DatasourceCache)
t, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}
@ -78,7 +78,7 @@ func (f *ForkedRulerApi) forkRouteGetRulegGroupConfig(ctx *models.ReqContext) re
}
func (f *ForkedRulerApi) forkRouteGetRulesConfig(ctx *models.ReqContext) response.Response {
t, err := backendType(ctx, f.DatasourceCache)
t, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}
@ -91,7 +91,7 @@ func (f *ForkedRulerApi) forkRouteGetRulesConfig(ctx *models.ReqContext) respons
}
func (f *ForkedRulerApi) forkRoutePostNameRulesConfig(ctx *models.ReqContext, conf apimodels.PostableRuleGroupConfig) response.Response {
backendType, err := backendType(ctx, f.DatasourceCache)
backendType, err := backendTypeByUID(ctx, f.DatasourceCache)
if err != nil {
return ErrResp(400, err, "")
}

View File

@ -113,21 +113,21 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
),
)
group.Delete(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodDelete, "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodDelete, "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}",
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}",
srv.RouteDeleteNamespaceRulesConfig,
m,
),
)
group.Delete(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodDelete, "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodDelete, "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}",
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}",
srv.RouteDeleteRuleGroupConfig,
m,
),
@ -163,31 +163,31 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
),
)
group.Get(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}",
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}",
srv.RouteGetNamespaceRulesConfig,
m,
),
)
group.Get(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}",
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}",
srv.RouteGetRulegGroupConfig,
m,
),
)
group.Get(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceID}/api/v1/rules"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules"),
api.authorize(http.MethodGet, "/api/ruler/{DatasourceUID}/api/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{DatasourceID}/api/v1/rules",
"/api/ruler/{DatasourceUID}/api/v1/rules",
srv.RouteGetRulesConfig,
m,
),
@ -203,11 +203,11 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
),
)
group.Post(
toMacaronPath("/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodPost, "/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}"),
toMacaronPath("/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodPost, "/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodPost,
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}",
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}",
srv.RoutePostNameRulesConfig,
m,
),

View File

@ -5,7 +5,6 @@ import (
"fmt"
"net/http"
"net/url"
"strconv"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/web"
@ -176,12 +175,12 @@ func (r *LotexRuler) RoutePostNameRulesConfig(ctx *models.ReqContext, conf apimo
}
func (r *LotexRuler) validateAndGetPrefix(ctx *models.ReqContext) (string, error) {
datasourceID, err := strconv.ParseInt(web.Params(ctx.Req)[":DatasourceID"], 10, 64)
if err != nil {
return "", fmt.Errorf("datasource ID is invalid")
datasourceUID := web.Params(ctx.Req)[":DatasourceUID"]
if datasourceUID == "" {
return "", fmt.Errorf("datasource UID is invalid")
}
ds, err := r.DataProxy.DataSourceCache.GetDatasource(ctx.Req.Context(), datasourceID, ctx.SignedInUser, ctx.SkipCache)
ds, err := r.DataProxy.DataSourceCache.GetDatasourceByUID(ctx.Req.Context(), datasourceUID, ctx.SignedInUser, ctx.SkipCache)
if err != nil {
return "", err
}

View File

@ -25,64 +25,64 @@ func TestLotexRuler_ValidateAndGetPrefix(t *testing.T) {
err error
}{
{
name: "with an invalid datasource ID",
namedParams: map[string]string{":DatasourceID": "AAABBB"},
err: errors.New("datasource ID is invalid"),
name: "with an empty datasource UID",
namedParams: map[string]string{":DatasourceUID": ""},
err: errors.New("datasource UID is invalid"),
},
{
name: "with an error while trying to fetch the datasource",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{err: models.ErrDataSourceNotFound},
err: errors.New("data source not found"),
},
{
name: "with an empty datasource URL",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{}},
err: errors.New("URL for this data source is empty"),
},
{
name: "with an unsupported datasource type",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com"}},
err: errors.New("unexpected datasource type. expecting loki or prometheus"),
},
{
name: "with a Loki datasource",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: LokiDatasourceType}},
expected: "/api/prom/rules",
},
{
name: "with a Prometheus datasource",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and subtype of Cortex",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=cortex",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and subtype of Mimir",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=mimir",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/config/v1/rules",
},
{
name: "with a Prometheus datasource and subtype of Prometheus",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=prometheus",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and no subtype",
namedParams: map[string]string{":DatasourceID": "164"},
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},

View File

@ -1,10 +1,10 @@
@prometheusDatasourceID = 35
@prometheusDatasourceUID = 7DEsN5_Mk
// should point to an existing folder named alerting
@namespace1 = test
// create/update test namespace group42 rulegroup
POST http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
POST http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
content-type: application/json
{
@ -20,7 +20,7 @@ content-type: application/json
###
// create group101
POST http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
POST http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
content-type: application/json
{
@ -36,40 +36,41 @@ content-type: application/json
###
// get group42 rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}/group42
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get group101 rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}/group101
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}/group101
###
// get namespace rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get org rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules
###
// delete group42 rules
DELETE http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}/group42
DELETE http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get namespace rules - only group101 should be listed
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// delete namespace rules
DELETE http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
DELETE http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get namespace rules - no rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get group42 rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}/group42
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get namespace rules
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{prometheusDatasourceUID}}/api/v1/rules/{{namespace1}}
U

View File

@ -1,10 +1,10 @@
@lokiDatasourceID = 32
@lokiDatasourceUID = 9w8X2zlMz
// should point to an existing folder named alerting
@namespace1 = test
// create/update test namespace group42 rulegroup
POST http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
POST http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
content-type: application/json
{
@ -20,7 +20,7 @@ content-type: application/json
###
// create group101
POST http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
POST http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
content-type: application/json
{
@ -36,40 +36,40 @@ content-type: application/json
###
// get group42 rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}/group42
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get group101 rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}/group101
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}/group101
###
// get namespace rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get org rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules
###
// delete group42 rules
DELETE http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}/group42
DELETE http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get namespace rules - only group101 should be listed
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// delete namespace rules
DELETE http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
DELETE http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get namespace rules - no rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}
###
// get group42 rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}/group42
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}/group42
###
// get namespace rules
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceID}}/api/v1/rules/{{namespace1}}
GET http://admin:admin@localhost:3000/api/ruler/{{lokiDatasourceUID}}/api/v1/rules/{{namespace1}}

View File

@ -427,21 +427,17 @@ type AlertsParams struct {
}
// swagger:parameters RoutePostAMAlerts RoutePostGrafanaAMAlerts
// swagger:parameters RoutePostAMAlerts
type PostableAlerts struct {
// in:body
PostableAlerts []amv2.PostableAlert `yaml:"" json:""`
}
// swagger:parameters RoutePostAlertingConfig RoutePostGrafanaAlertingConfig
// swagger:parameters RoutePostAlertingConfig
type BodyAlertingConfig struct {
// in:body
Body PostableUserConfig
}
// ruler routes
// swagger:parameters RouteGetRulesConfig RoutePostNameRulesConfig RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig
// prom routes
// swagger:parameters RouteGetRuleStatuses RouteGetAlertStatuses
// testing routes
@ -454,6 +450,8 @@ type DatasourceIDReference struct {
// alertmanager routes
// swagger:parameters RoutePostAlertingConfig RouteGetAlertingConfig RouteDeleteAlertingConfig RouteGetAMStatus RouteGetAMAlerts RoutePostAMAlerts RouteGetAMAlertGroups RouteGetSilences RouteCreateSilence RouteGetSilence RouteDeleteSilence RoutePostAlertingConfig RoutePostTestReceivers
// ruler routes
// swagger:parameters RouteGetRulesConfig RoutePostNameRulesConfig RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig
type DatasourceUIDReference struct {
// DatasoureUID should be the datasource UID identifier
// in:path

View File

@ -21,7 +21,7 @@ import (
// 202: NamespaceConfigResponse
//
// swagger:route Get /api/ruler/{DatasourceID}/api/v1/rules ruler RouteGetRulesConfig
// swagger:route Get /api/ruler/{DatasourceUID}/api/v1/rules ruler RouteGetRulesConfig
//
// List rule groups
//
@ -43,7 +43,7 @@ import (
// 202: Ack
//
// swagger:route POST /api/ruler/{DatasourceID}/api/v1/rules/{Namespace} ruler RoutePostNameRulesConfig
// swagger:route POST /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace} ruler RoutePostNameRulesConfig
//
// Creates or updates a rule group
//
@ -64,7 +64,7 @@ import (
// Responses:
// 202: NamespaceConfigResponse
// swagger:route Get /api/ruler/{DatasourceID}/api/v1/rules/{Namespace} ruler RouteGetNamespaceRulesConfig
// swagger:route Get /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace} ruler RouteGetNamespaceRulesConfig
//
// Get rule groups by namespace
//
@ -81,7 +81,7 @@ import (
// Responses:
// 202: Ack
// swagger:route Delete /api/ruler/{DatasourceID}/api/v1/rules/{Namespace} ruler RouteDeleteNamespaceRulesConfig
// swagger:route Delete /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace} ruler RouteDeleteNamespaceRulesConfig
//
// Delete namespace
//
@ -98,7 +98,7 @@ import (
// Responses:
// 202: RuleGroupConfigResponse
// swagger:route Get /api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname} ruler RouteGetRulegGroupConfig
// swagger:route Get /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname} ruler RouteGetRulegGroupConfig
//
// Get rule group
//
@ -115,7 +115,7 @@ import (
// Responses:
// 202: Ack
// swagger:route Delete /api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname} ruler RouteDeleteRuleGroupConfig
// swagger:route Delete /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname} ruler RouteDeleteRuleGroupConfig
//
// Delete rule group
//

View File

@ -977,6 +977,9 @@
"type": "integer",
"x-go-name": "OrgID"
},
"provenance": {
"$ref": "#/definitions/Provenance"
},
"rule_group": {
"type": "string",
"x-go-name": "RuleGroup"
@ -3103,7 +3106,6 @@
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertGroup": {
"description": "AlertGroup alert group",
"properties": {
"alerts": {
"description": "alerts",
@ -3125,14 +3127,17 @@
"labels",
"receiver"
],
"type": "object"
"type": "object",
"x-go-name": "AlertGroup",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup"
},
"type": "array"
"type": "array",
"x-go-name": "AlertGroups",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertStatus": {
"description": "AlertStatus alert status",
@ -3252,7 +3257,6 @@
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@ -3311,7 +3315,9 @@
"status",
"updatedAt"
],
"type": "object"
"type": "object",
"x-go-name": "GettableAlert",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
@ -3376,11 +3382,12 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
"type": "array"
"type": "array",
"x-go-name": "GettableSilences",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"labelSet": {
"additionalProperties": {
@ -5162,18 +5169,17 @@
]
}
},
"/api/ruler/{DatasourceID}/api/v1/rules": {
"/api/ruler/{DatasourceUID}/api/v1/rules": {
"get": {
"description": "List rule groups",
"operationId": "RouteGetRulesConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "query",
@ -5203,18 +5209,17 @@
]
}
},
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}": {
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}": {
"delete": {
"description": "Delete namespace",
"operationId": "RouteDeleteNamespaceRulesConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "path",
@ -5240,12 +5245,11 @@
"operationId": "RouteGetNamespaceRulesConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "path",
@ -5278,12 +5282,11 @@
"operationId": "RoutePostNameRulesConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "path",
@ -5312,18 +5315,17 @@
]
}
},
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}": {
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}": {
"delete": {
"description": "Delete rule group",
"operationId": "RouteDeleteRuleGroupConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "path",
@ -5355,12 +5357,11 @@
"operationId": "RouteGetRulegGroupConfig",
"parameters": [
{
"description": "DatasourceID should be the numeric datasource identifier",
"format": "int64",
"description": "DatasoureUID should be the datasource UID identifier",
"in": "path",
"name": "DatasourceID",
"name": "DatasourceUID",
"required": true,
"type": "integer"
"type": "string"
},
{
"in": "path",

View File

@ -1501,7 +1501,7 @@
}
}
},
"/api/ruler/{DatasourceID}/api/v1/rules": {
"/api/ruler/{DatasourceUID}/api/v1/rules": {
"get": {
"description": "List rule groups",
"produces": [
@ -1513,10 +1513,9 @@
"operationId": "RouteGetRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -1542,7 +1541,7 @@
}
}
},
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}": {
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}": {
"get": {
"description": "Get rule groups by namespace",
"produces": [
@ -1554,10 +1553,9 @@
"operationId": "RouteGetNamespaceRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -1589,10 +1587,9 @@
"operationId": "RoutePostNameRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -1627,10 +1624,9 @@
"operationId": "RouteDeleteNamespaceRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -1651,7 +1647,7 @@
}
}
},
"/api/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}": {
"/api/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}": {
"get": {
"description": "Get rule group",
"produces": [
@ -1663,10 +1659,9 @@
"operationId": "RouteGetRulegGroupConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -1700,10 +1695,9 @@
"operationId": "RouteDeleteRuleGroupConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -2922,6 +2916,9 @@
"format": "int64",
"x-go-name": "OrgID"
},
"provenance": {
"$ref": "#/definitions/Provenance"
},
"rule_group": {
"type": "string",
"x-go-name": "RuleGroup"
@ -5048,7 +5045,6 @@
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertGroup": {
"description": "AlertGroup alert group",
"type": "object",
"required": [
"alerts",
@ -5071,14 +5067,17 @@
"$ref": "#/definitions/receiver"
}
},
"x-go-name": "AlertGroup",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
"$ref": "#/definitions/alertGroup"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"$ref": "#/definitions/alertGroup"
},
"x-go-name": "AlertGroups",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
"$ref": "#/definitions/alertGroups"
},
"alertStatus": {
@ -5199,7 +5198,6 @@
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"type": "object",
"required": [
"labels",
@ -5259,6 +5257,8 @@
"x-go-name": "UpdatedAt"
}
},
"x-go-name": "GettableAlert",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
"$ref": "#/definitions/gettableAlert"
},
"gettableAlerts": {
@ -5326,11 +5326,12 @@
"$ref": "#/definitions/gettableSilence"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"type": "array",
"items": {
"$ref": "#/definitions/gettableSilence"
},
"x-go-name": "GettableSilences",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
"$ref": "#/definitions/gettableSilences"
},
"labelSet": {

View File

@ -7590,7 +7590,7 @@
}
}
},
"/ruler/{DatasourceID}/api/v1/rules": {
"/ruler/{DatasourceUID}/api/v1/rules": {
"get": {
"description": "List rule groups",
"produces": ["application/json"],
@ -7598,10 +7598,9 @@
"operationId": "RouteGetRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -7627,7 +7626,7 @@
}
}
},
"/ruler/{DatasourceID}/api/v1/rules/{Namespace}": {
"/ruler/{DatasourceUID}/api/v1/rules/{Namespace}": {
"get": {
"description": "Get rule groups by namespace",
"produces": ["application/json"],
@ -7635,10 +7634,9 @@
"operationId": "RouteGetNamespaceRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -7665,10 +7663,9 @@
"operationId": "RoutePostNameRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -7701,10 +7698,9 @@
"operationId": "RouteDeleteNamespaceRulesConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -7725,7 +7721,7 @@
}
}
},
"/ruler/{DatasourceID}/api/v1/rules/{Namespace}/{Groupname}": {
"/ruler/{DatasourceUID}/api/v1/rules/{Namespace}/{Groupname}": {
"get": {
"description": "Get rule group",
"produces": ["application/json"],
@ -7733,10 +7729,9 @@
"operationId": "RouteGetRulegGroupConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -7768,10 +7763,9 @@
"operationId": "RouteDeleteRuleGroupConfig",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "DatasourceID should be the numeric datasource identifier",
"name": "DatasourceID",
"type": "string",
"description": "DatasoureUID should be the datasource UID identifier",
"name": "DatasourceUID",
"in": "path",
"required": true
},
@ -12629,6 +12623,9 @@
"format": "int64",
"x-go-name": "OrgID"
},
"provenance": {
"$ref": "#/definitions/Provenance"
},
"rule_group": {
"type": "string",
"x-go-name": "RuleGroup"
@ -17306,7 +17303,6 @@
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertGroup": {
"description": "AlertGroup alert group",
"type": "object",
"required": ["alerts", "labels", "receiver"],
"properties": {
@ -17324,14 +17320,17 @@
"receiver": {
"$ref": "#/definitions/receiver"
}
}
},
"x-go-name": "AlertGroup",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"$ref": "#/definitions/alertGroup"
}
},
"x-go-name": "AlertGroups",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"alertStatus": {
"description": "AlertStatus alert status",
@ -17434,7 +17433,6 @@
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"type": "object",
"required": ["labels", "annotations", "endsAt", "fingerprint", "receivers", "startsAt", "status", "updatedAt"],
"properties": {
@ -17484,7 +17482,9 @@
"format": "date-time",
"x-go-name": "UpdatedAt"
}
}
},
"x-go-name": "GettableAlert",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
@ -17540,11 +17540,12 @@
}
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"type": "array",
"items": {
"$ref": "#/definitions/gettableSilence"
}
},
"x-go-name": "GettableSilences",
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
},
"labelSet": {
"description": "LabelSet label set",

View File

@ -1,13 +1,13 @@
import { RulerDataSourceConfig } from 'app/types/unified-alerting';
import { getDatasourceAPIId } from '../utils/datasource';
import { getDatasourceAPIUid } from '../utils/datasource';
import { rulerUrlBuilder } from './ruler';
jest.mock('../utils/datasource');
const mocks = {
getDatasourceAPIId: jest.mocked(getDatasourceAPIId),
getDatasourceAPIUId: jest.mocked(getDatasourceAPIUid),
};
describe('rulerUrlBuilder', () => {
@ -18,7 +18,7 @@ describe('rulerUrlBuilder', () => {
apiVersion: 'legacy',
};
mocks.getDatasourceAPIId.mockReturnValue('ds-uid');
mocks.getDatasourceAPIUId.mockReturnValue('ds-uid');
// Act
const builder = rulerUrlBuilder(config);
@ -45,7 +45,7 @@ describe('rulerUrlBuilder', () => {
apiVersion: 'config',
};
mocks.getDatasourceAPIId.mockReturnValue('ds-uid');
mocks.getDatasourceAPIUId.mockReturnValue('ds-uid');
// Act
const builder = rulerUrlBuilder(config);
@ -72,7 +72,7 @@ describe('rulerUrlBuilder', () => {
apiVersion: 'config',
};
mocks.getDatasourceAPIId.mockReturnValue('ds-uid');
mocks.getDatasourceAPIUId.mockReturnValue('ds-uid');
// Act
const builder = rulerUrlBuilder(config);
@ -94,7 +94,7 @@ describe('rulerUrlBuilder', () => {
apiVersion: 'config',
};
mocks.getDatasourceAPIId.mockReturnValue('ds-uid');
mocks.getDatasourceAPIUId.mockReturnValue('ds-uid');
// Act
const builder = rulerUrlBuilder(config);

View File

@ -5,7 +5,7 @@ import { RulerDataSourceConfig } from 'app/types/unified-alerting';
import { PostableRulerRuleGroupDTO, RulerRuleGroupDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto';
import { RULER_NOT_SUPPORTED_MSG } from '../utils/constants';
import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
import { getDatasourceAPIUid, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
import { prepareRulesFilterQueryParams } from './prometheus';
@ -20,7 +20,7 @@ export interface RulerRequestUrl {
}
export function rulerUrlBuilder(rulerConfig: RulerDataSourceConfig) {
const grafanaServerPath = `/api/ruler/${getDatasourceAPIId(rulerConfig.dataSourceName)}`;
const grafanaServerPath = `/api/ruler/${getDatasourceAPIUid(rulerConfig.dataSourceName)}`;
const rulerPath = `${grafanaServerPath}/api/v1/rules`;
const rulerSearchParams = new URLSearchParams();
@ -94,7 +94,7 @@ export async function fetchRulerRulesNamespace(rulerConfig: RulerDataSourceConfi
// will throw with { status: 404 } if rule group does not exist
export async function fetchTestRulerRulesGroup(dataSourceName: string): Promise<RulerRuleGroupDTO | null> {
return rulerGetRequest<RulerRuleGroupDTO | null>(
`/api/ruler/${getDatasourceAPIId(dataSourceName)}/api/v1/rules/test/test`,
`/api/ruler/${getDatasourceAPIUid(dataSourceName)}/api/v1/rules/test/test`,
null
);
}