Alerting: Expose info about notification delivery errors in a new /receivers endpoint (#55429)

* (WIP) switch to fork AM, first implementation of the API, generate spec

* get receivers avoiding race conditions

* use latest version of our forked AM, tests

* make linter happy, delete TODO comment

* update number of expected paths to += 2

* delete unused endpoint code, code review comments, tests

* Update pkg/services/ngalert/notifier/alertmanager.go

Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>

* remove call to fmt.Println

* clear naming for fields

* shorter variable names in GetReceivers

Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>
This commit is contained in:
Santiago
2022-10-03 10:58:41 -03:00
committed by GitHub
parent 1e16dd5b7c
commit 09f8e026a1
17 changed files with 667 additions and 454 deletions

View File

@@ -49,7 +49,8 @@ type Alertmanager interface {
GetAlerts(active, silenced, inhibited bool, filter []string, receiver string) (apimodels.GettableAlerts, error)
GetAlertGroups(active, silenced, inhibited bool, filter []string, receiver string) (apimodels.AlertGroups, error)
// Testing
// Receivers
GetReceivers(ctx context.Context) apimodels.Receivers
TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*notifier.TestReceiversResult, error)
}

View File

@@ -248,6 +248,16 @@ func (srv AlertmanagerSrv) RoutePostAMAlerts(_ *models.ReqContext, _ apimodels.P
return NotImplementedResp
}
func (srv AlertmanagerSrv) RouteGetReceivers(c *models.ReqContext) response.Response {
am, errResp := srv.AlertmanagerFor(c.OrgID)
if errResp != nil {
return errResp
}
rcvs := am.GetReceivers(c.Req.Context())
return response.JSON(http.StatusOK, rcvs)
}
func (srv AlertmanagerSrv) RoutePostTestReceivers(c *models.ReqContext, body apimodels.TestReceiversConfigBodyParams) response.Response {
if err := srv.crypto.LoadSecureSettings(c.Req.Context(), c.OrgID, body.Receivers); err != nil {
var unknownReceiverError UnknownReceiverError

View File

@@ -156,6 +156,8 @@ func (api *API) authorize(method, path string) web.Handler {
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/alerts":
// additional authorization is done in the request handler
eval = ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsWrite))
case http.MethodGet + "/api/alertmanager/grafana/config/api/v1/receivers":
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/receivers/test":
fallback = middleware.ReqEditorRole
eval = ac.EvalPermission(ac.ActionAlertingNotificationsRead)

View File

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

View File

@@ -187,6 +187,10 @@ func (f *AlertmanagerApiHandler) handleRoutePostGrafanaAlertingConfig(ctx *model
return f.GrafanaSvc.RoutePostAlertingConfig(ctx, conf)
}
func (f *AlertmanagerApiHandler) handleRouteGetGrafanaReceivers(ctx *models.ReqContext) response.Response {
return f.GrafanaSvc.RouteGetReceivers(ctx)
}
func (f *AlertmanagerApiHandler) handleRoutePostTestGrafanaReceivers(ctx *models.ReqContext, conf apimodels.TestReceiversConfigBodyParams) response.Response {
return f.GrafanaSvc.RoutePostTestReceivers(ctx, conf)
}

View File

@@ -33,6 +33,7 @@ type AlertmanagerApi interface {
RouteGetGrafanaAMAlerts(*models.ReqContext) response.Response
RouteGetGrafanaAMStatus(*models.ReqContext) response.Response
RouteGetGrafanaAlertingConfig(*models.ReqContext) response.Response
RouteGetGrafanaReceivers(*models.ReqContext) response.Response
RouteGetGrafanaSilence(*models.ReqContext) response.Response
RouteGetGrafanaSilences(*models.ReqContext) response.Response
RouteGetSilence(*models.ReqContext) response.Response
@@ -114,6 +115,9 @@ func (f *AlertmanagerApiHandler) RouteGetGrafanaAMStatus(ctx *models.ReqContext)
func (f *AlertmanagerApiHandler) RouteGetGrafanaAlertingConfig(ctx *models.ReqContext) response.Response {
return f.handleRouteGetGrafanaAlertingConfig(ctx)
}
func (f *AlertmanagerApiHandler) RouteGetGrafanaReceivers(ctx *models.ReqContext) response.Response {
return f.handleRouteGetGrafanaReceivers(ctx)
}
func (f *AlertmanagerApiHandler) RouteGetGrafanaSilence(ctx *models.ReqContext) response.Response {
// Parse Path Parameters
silenceIdParam := web.Params(ctx.Req)[":SilenceId"]
@@ -330,6 +334,16 @@ func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApi, m *metrics
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/config/api/v1/receivers"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/config/api/v1/receivers"),
metrics.Instrument(
http.MethodGet,
"/api/alertmanager/grafana/config/api/v1/receivers",
srv.RouteGetGrafanaReceivers,
m,
),
)
group.Get(
toMacaronPath("/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),
api.authorize(http.MethodGet, "/api/alertmanager/grafana/api/v2/silence/{SilenceId}"),

View File

@@ -260,7 +260,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"labels": {
"additionalProperties": {
@@ -378,25 +378,6 @@
"title": "DataTopic is used to identify which topic the frame should be assigned to.",
"type": "string"
},
"DateTime": {
"description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.",
"format": "date-time",
"type": "string"
},
"DayOfMonthRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A DayOfMonthRange is an inclusive range that may have negative Beginning/End values that represent distance from the End of the month Beginning at -1.",
"type": "object"
},
"DiscoveryBase": {
"properties": {
"error": {
@@ -625,16 +606,12 @@
"FieldConfig": {
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Panel Specific Values",
"type": "object"
},
@@ -742,8 +719,7 @@
"type": "string"
},
"custom": {
"description": "Custom datasource specific values.",
"type": "object"
"description": "Custom datasource specific values."
},
"dataTopic": {
"$ref": "#/definitions/DataTopic"
@@ -939,7 +915,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/GettableGrafanaRule"
@@ -1239,6 +1215,10 @@
"description": "The bearer token file for the targets. Deprecated in favour of\nAuthorization.CredentialsFile.",
"type": "string"
},
"enable_http2": {
"description": "EnableHTTP2 specifies whether the client should configure HTTP2.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
},
"follow_redirects": {
"description": "FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
@@ -1268,20 +1248,6 @@
"title": "HostPort represents a \"host:port\" network address.",
"type": "object"
},
"InclusiveRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "InclusiveRange is used to hold the Beginning and End values of many time interval components.",
"type": "object"
},
"InhibitRule": {
"description": "InhibitRule defines an inhibition rule that mutes alerts that match the\ntarget labels if an alert matching the source labels exists.\nBoth alerts have to have a set of labels being equal.",
"properties": {
@@ -1501,20 +1467,6 @@
},
"type": "array"
},
"MonthRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A MonthRange is an inclusive range between [1, 12] where 1 = January.",
"type": "object"
},
"MultiStatus": {
"type": "object"
},
@@ -1605,6 +1557,9 @@
},
"type": "object"
},
"proxy_url": {
"$ref": "#/definitions/URL"
},
"scopes": {
"items": {
"type": "string"
@@ -1931,7 +1886,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/PostableGrafanaRule"
@@ -2220,7 +2175,7 @@
"PushoverConfig": {
"properties": {
"expire": {
"$ref": "#/definitions/duration"
"type": "string"
},
"html": {
"type": "boolean"
@@ -2235,7 +2190,7 @@
"type": "string"
},
"retry": {
"$ref": "#/definitions/duration"
"type": "string"
},
"send_resolved": {
"type": "boolean"
@@ -2265,16 +2220,12 @@
"description": "The embedded FieldConfig's display name must be set.\nIt corresponds to the QueryResultMetaStat on the frontend (https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L53).",
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Panel Specific Values",
"type": "object"
},
@@ -2462,10 +2413,10 @@
"type": "array"
},
"group_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"group_wait": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"match": {
"additionalProperties": {
@@ -2496,7 +2447,7 @@
"type": "string"
},
"repeat_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"routes": {
"items": {
@@ -2897,6 +2848,9 @@
"description": "The client key file for the targets.",
"type": "string"
},
"min_version": {
"$ref": "#/definitions/TLSVersion"
},
"server_name": {
"description": "Used to verify the hostname for the targets.",
"type": "string"
@@ -2905,6 +2859,10 @@
"title": "TLSConfig configures the options for TLS connections.",
"type": "object"
},
"TLSVersion": {
"format": "uint16",
"type": "integer"
},
"TelegramConfig": {
"properties": {
"api_url": {
@@ -3073,13 +3031,13 @@
"properties": {
"days_of_month": {
"items": {
"$ref": "#/definitions/DayOfMonthRange"
"type": "string"
},
"type": "array"
},
"months": {
"items": {
"$ref": "#/definitions/MonthRange"
"type": "string"
},
"type": "array"
},
@@ -3091,13 +3049,13 @@
},
"weekdays": {
"items": {
"$ref": "#/definitions/WeekdayRange"
"type": "string"
},
"type": "array"
},
"years": {
"items": {
"$ref": "#/definitions/YearRange"
"type": "string"
},
"type": "array"
}
@@ -3120,7 +3078,6 @@
"type": "object"
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -3131,6 +3088,9 @@
"Host": {
"type": "string"
},
"OmitHost": {
"type": "boolean"
},
"Opaque": {
"type": "string"
},
@@ -3153,7 +3113,7 @@
"$ref": "#/definitions/Userinfo"
}
},
"title": "A URL represents a parsed URL (technically, a URI reference).",
"title": "URL is a custom URL type that allows validation at configuration load time.",
"type": "object"
},
"Userinfo": {
@@ -3291,34 +3251,6 @@
"title": "WechatConfig configures notifications via Wechat.",
"type": "object"
},
"WeekdayRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A WeekdayRange is an inclusive range between [0, 6] where 0 = Sunday.",
"type": "object"
},
"YearRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A YearRange is a positive inclusive range.",
"type": "object"
},
"alert": {
"description": "Alert alert",
"properties": {
@@ -3361,6 +3293,7 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup"
},
@@ -3464,10 +3397,8 @@
],
"type": "object"
},
"duration": {
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@@ -3530,6 +3461,7 @@
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3578,11 +3510,42 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
"type": "array"
},
"integration": {
"properties": {
"lastNotifyAttempt": {
"description": "A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
"format": "date-time",
"type": "string"
},
"lastNotifyAttemptDuration": {
"description": "Duration of the last attempt to deliver a notification in humanized format (`1s` or `15ms`, etc).",
"type": "string"
},
"lastNotifyAttemptError": {
"description": "Error string for the last attempt to deliver a notification. Empty if the last attempt was successful.",
"type": "string"
},
"name": {
"description": "name",
"type": "string"
},
"sendResolved": {
"description": "send resolved",
"type": "boolean"
}
},
"required": [
"name",
"sendResolved"
],
"type": "object"
},
"labelSet": {
"additionalProperties": {
"type": "string"
@@ -3688,6 +3651,7 @@
"type": "array"
},
"postableSilence": {
"description": "PostableSilence postable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3725,14 +3689,26 @@
"type": "object"
},
"receiver": {
"description": "Receiver receiver",
"properties": {
"active": {
"description": "active",
"type": "boolean"
},
"integrations": {
"description": "integrations",
"items": {
"$ref": "#/definitions/integration"
},
"type": "array"
},
"name": {
"description": "name",
"type": "string"
}
},
"required": [
"active",
"integrations",
"name"
],
"type": "object"

View File

@@ -142,6 +142,13 @@ import (
// 400: ValidationError
// 404: NotFound
// swagger:route GET /api/alertmanager/grafana/config/api/v1/receivers alertmanager RouteGetGrafanaReceivers
//
// Get a list of all receivers.
//
// Responses:
// 200: receivers
// swagger:route POST /api/alertmanager/grafana/config/api/v1/receivers/test alertmanager RoutePostTestGrafanaReceivers
//
// Test Grafana managed receivers without saving them.
@@ -403,6 +410,12 @@ type AlertGroup = amv2.AlertGroup
// swagger:model receiver
type Receiver = amv2.Receiver
// swagger:model receivers
type Receivers = []amv2.Receiver
// swagger:model integration
type Integration = amv2.Integration
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups RouteGetGrafanaAMAlerts RouteGetGrafanaAMAlertGroups
type AlertsParams struct {

View File

@@ -260,7 +260,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"labels": {
"additionalProperties": {
@@ -378,25 +378,6 @@
"title": "DataTopic is used to identify which topic the frame should be assigned to.",
"type": "string"
},
"DateTime": {
"description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.",
"format": "date-time",
"type": "string"
},
"DayOfMonthRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A DayOfMonthRange is an inclusive range that may have negative Beginning/End values that represent distance from the End of the month Beginning at -1.",
"type": "object"
},
"DiscoveryBase": {
"properties": {
"error": {
@@ -625,16 +606,12 @@
"FieldConfig": {
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Panel Specific Values",
"type": "object"
},
@@ -742,8 +719,7 @@
"type": "string"
},
"custom": {
"description": "Custom datasource specific values.",
"type": "object"
"description": "Custom datasource specific values."
},
"dataTopic": {
"$ref": "#/definitions/DataTopic"
@@ -939,7 +915,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/GettableGrafanaRule"
@@ -1239,6 +1215,10 @@
"description": "The bearer token file for the targets. Deprecated in favour of\nAuthorization.CredentialsFile.",
"type": "string"
},
"enable_http2": {
"description": "EnableHTTP2 specifies whether the client should configure HTTP2.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
},
"follow_redirects": {
"description": "FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
@@ -1268,20 +1248,6 @@
"title": "HostPort represents a \"host:port\" network address.",
"type": "object"
},
"InclusiveRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "InclusiveRange is used to hold the Beginning and End values of many time interval components.",
"type": "object"
},
"InhibitRule": {
"description": "InhibitRule defines an inhibition rule that mutes alerts that match the\ntarget labels if an alert matching the source labels exists.\nBoth alerts have to have a set of labels being equal.",
"properties": {
@@ -1501,20 +1467,6 @@
},
"type": "array"
},
"MonthRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A MonthRange is an inclusive range between [1, 12] where 1 = January.",
"type": "object"
},
"MultiStatus": {
"type": "object"
},
@@ -1605,6 +1557,9 @@
},
"type": "object"
},
"proxy_url": {
"$ref": "#/definitions/URL"
},
"scopes": {
"items": {
"type": "string"
@@ -1931,7 +1886,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/PostableGrafanaRule"
@@ -2220,7 +2175,7 @@
"PushoverConfig": {
"properties": {
"expire": {
"$ref": "#/definitions/duration"
"type": "string"
},
"html": {
"type": "boolean"
@@ -2235,7 +2190,7 @@
"type": "string"
},
"retry": {
"$ref": "#/definitions/duration"
"type": "string"
},
"send_resolved": {
"type": "boolean"
@@ -2265,16 +2220,12 @@
"description": "The embedded FieldConfig's display name must be set.\nIt corresponds to the QueryResultMetaStat on the frontend (https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L53).",
"properties": {
"color": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object"
},
"custom": {
"additionalProperties": {
"type": "object"
},
"additionalProperties": {},
"description": "Panel Specific Values",
"type": "object"
},
@@ -2462,10 +2413,10 @@
"type": "array"
},
"group_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"group_wait": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"match": {
"additionalProperties": {
@@ -2496,7 +2447,7 @@
"type": "string"
},
"repeat_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"routes": {
"items": {
@@ -2897,6 +2848,9 @@
"description": "The client key file for the targets.",
"type": "string"
},
"min_version": {
"$ref": "#/definitions/TLSVersion"
},
"server_name": {
"description": "Used to verify the hostname for the targets.",
"type": "string"
@@ -2905,6 +2859,10 @@
"title": "TLSConfig configures the options for TLS connections.",
"type": "object"
},
"TLSVersion": {
"format": "uint16",
"type": "integer"
},
"TelegramConfig": {
"properties": {
"api_url": {
@@ -3073,13 +3031,13 @@
"properties": {
"days_of_month": {
"items": {
"$ref": "#/definitions/DayOfMonthRange"
"type": "string"
},
"type": "array"
},
"months": {
"items": {
"$ref": "#/definitions/MonthRange"
"type": "string"
},
"type": "array"
},
@@ -3091,13 +3049,13 @@
},
"weekdays": {
"items": {
"$ref": "#/definitions/WeekdayRange"
"type": "string"
},
"type": "array"
},
"years": {
"items": {
"$ref": "#/definitions/YearRange"
"type": "string"
},
"type": "array"
}
@@ -3120,6 +3078,7 @@
"type": "object"
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -3130,6 +3089,9 @@
"Host": {
"type": "string"
},
"OmitHost": {
"type": "boolean"
},
"Opaque": {
"type": "string"
},
@@ -3152,7 +3114,7 @@
"$ref": "#/definitions/Userinfo"
}
},
"title": "URL is a custom URL type that allows validation at configuration load time.",
"title": "A URL represents a parsed URL (technically, a URI reference).",
"type": "object"
},
"Userinfo": {
@@ -3290,34 +3252,6 @@
"title": "WechatConfig configures notifications via Wechat.",
"type": "object"
},
"WeekdayRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A WeekdayRange is an inclusive range between [0, 6] where 0 = Sunday.",
"type": "object"
},
"YearRange": {
"properties": {
"Begin": {
"format": "int64",
"type": "integer"
},
"End": {
"format": "int64",
"type": "integer"
}
},
"title": "A YearRange is a positive inclusive range.",
"type": "object"
},
"alert": {
"description": "Alert alert",
"properties": {
@@ -3462,11 +3396,7 @@
],
"type": "object"
},
"duration": {
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@@ -3522,6 +3452,7 @@
"type": "object"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"items": {
"$ref": "#/definitions/gettableAlert"
},
@@ -3576,12 +3507,42 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
"type": "array"
},
"integration": {
"description": "Integration integration",
"properties": {
"lastNotifyAttempt": {
"description": "A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
"format": "date-time",
"type": "string"
},
"lastNotifyAttemptDuration": {
"description": "Duration of the last attempt to deliver a notification in humanized format (`1s` or `15ms`, etc).",
"type": "string"
},
"lastNotifyAttemptError": {
"description": "Error string for the last attempt to deliver a notification. Empty if the last attempt was successful.",
"type": "string"
},
"name": {
"description": "name",
"type": "string"
},
"sendResolved": {
"description": "send resolved",
"type": "boolean"
}
},
"required": [
"name",
"sendResolved"
],
"type": "object"
},
"labelSet": {
"additionalProperties": {
"type": "string"
@@ -3687,7 +3648,6 @@
"type": "array"
},
"postableSilence": {
"description": "PostableSilence postable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3725,13 +3685,27 @@
"type": "object"
},
"receiver": {
"description": "Receiver receiver",
"properties": {
"active": {
"description": "active",
"type": "boolean"
},
"integrations": {
"description": "integrations",
"items": {
"$ref": "#/definitions/integration"
},
"type": "array"
},
"name": {
"description": "name",
"type": "string"
}
},
"required": [
"active",
"integrations",
"name"
],
"type": "object"
@@ -4206,6 +4180,20 @@
]
}
},
"/api/alertmanager/grafana/config/api/v1/receivers": {
"get": {
"operationId": "RouteGetGrafanaReceivers",
"responses": {
"200": {
"$ref": "#/responses/receivers"
}
},
"summary": "Get a list of all receivers.",
"tags": [
"alertmanager"
]
}
},
"/api/alertmanager/grafana/config/api/v1/receivers/test": {
"post": {
"operationId": "RoutePostTestGrafanaReceivers",
@@ -5462,6 +5450,26 @@
]
}
},
"/api/v1/ngalert": {
"get": {
"description": "Get the status of the alerting engine",
"operationId": "RouteGetStatus",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "AlertingStatus",
"schema": {
"$ref": "#/definitions/AlertingStatus"
}
}
},
"tags": [
"configuration"
]
}
},
"/api/v1/ngalert/admin_config": {
"delete": {
"consumes": [
@@ -5571,26 +5579,6 @@
]
}
},
"/api/v1/ngalert": {
"get": {
"description": "Get the status of the alerting engine",
"operationId": "RouteGetStatus",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "AlertingStatus",
"schema": {
"$ref": "#/definitions/AlertingStatus"
}
}
},
"tags": [
"configuration"
]
}
},
"/api/v1/provisioning/alert-rules": {
"post": {
"consumes": [

View File

@@ -392,6 +392,20 @@
}
}
},
"/api/alertmanager/grafana/config/api/v1/receivers": {
"get": {
"tags": [
"alertmanager"
],
"summary": "Get a list of all receivers.",
"operationId": "RouteGetGrafanaReceivers",
"responses": {
"200": {
"$ref": "#/responses/receivers"
}
}
}
},
"/api/alertmanager/grafana/config/api/v1/receivers/test": {
"post": {
"tags": [
@@ -1648,6 +1662,26 @@
}
}
},
"/api/v1/ngalert": {
"get": {
"description": "Get the status of the alerting engine",
"produces": [
"application/json"
],
"tags": [
"configuration"
],
"operationId": "RouteGetStatus",
"responses": {
"200": {
"description": "AlertingStatus",
"schema": {
"$ref": "#/definitions/AlertingStatus"
}
}
}
}
},
"/api/v1/ngalert/admin_config": {
"get": {
"produces": [
@@ -1757,26 +1791,6 @@
}
}
},
"/api/v1/ngalert": {
"get": {
"description": "Get the status of the alerting engine",
"produces": [
"application/json"
],
"tags": [
"configuration"
],
"operationId": "RouteGetStatus",
"responses": {
"200": {
"description": "AlertingStatus",
"schema": {
"$ref": "#/definitions/AlertingStatus"
}
}
}
}
},
"/api/v1/provisioning/alert-rules": {
"post": {
"consumes": [
@@ -2782,7 +2796,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"labels": {
"type": "object",
@@ -2899,25 +2913,6 @@
"type": "string",
"title": "DataTopic is used to identify which topic the frame should be assigned to."
},
"DateTime": {
"description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.",
"type": "string",
"format": "date-time"
},
"DayOfMonthRange": {
"type": "object",
"title": "A DayOfMonthRange is an inclusive range that may have negative Beginning/End values that represent distance from the End of the month Beginning at -1.",
"properties": {
"Begin": {
"type": "integer",
"format": "int64"
},
"End": {
"type": "integer",
"format": "int64"
}
}
},
"DiscoveryBase": {
"type": "object",
"required": [
@@ -3153,16 +3148,12 @@
"color": {
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object",
"additionalProperties": {
"type": "object"
}
"additionalProperties": {}
},
"custom": {
"description": "Panel Specific Values",
"type": "object",
"additionalProperties": {
"type": "object"
}
"additionalProperties": {}
},
"decimals": {
"type": "integer",
@@ -3268,8 +3259,7 @@
"type": "string"
},
"custom": {
"description": "Custom datasource specific values.",
"type": "object"
"description": "Custom datasource specific values."
},
"dataTopic": {
"$ref": "#/definitions/DataTopic"
@@ -3464,7 +3454,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/GettableGrafanaRule"
@@ -3765,6 +3755,10 @@
"description": "The bearer token file for the targets. Deprecated in favour of\nAuthorization.CredentialsFile.",
"type": "string"
},
"enable_http2": {
"description": "EnableHTTP2 specifies whether the client should configure HTTP2.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
},
"follow_redirects": {
"description": "FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\nThe omitempty flag is not set, because it would be hidden from the\nmarshalled configuration when set to false.",
"type": "boolean"
@@ -3792,20 +3786,6 @@
}
}
},
"InclusiveRange": {
"type": "object",
"title": "InclusiveRange is used to hold the Beginning and End values of many time interval components.",
"properties": {
"Begin": {
"type": "integer",
"format": "int64"
},
"End": {
"type": "integer",
"format": "int64"
}
}
},
"InhibitRule": {
"description": "InhibitRule defines an inhibition rule that mutes alerts that match the\ntarget labels if an alert matching the source labels exists.\nBoth alerts have to have a set of labels being equal.",
"type": "object",
@@ -4026,20 +4006,6 @@
"$ref": "#/definitions/MessageTemplate"
}
},
"MonthRange": {
"type": "object",
"title": "A MonthRange is an inclusive range between [1, 12] where 1 = January.",
"properties": {
"Begin": {
"type": "integer",
"format": "int64"
},
"End": {
"type": "integer",
"format": "int64"
}
}
},
"MultiStatus": {
"type": "object"
},
@@ -4132,6 +4098,9 @@
"type": "string"
}
},
"proxy_url": {
"$ref": "#/definitions/URL"
},
"scopes": {
"type": "array",
"items": {
@@ -4457,7 +4426,7 @@
"type": "string"
},
"for": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"grafana_alert": {
"$ref": "#/definitions/PostableGrafanaRule"
@@ -4746,7 +4715,7 @@
"type": "object",
"properties": {
"expire": {
"$ref": "#/definitions/duration"
"type": "string"
},
"html": {
"type": "boolean"
@@ -4761,7 +4730,7 @@
"type": "string"
},
"retry": {
"$ref": "#/definitions/duration"
"type": "string"
},
"send_resolved": {
"type": "boolean"
@@ -4794,16 +4763,12 @@
"color": {
"description": "Map values to a display color\nNOTE: this interface is under development in the frontend... so simple map for now",
"type": "object",
"additionalProperties": {
"type": "object"
}
"additionalProperties": {}
},
"custom": {
"description": "Panel Specific Values",
"type": "object",
"additionalProperties": {
"type": "object"
}
"additionalProperties": {}
},
"decimals": {
"type": "integer",
@@ -4988,10 +4953,10 @@
}
},
"group_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"group_wait": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"match": {
"description": "Deprecated. Remove before v1.0 release.",
@@ -5022,7 +4987,7 @@
"type": "string"
},
"repeat_interval": {
"$ref": "#/definitions/Duration"
"type": "string"
},
"routes": {
"type": "array",
@@ -5424,12 +5389,19 @@
"description": "The client key file for the targets.",
"type": "string"
},
"min_version": {
"$ref": "#/definitions/TLSVersion"
},
"server_name": {
"description": "Used to verify the hostname for the targets.",
"type": "string"
}
}
},
"TLSVersion": {
"type": "integer",
"format": "uint16"
},
"TelegramConfig": {
"type": "object",
"title": "TelegramConfig configures notifications via Telegram.",
@@ -5600,13 +5572,13 @@
"days_of_month": {
"type": "array",
"items": {
"$ref": "#/definitions/DayOfMonthRange"
"type": "string"
}
},
"months": {
"type": "array",
"items": {
"$ref": "#/definitions/MonthRange"
"type": "string"
}
},
"times": {
@@ -5618,13 +5590,13 @@
"weekdays": {
"type": "array",
"items": {
"$ref": "#/definitions/WeekdayRange"
"type": "string"
}
},
"years": {
"type": "array",
"items": {
"$ref": "#/definitions/YearRange"
"type": "string"
}
}
}
@@ -5645,8 +5617,9 @@
}
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"type": "object",
"title": "URL is a custom URL type that allows validation at configuration load time.",
"title": "A URL represents a parsed URL (technically, a URI reference).",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -5657,6 +5630,9 @@
"Host": {
"type": "string"
},
"OmitHost": {
"type": "boolean"
},
"Opaque": {
"type": "string"
},
@@ -5815,34 +5791,6 @@
}
}
},
"WeekdayRange": {
"type": "object",
"title": "A WeekdayRange is an inclusive range between [0, 6] where 0 = Sunday.",
"properties": {
"Begin": {
"type": "integer",
"format": "int64"
},
"End": {
"type": "integer",
"format": "int64"
}
}
},
"YearRange": {
"type": "object",
"title": "A YearRange is a positive inclusive range.",
"properties": {
"Begin": {
"type": "integer",
"format": "int64"
},
"End": {
"type": "integer",
"format": "int64"
}
}
},
"alert": {
"description": "Alert alert",
"type": "object",
@@ -5989,11 +5937,7 @@
}
}
},
"duration": {
"$ref": "#/definitions/Duration"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"type": "object",
"required": [
"labels",
@@ -6050,6 +5994,7 @@
"$ref": "#/definitions/gettableAlert"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"type": "array",
"items": {
"$ref": "#/definitions/gettableAlert"
@@ -6106,13 +6051,44 @@
"$ref": "#/definitions/gettableSilence"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"type": "array",
"items": {
"$ref": "#/definitions/gettableSilence"
},
"$ref": "#/definitions/gettableSilences"
},
"integration": {
"description": "Integration integration",
"type": "object",
"required": [
"name",
"sendResolved"
],
"properties": {
"lastNotifyAttempt": {
"description": "A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
"type": "string",
"format": "date-time"
},
"lastNotifyAttemptDuration": {
"description": "Duration of the last attempt to deliver a notification in humanized format (`1s` or `15ms`, etc).",
"type": "string"
},
"lastNotifyAttemptError": {
"description": "Error string for the last attempt to deliver a notification. Empty if the last attempt was successful.",
"type": "string"
},
"name": {
"description": "name",
"type": "string"
},
"sendResolved": {
"description": "send resolved",
"type": "boolean"
}
},
"$ref": "#/definitions/integration"
},
"labelSet": {
"description": "LabelSet label set",
"type": "object",
@@ -6218,7 +6194,6 @@
}
},
"postableSilence": {
"description": "PostableSilence postable silence",
"type": "object",
"required": [
"comment",
@@ -6257,11 +6232,25 @@
"$ref": "#/definitions/postableSilence"
},
"receiver": {
"description": "Receiver receiver",
"type": "object",
"required": [
"active",
"integrations",
"name"
],
"properties": {
"active": {
"description": "active",
"type": "boolean"
},
"integrations": {
"description": "integrations",
"type": "array",
"items": {
"$ref": "#/definitions/integration"
}
},
"name": {
"description": "name",
"type": "string"