mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 16:02:43 +08:00

* wip * Add prom flavor support for data source variables and export/import dashboards (#103321) * add dashboard and data source var selection * use match plugin id instead * use updated matchpluginid * formatting * cleanup * regex anchor * update error msg * Alerting: Clean up prometheus-flavored types and functions (#103703) * clean up types and utility functions for dealing with prometheus-flavored data sources * Refactor alerting datasource types to use constants as source of truth * Alerting: Clean up prometheus-flavored types and functions on the bac… (#103716) Alerting: Clean up prometheus-flavored types and functions on the backend * add matchPluginId tests * Update matchPluginId func to bidirectional (#103746) * update matchpluginid func to bidirectional * lint * formatting * use actual isSupportedExternalRulesSourceType in test * add tests in datasource_srv * betterer * remove type assertion * remove unnecessary case * use satisifies to not have to convert tuple to an array of string * add prometheus_flavor test --------- Co-authored-by: Andrew Hackmann <5140848+bossinc@users.noreply.github.com> Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com> Co-authored-by: Alexander Akhmetov <me@alx.cx>
107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
"github.com/grafana/grafana/pkg/services/datasources"
|
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
|
"github.com/grafana/grafana/pkg/web"
|
|
)
|
|
|
|
type promEndpoints struct {
|
|
rules, alerts string
|
|
}
|
|
|
|
var (
|
|
prometheusEndpoints = promEndpoints{
|
|
rules: "/api/v1/rules",
|
|
alerts: "/api/v1/alerts",
|
|
}
|
|
lokiEndpoints = promEndpoints{
|
|
rules: "/prometheus/api/v1/rules",
|
|
alerts: "/prometheus/api/v1/alerts",
|
|
}
|
|
)
|
|
|
|
type LotexProm struct {
|
|
log log.Logger
|
|
*AlertingProxy
|
|
}
|
|
|
|
func NewLotexProm(proxy *AlertingProxy, log log.Logger) *LotexProm {
|
|
return &LotexProm{
|
|
log: log,
|
|
AlertingProxy: proxy,
|
|
}
|
|
}
|
|
|
|
func (p *LotexProm) RouteGetAlertStatuses(ctx *contextmodel.ReqContext) response.Response {
|
|
endpoints, err := p.getEndpoints(ctx)
|
|
if err != nil {
|
|
return ErrResp(http.StatusInternalServerError, err, "")
|
|
}
|
|
|
|
return p.withReq(
|
|
ctx,
|
|
http.MethodGet,
|
|
withPath(
|
|
*ctx.Req.URL,
|
|
endpoints.alerts,
|
|
),
|
|
nil,
|
|
jsonExtractor(&apimodels.AlertResponse{}),
|
|
nil,
|
|
)
|
|
}
|
|
|
|
func (p *LotexProm) RouteGetRuleStatuses(ctx *contextmodel.ReqContext) response.Response {
|
|
endpoints, err := p.getEndpoints(ctx)
|
|
if err != nil {
|
|
return ErrResp(http.StatusInternalServerError, err, "")
|
|
}
|
|
|
|
return p.withReq(
|
|
ctx,
|
|
http.MethodGet,
|
|
withPath(
|
|
*ctx.Req.URL,
|
|
endpoints.rules,
|
|
),
|
|
nil,
|
|
jsonExtractor(&apimodels.RuleResponse{}),
|
|
nil,
|
|
)
|
|
}
|
|
|
|
func (p *LotexProm) getEndpoints(ctx *contextmodel.ReqContext) (*promEndpoints, error) {
|
|
datasourceUID := web.Params(ctx.Req)[":DatasourceUID"]
|
|
if datasourceUID == "" {
|
|
return nil, fmt.Errorf("datasource UID is invalid")
|
|
}
|
|
|
|
ds, err := p.DataProxy.DataSourceCache.GetDatasourceByUID(ctx.Req.Context(), datasourceUID, ctx.SignedInUser, ctx.SkipDSCache)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if ds.URL == "" {
|
|
return nil, fmt.Errorf("URL for this data source is empty")
|
|
}
|
|
|
|
var routes promEndpoints
|
|
switch {
|
|
case isPrometheusCompatible(ds.Type):
|
|
routes = prometheusEndpoints
|
|
case ds.Type == datasources.DS_LOKI:
|
|
routes = lokiEndpoints
|
|
default:
|
|
return nil, unexpectedDatasourceTypeError(ds.Type, "loki, prometheus, amazon prometheus, azure prometheus")
|
|
}
|
|
|
|
return &routes, nil
|
|
}
|