Alerting: New API endpoint GET /api/v1/ngalert (#55134)
* declare new endpoint /api/v1/ngalert * add authorization for new path * add request handler for the new path
This commit is contained in:
@@ -143,3 +143,22 @@ func (srv ConfigSrv) externalAlertmanagers(ctx context.Context, orgID int64) ([]
|
|||||||
}
|
}
|
||||||
return alertmanagers, nil
|
return alertmanagers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv ConfigSrv) RouteGetAlertingStatus(c *models.ReqContext) response.Response {
|
||||||
|
sendsAlertsTo := ngmodels.InternalAlertmanager
|
||||||
|
|
||||||
|
cfg, err := srv.store.GetAdminConfiguration(c.OrgID)
|
||||||
|
if err != nil && !errors.Is(err, store.ErrNoAdminConfiguration) {
|
||||||
|
msg := "failed to fetch configuration from the database"
|
||||||
|
srv.log.Error(msg, "err", err)
|
||||||
|
return ErrResp(http.StatusInternalServerError, err, msg)
|
||||||
|
}
|
||||||
|
if cfg != nil {
|
||||||
|
sendsAlertsTo = cfg.SendAlertsTo
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := apimodels.AlertingStatus{
|
||||||
|
AlertmanagersChoice: apimodels.AlertmanagersChoice(sendsAlertsTo.String()),
|
||||||
|
}
|
||||||
|
return response.JSON(http.StatusOK, resp)
|
||||||
|
}
|
||||||
|
|||||||
@@ -172,6 +172,16 @@ func (api *API) authorize(method, path string) web.Handler {
|
|||||||
case http.MethodPost + "/api/alertmanager/{DatasourceUID}/config/api/v1/receivers/test":
|
case http.MethodPost + "/api/alertmanager/{DatasourceUID}/config/api/v1/receivers/test":
|
||||||
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
|
eval = ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead, datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":DatasourceUID")))
|
||||||
|
|
||||||
|
case http.MethodGet + "/api/v1/ngalert":
|
||||||
|
// let user with any alerting permission access this API
|
||||||
|
eval = ac.EvalAny(
|
||||||
|
ac.EvalPermission(ac.ActionAlertingInstanceRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingInstancesExternalRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingRuleRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingRuleExternalRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingNotificationsRead),
|
||||||
|
ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead),
|
||||||
|
)
|
||||||
// Raw Alertmanager Config Paths
|
// Raw Alertmanager Config Paths
|
||||||
case http.MethodDelete + "/api/v1/ngalert/admin_config",
|
case http.MethodDelete + "/api/v1/ngalert/admin_config",
|
||||||
http.MethodGet + "/api/v1/ngalert/admin_config",
|
http.MethodGet + "/api/v1/ngalert/admin_config",
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func TestAuthorize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
paths[p] = methods
|
paths[p] = methods
|
||||||
}
|
}
|
||||||
require.Len(t, paths, 39)
|
require.Len(t, paths, 40)
|
||||||
|
|
||||||
ac := acmock.New()
|
ac := acmock.New()
|
||||||
api := &API{AccessControl: ac}
|
api := &API{AccessControl: ac}
|
||||||
|
|||||||
@@ -32,3 +32,7 @@ func (f *ConfigurationApiHandler) handleRoutePostNGalertConfig(c *models.ReqCont
|
|||||||
func (f *ConfigurationApiHandler) handleRouteDeleteNGalertConfig(c *models.ReqContext) response.Response {
|
func (f *ConfigurationApiHandler) handleRouteDeleteNGalertConfig(c *models.ReqContext) response.Response {
|
||||||
return f.grafana.RouteDeleteNGalertConfig(c)
|
return f.grafana.RouteDeleteNGalertConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *ConfigurationApiHandler) handleRouteGetStatus(c *models.ReqContext) response.Response {
|
||||||
|
return f.grafana.RouteGetAlertingStatus(c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type ConfigurationApi interface {
|
|||||||
RouteDeleteNGalertConfig(*models.ReqContext) response.Response
|
RouteDeleteNGalertConfig(*models.ReqContext) response.Response
|
||||||
RouteGetAlertmanagers(*models.ReqContext) response.Response
|
RouteGetAlertmanagers(*models.ReqContext) response.Response
|
||||||
RouteGetNGalertConfig(*models.ReqContext) response.Response
|
RouteGetNGalertConfig(*models.ReqContext) response.Response
|
||||||
|
RouteGetStatus(*models.ReqContext) response.Response
|
||||||
RoutePostNGalertConfig(*models.ReqContext) response.Response
|
RoutePostNGalertConfig(*models.ReqContext) response.Response
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +35,9 @@ func (f *ConfigurationApiHandler) RouteGetAlertmanagers(ctx *models.ReqContext)
|
|||||||
func (f *ConfigurationApiHandler) RouteGetNGalertConfig(ctx *models.ReqContext) response.Response {
|
func (f *ConfigurationApiHandler) RouteGetNGalertConfig(ctx *models.ReqContext) response.Response {
|
||||||
return f.handleRouteGetNGalertConfig(ctx)
|
return f.handleRouteGetNGalertConfig(ctx)
|
||||||
}
|
}
|
||||||
|
func (f *ConfigurationApiHandler) RouteGetStatus(ctx *models.ReqContext) response.Response {
|
||||||
|
return f.handleRouteGetStatus(ctx)
|
||||||
|
}
|
||||||
func (f *ConfigurationApiHandler) RoutePostNGalertConfig(ctx *models.ReqContext) response.Response {
|
func (f *ConfigurationApiHandler) RoutePostNGalertConfig(ctx *models.ReqContext) response.Response {
|
||||||
// Parse Request Body
|
// Parse Request Body
|
||||||
conf := apimodels.PostableNGalertConfig{}
|
conf := apimodels.PostableNGalertConfig{}
|
||||||
@@ -75,6 +79,16 @@ func (api *API) RegisterConfigurationApiEndpoints(srv ConfigurationApi, m *metri
|
|||||||
m,
|
m,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
group.Get(
|
||||||
|
toMacaronPath("/api/v1/ngalert"),
|
||||||
|
api.authorize(http.MethodGet, "/api/v1/ngalert"),
|
||||||
|
metrics.Instrument(
|
||||||
|
http.MethodGet,
|
||||||
|
"/api/v1/ngalert",
|
||||||
|
srv.RouteGetStatus,
|
||||||
|
m,
|
||||||
|
),
|
||||||
|
)
|
||||||
group.Post(
|
group.Post(
|
||||||
toMacaronPath("/api/v1/ngalert/admin_config"),
|
toMacaronPath("/api/v1/ngalert/admin_config"),
|
||||||
api.authorize(http.MethodPost, "/api/v1/ngalert/admin_config"),
|
api.authorize(http.MethodPost, "/api/v1/ngalert/admin_config"),
|
||||||
|
|||||||
@@ -232,6 +232,19 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AlertingStatus": {
|
||||||
|
"properties": {
|
||||||
|
"alertmanagersChoice": {
|
||||||
|
"enum": [
|
||||||
|
"all",
|
||||||
|
"internal",
|
||||||
|
"external"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"ApiRuleNode": {
|
"ApiRuleNode": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"alert": {
|
"alert": {
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ import (
|
|||||||
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
|
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// swagger:route GET /api/v1/ngalert configuration RouteGetStatus
|
||||||
|
//
|
||||||
|
// Get the status of the alerting engine
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: AlertingStatus
|
||||||
|
|
||||||
// swagger:route GET /api/v1/ngalert/alertmanagers configuration RouteGetAlertmanagers
|
// swagger:route GET /api/v1/ngalert/alertmanagers configuration RouteGetAlertmanagers
|
||||||
//
|
//
|
||||||
// Get the discovered and dropped Alertmanagers of the user's organization based on the specified configuration.
|
// Get the discovered and dropped Alertmanagers of the user's organization based on the specified configuration.
|
||||||
@@ -81,3 +91,8 @@ type GettableAlertmanagers struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Data v1.AlertManagersResult `json:"data"`
|
Data v1.AlertManagersResult `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model
|
||||||
|
type AlertingStatus struct {
|
||||||
|
AlertmanagersChoice AlertmanagersChoice `json:"alertmanagersChoice"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -232,6 +232,19 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AlertingStatus": {
|
||||||
|
"properties": {
|
||||||
|
"alertmanagersChoice": {
|
||||||
|
"enum": [
|
||||||
|
"all",
|
||||||
|
"internal",
|
||||||
|
"external"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"ApiRuleNode": {
|
"ApiRuleNode": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"alert": {
|
"alert": {
|
||||||
@@ -5558,6 +5571,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/provisioning/alert-rules": {
|
"/api/v1/provisioning/alert-rules": {
|
||||||
"post": {
|
"post": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
|
|||||||
@@ -1757,6 +1757,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/provisioning/alert-rules": {
|
"/api/v1/provisioning/alert-rules": {
|
||||||
"post": {
|
"post": {
|
||||||
"consumes": [
|
"consumes": [
|
||||||
@@ -2733,6 +2753,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"AlertingStatus": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"alertmanagersChoice": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"all",
|
||||||
|
"internal",
|
||||||
|
"external"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ApiRuleNode": {
|
"ApiRuleNode": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
Reference in New Issue
Block a user