Alerting: Notifications Routes API (#91550)

* Introduce new models RoutingTree, RouteDefaults and Route and api-server to serve them that is backed by provisioning notification policy service.

* update method UpdatePolicyTree of notification policy service to return route and new version

* declare new actions alert.notifications.routes:read and alert.notifications.routes:write and two corresponding fixed roles.

---------

Co-authored-by: Tom Ratcliffe <tom.ratcliffe@grafana.com>
Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>
This commit is contained in:
Yuri Tseretyan
2024-10-24 13:53:03 -04:00
committed by GitHub
co-authored by Tom Ratcliffe Matthew Jacobson
parent fb0221d561
commit 2deced7d40
41 changed files with 2809 additions and 54 deletions
@@ -58,7 +58,10 @@ func (srv AlertmanagerSrv) k8sApiServiceGuard(currentConfig apimodels.GettableUs
func checkRoutes(currentConfig apimodels.GettableUserConfig, newConfig apimodels.PostableUserConfig) error {
reporter := cmputil.DiffReporter{}
options := []cmp.Option{cmp.Reporter(&reporter), cmpopts.EquateEmpty(), cmpopts.IgnoreUnexported(labels.Matcher{})}
options := []cmp.Option{cmp.Reporter(&reporter), cmpopts.EquateEmpty(), cmpopts.IgnoreUnexported(labels.Matcher{}), cmp.Transformer("", func(regexp amConfig.Regexp) any {
r, _ := regexp.MarshalYAML()
return r
})}
routesEqual := cmp.Equal(currentConfig.AlertmanagerConfig.Route, newConfig.AlertmanagerConfig.Route, options...)
if !routesEqual && currentConfig.AlertmanagerConfig.Route.Provenance != apimodels.Provenance(ngmodels.ProvenanceNone) {
return fmt.Errorf("policies were provisioned and cannot be changed through the UI")
+2 -2
View File
@@ -52,7 +52,7 @@ type TemplateService interface {
type NotificationPolicyService interface {
GetPolicyTree(ctx context.Context, orgID int64) (definitions.Route, string, error)
UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p alerting_models.Provenance, version string) error
UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p alerting_models.Provenance, version string) (definitions.Route, string, error)
ResetPolicyTree(ctx context.Context, orgID int64, provenance alerting_models.Provenance) (definitions.Route, error)
}
@@ -109,7 +109,7 @@ func (srv *ProvisioningSrv) RouteGetPolicyTreeExport(c *contextmodel.ReqContext)
func (srv *ProvisioningSrv) RoutePutPolicyTree(c *contextmodel.ReqContext, tree definitions.Route) response.Response {
provenance := determineProvenance(c)
err := srv.policies.UpdatePolicyTree(c.Req.Context(), c.SignedInUser.GetOrgID(), tree, alerting_models.Provenance(provenance), "")
_, _, err := srv.policies.UpdatePolicyTree(c.Req.Context(), c.SignedInUser.GetOrgID(), tree, alerting_models.Provenance(provenance), "")
if errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
return ErrResp(http.StatusNotFound, err, "")
}
@@ -2035,13 +2035,13 @@ func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID
return result, "", nil
}
func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, _ string) error {
func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, version string) (definitions.Route, string, error) {
if orgID != 1 {
return store.ErrNoAlertmanagerConfiguration
return definitions.Route{}, "", store.ErrNoAlertmanagerConfiguration
}
f.tree = tree
f.prov = p
return nil
return tree, "some", nil
}
func (f *fakeNotificationPolicyService) ResetPolicyTree(ctx context.Context, orgID int64, provenance models.Provenance) (definitions.Route, error) {
@@ -2055,8 +2055,8 @@ func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context
return definitions.Route{}, "", fmt.Errorf("something went wrong")
}
func (f *fakeFailingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, _ string) error {
return fmt.Errorf("something went wrong")
func (f *fakeFailingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, version string) (definitions.Route, string, error) {
return definitions.Route{}, "", fmt.Errorf("something went wrong")
}
func (f *fakeFailingNotificationPolicyService) ResetPolicyTree(ctx context.Context, orgID int64, provenance models.Provenance) (definitions.Route, error) {
@@ -2069,8 +2069,8 @@ func (f *fakeRejectingNotificationPolicyService) GetPolicyTree(ctx context.Conte
return definitions.Route{}, "", nil
}
func (f *fakeRejectingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, _ string) error {
return fmt.Errorf("%w: invalid policy tree", provisioning.ErrValidation)
func (f *fakeRejectingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree definitions.Route, p models.Provenance, version string) (definitions.Route, string, error) {
return definitions.Route{}, "", fmt.Errorf("%w: invalid policy tree", provisioning.ErrValidation)
}
func (f *fakeRejectingNotificationPolicyService) ResetPolicyTree(ctx context.Context, orgID int64, provenance models.Provenance) (definitions.Route, error) {