Alerting: conversion API structure (#100258)

pull/100483/head
Alexander Akhmetov 5 months ago committed by GitHub
parent 9b37e9249a
commit 9593e51da7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      packages/grafana-data/src/types/featureToggles.gen.ts
  2. 8
      pkg/services/featuremgmt/registry.go
  3. 1
      pkg/services/featuremgmt/toggles_gen.csv
  4. 4
      pkg/services/featuremgmt/toggles_gen.go
  5. 14
      pkg/services/featuremgmt/toggles_gen.json
  6. 6
      pkg/services/ngalert/api/api.go
  7. 36
      pkg/services/ngalert/api/api_convert_prometheus.go
  8. 28
      pkg/services/ngalert/api/authorization.go
  9. 2
      pkg/services/ngalert/api/authorization_test.go
  10. 136
      pkg/services/ngalert/api/generated_base_api_convert_prometheus.go
  11. 56
      pkg/services/ngalert/api/prometheus_conversion.go
  12. 79
      pkg/services/ngalert/api/tooling/api.json
  13. 139
      pkg/services/ngalert/api/tooling/definitions/convert_prometheus_api.go
  14. 332
      pkg/services/ngalert/api/tooling/post.json
  15. 332
      pkg/services/ngalert/api/tooling/spec.json
  16. 9
      pkg/services/ngalert/api/tooling/swagger-codegen/templates/controller-api.mustache
  17. 79
      public/api-merged.json
  18. 79
      public/openapi3.json

@ -253,6 +253,7 @@ export interface FeatureToggles {
exploreMetricsUseExternalAppPlugin?: boolean;
datasourceConnectionsTab?: boolean;
fetchRulesUsingPost?: boolean;
alertingConversionAPI?: boolean;
alertingAlertmanagerExtraDedupStage?: boolean;
alertingAlertmanagerExtraDedupStageStopPipeline?: boolean;
newLogsPanel?: boolean;

@ -1760,6 +1760,14 @@ var (
HideFromAdminPage: true,
HideFromDocs: true,
},
{
Name: "alertingConversionAPI",
Description: "Enable the alerting conversion API",
Stage: FeatureStageExperimental,
Owner: grafanaAlertingSquad,
HideFromAdminPage: true,
HideFromDocs: true,
},
{
Name: "alertingAlertmanagerExtraDedupStage",
Description: "enables extra deduplication stage in alertmanager that checks that timestamps of the pipeline and the current state are matching",

@ -234,6 +234,7 @@ elasticsearchImprovedParsing,experimental,@grafana/aws-datasources,false,false,f
exploreMetricsUseExternalAppPlugin,experimental,@grafana/observability-metrics,false,true,true
datasourceConnectionsTab,experimental,@grafana/plugins-platform-backend,false,false,true
fetchRulesUsingPost,experimental,@grafana/alerting-squad,false,false,false
alertingConversionAPI,experimental,@grafana/alerting-squad,false,false,false
alertingAlertmanagerExtraDedupStage,experimental,@grafana/alerting-squad,false,true,false
alertingAlertmanagerExtraDedupStageStopPipeline,experimental,@grafana/alerting-squad,false,true,false
newLogsPanel,experimental,@grafana/observability-logs,false,false,true

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
234 exploreMetricsUseExternalAppPlugin experimental @grafana/observability-metrics false true true
235 datasourceConnectionsTab experimental @grafana/plugins-platform-backend false false true
236 fetchRulesUsingPost experimental @grafana/alerting-squad false false false
237 alertingConversionAPI experimental @grafana/alerting-squad false false false
238 alertingAlertmanagerExtraDedupStage experimental @grafana/alerting-squad false true false
239 alertingAlertmanagerExtraDedupStageStopPipeline experimental @grafana/alerting-squad false true false
240 newLogsPanel experimental @grafana/observability-logs false false true

@ -947,6 +947,10 @@ const (
// Use a POST request to list rules by passing down the namespaces user has access to
FlagFetchRulesUsingPost = "fetchRulesUsingPost"
// FlagAlertingConversionAPI
// Enable the alerting conversion API
FlagAlertingConversionAPI = "alertingConversionAPI"
// FlagAlertingAlertmanagerExtraDedupStage
// enables extra deduplication stage in alertmanager that checks that timestamps of the pipeline and the current state are matching
FlagAlertingAlertmanagerExtraDedupStage = "alertingAlertmanagerExtraDedupStage"

@ -215,6 +215,20 @@
"frontend": true
}
},
{
"metadata": {
"name": "alertingConversionAPI",
"resourceVersion": "1739207762746",
"creationTimestamp": "2025-02-10T17:16:02Z"
},
"spec": {
"description": "Enable the alerting conversion API",
"stage": "experimental",
"codeowner": "@grafana/alerting-squad",
"hideFromAdminPage": true,
"hideFromDocs": true
}
},
{
"metadata": {
"name": "alertingDisableSendAlertsExternal",

@ -185,4 +185,10 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
receiverService: api.ReceiverService,
muteTimingService: api.MuteTimings,
}), m)
if api.FeatureManager.IsEnabledGlobally(featuremgmt.FlagAlertingConversionAPI) {
api.RegisterConvertPrometheusApiEndpoints(NewConvertPrometheusApi(&ConvertPrometheusSrv{
logger: logger,
}), m)
}
}

@ -0,0 +1,36 @@
package api
import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/log"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
)
type ConvertPrometheusSrv struct {
logger log.Logger
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusGetRules(c *contextmodel.ReqContext) response.Response {
return response.Error(501, "Not implemented", nil)
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusDeleteNamespace(c *contextmodel.ReqContext, namespaceTitle string) response.Response {
return response.Error(501, "Not implemented", nil)
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusDeleteRuleGroup(c *contextmodel.ReqContext, namespaceTitle string, group string) response.Response {
return response.Error(501, "Not implemented", nil)
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusGetNamespace(c *contextmodel.ReqContext, namespaceTitle string) response.Response {
return response.Error(501, "Not implemented", nil)
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusGetRuleGroup(c *contextmodel.ReqContext, namespaceTitle string, group string) response.Response {
return response.Error(501, "Not implemented", nil)
}
func (srv *ConvertPrometheusSrv) RouteConvertPrometheusPostRuleGroup(c *contextmodel.ReqContext, namespaceTitle string, prometheusGroup apimodels.PrometheusRuleGroup) response.Response {
return response.Error(501, "Not implemented", nil)
}

@ -123,6 +123,34 @@ func (api *API) authorize(method, path string) web.Handler {
case http.MethodPost + "/api/v1/rule/test/{DatasourceUID}":
eval = ac.EvalPermission(ac.ActionAlertingRuleExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
// convert/prometheus API paths
case http.MethodGet + "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}",
http.MethodGet + "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}":
eval = ac.EvalAll(
ac.EvalPermission(ac.ActionAlertingRuleRead),
ac.EvalPermission(dashboards.ActionFoldersRead),
)
case http.MethodGet + "/api/convert/prometheus/config/v1/rules":
eval = ac.EvalPermission(ac.ActionAlertingRuleRead)
case http.MethodPost + "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}":
eval = ac.EvalAll(
ac.EvalPermission(dashboards.ActionFoldersWrite),
ac.EvalPermission(ac.ActionAlertingRuleRead),
ac.EvalPermission(ac.ActionAlertingRuleUpdate),
ac.EvalPermission(ac.ActionAlertingRuleCreate),
ac.EvalPermission(ac.ActionAlertingRuleDelete),
)
case http.MethodDelete + "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}",
http.MethodDelete + "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}":
eval = ac.EvalAll(
ac.EvalPermission(ac.ActionAlertingRuleDelete),
ac.EvalPermission(ac.ActionAlertingRuleRead),
ac.EvalPermission(dashboards.ActionFoldersRead),
)
// Alert Instances and Silences
// Silences for Grafana paths.

@ -41,7 +41,7 @@ func TestAuthorize(t *testing.T) {
}
paths[p] = methods
}
require.Len(t, paths, 60)
require.Len(t, paths, 63)
ac := acmock.New()
api := &API{AccessControl: ac, FeatureManager: featuremgmt.WithFeatures()}

@ -0,0 +1,136 @@
/*Package api contains base API implementation of unified alerting
*
*Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*
*Do not manually edit these files, please find ngalert/api/swagger-codegen/ for commands on how to generate them.
*/
package api
import (
"net/http"
"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/middleware/requestmeta"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
"github.com/grafana/grafana/pkg/web"
)
type ConvertPrometheusApi interface {
RouteConvertPrometheusDeleteNamespace(*contextmodel.ReqContext) response.Response
RouteConvertPrometheusDeleteRuleGroup(*contextmodel.ReqContext) response.Response
RouteConvertPrometheusGetNamespace(*contextmodel.ReqContext) response.Response
RouteConvertPrometheusGetRuleGroup(*contextmodel.ReqContext) response.Response
RouteConvertPrometheusGetRules(*contextmodel.ReqContext) response.Response
RouteConvertPrometheusPostRuleGroup(*contextmodel.ReqContext) response.Response
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusDeleteNamespace(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
namespaceTitleParam := web.Params(ctx.Req)[":NamespaceTitle"]
return f.handleRouteConvertPrometheusDeleteNamespace(ctx, namespaceTitleParam)
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusDeleteRuleGroup(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
namespaceTitleParam := web.Params(ctx.Req)[":NamespaceTitle"]
groupParam := web.Params(ctx.Req)[":Group"]
return f.handleRouteConvertPrometheusDeleteRuleGroup(ctx, namespaceTitleParam, groupParam)
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusGetNamespace(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
namespaceTitleParam := web.Params(ctx.Req)[":NamespaceTitle"]
return f.handleRouteConvertPrometheusGetNamespace(ctx, namespaceTitleParam)
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusGetRuleGroup(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
namespaceTitleParam := web.Params(ctx.Req)[":NamespaceTitle"]
groupParam := web.Params(ctx.Req)[":Group"]
return f.handleRouteConvertPrometheusGetRuleGroup(ctx, namespaceTitleParam, groupParam)
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusGetRules(ctx *contextmodel.ReqContext) response.Response {
return f.handleRouteConvertPrometheusGetRules(ctx)
}
func (f *ConvertPrometheusApiHandler) RouteConvertPrometheusPostRuleGroup(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
namespaceTitleParam := web.Params(ctx.Req)[":NamespaceTitle"]
return f.handleRouteConvertPrometheusPostRuleGroup(ctx, namespaceTitleParam)
}
func (api *API) RegisterConvertPrometheusApiEndpoints(srv ConvertPrometheusApi, m *metrics.API) {
api.RouteRegister.Group("", func(group routing.RouteRegister) {
group.Delete(
toMacaronPath("/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodDelete, "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
metrics.Instrument(
http.MethodDelete,
"/api/convert/prometheus/config/v1/rules/{NamespaceTitle}",
api.Hooks.Wrap(srv.RouteConvertPrometheusDeleteNamespace),
m,
),
)
group.Delete(
toMacaronPath("/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodDelete, "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}"),
metrics.Instrument(
http.MethodDelete,
"/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}",
api.Hooks.Wrap(srv.RouteConvertPrometheusDeleteRuleGroup),
m,
),
)
group.Get(
toMacaronPath("/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodGet, "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
metrics.Instrument(
http.MethodGet,
"/api/convert/prometheus/config/v1/rules/{NamespaceTitle}",
api.Hooks.Wrap(srv.RouteConvertPrometheusGetNamespace),
m,
),
)
group.Get(
toMacaronPath("/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodGet, "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}"),
metrics.Instrument(
http.MethodGet,
"/api/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}",
api.Hooks.Wrap(srv.RouteConvertPrometheusGetRuleGroup),
m,
),
)
group.Get(
toMacaronPath("/api/convert/prometheus/config/v1/rules"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodGet, "/api/convert/prometheus/config/v1/rules"),
metrics.Instrument(
http.MethodGet,
"/api/convert/prometheus/config/v1/rules",
api.Hooks.Wrap(srv.RouteConvertPrometheusGetRules),
m,
),
)
group.Post(
toMacaronPath("/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodPost, "/api/convert/prometheus/config/v1/rules/{NamespaceTitle}"),
metrics.Instrument(
http.MethodPost,
"/api/convert/prometheus/config/v1/rules/{NamespaceTitle}",
api.Hooks.Wrap(srv.RouteConvertPrometheusPostRuleGroup),
m,
),
)
}, middleware.ReqSignedIn)
}

@ -0,0 +1,56 @@
package api
import (
"io"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/api/response"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
)
type ConvertPrometheusApiHandler struct {
svc *ConvertPrometheusSrv
}
func NewConvertPrometheusApi(svc *ConvertPrometheusSrv) *ConvertPrometheusApiHandler {
return &ConvertPrometheusApiHandler{
svc: svc,
}
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusGetRules(ctx *contextmodel.ReqContext) response.Response {
return f.svc.RouteConvertPrometheusGetRules(ctx)
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusDeleteNamespace(ctx *contextmodel.ReqContext, namespaceTitle string) response.Response {
return f.svc.RouteConvertPrometheusDeleteNamespace(ctx, namespaceTitle)
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusDeleteRuleGroup(ctx *contextmodel.ReqContext, namespaceTitle string, group string) response.Response {
return f.svc.RouteConvertPrometheusDeleteRuleGroup(ctx, namespaceTitle, group)
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusGetNamespace(ctx *contextmodel.ReqContext, namespaceTitle string) response.Response {
return f.svc.RouteConvertPrometheusGetNamespace(ctx, namespaceTitle)
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusGetRuleGroup(ctx *contextmodel.ReqContext, namespaceTitle string, group string) response.Response {
return f.svc.RouteConvertPrometheusGetRuleGroup(ctx, namespaceTitle, group)
}
func (f *ConvertPrometheusApiHandler) handleRouteConvertPrometheusPostRuleGroup(ctx *contextmodel.ReqContext, namespaceTitle string) response.Response {
body, err := io.ReadAll(ctx.Req.Body)
if err != nil {
return errorToResponse(err)
}
defer func() { _ = ctx.Req.Body.Close() }()
var promGroup apimodels.PrometheusRuleGroup
if err := yaml.Unmarshal(body, &promGroup); err != nil {
return errorToResponse(err)
}
return f.svc.RouteConvertPrometheusPostRuleGroup(ctx, namespaceTitle, promGroup)
}

@ -734,6 +734,20 @@
},
"type": "array"
},
"ConvertPrometheusResponse": {
"properties": {
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"CounterResetHint": {
"description": "or alternatively that we are dealing with a gauge histogram, where counter resets do not apply.",
"format": "uint8",
@ -2940,6 +2954,70 @@
},
"type": "object"
},
"PrometheusNamespace": {
"properties": {
"Body": {
"additionalProperties": {
"items": {
"$ref": "#/definitions/PrometheusRuleGroup"
},
"type": "array"
},
"description": "in: body",
"type": "object"
}
},
"type": "object"
},
"PrometheusRule": {
"properties": {
"Alert": {
"type": "string"
},
"Annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Expr": {
"type": "string"
},
"For": {
"type": "string"
},
"KeepFiringFor": {
"type": "string"
},
"Labels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Record": {
"type": "string"
}
},
"type": "object"
},
"PrometheusRuleGroup": {
"properties": {
"Interval": {
"$ref": "#/definitions/Duration"
},
"Name": {
"type": "string"
},
"Rules": {
"items": {
"$ref": "#/definitions/PrometheusRule"
},
"type": "array"
}
},
"type": "object"
},
"Provenance": {
"type": "string"
},
@ -4692,7 +4770,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup",
"type": "object"

@ -0,0 +1,139 @@
package definitions
import (
"github.com/prometheus/common/model"
)
// swagger:route GET /convert/prometheus/config/v1/rules convert_prometheus RouteConvertPrometheusGetRules
//
// Gets all namespaces with their rule groups in Prometheus format.
//
// Produces:
// - application/json
//
// Responses:
// 200: PrometheusNamespace
// 403: ForbiddenError
// 404: NotFound
// swagger:route GET /convert/prometheus/config/v1/rules/{NamespaceTitle} convert_prometheus RouteConvertPrometheusGetNamespace
//
// Gets rules in prometheus format for a given namespace.
//
// Produces:
// - application/json
//
// Responses:
// 200: PrometheusNamespace
// 403: ForbiddenError
// 404: NotFound
// swagger:route GET /convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group} convert_prometheus RouteConvertPrometheusGetRuleGroup
//
// Gets a rule group in Prometheus format.
//
// Produces:
// - application/json
//
// Responses:
// 200: PrometheusRuleGroup
// 403: ForbiddenError
// 404: NotFound
// swagger:route POST /convert/prometheus/config/v1/rules/{NamespaceTitle} convert_prometheus RouteConvertPrometheusPostRuleGroup
//
// Creates or updates a rule group in Prometheus format.
//
// Consumes:
// - application/yaml
//
// Produces:
// - application/json
//
// Responses:
// 202: ConvertPrometheusResponse
// 403: ForbiddenError
//
// Extensions:
// x-raw-request: true
// swagger:route DELETE /convert/prometheus/config/v1/rules/{NamespaceTitle} convert_prometheus RouteConvertPrometheusDeleteNamespace
//
// Deletes all rule groups in the given namespace.
//
// Produces:
// - application/json
//
// Responses:
// 202: ConvertPrometheusResponse
// 403: ForbiddenError
// swagger:route DELETE /convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group} convert_prometheus RouteConvertPrometheusDeleteRuleGroup
//
// Deletes a rule group in Prometheus format.
//
// Produces:
// - application/json
//
// Responses:
// 202: ConvertPrometheusResponse
// 403: ForbiddenError
// swagger:parameters RouteConvertPrometheusPostRuleGroup
type RouteConvertPrometheusPostRuleGroupParams struct {
// in: path
NamespaceTitle string
// in: header
DatasourceUID string `json:"x-datasource-uid"`
// in: header
RecordingRulesPaused bool `json:"x-recording-rules-paused"`
// in: header
AlertRulesPaused bool `json:"x-alert-rules-paused"`
// in:body
Body PrometheusRuleGroup
}
// swagger:model
type PrometheusNamespace struct {
// in: body
Body map[string][]PrometheusRuleGroup
}
// swagger:model
type PrometheusRuleGroup struct {
Name string `yaml:"name"`
Interval model.Duration `yaml:"interval"`
Rules []PrometheusRule `yaml:"rules"`
}
// swagger:model
type PrometheusRule struct {
Alert string `yaml:"alert,omitempty"`
Expr string `yaml:"expr"`
For *model.Duration `yaml:"for,omitempty"`
KeepFiringFor *model.Duration `yaml:"keep_firing_for,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"`
Annotations map[string]string `yaml:"annotations,omitempty"`
Record string `yaml:"record,omitempty"`
}
// swagger:parameters RouteConvertPrometheusDeleteRuleGroup RouteConvertPrometheusGetRuleGroup
type RouteConvertPrometheusDeleteRuleGroupParams struct {
// in: path
NamespaceTitle string
// in: path
Group string
}
// swagger:parameters RouteConvertPrometheusDeleteNamespace RouteConvertPrometheusGetNamespace
type RouteConvertPrometheusDeleteNamespaceParams struct {
// in: path
NamespaceTitle string
}
// swagger:model
type ConvertPrometheusResponse struct {
Status string `json:"status"`
ErrorType string `json:"errorType"`
Error string `json:"error"`
}

@ -734,6 +734,20 @@
},
"type": "array"
},
"ConvertPrometheusResponse": {
"properties": {
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"CounterResetHint": {
"description": "or alternatively that we are dealing with a gauge histogram, where counter resets do not apply.",
"format": "uint8",
@ -2940,6 +2954,70 @@
},
"type": "object"
},
"PrometheusNamespace": {
"properties": {
"Body": {
"additionalProperties": {
"items": {
"$ref": "#/definitions/PrometheusRuleGroup"
},
"type": "array"
},
"description": "in: body",
"type": "object"
}
},
"type": "object"
},
"PrometheusRule": {
"properties": {
"Alert": {
"type": "string"
},
"Annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Expr": {
"type": "string"
},
"For": {
"type": "string"
},
"KeepFiringFor": {
"type": "string"
},
"Labels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Record": {
"type": "string"
}
},
"type": "object"
},
"PrometheusRuleGroup": {
"properties": {
"Interval": {
"$ref": "#/definitions/Duration"
},
"Name": {
"type": "string"
},
"Rules": {
"items": {
"$ref": "#/definitions/PrometheusRule"
},
"type": "array"
}
},
"type": "object"
},
"Provenance": {
"type": "string"
},
@ -4854,7 +4932,6 @@
"type": "object"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"items": {
"$ref": "#/definitions/gettableAlert",
"type": "object"
@ -4979,7 +5056,6 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence",
"type": "object"
@ -6322,6 +6398,252 @@
]
}
},
"/convert/prometheus/config/v1/rules": {
"get": {
"operationId": "RouteConvertPrometheusGetRules",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "PrometheusNamespace",
"schema": {
"$ref": "#/definitions/PrometheusNamespace"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
},
"summary": "Gets all namespaces with their rule groups in Prometheus format.",
"tags": [
"convert_prometheus"
]
}
},
"/convert/prometheus/config/v1/rules/{NamespaceTitle}": {
"delete": {
"operationId": "RouteConvertPrometheusDeleteNamespace",
"parameters": [
{
"in": "path",
"name": "NamespaceTitle",
"required": true,
"type": "string"
}
],
"produces": [
"application/json"
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
},
"summary": "Deletes all rule groups in the given namespace.",
"tags": [
"convert_prometheus"
]
},
"get": {
"operationId": "RouteConvertPrometheusGetNamespace",
"parameters": [
{
"in": "path",
"name": "NamespaceTitle",
"required": true,
"type": "string"
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "PrometheusNamespace",
"schema": {
"$ref": "#/definitions/PrometheusNamespace"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
},
"summary": "Gets rules in prometheus format for a given namespace.",
"tags": [
"convert_prometheus"
]
},
"post": {
"consumes": [
"application/yaml"
],
"operationId": "RouteConvertPrometheusPostRuleGroup",
"parameters": [
{
"in": "path",
"name": "NamespaceTitle",
"required": true,
"type": "string"
},
{
"in": "header",
"name": "x-datasource-uid",
"type": "string"
},
{
"in": "header",
"name": "x-recording-rules-paused",
"type": "boolean"
},
{
"in": "header",
"name": "x-alert-rules-paused",
"type": "boolean"
},
{
"in": "body",
"name": "Body",
"schema": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
}
],
"produces": [
"application/json"
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
},
"summary": "Creates or updates a rule group in Prometheus format.",
"tags": [
"convert_prometheus"
],
"x-raw-request": "true"
}
},
"/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}": {
"delete": {
"operationId": "RouteConvertPrometheusDeleteRuleGroup",
"parameters": [
{
"in": "path",
"name": "NamespaceTitle",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "Group",
"required": true,
"type": "string"
}
],
"produces": [
"application/json"
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
},
"summary": "Deletes a rule group in Prometheus format.",
"tags": [
"convert_prometheus"
]
},
"get": {
"operationId": "RouteConvertPrometheusGetRuleGroup",
"parameters": [
{
"in": "path",
"name": "NamespaceTitle",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "Group",
"required": true,
"type": "string"
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "PrometheusRuleGroup",
"schema": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
},
"summary": "Gets a rule group in Prometheus format.",
"tags": [
"convert_prometheus"
]
}
},
"/prometheus/grafana/api/v1/alerts": {
"get": {
"description": "gets the current alerts",
@ -6886,6 +7208,12 @@
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
},
"tags": [

@ -1102,6 +1102,252 @@
}
}
},
"/convert/prometheus/config/v1/rules": {
"get": {
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Gets all namespaces with their rule groups in Prometheus format.",
"operationId": "RouteConvertPrometheusGetRules",
"responses": {
"200": {
"description": "PrometheusNamespace",
"schema": {
"$ref": "#/definitions/PrometheusNamespace"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
}
}
},
"/convert/prometheus/config/v1/rules/{NamespaceTitle}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Gets rules in prometheus format for a given namespace.",
"operationId": "RouteConvertPrometheusGetNamespace",
"parameters": [
{
"type": "string",
"name": "NamespaceTitle",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "PrometheusNamespace",
"schema": {
"$ref": "#/definitions/PrometheusNamespace"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
}
},
"post": {
"consumes": [
"application/yaml"
],
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Creates or updates a rule group in Prometheus format.",
"operationId": "RouteConvertPrometheusPostRuleGroup",
"parameters": [
{
"type": "string",
"name": "NamespaceTitle",
"in": "path",
"required": true
},
{
"type": "string",
"name": "x-datasource-uid",
"in": "header"
},
{
"type": "boolean",
"name": "x-recording-rules-paused",
"in": "header"
},
{
"type": "boolean",
"name": "x-alert-rules-paused",
"in": "header"
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
}
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
},
"x-raw-request": "true"
},
"delete": {
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Deletes all rule groups in the given namespace.",
"operationId": "RouteConvertPrometheusDeleteNamespace",
"parameters": [
{
"type": "string",
"name": "NamespaceTitle",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
}
}
},
"/convert/prometheus/config/v1/rules/{NamespaceTitle}/{Group}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Gets a rule group in Prometheus format.",
"operationId": "RouteConvertPrometheusGetRuleGroup",
"parameters": [
{
"type": "string",
"name": "NamespaceTitle",
"in": "path",
"required": true
},
{
"type": "string",
"name": "Group",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "PrometheusRuleGroup",
"schema": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
}
},
"delete": {
"produces": [
"application/json"
],
"tags": [
"convert_prometheus"
],
"summary": "Deletes a rule group in Prometheus format.",
"operationId": "RouteConvertPrometheusDeleteRuleGroup",
"parameters": [
{
"type": "string",
"name": "NamespaceTitle",
"in": "path",
"required": true
},
{
"type": "string",
"name": "Group",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "ConvertPrometheusResponse",
"schema": {
"$ref": "#/definitions/ConvertPrometheusResponse"
}
},
"403": {
"description": "ForbiddenError",
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
}
}
}
},
"/prometheus/grafana/api/v1/alerts": {
"get": {
"description": "gets the current alerts",
@ -1633,6 +1879,12 @@
"schema": {
"$ref": "#/definitions/ForbiddenError"
}
},
"404": {
"description": "NotFound",
"schema": {
"$ref": "#/definitions/NotFound"
}
}
}
},
@ -4420,6 +4672,20 @@
"$ref": "#/definitions/EmbeddedContactPoint"
}
},
"ConvertPrometheusResponse": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"CounterResetHint": {
"description": "or alternatively that we are dealing with a gauge histogram, where counter resets do not apply.",
"type": "integer",
@ -6628,6 +6894,70 @@
}
}
},
"PrometheusNamespace": {
"type": "object",
"properties": {
"Body": {
"description": "in: body",
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
}
}
}
},
"PrometheusRule": {
"type": "object",
"properties": {
"Alert": {
"type": "string"
},
"Annotations": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"Expr": {
"type": "string"
},
"For": {
"type": "string"
},
"KeepFiringFor": {
"type": "string"
},
"Labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"Record": {
"type": "string"
}
}
},
"PrometheusRuleGroup": {
"type": "object",
"properties": {
"Interval": {
"$ref": "#/definitions/Duration"
},
"Name": {
"type": "string"
},
"Rules": {
"type": "array",
"items": {
"$ref": "#/definitions/PrometheusRule"
}
}
}
},
"Provenance": {
"type": "string"
},
@ -8542,7 +8872,6 @@
}
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"type": "array",
"items": {
"type": "object",
@ -8667,7 +8996,6 @@
}
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"type": "array",
"items": {
"type": "object",

@ -20,6 +20,14 @@ type {{classname}} interface { {{#operation}}
}
{{#operations}}{{#operation}}
{{#vendorExtensions.x-raw-request}}
func (f *{{classname}}Handler) {{nickname}}(ctx *contextmodel.ReqContext) response.Response { {{#hasPathParams}}
// Parse Path Parameters{{/hasPathParams}}{{#pathParams}}
{{paramName}}Param := web.Params(ctx.Req)[":{{baseName}}"]{{/pathParams}}
return f.handle{{nickname}}(ctx{{#pathParams}}, {{paramName}}Param{{/pathParams}})
}
{{/vendorExtensions.x-raw-request}}
{{^vendorExtensions.x-raw-request}}
func (f *{{classname}}Handler) {{nickname}}(ctx *contextmodel.ReqContext) response.Response { {{#hasPathParams}}
// Parse Path Parameters{{/hasPathParams}}{{#pathParams}}
{{paramName}}Param := web.Params(ctx.Req)[":{{baseName}}"]{{/pathParams}}
@ -31,6 +39,7 @@ func (f *{{classname}}Handler) {{nickname}}(ctx *contextmodel.ReqContext) respon
}
{{/bodyParams}}return f.handle{{nickname}}(ctx{{#bodyParams}}, conf{{/bodyParams}}{{#pathParams}}, {{paramName}}Param{{/pathParams}})
}
{{/vendorExtensions.x-raw-request}}
{{/operation}}{{/operations}}
func (api *API) Register{{classname}}Endpoints(srv {{classname}}, m *metrics.API) {

@ -13882,6 +13882,20 @@
"$ref": "#/definitions/EmbeddedContactPoint"
}
},
"ConvertPrometheusResponse": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"CookiePreferences": {
"type": "object",
"properties": {
@ -18520,6 +18534,21 @@
}
}
},
"PrometheusNamespace": {
"type": "object",
"properties": {
"Body": {
"description": "in: body",
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "#/definitions/PrometheusRuleGroup"
}
}
}
}
},
"PrometheusRemoteWriteTargetJSON": {
"type": "object",
"properties": {
@ -18534,6 +18563,55 @@
}
}
},
"PrometheusRule": {
"type": "object",
"properties": {
"Alert": {
"type": "string"
},
"Annotations": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"Expr": {
"type": "string"
},
"For": {
"type": "string"
},
"KeepFiringFor": {
"type": "string"
},
"Labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"Record": {
"type": "string"
}
}
},
"PrometheusRuleGroup": {
"type": "object",
"properties": {
"Interval": {
"$ref": "#/definitions/Duration"
},
"Name": {
"type": "string"
},
"Rules": {
"type": "array",
"items": {
"$ref": "#/definitions/PrometheusRule"
}
}
}
},
"Provenance": {
"type": "string"
},
@ -22483,7 +22561,6 @@
}
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"type": "object",

@ -3957,6 +3957,20 @@
},
"type": "array"
},
"ConvertPrometheusResponse": {
"properties": {
"error": {
"type": "string"
},
"errorType": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"CookiePreferences": {
"properties": {
"analytics": {},
@ -8595,6 +8609,21 @@
},
"type": "object"
},
"PrometheusNamespace": {
"properties": {
"Body": {
"additionalProperties": {
"items": {
"$ref": "#/components/schemas/PrometheusRuleGroup"
},
"type": "array"
},
"description": "in: body",
"type": "object"
}
},
"type": "object"
},
"PrometheusRemoteWriteTargetJSON": {
"properties": {
"data_source_uid": {
@ -8609,6 +8638,55 @@
},
"type": "object"
},
"PrometheusRule": {
"properties": {
"Alert": {
"type": "string"
},
"Annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Expr": {
"type": "string"
},
"For": {
"type": "string"
},
"KeepFiringFor": {
"type": "string"
},
"Labels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"Record": {
"type": "string"
}
},
"type": "object"
},
"PrometheusRuleGroup": {
"properties": {
"Interval": {
"$ref": "#/components/schemas/Duration"
},
"Name": {
"type": "string"
},
"Rules": {
"items": {
"$ref": "#/components/schemas/PrometheusRule"
},
"type": "array"
}
},
"type": "object"
},
"Provenance": {
"type": "string"
},
@ -12557,7 +12635,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/components/schemas/alertGroup"
},

Loading…
Cancel
Save