Alerting: Split grafana and lotex routes (#44742)

* split Lotex and Grafana routes
* update template to use authorize function for every route
This commit is contained in:
Yuriy Tseretyan 2022-02-04 12:42:04 -05:00 committed by GitHub
parent 126ed461b1
commit ddfe2dce74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 2257 additions and 214 deletions

View File

@ -83,22 +83,22 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
api.RegisterAlertmanagerApiEndpoints(NewForkedAM(
api.DatasourceCache,
NewLotexAM(proxy, logger),
AlertmanagerSrv{store: api.AlertingStore, mam: api.MultiOrgAlertmanager, secrets: api.SecretsService, log: logger},
&AlertmanagerSrv{store: api.AlertingStore, mam: api.MultiOrgAlertmanager, secrets: api.SecretsService, log: logger},
), m)
// Register endpoints for proxying to Prometheus-compatible backends.
api.RegisterPrometheusApiEndpoints(NewForkedProm(
api.DatasourceCache,
NewLotexProm(proxy, logger),
PrometheusSrv{log: logger, manager: api.StateManager, store: api.RuleStore},
&PrometheusSrv{log: logger, manager: api.StateManager, store: api.RuleStore},
), m)
// Register endpoints for proxying to Cortex Ruler-compatible backends.
api.RegisterRulerApiEndpoints(NewForkedRuler(
api.DatasourceCache,
NewLotexRuler(proxy, logger),
RulerSrv{DatasourceCache: api.DatasourceCache, QuotaService: api.QuotaService, scheduleService: api.Schedule, store: api.RuleStore, log: logger},
&RulerSrv{DatasourceCache: api.DatasourceCache, QuotaService: api.QuotaService, scheduleService: api.Schedule, store: api.RuleStore, log: logger},
), m)
api.RegisterTestingApiEndpoints(NewForkedTestingApi(
TestingApiSrv{
&TestingApiSrv{
AlertingProxy: proxy,
Cfg: api.Cfg,
ExpressionService: api.ExpressionService,
@ -107,7 +107,7 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
log: logger,
}), m)
api.RegisterConfigurationApiEndpoints(NewForkedConfiguration(
AdminSrv{
&AdminSrv{
store: api.AdminConfigStore,
log: logger,
scheduler: api.Schedule,

View File

@ -29,15 +29,15 @@ type TestingApiSrv struct {
secretsService secrets.Service
}
func (srv TestingApiSrv) RouteTestGrafanaRuleConfig(c *models.ReqContext, body apimodels.TestRulePayload) response.Response {
if body.Type() != apimodels.GrafanaBackend || body.GrafanaManagedCondition == nil {
return ErrResp(http.StatusBadRequest, errors.New("unexpected payload"), "")
}
return conditionEval(c, *body.GrafanaManagedCondition, srv.DatasourceCache, srv.ExpressionService, srv.secretsService, srv.Cfg, srv.log)
}
func (srv TestingApiSrv) RouteTestRuleConfig(c *models.ReqContext, body apimodels.TestRulePayload) response.Response {
recipient := web.Params(c.Req)[":Recipient"]
if recipient == apimodels.GrafanaBackend.String() {
if body.Type() != apimodels.GrafanaBackend || body.GrafanaManagedCondition == nil {
return ErrResp(http.StatusBadRequest, errors.New("unexpected payload"), "")
}
return conditionEval(c, *body.GrafanaManagedCondition, srv.DatasourceCache, srv.ExpressionService, srv.secretsService, srv.Cfg, srv.log)
}
if body.Type() != apimodels.LoTexRulerBackend {
return ErrResp(http.StatusBadRequest, errors.New("unexpected payload"), "")
}

View File

@ -0,0 +1,11 @@
package api
import (
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/web"
)
func (api *API) authorize(method, path string) web.Handler {
// TODO Add fine-grained authorization for every route
return middleware.ReqSignedIn
}

View File

@ -11,12 +11,13 @@ import (
// ForkedRulerApi will validate and proxy requests to the correct backend type depending on the datasource.
type ForkedRulerApi struct {
LotexRuler, GrafanaRuler RulerApiService
DatasourceCache datasources.CacheService
LotexRuler *LotexRuler
GrafanaRuler *RulerSrv
DatasourceCache datasources.CacheService
}
// NewForkedRuler implements a set of routes that proxy to various Cortex Ruler-compatible backends.
func NewForkedRuler(datasourceCache datasources.CacheService, lotex, grafana RulerApiService) *ForkedRulerApi {
func NewForkedRuler(datasourceCache datasources.CacheService, lotex *LotexRuler, grafana *RulerSrv) *ForkedRulerApi {
return &ForkedRulerApi{
LotexRuler: lotex,
GrafanaRuler: grafana,
@ -30,8 +31,6 @@ func (f *ForkedRulerApi) forkRouteDeleteNamespaceRulesConfig(ctx *models.ReqCont
return ErrResp(400, err, "")
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RouteDeleteNamespaceRulesConfig(ctx)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RouteDeleteNamespaceRulesConfig(ctx)
default:
@ -45,8 +44,6 @@ func (f *ForkedRulerApi) forkRouteDeleteRuleGroupConfig(ctx *models.ReqContext)
return ErrResp(400, err, "")
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RouteDeleteRuleGroupConfig(ctx)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RouteDeleteRuleGroupConfig(ctx)
default:
@ -60,8 +57,6 @@ func (f *ForkedRulerApi) forkRouteGetNamespaceRulesConfig(ctx *models.ReqContext
return ErrResp(400, err, "")
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RouteGetNamespaceRulesConfig(ctx)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RouteGetNamespaceRulesConfig(ctx)
default:
@ -75,8 +70,6 @@ func (f *ForkedRulerApi) forkRouteGetRulegGroupConfig(ctx *models.ReqContext) re
return ErrResp(400, err, "")
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RouteGetRulegGroupConfig(ctx)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RouteGetRulegGroupConfig(ctx)
default:
@ -90,8 +83,6 @@ func (f *ForkedRulerApi) forkRouteGetRulesConfig(ctx *models.ReqContext) respons
return ErrResp(400, err, "")
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RouteGetRulesConfig(ctx)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RouteGetRulesConfig(ctx)
default:
@ -111,11 +102,37 @@ func (f *ForkedRulerApi) forkRoutePostNameRulesConfig(ctx *models.ReqContext, co
}
switch backendType {
case apimodels.GrafanaBackend:
return f.GrafanaRuler.RoutePostNameRulesConfig(ctx, conf)
case apimodels.LoTexRulerBackend:
return f.LotexRuler.RoutePostNameRulesConfig(ctx, conf)
default:
return ErrResp(400, fmt.Errorf("unexpected backend type (%v)", backendType), "")
}
}
func (f *ForkedRulerApi) forkRouteDeleteNamespaceGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaRuler.RouteDeleteNamespaceRulesConfig(ctx)
}
func (f *ForkedRulerApi) forkRouteDeleteGrafanaRuleGroupConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaRuler.RouteDeleteRuleGroupConfig(ctx)
}
func (f *ForkedRulerApi) forkRouteGetNamespaceGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaRuler.RouteGetNamespaceRulesConfig(ctx)
}
func (f *ForkedRulerApi) forkRouteGetGrafanaRuleGroupConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaRuler.RouteGetRulegGroupConfig(ctx)
}
func (f *ForkedRulerApi) forkRouteGetGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaRuler.RouteGetRulesConfig(ctx)
}
func (f *ForkedRulerApi) forkRoutePostNameGrafanaRulesConfig(ctx *models.ReqContext, conf apimodels.PostableRuleGroupConfig) response.Response {
payloadType := conf.Type()
if payloadType != apimodels.GrafanaBackend {
return ErrResp(400, fmt.Errorf("unexpected backend type (%v) vs payload type (%v)", apimodels.GrafanaBackend, payloadType), "")
}
return f.GrafanaRuler.RoutePostNameRulesConfig(ctx, conf)
}

View File

@ -8,11 +8,11 @@ import (
// ForkedConfigurationApi always forwards requests to grafana backend
type ForkedConfigurationApi struct {
grafana ConfigurationApiService
grafana *AdminSrv
}
// NewForkedConfiguration creates a new ForkedConfigurationApi instance
func NewForkedConfiguration(grafana ConfigurationApiService) *ForkedConfigurationApi {
func NewForkedConfiguration(grafana *AdminSrv) *ForkedConfigurationApi {
return &ForkedConfigurationApi{
grafana: grafana,
}

View File

@ -10,12 +10,13 @@ import (
)
type ForkedAlertmanagerApi struct {
AMSvc, GrafanaSvc AlertmanagerApiService
DatasourceCache datasources.CacheService
AMSvc *LotexAM
GrafanaSvc *AlertmanagerSrv
DatasourceCache datasources.CacheService
}
// NewForkedAM implements a set of routes that proxy to various Alertmanager-compatible backends.
func NewForkedAM(datasourceCache datasources.CacheService, proxy, grafana AlertmanagerApiService) *ForkedAlertmanagerApi {
func NewForkedAM(datasourceCache datasources.CacheService, proxy *LotexAM, grafana *AlertmanagerSrv) *ForkedAlertmanagerApi {
return &ForkedAlertmanagerApi{
AMSvc: proxy,
GrafanaSvc: grafana,
@ -23,15 +24,13 @@ func NewForkedAM(datasourceCache datasources.CacheService, proxy, grafana Alertm
}
}
func (f *ForkedAlertmanagerApi) getService(ctx *models.ReqContext) (AlertmanagerApiService, error) {
func (f *ForkedAlertmanagerApi) getService(ctx *models.ReqContext) (*LotexAM, error) {
t, err := backendType(ctx, f.DatasourceCache)
if err != nil {
return nil, err
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaSvc, nil
case apimodels.AlertmanagerBackend:
return f.AMSvc, nil
default:
@ -155,3 +154,51 @@ func (f *ForkedAlertmanagerApi) forkRoutePostTestReceivers(ctx *models.ReqContex
return s.RoutePostTestReceivers(ctx, body)
}
func (f *ForkedAlertmanagerApi) forkRouteDeleteGrafanaSilence(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteDeleteSilence(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteDeleteGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteDeleteAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteCreateGrafanaSilence(ctx *models.ReqContext, body apimodels.PostableSilence) response.Response {
return f.GrafanaSvc.RouteCreateSilence(ctx, body)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaAMStatus(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetAMStatus(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaAMAlerts(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetAMAlerts(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaAMAlertGroups(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetAMAlertGroups(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaSilence(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetSilence(ctx)
}
func (f *ForkedAlertmanagerApi) forkRouteGetGrafanaSilences(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetSilences(ctx)
}
func (f *ForkedAlertmanagerApi) forkRoutePostGrafanaAMAlerts(ctx *models.ReqContext, conf apimodels.PostableAlerts) response.Response {
return f.GrafanaSvc.RoutePostAMAlerts(ctx, conf)
}
func (f *ForkedAlertmanagerApi) forkRoutePostGrafanaAlertingConfig(ctx *models.ReqContext, conf apimodels.PostableUserConfig) response.Response {
return f.GrafanaSvc.RoutePostAlertingConfig(ctx, conf)
}
func (f *ForkedAlertmanagerApi) forkRoutePostTestGrafanaReceivers(ctx *models.ReqContext, conf apimodels.TestReceiversConfigBodyParams) response.Response {
return f.GrafanaSvc.RoutePostTestReceivers(ctx, conf)
}

View File

@ -10,12 +10,13 @@ import (
)
type ForkedPrometheusApi struct {
ProxySvc, GrafanaSvc PrometheusApiService
DatasourceCache datasources.CacheService
ProxySvc *LotexProm
GrafanaSvc *PrometheusSrv
DatasourceCache datasources.CacheService
}
// NewForkedProm implements a set of routes that proxy to various Prometheus-compatible backends.
func NewForkedProm(datasourceCache datasources.CacheService, proxy, grafana PrometheusApiService) *ForkedPrometheusApi {
func NewForkedProm(datasourceCache datasources.CacheService, proxy *LotexProm, grafana *PrometheusSrv) *ForkedPrometheusApi {
return &ForkedPrometheusApi{
ProxySvc: proxy,
GrafanaSvc: grafana,
@ -30,8 +31,6 @@ func (f *ForkedPrometheusApi) forkRouteGetAlertStatuses(ctx *models.ReqContext)
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaSvc.RouteGetAlertStatuses(ctx)
case apimodels.LoTexRulerBackend:
return f.ProxySvc.RouteGetAlertStatuses(ctx)
default:
@ -46,11 +45,17 @@ func (f *ForkedPrometheusApi) forkRouteGetRuleStatuses(ctx *models.ReqContext) r
}
switch t {
case apimodels.GrafanaBackend:
return f.GrafanaSvc.RouteGetRuleStatuses(ctx)
case apimodels.LoTexRulerBackend:
return f.ProxySvc.RouteGetRuleStatuses(ctx)
default:
return ErrResp(400, fmt.Errorf("unexpected backend type (%v)", t), "")
}
}
func (f *ForkedPrometheusApi) forkRouteGetGrafanaAlertStatuses(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetAlertStatuses(ctx)
}
func (f *ForkedPrometheusApi) forkRouteGetGrafanaRuleStatuses(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetRuleStatuses(ctx)
}

View File

@ -8,20 +8,24 @@ import (
// ForkedTestingApi always forwards requests to grafana backend
type ForkedTestingApi struct {
grafana TestingApiService
svc *TestingApiSrv
}
// NewForkedTestingApi creates a new ForkedTestingApi instance
func NewForkedTestingApi(grafana TestingApiService) *ForkedTestingApi {
func NewForkedTestingApi(svc *TestingApiSrv) *ForkedTestingApi {
return &ForkedTestingApi{
grafana: grafana,
svc: svc,
}
}
func (f *ForkedTestingApi) forkRouteTestRuleConfig(c *models.ReqContext, body apimodels.TestRulePayload) response.Response {
return f.grafana.RouteTestRuleConfig(c, body)
return f.svc.RouteTestRuleConfig(c, body)
}
func (f *ForkedTestingApi) forkRouteTestRuleGrafanaConfig(c *models.ReqContext, body apimodels.TestRulePayload) response.Response {
return f.svc.RouteTestGrafanaRuleConfig(c, body)
}
func (f *ForkedTestingApi) forkRouteEvalQueries(c *models.ReqContext, body apimodels.EvalQueriesPayload) response.Response {
return f.grafana.RouteEvalQueries(c, body)
return f.svc.RouteEvalQueries(c, body)
}

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
@ -20,33 +19,38 @@ import (
)
type AlertmanagerApiForkingService interface {
RouteCreateGrafanaSilence(*models.ReqContext) response.Response
RouteCreateSilence(*models.ReqContext) response.Response
RouteDeleteAlertingConfig(*models.ReqContext) response.Response
RouteDeleteGrafanaAlertingConfig(*models.ReqContext) response.Response
RouteDeleteGrafanaSilence(*models.ReqContext) response.Response
RouteDeleteSilence(*models.ReqContext) response.Response
RouteGetAMAlertGroups(*models.ReqContext) response.Response
RouteGetAMAlerts(*models.ReqContext) response.Response
RouteGetAMStatus(*models.ReqContext) response.Response
RouteGetAlertingConfig(*models.ReqContext) response.Response
RouteGetGrafanaAMAlertGroups(*models.ReqContext) response.Response
RouteGetGrafanaAMAlerts(*models.ReqContext) response.Response
RouteGetGrafanaAMStatus(*models.ReqContext) response.Response
RouteGetGrafanaAlertingConfig(*models.ReqContext) response.Response
RouteGetGrafanaSilence(*models.ReqContext) response.Response
RouteGetGrafanaSilences(*models.ReqContext) response.Response
RouteGetSilence(*models.ReqContext) response.Response
RouteGetSilences(*models.ReqContext) response.Response
RoutePostAMAlerts(*models.ReqContext) response.Response
RoutePostAlertingConfig(*models.ReqContext) response.Response
RoutePostGrafanaAMAlerts(*models.ReqContext) response.Response
RoutePostGrafanaAlertingConfig(*models.ReqContext) response.Response
RoutePostTestGrafanaReceivers(*models.ReqContext) response.Response
RoutePostTestReceivers(*models.ReqContext) response.Response
}
type AlertmanagerApiService interface {
RouteCreateSilence(*models.ReqContext, apimodels.PostableSilence) response.Response
RouteDeleteAlertingConfig(*models.ReqContext) response.Response
RouteDeleteSilence(*models.ReqContext) response.Response
RouteGetAMAlertGroups(*models.ReqContext) response.Response
RouteGetAMAlerts(*models.ReqContext) response.Response
RouteGetAMStatus(*models.ReqContext) response.Response
RouteGetAlertingConfig(*models.ReqContext) response.Response
RouteGetSilence(*models.ReqContext) response.Response
RouteGetSilences(*models.ReqContext) response.Response
RoutePostAMAlerts(*models.ReqContext, apimodels.PostableAlerts) response.Response
RoutePostAlertingConfig(*models.ReqContext, apimodels.PostableUserConfig) response.Response
RoutePostTestReceivers(*models.ReqContext, apimodels.TestReceiversConfigBodyParams) response.Response
func (f *ForkedAlertmanagerApi) RouteCreateGrafanaSilence(ctx *models.ReqContext) response.Response {
conf := apimodels.PostableSilence{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRouteCreateGrafanaSilence(ctx, conf)
}
func (f *ForkedAlertmanagerApi) RouteCreateSilence(ctx *models.ReqContext) response.Response {
@ -61,6 +65,14 @@ func (f *ForkedAlertmanagerApi) RouteDeleteAlertingConfig(ctx *models.ReqContext
return f.forkRouteDeleteAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) RouteDeleteGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteGrafanaAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) RouteDeleteGrafanaSilence(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteGrafanaSilence(ctx)
}
func (f *ForkedAlertmanagerApi) RouteDeleteSilence(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteSilence(ctx)
}
@ -81,6 +93,30 @@ func (f *ForkedAlertmanagerApi) RouteGetAlertingConfig(ctx *models.ReqContext) r
return f.forkRouteGetAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaAMAlertGroups(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaAMAlertGroups(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaAMAlerts(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaAMAlerts(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaAMStatus(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaAMStatus(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaAlertingConfig(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaSilence(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaSilence(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetGrafanaSilences(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaSilences(ctx)
}
func (f *ForkedAlertmanagerApi) RouteGetSilence(ctx *models.ReqContext) response.Response {
return f.forkRouteGetSilence(ctx)
}
@ -105,6 +141,30 @@ func (f *ForkedAlertmanagerApi) RoutePostAlertingConfig(ctx *models.ReqContext)
return f.forkRoutePostAlertingConfig(ctx, conf)
}
func (f *ForkedAlertmanagerApi) RoutePostGrafanaAMAlerts(ctx *models.ReqContext) response.Response {
conf := apimodels.PostableAlerts{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRoutePostGrafanaAMAlerts(ctx, conf)
}
func (f *ForkedAlertmanagerApi) RoutePostGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
conf := apimodels.PostableUserConfig{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRoutePostGrafanaAlertingConfig(ctx, conf)
}
func (f *ForkedAlertmanagerApi) RoutePostTestGrafanaReceivers(ctx *models.ReqContext) response.Response {
conf := apimodels.TestReceiversConfigBodyParams{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRoutePostTestGrafanaReceivers(ctx, conf)
}
func (f *ForkedAlertmanagerApi) RoutePostTestReceivers(ctx *models.ReqContext) response.Response {
conf := apimodels.TestReceiversConfigBodyParams{}
if err := web.Bind(ctx.Req, &conf); err != nil {
@ -115,8 +175,19 @@ func (f *ForkedAlertmanagerApi) RoutePostTestReceivers(ctx *models.ReqContext) r
func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingService, m *metrics.API) {
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Post(
toMacaronPath("/api/alertmanager/grafana/api/v2/silences"),
api.authorize(http.MethodPost, "/api/alertmanager/grafana/api/v2/silences"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/grafana/api/v2/silences",
srv.RouteCreateGrafanaSilence,
m,
),
)
group.Post(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/silences"),
api.authorize(http.MethodPost, "/api/alertmanager/{Recipient}/api/v2/silences"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/{Recipient}/api/v2/silences",
@ -126,6 +197,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Delete(
toMacaronPath("/api/alertmanager/{Recipient}/config/api/v1/alerts"),
api.authorize(http.MethodDelete, "/api/alertmanager/{Recipient}/config/api/v1/alerts"),
metrics.Instrument(
http.MethodDelete,
"/api/alertmanager/{Recipient}/config/api/v1/alerts",
@ -133,8 +205,29 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
m,
),
)
group.Delete(
toMacaronPath("/api/alertmanager/grafana/config/api/v1/alerts"),
api.authorize(http.MethodDelete, "/api/alertmanager/grafana/config/api/v1/alerts"),
metrics.Instrument(
http.MethodDelete,
"/api/alertmanager/grafana/config/api/v1/alerts",
srv.RouteDeleteGrafanaAlertingConfig,
m,
),
)
group.Delete(
toMacaronPath("/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),
api.authorize(http.MethodDelete, "/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),
metrics.Instrument(
http.MethodDelete,
"/api/alertmanager/grafana/api/v2/silence/{SilenceId}",
srv.RouteDeleteGrafanaSilence,
m,
),
)
group.Delete(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"),
api.authorize(http.MethodDelete, "/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"),
metrics.Instrument(
http.MethodDelete,
"/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}",
@ -144,6 +237,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/alerts/groups"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/api/v2/alerts/groups"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/api/v2/alerts/groups",
@ -153,6 +247,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/alerts"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/api/v2/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/api/v2/alerts",
@ -162,6 +257,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/status"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/api/v2/status"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/api/v2/status",
@ -171,6 +267,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/config/api/v1/alerts"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/config/api/v1/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/config/api/v1/alerts",
@ -178,8 +275,69 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/alerts/groups"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/alerts/groups"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/api/v2/alerts/groups",
srv.RouteGetGrafanaAMAlertGroups,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/alerts"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/api/v2/alerts",
srv.RouteGetGrafanaAMAlerts,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/status"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/status"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/api/v2/status",
srv.RouteGetGrafanaAMStatus,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/config/api/v1/alerts"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/config/api/v1/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/config/api/v1/alerts",
srv.RouteGetGrafanaAlertingConfig,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/api/v2/silence/{SilenceId}",
srv.RouteGetGrafanaSilence,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/silences"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/silences"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/api/v2/silences",
srv.RouteGetGrafanaSilences,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/api/v2/silence/{SilenceId}",
@ -189,6 +347,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Get(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/silences"),
api.authorize(http.MethodGet, "/api/alertmanager/{Recipient}/api/v2/silences"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/{Recipient}/api/v2/silences",
@ -198,6 +357,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Post(
toMacaronPath("/api/alertmanager/{Recipient}/api/v2/alerts"),
api.authorize(http.MethodPost, "/api/alertmanager/{Recipient}/api/v2/alerts"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/{Recipient}/api/v2/alerts",
@ -207,6 +367,7 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
)
group.Post(
toMacaronPath("/api/alertmanager/{Recipient}/config/api/v1/alerts"),
api.authorize(http.MethodPost, "/api/alertmanager/{Recipient}/config/api/v1/alerts"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/{Recipient}/config/api/v1/alerts",
@ -214,8 +375,39 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
m,
),
)
group.Post(
toMacaronPath("/api/alertmanager/grafana/api/v2/alerts"),
api.authorize(http.MethodPost, "/api/alertmanager/grafana/api/v2/alerts"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/grafana/api/v2/alerts",
srv.RoutePostGrafanaAMAlerts,
m,
),
)
group.Post(
toMacaronPath("/api/alertmanager/grafana/config/api/v1/alerts"),
api.authorize(http.MethodPost, "/api/alertmanager/grafana/config/api/v1/alerts"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/grafana/config/api/v1/alerts",
srv.RoutePostGrafanaAlertingConfig,
m,
),
)
group.Post(
toMacaronPath("/api/alertmanager/grafana/config/api/v1/receivers/test"),
api.authorize(http.MethodPost, "/api/alertmanager/grafana/config/api/v1/receivers/test"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/grafana/config/api/v1/receivers/test",
srv.RoutePostTestGrafanaReceivers,
m,
),
)
group.Post(
toMacaronPath("/api/alertmanager/{Recipient}/config/api/v1/receivers/test"),
api.authorize(http.MethodPost, "/api/alertmanager/{Recipient}/config/api/v1/receivers/test"),
metrics.Instrument(
http.MethodPost,
"/api/alertmanager/{Recipient}/config/api/v1/receivers/test",
@ -223,5 +415,5 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiForkingServi
m,
),
)
}, middleware.ReqSignedIn)
})
}

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
@ -26,13 +25,6 @@ type ConfigurationApiForkingService interface {
RoutePostNGalertConfig(*models.ReqContext) response.Response
}
type ConfigurationApiService interface {
RouteDeleteNGalertConfig(*models.ReqContext) response.Response
RouteGetAlertmanagers(*models.ReqContext) response.Response
RouteGetNGalertConfig(*models.ReqContext) response.Response
RoutePostNGalertConfig(*models.ReqContext, apimodels.PostableNGalertConfig) response.Response
}
func (f *ForkedConfigurationApi) RouteDeleteNGalertConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteNGalertConfig(ctx)
}
@ -57,6 +49,7 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApiForkingSer
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Delete(
toMacaronPath("/api/v1/ngalert/admin_config"),
api.authorize(http.MethodDelete, "/api/v1/ngalert/admin_config"),
metrics.Instrument(
http.MethodDelete,
"/api/v1/ngalert/admin_config",
@ -66,6 +59,7 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApiForkingSer
)
group.Get(
toMacaronPath("/api/v1/ngalert/alertmanagers"),
api.authorize(http.MethodGet, "/api/v1/ngalert/alertmanagers"),
metrics.Instrument(
http.MethodGet,
"/api/v1/ngalert/alertmanagers",
@ -75,6 +69,7 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApiForkingSer
)
group.Get(
toMacaronPath("/api/v1/ngalert/admin_config"),
api.authorize(http.MethodGet, "/api/v1/ngalert/admin_config"),
metrics.Instrument(
http.MethodGet,
"/api/v1/ngalert/admin_config",
@ -84,6 +79,7 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApiForkingSer
)
group.Post(
toMacaronPath("/api/v1/ngalert/admin_config"),
api.authorize(http.MethodPost, "/api/v1/ngalert/admin_config"),
metrics.Instrument(
http.MethodPost,
"/api/v1/ngalert/admin_config",
@ -91,5 +87,5 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApiForkingSer
m,
),
)
}, middleware.ReqSignedIn)
})
}

View File

@ -12,18 +12,14 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
)
type PrometheusApiForkingService interface {
RouteGetAlertStatuses(*models.ReqContext) response.Response
RouteGetRuleStatuses(*models.ReqContext) response.Response
}
type PrometheusApiService interface {
RouteGetAlertStatuses(*models.ReqContext) response.Response
RouteGetGrafanaAlertStatuses(*models.ReqContext) response.Response
RouteGetGrafanaRuleStatuses(*models.ReqContext) response.Response
RouteGetRuleStatuses(*models.ReqContext) response.Response
}
@ -31,6 +27,14 @@ func (f *ForkedPrometheusApi) RouteGetAlertStatuses(ctx *models.ReqContext) resp
return f.forkRouteGetAlertStatuses(ctx)
}
func (f *ForkedPrometheusApi) RouteGetGrafanaAlertStatuses(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaAlertStatuses(ctx)
}
func (f *ForkedPrometheusApi) RouteGetGrafanaRuleStatuses(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaRuleStatuses(ctx)
}
func (f *ForkedPrometheusApi) RouteGetRuleStatuses(ctx *models.ReqContext) response.Response {
return f.forkRouteGetRuleStatuses(ctx)
}
@ -39,6 +43,7 @@ func (api *API) RegisterPrometheusApiEndpoints(srv PrometheusApiForkingService,
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Get(
toMacaronPath("/api/prometheus/{Recipient}/api/v1/alerts"),
api.authorize(http.MethodGet, "/api/prometheus/{Recipient}/api/v1/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/prometheus/{Recipient}/api/v1/alerts",
@ -46,8 +51,29 @@ func (api *API) RegisterPrometheusApiEndpoints(srv PrometheusApiForkingService,
m,
),
)
group.Get(
toMacaronPath("/api/prometheus/grafana/api/v1/alerts"),
api.authorize(http.MethodGet, "/api/prometheus/grafana/api/v1/alerts"),
metrics.Instrument(
http.MethodGet,
"/api/prometheus/grafana/api/v1/alerts",
srv.RouteGetGrafanaAlertStatuses,
m,
),
)
group.Get(
toMacaronPath("/api/prometheus/grafana/api/v1/rules"),
api.authorize(http.MethodGet, "/api/prometheus/grafana/api/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/prometheus/grafana/api/v1/rules",
srv.RouteGetGrafanaRuleStatuses,
m,
),
)
group.Get(
toMacaronPath("/api/prometheus/{Recipient}/api/v1/rules"),
api.authorize(http.MethodGet, "/api/prometheus/{Recipient}/api/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/prometheus/{Recipient}/api/v1/rules",
@ -55,5 +81,5 @@ func (api *API) RegisterPrometheusApiEndpoints(srv PrometheusApiForkingService,
m,
),
)
}, middleware.ReqSignedIn)
})
}

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
@ -20,21 +19,26 @@ import (
)
type RulerApiForkingService interface {
RouteDeleteGrafanaRuleGroupConfig(*models.ReqContext) response.Response
RouteDeleteNamespaceGrafanaRulesConfig(*models.ReqContext) response.Response
RouteDeleteNamespaceRulesConfig(*models.ReqContext) response.Response
RouteDeleteRuleGroupConfig(*models.ReqContext) response.Response
RouteGetGrafanaRuleGroupConfig(*models.ReqContext) response.Response
RouteGetGrafanaRulesConfig(*models.ReqContext) response.Response
RouteGetNamespaceGrafanaRulesConfig(*models.ReqContext) response.Response
RouteGetNamespaceRulesConfig(*models.ReqContext) response.Response
RouteGetRulegGroupConfig(*models.ReqContext) response.Response
RouteGetRulesConfig(*models.ReqContext) response.Response
RoutePostNameGrafanaRulesConfig(*models.ReqContext) response.Response
RoutePostNameRulesConfig(*models.ReqContext) response.Response
}
type RulerApiService interface {
RouteDeleteNamespaceRulesConfig(*models.ReqContext) response.Response
RouteDeleteRuleGroupConfig(*models.ReqContext) response.Response
RouteGetNamespaceRulesConfig(*models.ReqContext) response.Response
RouteGetRulegGroupConfig(*models.ReqContext) response.Response
RouteGetRulesConfig(*models.ReqContext) response.Response
RoutePostNameRulesConfig(*models.ReqContext, apimodels.PostableRuleGroupConfig) response.Response
func (f *ForkedRulerApi) RouteDeleteGrafanaRuleGroupConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteGrafanaRuleGroupConfig(ctx)
}
func (f *ForkedRulerApi) RouteDeleteNamespaceGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteDeleteNamespaceGrafanaRulesConfig(ctx)
}
func (f *ForkedRulerApi) RouteDeleteNamespaceRulesConfig(ctx *models.ReqContext) response.Response {
@ -45,6 +49,18 @@ func (f *ForkedRulerApi) RouteDeleteRuleGroupConfig(ctx *models.ReqContext) resp
return f.forkRouteDeleteRuleGroupConfig(ctx)
}
func (f *ForkedRulerApi) RouteGetGrafanaRuleGroupConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaRuleGroupConfig(ctx)
}
func (f *ForkedRulerApi) RouteGetGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteGetGrafanaRulesConfig(ctx)
}
func (f *ForkedRulerApi) RouteGetNamespaceGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteGetNamespaceGrafanaRulesConfig(ctx)
}
func (f *ForkedRulerApi) RouteGetNamespaceRulesConfig(ctx *models.ReqContext) response.Response {
return f.forkRouteGetNamespaceRulesConfig(ctx)
}
@ -57,6 +73,14 @@ func (f *ForkedRulerApi) RouteGetRulesConfig(ctx *models.ReqContext) response.Re
return f.forkRouteGetRulesConfig(ctx)
}
func (f *ForkedRulerApi) RoutePostNameGrafanaRulesConfig(ctx *models.ReqContext) response.Response {
conf := apimodels.PostableRuleGroupConfig{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRoutePostNameGrafanaRulesConfig(ctx, conf)
}
func (f *ForkedRulerApi) RoutePostNameRulesConfig(ctx *models.ReqContext) response.Response {
conf := apimodels.PostableRuleGroupConfig{}
if err := web.Bind(ctx.Req, &conf); err != nil {
@ -67,8 +91,29 @@ func (f *ForkedRulerApi) RoutePostNameRulesConfig(ctx *models.ReqContext) respon
func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics.API) {
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Delete(
toMacaronPath("/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodDelete, "/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}",
srv.RouteDeleteGrafanaRuleGroupConfig,
m,
),
)
group.Delete(
toMacaronPath("/api/ruler/grafana/api/v1/rules/{Namespace}"),
api.authorize(http.MethodDelete, "/api/ruler/grafana/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/grafana/api/v1/rules/{Namespace}",
srv.RouteDeleteNamespaceGrafanaRulesConfig,
m,
),
)
group.Delete(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodDelete, "/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/{Recipient}/api/v1/rules/{Namespace}",
@ -78,6 +123,7 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
)
group.Delete(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodDelete, "/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodDelete,
"/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}",
@ -85,8 +131,39 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
m,
),
)
group.Get(
toMacaronPath("/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodGet, "/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}",
srv.RouteGetGrafanaRuleGroupConfig,
m,
),
)
group.Get(
toMacaronPath("/api/ruler/grafana/api/v1/rules"),
api.authorize(http.MethodGet, "/api/ruler/grafana/api/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/grafana/api/v1/rules",
srv.RouteGetGrafanaRulesConfig,
m,
),
)
group.Get(
toMacaronPath("/api/ruler/grafana/api/v1/rules/{Namespace}"),
api.authorize(http.MethodGet, "/api/ruler/grafana/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/grafana/api/v1/rules/{Namespace}",
srv.RouteGetNamespaceGrafanaRulesConfig,
m,
),
)
group.Get(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodGet, "/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{Recipient}/api/v1/rules/{Namespace}",
@ -96,6 +173,7 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
)
group.Get(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}"),
api.authorize(http.MethodGet, "/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname}",
@ -105,6 +183,7 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
)
group.Get(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules"),
api.authorize(http.MethodGet, "/api/ruler/{Recipient}/api/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/ruler/{Recipient}/api/v1/rules",
@ -112,8 +191,19 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
m,
),
)
group.Post(
toMacaronPath("/api/ruler/grafana/api/v1/rules/{Namespace}"),
api.authorize(http.MethodPost, "/api/ruler/grafana/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodPost,
"/api/ruler/grafana/api/v1/rules/{Namespace}",
srv.RoutePostNameGrafanaRulesConfig,
m,
),
)
group.Post(
toMacaronPath("/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
api.authorize(http.MethodPost, "/api/ruler/{Recipient}/api/v1/rules/{Namespace}"),
metrics.Instrument(
http.MethodPost,
"/api/ruler/{Recipient}/api/v1/rules/{Namespace}",
@ -121,5 +211,5 @@ func (api *API) RegisterRulerApiEndpoints(srv RulerApiForkingService, m *metrics
m,
),
)
}, middleware.ReqSignedIn)
})
}

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
@ -22,11 +21,7 @@ import (
type TestingApiForkingService interface {
RouteEvalQueries(*models.ReqContext) response.Response
RouteTestRuleConfig(*models.ReqContext) response.Response
}
type TestingApiService interface {
RouteEvalQueries(*models.ReqContext, apimodels.EvalQueriesPayload) response.Response
RouteTestRuleConfig(*models.ReqContext, apimodels.TestRulePayload) response.Response
RouteTestRuleGrafanaConfig(*models.ReqContext) response.Response
}
func (f *ForkedTestingApi) RouteEvalQueries(ctx *models.ReqContext) response.Response {
@ -45,10 +40,19 @@ func (f *ForkedTestingApi) RouteTestRuleConfig(ctx *models.ReqContext) response.
return f.forkRouteTestRuleConfig(ctx, conf)
}
func (f *ForkedTestingApi) RouteTestRuleGrafanaConfig(ctx *models.ReqContext) response.Response {
conf := apimodels.TestRulePayload{}
if err := web.Bind(ctx.Req, &conf); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
return f.forkRouteTestRuleGrafanaConfig(ctx, conf)
}
func (api *API) RegisterTestingApiEndpoints(srv TestingApiForkingService, m *metrics.API) {
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Post(
toMacaronPath("/api/v1/eval"),
api.authorize(http.MethodPost, "/api/v1/eval"),
metrics.Instrument(
http.MethodPost,
"/api/v1/eval",
@ -58,6 +62,7 @@ func (api *API) RegisterTestingApiEndpoints(srv TestingApiForkingService, m *met
)
group.Post(
toMacaronPath("/api/v1/rule/test/{Recipient}"),
api.authorize(http.MethodPost, "/api/v1/rule/test/{Recipient}"),
metrics.Instrument(
http.MethodPost,
"/api/v1/rule/test/{Recipient}",
@ -65,5 +70,15 @@ func (api *API) RegisterTestingApiEndpoints(srv TestingApiForkingService, m *met
m,
),
)
}, middleware.ReqSignedIn)
group.Post(
toMacaronPath("/api/v1/rule/test/grafana"),
api.authorize(http.MethodPost, "/api/v1/rule/test/grafana"),
metrics.Instrument(
http.MethodPost,
"/api/v1/rule/test/grafana",
srv.RouteTestRuleGrafanaConfig,
m,
),
)
})
}

View File

@ -10,17 +10,26 @@ import (
"time"
"github.com/go-openapi/strfmt"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/util"
"github.com/pkg/errors"
amv2 "github.com/prometheus/alertmanager/api/v2/models"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/pkg/labels"
"github.com/prometheus/common/model"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/util"
)
// swagger:route POST /api/alertmanager/grafana/config/api/v1/alerts alertmanager RoutePostGrafanaAlertingConfig
//
// sets an Alerting config
//
// Responses:
// 201: Ack
// 400: ValidationError
// swagger:route POST /api/alertmanager/{Recipient}/config/api/v1/alerts alertmanager RoutePostAlertingConfig
//
// sets an Alerting config
@ -29,6 +38,14 @@ import (
// 201: Ack
// 400: ValidationError
// swagger:route GET /api/alertmanager/grafana/config/api/v1/alerts alertmanager RouteGetGrafanaAlertingConfig
//
// gets an Alerting config
//
// Responses:
// 200: GettableUserConfig
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/config/api/v1/alerts alertmanager RouteGetAlertingConfig
//
// gets an Alerting config
@ -37,6 +54,14 @@ import (
// 200: GettableUserConfig
// 400: ValidationError
// swagger:route DELETE /api/alertmanager/grafana/config/api/v1/alerts alertmanager RouteDeleteGrafanaAlertingConfig
//
// deletes the Alerting config for a tenant
//
// Responses:
// 200: Ack
// 400: ValidationError
// swagger:route DELETE /api/alertmanager/{Recipient}/config/api/v1/alerts alertmanager RouteDeleteAlertingConfig
//
// deletes the Alerting config for a tenant
@ -45,6 +70,14 @@ import (
// 200: Ack
// 400: ValidationError
// swagger:route GET /api/alertmanager/grafana/api/v2/status alertmanager RouteGetGrafanaAMStatus
//
// get alertmanager status and configuration
//
// Responses:
// 200: GettableStatus
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/api/v2/status alertmanager RouteGetAMStatus
//
// get alertmanager status and configuration
@ -53,6 +86,14 @@ import (
// 200: GettableStatus
// 400: ValidationError
// swagger:route GET /api/alertmanager/grafana/api/v2/alerts alertmanager RouteGetGrafanaAMAlerts
//
// get alertmanager alerts
//
// Responses:
// 200: gettableAlerts
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/api/v2/alerts alertmanager RouteGetAMAlerts
//
// get alertmanager alerts
@ -61,6 +102,14 @@ import (
// 200: gettableAlerts
// 400: ValidationError
// swagger:route POST /api/alertmanager/grafana/api/v2/alerts alertmanager RoutePostGrafanaAMAlerts
//
// create alertmanager alerts
//
// Responses:
// 200: Ack
// 400: ValidationError
// swagger:route POST /api/alertmanager/{Recipient}/api/v2/alerts alertmanager RoutePostAMAlerts
//
// create alertmanager alerts
@ -69,6 +118,14 @@ import (
// 200: Ack
// 400: ValidationError
// swagger:route GET /api/alertmanager/grafana/api/v2/alerts/groups alertmanager RouteGetGrafanaAMAlertGroups
//
// get alertmanager alerts
//
// Responses:
// 200: alertGroups
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/api/v2/alerts/groups alertmanager RouteGetAMAlertGroups
//
// get alertmanager alerts
@ -77,6 +134,20 @@ import (
// 200: alertGroups
// 400: ValidationError
// swagger:route POST /api/alertmanager/grafana/config/api/v1/receivers/test alertmanager RoutePostTestGrafanaReceivers
//
// Test Grafana managed receivers without saving them.
//
// Responses:
//
// 200: Ack
// 207: MultiStatus
// 400: ValidationError
// 403: PermissionDenied
// 404: AlertManagerNotFound
// 408: Failure
// 409: AlertManagerNotReady
// swagger:route POST /api/alertmanager/{Recipient}/config/api/v1/receivers/test alertmanager RoutePostTestReceivers
//
// Test Grafana managed receivers without saving them.
@ -91,6 +162,14 @@ import (
// 408: Failure
// 409: AlertManagerNotReady
// swagger:route GET /api/alertmanager/grafana/api/v2/silences alertmanager RouteGetGrafanaSilences
//
// get silences
//
// Responses:
// 200: gettableSilences
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/api/v2/silences alertmanager RouteGetSilences
//
// get silences
@ -99,6 +178,14 @@ import (
// 200: gettableSilences
// 400: ValidationError
// swagger:route POST /api/alertmanager/grafana/api/v2/silences alertmanager RouteCreateGrafanaSilence
//
// create silence
//
// Responses:
// 201: gettableSilence
// 400: ValidationError
// swagger:route POST /api/alertmanager/{Recipient}/api/v2/silences alertmanager RouteCreateSilence
//
// create silence
@ -107,6 +194,14 @@ import (
// 201: gettableSilence
// 400: ValidationError
// swagger:route GET /api/alertmanager/grafana/api/v2/silence/{SilenceId} alertmanager RouteGetGrafanaSilence
//
// get silence
//
// Responses:
// 200: gettableSilence
// 400: ValidationError
// swagger:route GET /api/alertmanager/{Recipient}/api/v2/silence/{SilenceId} alertmanager RouteGetSilence
//
// get silence
@ -115,6 +210,14 @@ import (
// 200: gettableSilence
// 400: ValidationError
// swagger:route DELETE /api/alertmanager/grafana/api/v2/silence/{SilenceId} alertmanager RouteDeleteGrafanaSilence
//
// delete silence
//
// Responses:
// 200: Ack
// 400: ValidationError
// swagger:route DELETE /api/alertmanager/{Recipient}/api/v2/silence/{SilenceId} alertmanager RouteDeleteSilence
//
// delete silence
@ -135,7 +238,7 @@ type AlertManagerNotReady struct{}
// swagger:model
type MultiStatus struct{}
// swagger:parameters RoutePostTestReceivers
// swagger:parameters RoutePostTestReceivers RoutePostTestGrafanaReceivers
type TestReceiversConfigParams struct {
// in:body
Body TestReceiversConfigBodyParams
@ -176,25 +279,25 @@ type TestReceiverConfigResult struct {
Error string `json:"error,omitempty"`
}
// swagger:parameters RouteCreateSilence
// swagger:parameters RouteCreateSilence RouteCreateGrafanaSilence
type CreateSilenceParams struct {
// in:body
Silence PostableSilence
}
// swagger:parameters RouteGetSilence RouteDeleteSilence
// swagger:parameters RouteGetSilence RouteDeleteSilence RouteGetGrafanaSilence RouteDeleteGrafanaSilence
type GetDeleteSilenceParams struct {
// in:path
SilenceId string
}
// swagger:parameters RouteGetSilences
// swagger:parameters RouteGetSilences RouteGetGrafanaSilences
type GetSilencesParams struct {
// in:query
Filter []string `json:"filter"`
}
// swagger:parameters RouteGetRuleStatuses
// swagger:parameters RouteGetRuleStatuses RouteGetGrafanaRuleStatuses
type GetRuleStatusesParams struct {
// in: query
DashboardUID string
@ -299,7 +402,7 @@ type AlertGroup = amv2.AlertGroup
// swagger:model receiver
type Receiver = amv2.Receiver
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups RouteGetGrafanaAMAlerts RouteGetGrafanaAMAlertGroups
type AlertsParams struct {
// Show active alerts
@ -331,13 +434,13 @@ type AlertsParams struct {
Receivers string `json:"receiver"`
}
// swagger:parameters RoutePostAMAlerts
// swagger:parameters RoutePostAMAlerts RoutePostGrafanaAMAlerts
type PostableAlerts struct {
// in:body
PostableAlerts []amv2.PostableAlert `yaml:"" json:""`
}
// swagger:parameters RoutePostAlertingConfig
// swagger:parameters RoutePostAlertingConfig RoutePostGrafanaAlertingConfig
type BodyAlertingConfig struct {
// in:body
Body PostableUserConfig
@ -352,10 +455,9 @@ type BodyAlertingConfig struct {
// testing routes
// swagger:parameters RouteTestReceiverConfig RouteTestRuleConfig
type DatasourceReference struct {
// Recipient should be "grafana" for requests to be handled by grafana
// and the numeric datasource id for requests to be forwarded to a datasource
// Recipient should be the numeric datasource id
// in:path
Recipient string
Recipient int
}
// swagger:model

View File

@ -5,10 +5,22 @@ import (
"fmt"
"time"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/prometheus/common/model"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
// swagger:route Get /api/ruler/grafana/api/v1/rules ruler RouteGetGrafanaRulesConfig
//
// List rule groups
//
// Produces:
// - application/json
//
// Responses:
// 202: NamespaceConfigResponse
//
// swagger:route Get /api/ruler/{Recipient}/api/v1/rules ruler RouteGetRulesConfig
//
// List rule groups
@ -19,6 +31,18 @@ import (
// Responses:
// 202: NamespaceConfigResponse
// swagger:route POST /api/ruler/grafana/api/v1/rules/{Namespace} ruler RoutePostNameGrafanaRulesConfig
//
// Creates or updates a rule group
//
// Consumes:
// - application/json
// - application/yaml
//
// Responses:
// 202: Ack
//
// swagger:route POST /api/ruler/{Recipient}/api/v1/rules/{Namespace} ruler RoutePostNameRulesConfig
//
// Creates or updates a rule group
@ -30,6 +54,16 @@ import (
// Responses:
// 202: Ack
// swagger:route Get /api/ruler/grafana/api/v1/rules/{Namespace} ruler RouteGetNamespaceGrafanaRulesConfig
//
// Get rule groups by namespace
//
// Produces:
// - application/json
//
// Responses:
// 202: NamespaceConfigResponse
// swagger:route Get /api/ruler/{Recipient}/api/v1/rules/{Namespace} ruler RouteGetNamespaceRulesConfig
//
// Get rule groups by namespace
@ -40,6 +74,13 @@ import (
// Responses:
// 202: NamespaceConfigResponse
// swagger:route Delete /api/ruler/grafana/api/v1/rules/{Namespace} ruler RouteDeleteNamespaceGrafanaRulesConfig
//
// Delete namespace
//
// Responses:
// 202: Ack
// swagger:route Delete /api/ruler/{Recipient}/api/v1/rules/{Namespace} ruler RouteDeleteNamespaceRulesConfig
//
// Delete namespace
@ -47,6 +88,16 @@ import (
// Responses:
// 202: Ack
// swagger:route Get /api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname} ruler RouteGetGrafanaRuleGroupConfig
//
// Get rule group
//
// Produces:
// - application/json
//
// Responses:
// 202: RuleGroupConfigResponse
// swagger:route Get /api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname} ruler RouteGetRulegGroupConfig
//
// Get rule group
@ -57,6 +108,13 @@ import (
// Responses:
// 202: RuleGroupConfigResponse
// swagger:route Delete /api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname} ruler RouteDeleteGrafanaRuleGroupConfig
//
// Delete rule group
//
// Responses:
// 202: Ack
// swagger:route Delete /api/ruler/{Recipient}/api/v1/rules/{Namespace}/{Groupname} ruler RouteDeleteRuleGroupConfig
//
// Delete rule group
@ -64,7 +122,7 @@ import (
// Responses:
// 202: Ack
// swagger:parameters RoutePostNameRulesConfig
// swagger:parameters RoutePostNameRulesConfig RoutePostNameGrafanaRulesConfig
type NamespaceConfig struct {
// in:path
Namespace string
@ -72,13 +130,13 @@ type NamespaceConfig struct {
Body PostableRuleGroupConfig
}
// swagger:parameters RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig
// swagger:parameters RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig RouteGetNamespaceGrafanaRulesConfig RouteDeleteNamespaceGrafanaRulesConfig
type PathNamespaceConfig struct {
// in: path
Namespace string
}
// swagger:parameters RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig
// swagger:parameters RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig RouteGetGrafanaRuleGroupConfig RouteDeleteGrafanaRuleGroupConfig
type PathRouleGroupConfig struct {
// in: path
Namespace string
@ -86,7 +144,7 @@ type PathRouleGroupConfig struct {
Groupname string
}
// swagger:parameters RouteGetRulesConfig
// swagger:parameters RouteGetRulesConfig RouteGetGrafanaRulesConfig
type PathGetRulesParams struct {
// in: query
DashboardUID string

View File

@ -6,6 +6,13 @@ import (
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
)
// swagger:route GET /api/prometheus/grafana/api/v1/rules prometheus RouteGetGrafanaRuleStatuses
//
// gets the evaluation statuses of all rules
//
// Responses:
// 200: RuleResponse
// swagger:route GET /api/prometheus/{Recipient}/api/v1/rules prometheus RouteGetRuleStatuses
//
// gets the evaluation statuses of all rules
@ -13,6 +20,13 @@ import (
// Responses:
// 200: RuleResponse
// swagger:route GET /api/prometheus/grafana/api/v1/alerts prometheus RouteGetGrafanaAlertStatuses
//
// gets the current alerts
//
// Responses:
// 200: AlertResponse
// swagger:route GET /api/prometheus/{Recipient}/api/v1/alerts prometheus RouteGetAlertStatuses
//
// gets the current alerts

View File

@ -7,14 +7,28 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/prometheus/promql"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
// swagger:route Post /api/v1/rule/test/grafana testing RouteTestRuleGrafanaConfig
//
// Test a rule against Grafana ruler
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
//
// Responses:
// 200: TestRuleResponse
// swagger:route Post /api/v1/rule/test/{Recipient} testing RouteTestRuleConfig
//
// Test rule
// Test a rule against external data source ruler
//
// Consumes:
// - application/json
@ -44,7 +58,7 @@ type TestReceiverRequest struct {
Body ExtendedReceiver
}
// swagger:parameters RouteTestRuleConfig
// swagger:parameters RouteTestRuleConfig RouteTestRuleGrafanaConfig
type TestRuleRequest struct {
// in:body
Body TestRulePayload

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,454 @@
},
"basePath": "/api/v1",
"paths": {
"/api/alertmanager/grafana/api/v2/alerts": {
"get": {
"description": "get alertmanager alerts",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaAMAlerts",
"parameters": [
{
"type": "boolean",
"default": true,
"x-go-name": "Active",
"description": "Show active alerts",
"name": "active",
"in": "query"
},
{
"type": "boolean",
"default": true,
"x-go-name": "Silenced",
"description": "Show silenced alerts",
"name": "silenced",
"in": "query"
},
{
"type": "boolean",
"default": true,
"x-go-name": "Inhibited",
"description": "Show inhibited alerts",
"name": "inhibited",
"in": "query"
},
{
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Matchers",
"description": "A list of matchers to filter alerts by",
"name": "filter",
"in": "query"
},
{
"type": "string",
"x-go-name": "Receivers",
"description": "A regex matching receivers to filter alerts by",
"name": "receiver",
"in": "query"
}
],
"responses": {
"200": {
"description": "gettableAlerts",
"schema": {
"$ref": "#/definitions/gettableAlerts"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
},
"post": {
"description": "create alertmanager alerts",
"tags": [
"alertmanager"
],
"operationId": "RoutePostGrafanaAMAlerts",
"parameters": [
{
"name": "PostableAlerts",
"in": "body",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/postableAlert"
}
}
}
],
"responses": {
"200": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/api/v2/alerts/groups": {
"get": {
"description": "get alertmanager alerts",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaAMAlertGroups",
"parameters": [
{
"type": "boolean",
"default": true,
"x-go-name": "Active",
"description": "Show active alerts",
"name": "active",
"in": "query"
},
{
"type": "boolean",
"default": true,
"x-go-name": "Silenced",
"description": "Show silenced alerts",
"name": "silenced",
"in": "query"
},
{
"type": "boolean",
"default": true,
"x-go-name": "Inhibited",
"description": "Show inhibited alerts",
"name": "inhibited",
"in": "query"
},
{
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Matchers",
"description": "A list of matchers to filter alerts by",
"name": "filter",
"in": "query"
},
{
"type": "string",
"x-go-name": "Receivers",
"description": "A regex matching receivers to filter alerts by",
"name": "receiver",
"in": "query"
}
],
"responses": {
"200": {
"description": "alertGroups",
"schema": {
"$ref": "#/definitions/alertGroups"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/api/v2/silence/{SilenceId}": {
"get": {
"description": "get silence",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaSilence",
"parameters": [
{
"type": "string",
"name": "SilenceId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "gettableSilence",
"schema": {
"$ref": "#/definitions/gettableSilence"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
},
"delete": {
"description": "delete silence",
"tags": [
"alertmanager"
],
"operationId": "RouteDeleteGrafanaSilence",
"parameters": [
{
"type": "string",
"name": "SilenceId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/api/v2/silences": {
"get": {
"description": "get silences",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaSilences",
"parameters": [
{
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Filter",
"name": "filter",
"in": "query"
}
],
"responses": {
"200": {
"description": "gettableSilences",
"schema": {
"$ref": "#/definitions/gettableSilences"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
},
"post": {
"description": "create silence",
"tags": [
"alertmanager"
],
"operationId": "RouteCreateGrafanaSilence",
"parameters": [
{
"name": "Silence",
"in": "body",
"schema": {
"$ref": "#/definitions/postableSilence"
}
}
],
"responses": {
"201": {
"description": "gettableSilence",
"schema": {
"$ref": "#/definitions/gettableSilence"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/api/v2/status": {
"get": {
"description": "get alertmanager status and configuration",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaAMStatus",
"responses": {
"200": {
"description": "GettableStatus",
"schema": {
"$ref": "#/definitions/GettableStatus"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/config/api/v1/alerts": {
"get": {
"description": "gets an Alerting config",
"tags": [
"alertmanager"
],
"operationId": "RouteGetGrafanaAlertingConfig",
"responses": {
"200": {
"description": "GettableUserConfig",
"schema": {
"$ref": "#/definitions/GettableUserConfig"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
},
"post": {
"description": "sets an Alerting config",
"tags": [
"alertmanager"
],
"operationId": "RoutePostGrafanaAlertingConfig",
"parameters": [
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/PostableUserConfig"
}
}
],
"responses": {
"201": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
},
"delete": {
"description": "deletes the Alerting config for a tenant",
"tags": [
"alertmanager"
],
"operationId": "RouteDeleteGrafanaAlertingConfig",
"responses": {
"200": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
},
"/api/alertmanager/grafana/config/api/v1/receivers/test": {
"post": {
"tags": [
"alertmanager"
],
"summary": "Test Grafana managed receivers without saving them.",
"operationId": "RoutePostTestGrafanaReceivers",
"parameters": [
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/TestReceiversConfigBodyParams"
}
}
],
"responses": {
"200": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
},
"207": {
"description": "MultiStatus",
"schema": {
"$ref": "#/definitions/MultiStatus"
}
},
"400": {
"description": "ValidationError",
"schema": {
"$ref": "#/definitions/ValidationError"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
},
"404": {
"description": "AlertManagerNotFound",
"schema": {
"$ref": "#/definitions/AlertManagerNotFound"
}
},
"408": {
"description": "Failure",
"schema": {
"$ref": "#/definitions/Failure"
}
},
"409": {
"description": "AlertManagerNotReady",
"schema": {
"$ref": "#/definitions/AlertManagerNotReady"
}
}
}
}
},
"/api/alertmanager/{Recipient}/api/v2/alerts": {
"get": {
"description": "get alertmanager alerts",
@ -67,8 +515,9 @@
"in": "query"
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -107,8 +556,9 @@
}
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -180,8 +630,9 @@
"in": "query"
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -218,8 +669,9 @@
"required": true
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -254,8 +706,9 @@
"required": true
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -295,8 +748,9 @@
"in": "query"
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -332,8 +786,9 @@
}
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -364,8 +819,9 @@
"operationId": "RouteGetAMStatus",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -396,8 +852,9 @@
"operationId": "RouteGetAlertingConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -433,8 +890,9 @@
}
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -463,8 +921,9 @@
"operationId": "RouteDeleteAlertingConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -502,8 +961,9 @@
}
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -555,6 +1015,53 @@
}
}
},
"/api/prometheus/grafana/api/v1/alerts": {
"get": {
"description": "gets the current alerts",
"tags": [
"prometheus"
],
"operationId": "RouteGetGrafanaAlertStatuses",
"responses": {
"200": {
"description": "AlertResponse",
"schema": {
"$ref": "#/definitions/AlertResponse"
}
}
}
}
},
"/api/prometheus/grafana/api/v1/rules": {
"get": {
"description": "gets the evaluation statuses of all rules",
"tags": [
"prometheus"
],
"operationId": "RouteGetGrafanaRuleStatuses",
"parameters": [
{
"type": "string",
"name": "DashboardUID",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"name": "PanelID",
"in": "query"
}
],
"responses": {
"200": {
"description": "RuleResponse",
"schema": {
"$ref": "#/definitions/RuleResponse"
}
}
}
}
},
"/api/prometheus/{Recipient}/api/v1/alerts": {
"get": {
"description": "gets the current alerts",
@ -564,8 +1071,9 @@
"operationId": "RouteGetAlertStatuses",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -601,8 +1109,9 @@
"in": "query"
},
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -618,6 +1127,187 @@
}
}
},
"/api/ruler/grafana/api/v1/rules": {
"get": {
"description": "List rule groups",
"produces": [
"application/json"
],
"tags": [
"ruler"
],
"operationId": "RouteGetGrafanaRulesConfig",
"parameters": [
{
"type": "string",
"name": "DashboardUID",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"name": "PanelID",
"in": "query"
}
],
"responses": {
"202": {
"description": "NamespaceConfigResponse",
"schema": {
"$ref": "#/definitions/NamespaceConfigResponse"
}
}
}
}
},
"/api/ruler/grafana/api/v1/rules/{Namespace}": {
"get": {
"description": "Get rule groups by namespace",
"produces": [
"application/json"
],
"tags": [
"ruler"
],
"operationId": "RouteGetNamespaceGrafanaRulesConfig",
"parameters": [
{
"type": "string",
"name": "Namespace",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "NamespaceConfigResponse",
"schema": {
"$ref": "#/definitions/NamespaceConfigResponse"
}
}
}
},
"post": {
"description": "Creates or updates a rule group",
"consumes": [
"application/json",
"application/yaml"
],
"tags": [
"ruler"
],
"operationId": "RoutePostNameGrafanaRulesConfig",
"parameters": [
{
"type": "string",
"name": "Namespace",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/PostableRuleGroupConfig"
}
}
],
"responses": {
"202": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
}
}
},
"delete": {
"description": "Delete namespace",
"tags": [
"ruler"
],
"operationId": "RouteDeleteNamespaceGrafanaRulesConfig",
"parameters": [
{
"type": "string",
"name": "Namespace",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
}
}
}
},
"/api/ruler/grafana/api/v1/rules/{Namespace}/{Groupname}": {
"get": {
"description": "Get rule group",
"produces": [
"application/json"
],
"tags": [
"ruler"
],
"operationId": "RouteGetGrafanaRuleGroupConfig",
"parameters": [
{
"type": "string",
"name": "Namespace",
"in": "path",
"required": true
},
{
"type": "string",
"name": "Groupname",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "RuleGroupConfigResponse",
"schema": {
"$ref": "#/definitions/RuleGroupConfigResponse"
}
}
}
},
"delete": {
"description": "Delete rule group",
"tags": [
"ruler"
],
"operationId": "RouteDeleteGrafanaRuleGroupConfig",
"parameters": [
{
"type": "string",
"name": "Namespace",
"in": "path",
"required": true
},
{
"type": "string",
"name": "Groupname",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "Ack",
"schema": {
"$ref": "#/definitions/Ack"
}
}
}
}
},
"/api/ruler/{Recipient}/api/v1/rules": {
"get": {
"description": "List rule groups",
@ -630,8 +1320,9 @@
"operationId": "RouteGetRulesConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -670,8 +1361,9 @@
"operationId": "RouteGetNamespaceRulesConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -704,8 +1396,9 @@
"operationId": "RoutePostNameRulesConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -741,8 +1434,9 @@
"operationId": "RouteDeleteNamespaceRulesConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -776,8 +1470,9 @@
"operationId": "RouteGetRulegGroupConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -812,8 +1507,9 @@
"operationId": "RouteDeleteRuleGroupConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -982,9 +1678,41 @@
}
}
},
"/api/v1/rule/test/grafana": {
"post": {
"description": "Test a rule against Grafana ruler",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"testing"
],
"operationId": "RouteTestRuleGrafanaConfig",
"parameters": [
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/TestRulePayload"
}
}
],
"responses": {
"200": {
"description": "TestRuleResponse",
"schema": {
"$ref": "#/definitions/TestRuleResponse"
}
}
}
}
},
"/api/v1/rule/test/{Recipient}": {
"post": {
"description": "Test rule",
"description": "Test a rule against external data source ruler",
"consumes": [
"application/json"
],
@ -997,8 +1725,9 @@
"operationId": "RouteTestRuleConfig",
"parameters": [
{
"type": "string",
"description": "Recipient should be \"grafana\" for requests to be handled by grafana\nand the numeric datasource id for requests to be forwarded to a datasource",
"type": "integer",
"format": "int64",
"description": "Recipient should be the numeric datasource id",
"name": "Recipient",
"in": "path",
"required": true
@ -3957,12 +4686,11 @@
"$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": {

View File

@ -17,10 +17,6 @@ type {{classname}}ForkingService interface { {{#operation}}
{{nickname}}(*models.ReqContext) response.Response{{/operation}}
}
type {{classname}}Service interface { {{#operation}}
{{nickname}}(*models.ReqContext{{#bodyParams}}, apimodels.{{dataType}}{{/bodyParams}}) response.Response{{/operation}}
}
{{#operations}}{{#operation}}
func (f *Forked{{classname}}) {{nickname}}(ctx *models.ReqContext) response.Response {
{{#bodyParams}}
@ -40,6 +36,7 @@ func (api *API) Register{{classname}}Endpoints(srv {{classname}}ForkingService,
api.RouteRegister.Group("", func(group routing.RouteRegister){ {{#operations}}{{#operation}}
group.{{httpMethod}}(
toMacaronPath("{{{path}}}"),
api.authorize(http.Method{{httpMethod}}, "{{{path}}}"),
metrics.Instrument(
http.Method{{httpMethod}},
"{{{path}}}",
@ -47,6 +44,6 @@ func (api *API) Register{{classname}}Endpoints(srv {{classname}}ForkingService,
m,
),
){{/operation}}{{/operations}}
}, middleware.ReqSignedIn)
})
}{{#operation}}
{{/operation}}{{/operations}}

View File

@ -13,6 +13,9 @@ import (
"strings"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
@ -26,8 +29,6 @@ import (
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
var searchRegex = regexp.MustCompile(`\{(\w+)\}`)
@ -43,9 +44,6 @@ func toMacaronPath(path string) string {
func backendType(ctx *models.ReqContext, cache datasources.CacheService) (apimodels.Backend, error) {
recipient := web.Params(ctx.Req)[":Recipient"]
if recipient == apimodels.GrafanaBackend.String() {
return apimodels.GrafanaBackend, nil
}
if datasourceID, err := strconv.ParseInt(recipient, 10, 64); err == nil {
if ds, err := cache.GetDatasource(ctx.Req.Context(), datasourceID, ctx.SignedInUser, ctx.SkipCache); err == nil {
switch ds.Type {