Alerting: Allow more characters in label names so notifications are sent (#38629)
Remove validation for labels to be accepted in the Alertmanager, This helps with datasources that produce non-compatible labels. Adds an "object_matchers" to alert manager routers so we can support labels names with extended characters beyond prometheus/openmetrics. It only does this for the internal Grafana managed Alert Manager. This requires a change to alert manager, so for now we use grafana/alertmanager which is a slight fork, with the intention of going back to upstream. The frontend handles the migration of "matchers" -> "object_matchers" when the route is edited and saved. Once this is done, downgrades will not work old versions will not recognize the "object_matchers". Co-authored-by: Kyle Brandt <kyle@grafana.com> Co-authored-by: Nathan Rodman <nathanrodman@gmail.com>
This commit is contained in:
co-authored by
Kyle Brandt
Nathan Rodman
parent
706a665240
commit
6572017ec7
@@ -11,6 +11,10 @@ replace github.com/denisenkom/go-mssqldb => github.com/grafana/go-mssqldb v0.0.0
|
||||
// It's also present on grafana/loki's go.mod so we'll need till it gets updated.
|
||||
replace k8s.io/client-go => k8s.io/client-go v0.22.1
|
||||
|
||||
// For now we are using a Grafana fork of alertmanager until the ability to bypass label name/key validation
|
||||
// is merged into upstream (2021-10-01).
|
||||
replace github.com/prometheus/alertmanager => github.com/grafana/alertmanager v0.21.1-0.20210929114340-613e5cc2a4ee
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.14.0
|
||||
cuelang.org/go v0.4.0
|
||||
|
||||
@@ -362,13 +362,10 @@ github.com/cactus/go-statsd-client/statsd v0.0.0-20191106001114-12b4e2b38748/go.
|
||||
github.com/caio/go-tdigest v2.3.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/casbin/casbin/v2 v2.31.6/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v1.0.0/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -378,7 +375,6 @@ github.com/centrifugal/centrifuge v0.18.4/go.mod h1:t/PkawecPuBBOhyuNbrTQSCQutmE
|
||||
github.com/centrifugal/protocol v0.7.3 h1:XEBDwfWuUWj0L/ZVKUsf0K8TKjsOTbtKIMq84+r5aTU=
|
||||
github.com/centrifugal/protocol v0.7.3/go.mod h1:qoeBHrRCi5mJ5XZfrKHnedz9UWpYbDLXr8iZUO3pTtc=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||
@@ -792,7 +788,6 @@ github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNI
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||
github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||
@@ -804,7 +799,6 @@ github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxl
|
||||
github.com/go-openapi/analysis v0.20.1 h1:zdVbw8yoD4SWZeq+cWdGgquaB0W4VrsJvDJHJND/Ktc=
|
||||
github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og=
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
@@ -817,7 +811,6 @@ github.com/go-openapi/errors v0.20.0 h1:Sxpo9PjEHDzhs3FbnGNonvDgWcMW2U7wGTcDDSFS
|
||||
github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
@@ -825,7 +818,6 @@ github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUe
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
@@ -833,7 +825,6 @@ github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE
|
||||
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
||||
@@ -846,20 +837,17 @@ github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20
|
||||
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
|
||||
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.18.0/go.mod h1:uI6pHuxWYTy94zZxgcwJkUWa9wbIlhteGfloI10GD4U=
|
||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||
github.com/go-openapi/runtime v0.19.3/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
|
||||
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
|
||||
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
|
||||
github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||
github.com/go-openapi/runtime v0.19.28/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||
github.com/go-openapi/runtime v0.19.29 h1:5IIvCaIDbxetN674vX9eOxvoZ9mYGQ16fV1Q0VSG+NA=
|
||||
github.com/go-openapi/runtime v0.19.29/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
@@ -873,7 +861,6 @@ github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a
|
||||
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
|
||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||
@@ -887,7 +874,6 @@ github.com/go-openapi/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlON
|
||||
github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.4/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
@@ -900,7 +886,6 @@ github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
||||
@@ -1128,7 +1113,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2/go.mod h1:DavVbd41y+b7ukKDmlnPR4nGYmkWXR6vHUkjQNiHPBs=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -1189,6 +1173,8 @@ 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/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
||||
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
||||
github.com/grafana/alertmanager v0.21.1-0.20210929114340-613e5cc2a4ee h1:iGtJW4VSG/YF6y2rQICOeLjv6qJZsul8CbqS/6KPKLA=
|
||||
github.com/grafana/alertmanager v0.21.1-0.20210929114340-613e5cc2a4ee/go.mod h1:U7pGu+z7A9ZKhK8lq1MvIOp5GdVlZjwOYk+S0h3LSbA=
|
||||
github.com/grafana/cuetsy v0.0.0-20210928021233-5ddfb47f9a7d h1:vYCNM25g5aEactkMiILJvm2jW2BVGYB1QzLx7lAhMLw=
|
||||
github.com/grafana/cuetsy v0.0.0-20210928021233-5ddfb47f9a7d/go.mod h1:H9Ei+Q808FCWyeEzpaW5GMfBvXCuFOfQa4x/vzKY+Fg=
|
||||
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA=
|
||||
@@ -1250,10 +1236,7 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
|
||||
github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0=
|
||||
github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088/go.mod h1:vZu6Opqf49xX5lsFAu7iFNewkcVF1sn/wyapZh5ytlg=
|
||||
@@ -1324,7 +1307,6 @@ github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
||||
github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.2.3/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.2.4 h1:OOhYzSvFnkFQXm1ysE8RjXTHsqSRDyP4emusC9K7DYg=
|
||||
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q=
|
||||
@@ -1433,7 +1415,6 @@ github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/U
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
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/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
@@ -1544,7 +1525,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||
github.com/kubernetes/apimachinery v0.0.0-20190119020841-d41becfba9ee/go.mod h1:Pe/YBTPc3vqoMkbuIWPH8CF9ehINdvNyS0dP3J6HC0s=
|
||||
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
@@ -1782,7 +1762,6 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/oklog/ulid v0.0.0-20170117200651-66bb6560562f/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
@@ -1913,18 +1892,6 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/prometheus/alertmanager v0.18.0/go.mod h1:WcxHBl40VSPuOaqWae6l6HpnEOVRIycEJ7i9iYkadEE=
|
||||
github.com/prometheus/alertmanager v0.19.0/go.mod h1:Eyp94Yi/T+kdeb2qvq66E3RGuph5T/jm/RBVh4yz1xo=
|
||||
github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg=
|
||||
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.20201106142418-c39b78780054/go.mod h1:imXRHOP6QTsE0fFsIsAV/cXimS32m7gVZOiUj11m6Ig=
|
||||
github.com/prometheus/alertmanager v0.21.1-0.20210310093010-0f9cab6991e6/go.mod h1:MTqVn+vIupE0dzdgo+sMcNCp37SCAi8vPrvKTTnTz9g=
|
||||
github.com/prometheus/alertmanager v0.21.1-0.20210422101724-8176f78a70e1/go.mod h1:gsEqwD5BHHW9RNKvCuPOrrTMiP5I+faJUyLXvnivHik=
|
||||
github.com/prometheus/alertmanager v0.22.2/go.mod h1:rYinOWxFuCnNssc3iOjn2oMTlhLaPcUuqV5yk5JKUAE=
|
||||
github.com/prometheus/alertmanager v0.23.0/go.mod h1:0MLTrjQI8EuVmvykEhcfr/7X0xmaDAZrqMgxIq3OXHk=
|
||||
github.com/prometheus/alertmanager v0.23.1-0.20210914172521-e35efbddb66a h1:qroc/F4ygaQ0uc2S+Pyk/exMwnSpokGyN1QjfZ1DiWU=
|
||||
github.com/prometheus/alertmanager v0.23.1-0.20210914172521-e35efbddb66a/go.mod h1:U7pGu+z7A9ZKhK8lq1MvIOp5GdVlZjwOYk+S0h3LSbA=
|
||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/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=
|
||||
@@ -1968,7 +1935,6 @@ github.com/prometheus/common v0.8.0/go.mod h1:PC/OgXc+UN7B4ALwvn1yzVZmVwvhXp5Jsb
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.11.1/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.12.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
@@ -1982,7 +1948,6 @@ github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||
github.com/prometheus/exporter-toolkit v0.5.0/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg=
|
||||
github.com/prometheus/exporter-toolkit v0.5.1/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg=
|
||||
github.com/prometheus/exporter-toolkit v0.6.1 h1:Aqk75wQD92N9CqmTlZwjKwq6272nOGrWIbc8Z7+xQO0=
|
||||
github.com/prometheus/exporter-toolkit v0.6.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||
@@ -2006,7 +1971,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||
github.com/prometheus/prometheus v0.0.0-20190818123050-43acd0e2e93f/go.mod h1:rMTlmxGCvukf2KMu3fClMDKLLoJ5hl61MhcJ7xKakf0=
|
||||
github.com/prometheus/prometheus v0.0.0-20200609090129-a6600f564e3c/go.mod h1:S5n0C6tSgdnwWshBUceRx5G1OsjLv/EeZ9t3wIfEtsY=
|
||||
github.com/prometheus/prometheus v1.8.2-0.20200107122003-4708915ac6ef/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI=
|
||||
@@ -2057,8 +2021,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so=
|
||||
github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
@@ -2083,7 +2045,6 @@ github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e/go.mod h1:gi+0
|
||||
github.com/samuel/go-zookeeper v0.0.0-20201211165307-7117e9ea2414/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
|
||||
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
|
||||
github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44 h1:3egqo0Vut6daANFm7tOXdNAa8v5/uLU+sgCJrc88Meo=
|
||||
@@ -2112,12 +2073,10 @@ github.com/shirou/gopsutil/v3 v3.20.10/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkU
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180825020608-02ddb050ef6b/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200627165143-92b8a710ab6c/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
|
||||
@@ -2333,7 +2292,6 @@ github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xlab/treeprint v1.0.0/go.mod h1:IoImgRak9i3zJyuxOKUP1v4UZd1tMoKkq/Cimt1uhCg=
|
||||
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
github.com/xorcare/pointer v1.1.0 h1:sFwXOhRF8QZ0tyVZrtxWGIoVZNEmRzBCaFWdONPQIUM=
|
||||
github.com/xorcare/pointer v1.1.0/go.mod h1:6KLhkOh6YbuvZkT4YbxIbR/wzLBjyMxOiNzZhJTor2Y=
|
||||
@@ -2634,7 +2592,6 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||
golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
@@ -2810,7 +2767,6 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -2832,7 +2788,6 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
@@ -2862,7 +2817,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20181112210238-4b1f3b6b1646/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -2930,7 +2884,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200513154647-78b527d18275/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200513201620-d5fe73897c97/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200603131246-cc40288be839/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
|
||||
@@ -5,12 +5,15 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/pkg/errors"
|
||||
amv2 "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/pkg/labels"
|
||||
"github.com/prometheus/common/model"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@@ -214,7 +217,7 @@ func (s *GettableStatus) UnmarshalJSON(b []byte) error {
|
||||
s.Cluster = amStatus.Cluster
|
||||
s.Config = &PostableApiAlertingConfig{Config: Config{
|
||||
Global: c.Global,
|
||||
Route: c.Route,
|
||||
Route: AsGrafanaRoute(c.Route),
|
||||
InhibitRules: c.InhibitRules,
|
||||
Templates: c.Templates,
|
||||
}}
|
||||
@@ -556,7 +559,7 @@ func (c *GettableApiAlertingConfig) validate() error {
|
||||
return fmt.Errorf("cannot mix Alertmanager & Grafana receiver types")
|
||||
}
|
||||
|
||||
for _, receiver := range AllReceivers(c.Route) {
|
||||
for _, receiver := range AllReceivers(c.Route.AsAMRoute()) {
|
||||
_, ok := receivers[receiver]
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected receiver (%s) is undefined", receiver)
|
||||
@@ -569,11 +572,124 @@ func (c *GettableApiAlertingConfig) validate() error {
|
||||
// Config is the top-level configuration for Alertmanager's config files.
|
||||
type Config struct {
|
||||
Global *config.GlobalConfig `yaml:"global,omitempty" json:"global,omitempty"`
|
||||
Route *config.Route `yaml:"route,omitempty" json:"route,omitempty"`
|
||||
Route *Route `yaml:"route,omitempty" json:"route,omitempty"`
|
||||
InhibitRules []*config.InhibitRule `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"`
|
||||
Templates []string `yaml:"templates" json:"templates"`
|
||||
}
|
||||
|
||||
// A Route is a node that contains definitions of how to handle alerts. This is modified
|
||||
// from the upstream alertmanager in that it adds the ObjectMatchers property.
|
||||
type Route struct {
|
||||
Receiver string `yaml:"receiver,omitempty" json:"receiver,omitempty"`
|
||||
|
||||
GroupByStr []string `yaml:"group_by,omitempty" json:"group_by,omitempty"`
|
||||
GroupBy []model.LabelName `yaml:"-" json:"-"`
|
||||
GroupByAll bool `yaml:"-" json:"-"`
|
||||
// Deprecated. Remove before v1.0 release.
|
||||
Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"`
|
||||
// Deprecated. Remove before v1.0 release.
|
||||
MatchRE config.MatchRegexps `yaml:"match_re,omitempty" json:"match_re,omitempty"`
|
||||
Matchers config.Matchers `yaml:"matchers,omitempty" json:"matchers,omitempty"`
|
||||
ObjectMatchers ObjectMatchers `yaml:"object_matchers,omitempty" json:"object_matchers,omitempty"`
|
||||
MuteTimeIntervals []string `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"`
|
||||
Continue bool `yaml:"continue" json:"continue,omitempty"`
|
||||
Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"`
|
||||
|
||||
GroupWait *model.Duration `yaml:"group_wait,omitempty" json:"group_wait,omitempty"`
|
||||
GroupInterval *model.Duration `yaml:"group_interval,omitempty" json:"group_interval,omitempty"`
|
||||
RepeatInterval *model.Duration `yaml:"repeat_interval,omitempty" json:"repeat_interval,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface for Route. This is a copy of alertmanager's upstream except it removes validation on the label key.
|
||||
func (r *Route) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
type plain Route
|
||||
if err := unmarshal((*plain)(r)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, l := range r.GroupByStr {
|
||||
if l == "..." {
|
||||
r.GroupByAll = true
|
||||
} else {
|
||||
r.GroupBy = append(r.GroupBy, model.LabelName(l))
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.GroupBy) > 0 && r.GroupByAll {
|
||||
return fmt.Errorf("cannot have wildcard group_by (`...`) and other other labels at the same time")
|
||||
}
|
||||
|
||||
groupBy := map[model.LabelName]struct{}{}
|
||||
|
||||
for _, ln := range r.GroupBy {
|
||||
if _, ok := groupBy[ln]; ok {
|
||||
return fmt.Errorf("duplicated label %q in group_by", ln)
|
||||
}
|
||||
groupBy[ln] = struct{}{}
|
||||
}
|
||||
|
||||
if r.GroupInterval != nil && time.Duration(*r.GroupInterval) == time.Duration(0) {
|
||||
return fmt.Errorf("group_interval cannot be zero")
|
||||
}
|
||||
if r.RepeatInterval != nil && time.Duration(*r.RepeatInterval) == time.Duration(0) {
|
||||
return fmt.Errorf("repeat_interval cannot be zero")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return an alertmanager route from a Grafana route. The ObjectMatchers are converted to Matchers.
|
||||
func (r *Route) AsAMRoute() *config.Route {
|
||||
amRoute := &config.Route{
|
||||
Receiver: r.Receiver,
|
||||
GroupByStr: r.GroupByStr,
|
||||
GroupBy: r.GroupBy,
|
||||
GroupByAll: r.GroupByAll,
|
||||
Match: r.Match,
|
||||
MatchRE: r.MatchRE,
|
||||
Matchers: append(r.Matchers, r.ObjectMatchers...),
|
||||
MuteTimeIntervals: r.MuteTimeIntervals,
|
||||
Continue: r.Continue,
|
||||
|
||||
GroupWait: r.GroupWait,
|
||||
GroupInterval: r.GroupInterval,
|
||||
RepeatInterval: r.RepeatInterval,
|
||||
|
||||
Routes: make([]*config.Route, 0, len(r.Routes)),
|
||||
}
|
||||
for _, rt := range r.Routes {
|
||||
amRoute.Routes = append(amRoute.Routes, rt.AsAMRoute())
|
||||
}
|
||||
|
||||
return amRoute
|
||||
}
|
||||
|
||||
// Return a Grafana route from an alertmanager route. The Matchers are converted to ObjectMatchers.
|
||||
func AsGrafanaRoute(r *config.Route) *Route {
|
||||
gRoute := &Route{
|
||||
Receiver: r.Receiver,
|
||||
GroupByStr: r.GroupByStr,
|
||||
GroupBy: r.GroupBy,
|
||||
GroupByAll: r.GroupByAll,
|
||||
Match: r.Match,
|
||||
MatchRE: r.MatchRE,
|
||||
ObjectMatchers: ObjectMatchers(r.Matchers),
|
||||
MuteTimeIntervals: r.MuteTimeIntervals,
|
||||
Continue: r.Continue,
|
||||
|
||||
GroupWait: r.GroupWait,
|
||||
GroupInterval: r.GroupInterval,
|
||||
RepeatInterval: r.RepeatInterval,
|
||||
|
||||
Routes: make([]*Route, 0, len(r.Routes)),
|
||||
}
|
||||
for _, rt := range r.Routes {
|
||||
gRoute.Routes = append(gRoute.Routes, AsGrafanaRoute(rt))
|
||||
}
|
||||
|
||||
return gRoute
|
||||
}
|
||||
|
||||
// Config is the entrypoint for the embedded Alertmanager config with the exception of receivers.
|
||||
// Prometheus historically uses yaml files as the method of configuration and thus some
|
||||
// post-validation is included in the UnmarshalYAML method. Here we simply run this with
|
||||
@@ -686,7 +802,7 @@ func (c *PostableApiAlertingConfig) validate() error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, receiver := range AllReceivers(c.Route) {
|
||||
for _, receiver := range AllReceivers(c.Route.AsAMRoute()) {
|
||||
_, ok := receivers[receiver]
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected receiver (%s) is undefined", receiver)
|
||||
@@ -972,3 +1088,90 @@ func processReceiverConfigs(c []*PostableApiReceiver) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ObjectMatchers is Matchers with a different Unmarshal and Marshal methods that accept matchers as objects
|
||||
// that have already been parsed.
|
||||
type ObjectMatchers labels.Matchers
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface for Matchers.
|
||||
func (m *ObjectMatchers) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var rawMatchers [][3]string
|
||||
if err := unmarshal(&rawMatchers); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rawMatcher := range rawMatchers {
|
||||
var matchType labels.MatchType
|
||||
switch rawMatcher[1] {
|
||||
case "=":
|
||||
matchType = labels.MatchEqual
|
||||
case "!=":
|
||||
matchType = labels.MatchNotEqual
|
||||
case "=~":
|
||||
matchType = labels.MatchRegexp
|
||||
case "!~":
|
||||
matchType = labels.MatchNotRegexp
|
||||
default:
|
||||
return fmt.Errorf("unsupported match type %q in matcher", rawMatcher[1])
|
||||
}
|
||||
|
||||
matcher, err := labels.NewMatcher(matchType, rawMatcher[0], rawMatcher[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = append(*m, matcher)
|
||||
}
|
||||
sort.Sort(labels.Matchers(*m))
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for Matchers.
|
||||
func (m *ObjectMatchers) UnmarshalJSON(data []byte) error {
|
||||
var rawMatchers [][3]string
|
||||
if err := json.Unmarshal(data, &rawMatchers); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rawMatcher := range rawMatchers {
|
||||
var matchType labels.MatchType
|
||||
switch rawMatcher[1] {
|
||||
case "=":
|
||||
matchType = labels.MatchEqual
|
||||
case "!=":
|
||||
matchType = labels.MatchNotEqual
|
||||
case "=~":
|
||||
matchType = labels.MatchRegexp
|
||||
case "!~":
|
||||
matchType = labels.MatchNotRegexp
|
||||
default:
|
||||
return fmt.Errorf("unsupported match type %q in matcher", rawMatcher[1])
|
||||
}
|
||||
|
||||
matcher, err := labels.NewMatcher(matchType, rawMatcher[0], rawMatcher[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = append(*m, matcher)
|
||||
}
|
||||
sort.Sort(labels.Matchers(*m))
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML implements the yaml.Marshaler interface for Matchers.
|
||||
func (m ObjectMatchers) MarshalYAML() (interface{}, error) {
|
||||
result := make([][3]string, len(m))
|
||||
for i, matcher := range m {
|
||||
result[i] = [3]string{matcher.Name, matcher.Type.String(), matcher.Value}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface for Matchers.
|
||||
func (m ObjectMatchers) MarshalJSON() ([]byte, error) {
|
||||
if len(m) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
result := make([][3]string, len(m))
|
||||
for i, matcher := range m {
|
||||
result[i] = [3]string{matcher.Name, matcher.Type.String(), matcher.Value}
|
||||
}
|
||||
return json.Marshal(result)
|
||||
}
|
||||
|
||||
@@ -115,12 +115,12 @@ func Test_APIReceiverType(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_AllReceivers(t *testing.T) {
|
||||
input := &config.Route{
|
||||
input := &Route{
|
||||
Receiver: "foo",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "bar",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "bazz",
|
||||
},
|
||||
@@ -132,11 +132,12 @@ func Test_AllReceivers(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
require.Equal(t, []string{"foo", "bar", "bazz", "buzz"}, AllReceivers(input))
|
||||
require.Equal(t, []string{"foo", "bar", "bazz", "buzz"}, AllReceivers(input.AsAMRoute()))
|
||||
|
||||
// test empty
|
||||
var empty []string
|
||||
require.Equal(t, empty, AllReceivers(&config.Route{}))
|
||||
emptyRoute := &Route{}
|
||||
require.Equal(t, empty, AllReceivers(emptyRoute.AsAMRoute()))
|
||||
}
|
||||
|
||||
func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
@@ -149,9 +150,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "success am",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
@@ -172,9 +173,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "success graf",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
@@ -197,9 +198,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "failure undefined am receiver",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "unmentioned",
|
||||
},
|
||||
@@ -221,9 +222,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "failure undefined graf receiver",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "unmentioned",
|
||||
},
|
||||
@@ -263,8 +264,8 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "failure graf no default receiver",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Routes: []*config.Route{
|
||||
Route: &Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
@@ -288,9 +289,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "failure graf root route with matchers",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
@@ -315,9 +316,9 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) {
|
||||
desc: "failure graf nested route duplicate group by labels",
|
||||
input: PostableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
GroupByStr: []string{"foo", "bar", "foo"},
|
||||
@@ -481,9 +482,9 @@ alertmanager_config: |
|
||||
AlertmanagerConfig: GettableApiAlertingConfig{
|
||||
Config: Config{
|
||||
Templates: []string{},
|
||||
Route: &config.Route{
|
||||
Route: &Route{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
Routes: []*Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
|
||||
@@ -88,7 +88,7 @@ type AlertingRule struct {
|
||||
Query string `json:"query,omitempty"`
|
||||
Duration float64 `json:"duration,omitempty"`
|
||||
// required: true
|
||||
Annotations labels `json:"annotations,omitempty"`
|
||||
Annotations overrideLabels `json:"annotations,omitempty"`
|
||||
// required: true
|
||||
Alerts []*Alert `json:"alerts,omitempty"`
|
||||
Rule
|
||||
@@ -100,8 +100,8 @@ type Rule struct {
|
||||
// required: true
|
||||
Name string `json:"name"`
|
||||
// required: true
|
||||
Query string `json:"query"`
|
||||
Labels labels `json:"labels"`
|
||||
Query string `json:"query"`
|
||||
Labels overrideLabels `json:"labels"`
|
||||
// required: true
|
||||
Health string `json:"health"`
|
||||
LastError string `json:"lastError"`
|
||||
@@ -115,9 +115,9 @@ type Rule struct {
|
||||
// swagger:model
|
||||
type Alert struct {
|
||||
// required: true
|
||||
Labels labels `json:"labels"`
|
||||
Labels overrideLabels `json:"labels"`
|
||||
// required: true
|
||||
Annotations labels `json:"annotations"`
|
||||
Annotations overrideLabels `json:"annotations"`
|
||||
// required: true
|
||||
State string `json:"state"`
|
||||
ActiveAt *time.Time `json:"activeAt"`
|
||||
@@ -127,4 +127,4 @@ type Alert struct {
|
||||
|
||||
// override the labels type with a map for generation.
|
||||
// The custom marshaling for labels.Labels ends up doing this anyways.
|
||||
type labels map[string]string
|
||||
type overrideLabels map[string]string
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
"x-go-name": "ActiveAt"
|
||||
},
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
@@ -179,7 +179,7 @@
|
||||
"x-go-name": "Alerts"
|
||||
},
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"duration": {
|
||||
"format": "double",
|
||||
@@ -196,7 +196,7 @@
|
||||
"x-go-name": "Health"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"lastError": {
|
||||
"type": "string",
|
||||
@@ -607,6 +607,13 @@
|
||||
"type": "array",
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/VictorOpsConfig"
|
||||
@@ -1164,6 +1171,10 @@
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/prometheus/common/config"
|
||||
},
|
||||
"ObjectMatchers": {
|
||||
"$ref": "#/definitions/Matchers",
|
||||
"description": "ObjectMatchers is Matchers with a different Unmarshal and Marshal methods that accept matchers as objects\nthat have already been parsed."
|
||||
},
|
||||
"OpsGenieConfig": {
|
||||
"properties": {
|
||||
"api_key": {
|
||||
@@ -1216,6 +1227,10 @@
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"x-go-name": "Tags"
|
||||
},
|
||||
"update_alerts": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "UpdateAlerts"
|
||||
}
|
||||
},
|
||||
"title": "OpsGenieConfig configures notifications via OpsGenie.",
|
||||
@@ -1454,6 +1469,13 @@
|
||||
"type": "array",
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/VictorOpsConfig"
|
||||
@@ -1747,6 +1769,13 @@
|
||||
"type": "array",
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/VictorOpsConfig"
|
||||
@@ -1803,6 +1832,7 @@
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"Route": {
|
||||
"description": "A Route is a node that contains definitions of how to handle alerts. This is modified\nfrom the upstream alertmanager in that it adds the ObjectMatchers property.",
|
||||
"properties": {
|
||||
"continue": {
|
||||
"type": "boolean",
|
||||
@@ -1842,6 +1872,9 @@
|
||||
"type": "array",
|
||||
"x-go-name": "MuteTimeIntervals"
|
||||
},
|
||||
"object_matchers": {
|
||||
"$ref": "#/definitions/ObjectMatchers"
|
||||
},
|
||||
"receiver": {
|
||||
"type": "string",
|
||||
"x-go-name": "Receiver"
|
||||
@@ -1857,9 +1890,8 @@
|
||||
"x-go-name": "Routes"
|
||||
}
|
||||
},
|
||||
"title": "A Route is a node that contains definitions of how to handle alerts.",
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/config"
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"Rule": {
|
||||
"description": "adapted from cortex",
|
||||
@@ -1874,7 +1906,7 @@
|
||||
"x-go-name": "Health"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"lastError": {
|
||||
"type": "string",
|
||||
@@ -2013,6 +2045,53 @@
|
||||
"type": "string",
|
||||
"x-go-package": "github.com/prometheus/client_golang/api/prometheus/v1"
|
||||
},
|
||||
"SNSConfig": {
|
||||
"properties": {
|
||||
"api_url": {
|
||||
"type": "string",
|
||||
"x-go-name": "APIUrl"
|
||||
},
|
||||
"attributes": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object",
|
||||
"x-go-name": "Attributes"
|
||||
},
|
||||
"http_config": {
|
||||
"$ref": "#/definitions/HTTPClientConfig"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
},
|
||||
"phone_number": {
|
||||
"type": "string",
|
||||
"x-go-name": "PhoneNumber"
|
||||
},
|
||||
"send_resolved": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "VSendResolved"
|
||||
},
|
||||
"sigv4": {
|
||||
"$ref": "#/definitions/SigV4Config"
|
||||
},
|
||||
"subject": {
|
||||
"type": "string",
|
||||
"x-go-name": "Subject"
|
||||
},
|
||||
"target_arn": {
|
||||
"type": "string",
|
||||
"x-go-name": "TargetARN"
|
||||
},
|
||||
"topic_arn": {
|
||||
"type": "string",
|
||||
"x-go-name": "TopicARN"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/config"
|
||||
},
|
||||
"Sample": {
|
||||
"properties": {
|
||||
"Metric": {
|
||||
@@ -2040,6 +2119,28 @@
|
||||
"$ref": "#/definitions/URL",
|
||||
"title": "SecretURL is a URL that must not be revealed on marshaling."
|
||||
},
|
||||
"SigV4Config": {
|
||||
"description": "SigV4Config is the configuration for signing remote write requests with\nAWS's SigV4 verification process. Empty values will be retrieved using the\nAWS default credentials chain.",
|
||||
"properties": {
|
||||
"AccessKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"Profile": {
|
||||
"type": "string"
|
||||
},
|
||||
"Region": {
|
||||
"type": "string"
|
||||
},
|
||||
"RoleARN": {
|
||||
"type": "string"
|
||||
},
|
||||
"SecretKey": {
|
||||
"$ref": "#/definitions/Secret"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/prometheus/common/sigv4"
|
||||
},
|
||||
"SlackAction": {
|
||||
"description": "See https://api.slack.com/docs/message-attachments#action_fields and https://api.slack.com/docs/message-buttons\nfor more information.",
|
||||
"properties": {
|
||||
@@ -2548,7 +2649,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"alertGroup": {
|
||||
"description": "AlertGroup alert group",
|
||||
"properties": {
|
||||
"alerts": {
|
||||
"description": "alerts",
|
||||
@@ -2570,14 +2670,17 @@
|
||||
"labels",
|
||||
"receiver"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"x-go-name": "AlertGroup",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"x-go-name": "AlertGroups",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"alertStatus": {
|
||||
"description": "AlertStatus alert status",
|
||||
@@ -2697,6 +2800,7 @@
|
||||
"$ref": "#/definitions/Duration"
|
||||
},
|
||||
"gettableAlert": {
|
||||
"description": "GettableAlert gettable alert",
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labelSet"
|
||||
@@ -2755,17 +2859,14 @@
|
||||
"status",
|
||||
"updatedAt"
|
||||
],
|
||||
"type": "object",
|
||||
"x-go-name": "GettableAlert",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "GettableAlerts",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"type": "array"
|
||||
},
|
||||
"gettableSilence": {
|
||||
"properties": {
|
||||
@@ -2824,12 +2925,11 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"gettableSilences": {
|
||||
"description": "GettableSilences gettable silences",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "GettableSilences",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"type": "array"
|
||||
},
|
||||
"labelSet": {
|
||||
"additionalProperties": {
|
||||
@@ -2840,15 +2940,6 @@
|
||||
"x-go-name": "LabelSet",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"labels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The custom marshaling for labels.Labels ends up doing this anyways.",
|
||||
"title": "override the labels type with a map for generation.",
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"matcher": {
|
||||
"description": "Matcher matcher",
|
||||
"properties": {
|
||||
@@ -2891,6 +2982,15 @@
|
||||
"x-go-name": "Matchers",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"overrideLabels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The custom marshaling for labels.Labels ends up doing this anyways.",
|
||||
"title": "override the labels type with a map for generation.",
|
||||
"type": "object",
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"peerStatus": {
|
||||
"description": "PeerStatus peer status",
|
||||
"properties": {
|
||||
@@ -2958,7 +3058,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
@@ -2998,9 +3097,12 @@
|
||||
"matchers",
|
||||
"startsAt"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"x-go-name": "PostableSilence",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "name",
|
||||
@@ -3011,9 +3113,7 @@
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"type": "object",
|
||||
"x-go-name": "Receiver",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"type": "object"
|
||||
},
|
||||
"silence": {
|
||||
"description": "Silence silence",
|
||||
|
||||
@@ -1024,10 +1024,10 @@
|
||||
"x-go-name": "ActiveAt"
|
||||
},
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
@@ -1189,7 +1189,7 @@
|
||||
"x-go-name": "Alerts"
|
||||
},
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"duration": {
|
||||
"type": "number",
|
||||
@@ -1206,7 +1206,7 @@
|
||||
"x-go-name": "Health"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"lastError": {
|
||||
"type": "string",
|
||||
@@ -1611,6 +1611,13 @@
|
||||
},
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -2168,6 +2175,10 @@
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/common/config"
|
||||
},
|
||||
"ObjectMatchers": {
|
||||
"description": "ObjectMatchers is Matchers with a different Unmarshal and Marshal methods that accept matchers as objects\nthat have already been parsed.",
|
||||
"$ref": "#/definitions/Matchers"
|
||||
},
|
||||
"OpsGenieConfig": {
|
||||
"type": "object",
|
||||
"title": "OpsGenieConfig configures notifications via OpsGenie.",
|
||||
@@ -2222,6 +2233,10 @@
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"x-go-name": "Tags"
|
||||
},
|
||||
"update_alerts": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "UpdateAlerts"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/alertmanager/config"
|
||||
@@ -2459,6 +2474,13 @@
|
||||
},
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -2753,6 +2775,13 @@
|
||||
},
|
||||
"x-go-name": "SlackConfigs"
|
||||
},
|
||||
"sns_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/SNSConfig"
|
||||
},
|
||||
"x-go-name": "SNSConfigs"
|
||||
},
|
||||
"victorops_configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -2807,8 +2836,8 @@
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"Route": {
|
||||
"description": "A Route is a node that contains definitions of how to handle alerts. This is modified\nfrom the upstream alertmanager in that it adds the ObjectMatchers property.",
|
||||
"type": "object",
|
||||
"title": "A Route is a node that contains definitions of how to handle alerts.",
|
||||
"properties": {
|
||||
"continue": {
|
||||
"type": "boolean",
|
||||
@@ -2848,6 +2877,9 @@
|
||||
},
|
||||
"x-go-name": "MuteTimeIntervals"
|
||||
},
|
||||
"object_matchers": {
|
||||
"$ref": "#/definitions/ObjectMatchers"
|
||||
},
|
||||
"receiver": {
|
||||
"type": "string",
|
||||
"x-go-name": "Receiver"
|
||||
@@ -2863,7 +2895,7 @@
|
||||
"x-go-name": "Routes"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/alertmanager/config"
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"Rule": {
|
||||
"description": "adapted from cortex",
|
||||
@@ -2885,7 +2917,7 @@
|
||||
"x-go-name": "Health"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
"$ref": "#/definitions/overrideLabels"
|
||||
},
|
||||
"lastError": {
|
||||
"type": "string",
|
||||
@@ -3017,6 +3049,53 @@
|
||||
"title": "RuleType models the type of a rule.",
|
||||
"x-go-package": "github.com/prometheus/client_golang/api/prometheus/v1"
|
||||
},
|
||||
"SNSConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_url": {
|
||||
"type": "string",
|
||||
"x-go-name": "APIUrl"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "Attributes"
|
||||
},
|
||||
"http_config": {
|
||||
"$ref": "#/definitions/HTTPClientConfig"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
},
|
||||
"phone_number": {
|
||||
"type": "string",
|
||||
"x-go-name": "PhoneNumber"
|
||||
},
|
||||
"send_resolved": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "VSendResolved"
|
||||
},
|
||||
"sigv4": {
|
||||
"$ref": "#/definitions/SigV4Config"
|
||||
},
|
||||
"subject": {
|
||||
"type": "string",
|
||||
"x-go-name": "Subject"
|
||||
},
|
||||
"target_arn": {
|
||||
"type": "string",
|
||||
"x-go-name": "TargetARN"
|
||||
},
|
||||
"topic_arn": {
|
||||
"type": "string",
|
||||
"x-go-name": "TopicARN"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/alertmanager/config"
|
||||
},
|
||||
"Sample": {
|
||||
"type": "object",
|
||||
"title": "Sample is a single sample belonging to a metric.",
|
||||
@@ -3044,6 +3123,28 @@
|
||||
"title": "SecretURL is a URL that must not be revealed on marshaling.",
|
||||
"$ref": "#/definitions/URL"
|
||||
},
|
||||
"SigV4Config": {
|
||||
"description": "SigV4Config is the configuration for signing remote write requests with\nAWS's SigV4 verification process. Empty values will be retrieved using the\nAWS default credentials chain.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"AccessKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"Profile": {
|
||||
"type": "string"
|
||||
},
|
||||
"Region": {
|
||||
"type": "string"
|
||||
},
|
||||
"RoleARN": {
|
||||
"type": "string"
|
||||
},
|
||||
"SecretKey": {
|
||||
"$ref": "#/definitions/Secret"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/common/sigv4"
|
||||
},
|
||||
"SlackAction": {
|
||||
"description": "See https://api.slack.com/docs/message-attachments#action_fields and https://api.slack.com/docs/message-buttons\nfor more information.",
|
||||
"type": "object",
|
||||
@@ -3552,7 +3653,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"alertGroup": {
|
||||
"description": "AlertGroup alert group",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"alerts",
|
||||
@@ -3575,14 +3675,17 @@
|
||||
"$ref": "#/definitions/receiver"
|
||||
}
|
||||
},
|
||||
"x-go-name": "AlertGroup",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"x-go-name": "AlertGroups",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/alertGroups"
|
||||
},
|
||||
"alertStatus": {
|
||||
@@ -3703,6 +3806,7 @@
|
||||
"$ref": "#/definitions/Duration"
|
||||
},
|
||||
"gettableAlert": {
|
||||
"description": "GettableAlert gettable alert",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"labels",
|
||||
@@ -3762,17 +3866,14 @@
|
||||
"x-go-name": "UpdatedAt"
|
||||
}
|
||||
},
|
||||
"x-go-name": "GettableAlert",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"x-go-name": "GettableAlerts",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/gettableAlerts"
|
||||
},
|
||||
"gettableSilence": {
|
||||
@@ -3833,12 +3934,11 @@
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
"gettableSilences": {
|
||||
"description": "GettableSilences gettable silences",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
"x-go-name": "GettableSilences",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/gettableSilences"
|
||||
},
|
||||
"labelSet": {
|
||||
@@ -3850,15 +3950,6 @@
|
||||
"x-go-name": "LabelSet",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"labels": {
|
||||
"description": "The custom marshaling for labels.Labels ends up doing this anyways.",
|
||||
"type": "object",
|
||||
"title": "override the labels type with a map for generation.",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"matcher": {
|
||||
"description": "Matcher matcher",
|
||||
"type": "object",
|
||||
@@ -3901,6 +3992,15 @@
|
||||
"x-go-name": "Matchers",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"overrideLabels": {
|
||||
"description": "The custom marshaling for labels.Labels ends up doing this anyways.",
|
||||
"type": "object",
|
||||
"title": "override the labels type with a map for generation.",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
},
|
||||
"peerStatus": {
|
||||
"description": "PeerStatus peer status",
|
||||
"type": "object",
|
||||
@@ -3968,7 +4068,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"comment",
|
||||
@@ -4009,9 +4108,12 @@
|
||||
"x-go-name": "StartsAt"
|
||||
}
|
||||
},
|
||||
"x-go-name": "PostableSilence",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/postableSilence"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
@@ -4023,8 +4125,6 @@
|
||||
"x-go-name": "Name"
|
||||
}
|
||||
},
|
||||
"x-go-name": "Receiver",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/receiver"
|
||||
},
|
||||
"silence": {
|
||||
|
||||
@@ -10,9 +10,11 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
gokit_log "github.com/go-kit/kit/log"
|
||||
amv2 "github.com/prometheus/alertmanager/api/v2/models"
|
||||
@@ -39,6 +41,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier/channels"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
pb "github.com/prometheus/alertmanager/silence/silencepb"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -57,6 +60,24 @@ const (
|
||||
memoryAlertsGCInterval = 30 * time.Minute
|
||||
)
|
||||
|
||||
func init() {
|
||||
silence.ValidateMatcher = func(m *pb.Matcher) error {
|
||||
switch m.Type {
|
||||
case pb.Matcher_EQUAL, pb.Matcher_NOT_EQUAL:
|
||||
if !model.LabelValue(m.Pattern).IsValid() {
|
||||
return fmt.Errorf("invalid label value %q", m.Pattern)
|
||||
}
|
||||
case pb.Matcher_REGEXP, pb.Matcher_NOT_REGEXP:
|
||||
if _, err := regexp.Compile(m.Pattern); err != nil {
|
||||
return fmt.Errorf("invalid regular expression %q: %s", m.Pattern, err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown matcher type %q", m.Type)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type ClusterPeer interface {
|
||||
AddState(string, cluster.State, prometheus.Registerer) cluster.ClusterChannel
|
||||
Position() int
|
||||
@@ -392,7 +413,7 @@ func (am *Alertmanager) applyConfig(cfg *apimodels.PostableUserConfig, rawConfig
|
||||
routingStage[name] = notify.MultiStage{meshStage, silencingStage, inhibitionStage, stage}
|
||||
}
|
||||
|
||||
am.route = dispatch.NewRoute(cfg.AlertmanagerConfig.Route, nil)
|
||||
am.route = dispatch.NewRoute(cfg.AlertmanagerConfig.Route.AsAMRoute(), nil)
|
||||
am.dispatcher = dispatch.NewDispatcher(am.alerts, am.route, routingStage, am.marker, am.timeoutFunc, &nilLimits{}, am.gokitLogger, am.dispatcherMetrics)
|
||||
|
||||
am.wg.Add(1)
|
||||
@@ -638,22 +659,14 @@ func validateLabelSet(ls model.LabelSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isValidLabelName is ln.IsValid() while additionally allowing spaces.
|
||||
// The regex for Prometheus data model is ^[a-zA-Z_][a-zA-Z0-9_]*$
|
||||
// while we will follow ^[a-zA-Z_][a-zA-Z0-9_ ]*$
|
||||
// isValidLabelName is ln.IsValid() without restrictions other than it can not be empty.
|
||||
// The regex for Prometheus data model is ^[a-zA-Z_][a-zA-Z0-9_]*$.
|
||||
func isValidLabelName(ln model.LabelName) bool {
|
||||
if len(ln) == 0 {
|
||||
return false
|
||||
}
|
||||
for i, b := range ln {
|
||||
if !((b >= 'a' && b <= 'z') ||
|
||||
(b >= 'A' && b <= 'Z') ||
|
||||
b == '_' ||
|
||||
(i > 0 && (b == ' ' || (b >= '0' && b <= '9')))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
return utf8.ValidString(string(ln))
|
||||
}
|
||||
|
||||
// AlertValidationError is the error capturing the validation errors
|
||||
|
||||
@@ -208,48 +208,57 @@ func TestPutAlert(t *testing.T) {
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "Invalid labels",
|
||||
title: "Special characters in labels",
|
||||
postableAlerts: apimodels.PostableAlerts{
|
||||
PostableAlerts: []models.PostableAlert{
|
||||
{
|
||||
Alert: models.Alert{
|
||||
Labels: models.LabelSet{"alertname$": "Alert1"},
|
||||
Labels: models.LabelSet{"alertname$": "Alert1", "az3-- __...++!!!£@@312312": "1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expError: &AlertValidationError{
|
||||
Alerts: []models.PostableAlert{
|
||||
expAlerts: func(now time.Time) []*types.Alert {
|
||||
return []*types.Alert{
|
||||
{
|
||||
Alert: models.Alert{
|
||||
Labels: models.LabelSet{"alertname$": "Alert1"},
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname$": "Alert1", "az3-- __...++!!!£@@312312": "1"},
|
||||
Annotations: model.LabelSet{},
|
||||
StartsAt: now,
|
||||
EndsAt: now.Add(defaultResolveTimeout),
|
||||
GeneratorURL: "",
|
||||
},
|
||||
UpdatedAt: now,
|
||||
Timeout: true,
|
||||
},
|
||||
},
|
||||
Errors: []error{errors.New("invalid label set: invalid name \"alertname$\"")},
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "Invalid annotation",
|
||||
title: "Special characters in annotations",
|
||||
postableAlerts: apimodels.PostableAlerts{
|
||||
PostableAlerts: []models.PostableAlert{
|
||||
{
|
||||
Annotations: models.LabelSet{"msg$": "Alert4 annotation"},
|
||||
Annotations: models.LabelSet{"az3-- __...++!!!£@@312312": "Alert4 annotation"},
|
||||
Alert: models.Alert{
|
||||
Labels: models.LabelSet{"alertname": "Alert1"},
|
||||
Labels: models.LabelSet{"alertname": "Alert4"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expError: &AlertValidationError{
|
||||
Alerts: []models.PostableAlert{
|
||||
expAlerts: func(now time.Time) []*types.Alert {
|
||||
return []*types.Alert{
|
||||
{
|
||||
Annotations: models.LabelSet{"msg$": "Alert4 annotation"},
|
||||
Alert: models.Alert{
|
||||
Labels: models.LabelSet{"alertname": "Alert1"},
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "Alert4"},
|
||||
Annotations: model.LabelSet{"az3-- __...++!!!£@@312312": "Alert4 annotation"},
|
||||
StartsAt: now,
|
||||
EndsAt: now.Add(defaultResolveTimeout),
|
||||
GeneratorURL: "",
|
||||
},
|
||||
UpdatedAt: now,
|
||||
Timeout: true,
|
||||
},
|
||||
},
|
||||
Errors: []error{errors.New("invalid annotations: invalid name \"msg$\"")},
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "No labels after removing empty",
|
||||
|
||||
@@ -36,6 +36,7 @@ const mocks = {
|
||||
|
||||
const renderAmRoutes = (alertManagerSourceName?: string) => {
|
||||
const store = configureStore();
|
||||
locationService.push(location);
|
||||
|
||||
locationService.push(
|
||||
'/alerting/routes' + (alertManagerSourceName ? `?${ALERTMANAGER_NAME_QUERY_KEY}=${alertManagerSourceName}` : '')
|
||||
@@ -144,6 +145,11 @@ describe('AmRoutes', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const simpleRoute: Route = {
|
||||
receiver: 'simple-receiver',
|
||||
matchers: ['hello=world', 'foo!=bar'],
|
||||
};
|
||||
|
||||
const rootRoute: Route = {
|
||||
receiver: 'default-receiver',
|
||||
group_by: ['a-group', 'another-group'],
|
||||
@@ -349,6 +355,142 @@ describe('AmRoutes', () => {
|
||||
expect(ui.editButton.query()).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Converts matchers to object_matchers for grafana alertmanager', async () => {
|
||||
const defaultConfig: AlertManagerCortexConfig = {
|
||||
alertmanager_config: {
|
||||
receivers: [{ name: 'default' }, { name: 'critical' }],
|
||||
route: {
|
||||
continue: false,
|
||||
receiver: 'default',
|
||||
group_by: ['alertname'],
|
||||
routes: [simpleRoute],
|
||||
group_interval: '4m',
|
||||
group_wait: '1m',
|
||||
repeat_interval: '5h',
|
||||
},
|
||||
templates: [],
|
||||
},
|
||||
template_files: {},
|
||||
};
|
||||
|
||||
const currentConfig = { current: defaultConfig };
|
||||
mocks.api.updateAlertManagerConfig.mockImplementation((amSourceName, newConfig) => {
|
||||
currentConfig.current = newConfig;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
mocks.api.fetchAlertManagerConfig.mockImplementation(() => {
|
||||
return Promise.resolve(currentConfig.current);
|
||||
});
|
||||
|
||||
await renderAmRoutes(GRAFANA_RULES_SOURCE_NAME);
|
||||
expect(await ui.rootReceiver.find()).toHaveTextContent('default');
|
||||
expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled();
|
||||
|
||||
// Toggle a save to test new object_matchers
|
||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||
|
||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||
|
||||
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled();
|
||||
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith(GRAFANA_RULES_SOURCE_NAME, {
|
||||
alertmanager_config: {
|
||||
receivers: [{ name: 'default' }, { name: 'critical' }],
|
||||
route: {
|
||||
continue: false,
|
||||
group_by: ['alertname'],
|
||||
group_interval: '4m',
|
||||
group_wait: '1m',
|
||||
receiver: 'default',
|
||||
repeat_interval: '5h',
|
||||
routes: [
|
||||
{
|
||||
continue: false,
|
||||
group_by: [],
|
||||
object_matchers: [
|
||||
['hello', '=', 'world'],
|
||||
['foo', '!=', 'bar'],
|
||||
],
|
||||
receiver: 'simple-receiver',
|
||||
routes: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
templates: [],
|
||||
},
|
||||
template_files: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('Keeps matchers for non-grafana alertmanager sources', async () => {
|
||||
const defaultConfig: AlertManagerCortexConfig = {
|
||||
alertmanager_config: {
|
||||
receivers: [{ name: 'default' }, { name: 'critical' }],
|
||||
route: {
|
||||
continue: false,
|
||||
receiver: 'default',
|
||||
group_by: ['alertname'],
|
||||
routes: [simpleRoute],
|
||||
group_interval: '4m',
|
||||
group_wait: '1m',
|
||||
repeat_interval: '5h',
|
||||
},
|
||||
templates: [],
|
||||
},
|
||||
template_files: {},
|
||||
};
|
||||
|
||||
const currentConfig = { current: defaultConfig };
|
||||
mocks.api.updateAlertManagerConfig.mockImplementation((amSourceName, newConfig) => {
|
||||
currentConfig.current = newConfig;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
mocks.api.fetchAlertManagerConfig.mockImplementation(() => {
|
||||
return Promise.resolve(currentConfig.current);
|
||||
});
|
||||
|
||||
await renderAmRoutes(dataSources.am.name);
|
||||
expect(await ui.rootReceiver.find()).toHaveTextContent('default');
|
||||
expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled();
|
||||
|
||||
// Toggle a save to test new object_matchers
|
||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||
|
||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||
|
||||
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled();
|
||||
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith(dataSources.am.name, {
|
||||
alertmanager_config: {
|
||||
receivers: [{ name: 'default' }, { name: 'critical' }],
|
||||
route: {
|
||||
continue: false,
|
||||
group_by: ['alertname'],
|
||||
group_interval: '4m',
|
||||
group_wait: '1m',
|
||||
matchers: [],
|
||||
receiver: 'default',
|
||||
repeat_interval: '5h',
|
||||
routes: [
|
||||
{
|
||||
continue: false,
|
||||
group_by: [],
|
||||
matchers: ['hello=world', 'foo!=bar'],
|
||||
receiver: 'simple-receiver',
|
||||
routes: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
templates: [],
|
||||
},
|
||||
template_files: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('Prometheus Alertmanager routes cannot be edited', async () => {
|
||||
mocks.api.fetchStatus.mockResolvedValue({
|
||||
...someCloudAlertManagerStatus,
|
||||
|
||||
@@ -59,6 +59,7 @@ const AmRoutes: FC = () => {
|
||||
useCleanup((state) => state.unifiedAlerting.saveAMConfig);
|
||||
const handleSave = (data: Partial<FormAmRoute>) => {
|
||||
const newData = formAmRouteToAmRoute(
|
||||
alertManagerSourceName,
|
||||
{
|
||||
...rootRoute,
|
||||
...data,
|
||||
|
||||
@@ -51,19 +51,19 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
{/* @ts-ignore-check: react-hook-form made me do this */}
|
||||
<input type="hidden" {...register('id')} />
|
||||
{/* @ts-ignore-check: react-hook-form made me do this */}
|
||||
<FieldArray name="matchers" control={control}>
|
||||
<FieldArray name="object_matchers" control={control}>
|
||||
{({ fields, append, remove }) => (
|
||||
<>
|
||||
<div>Matching labels</div>
|
||||
<div className={styles.matchersContainer}>
|
||||
{fields.map((field, index) => {
|
||||
const localPath = `matchers[${index}]`;
|
||||
const localPath = `object_matchers[${index}]`;
|
||||
return (
|
||||
<HorizontalGroup key={field.id} align="flex-start">
|
||||
<Field
|
||||
label="Label"
|
||||
invalid={!!errors.matchers?.[index]?.name}
|
||||
error={errors.matchers?.[index]?.name?.message}
|
||||
invalid={!!errors.object_matchers?.[index]?.name}
|
||||
error={errors.object_matchers?.[index]?.name?.message}
|
||||
>
|
||||
<Input
|
||||
{...register(`${localPath}.name`, { required: 'Field is required' })}
|
||||
@@ -89,8 +89,8 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
</Field>
|
||||
<Field
|
||||
label="Value"
|
||||
invalid={!!errors.matchers?.[index]?.value}
|
||||
error={errors.matchers?.[index]?.value?.message}
|
||||
invalid={!!errors.object_matchers?.[index]?.value}
|
||||
error={errors.object_matchers?.[index]?.value?.message}
|
||||
>
|
||||
<Input
|
||||
{...register(`${localPath}.value`, { required: 'Field is required' })}
|
||||
|
||||
@@ -41,7 +41,7 @@ export const AmRoutesTable: FC<AmRoutesTableProps> = ({
|
||||
id: 'matchingCriteria',
|
||||
label: 'Matching labels',
|
||||
// eslint-disable-next-line react/display-name
|
||||
renderCell: (item) => <Matchers matchers={item.data.matchers.map(matcherFieldToMatcher)} />,
|
||||
renderCell: (item) => <Matchers matchers={item.data.object_matchers.map(matcherFieldToMatcher)} />,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ import { MatcherFieldValue } from './silence-form';
|
||||
|
||||
export interface FormAmRoute {
|
||||
id: string;
|
||||
matchers: MatcherFieldValue[];
|
||||
object_matchers: MatcherFieldValue[];
|
||||
continue: boolean;
|
||||
receiver: string;
|
||||
groupBy: string[];
|
||||
|
||||
@@ -3,9 +3,10 @@ import { Validate } from 'react-hook-form';
|
||||
import { MatcherOperator, Route } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { FormAmRoute } from '../types/amroutes';
|
||||
import { parseInterval, timeOptions } from './time';
|
||||
import { matcherToMatcherField, matcherFieldToMatcher, parseMatcher, stringifyMatcher } from './alertmanager';
|
||||
import { isUndefined, omitBy } from 'lodash';
|
||||
import { MatcherFieldValue } from '../types/silence-form';
|
||||
import { matcherToMatcherField, parseMatcher } from './alertmanager';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from './datasource';
|
||||
|
||||
const defaultValueAndType: [string, string] = ['', timeOptions[0].value];
|
||||
|
||||
@@ -55,7 +56,7 @@ export const emptyArrayFieldMatcher: MatcherFieldValue = {
|
||||
export const emptyRoute: FormAmRoute = {
|
||||
id: '',
|
||||
groupBy: [],
|
||||
matchers: [],
|
||||
object_matchers: [],
|
||||
routes: [],
|
||||
continue: false,
|
||||
receiver: '',
|
||||
@@ -88,11 +89,18 @@ export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Re
|
||||
Object.assign(id2route, subId2Route);
|
||||
});
|
||||
|
||||
// Frontend migration to use object_matchers instead of matchers
|
||||
const matchers = route.matchers
|
||||
? route.matchers?.map((matcher) => matcherToMatcherField(parseMatcher(matcher))) ?? []
|
||||
: route.object_matchers?.map(
|
||||
(matcher) => ({ name: matcher[0], operator: matcher[1], value: matcher[2] } as MatcherFieldValue)
|
||||
) ?? [];
|
||||
|
||||
return [
|
||||
{
|
||||
id,
|
||||
matchers: [
|
||||
...(route.matchers?.map((matcher) => matcherToMatcherField(parseMatcher(matcher))) ?? []),
|
||||
object_matchers: [
|
||||
...matchers,
|
||||
...matchersToArrayFieldMatchers(route.match, false),
|
||||
...matchersToArrayFieldMatchers(route.match_re, true),
|
||||
],
|
||||
@@ -111,14 +119,18 @@ export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Re
|
||||
];
|
||||
};
|
||||
|
||||
export const formAmRouteToAmRoute = (formAmRoute: FormAmRoute, id2ExistingRoute: Record<string, Route>): Route => {
|
||||
export const formAmRouteToAmRoute = (
|
||||
alertManagerSourceName: string | undefined,
|
||||
formAmRoute: FormAmRoute,
|
||||
id2ExistingRoute: Record<string, Route>
|
||||
): Route => {
|
||||
const existing: Route | undefined = id2ExistingRoute[formAmRoute.id];
|
||||
const amRoute: Route = {
|
||||
...(existing ?? {}),
|
||||
continue: formAmRoute.continue,
|
||||
group_by: formAmRoute.groupBy,
|
||||
matchers: formAmRoute.matchers.length
|
||||
? formAmRoute.matchers.map((matcher) => stringifyMatcher(matcherFieldToMatcher(matcher)))
|
||||
object_matchers: formAmRoute.object_matchers.length
|
||||
? formAmRoute.object_matchers.map((matcher) => [matcher.name, matcher.operator, matcher.value])
|
||||
: undefined,
|
||||
match: undefined,
|
||||
match_re: undefined,
|
||||
@@ -131,9 +143,18 @@ export const formAmRouteToAmRoute = (formAmRoute: FormAmRoute, id2ExistingRoute:
|
||||
repeat_interval: formAmRoute.repeatIntervalValue
|
||||
? `${formAmRoute.repeatIntervalValue}${formAmRoute.repeatIntervalValueType}`
|
||||
: undefined,
|
||||
routes: formAmRoute.routes.map((subRoute) => formAmRouteToAmRoute(subRoute, id2ExistingRoute)),
|
||||
routes: formAmRoute.routes.map((subRoute) =>
|
||||
formAmRouteToAmRoute(alertManagerSourceName, subRoute, id2ExistingRoute)
|
||||
),
|
||||
};
|
||||
|
||||
if (alertManagerSourceName !== GRAFANA_RULES_SOURCE_NAME) {
|
||||
amRoute.matchers = formAmRoute.object_matchers.map(({ name, operator, value }) => `${name}${operator}${value}`);
|
||||
amRoute.object_matchers = undefined;
|
||||
} else {
|
||||
amRoute.matchers = undefined;
|
||||
}
|
||||
|
||||
if (formAmRoute.receiver) {
|
||||
amRoute.receiver = formAmRoute.receiver;
|
||||
}
|
||||
|
||||
@@ -89,12 +89,17 @@ export type Receiver = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
type ObjectMatcher = [name: string, operator: MatcherOperator, value: string];
|
||||
|
||||
export type Route = {
|
||||
receiver?: string;
|
||||
group_by?: string[];
|
||||
continue?: boolean;
|
||||
object_matchers?: ObjectMatcher[];
|
||||
matchers?: string[];
|
||||
/** @deprecated use `object_matchers` */
|
||||
match?: Record<string, string>;
|
||||
/** @deprecated use `object_matchers` */
|
||||
match_re?: Record<string, string>;
|
||||
group_wait?: string;
|
||||
group_interval?: string;
|
||||
|
||||
Reference in New Issue
Block a user