Alerting: Allow provenance disable in alerting provisioning API (#63650)

* Allow provenance None in alert rule update and rule group replace

* Allow provenance None in contact point update

* Allow updating policies to none by sending x-disable-provenance header

* Allow mute timings to disable provenance with x-disable-provenance header

* Allow disabling provenance by using x-disable-provenance header

* Add provenance helper to lower the cyclomatic complexity

* Do not downgrade provenance except un ReplaceRuleGroup

* Add function explanation and change error handling

* Add docs for x-disable-provenance changes (#66300)

* Add docs for x-disable-provenance changes

* Apply suggestions from code review

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>

* Update _index.md

---------

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>

* Update docs/sources/alerting/set-up/provision-alerting-resources/_index.md

Co-authored-by: George Robinson <george.robinson@grafana.com>

* Add error message check in tests

* Change docs

---------

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
Co-authored-by: George Robinson <george.robinson@grafana.com>
This commit is contained in:
Alex Moreno
2023-04-18 15:10:36 +02:00
committed by GitHub
co-authored by brendamuir George Robinson
parent 614427c602
commit f64a89727e
8 changed files with 157 additions and 136 deletions
+20 -16
View File
@@ -80,7 +80,8 @@ func (srv *ProvisioningSrv) RouteGetPolicyTree(c *contextmodel.ReqContext) respo
}
func (srv *ProvisioningSrv) RoutePutPolicyTree(c *contextmodel.ReqContext, tree definitions.Route) response.Response {
err := srv.policies.UpdatePolicyTree(c.Req.Context(), c.OrgID, tree, alerting_models.ProvenanceAPI)
provenance := determineProvenance(c)
err := srv.policies.UpdatePolicyTree(c.Req.Context(), c.OrgID, tree, alerting_models.Provenance(provenance))
if errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
return ErrResp(http.StatusNotFound, err, "")
}
@@ -115,8 +116,8 @@ func (srv *ProvisioningSrv) RouteGetContactPoints(c *contextmodel.ReqContext) re
}
func (srv *ProvisioningSrv) RoutePostContactPoint(c *contextmodel.ReqContext, cp definitions.EmbeddedContactPoint) response.Response {
// TODO: provenance is hardcoded for now, change it later to make it more flexible
contactPoint, err := srv.contactPointService.CreateContactPoint(c.Req.Context(), c.OrgID, cp, alerting_models.ProvenanceAPI)
provenance := determineProvenance(c)
contactPoint, err := srv.contactPointService.CreateContactPoint(c.Req.Context(), c.OrgID, cp, alerting_models.Provenance(provenance))
if errors.Is(err, provisioning.ErrValidation) {
return ErrResp(http.StatusBadRequest, err, "")
}
@@ -128,7 +129,8 @@ func (srv *ProvisioningSrv) RoutePostContactPoint(c *contextmodel.ReqContext, cp
func (srv *ProvisioningSrv) RoutePutContactPoint(c *contextmodel.ReqContext, cp definitions.EmbeddedContactPoint, UID string) response.Response {
cp.UID = UID
err := srv.contactPointService.UpdateContactPoint(c.Req.Context(), c.OrgID, cp, alerting_models.ProvenanceAPI)
provenance := determineProvenance(c)
err := srv.contactPointService.UpdateContactPoint(c.Req.Context(), c.OrgID, cp, alerting_models.Provenance(provenance))
if errors.Is(err, provisioning.ErrValidation) {
return ErrResp(http.StatusBadRequest, err, "")
}
@@ -176,7 +178,7 @@ func (srv *ProvisioningSrv) RoutePutTemplate(c *contextmodel.ReqContext, body de
tmpl := definitions.NotificationTemplate{
Name: name,
Template: body.Template,
Provenance: definitions.Provenance(alerting_models.ProvenanceAPI),
Provenance: determineProvenance(c),
}
modified, err := srv.templates.SetTemplate(c.Req.Context(), c.OrgID, tmpl)
if err != nil {
@@ -218,7 +220,7 @@ func (srv *ProvisioningSrv) RouteGetMuteTimings(c *contextmodel.ReqContext) resp
}
func (srv *ProvisioningSrv) RoutePostMuteTiming(c *contextmodel.ReqContext, mt definitions.MuteTimeInterval) response.Response {
mt.Provenance = definitions.Provenance(alerting_models.ProvenanceAPI)
mt.Provenance = determineProvenance(c)
created, err := srv.muteTimings.CreateMuteTiming(c.Req.Context(), mt, c.OrgID)
if err != nil {
if errors.Is(err, provisioning.ErrValidation) {
@@ -231,7 +233,7 @@ func (srv *ProvisioningSrv) RoutePostMuteTiming(c *contextmodel.ReqContext, mt d
func (srv *ProvisioningSrv) RoutePutMuteTiming(c *contextmodel.ReqContext, mt definitions.MuteTimeInterval, name string) response.Response {
mt.Name = name
mt.Provenance = definitions.Provenance(alerting_models.ProvenanceAPI)
mt.Provenance = determineProvenance(c)
updated, err := srv.muteTimings.UpdateMuteTiming(c.Req.Context(), mt, c.OrgID)
if err != nil {
if errors.Is(err, provisioning.ErrValidation) {
@@ -276,7 +278,7 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar de
return ErrResp(http.StatusBadRequest, err, "")
}
provenance := determineProvenance(c)
createdAlertRule, err := srv.alertRules.CreateAlertRule(c.Req.Context(), upstreamModel, provenance, c.UserID)
createdAlertRule, err := srv.alertRules.CreateAlertRule(c.Req.Context(), upstreamModel, alerting_models.Provenance(provenance), c.UserID)
if errors.Is(err, alerting_models.ErrAlertRuleFailedValidation) {
return ErrResp(http.StatusBadRequest, err, "")
}
@@ -290,7 +292,7 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar de
return ErrResp(http.StatusInternalServerError, err, "")
}
resp := ProvisionedAlertRuleFromAlertRule(createdAlertRule, provenance)
resp := ProvisionedAlertRuleFromAlertRule(createdAlertRule, alerting_models.Provenance(provenance))
return response.JSON(http.StatusCreated, resp)
}
@@ -302,7 +304,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
updated.OrgID = c.OrgID
updated.UID = UID
provenance := determineProvenance(c)
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), updated, provenance)
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), updated, alerting_models.Provenance(provenance))
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
return response.Empty(http.StatusNotFound)
}
@@ -316,12 +318,13 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
return ErrResp(http.StatusInternalServerError, err, "")
}
resp := ProvisionedAlertRuleFromAlertRule(updatedAlertRule, provenance)
resp := ProvisionedAlertRuleFromAlertRule(updatedAlertRule, alerting_models.Provenance(provenance))
return response.JSON(http.StatusOK, resp)
}
func (srv *ProvisioningSrv) RouteDeleteAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
err := srv.alertRules.DeleteAlertRule(c.Req.Context(), c.OrgID, UID, alerting_models.ProvenanceAPI)
provenance := determineProvenance(c)
err := srv.alertRules.DeleteAlertRule(c.Req.Context(), c.OrgID, UID, alerting_models.Provenance(provenance))
if err != nil {
return ErrResp(http.StatusInternalServerError, err, "")
}
@@ -406,7 +409,8 @@ func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *contextmodel.ReqContext, a
if err != nil {
ErrResp(http.StatusBadRequest, err, "")
}
err = srv.alertRules.ReplaceRuleGroup(c.Req.Context(), c.OrgID, groupModel, c.UserID, alerting_models.ProvenanceAPI)
provenance := determineProvenance(c)
err = srv.alertRules.ReplaceRuleGroup(c.Req.Context(), c.OrgID, groupModel, c.UserID, alerting_models.Provenance(provenance))
if errors.Is(err, alerting_models.ErrAlertRuleFailedValidation) {
return ErrResp(http.StatusBadRequest, err, "")
}
@@ -419,11 +423,11 @@ func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *contextmodel.ReqContext, a
return response.JSON(http.StatusOK, ag)
}
func determineProvenance(ctx *contextmodel.ReqContext) alerting_models.Provenance {
func determineProvenance(ctx *contextmodel.ReqContext) definitions.Provenance {
if _, disabled := ctx.Req.Header[disableProvenanceHeaderName]; disabled {
return alerting_models.ProvenanceNone
return definitions.Provenance(alerting_models.ProvenanceNone)
}
return alerting_models.ProvenanceAPI
return definitions.Provenance(alerting_models.ProvenanceAPI)
}
func exportResponse(c *contextmodel.ReqContext, body any) response.Response {