mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Introduce the silencing interface (#32517)
* Alerting: Introduce the silencing interface The operations introduced are: - Listing silences - Retrieving an specific silence - Deleting a silence - Creating a silence Signed-off-by: Josue Abreu <josue@grafana.com> * Add a comment to listing silences * Update to upstream alertmanager * Remove copied code from the Alertmanager
This commit is contained in:
parent
230f95dc47
commit
433f6b91d0
4
go.mod
4
go.mod
@ -40,7 +40,7 @@ require (
|
|||||||
github.com/google/go-cmp v0.5.5
|
github.com/google/go-cmp v0.5.5
|
||||||
github.com/google/uuid v1.2.0
|
github.com/google/uuid v1.2.0
|
||||||
github.com/gosimple/slug v1.9.0
|
github.com/gosimple/slug v1.9.0
|
||||||
github.com/grafana/alerting-api v0.0.0-20210323194814-03a29a4c4c27
|
github.com/grafana/alerting-api v0.0.0-20210330162237-0b5408c529a8
|
||||||
github.com/grafana/grafana-aws-sdk v0.3.0
|
github.com/grafana/grafana-aws-sdk v0.3.0
|
||||||
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
|
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
|
||||||
github.com/grafana/grafana-plugin-sdk-go v0.89.0
|
github.com/grafana/grafana-plugin-sdk-go v0.89.0
|
||||||
@ -62,7 +62,7 @@ require (
|
|||||||
github.com/opentracing/opentracing-go v1.2.0
|
github.com/opentracing/opentracing-go v1.2.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prometheus/alertmanager v0.21.1-0.20210324070758-10757eb5fb78
|
github.com/prometheus/alertmanager v0.21.1-0.20210331075806-bc7b16d61afd
|
||||||
github.com/prometheus/client_golang v1.10.0
|
github.com/prometheus/client_golang v1.10.0
|
||||||
github.com/prometheus/client_model v0.2.0
|
github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/common v0.19.0
|
github.com/prometheus/common v0.19.0
|
||||||
|
13
go.sum
13
go.sum
@ -362,6 +362,7 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh
|
|||||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||||
github.com/docker/go-plugins-helpers v0.0.0-20181025120712-1e6269c305b8/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA=
|
github.com/docker/go-plugins-helpers v0.0.0-20181025120712-1e6269c305b8/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA=
|
||||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
@ -795,14 +796,12 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
|
|||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
||||||
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
||||||
github.com/grafana/alerting-api v0.0.0-20210323194814-03a29a4c4c27 h1:DuyuEAHJeI+CMxIyzCVhmHcIeK+sjqberhDUfrgd3PY=
|
github.com/grafana/alerting-api v0.0.0-20210330162237-0b5408c529a8 h1:okhEX26LU7AGN/3C8NDWfdjBmKclvoFvJz9o/LsNcK8=
|
||||||
github.com/grafana/alerting-api v0.0.0-20210323194814-03a29a4c4c27/go.mod h1:5IppnPguSHcCbVLGCVzVjBvuQZNbYgVJ4KyXXjhCyWY=
|
github.com/grafana/alerting-api v0.0.0-20210330162237-0b5408c529a8/go.mod h1:5IppnPguSHcCbVLGCVzVjBvuQZNbYgVJ4KyXXjhCyWY=
|
||||||
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA=
|
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA=
|
||||||
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/grafana/grafana v1.9.2-0.20210308201921-4ce0a49eac03/go.mod h1:AHRRvd4utJGY25J5nW8aL7wZzn/LcJ0z2za9oOp14j4=
|
github.com/grafana/grafana v1.9.2-0.20210308201921-4ce0a49eac03/go.mod h1:AHRRvd4utJGY25J5nW8aL7wZzn/LcJ0z2za9oOp14j4=
|
||||||
github.com/grafana/grafana-aws-sdk v0.1.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U=
|
github.com/grafana/grafana-aws-sdk v0.1.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U=
|
||||||
github.com/grafana/grafana-aws-sdk v0.2.0 h1:UTBBYwye+ad5YUIlwN7TGxLdz1wXN3Ezhl0pseDGRVA=
|
|
||||||
github.com/grafana/grafana-aws-sdk v0.2.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U=
|
|
||||||
github.com/grafana/grafana-aws-sdk v0.3.0 h1:UT3rIXQFeAh0OaRJT7dUQojYaSjbI9RwOtMacaerv8I=
|
github.com/grafana/grafana-aws-sdk v0.3.0 h1:UT3rIXQFeAh0OaRJT7dUQojYaSjbI9RwOtMacaerv8I=
|
||||||
github.com/grafana/grafana-aws-sdk v0.3.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U=
|
github.com/grafana/grafana-aws-sdk v0.3.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U=
|
||||||
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SPdxCL9BChFTlyi0Khv64vdCW4TMna8+sxL7+Chx+Ag=
|
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SPdxCL9BChFTlyi0Khv64vdCW4TMna8+sxL7+Chx+Ag=
|
||||||
@ -968,6 +967,7 @@ github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxy
|
|||||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||||
@ -1336,8 +1336,8 @@ github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2a
|
|||||||
github.com/prometheus/alertmanager v0.21.0/go.mod h1:h7tJ81NA0VLWvWEayi1QltevFkLF3KxmC/malTcT8Go=
|
github.com/prometheus/alertmanager v0.21.0/go.mod h1:h7tJ81NA0VLWvWEayi1QltevFkLF3KxmC/malTcT8Go=
|
||||||
github.com/prometheus/alertmanager v0.21.1-0.20200911160112-1fdff6b3f939/go.mod h1:imXRHOP6QTsE0fFsIsAV/cXimS32m7gVZOiUj11m6Ig=
|
github.com/prometheus/alertmanager v0.21.1-0.20200911160112-1fdff6b3f939/go.mod h1:imXRHOP6QTsE0fFsIsAV/cXimS32m7gVZOiUj11m6Ig=
|
||||||
github.com/prometheus/alertmanager v0.21.1-0.20210211203738-a7ca7b1d2951/go.mod h1:6Yc2n2ap5/oP99x1yN6Ho+yL0w8a0oClIR5xxW/JLGs=
|
github.com/prometheus/alertmanager v0.21.1-0.20210211203738-a7ca7b1d2951/go.mod h1:6Yc2n2ap5/oP99x1yN6Ho+yL0w8a0oClIR5xxW/JLGs=
|
||||||
github.com/prometheus/alertmanager v0.21.1-0.20210324070758-10757eb5fb78 h1:au9OzjUv3GWdL4s98I84hx38oAs+xxxpv/9n2Xuh6n0=
|
github.com/prometheus/alertmanager v0.21.1-0.20210331075806-bc7b16d61afd h1:lu8HKBn7BmowoO79Ypzxn5EN6fHrAbJ6his5dRKDUIY=
|
||||||
github.com/prometheus/alertmanager v0.21.1-0.20210324070758-10757eb5fb78/go.mod h1:g6wbBgNXmelfXjJhLLl5NIJDpejM5oEjiSKDsqnTzio=
|
github.com/prometheus/alertmanager v0.21.1-0.20210331075806-bc7b16d61afd/go.mod h1:g6wbBgNXmelfXjJhLLl5NIJDpejM5oEjiSKDsqnTzio=
|
||||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||||
@ -1440,6 +1440,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/russellhaering/goxmldsig v1.1.0 h1:lK/zeJie2sqG52ZAlPNn1oBBqsIsEKypUUBGpYYF6lk=
|
github.com/russellhaering/goxmldsig v1.1.0 h1:lK/zeJie2sqG52ZAlPNn1oBBqsIsEKypUUBGpYYF6lk=
|
||||||
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
||||||
|
@ -18,14 +18,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type AlertmanagerApiService interface {
|
type AlertmanagerApiService interface {
|
||||||
RouteCreateSilence(*models.ReqContext, apimodels.SilenceBody) response.Response
|
RouteCreateSilence(*models.ReqContext, apimodels.CreateSilenceParams) response.Response
|
||||||
RouteDeleteAlertingConfig(*models.ReqContext) response.Response
|
RouteGetSilences(*models.ReqContext) response.Response
|
||||||
|
RouteGetSilence(*models.ReqContext) response.Response
|
||||||
RouteDeleteSilence(*models.ReqContext) response.Response
|
RouteDeleteSilence(*models.ReqContext) response.Response
|
||||||
|
|
||||||
|
RouteDeleteAlertingConfig(*models.ReqContext) response.Response
|
||||||
RouteGetAMAlertGroups(*models.ReqContext) response.Response
|
RouteGetAMAlertGroups(*models.ReqContext) response.Response
|
||||||
RouteGetAMAlerts(*models.ReqContext) response.Response
|
RouteGetAMAlerts(*models.ReqContext) response.Response
|
||||||
RouteGetAlertingConfig(*models.ReqContext) response.Response
|
RouteGetAlertingConfig(*models.ReqContext) response.Response
|
||||||
RouteGetSilence(*models.ReqContext) response.Response
|
|
||||||
RouteGetSilences(*models.ReqContext) response.Response
|
|
||||||
RoutePostAMAlerts(*models.ReqContext, apimodels.PostableAlerts) response.Response
|
RoutePostAMAlerts(*models.ReqContext, apimodels.PostableAlerts) response.Response
|
||||||
RoutePostAlertingConfig(*models.ReqContext, apimodels.PostableUserConfig) response.Response
|
RoutePostAlertingConfig(*models.ReqContext, apimodels.PostableUserConfig) response.Response
|
||||||
}
|
}
|
||||||
@ -36,29 +37,44 @@ type AlertmanagerApiBase struct {
|
|||||||
|
|
||||||
func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiService) {
|
func (api *API) RegisterAlertmanagerApiEndpoints(srv AlertmanagerApiService) {
|
||||||
api.RouteRegister.Group("", func(group routing.RouteRegister) {
|
api.RouteRegister.Group("", func(group routing.RouteRegister) {
|
||||||
group.Post(toMacaronPath("/alertmanager/{Recipient}/api/v2/silences"), binding.Bind(apimodels.SilenceBody{}), routing.Wrap(srv.RouteCreateSilence))
|
// Silences
|
||||||
group.Delete(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), routing.Wrap(srv.RouteDeleteAlertingConfig))
|
group.Post(toMacaronPath("/alertmanager/{Recipient}/api/v2/silences"), binding.Bind(apimodels.CreateSilenceParams{}), routing.Wrap(srv.RouteCreateSilence))
|
||||||
|
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/silences"), routing.Wrap(srv.RouteGetSilences))
|
||||||
|
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"), routing.Wrap(srv.RouteGetSilence))
|
||||||
group.Delete(toMacaronPath("/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"), routing.Wrap(srv.RouteDeleteSilence))
|
group.Delete(toMacaronPath("/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"), routing.Wrap(srv.RouteDeleteSilence))
|
||||||
|
|
||||||
|
// Alerts
|
||||||
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts/groups"), routing.Wrap(srv.RouteGetAMAlertGroups))
|
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts/groups"), routing.Wrap(srv.RouteGetAMAlertGroups))
|
||||||
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts"), routing.Wrap(srv.RouteGetAMAlerts))
|
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts"), routing.Wrap(srv.RouteGetAMAlerts))
|
||||||
group.Get(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), routing.Wrap(srv.RouteGetAlertingConfig))
|
|
||||||
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/silence/{SilenceId}"), routing.Wrap(srv.RouteGetSilence))
|
|
||||||
group.Get(toMacaronPath("/alertmanager/{Recipient}/api/v2/silences"), routing.Wrap(srv.RouteGetSilences))
|
|
||||||
group.Post(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts"), binding.Bind(apimodels.PostableAlerts{}), routing.Wrap(srv.RoutePostAMAlerts))
|
group.Post(toMacaronPath("/alertmanager/{Recipient}/api/v2/alerts"), binding.Bind(apimodels.PostableAlerts{}), routing.Wrap(srv.RoutePostAMAlerts))
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
group.Delete(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), routing.Wrap(srv.RouteDeleteAlertingConfig))
|
||||||
|
group.Get(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), routing.Wrap(srv.RouteGetAlertingConfig))
|
||||||
group.Post(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), binding.Bind(apimodels.PostableUserConfig{}), routing.Wrap(srv.RoutePostAlertingConfig))
|
group.Post(toMacaronPath("/alertmanager/{Recipient}/config/api/v1/alerts"), binding.Bind(apimodels.PostableUserConfig{}), routing.Wrap(srv.RoutePostAlertingConfig))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RouteCreateSilence(c *models.ReqContext, body apimodels.SilenceBody) response.Response {
|
func (base AlertmanagerApiBase) RouteCreateSilence(c *models.ReqContext, params apimodels.CreateSilenceParams) response.Response {
|
||||||
recipient := c.Params(":Recipient")
|
recipient := c.Params(":Recipient")
|
||||||
base.log.Info("RouteCreateSilence: ", "Recipient", recipient)
|
base.log.Info("RouteCreateSilence: ", "Recipient", recipient)
|
||||||
base.log.Info("RouteCreateSilence: ", "body", body)
|
base.log.Info("RouteCreateSilence: ", "params", params)
|
||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RouteDeleteAlertingConfig(c *models.ReqContext) response.Response {
|
func (base AlertmanagerApiBase) RouteGetSilences(c *models.ReqContext) response.Response {
|
||||||
recipient := c.Params(":Recipient")
|
recipient := c.Params(":Recipient")
|
||||||
base.log.Info("RouteDeleteAlertingConfig: ", "Recipient", recipient)
|
base.log.Info("RouteGetSilences: ", "Recipient", recipient)
|
||||||
|
filter := c.Params(":Filter")
|
||||||
|
base.log.Info("RouteGetSilences: ", "params", filter)
|
||||||
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (base AlertmanagerApiBase) RouteGetSilence(c *models.ReqContext) response.Response {
|
||||||
|
silenceId := c.Params(":SilenceId")
|
||||||
|
base.log.Info("RouteGetSilence: ", "SilenceId", silenceId)
|
||||||
|
recipient := c.Params(":Recipient")
|
||||||
|
base.log.Info("RouteGetSilence: ", "Recipient", recipient)
|
||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +86,12 @@ func (base AlertmanagerApiBase) RouteDeleteSilence(c *models.ReqContext) respons
|
|||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (base AlertmanagerApiBase) RouteDeleteAlertingConfig(c *models.ReqContext) response.Response {
|
||||||
|
recipient := c.Params(":Recipient")
|
||||||
|
base.log.Info("RouteDeleteAlertingConfig: ", "Recipient", recipient)
|
||||||
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RouteGetAMAlertGroups(c *models.ReqContext) response.Response {
|
func (base AlertmanagerApiBase) RouteGetAMAlertGroups(c *models.ReqContext) response.Response {
|
||||||
recipient := c.Params(":Recipient")
|
recipient := c.Params(":Recipient")
|
||||||
base.log.Info("RouteGetAMAlertGroups: ", "Recipient", recipient)
|
base.log.Info("RouteGetAMAlertGroups: ", "Recipient", recipient)
|
||||||
@ -88,20 +110,6 @@ func (base AlertmanagerApiBase) RouteGetAlertingConfig(c *models.ReqContext) res
|
|||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RouteGetSilence(c *models.ReqContext) response.Response {
|
|
||||||
silenceId := c.Params(":SilenceId")
|
|
||||||
base.log.Info("RouteGetSilence: ", "SilenceId", silenceId)
|
|
||||||
recipient := c.Params(":Recipient")
|
|
||||||
base.log.Info("RouteGetSilence: ", "Recipient", recipient)
|
|
||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RouteGetSilences(c *models.ReqContext) response.Response {
|
|
||||||
recipient := c.Params(":Recipient")
|
|
||||||
base.log.Info("RouteGetSilences: ", "Recipient", recipient)
|
|
||||||
return response.Error(http.StatusNotImplemented, "", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (base AlertmanagerApiBase) RoutePostAMAlerts(c *models.ReqContext, body apimodels.PostableAlerts) response.Response {
|
func (base AlertmanagerApiBase) RoutePostAMAlerts(c *models.ReqContext, body apimodels.PostableAlerts) response.Response {
|
||||||
recipient := c.Params(":Recipient")
|
recipient := c.Params(":Recipient")
|
||||||
base.log.Info("RoutePostAMAlerts: ", "Recipient", recipient)
|
base.log.Info("RoutePostAMAlerts: ", "Recipient", recipient)
|
||||||
|
@ -523,7 +523,7 @@ type AlertmanagerApiMock struct {
|
|||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mock AlertmanagerApiMock) RouteCreateSilence(c *models.ReqContext, body apimodels.SilenceBody) response.Response {
|
func (mock AlertmanagerApiMock) RouteCreateSilence(c *models.ReqContext, body apimodels.CreateSilenceParams) response.Response {
|
||||||
recipient := c.Params(":Recipient")
|
recipient := c.Params(":Recipient")
|
||||||
mock.log.Info("RouteCreateSilence: ", "Recipient", recipient)
|
mock.log.Info("RouteCreateSilence: ", "Recipient", recipient)
|
||||||
mock.log.Info("RouteCreateSilence: ", "body", body)
|
mock.log.Info("RouteCreateSilence: ", "body", body)
|
||||||
|
@ -38,7 +38,7 @@ func (am *ForkedAMSvc) getService(ctx *models.ReqContext) (AlertmanagerApiServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *ForkedAMSvc) RouteCreateSilence(ctx *models.ReqContext, body apimodels.SilenceBody) response.Response {
|
func (am *ForkedAMSvc) RouteCreateSilence(ctx *models.ReqContext, body apimodels.CreateSilenceParams) response.Response {
|
||||||
s, err := am.getService(ctx)
|
s, err := am.getService(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(400, err.Error(), nil)
|
return response.Error(400, err.Error(), nil)
|
||||||
|
@ -32,7 +32,7 @@ func NewLotexAM(proxy *AlertingProxy, log log.Logger) *LotexAM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *LotexAM) RouteCreateSilence(ctx *models.ReqContext, silenceBody apimodels.SilenceBody) response.Response {
|
func (am *LotexAM) RouteCreateSilence(ctx *models.ReqContext, silenceBody apimodels.CreateSilenceParams) response.Response {
|
||||||
blob, err := json.Marshal(silenceBody)
|
blob, err := json.Marshal(silenceBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(500, "Failed marshal silence", err)
|
return response.Error(500, "Failed marshal silence", err)
|
||||||
|
@ -3,7 +3,6 @@ package notifier
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -14,9 +13,7 @@ import (
|
|||||||
"github.com/prometheus/alertmanager/nflog"
|
"github.com/prometheus/alertmanager/nflog"
|
||||||
"github.com/prometheus/alertmanager/nflog/nflogpb"
|
"github.com/prometheus/alertmanager/nflog/nflogpb"
|
||||||
"github.com/prometheus/alertmanager/notify"
|
"github.com/prometheus/alertmanager/notify"
|
||||||
"github.com/prometheus/alertmanager/pkg/labels"
|
|
||||||
"github.com/prometheus/alertmanager/silence"
|
"github.com/prometheus/alertmanager/silence"
|
||||||
"github.com/prometheus/alertmanager/silence/silencepb"
|
|
||||||
"github.com/prometheus/alertmanager/template"
|
"github.com/prometheus/alertmanager/template"
|
||||||
"github.com/prometheus/alertmanager/types"
|
"github.com/prometheus/alertmanager/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
@ -33,6 +30,8 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
workingDir = "alerting"
|
workingDir = "alerting"
|
||||||
|
// How long should we keep silences and notification entries on-disk after they've served their purpose.
|
||||||
|
retentionNotificationsAndSilences = 5 * 24 * time.Hour
|
||||||
)
|
)
|
||||||
|
|
||||||
type Alertmanager struct {
|
type Alertmanager struct {
|
||||||
@ -74,15 +73,15 @@ func (am *Alertmanager) Init() (err error) {
|
|||||||
am.Store = store.DBstore{SQLStore: am.SQLStore}
|
am.Store = store.DBstore{SQLStore: am.SQLStore}
|
||||||
|
|
||||||
am.notificationLog, err = nflog.New(
|
am.notificationLog, err = nflog.New(
|
||||||
nflog.WithRetention(time.Hour*24), //TODO: This is a setting.
|
nflog.WithRetention(retentionNotificationsAndSilences),
|
||||||
nflog.WithSnapshot(filepath.Join("dir", "notifications")), //TODO: This should be a setting
|
nflog.WithSnapshot(filepath.Join(am.WorkingDirPath(), "notifications")),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to initialize the notification log component of alerting")
|
return errors.Wrap(err, "unable to initialize the notification log component of alerting")
|
||||||
}
|
}
|
||||||
am.silences, err = silence.New(silence.Options{
|
am.silences, err = silence.New(silence.Options{
|
||||||
SnapshotFile: filepath.Join("dir", "silences"), //TODO: This is a setting
|
SnapshotFile: filepath.Join(am.WorkingDirPath(), "silences"),
|
||||||
Retention: time.Hour * 24, //TODO: This is also a setting
|
Retention: retentionNotificationsAndSilences,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to initialize the silencing component of alerting")
|
return errors.Wrap(err, "unable to initialize the silencing component of alerting")
|
||||||
@ -251,66 +250,6 @@ func (am *Alertmanager) PutAlerts(alerts ...*PostableAlert) error {
|
|||||||
return am.alerts.PutPostableAlert(alerts...)
|
return am.alerts.PutPostableAlert(alerts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *Alertmanager) ListSilences(matchers []*labels.Matcher) ([]types.Silence, error) {
|
|
||||||
pbsilences, _, err := am.silences.Query()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "unable to query for the list of silences")
|
|
||||||
}
|
|
||||||
r := []types.Silence{}
|
|
||||||
for _, pbs := range pbsilences {
|
|
||||||
s, err := silenceFromProto(pbs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "unable to marshal silence")
|
|
||||||
}
|
|
||||||
|
|
||||||
sms := make(map[string]string)
|
|
||||||
for _, m := range s.Matchers {
|
|
||||||
sms[m.Name] = m.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
if !matchFilterLabels(matchers, sms) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r = append(r, *s)
|
|
||||||
}
|
|
||||||
|
|
||||||
var active, pending, expired []types.Silence
|
|
||||||
for _, s := range r {
|
|
||||||
switch s.Status.State {
|
|
||||||
case types.SilenceStateActive:
|
|
||||||
active = append(active, s)
|
|
||||||
case types.SilenceStatePending:
|
|
||||||
pending = append(pending, s)
|
|
||||||
case types.SilenceStateExpired:
|
|
||||||
expired = append(expired, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(active, func(i int, j int) bool {
|
|
||||||
return active[i].EndsAt.Before(active[j].EndsAt)
|
|
||||||
})
|
|
||||||
sort.Slice(pending, func(i int, j int) bool {
|
|
||||||
return pending[i].EndsAt.Before(pending[j].EndsAt)
|
|
||||||
})
|
|
||||||
sort.Slice(expired, func(i int, j int) bool {
|
|
||||||
return expired[i].EndsAt.After(expired[j].EndsAt)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Initialize silences explicitly to an empty list (instead of nil)
|
|
||||||
// So that it does not get converted to "null" in JSON.
|
|
||||||
silences := []types.Silence{}
|
|
||||||
silences = append(silences, active...)
|
|
||||||
silences = append(silences, pending...)
|
|
||||||
silences = append(silences, expired...)
|
|
||||||
|
|
||||||
return silences, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (am *Alertmanager) GetSilence(silence *types.Silence) {}
|
|
||||||
func (am *Alertmanager) CreateSilence(silence *types.Silence) {}
|
|
||||||
func (am *Alertmanager) DeleteSilence(silence *types.Silence) {}
|
|
||||||
|
|
||||||
// createReceiverStage creates a pipeline of stages for a receiver.
|
// createReceiverStage creates a pipeline of stages for a receiver.
|
||||||
func (am *Alertmanager) createReceiverStage(name string, integrations []notify.Integration, wait func() time.Duration, notificationLog notify.NotificationLog) notify.Stage {
|
func (am *Alertmanager) createReceiverStage(name string, integrations []notify.Integration, wait func() time.Duration, notificationLog notify.NotificationLog) notify.Stage {
|
||||||
var fs notify.FanoutStage
|
var fs notify.FanoutStage
|
||||||
@ -343,63 +282,3 @@ func timeoutFunc(d time.Duration) time.Duration {
|
|||||||
}
|
}
|
||||||
return d + waitFunc()
|
return d + waitFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
// copied from the Alertmanager
|
|
||||||
func silenceFromProto(s *silencepb.Silence) (*types.Silence, error) {
|
|
||||||
sil := &types.Silence{
|
|
||||||
ID: s.Id,
|
|
||||||
StartsAt: s.StartsAt,
|
|
||||||
EndsAt: s.EndsAt,
|
|
||||||
UpdatedAt: s.UpdatedAt,
|
|
||||||
Status: types.SilenceStatus{
|
|
||||||
State: types.CalcSilenceState(s.StartsAt, s.EndsAt),
|
|
||||||
},
|
|
||||||
Comment: s.Comment,
|
|
||||||
CreatedBy: s.CreatedBy,
|
|
||||||
}
|
|
||||||
for _, m := range s.Matchers {
|
|
||||||
var t labels.MatchType
|
|
||||||
switch m.Type {
|
|
||||||
case silencepb.Matcher_EQUAL:
|
|
||||||
t = labels.MatchEqual
|
|
||||||
case silencepb.Matcher_REGEXP:
|
|
||||||
t = labels.MatchRegexp
|
|
||||||
case silencepb.Matcher_NOT_EQUAL:
|
|
||||||
t = labels.MatchNotEqual
|
|
||||||
case silencepb.Matcher_NOT_REGEXP:
|
|
||||||
t = labels.MatchNotRegexp
|
|
||||||
}
|
|
||||||
matcher, err := labels.NewMatcher(t, m.Name, m.Pattern)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sil.Matchers = append(sil.Matchers, matcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchFilterLabels(matchers []*labels.Matcher, sms map[string]string) bool {
|
|
||||||
for _, m := range matchers {
|
|
||||||
v, prs := sms[m.Name]
|
|
||||||
switch m.Type {
|
|
||||||
case labels.MatchNotRegexp, labels.MatchNotEqual:
|
|
||||||
if m.Value == "" && prs {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !m.Matches(v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if m.Value == "" && !prs {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !m.Matches(v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
@ -1 +1,122 @@
|
|||||||
package notifier
|
package notifier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
apimodels "github.com/grafana/alerting-api/pkg/api"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
v2 "github.com/prometheus/alertmanager/api/v2"
|
||||||
|
"github.com/prometheus/alertmanager/pkg/labels"
|
||||||
|
"github.com/prometheus/alertmanager/silence"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrGetSilencesInternal = errors.New("unable to retrieve silence(s) due to an internal error")
|
||||||
|
ErrDeleteSilenceInternal = errors.New("unable to delete silence due to an internal error")
|
||||||
|
ErrCreateSilenceBadPayload = errors.New("unable to create silence")
|
||||||
|
ErrListSilencesBadPayload = errors.New("unable to list silences")
|
||||||
|
ErrSilenceNotFound = silence.ErrNotFound
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListSilences retrieves a list of stored silences. It supports a set of labels as filters.
|
||||||
|
func (am *Alertmanager) ListSilences(filters []string) (apimodels.GettableSilences, error) {
|
||||||
|
matchers := []*labels.Matcher{}
|
||||||
|
for _, matcherString := range filters {
|
||||||
|
matcher, err := labels.ParseMatcher(matcherString)
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error("failed to parse matcher", "err", err, "matcher", matcherString)
|
||||||
|
return nil, errors.Wrap(ErrListSilencesBadPayload, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
matchers = append(matchers, matcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
psils, _, err := am.silences.Query()
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error(ErrGetSilencesInternal.Error(), "err", err)
|
||||||
|
return nil, errors.Wrap(ErrGetSilencesInternal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
sils := apimodels.GettableSilences{}
|
||||||
|
for _, ps := range psils {
|
||||||
|
if !v2.CheckSilenceMatchesFilterLabels(ps, matchers) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
silence, err := v2.GettableSilenceFromProto(ps)
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error("unmarshaling from protobuf failed", "err", err)
|
||||||
|
return apimodels.GettableSilences{}, errors.Wrap(ErrGetSilencesInternal, fmt.Sprintf("failed to convert internal silence to API silence: %v", err.Error()))
|
||||||
|
}
|
||||||
|
sils = append(sils, &silence)
|
||||||
|
}
|
||||||
|
|
||||||
|
v2.SortSilences(sils)
|
||||||
|
|
||||||
|
return sils, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSilence retrieves a silence by the provided silenceID. It returns ErrSilenceNotFound if the silence is not present.
|
||||||
|
func (am *Alertmanager) GetSilence(silenceID string) (apimodels.GettableSilence, error) {
|
||||||
|
sils, _, err := am.silences.Query(silence.QIDs(silenceID))
|
||||||
|
if err != nil {
|
||||||
|
return apimodels.GettableSilence{}, errors.Wrap(ErrGetSilencesInternal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sils) == 0 {
|
||||||
|
am.logger.Error("failed to find silence", "err", err, "id", sils)
|
||||||
|
return apimodels.GettableSilence{}, ErrSilenceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
sil, err := v2.GettableSilenceFromProto(sils[0])
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error("unmarshaling from protobuf failed", "err", err)
|
||||||
|
return apimodels.GettableSilence{}, errors.Wrap(ErrGetSilencesInternal, fmt.Sprintf("failed to convert internal silence to API silence: %v", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return sil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSilence persists the provided silence and returns the silence ID if successful.
|
||||||
|
func (am *Alertmanager) CreateSilence(ps *apimodels.PostableSilence) (string, error) {
|
||||||
|
sil, err := v2.PostableSilenceToProto(ps)
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error("marshaling to protobuf failed", "err", err)
|
||||||
|
return "", errors.Wrap(ErrCreateSilenceBadPayload, fmt.Sprintf("failed to convert API silence to internal silence: %v", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if sil.StartsAt.After(sil.EndsAt) || sil.StartsAt.Equal(sil.EndsAt) {
|
||||||
|
msg := "start time must be before end time"
|
||||||
|
am.logger.Error(msg, "err", "starts_at", sil.StartsAt, "ends_at", sil.EndsAt)
|
||||||
|
return "", errors.Wrap(ErrCreateSilenceBadPayload, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sil.EndsAt.Before(time.Now()) {
|
||||||
|
msg := "end time can't be in the past"
|
||||||
|
am.logger.Error(msg, "ends_at", sil.EndsAt)
|
||||||
|
return "", errors.Wrap(ErrCreateSilenceBadPayload, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
silenceID, err := am.silences.Set(sil)
|
||||||
|
if err != nil {
|
||||||
|
am.logger.Error("msg", "unable to save silence", "err", err)
|
||||||
|
if errors.Is(err, silence.ErrNotFound) {
|
||||||
|
return "", ErrSilenceNotFound
|
||||||
|
}
|
||||||
|
return "", errors.Wrap(ErrCreateSilenceBadPayload, fmt.Sprintf("unable to save silence: %v", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return silenceID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSilence looks for and expires the silence by the provided silenceID. It returns ErrSilenceNotFound if the silence is not present.
|
||||||
|
func (am *Alertmanager) DeleteSilence(silenceID string) error {
|
||||||
|
if err := am.silences.Expire(silenceID); err != nil {
|
||||||
|
if errors.Is(err, silence.ErrNotFound) {
|
||||||
|
return ErrSilenceNotFound
|
||||||
|
}
|
||||||
|
return errors.Wrap(ErrDeleteSilenceInternal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user