From 98d6695064dc5299f81de126b10206376b086918 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Thu, 5 Dec 2024 19:34:59 +0100 Subject: [PATCH 01/44] Add alertmanager config handling --- go.mod | 47 ++- go.sum | 495 +++++++++++++++++++++++++- pkg/alertmanager/alertmanager_test.go | 111 ++++++ 3 files changed, 650 insertions(+), 3 deletions(-) create mode 100644 pkg/alertmanager/alertmanager_test.go diff --git a/go.mod b/go.mod index 5ec48bbd..e15e4dda 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/Masterminds/sprig/v3 v3.3.0 github.com/blang/semver v3.5.1+incompatible github.com/giantswarm/apiextensions-application v0.6.2 + github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f github.com/go-logr/logr v1.4.2 github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb github.com/onsi/ginkgo/v2 v2.22.0 @@ -15,9 +16,11 @@ require ( github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 github.com/pkg/errors v0.9.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.2 + github.com/prometheus/alertmanager v0.27.0 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/common v0.61.0 github.com/sirupsen/logrus v1.9.3 + gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.31.3 k8s.io/apimachinery v0.31.3 k8s.io/client-go v0.31.3 @@ -86,9 +89,30 @@ require ( require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aws/aws-sdk-go v1.50.8 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/giantswarm/apiextensions/v6 v6.6.0 // indirect + github.com/giantswarm/backoff v1.0.0 // indirect + github.com/giantswarm/exporterkit v1.1.0 // indirect + github.com/giantswarm/k8sclient/v7 v7.2.0 // indirect + github.com/giantswarm/microendpoint v1.1.0 // indirect + github.com/giantswarm/microerror v0.4.1 // indirect + github.com/giantswarm/microkit v1.0.1 // indirect + github.com/giantswarm/micrologger v1.1.1 // indirect + github.com/giantswarm/operatorkit/v7 v7.2.0 // indirect + github.com/giantswarm/to v0.4.0 // indirect + github.com/giantswarm/versionbundle v1.1.0 // indirect + github.com/go-kit/kit v0.13.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect @@ -97,22 +121,43 @@ require ( github.com/go-openapi/spec v0.21.0 // indirect github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 // indirect + github.com/prometheus/common/sigv4 v0.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect + github.com/spf13/viper v1.19.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sync v0.10.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/resty.v1 v1.12.0 // indirect + k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 98add1da..8584559c 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,66 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.50.8 h1:gY0WoOW+/Wz6XmYSgDH9ge3wnAevYDSQWPxxJvqAkP4= +github.com/aws/aws-sdk-go v1.50.8/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -20,12 +69,22 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/corefile-migration v1.0.23 h1:Fp4FETmk8sT/IRgnKX2xstC2dL7+QdcU+BL5AYIN3Jw= github.com/coredns/corefile-migration v1.0.23/go.mod h1:8HyMhuyzx9RLZp8cRc9Uf3ECpEAafHOFxQWUPqktMQI= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -34,8 +93,12 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -46,12 +109,59 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= +github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/giantswarm/apiextensions-application v0.6.2 h1:XL86OrpprWl5Wp38EUvUXt3ztTo25+V63oDVlFwDpNg= github.com/giantswarm/apiextensions-application v0.6.2/go.mod h1:8ylqSmDSzFblCppRQTFo8v9s/F6MX6RTusVVoDDfWso= +github.com/giantswarm/apiextensions/v6 v6.6.0 h1:qtsZuxsfigUB6xRd/UygQjh3Oaf54uXp+adbtgpCfiI= +github.com/giantswarm/apiextensions/v6 v6.6.0/go.mod h1:Wgc2Rx8YAYF2HidjabEvhsj5ADL+RteIC86ofulY+YE= +github.com/giantswarm/backoff v1.0.0 h1:1oeTvyPsm1tJrHlSmfxbIWuoCNWPOkWJCb8kfLvE2T0= +github.com/giantswarm/backoff v1.0.0/go.mod h1:l/WqbggvG5Ndxxws0LUgVEvP5E82Qj5/PF8SMip/1QM= +github.com/giantswarm/exporterkit v1.1.0 h1:It+tps930KykISVLtwrn9dKq4kVHLk0rnjaQvKHOV0o= +github.com/giantswarm/exporterkit v1.1.0/go.mod h1:nzlgQdEZ29umzo6cY/ggVqSanQumkS0aLU1Kckv2ZSk= +github.com/giantswarm/k8sclient/v7 v7.2.0 h1:twh4egNcuTJEH7R/hYVhs8nwEXPlr0u/o9CB1Kv9H9A= +github.com/giantswarm/k8sclient/v7 v7.2.0/go.mod h1:kZGRtOqe4vAKXtWm69tsj2Q9CpWlwzpa1uP1lfDtjlE= github.com/giantswarm/k8smetadata v0.25.0 h1:6mKmmm4xHPuBvxDMAkIhU5oj6KJkJSaR2s5esIsnHs4= github.com/giantswarm/k8smetadata v0.25.0/go.mod h1:QiQAyaZnwco1U0lENLF0Kp4bSN4dIPwIlHWEvUo3ES8= +github.com/giantswarm/microendpoint v1.1.0 h1:z2MUbN/BJ5ME92v93TidfV2JjftfOaJa7rKFdPb6vRU= +github.com/giantswarm/microendpoint v1.1.0/go.mod h1:Zpelq95t2I4Pa8Fvaz8/Ttr3xeeCEgEPIilGUzXwXDY= +github.com/giantswarm/microerror v0.4.1 h1:WMiD7HQASoUA9lZzPlPK+erCEOJ0uT4cyo18VfCXHD0= +github.com/giantswarm/microerror v0.4.1/go.mod h1:URFj0gFCmZihjya6saQCXxslBrgctXb4NsXYHB5JdrI= +github.com/giantswarm/microkit v1.0.1 h1:P5N9ywvaHvwhxx8WXbZ45iqJs31TZvL4rtMv+owdXac= +github.com/giantswarm/microkit v1.0.1/go.mod h1:EiNhNb6i4JQl8EnfVVUqrb3FD7rU8p5QRbR2nqG7iMI= +github.com/giantswarm/micrologger v1.1.1 h1:gpu9uq1Vixey20Zo5pra5m/5EsmLrNlTwIgjBoc1jhE= +github.com/giantswarm/micrologger v1.1.1/go.mod h1:l84q1WCLdXtPimHoJlgYEAJ3lmLyWbPbHW1ZpV+wPaA= +github.com/giantswarm/operatorkit/v7 v7.2.0 h1:eoKInQ6Ka0NlQEEqjQbmbAFLW/eOjKHkH2+wBs/JuMU= +github.com/giantswarm/operatorkit/v7 v7.2.0/go.mod h1:rvHDLhFd5P2tVx1GbnUTUURWmRWmHI+91M2GPcBEraM= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205162658-e52a672a0f04 h1:59TTWgResI64Xx3Du5xt8ofdD5QiFu0DY6bRLDkIIy0= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205162658-e52a672a0f04/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205181233-1b0048f5eab5 h1:BE38RRya0rIcWlY8JqLuEGRdLM8ReEnmsPAtzj+9UIw= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205181233-1b0048f5eab5/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f h1:+ybaKU8ZTqEgXogpRKIIM1ooeO/eyM4ANbFwHoPXVpY= +github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= +github.com/giantswarm/to v0.4.0 h1:x0GjbI94/nxcHztJiRtJzihCjgmUlEOto8RD98VA7WI= +github.com/giantswarm/to v0.4.0/go.mod h1:RTRtw+Dyk6YqoiNBOGLO981BqhibtVwogdaFIMO1y/A= +github.com/giantswarm/versionbundle v1.1.0 h1:Fk0UWTMnA56voTh5P/LmLLPbAkEkFE5jKKpVzcMOL1A= +github.com/giantswarm/versionbundle v1.1.0/go.mod h1:+sEGkxho1b7UYid1F9+xIAoRWiZ4Wyrh6P5a6hxgtWc= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= +github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -79,30 +189,84 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb h1:fdtb12RMGDBdQwUuWw9SnBWO2kANZGlfh++tIVBYjbU= github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb/go.mod h1:hiZnMmXc9KXNUlvkV2BKFsiWuIFF/fF4wGgYWEjBitI= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -114,29 +278,52 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -148,6 +335,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -157,10 +345,13 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -175,6 +366,11 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 h1:EFOD/cRfMeq+PCibHddoRTXu8CTN1m8Oj1Tk6eoz8Dw= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23/go.mod h1:1BK0BG3Mz//zeujilvvu3GJ0jnyZwFdT9XjznoPv6kk= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -183,48 +379,97 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.2 h1:SyoVBXD/r0PntR1rprb90ClI32FSUNOCWqqTatnipHM= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.2/go.mod h1:SvsRXw4m1F2vk7HquU5h475bFpke27mIUswfyw9u3ug= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 h1:SyBTzvFuVshDNjDVALs6+NgOy3qh8/xlAsyqB1SzHbI= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0/go.mod h1:FlcnLo14zQxL6P1yPrV22kYBqyAT0ZRRytv98+B7lBQ= +github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I= +github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +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/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -247,36 +492,138 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -290,15 +637,60 @@ golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +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.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/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-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= @@ -308,28 +700,122 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= @@ -338,6 +824,8 @@ k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4= k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE= +k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 h1:y0TgWoHaeYEv3L1MfLC+D2WVxyN1fGr6axURHXq+wHE= +k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0/go.mod h1:w6/LjLR3DPQd57vlgvgbpzpuJKsCiily0+OzQI+nyfI= k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= k8s.io/cluster-bootstrap v0.30.3 h1:MgxyxMkpaC6mu0BKWJ8985XCOnKU+eH3Iy+biwtDXRk= @@ -350,6 +838,9 @@ k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUx k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/cluster-api v1.8.5 h1:lNA2fPN4fkXEs+oOQlnwxT/4VwRFBpv5kkSoJG8nqBA= diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go new file mode 100644 index 00000000..04960072 --- /dev/null +++ b/pkg/alertmanager/alertmanager_test.go @@ -0,0 +1,111 @@ +package alertmanager + +import ( + "bytes" + "io" + "net/http" + "path/filepath" + "testing" + + "github.com/giantswarm/prometheus-meta-operator/v2/service/controller/resource/alerting/alertmanagerconfig" + "github.com/prometheus/alertmanager/config" + "golang.org/x/net/http/httpproxy" + "gopkg.in/yaml.v2" +) + +const alertmanagerAPIPath = "/api/v1/alerts" + +type configCompat struct { + TemplateFiles map[string]string `yaml:"template_files"` + AlertmanagerConfig string `yaml:"alertmanager_config"` +} + +func TestAlertmanagerConfigLoad(t *testing.T) { + const ( + //alertmanagerConfigPath = "alertmanager.yaml" + //templatePath = "notification-template.tmpl" + + // Mimir Alertmanager URL and path + alertmanagerURL = "http://localhost:8080" + alertmanagerAPIPath = "/api/v1/alerts" + + tenandID = "anonymous" + ) + + // Use alertmanagerconfig.Resource from prometheus-meta-operator + // Re-using the same template files and rendering logic to ensure same config are generated. + c := alertmanagerconfig.Config{ + BaseDomain: "http://base", + GrafanaAddress: "http://grafana", + Installation: "test-installation", + MimirEnabled: true, + OpsgenieKey: "opsgenie-key", + Pipeline: "test", + Proxy: httpproxy.FromEnvironment().ProxyFunc(), + SlackApiToken: "slack-token", + SlackApiURL: "http://slack", + } + r, err := alertmanagerconfig.New(c) + if err != nil { + t.Fatalf("Error instantiating resource: %v", err) + } + + // Render alertmanager config + alertmanagerContent, err := r.RenderAlertmanagerConfig() + //alertmanagerContent, err := os.ReadFile(alertmanagerConfigPath) + if err != nil { + t.Fatalf("Error rendering config: %v", err) + } + + // Ensure template name in alertmanager config is a name and not a path, this is to avoid following error: + // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path + templateBase := filepath.Base(templatePath) + alertmanagerConfig, err := config.Load(string(alertmanagerContent)) + if err != nil { + t.Fatalf("Error loading config: %v", err) + } + alertmanagerConfig.Templates = []string{templateBase} + alertmanagerConfigString := alertmanagerConfig.String() + + // Render alertmanager template + alertmanagerTemplate, err := r.RenderNotificationTemplate() + //alertmanagerTemplate, err := os.ReadFile(templatePath) + if err != nil { + t.Fatalf("Error rendering template: %v", err) + } + + t.Logf("config: %d, template: %d\n", len(alertmanagerConfigString), len(alertmanagerTemplate)) + + // Prepare request for Alertmanager API + compact := configCompat{ + AlertmanagerConfig: string(alertmanagerConfigString), + TemplateFiles: map[string]string{ + templateBase: string(alertmanagerTemplate), + }, + } + data, err := yaml.Marshal(compact) + if err != nil { + t.Fatalf("Error marshalling yaml: %v", err) + } + + // Send request to Alertmanager API + req, err := http.NewRequest("POST", alertmanagerURL+alertmanagerAPIPath, bytes.NewBuffer(data)) + //req, err := http.NewRequest("DELETE", "http://localhost:8080/api/v1/alerts", nil) + if err != nil { + t.Fatalf("Error creating request: %v", err) + } + req.Header.Set("X-Scope-OrgID", tenandID) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Error sending request: %v", err) + } + defer resp.Body.Close() + + // Debug response + respData, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Error reading response: %v", err) + } + t.Logf("response: %d %s\n", resp.StatusCode, respData) +} From b57550727447e5fac61ce47c3ccdd4e5afe4bc5b Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Thu, 5 Dec 2024 20:40:24 +0100 Subject: [PATCH 02/44] make the alertmanagerURL simpler --- pkg/alertmanager/alertmanager_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go index 04960072..b10027c4 100644 --- a/pkg/alertmanager/alertmanager_test.go +++ b/pkg/alertmanager/alertmanager_test.go @@ -26,8 +26,7 @@ func TestAlertmanagerConfigLoad(t *testing.T) { //templatePath = "notification-template.tmpl" // Mimir Alertmanager URL and path - alertmanagerURL = "http://localhost:8080" - alertmanagerAPIPath = "/api/v1/alerts" + alertmanagerURL = "http://localhost:8080/api/v1/alerts" tenandID = "anonymous" ) @@ -89,7 +88,7 @@ func TestAlertmanagerConfigLoad(t *testing.T) { } // Send request to Alertmanager API - req, err := http.NewRequest("POST", alertmanagerURL+alertmanagerAPIPath, bytes.NewBuffer(data)) + req, err := http.NewRequest("POST", alertmanagerURL, bytes.NewBuffer(data)) //req, err := http.NewRequest("DELETE", "http://localhost:8080/api/v1/alerts", nil) if err != nil { t.Fatalf("Error creating request: %v", err) From f281c754f5adff609c6202a10a5ffa39526ca73b Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Thu, 5 Dec 2024 21:18:29 +0100 Subject: [PATCH 03/44] make the build green --- pkg/alertmanager/alertmanager_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go index b10027c4..2da71730 100644 --- a/pkg/alertmanager/alertmanager_test.go +++ b/pkg/alertmanager/alertmanager_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package alertmanager import ( @@ -23,7 +26,7 @@ type configCompat struct { func TestAlertmanagerConfigLoad(t *testing.T) { const ( //alertmanagerConfigPath = "alertmanager.yaml" - //templatePath = "notification-template.tmpl" + templatePath = "notification-template.tmpl" // Mimir Alertmanager URL and path alertmanagerURL = "http://localhost:8080/api/v1/alerts" From b58a751105bd6798cbeba3488b47049120e7acc5 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Thu, 5 Dec 2024 21:28:51 +0100 Subject: [PATCH 04/44] I said green --- pkg/alertmanager/alertmanager.go | 1 + 1 file changed, 1 insertion(+) create mode 100644 pkg/alertmanager/alertmanager.go diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go new file mode 100644 index 00000000..58f40e16 --- /dev/null +++ b/pkg/alertmanager/alertmanager.go @@ -0,0 +1 @@ +package alertmanager From bc2aef816f3e32ea6f3125faea89d619cf70ea26 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Thu, 5 Dec 2024 21:37:12 +0100 Subject: [PATCH 05/44] go mod tidy --- go.mod | 27 +-------------------------- go.sum | 53 ----------------------------------------------------- 2 files changed, 1 insertion(+), 79 deletions(-) diff --git a/go.mod b/go.mod index e15e4dda..b76dca30 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.30.0 golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.32.0 golang.org/x/oauth2 v0.24.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect @@ -96,21 +96,12 @@ require ( github.com/aws/aws-sdk-go v1.50.8 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getsentry/sentry-go v0.25.0 // indirect - github.com/giantswarm/apiextensions/v6 v6.6.0 // indirect github.com/giantswarm/backoff v1.0.0 // indirect - github.com/giantswarm/exporterkit v1.1.0 // indirect github.com/giantswarm/k8sclient/v7 v7.2.0 // indirect - github.com/giantswarm/microendpoint v1.1.0 // indirect github.com/giantswarm/microerror v0.4.1 // indirect - github.com/giantswarm/microkit v1.0.1 // indirect github.com/giantswarm/micrologger v1.1.1 // indirect - github.com/giantswarm/operatorkit/v7 v7.2.0 // indirect - github.com/giantswarm/to v0.4.0 // indirect github.com/giantswarm/versionbundle v1.1.0 // indirect - github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -122,42 +113,26 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/viper v1.19.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sync v0.10.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/resty.v1 v1.12.0 // indirect - k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 8584559c..84ebe85a 100644 --- a/go.sum +++ b/go.sum @@ -84,7 +84,6 @@ github.com/coredns/corefile-migration v1.0.23 h1:Fp4FETmk8sT/IRgnKX2xstC2dL7+Qdc github.com/coredns/corefile-migration v1.0.23/go.mod h1:8HyMhuyzx9RLZp8cRc9Uf3ECpEAafHOFxQWUPqktMQI= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -109,42 +108,24 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= -github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/giantswarm/apiextensions-application v0.6.2 h1:XL86OrpprWl5Wp38EUvUXt3ztTo25+V63oDVlFwDpNg= github.com/giantswarm/apiextensions-application v0.6.2/go.mod h1:8ylqSmDSzFblCppRQTFo8v9s/F6MX6RTusVVoDDfWso= github.com/giantswarm/apiextensions/v6 v6.6.0 h1:qtsZuxsfigUB6xRd/UygQjh3Oaf54uXp+adbtgpCfiI= github.com/giantswarm/apiextensions/v6 v6.6.0/go.mod h1:Wgc2Rx8YAYF2HidjabEvhsj5ADL+RteIC86ofulY+YE= github.com/giantswarm/backoff v1.0.0 h1:1oeTvyPsm1tJrHlSmfxbIWuoCNWPOkWJCb8kfLvE2T0= github.com/giantswarm/backoff v1.0.0/go.mod h1:l/WqbggvG5Ndxxws0LUgVEvP5E82Qj5/PF8SMip/1QM= -github.com/giantswarm/exporterkit v1.1.0 h1:It+tps930KykISVLtwrn9dKq4kVHLk0rnjaQvKHOV0o= -github.com/giantswarm/exporterkit v1.1.0/go.mod h1:nzlgQdEZ29umzo6cY/ggVqSanQumkS0aLU1Kckv2ZSk= github.com/giantswarm/k8sclient/v7 v7.2.0 h1:twh4egNcuTJEH7R/hYVhs8nwEXPlr0u/o9CB1Kv9H9A= github.com/giantswarm/k8sclient/v7 v7.2.0/go.mod h1:kZGRtOqe4vAKXtWm69tsj2Q9CpWlwzpa1uP1lfDtjlE= github.com/giantswarm/k8smetadata v0.25.0 h1:6mKmmm4xHPuBvxDMAkIhU5oj6KJkJSaR2s5esIsnHs4= github.com/giantswarm/k8smetadata v0.25.0/go.mod h1:QiQAyaZnwco1U0lENLF0Kp4bSN4dIPwIlHWEvUo3ES8= -github.com/giantswarm/microendpoint v1.1.0 h1:z2MUbN/BJ5ME92v93TidfV2JjftfOaJa7rKFdPb6vRU= -github.com/giantswarm/microendpoint v1.1.0/go.mod h1:Zpelq95t2I4Pa8Fvaz8/Ttr3xeeCEgEPIilGUzXwXDY= github.com/giantswarm/microerror v0.4.1 h1:WMiD7HQASoUA9lZzPlPK+erCEOJ0uT4cyo18VfCXHD0= github.com/giantswarm/microerror v0.4.1/go.mod h1:URFj0gFCmZihjya6saQCXxslBrgctXb4NsXYHB5JdrI= -github.com/giantswarm/microkit v1.0.1 h1:P5N9ywvaHvwhxx8WXbZ45iqJs31TZvL4rtMv+owdXac= -github.com/giantswarm/microkit v1.0.1/go.mod h1:EiNhNb6i4JQl8EnfVVUqrb3FD7rU8p5QRbR2nqG7iMI= github.com/giantswarm/micrologger v1.1.1 h1:gpu9uq1Vixey20Zo5pra5m/5EsmLrNlTwIgjBoc1jhE= github.com/giantswarm/micrologger v1.1.1/go.mod h1:l84q1WCLdXtPimHoJlgYEAJ3lmLyWbPbHW1ZpV+wPaA= -github.com/giantswarm/operatorkit/v7 v7.2.0 h1:eoKInQ6Ka0NlQEEqjQbmbAFLW/eOjKHkH2+wBs/JuMU= -github.com/giantswarm/operatorkit/v7 v7.2.0/go.mod h1:rvHDLhFd5P2tVx1GbnUTUURWmRWmHI+91M2GPcBEraM= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205162658-e52a672a0f04 h1:59TTWgResI64Xx3Du5xt8ofdD5QiFu0DY6bRLDkIIy0= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205162658-e52a672a0f04/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205181233-1b0048f5eab5 h1:BE38RRya0rIcWlY8JqLuEGRdLM8ReEnmsPAtzj+9UIw= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205181233-1b0048f5eab5/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f h1:+ybaKU8ZTqEgXogpRKIIM1ooeO/eyM4ANbFwHoPXVpY= github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= -github.com/giantswarm/to v0.4.0 h1:x0GjbI94/nxcHztJiRtJzihCjgmUlEOto8RD98VA7WI= -github.com/giantswarm/to v0.4.0/go.mod h1:RTRtw+Dyk6YqoiNBOGLO981BqhibtVwogdaFIMO1y/A= github.com/giantswarm/versionbundle v1.1.0 h1:Fk0UWTMnA56voTh5P/LmLLPbAkEkFE5jKKpVzcMOL1A= github.com/giantswarm/versionbundle v1.1.0/go.mod h1:+sEGkxho1b7UYid1F9+xIAoRWiZ4Wyrh6P5a6hxgtWc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -152,8 +133,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= -github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= @@ -265,8 +244,6 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb h1:fdtb12RMGDBdQwUuWw9SnBWO2kANZGlfh++tIVBYjbU= github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb/go.mod h1:hiZnMmXc9KXNUlvkV2BKFsiWuIFF/fF4wGgYWEjBitI= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -280,8 +257,6 @@ github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISH github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -322,8 +297,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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -366,10 +339,6 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 h1:EFOD/cRfMeq+PCibHddoRTXu8CTN1m8Oj1Tk6eoz8Dw= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23/go.mod h1:1BK0BG3Mz//zeujilvvu3GJ0jnyZwFdT9XjznoPv6kk= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -379,8 +348,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.2 h1:SyoVBXD/r0PntR1rprb90ClI32FSUNOCWqqTatnipHM= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.2/go.mod h1:SvsRXw4m1F2vk7HquU5h475bFpke27mIUswfyw9u3ug= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 h1:SyBTzvFuVshDNjDVALs6+NgOy3qh8/xlAsyqB1SzHbI= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0/go.mod h1:FlcnLo14zQxL6P1yPrV22kYBqyAT0ZRRytv98+B7lBQ= github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I= github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -412,11 +379,6 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -424,25 +386,18 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -451,12 +406,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -794,8 +745,6 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -824,8 +773,6 @@ k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4= k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE= -k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 h1:y0TgWoHaeYEv3L1MfLC+D2WVxyN1fGr6axURHXq+wHE= -k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0/go.mod h1:w6/LjLR3DPQd57vlgvgbpzpuJKsCiily0+OzQI+nyfI= k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= k8s.io/cluster-bootstrap v0.30.3 h1:MgxyxMkpaC6mu0BKWJ8985XCOnKU+eH3Iy+biwtDXRk= From a6b2ccce812feef4edda1844fc33c0ffd9ddb5b6 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Mon, 9 Dec 2024 15:35:49 +0100 Subject: [PATCH 06/44] Add some stuff --- helm/observability-operator/templates/deployment.yaml | 2 ++ main.go | 4 ++++ pkg/alertmanager/alertmanager_test.go | 5 ----- pkg/config/config.go | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/helm/observability-operator/templates/deployment.yaml b/helm/observability-operator/templates/deployment.yaml index de778056..31028517 100644 --- a/helm/observability-operator/templates/deployment.yaml +++ b/helm/observability-operator/templates/deployment.yaml @@ -31,11 +31,13 @@ spec: - --management-cluster-pipeline={{ $.Values.managementCluster.pipeline }} - --management-cluster-region={{ $.Values.managementCluster.region }} # Monitoring configuration + - --alertmanager-secret-name={{ include "alertmanager-secret.name" . }} - --monitoring-enabled={{ $.Values.monitoring.enabled }} - --monitoring-agent={{ $.Values.monitoring.agent }} - --monitoring-sharding-scale-up-series-count={{ $.Values.monitoring.sharding.scaleUpSeriesCount }} - --monitoring-sharding-scale-down-percentage={{ $.Values.monitoring.sharding.scaleDownPercentage }} - --monitoring-wal-truncate-frequency={{ $.Values.monitoring.wal.truncateFrequency }} + - --namespace={{ include "resource.default.namespace" . }} {{- if .Values.monitoring.prometheusVersion }} - --prometheus-version={{ $.Values.monitoring.prometheusVersion }} {{- end }} diff --git a/main.go b/main.go index 82832bd0..60a7ec18 100644 --- a/main.go +++ b/main.go @@ -103,6 +103,10 @@ func main() { flag.StringVar(&conf.ManagementCluster.Region, "management-cluster-region", "", "The region of the management cluster.") // Monitoring configuration flags. + flag.StringVar(&conf.AlertmanagerSecretName, "alertmanager-secret-name", "", + "The name of the secret containing the Alertmanager configuration.") + flag.StringVar(&conf.Namespace, "namespace", "", + "The namespace where the observability-operator is running.") flag.StringVar(&conf.Monitoring.MonitoringAgent, "monitoring-agent", commonmonitoring.MonitoringAgentAlloy, fmt.Sprintf("select monitoring agent to use (%s or %s)", commonmonitoring.MonitoringAgentPrometheus, commonmonitoring.MonitoringAgentAlloy)) flag.BoolVar(&conf.Monitoring.Enabled, "monitoring-enabled", false, diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go index 2da71730..cd0ca731 100644 --- a/pkg/alertmanager/alertmanager_test.go +++ b/pkg/alertmanager/alertmanager_test.go @@ -18,11 +18,6 @@ import ( const alertmanagerAPIPath = "/api/v1/alerts" -type configCompat struct { - TemplateFiles map[string]string `yaml:"template_files"` - AlertmanagerConfig string `yaml:"alertmanager_config"` -} - func TestAlertmanagerConfigLoad(t *testing.T) { const ( //alertmanagerConfigPath = "alertmanager.yaml" diff --git a/pkg/config/config.go b/pkg/config/config.go index 143484ed..9d35cb3c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -12,6 +12,10 @@ type Config struct { SecureMetrics bool EnableHTTP2 bool + AlertmanagerSecretName string + AlertmanagerURL string + Namespace string + ManagementCluster common.ManagementCluster Monitoring monitoring.Config From 5e41fc5ca5e572f740bd81b93a22ce2c5f4ba775 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Mon, 9 Dec 2024 16:06:21 +0100 Subject: [PATCH 07/44] Add alertmanager.Configure --- go.mod | 16 +--- go.sum | 33 +------ main.go | 8 +- pkg/alertmanager/alertmanager.go | 109 +++++++++++++++++++++++ pkg/alertmanager/alertmanager_test.go | 122 ++++++++------------------ pkg/config/config.go | 5 +- pkg/monitoring/config.go | 6 +- 7 files changed, 164 insertions(+), 135 deletions(-) diff --git a/go.mod b/go.mod index 4c91a731..acc16ec0 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/Netflix/go-env v0.1.2 github.com/blang/semver v3.5.1+incompatible github.com/giantswarm/apiextensions-application v0.6.2 - github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f github.com/go-logr/logr v1.4.2 github.com/grafana/grafana-openapi-client-go v0.0.0-20241126111151-59d2d35e24eb github.com/onsi/ginkgo/v2 v2.22.0 @@ -68,7 +67,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.30.0 golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect - golang.org/x/net v0.32.0 + golang.org/x/net v0.32.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect @@ -90,21 +89,12 @@ require ( require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go v1.50.8 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/coreos/go-semver v0.3.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/giantswarm/backoff v1.0.0 // indirect - github.com/giantswarm/k8sclient/v7 v7.2.0 // indirect - github.com/giantswarm/microerror v0.4.1 // indirect - github.com/giantswarm/micrologger v1.1.1 // indirect - github.com/giantswarm/versionbundle v1.1.0 // indirect github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect @@ -113,7 +103,6 @@ require ( github.com/go-openapi/spec v0.21.0 // indirect github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect @@ -133,7 +122,6 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sync v0.10.0 // indirect - gopkg.in/resty.v1 v1.12.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index d01cfafc..8d5cba75 100644 --- a/go.sum +++ b/go.sum @@ -39,12 +39,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Netflix/go-env v0.1.2 h1:0DRoLR9lECQ9Zqvkswuebm3jJ/2enaDX6Ei8/Z+EnK0= @@ -84,8 +80,6 @@ github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/corefile-migration v1.0.23 h1:Fp4FETmk8sT/IRgnKX2xstC2dL7+QdcU+BL5AYIN3Jw= github.com/coredns/corefile-migration v1.0.23/go.mod h1:8HyMhuyzx9RLZp8cRc9Uf3ECpEAafHOFxQWUPqktMQI= -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -98,8 +92,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -114,22 +108,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/giantswarm/apiextensions-application v0.6.2 h1:XL86OrpprWl5Wp38EUvUXt3ztTo25+V63oDVlFwDpNg= github.com/giantswarm/apiextensions-application v0.6.2/go.mod h1:8ylqSmDSzFblCppRQTFo8v9s/F6MX6RTusVVoDDfWso= -github.com/giantswarm/apiextensions/v6 v6.6.0 h1:qtsZuxsfigUB6xRd/UygQjh3Oaf54uXp+adbtgpCfiI= -github.com/giantswarm/apiextensions/v6 v6.6.0/go.mod h1:Wgc2Rx8YAYF2HidjabEvhsj5ADL+RteIC86ofulY+YE= -github.com/giantswarm/backoff v1.0.0 h1:1oeTvyPsm1tJrHlSmfxbIWuoCNWPOkWJCb8kfLvE2T0= -github.com/giantswarm/backoff v1.0.0/go.mod h1:l/WqbggvG5Ndxxws0LUgVEvP5E82Qj5/PF8SMip/1QM= -github.com/giantswarm/k8sclient/v7 v7.2.0 h1:twh4egNcuTJEH7R/hYVhs8nwEXPlr0u/o9CB1Kv9H9A= -github.com/giantswarm/k8sclient/v7 v7.2.0/go.mod h1:kZGRtOqe4vAKXtWm69tsj2Q9CpWlwzpa1uP1lfDtjlE= github.com/giantswarm/k8smetadata v0.25.0 h1:6mKmmm4xHPuBvxDMAkIhU5oj6KJkJSaR2s5esIsnHs4= github.com/giantswarm/k8smetadata v0.25.0/go.mod h1:QiQAyaZnwco1U0lENLF0Kp4bSN4dIPwIlHWEvUo3ES8= -github.com/giantswarm/microerror v0.4.1 h1:WMiD7HQASoUA9lZzPlPK+erCEOJ0uT4cyo18VfCXHD0= -github.com/giantswarm/microerror v0.4.1/go.mod h1:URFj0gFCmZihjya6saQCXxslBrgctXb4NsXYHB5JdrI= -github.com/giantswarm/micrologger v1.1.1 h1:gpu9uq1Vixey20Zo5pra5m/5EsmLrNlTwIgjBoc1jhE= -github.com/giantswarm/micrologger v1.1.1/go.mod h1:l84q1WCLdXtPimHoJlgYEAJ3lmLyWbPbHW1ZpV+wPaA= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f h1:+ybaKU8ZTqEgXogpRKIIM1ooeO/eyM4ANbFwHoPXVpY= -github.com/giantswarm/prometheus-meta-operator/v2 v2.4.1-0.20241205182541-c7a492eb2f8f/go.mod h1:Ci/KHZMSfSGBRbeRcZn4lbD3SmaX7tMMR1h1nGLX0rI= -github.com/giantswarm/versionbundle v1.1.0 h1:Fk0UWTMnA56voTh5P/LmLLPbAkEkFE5jKKpVzcMOL1A= -github.com/giantswarm/versionbundle v1.1.0/go.mod h1:+sEGkxho1b7UYid1F9+xIAoRWiZ4Wyrh6P5a6hxgtWc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -141,8 +121,8 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -171,8 +151,6 @@ github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= @@ -488,7 +466,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -747,8 +724,6 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go index 4ff48562..c3906bd7 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,8 @@ func main() { "If set the metrics endpoint is served securely") flag.BoolVar(&conf.EnableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") + flag.StringVar(&conf.Namespace, "namespace", "", + "The namespace where the observability-operator is running.") // Management cluster configuration flags. flag.StringVar(&conf.ManagementCluster.BaseDomain, "management-cluster-base-domain", "", @@ -90,10 +92,10 @@ func main() { "The region of the management cluster.") // Monitoring configuration flags. - flag.StringVar(&conf.AlertmanagerSecretName, "alertmanager-secret-name", "", + flag.StringVar(&conf.Monitoring.AlertmanagerSecretName, "alertmanager-secret-name", "", "The name of the secret containing the Alertmanager configuration.") - flag.StringVar(&conf.Namespace, "namespace", "", - "The namespace where the observability-operator is running.") + flag.StringVar(&conf.Monitoring.AlertmanagerURL, "alertmanager-url", "", + "The URL of the Alertmanager API.") flag.StringVar(&conf.Monitoring.MonitoringAgent, "monitoring-agent", commonmonitoring.MonitoringAgentAlloy, fmt.Sprintf("select monitoring agent to use (%s or %s)", commonmonitoring.MonitoringAgentPrometheus, commonmonitoring.MonitoringAgentAlloy)) flag.BoolVar(&conf.Monitoring.Enabled, "monitoring-enabled", false, diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 58f40e16..878f5432 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -1 +1,110 @@ package alertmanager + +import ( + "bytes" + "context" + "fmt" + "net/http" + "strings" + + "github.com/pkg/errors" + "github.com/prometheus/alertmanager/config" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/yaml" + + pkgconfig "github.com/giantswarm/observability-operator/pkg/config" +) + +const ( + alertmanagerConfigKey = "alertmanager.yaml" + notificationTemplateKey = "notification-template.tmpl" + + orgIDHeader = "X-Scope-OrgID" + alertmanagerAPIPath = "/api/v1/alerts" +) + +type Job struct { + client client.Client + alertmanagerURL string +} + +type configRequest struct { + TemplateFiles map[string]string `yaml:"template_files"` + AlertmanagerConfig string `yaml:"alertmanager_config"` +} + +func New(conf pkgconfig.Config) Job { + job := Job{ + alertmanagerURL: strings.TrimSuffix(conf.Monitoring.AlertmanagerURL, "/"), + } + + return job +} + +func (j Job) Configure(ctx context.Context, conf pkgconfig.Config) error { + //TODO: get this from somewhere + tenantID := "anonymous" + + // Read alertmanager configuration source from the secret. + alertmanagerSecret := v1.Secret{} + err := j.client.Get(ctx, types.NamespacedName{Name: conf.Monitoring.AlertmanagerSecretName, Namespace: conf.Namespace}, &alertmanagerSecret) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to get secret: %w", err)) + } + + alertmanagerConfigContent, ok := alertmanagerSecret.Data[alertmanagerConfigKey] + if !ok { + return errors.WithStack(fmt.Errorf("alertmanager: config not found")) + } + + notificationTemplateContent, ok := alertmanagerSecret.Data[notificationTemplateKey] + if !ok { + return errors.WithStack(fmt.Errorf("alertmanager: notification template not found")) + } + + return j.configure(ctx, alertmanagerConfigContent, notificationTemplateContent, tenantID, conf) +} + +func (j Job) configure(ctx context.Context, alertmanagerConfigContent, notificationTemplateContent []byte, tenantID string, conf pkgconfig.Config) error { + // Load alertmanager configuration + alertmanagerConfig, err := config.Load(string(alertmanagerConfigContent)) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to load configuration: %w", err)) + } + + // Set notification template name + // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: + // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path + alertmanagerConfig.Templates = []string{notificationTemplateKey} + + // Prepare request for Alertmanager API + requestData := configRequest{ + AlertmanagerConfig: string(alertmanagerConfig.String()), + TemplateFiles: map[string]string{ + notificationTemplateKey: string(notificationTemplateContent), + }, + } + data, err := yaml.Marshal(requestData) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to marshal yaml: %w", err)) + } + + // Send request to Alertmanager's API + req, err := http.NewRequest(http.MethodPost, j.alertmanagerURL+alertmanagerAPIPath, bytes.NewBuffer(data)) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to create request: %w", err)) + } + req.Header.Set(orgIDHeader, tenantID) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to send request: %w", err)) + } + defer resp.Body.Close() + + //TODO: handle response errors if any + + return nil +} diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go index cd0ca731..03dd7cd5 100644 --- a/pkg/alertmanager/alertmanager_test.go +++ b/pkg/alertmanager/alertmanager_test.go @@ -4,105 +4,59 @@ package alertmanager import ( - "bytes" - "io" - "net/http" - "path/filepath" + "context" "testing" - "github.com/giantswarm/prometheus-meta-operator/v2/service/controller/resource/alerting/alertmanagerconfig" - "github.com/prometheus/alertmanager/config" - "golang.org/x/net/http/httpproxy" - "gopkg.in/yaml.v2" + pkgconfig "github.com/giantswarm/observability-operator/pkg/config" + "github.com/giantswarm/observability-operator/pkg/monitoring" ) -const alertmanagerAPIPath = "/api/v1/alerts" - func TestAlertmanagerConfigLoad(t *testing.T) { const ( - //alertmanagerConfigPath = "alertmanager.yaml" - templatePath = "notification-template.tmpl" - - // Mimir Alertmanager URL and path - alertmanagerURL = "http://localhost:8080/api/v1/alerts" + // Mimir Alertmanager URL + alertmanagerURL = "http://localhost:8080/" - tenandID = "anonymous" + tenantID = "anonymous" ) - // Use alertmanagerconfig.Resource from prometheus-meta-operator - // Re-using the same template files and rendering logic to ensure same config are generated. - c := alertmanagerconfig.Config{ - BaseDomain: "http://base", - GrafanaAddress: "http://grafana", - Installation: "test-installation", - MimirEnabled: true, - OpsgenieKey: "opsgenie-key", - Pipeline: "test", - Proxy: httpproxy.FromEnvironment().ProxyFunc(), - SlackApiToken: "slack-token", - SlackApiURL: "http://slack", - } - r, err := alertmanagerconfig.New(c) - if err != nil { - t.Fatalf("Error instantiating resource: %v", err) + c := pkgconfig.Config{ + Monitoring: monitoring.Config{ + AlertmanagerURL: alertmanagerURL, + }, } + job := New(c) - // Render alertmanager config - alertmanagerContent, err := r.RenderAlertmanagerConfig() - //alertmanagerContent, err := os.ReadFile(alertmanagerConfigPath) - if err != nil { - t.Fatalf("Error rendering config: %v", err) - } + // BaseDomain: "http://base", + // GrafanaAddress: "http://grafana", + // Installation: "test-installation", + // MimirEnabled: true, + // OpsgenieKey: "opsgenie-key", + // Pipeline: "test", + // Proxy: httpproxy.FromEnvironment().ProxyFunc(), + // SlackApiToken: "slack-token", + // SlackApiURL: "http://slack", - // Ensure template name in alertmanager config is a name and not a path, this is to avoid following error: - // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path - templateBase := filepath.Base(templatePath) - alertmanagerConfig, err := config.Load(string(alertmanagerContent)) - if err != nil { - t.Fatalf("Error loading config: %v", err) - } - alertmanagerConfig.Templates = []string{templateBase} - alertmanagerConfigString := alertmanagerConfig.String() + // Read alertmanager config + //alertmanagerContent, err := os.ReadFile(alertmanagerConfigPath) + //if err != nil { + // t.Fatalf("Error reading config: %v", err) + //} + alertmanagerContent := "" - // Render alertmanager template - alertmanagerTemplate, err := r.RenderNotificationTemplate() + // Read alertmanager template //alertmanagerTemplate, err := os.ReadFile(templatePath) - if err != nil { - t.Fatalf("Error rendering template: %v", err) - } + //if err != nil { + // t.Fatalf("Error reading template: %v", err) + //} + alertmanagerTemplate := "" - t.Logf("config: %d, template: %d\n", len(alertmanagerConfigString), len(alertmanagerTemplate)) - - // Prepare request for Alertmanager API - compact := configCompat{ - AlertmanagerConfig: string(alertmanagerConfigString), - TemplateFiles: map[string]string{ - templateBase: string(alertmanagerTemplate), - }, - } - data, err := yaml.Marshal(compact) - if err != nil { - t.Fatalf("Error marshalling yaml: %v", err) - } - - // Send request to Alertmanager API - req, err := http.NewRequest("POST", alertmanagerURL, bytes.NewBuffer(data)) - //req, err := http.NewRequest("DELETE", "http://localhost:8080/api/v1/alerts", nil) - if err != nil { - t.Fatalf("Error creating request: %v", err) - } - req.Header.Set("X-Scope-OrgID", tenandID) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("Error sending request: %v", err) - } - defer resp.Body.Close() + job.configure(context.TODO(), []byte(alertmanagerContent), []byte(alertmanagerTemplate), tenantID, c) + t.Logf("config: %d, template: %d\n", len(alertmanagerContent), len(alertmanagerTemplate)) // Debug response - respData, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatalf("Error reading response: %v", err) - } - t.Logf("response: %d %s\n", resp.StatusCode, respData) + //respData, err := io.ReadAll(resp.Body) + //if err != nil { + // t.Fatalf("Error reading response: %v", err) + //} + //t.Logf("response: %d %s\n", resp.StatusCode, respData) } diff --git a/pkg/config/config.go b/pkg/config/config.go index f8b1ccab..8589614e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -11,10 +11,7 @@ type Config struct { ProbeAddr string SecureMetrics bool EnableHTTP2 bool - - AlertmanagerSecretName string - AlertmanagerURL string - Namespace string + Namespace string ManagementCluster common.ManagementCluster diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go index fdc32883..6ed9b006 100644 --- a/pkg/monitoring/config.go +++ b/pkg/monitoring/config.go @@ -13,7 +13,11 @@ const MonitoringLabel = "giantswarm.io/monitoring" // Config represents the configuration used by the monitoring package. type Config struct { - Enabled bool + Enabled bool + + AlertmanagerSecretName string + AlertmanagerURL string + MonitoringAgent string DefaultShardingStrategy sharding.Strategy // WALTruncateFrequency is the frequency at which the WAL segments should be truncated. From 707b23ac1374b180054828253c8053c234ccc704 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 09:25:58 +0100 Subject: [PATCH 08/44] setup logger before loading env vars --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index c3906bd7..2511ebc7 100644 --- a/main.go +++ b/main.go @@ -115,6 +115,8 @@ func main() { opts.BindFlags(flag.CommandLine) flag.Parse() + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + // Load environment variables. _, err := env.UnmarshalFromEnviron(&conf.Environment) if err != nil { @@ -122,8 +124,6 @@ func main() { os.Exit(1) } - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - // if the enable-http2 flag is false (the default), http/2 should be disabled // due to its vulnerabilities. More specifically, disabling http/2 will // prevent from being vulnerable to the HTTP/2 Stream Cancelation and From 3776e728df139eea50831c4793cb2881bc97c6bd Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 09:34:25 +0100 Subject: [PATCH 09/44] Retrive all templates by suffix --- pkg/alertmanager/alertmanager.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 878f5432..57fa6065 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "maps" "net/http" "strings" @@ -18,8 +19,11 @@ import ( ) const ( - alertmanagerConfigKey = "alertmanager.yaml" - notificationTemplateKey = "notification-template.tmpl" + // Those values are used to retrieve the Alertmanager configuration from the secret named after conf.Monitoring.AlertmanagerSecretName + // alertmanagerConfigKey is the key to the alertmanager configuration in the secret + alertmanagerConfigKey = "alertmanager.yaml" + // templatesSuffix is the suffix used to identify the templates in the secret + templatesSuffix = ".tmpl" orgIDHeader = "X-Scope-OrgID" alertmanagerAPIPath = "/api/v1/alerts" @@ -47,27 +51,31 @@ func (j Job) Configure(ctx context.Context, conf pkgconfig.Config) error { //TODO: get this from somewhere tenantID := "anonymous" - // Read alertmanager configuration source from the secret. + // Read secret used as source for Alertmanager configuration alertmanagerSecret := v1.Secret{} err := j.client.Get(ctx, types.NamespacedName{Name: conf.Monitoring.AlertmanagerSecretName, Namespace: conf.Namespace}, &alertmanagerSecret) if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to get secret: %w", err)) } + // Retrieve Alertmanager configuration from secret alertmanagerConfigContent, ok := alertmanagerSecret.Data[alertmanagerConfigKey] if !ok { return errors.WithStack(fmt.Errorf("alertmanager: config not found")) } - notificationTemplateContent, ok := alertmanagerSecret.Data[notificationTemplateKey] - if !ok { - return errors.WithStack(fmt.Errorf("alertmanager: notification template not found")) + // Retrieve all alertmanager templates from secret + templates := make(map[string]string) + for key, value := range alertmanagerSecret.Data { + if strings.HasSuffix(key, templatesSuffix) { + templates[key] = string(value) + } } - return j.configure(ctx, alertmanagerConfigContent, notificationTemplateContent, tenantID, conf) + return j.configure(ctx, alertmanagerConfigContent, templates, tenantID, conf) } -func (j Job) configure(ctx context.Context, alertmanagerConfigContent, notificationTemplateContent []byte, tenantID string, conf pkgconfig.Config) error { +func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, templates map[string]string, tenantID string, conf pkgconfig.Config) error { // Load alertmanager configuration alertmanagerConfig, err := config.Load(string(alertmanagerConfigContent)) if err != nil { @@ -77,14 +85,12 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent, notificat // Set notification template name // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path - alertmanagerConfig.Templates = []string{notificationTemplateKey} + alertmanagerConfig.Templates = maps.Collect(maps.Keys(templates)) // Prepare request for Alertmanager API requestData := configRequest{ AlertmanagerConfig: string(alertmanagerConfig.String()), - TemplateFiles: map[string]string{ - notificationTemplateKey: string(notificationTemplateContent), - }, + TemplateFiles: templates, } data, err := yaml.Marshal(requestData) if err != nil { From 3e6e2f98a35b7c666d46f2d93f21146edc6a0c77 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 09:48:47 +0100 Subject: [PATCH 10/44] Fix maps > slices.Collect --- pkg/alertmanager/alertmanager.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 57fa6065..af41d65f 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -6,6 +6,7 @@ import ( "fmt" "maps" "net/http" + "slices" "strings" "github.com/pkg/errors" @@ -85,7 +86,7 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te // Set notification template name // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path - alertmanagerConfig.Templates = maps.Collect(maps.Keys(templates)) + alertmanagerConfig.Templates = slices.Collect(maps.Keys(templates)) // Prepare request for Alertmanager API requestData := configRequest{ From d8a3026eeada004e296690668cc578f22a61c3db Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 11:36:22 +0100 Subject: [PATCH 11/44] Fix test --- pkg/alertmanager/alertmanager_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go index 03dd7cd5..35d0eeb2 100644 --- a/pkg/alertmanager/alertmanager_test.go +++ b/pkg/alertmanager/alertmanager_test.go @@ -50,7 +50,11 @@ func TestAlertmanagerConfigLoad(t *testing.T) { //} alertmanagerTemplate := "" - job.configure(context.TODO(), []byte(alertmanagerContent), []byte(alertmanagerTemplate), tenantID, c) + templates := map[string]string{ + "notification-template.tmpl": alertmanagerTemplate, + } + + job.configure(context.TODO(), []byte(alertmanagerContent), templates, tenantID, c) t.Logf("config: %d, template: %d\n", len(alertmanagerContent), len(alertmanagerTemplate)) // Debug response From b1606599181be5522dffab591e71a8a4073c425b Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 11:54:55 +0100 Subject: [PATCH 12/44] Remove test --- pkg/alertmanager/alertmanager_test.go | 66 --------------------------- 1 file changed, 66 deletions(-) delete mode 100644 pkg/alertmanager/alertmanager_test.go diff --git a/pkg/alertmanager/alertmanager_test.go b/pkg/alertmanager/alertmanager_test.go deleted file mode 100644 index 35d0eeb2..00000000 --- a/pkg/alertmanager/alertmanager_test.go +++ /dev/null @@ -1,66 +0,0 @@ -//go:build integration -// +build integration - -package alertmanager - -import ( - "context" - "testing" - - pkgconfig "github.com/giantswarm/observability-operator/pkg/config" - "github.com/giantswarm/observability-operator/pkg/monitoring" -) - -func TestAlertmanagerConfigLoad(t *testing.T) { - const ( - // Mimir Alertmanager URL - alertmanagerURL = "http://localhost:8080/" - - tenantID = "anonymous" - ) - - c := pkgconfig.Config{ - Monitoring: monitoring.Config{ - AlertmanagerURL: alertmanagerURL, - }, - } - job := New(c) - - // BaseDomain: "http://base", - // GrafanaAddress: "http://grafana", - // Installation: "test-installation", - // MimirEnabled: true, - // OpsgenieKey: "opsgenie-key", - // Pipeline: "test", - // Proxy: httpproxy.FromEnvironment().ProxyFunc(), - // SlackApiToken: "slack-token", - // SlackApiURL: "http://slack", - - // Read alertmanager config - //alertmanagerContent, err := os.ReadFile(alertmanagerConfigPath) - //if err != nil { - // t.Fatalf("Error reading config: %v", err) - //} - alertmanagerContent := "" - - // Read alertmanager template - //alertmanagerTemplate, err := os.ReadFile(templatePath) - //if err != nil { - // t.Fatalf("Error reading template: %v", err) - //} - alertmanagerTemplate := "" - - templates := map[string]string{ - "notification-template.tmpl": alertmanagerTemplate, - } - - job.configure(context.TODO(), []byte(alertmanagerContent), templates, tenantID, c) - t.Logf("config: %d, template: %d\n", len(alertmanagerContent), len(alertmanagerTemplate)) - - // Debug response - //respData, err := io.ReadAll(resp.Body) - //if err != nil { - // t.Fatalf("Error reading response: %v", err) - //} - //t.Logf("response: %d %s\n", resp.StatusCode, respData) -} From b32a6de5f8c08bb5cf6b2741d4ac07a4d7afd122 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 12:27:32 +0100 Subject: [PATCH 13/44] go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index acc16ec0..aa64ede3 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/prometheus/common v0.61.0 github.com/sirupsen/logrus v1.9.3 - gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.31.3 k8s.io/apimachinery v0.31.3 k8s.io/client-go v0.31.3 @@ -122,6 +121,7 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sync v0.10.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) replace ( From 2023dc7b27c4e31cb38c9c13ac828a6f054a19bf Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 12:56:53 +0100 Subject: [PATCH 14/44] fix linting errors --- pkg/alertmanager/alertmanager.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index af41d65f..a3ba0449 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -73,10 +73,10 @@ func (j Job) Configure(ctx context.Context, conf pkgconfig.Config) error { } } - return j.configure(ctx, alertmanagerConfigContent, templates, tenantID, conf) + return j.configure(alertmanagerConfigContent, templates, tenantID) } -func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, templates map[string]string, tenantID string, conf pkgconfig.Config) error { +func (j Job) configure(alertmanagerConfigContent []byte, templates map[string]string, tenantID string) error { // Load alertmanager configuration alertmanagerConfig, err := config.Load(string(alertmanagerConfigContent)) if err != nil { @@ -90,7 +90,7 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te // Prepare request for Alertmanager API requestData := configRequest{ - AlertmanagerConfig: string(alertmanagerConfig.String()), + AlertmanagerConfig: alertmanagerConfig.String(), TemplateFiles: templates, } data, err := yaml.Marshal(requestData) @@ -109,7 +109,7 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to send request: %w", err)) } - defer resp.Body.Close() + defer resp.Body.Close() // nolint: errcheck //TODO: handle response errors if any From dfec94d4001a87b5b32f940982ee98675d4bb726 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 16:25:01 +0100 Subject: [PATCH 15/44] Add alertmanager helm helpers --- .../templates/alertmanager/_helpers.tpl | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 helm/observability-operator/templates/alertmanager/_helpers.tpl diff --git a/helm/observability-operator/templates/alertmanager/_helpers.tpl b/helm/observability-operator/templates/alertmanager/_helpers.tpl new file mode 100644 index 00000000..ee6fb834 --- /dev/null +++ b/helm/observability-operator/templates/alertmanager/_helpers.tpl @@ -0,0 +1,5 @@ +{{/* vim: set filetype=mustache: */}} + +{{- define "alertmanager-secret.name" -}} +{{- include "resource.default.name" . -}}-alertmanager +{{- end }} From 4e89889b901d2b098d39defe05cf2f73bc26ed7a Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 16:40:14 +0100 Subject: [PATCH 16/44] Wire Alertmanager into GrafanaOrganization controller --- .../grafanaorganization_controller.go | 33 ++++++++++++------- main.go | 2 +- pkg/alertmanager/alertmanager.go | 15 ++++++--- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/internal/controller/grafanaorganization_controller.go b/internal/controller/grafanaorganization_controller.go index c04c1d80..0eadbe69 100644 --- a/internal/controller/grafanaorganization_controller.go +++ b/internal/controller/grafanaorganization_controller.go @@ -38,6 +38,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" + "github.com/giantswarm/observability-operator/pkg/alertmanager" "github.com/giantswarm/observability-operator/pkg/config" grafanaclient "github.com/giantswarm/observability-operator/pkg/grafana/client" @@ -50,27 +51,28 @@ import ( // GrafanaOrganizationReconciler reconciles a GrafanaOrganization object type GrafanaOrganizationReconciler struct { client.Client - Scheme *runtime.Scheme - GrafanaAPI *grafanaAPI.GrafanaHTTPAPI + Scheme *runtime.Scheme + GrafanaAPI *grafanaAPI.GrafanaHTTPAPI + AlertmanagerJob alertmanager.Job } -func SetupGrafanaOrganizationReconciler(mgr manager.Manager, environment config.Environment) error { +func SetupGrafanaOrganizationReconciler(mgr manager.Manager, conf config.Config) error { // Generate Grafana client // Get grafana admin-password and admin-user grafanaAdminCredentials := grafanaclient.AdminCredentials{ - Username: environment.GrafanaAdminUsername, - Password: environment.GrafanaAdminPassword, + Username: conf.Environment.GrafanaAdminUsername, + Password: conf.Environment.GrafanaAdminPassword, } if grafanaAdminCredentials.Username == "" { - return fmt.Errorf("GrafanaAdminUsername not set: %q", environment.GrafanaAdminUsername) + return fmt.Errorf("GrafanaAdminUsername not set: %q", conf.Environment.GrafanaAdminUsername) } if grafanaAdminCredentials.Password == "" { - return fmt.Errorf("GrafanaAdminPassword not set: %q", environment.GrafanaAdminPassword) + return fmt.Errorf("GrafanaAdminPassword not set: %q", conf.Environment.GrafanaAdminPassword) } grafanaTLSConfig := grafanaclient.TLSConfig{ - Cert: environment.GrafanaTLSCertFile, - Key: environment.GrafanaTLSKeyFile, + Cert: conf.Environment.GrafanaTLSCertFile, + Key: conf.Environment.GrafanaTLSKeyFile, } grafanaAPI, err := grafanaclient.GenerateGrafanaClient(grafanaAdminCredentials, grafanaTLSConfig) if err != nil { @@ -78,9 +80,10 @@ func SetupGrafanaOrganizationReconciler(mgr manager.Manager, environment config. } r := &GrafanaOrganizationReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - GrafanaAPI: grafanaAPI, + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + GrafanaAPI: grafanaAPI, + AlertmanagerJob: alertmanager.New(conf), } err = r.SetupWithManager(mgr) @@ -181,6 +184,12 @@ func (r GrafanaOrganizationReconciler) reconcileCreate(ctx context.Context, graf return ctrl.Result{}, nil } + // Configure Alertmanager + err := r.AlertmanagerJob.Configure(ctx) + if err != nil { + return ctrl.Result{}, errors.WithStack(err) + } + // Configure the shared organization in Grafana if err := r.configureSharedOrg(ctx); err != nil { return ctrl.Result{}, errors.WithStack(err) diff --git a/main.go b/main.go index 2511ebc7..e1efa6b4 100644 --- a/main.go +++ b/main.go @@ -183,7 +183,7 @@ func main() { } // Setup controller for the GrafanaOrganization resource. - err = controller.SetupGrafanaOrganizationReconciler(mgr, conf.Environment) + err = controller.SetupGrafanaOrganizationReconciler(mgr, conf) if err != nil { setupLog.Error(err, "unable to setup controller", "controller", "GrafanaOrganizationReconciler") os.Exit(1) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index a3ba0449..64560d52 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -12,7 +12,6 @@ import ( "github.com/pkg/errors" "github.com/prometheus/alertmanager/config" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" @@ -31,8 +30,9 @@ const ( ) type Job struct { - client client.Client - alertmanagerURL string + client client.Client + alertmanagerURL string + alertmanagerSecret client.ObjectKey } type configRequest struct { @@ -43,18 +43,23 @@ type configRequest struct { func New(conf pkgconfig.Config) Job { job := Job{ alertmanagerURL: strings.TrimSuffix(conf.Monitoring.AlertmanagerURL, "/"), + alertmanagerSecret: client.ObjectKey{ + Name: conf.Monitoring.AlertmanagerSecretName, + Namespace: conf.Namespace, + }, } return job } -func (j Job) Configure(ctx context.Context, conf pkgconfig.Config) error { +func (j Job) Configure(ctx context.Context) error { //TODO: get this from somewhere tenantID := "anonymous" // Read secret used as source for Alertmanager configuration alertmanagerSecret := v1.Secret{} - err := j.client.Get(ctx, types.NamespacedName{Name: conf.Monitoring.AlertmanagerSecretName, Namespace: conf.Namespace}, &alertmanagerSecret) + err := j.client.Get(ctx, j.alertmanagerSecret, &alertmanagerSecret) + if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to get secret: %w", err)) } From cebac348f924e1e643f87f0139a5a9432930f5bd Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 17:04:34 +0100 Subject: [PATCH 17/44] Set the client --- internal/controller/grafanaorganization_controller.go | 2 +- pkg/alertmanager/alertmanager.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/controller/grafanaorganization_controller.go b/internal/controller/grafanaorganization_controller.go index 513fc903..9e3b6f83 100644 --- a/internal/controller/grafanaorganization_controller.go +++ b/internal/controller/grafanaorganization_controller.go @@ -83,7 +83,7 @@ func SetupGrafanaOrganizationReconciler(mgr manager.Manager, conf config.Config) Client: mgr.GetClient(), Scheme: mgr.GetScheme(), GrafanaAPI: grafanaAPI, - AlertmanagerJob: alertmanager.New(conf), + AlertmanagerJob: alertmanager.New(conf, mgr.GetClient()), } err = r.SetupWithManager(mgr) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 64560d52..d0021a2c 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -40,8 +40,9 @@ type configRequest struct { AlertmanagerConfig string `yaml:"alertmanager_config"` } -func New(conf pkgconfig.Config) Job { +func New(conf pkgconfig.Config, c client.Client) Job { job := Job{ + client: c, alertmanagerURL: strings.TrimSuffix(conf.Monitoring.AlertmanagerURL, "/"), alertmanagerSecret: client.ObjectKey{ Name: conf.Monitoring.AlertmanagerSecretName, From 171b62af9b24b5636c39bf7793800e7a434448d5 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 09:41:51 +0100 Subject: [PATCH 18/44] Add Alertmanager config and templates in Helm chart - Add secret resource, embedding raw and templated alertmanager files - Expose alertmanager templates values as helm chart values - Remove all Mimir related conditions - Split template into url and notification templates - Drop template directive, dynamically set by the operator - Escape template in template - Re-use slack actions --- .../files/alertmanager/alertmanager.yaml.tpl | 504 ++++++++++++++++++ .../alertmanager/notification-template.tmpl | 64 +++ .../files/alertmanager/url-template.tmpl.tpl | 18 + .../templates/alertmanager/_helpers.tpl | 5 + .../templates/alertmanager/secret.yaml | 20 + helm/observability-operator/values.yaml | 9 + 6 files changed, 620 insertions(+) create mode 100644 helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl create mode 100644 helm/observability-operator/files/alertmanager/notification-template.tmpl create mode 100644 helm/observability-operator/files/alertmanager/url-template.tmpl.tpl create mode 100644 helm/observability-operator/templates/alertmanager/_helpers.tpl create mode 100644 helm/observability-operator/templates/alertmanager/secret.yaml diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl b/helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl new file mode 100644 index 00000000..743d0ba0 --- /dev/null +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl @@ -0,0 +1,504 @@ +global: + resolve_timeout: 5m +{{- if .ProxyURL }} + http_config: + proxy_url: {{ .ProxyURL }} +{{- end }} +{{- if .SlackApiToken }} + slack_api_url: "https://slack.com/api/chat.postMessage" +{{- else }} + slack_api_url: {{ .SlackApiURL }} +{{- end }} + +route: + group_by: [alertname, cluster_id, installation, status, team] + group_interval: 15m + group_wait: 5m + repeat_interval: 4h + receiver: root + + routes: + - receiver: heartbeat + matchers: + - alertname="Heartbeat" + # TODO(@team-atlas): This label is needed for now because we support legacy and new heartbeat alerts. Lets remove it when we remove https://github.com/giantswarm/prometheus-rules/pull/1094/files#diff-2cc8f3328e242b6c86769bfb52b286c7146e074dd244ebb76a0025c838f33d0fR21 + - type="mimir-heartbeat" + continue: true + group_wait: 30s + group_interval: 30s + repeat_interval: 15m + {{- if eq .Pipeline "stable-testing" }} + - receiver: blackhole + matchers: + - cluster_type="workload_cluster" + continue: false + - receiver: blackhole + matchers: + - cluster_id=~"t-.*" + continue: false + - receiver: blackhole + matchers: + - alertname=~"WorkloadClusterApp.*" + continue: false + - receiver: blackhole + matchers: + - alertname="PrometheusMetaOperatorReconcileErrors" + continue: false + - receiver: blackhole + matchers: + - alertname="ClusterUnhealthyPhase" + continue: false + - receiver: blackhole + matchers: + - alertname="ClusterUnhealthyPhase" + - name=~"t-.*" + continue: false + # We don't want to get alerts by workload cluster apps that are failing. + # We select those by checking if the App CR is in a namespace starting with 'org-'. + - receiver: blackhole + matchers: + - alertname="ManagementClusterAppFailed" + - namespace=~"org-.*" + continue: false + {{- end }} + + # Falco noise Slack + - receiver: falco_noise_slack + matchers: + - alertname=~"Falco.*" + continue: false + + - receiver: team_tenet_slack + repeat_interval: 14d + matchers: + - severity=~"page|notify" + - team=~"tenet|tinkerers" + continue: false + + # Team Ops Opsgenie + - receiver: opsgenie_router + matchers: + - severity="page" + continue: true + + # Team Atlas Slack + - receiver: team_atlas_slack + matchers: + {{- if eq .Pipeline "stable" }} + - severity="notify" + {{- else }} + - severity=~"page|notify" + {{- end }} + - team="atlas" + - type!="heartbeat" + - alertname!~"Inhibition.*" + - alertname!="Heartbeat" + continue: false + + # Team Celestial Slack + - receiver: team_phoenix_slack + matchers: + - severity=~"page|notify" + - team="celestial" + - sloth_severity=~"page|ticket" + continue: false + + # Team Firecracker Slack + - receiver: team_phoenix_slack + matchers: + - severity=~"page|notify" + - team="firecracker" + - sloth_severity=~"page|ticket" + continue: false + + # Team Phoenix Slack + - receiver: team_phoenix_slack + matchers: + - team="phoenix" + - sloth_severity="page" + - silence="true" + continue: false + + # Team Shield Slack + - receiver: team_shield_slack + matchers: + - severity=~"page|notify" + - team="shield" + continue: false + + # Team BigMac Slack + - receiver: team_bigmac_slack + matchers: + - severity=~"page|notify" + - team="bigmac" + continue: false + + # Team Clippy Slack + # ReRoute to `phoenix` until we change all team ownership labels + - receiver: team_phoenix_slack + matchers: + - severity=~"page|notify" + - team="clippy" + continue: false + + # Team Rocket Slack + - receiver: team_rocket_slack + matchers: + - severity=~"page|notify" + - team="rocket" + continue: false + + # Team Turtles Slack + - receiver: team_turtles_slack + matchers: + - severity=~"page|notify" + - team="turtles" + continue: false + + # Team Honeybadger Slack + - receiver: team_honeybadger_slack + matchers: + - severity=~"page|notify" + - team="honeybadger" + continue: false + +receivers: +- name: root + +- name: heartbeat + webhook_configs: + - send_resolved: false + http_config: + authorization: + type: GenieKey + credentials: {{ .OpsgenieKey }} + follow_redirects: true + enable_http2: true + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + url: https://api.opsgenie.com/v2/heartbeats/{{ .Installation }}/ping + +{{- if eq .Pipeline "stable-testing" }} +- name: blackhole +{{- end }} + +- name: falco_noise_slack + slack_configs: + - channel: '#noise-falco' + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: &slack-actions + - type: button + text: ':green_book: OpsRecipe' + url: {{`{{ template "__runbookurl" . }}`}} + style: {{`{{ if eq .Status "firing" }}primary{{ else }}default{{ end }}`}} + - type: button + text: ':coffin: Linked PMs' + url: {{`{{ template "__alert_linked_postmortems" . }}`}} + - type: button + text: ':mag: Query' + url: {{`{{ template "__alerturl" . }}`}} + - type: button + text: ':grafana: Dashboard' + url: {{`{{ template "__dashboardurl" . }}`}} + - type: button + text: ':no_bell: Silence' + url: {{`{{ template "__alert_silence_link" .}}`}} + style: {{`{{ if eq .Status "firing" }}danger{{ else }}default{{ end }}`}} + +- name: team_atlas_slack + slack_configs: + {{- if eq .Pipeline "stable" }} + - channel: '#alert-atlas' + {{- else }} + - channel: '#alert-atlas-test' + {{- end }} + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_phoenix_slack + slack_configs: + {{- if eq .Pipeline "stable" }} + - channel: '#alert-phoenix' + {{- else }} + - channel: '#alert-phoenix-test' + {{- end }} + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_bigmac_slack + slack_configs: + {{- if eq .Pipeline "stable" }} + - channel: '#alert-bigmac' + {{- else }} + - channel: '#alert-bigmac-test' + {{- end }} + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_rocket_slack + slack_configs: + {{- if eq .Pipeline "stable" }} + - channel: '#alert-rocket' + {{- else }} + - channel: '#alert-rocket-test' + {{- end }} + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_shield_slack + slack_configs: + - channel: '#alert-shield' + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_turtles_slack + slack_configs: + {{- if eq .Pipeline "stable" }} + - channel: '#alert-turtles' + {{- else }} + - channel: '#alert-turtles-test' + {{- end }} + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_tenet_slack + slack_configs: + - channel: '#alert-tenet' + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: team_honeybadger_slack + slack_configs: + - channel: '#alert-honeybadger' + {{- if .SlackApiToken }} + http_config: + authorization: + type: Bearer + credentials: {{ .SlackApiToken }} + {{- if .ProxyURL }} + proxy_url: {{ .ProxyURL }} + {{- end }} + {{- end }} + send_resolved: true + actions: *slack-actions + +- name: opsgenie_router + opsgenie_configs: + - api_key: {{ .OpsgenieKey }} + tags: {{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}} + +inhibit_rules: +- source_matchers: + - inhibit_kube_state_metrics_down=true + target_matchers: + - cancel_if_kube_state_metrics_down=true + equal: [cluster_id] + +- source_matchers: + - inhibit_kube_state_metrics_down=true + - cluster_id={{ .Installation }} + target_matchers: + - cancel_if_mc_kube_state_metrics_down=true + +- source_matchers: + - inhibit_kube_state_metrics_down=true + target_matchers: + - cancel_if_any_kube_state_metrics_down=true + +- source_matchers: + - cluster_status_creating=true + target_matchers: + - cancel_if_cluster_status_creating=true + equal: [cluster_id] + +- source_matchers: + - cluster_status_created=true + target_matchers: + - cancel_if_cluster_status_created=true + equal: [cluster_id] + +- source_matchers: + - cluster_status_updating=true + target_matchers: + - cancel_if_cluster_status_updating=true + equal: [cluster_id] + +- source_matchers: + - cluster_status_updated=true + target_matchers: + - cancel_if_cluster_status_updated=true + equal: [cluster_id] + +- source_matchers: + - cluster_status_deleting=true + target_matchers: + - cancel_if_cluster_status_deleting=true + equal: [cluster_id] + +- source_matchers: + - cluster_with_no_nodepools=true + target_matchers: + - cancel_if_cluster_with_no_nodepools=true + equal: [cluster_id] + +- source_matchers: + - cluster_with_scaling_nodepools=true + target_matchers: + - cancel_if_cluster_with_scaling_nodepools=true + equal: [cluster_id] + +- source_matchers: + - cluster_with_notready_nodepools=true + target_matchers: + - cancel_if_cluster_with_notready_nodepools=true + equal: [cluster_id] + +- source_matchers: + - cluster_control_plane_unhealthy=true + target_matchers: + - cancel_if_cluster_control_plane_unhealthy=true + equal: [cluster_id] + +- source_matchers: + - cluster_control_plane_unhealthy=true + target_matchers: + - cancel_if_any_cluster_control_plane_unhealthy=true + +- source_matchers: + - instance_state_not_running=true + target_matchers: + - cancel_if_instance_state_not_running=true + equal: [node] + +- source_matchers: + - kiam_has_errors=true + target_matchers: + - cancel_if_kiam_has_errors=true + equal: [cluster_id] + +- source_matchers: + - kubelet_down=true + target_matchers: + - cancel_if_kubelet_down=true + equal: [cluster_id, ip] + +- source_matchers: + - control_plane_node_down=true + target_matchers: + - cancel_if_control_plane_node_down=true + equal: [cluster_id] + +- source_matchers: + - outside_working_hours=true + target_matchers: + - cancel_if_outside_working_hours=true + +- source_matchers: + - has_worker_nodes=false + target_matchers: + - cancel_if_cluster_has_no_workers=true + equal: [cluster_id] + +- source_matchers: + - cluster_is_not_running_monitoring_agent=true + target_matchers: + - cancel_if_cluster_is_not_running_monitoring_agent=true + equal: [cluster_id] + +- source_matchers: + - inhibit_monitoring_agent_down=true + target_matchers: + - cancel_if_monitoring_agent_down=true + equal: [cluster_id] + +- source_matchers: + - stack_failed=true + target_matchers: + - cancel_if_stack_failed=true + +# Source: https://github.com/giantswarm/prometheus-rules/blob/main/helm/prometheus-rules/templates/kaas/turtles/alerting-rules/inhibit.nodes.rules.yml +- source_matchers: + - node_not_ready=true + target_matchers: + - cancel_if_node_not_ready=true + equal: [cluster_id, node] + +# Source: https://github.com/giantswarm/prometheus-rules/blob/main/helm/prometheus-rules/templates/kaas/turtles/alerting-rules/inhibit.nodes.rules.yml +- source_matchers: + - node_unschedulable=true + target_matchers: + - cancel_if_node_unschedulable=true + equal: [cluster_id, node] diff --git a/helm/observability-operator/files/alertmanager/notification-template.tmpl b/helm/observability-operator/files/alertmanager/notification-template.tmpl new file mode 100644 index 00000000..acc60e21 --- /dev/null +++ b/helm/observability-operator/files/alertmanager/notification-template.tmpl @@ -0,0 +1,64 @@ +{{ define "__alertmanager" }}Alertmanager{{ end }} + +{{ define "slack.default.title" }}{{ .Status | toUpper }}[{{ if eq .Status "firing" }}{{ .Alerts.Firing | len }}{{- else }}{{ .Alerts.Resolved | len }}{{- end }}] {{ (index .Alerts 0).Labels.alertname }} - Team {{ (index .Alerts 0).Labels.team }}{{ end }} +{{ define "slack.default.username" }}{{ template "__alertmanager" . }}{{ end }} +{{ define "slack.default.fallback" }}{{ template "slack.default.title" . }} | {{ template "slack.default.titlelink" . }}{{ end }} +{{ define "slack.default.pretext" }}{{ end }} +{{ define "slack.default.titlelink" }}{{ template "__alerturl" . }}{{ end }} +{{ define "slack.default.iconemoji" }}{{ end }} +{{ define "slack.default.iconurl" }}{{ end }} +{{ define "slack.default.text" }}*Cluster:* {{ (index .Alerts 0).Labels.installation }}{{ if (index .Alerts 0).Labels.cluster_id }} / {{ (index .Alerts 0).Labels.cluster_id }}{{ end }}{{ if (index .Alerts 0).Labels.service }} / {{ (index .Alerts 0).Labels.service }}{{ end }} +*Area:* {{ (index .Alerts 0).Labels.area }} / {{ (index .Alerts 0).Labels.topic }} +{{- if (index .Alerts 0).Annotations.description }} +*Instances* +{{ if eq .Status "firing" }} +{{ range .Alerts.Firing }} +:fire: {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{- end }} +{{ else }} +{{ range .Alerts.Resolved }} +:success: {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{- end }} +{{ end }} +{{- end }} +{{ end }} + +{{ define "opsgenie.default.message" }}{{ .GroupLabels.installation }} / {{ .GroupLabels.cluster_id }}{{ if (index .Alerts 0).Labels.service }} / {{ (index .Alerts 0).Labels.service }}{{ end }} - {{ index (index .Alerts.Firing 0).Labels `alertname`}}{{ end }} +{{ define "opsgenie.default.source" }}{{ template "__alertmanager" . }}{{ end }} +{{ define "opsgenie.default.description" }}* Team: {{ (index .Alerts 0).Labels.team }} +* Area: {{ (index .Alerts 0).Labels.area }} / {{ (index .Alerts 0).Labels.topic }} + +* Instances:{{ range .Alerts.Firing }} +🔥 {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{ end }} + +--- + +{{ if (index .Alerts 0).Annotations.opsrecipe -}} +📗 Runbook: {{ template "__runbookurl" . }} +{{ end -}} +{{ if (index .Alerts 0).Annotations.dashboard -}} +📈 Dashboard: {{ template "__dashboardurl" . }} +{{ end -}} +👀 Explore: {{ template "__queryurl" . }} + +--- + +{{ if not (index .Alerts 0).Annotations.opsrecipe }}⚠️ There is no **runbook** for this alert, time to get your pen.{{- end }} +{{ if not (index .Alerts 0).Annotations.dashboard }}⚠️ There is no **dashboard** for this alert, time to sketch.{{- end }} +{{- end }} + +# This builds the silence URL. We exclude the alertname in the range +# to avoid the issue of having trailing comma separator (%2C) at the end +# of the generated URL +{{ define "__alert_silence_link" -}} + {{ .ExternalURL }}/#/silences/new?filter=%7B + {{- range .CommonLabels.SortedPairs -}} + {{- if ne .Name "alertname" -}} + {{- .Name }}%3D"{{- .Value -}}"%2C%20 + {{- end -}} + {{- end -}} + alertname%3D"{{ .CommonLabels.alertname }}"%7D +{{- end }} + +# Link to related PMs +{{ define "__alert_linked_postmortems" -}} +https://github.com/giantswarm/giantswarm/issues?q=is%3Aissue+is%3Aopen+label%3Apostmortem+label%3Aalert%2F{{ .CommonLabels.alertname }} +{{- end }} diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.tpl b/helm/observability-operator/files/alertmanager/url-template.tmpl.tpl new file mode 100644 index 00000000..c9424d8c --- /dev/null +++ b/helm/observability-operator/files/alertmanager/url-template.tmpl.tpl @@ -0,0 +1,18 @@ +{{` +{{ define "__alerturl" }} +`}}{{ .GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +{{ end }} + +{{ define "__dashboardurl" -}} +{{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} +{{ else }} +`}}{{ .GrafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} +{{ end }} +{{- end }} + +{{ define "__queryurl" }} +`}}{{ .GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +{{ end }} + +{{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} +`}} diff --git a/helm/observability-operator/templates/alertmanager/_helpers.tpl b/helm/observability-operator/templates/alertmanager/_helpers.tpl new file mode 100644 index 00000000..ee6fb834 --- /dev/null +++ b/helm/observability-operator/templates/alertmanager/_helpers.tpl @@ -0,0 +1,5 @@ +{{/* vim: set filetype=mustache: */}} + +{{- define "alertmanager-secret.name" -}} +{{- include "resource.default.name" . -}}-alertmanager +{{- end }} diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml new file mode 100644 index 00000000..c9bdc1f6 --- /dev/null +++ b/helm/observability-operator/templates/alertmanager/secret.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "labels.common" . | nindent 4 }} + name: {{ include "alertmanager-secret.name" . }} + namespace: {{ include "resource.default.namespace" . }} +data: + {{- /* Template all .tpl files found in files/alertmanager with values under alertmanager key */ -}} + {{ range $path, $content := .Files.Glob "files/alertmanager/*.tpl" }} + {{ base $path | trimSuffix ".tpl" }}: {{ tpl (printf "%s" $content) $.Values.alertmanager | b64enc }} + {{ end }} + + {{- /* Add all other non .tpl files found in files/alertmanager */ -}} + {{ range $path, $content := .Files.Glob "files/alertmanager/*" }} + {{ if not (hasSuffix ".tpl" $path) }} + {{ base $path }}: {{ (printf "%s" $content) | b64enc }} + {{ end }} + {{ end }} +type: Opaque diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 893459c2..5e7062eb 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -15,6 +15,15 @@ managementCluster: pipeline: pipeline region: region +alertmanager: + GrafanaAddress: "" + Installation: "" + OpsgenieKey: "" + Pipeline: "" + ProxyURL: "" + SlackApiToken: "" + SlackApiURL: "" + monitoring: agent: alloy enabled: false From 9eea3f8be51853787478c2ca1154c9aaed777258 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 10:25:47 +0100 Subject: [PATCH 19/44] use .helm-template instead of .tpl --- ...anager.yaml.tpl => alertmanager.yaml.helm-template} | 0 ...mplate.tmpl.tpl => url-template.tmpl.helm-template} | 0 .../templates/alertmanager/secret.yaml | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) rename helm/observability-operator/files/alertmanager/{alertmanager.yaml.tpl => alertmanager.yaml.helm-template} (100%) rename helm/observability-operator/files/alertmanager/{url-template.tmpl.tpl => url-template.tmpl.helm-template} (100%) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template similarity index 100% rename from helm/observability-operator/files/alertmanager/alertmanager.yaml.tpl rename to helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.tpl b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template similarity index 100% rename from helm/observability-operator/files/alertmanager/url-template.tmpl.tpl rename to helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml index c9bdc1f6..6286616a 100644 --- a/helm/observability-operator/templates/alertmanager/secret.yaml +++ b/helm/observability-operator/templates/alertmanager/secret.yaml @@ -6,14 +6,14 @@ metadata: name: {{ include "alertmanager-secret.name" . }} namespace: {{ include "resource.default.namespace" . }} data: - {{- /* Template all .tpl files found in files/alertmanager with values under alertmanager key */ -}} - {{ range $path, $content := .Files.Glob "files/alertmanager/*.tpl" }} - {{ base $path | trimSuffix ".tpl" }}: {{ tpl (printf "%s" $content) $.Values.alertmanager | b64enc }} + {{- /* Template all .helm-template files found in files/alertmanager with values under alertmanager key */ -}} + {{ range $path, $content := .Files.Glob "files/alertmanager/*.helm-template" }} + {{ base $path | trimSuffix ".helm-template" }}: {{ tpl (printf "%s" $content) $.Values.alertmanager | b64enc }} {{ end }} - {{- /* Add all other non .tpl files found in files/alertmanager */ -}} + {{- /* Add all other non .helm-template files found in files/alertmanager */ -}} {{ range $path, $content := .Files.Glob "files/alertmanager/*" }} - {{ if not (hasSuffix ".tpl" $path) }} + {{ if not (hasSuffix ".helm-template" $path) }} {{ base $path }}: {{ (printf "%s" $content) | b64enc }} {{ end }} {{ end }} From 27b62fa49e75d29d05390ee4f90614ce1db89fd5 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 11:09:46 +0100 Subject: [PATCH 20/44] re-use existing values --- .../alertmanager.yaml.helm-template | 64 +++++++++---------- .../url-template.tmpl.helm-template | 6 +- .../templates/alertmanager/secret.yaml | 2 +- helm/observability-operator/values.yaml | 3 - 4 files changed, 36 insertions(+), 39 deletions(-) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template index 743d0ba0..ace09db2 100644 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template @@ -4,10 +4,10 @@ global: http_config: proxy_url: {{ .ProxyURL }} {{- end }} -{{- if .SlackApiToken }} +{{- if .alertmanager.slackAPIToken }} slack_api_url: "https://slack.com/api/chat.postMessage" {{- else }} - slack_api_url: {{ .SlackApiURL }} + slack_api_url: {{ .alertmanager.slackAPIURL }} {{- end }} route: @@ -27,7 +27,7 @@ route: group_wait: 30s group_interval: 30s repeat_interval: 15m - {{- if eq .Pipeline "stable-testing" }} + {{- if eq .managementCluster.pipeline "stable-testing" }} - receiver: blackhole matchers: - cluster_type="workload_cluster" @@ -84,7 +84,7 @@ route: # Team Atlas Slack - receiver: team_atlas_slack matchers: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - severity="notify" {{- else }} - severity=~"page|notify" @@ -171,26 +171,26 @@ receivers: http_config: authorization: type: GenieKey - credentials: {{ .OpsgenieKey }} + credentials: {{ .monitoring.opsgenieApiKey }} follow_redirects: true enable_http2: true {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} - url: https://api.opsgenie.com/v2/heartbeats/{{ .Installation }}/ping + url: https://api.opsgenie.com/v2/heartbeats/{{ .managementCluster.name }}/ping -{{- if eq .Pipeline "stable-testing" }} +{{- if eq .managementCluster.pipeline "stable-testing" }} - name: blackhole {{- end }} - name: falco_noise_slack slack_configs: - channel: '#noise-falco' - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -217,16 +217,16 @@ receivers: - name: team_atlas_slack slack_configs: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - channel: '#alert-atlas' {{- else }} - channel: '#alert-atlas-test' {{- end }} - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -236,16 +236,16 @@ receivers: - name: team_phoenix_slack slack_configs: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - channel: '#alert-phoenix' {{- else }} - channel: '#alert-phoenix-test' {{- end }} - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -255,16 +255,16 @@ receivers: - name: team_bigmac_slack slack_configs: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - channel: '#alert-bigmac' {{- else }} - channel: '#alert-bigmac-test' {{- end }} - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -274,16 +274,16 @@ receivers: - name: team_rocket_slack slack_configs: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - channel: '#alert-rocket' {{- else }} - channel: '#alert-rocket-test' {{- end }} - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -294,11 +294,11 @@ receivers: - name: team_shield_slack slack_configs: - channel: '#alert-shield' - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -308,16 +308,16 @@ receivers: - name: team_turtles_slack slack_configs: - {{- if eq .Pipeline "stable" }} + {{- if eq .managementCluster.pipeline "stable" }} - channel: '#alert-turtles' {{- else }} - channel: '#alert-turtles-test' {{- end }} - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -328,11 +328,11 @@ receivers: - name: team_tenet_slack slack_configs: - channel: '#alert-tenet' - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -343,11 +343,11 @@ receivers: - name: team_honeybadger_slack slack_configs: - channel: '#alert-honeybadger' - {{- if .SlackApiToken }} + {{- if .alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .SlackApiToken }} + credentials: {{ .alertmanager.slackAPIToken }} {{- if .ProxyURL }} proxy_url: {{ .ProxyURL }} {{- end }} @@ -357,7 +357,7 @@ receivers: - name: opsgenie_router opsgenie_configs: - - api_key: {{ .OpsgenieKey }} + - api_key: {{ .monitoring.opsgenieApiKey }} tags: {{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}} inhibit_rules: @@ -369,7 +369,7 @@ inhibit_rules: - source_matchers: - inhibit_kube_state_metrics_down=true - - cluster_id={{ .Installation }} + - cluster_id={{ .managementCluster.name }} target_matchers: - cancel_if_mc_kube_state_metrics_down=true diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template index c9424d8c..8347cc43 100644 --- a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template +++ b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template @@ -1,17 +1,17 @@ {{` {{ define "__alerturl" }} -`}}{{ .GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .alertmanager.GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__dashboardurl" -}} {{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} {{ else }} -`}}{{ .GrafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} +`}}{{ .alertmanager.GrafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} {{ end }} {{- end }} {{ define "__queryurl" }} -`}}{{ .GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .alertmanager.GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml index 6286616a..2b704c92 100644 --- a/helm/observability-operator/templates/alertmanager/secret.yaml +++ b/helm/observability-operator/templates/alertmanager/secret.yaml @@ -8,7 +8,7 @@ metadata: data: {{- /* Template all .helm-template files found in files/alertmanager with values under alertmanager key */ -}} {{ range $path, $content := .Files.Glob "files/alertmanager/*.helm-template" }} - {{ base $path | trimSuffix ".helm-template" }}: {{ tpl (printf "%s" $content) $.Values.alertmanager | b64enc }} + {{ base $path | trimSuffix ".helm-template" }}: {{ tpl (printf "%s" $content) $.Values | b64enc }} {{ end }} {{- /* Add all other non .helm-template files found in files/alertmanager */ -}} diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 5e7062eb..1c19455d 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -17,9 +17,6 @@ managementCluster: alertmanager: GrafanaAddress: "" - Installation: "" - OpsgenieKey: "" - Pipeline: "" ProxyURL: "" SlackApiToken: "" SlackApiURL: "" From 49b5a1ac55088eee7d81ebd5a51bd36ce12d43a5 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 11:26:39 +0100 Subject: [PATCH 21/44] normalize values names --- .../alertmanager.yaml.helm-template | 44 +++++++++---------- .../url-template.tmpl.helm-template | 6 +-- helm/observability-operator/values.yaml | 8 ++-- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template index ace09db2..98283b2c 100644 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template @@ -1,8 +1,8 @@ global: resolve_timeout: 5m -{{- if .ProxyURL }} +{{- if .alertmanager.proxyURL }} http_config: - proxy_url: {{ .ProxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- if .alertmanager.slackAPIToken }} slack_api_url: "https://slack.com/api/chat.postMessage" @@ -174,8 +174,8 @@ receivers: credentials: {{ .monitoring.opsgenieApiKey }} follow_redirects: true enable_http2: true - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} url: https://api.opsgenie.com/v2/heartbeats/{{ .managementCluster.name }}/ping @@ -191,8 +191,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -227,8 +227,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -246,8 +246,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -265,8 +265,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -284,8 +284,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -299,8 +299,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -318,8 +318,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -333,8 +333,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -348,8 +348,8 @@ receivers: authorization: type: Bearer credentials: {{ .alertmanager.slackAPIToken }} - {{- if .ProxyURL }} - proxy_url: {{ .ProxyURL }} + {{- if .alertmanager.proxyURL }} + proxy_url: {{ .alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template index 8347cc43..e95f9a42 100644 --- a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template +++ b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template @@ -1,17 +1,17 @@ {{` {{ define "__alerturl" }} -`}}{{ .alertmanager.GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__dashboardurl" -}} {{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} {{ else }} -`}}{{ .alertmanager.GrafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} +`}}{{ .alertmanager.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} {{ end }} {{- end }} {{ define "__queryurl" }} -`}}{{ .alertmanager.GrafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 1c19455d..123a6ef4 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -16,10 +16,10 @@ managementCluster: region: region alertmanager: - GrafanaAddress: "" - ProxyURL: "" - SlackApiToken: "" - SlackApiURL: "" + grafanaAddress: "" + proxyURL: "" + slackAPIToken: "" + slackAPIURL: "" monitoring: agent: alloy From 2ea110157857680fd66f38733120daf7948748ce Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 13:13:25 +0100 Subject: [PATCH 22/44] try to make helm happy: error calling tpl: cannot retrieve Template.Basepath from values inside tpl function --- .../templates/alertmanager/secret.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml index 2b704c92..0384c1f0 100644 --- a/helm/observability-operator/templates/alertmanager/secret.yaml +++ b/helm/observability-operator/templates/alertmanager/secret.yaml @@ -7,14 +7,14 @@ metadata: namespace: {{ include "resource.default.namespace" . }} data: {{- /* Template all .helm-template files found in files/alertmanager with values under alertmanager key */ -}} - {{ range $path, $content := .Files.Glob "files/alertmanager/*.helm-template" }} - {{ base $path | trimSuffix ".helm-template" }}: {{ tpl (printf "%s" $content) $.Values | b64enc }} + {{ range $path, $_ := .Files.Glob "files/alertmanager/*.helm-template" }} + {{ base $path | trimSuffix ".helm-template" }}: {{ tpl ($.Files.Get $path) $.Values | b64enc }} {{ end }} {{- /* Add all other non .helm-template files found in files/alertmanager */ -}} - {{ range $path, $content := .Files.Glob "files/alertmanager/*" }} + {{ range $path, $_ := .Files.Glob "files/alertmanager/*" }} {{ if not (hasSuffix ".helm-template" $path) }} - {{ base $path }}: {{ (printf "%s" $content) | b64enc }} + {{ base $path }}: {{ ($.Files.Get $path) | b64enc }} {{ end }} {{ end }} type: Opaque From 801cadd56abdae9a9d90084947eb27c092af1cb3 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 15:43:28 +0100 Subject: [PATCH 23/44] helm 3.10.3 I hate you deeply This fixes the infamous: error calling tpl: cannot retrieve Template.Basepath from values inside tpl function It does use .Values in templates to access values and pass $ root context to tpl --- .../alertmanager.yaml.helm-template | 108 +++++++++--------- .../url-template.tmpl.helm-template | 6 +- .../templates/alertmanager/secret.yaml | 2 +- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template index 98283b2c..2ec50d6e 100644 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template @@ -1,13 +1,13 @@ global: resolve_timeout: 5m -{{- if .alertmanager.proxyURL }} +{{- if .Values.alertmanager.proxyURL }} http_config: - proxy_url: {{ .alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} -{{- if .alertmanager.slackAPIToken }} +{{- if .Values.alertmanager.slackAPIToken }} slack_api_url: "https://slack.com/api/chat.postMessage" {{- else }} - slack_api_url: {{ .alertmanager.slackAPIURL }} + slack_api_url: {{ .Values.alertmanager.slackAPIURL }} {{- end }} route: @@ -27,7 +27,7 @@ route: group_wait: 30s group_interval: 30s repeat_interval: 15m - {{- if eq .managementCluster.pipeline "stable-testing" }} + {{- if eq .Values.managementCluster.pipeline "stable-testing" }} - receiver: blackhole matchers: - cluster_type="workload_cluster" @@ -84,7 +84,7 @@ route: # Team Atlas Slack - receiver: team_atlas_slack matchers: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - severity="notify" {{- else }} - severity=~"page|notify" @@ -171,28 +171,28 @@ receivers: http_config: authorization: type: GenieKey - credentials: {{ .monitoring.opsgenieApiKey }} + credentials: {{ .Values.monitoring.opsgenieApiKey }} follow_redirects: true enable_http2: true - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} - url: https://api.opsgenie.com/v2/heartbeats/{{ .managementCluster.name }}/ping + url: https://api.opsgenie.com/v2/heartbeats/{{ .Values.managementCluster.name }}/ping -{{- if eq .managementCluster.pipeline "stable-testing" }} +{{- if eq .Values.managementCluster.pipeline "stable-testing" }} - name: blackhole {{- end }} - name: falco_noise_slack slack_configs: - channel: '#noise-falco' - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -217,18 +217,18 @@ receivers: - name: team_atlas_slack slack_configs: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - channel: '#alert-atlas' {{- else }} - channel: '#alert-atlas-test' {{- end }} - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -236,18 +236,18 @@ receivers: - name: team_phoenix_slack slack_configs: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - channel: '#alert-phoenix' {{- else }} - channel: '#alert-phoenix-test' {{- end }} - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -255,18 +255,18 @@ receivers: - name: team_bigmac_slack slack_configs: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - channel: '#alert-bigmac' {{- else }} - channel: '#alert-bigmac-test' {{- end }} - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -274,18 +274,18 @@ receivers: - name: team_rocket_slack slack_configs: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - channel: '#alert-rocket' {{- else }} - channel: '#alert-rocket-test' {{- end }} - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -294,13 +294,13 @@ receivers: - name: team_shield_slack slack_configs: - channel: '#alert-shield' - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -308,18 +308,18 @@ receivers: - name: team_turtles_slack slack_configs: - {{- if eq .managementCluster.pipeline "stable" }} + {{- if eq .Values.managementCluster.pipeline "stable" }} - channel: '#alert-turtles' {{- else }} - channel: '#alert-turtles-test' {{- end }} - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -328,13 +328,13 @@ receivers: - name: team_tenet_slack slack_configs: - channel: '#alert-tenet' - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -343,13 +343,13 @@ receivers: - name: team_honeybadger_slack slack_configs: - channel: '#alert-honeybadger' - {{- if .alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .alertmanager.slackAPIToken }} - {{- if .alertmanager.proxyURL }} - proxy_url: {{ .alertmanager.proxyURL }} + credentials: {{ .Values.alertmanager.slackAPIToken }} + {{- if .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alertmanager.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -357,7 +357,7 @@ receivers: - name: opsgenie_router opsgenie_configs: - - api_key: {{ .monitoring.opsgenieApiKey }} + - api_key: {{ .Values.monitoring.opsgenieApiKey }} tags: {{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}} inhibit_rules: @@ -369,7 +369,7 @@ inhibit_rules: - source_matchers: - inhibit_kube_state_metrics_down=true - - cluster_id={{ .managementCluster.name }} + - cluster_id={{ .Values.managementCluster.name }} target_matchers: - cancel_if_mc_kube_state_metrics_down=true diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template index e95f9a42..11630d3d 100644 --- a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template +++ b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template @@ -1,17 +1,17 @@ {{` {{ define "__alerturl" }} -`}}{{ .alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .Values.alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__dashboardurl" -}} {{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} {{ else }} -`}}{{ .alertmanager.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} +`}}{{ .Values.alertmanager.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} {{ end }} {{- end }} {{ define "__queryurl" }} -`}}{{ .alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .Values.alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml index 0384c1f0..6c50a26a 100644 --- a/helm/observability-operator/templates/alertmanager/secret.yaml +++ b/helm/observability-operator/templates/alertmanager/secret.yaml @@ -8,7 +8,7 @@ metadata: data: {{- /* Template all .helm-template files found in files/alertmanager with values under alertmanager key */ -}} {{ range $path, $_ := .Files.Glob "files/alertmanager/*.helm-template" }} - {{ base $path | trimSuffix ".helm-template" }}: {{ tpl ($.Files.Get $path) $.Values | b64enc }} + {{ base $path | trimSuffix ".helm-template" }}: {{ tpl ($.Files.Get $path) $ | b64enc }} {{ end }} {{- /* Add all other non .helm-template files found in files/alertmanager */ -}} From 8cbdbfb2882cfb2351c778b49a40f7938b85a665 Mon Sep 17 00:00:00 2001 From: Taylor Bot Date: Tue, 10 Dec 2024 23:47:03 +0900 Subject: [PATCH 24/44] Release v0.10.0 (#191) Co-authored-by: Quentin Bisson --- CHANGELOG.md | 5 ++++- helm/observability-operator/Chart.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70bcb316..3aa85a9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.10.0] - 2024-12-10 + ### Added - Add Mimir Alertmanager datasource. @@ -186,7 +188,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initialize project and create heartbeat for the installation. -[Unreleased]: https://github.com/giantswarm/observability-operator/compare/v0.9.1...HEAD +[Unreleased]: https://github.com/giantswarm/observability-operator/compare/v0.10.0...HEAD +[0.10.0]: https://github.com/giantswarm/observability-operator/compare/v0.9.1...v0.10.0 [0.9.1]: https://github.com/giantswarm/observability-operator/compare/v0.9.0...v0.9.1 [0.9.0]: https://github.com/giantswarm/observability-operator/compare/v0.8.1...v0.9.0 [0.8.1]: https://github.com/giantswarm/observability-operator/compare/v0.8.0...v0.8.1 diff --git a/helm/observability-operator/Chart.yaml b/helm/observability-operator/Chart.yaml index a19c0956..77c7acaa 100644 --- a/helm/observability-operator/Chart.yaml +++ b/helm/observability-operator/Chart.yaml @@ -3,7 +3,7 @@ name: observability-operator description: The observability-operator manages the Giant Swarm observability platform. home: https://github.com/giantswarm/observability-operator icon: https://s.giantswarm.io/app-icons/giantswarm/1/light.svg -version: 0.9.1 +version: 0.10.0 appVersion: 0.0.2 annotations: application.giantswarm.io/team: "atlas" From 5d320b91ac3a53460568b5fd704d159df2b98ce3 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 17:29:39 +0100 Subject: [PATCH 25/44] quote the tmp_string --- .../alertmanager/alertmanager.yaml.helm-template | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template index 2ec50d6e..f8a73102 100644 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template @@ -199,21 +199,21 @@ receivers: actions: &slack-actions - type: button text: ':green_book: OpsRecipe' - url: {{`{{ template "__runbookurl" . }}`}} - style: {{`{{ if eq .Status "firing" }}primary{{ else }}default{{ end }}`}} + url: '{{`{{ template "__runbookurl" . }}`}}' + style: '{{`{{ if eq .Status "firing" }}primary{{ else }}default{{ end }}`}}' - type: button text: ':coffin: Linked PMs' - url: {{`{{ template "__alert_linked_postmortems" . }}`}} + url: '{{`{{ template "__alert_linked_postmortems" . }}`}}' - type: button text: ':mag: Query' - url: {{`{{ template "__alerturl" . }}`}} + url: '{{`{{ template "__alerturl" . }}`}}' - type: button text: ':grafana: Dashboard' - url: {{`{{ template "__dashboardurl" . }}`}} + url: '{{`{{ template "__dashboardurl" . }}`}}' - type: button text: ':no_bell: Silence' - url: {{`{{ template "__alert_silence_link" .}}`}} - style: {{`{{ if eq .Status "firing" }}danger{{ else }}default{{ end }}`}} + url: '{{`{{ template "__alert_silence_link" .}}`}}' + style: '{{`{{ if eq .Status "firing" }}danger{{ else }}default{{ end }}`}}' - name: team_atlas_slack slack_configs: @@ -358,7 +358,7 @@ receivers: - name: opsgenie_router opsgenie_configs: - api_key: {{ .Values.monitoring.opsgenieApiKey }} - tags: {{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}} + tags: '{{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}}' inhibit_rules: - source_matchers: From 8a79cf5e7fa9330c93ae094ffa6ae0308d1bbd87 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 18:53:31 +0100 Subject: [PATCH 26/44] Add values and alertmanagerURL --- helm/observability-operator/templates/deployment.yaml | 1 + helm/observability-operator/values.yaml | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/helm/observability-operator/templates/deployment.yaml b/helm/observability-operator/templates/deployment.yaml index 31028517..a64dd371 100644 --- a/helm/observability-operator/templates/deployment.yaml +++ b/helm/observability-operator/templates/deployment.yaml @@ -32,6 +32,7 @@ spec: - --management-cluster-region={{ $.Values.managementCluster.region }} # Monitoring configuration - --alertmanager-secret-name={{ include "alertmanager-secret.name" . }} + - --alertmanager-url={{ $.Values.alertmanager.alertmanagerURL }} - --monitoring-enabled={{ $.Values.monitoring.enabled }} - --monitoring-agent={{ $.Values.monitoring.agent }} - --monitoring-sharding-scale-up-series-count={{ $.Values.monitoring.sharding.scaleUpSeriesCount }} diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 893459c2..d3a8fa30 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -15,6 +15,13 @@ managementCluster: pipeline: pipeline region: region +alertmanager: + alertmanagerURL: "" + grafanaAddress: "" + proxyURL: "" + slackAPIToken: "" + slackAPIURL: "" + monitoring: agent: alloy enabled: false From 4cfbb208e62f9f4d93641f696b701176c160a745 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 18:54:19 +0100 Subject: [PATCH 27/44] Add alertmanagerURL --- helm/observability-operator/values.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 123a6ef4..d3a8fa30 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -16,6 +16,7 @@ managementCluster: region: region alertmanager: + alertmanagerURL: "" grafanaAddress: "" proxyURL: "" slackAPIToken: "" From 3c450c7b2a8b01f9d61a389c3b8a76f907d8a9df Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 19:15:27 +0100 Subject: [PATCH 28/44] debug log --- pkg/alertmanager/alertmanager.go | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index d0021a2c..ef9595e2 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "io" "maps" "net/http" "slices" @@ -13,6 +14,7 @@ import ( "github.com/prometheus/alertmanager/config" v1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/yaml" pkgconfig "github.com/giantswarm/observability-operator/pkg/config" @@ -54,6 +56,10 @@ func New(conf pkgconfig.Config, c client.Client) Job { } func (j Job) Configure(ctx context.Context) error { + logger := log.FromContext(ctx) + + logger.Info("Alertmanager: configuring") + //TODO: get this from somewhere tenantID := "anonymous" @@ -79,10 +85,18 @@ func (j Job) Configure(ctx context.Context) error { } } - return j.configure(alertmanagerConfigContent, templates, tenantID) + err = j.configure(alertmanagerConfigContent, templates, tenantID) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to configure: %w", err)) + } + + logger.Info("Alertmanager: configured") + return nil } -func (j Job) configure(alertmanagerConfigContent []byte, templates map[string]string, tenantID string) error { +func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, templates map[string]string, tenantID string) error { + logger := log.FromContext(ctx) + // Load alertmanager configuration alertmanagerConfig, err := config.Load(string(alertmanagerConfigContent)) if err != nil { @@ -93,10 +107,11 @@ func (j Job) configure(alertmanagerConfigContent []byte, templates map[string]st // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path alertmanagerConfig.Templates = slices.Collect(maps.Keys(templates)) + alertmanacgerConfigString := alertmanagerConfig.String() // Prepare request for Alertmanager API requestData := configRequest{ - AlertmanagerConfig: alertmanagerConfig.String(), + AlertmanagerConfig: alertmanagerConfigString, TemplateFiles: templates, } data, err := yaml.Marshal(requestData) @@ -104,8 +119,11 @@ func (j Job) configure(alertmanagerConfigContent []byte, templates map[string]st return errors.WithStack(fmt.Errorf("alertmanager: failed to marshal yaml: %w", err)) } + url := j.alertmanagerURL + alertmanagerAPIPath + logger.WithValues("url", url, "data_size", len(data), "config_size", len(alertmanagerConfigString), "templates_count", len(templates)).Info("Alertmanager: sending configuration") + // Send request to Alertmanager's API - req, err := http.NewRequest(http.MethodPost, j.alertmanagerURL+alertmanagerAPIPath, bytes.NewBuffer(data)) + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to create request: %w", err)) } @@ -117,6 +135,13 @@ func (j Job) configure(alertmanagerConfigContent []byte, templates map[string]st } defer resp.Body.Close() // nolint: errcheck + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to read response: %w", err)) + } + + logger.WithValues("status_code", resp.StatusCode, "response", string(respBody)).Info("Alertmanager: configuration sent") + //TODO: handle response errors if any return nil From c522b8155ea2a25076f80a1d453751641015f2ed Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 19:20:30 +0100 Subject: [PATCH 29/44] fix debug log --- pkg/alertmanager/alertmanager.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index ef9595e2..6ce8ce77 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -85,7 +85,7 @@ func (j Job) Configure(ctx context.Context) error { } } - err = j.configure(alertmanagerConfigContent, templates, tenantID) + err = j.configure(ctx, alertmanagerConfigContent, templates, tenantID) if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to configure: %w", err)) } @@ -107,7 +107,7 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path alertmanagerConfig.Templates = slices.Collect(maps.Keys(templates)) - alertmanacgerConfigString := alertmanagerConfig.String() + alertmanagerConfigString := alertmanagerConfig.String() // Prepare request for Alertmanager API requestData := configRequest{ From 388a6395abab822d2b3ac058de00f17cd45f97f2 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 20:05:22 +0100 Subject: [PATCH 30/44] Fix invalid request body --- pkg/alertmanager/alertmanager.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 6ce8ce77..99cc6808 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -37,9 +37,11 @@ type Job struct { alertmanagerSecret client.ObjectKey } +// configRequest is the structure used to send the configuration to Alertmanager's API +// json tags also applies yaml field names type configRequest struct { - TemplateFiles map[string]string `yaml:"template_files"` - AlertmanagerConfig string `yaml:"alertmanager_config"` + TemplateFiles map[string]string `json:"template_files"` + AlertmanagerConfig string `json:"alertmanager_config"` } func New(conf pkgconfig.Config, c client.Client) Job { From a366895c3ea4feca727340dfeb7084ce15cf5d3a Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Tue, 10 Dec 2024 20:05:31 +0100 Subject: [PATCH 31/44] Handle non 201 errors --- pkg/alertmanager/alertmanager.go | 19 +++++++++++++------ pkg/alertmanager/error.go | 10 ++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 pkg/alertmanager/error.go diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 99cc6808..72e46810 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -137,14 +137,21 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te } defer resp.Body.Close() // nolint: errcheck - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return errors.WithStack(fmt.Errorf("alertmanager: failed to read response: %w", err)) - } + logger.WithValues("status_code", resp.StatusCode).Info("Alertmanager: configuration sent") + + if resp.StatusCode != http.StatusCreated { + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to read response: %w", err)) + } - logger.WithValues("status_code", resp.StatusCode, "response", string(respBody)).Info("Alertmanager: configuration sent") + e := APIError{ + Code: resp.StatusCode, + Message: string(respBody), + } - //TODO: handle response errors if any + return errors.WithStack(fmt.Errorf("alertmanager: failed to send configuration: %w", e)) + } return nil } diff --git a/pkg/alertmanager/error.go b/pkg/alertmanager/error.go new file mode 100644 index 00000000..1fc4c7e6 --- /dev/null +++ b/pkg/alertmanager/error.go @@ -0,0 +1,10 @@ +package alertmanager + +type APIError struct { + Code int + Message string +} + +func (e APIError) Error() string { + return e.Message +} From 9591a925c7090eb6b1e787e520732a56b022e001 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Fri, 13 Dec 2024 12:52:01 +0100 Subject: [PATCH 32/44] rename alertmanager to alerting in values.yaml --- .../alertmanager.yaml.helm-template | 84 +++++++++---------- .../url-template.tmpl.helm-template | 6 +- helm/observability-operator/values.yaml | 2 +- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template index f8a73102..1ced9a3e 100644 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template @@ -1,13 +1,13 @@ global: resolve_timeout: 5m -{{- if .Values.alertmanager.proxyURL }} +{{- if .Values.alerting.proxyURL }} http_config: - proxy_url: {{ .Values.alertmanager.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} -{{- if .Values.alertmanager.slackAPIToken }} +{{- if .Values.alerting.slackAPIToken }} slack_api_url: "https://slack.com/api/chat.postMessage" {{- else }} - slack_api_url: {{ .Values.alertmanager.slackAPIURL }} + slack_api_url: {{ .Values.alerting.slackAPIURL }} {{- end }} route: @@ -174,8 +174,8 @@ receivers: credentials: {{ .Values.monitoring.opsgenieApiKey }} follow_redirects: true enable_http2: true - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} url: https://api.opsgenie.com/v2/heartbeats/{{ .Values.managementCluster.name }}/ping @@ -186,13 +186,13 @@ receivers: - name: falco_noise_slack slack_configs: - channel: '#noise-falco' - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -222,13 +222,13 @@ receivers: {{- else }} - channel: '#alert-atlas-test' {{- end }} - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -241,13 +241,13 @@ receivers: {{- else }} - channel: '#alert-phoenix-test' {{- end }} - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -260,13 +260,13 @@ receivers: {{- else }} - channel: '#alert-bigmac-test' {{- end }} - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -279,13 +279,13 @@ receivers: {{- else }} - channel: '#alert-rocket-test' {{- end }} - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -294,13 +294,13 @@ receivers: - name: team_shield_slack slack_configs: - channel: '#alert-shield' - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -313,13 +313,13 @@ receivers: {{- else }} - channel: '#alert-turtles-test' {{- end }} - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -328,13 +328,13 @@ receivers: - name: team_tenet_slack slack_configs: - channel: '#alert-tenet' - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true @@ -343,13 +343,13 @@ receivers: - name: team_honeybadger_slack slack_configs: - channel: '#alert-honeybadger' - {{- if .Values.alertmanager.slackAPIToken }} + {{- if .Values.alerting.slackAPIToken }} http_config: authorization: type: Bearer - credentials: {{ .Values.alertmanager.slackAPIToken }} - {{- if .Values.alertmanager.proxyURL }} - proxy_url: {{ .Values.alertmanager.proxyURL }} + credentials: {{ .Values.alerting.slackAPIToken }} + {{- if .Values.alerting.proxyURL }} + proxy_url: {{ .Values.alerting.proxyURL }} {{- end }} {{- end }} send_resolved: true diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template index 11630d3d..b93f8937 100644 --- a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template +++ b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template @@ -1,17 +1,17 @@ {{` {{ define "__alerturl" }} -`}}{{ .Values.alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .Values.alerting.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__dashboardurl" -}} {{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} {{ else }} -`}}{{ .Values.alertmanager.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} +`}}{{ .Values.alerting.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} {{ end }} {{- end }} {{ define "__queryurl" }} -`}}{{ .Values.alertmanager.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find +`}}{{ .Values.alerting.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find {{ end }} {{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index d3a8fa30..23e398b9 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -15,7 +15,7 @@ managementCluster: pipeline: pipeline region: region -alertmanager: +alerting: alertmanagerURL: "" grafanaAddress: "" proxyURL: "" From e58c6827fb9445a5d7f3abcb7e91a7d460e75f22 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 17:43:56 +0100 Subject: [PATCH 33/44] remove alertmanager job from grafana organization controller --- .../grafanaorganization_controller.go | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/internal/controller/grafanaorganization_controller.go b/internal/controller/grafanaorganization_controller.go index 6271c75f..89fb758a 100644 --- a/internal/controller/grafanaorganization_controller.go +++ b/internal/controller/grafanaorganization_controller.go @@ -38,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/giantswarm/observability-operator/pkg/alertmanager" "github.com/giantswarm/observability-operator/pkg/config" grafanaclient "github.com/giantswarm/observability-operator/pkg/grafana/client" @@ -51,9 +50,8 @@ import ( // GrafanaOrganizationReconciler reconciles a GrafanaOrganization object type GrafanaOrganizationReconciler struct { client.Client - Scheme *runtime.Scheme - GrafanaAPI *grafanaAPI.GrafanaHTTPAPI - AlertmanagerJob alertmanager.Job + Scheme *runtime.Scheme + GrafanaAPI *grafanaAPI.GrafanaHTTPAPI } func SetupGrafanaOrganizationReconciler(mgr manager.Manager, conf config.Config) error { @@ -80,10 +78,9 @@ func SetupGrafanaOrganizationReconciler(mgr manager.Manager, conf config.Config) } r := &GrafanaOrganizationReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - GrafanaAPI: grafanaAPI, - AlertmanagerJob: alertmanager.New(conf, mgr.GetClient()), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + GrafanaAPI: grafanaAPI, } err = r.SetupWithManager(mgr) @@ -201,12 +198,6 @@ func (r GrafanaOrganizationReconciler) reconcileCreate(ctx context.Context, graf return ctrl.Result{}, nil } - // Configure Alertmanager - err := r.AlertmanagerJob.Configure(ctx) - if err != nil { - return ctrl.Result{}, errors.WithStack(err) - } - // Configure the shared organization in Grafana if err := r.configureSharedOrg(ctx); err != nil { return ctrl.Result{}, errors.WithStack(err) From 740d3b9229d24c5bda545ee8a9120cc5353f8fe1 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:02:00 +0100 Subject: [PATCH 34/44] Add Alertmanager controller --- CHANGELOG.md | 4 + .../controller/alertmanager_controller.go | 102 ++++++++++++++++++ .../alertmanager_secret_predicate.go | 67 ++++++++++++ main.go | 7 ++ 4 files changed, 180 insertions(+) create mode 100644 internal/controller/alertmanager_controller.go create mode 100644 internal/controller/predicates/alertmanager_secret_predicate.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 875d234d..5ab378b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add Alertmanager controller + ## [0.10.1] - 2024-12-12 ### Fixed diff --git a/internal/controller/alertmanager_controller.go b/internal/controller/alertmanager_controller.go new file mode 100644 index 00000000..bde782f4 --- /dev/null +++ b/internal/controller/alertmanager_controller.go @@ -0,0 +1,102 @@ +package controller + +import ( + "context" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/pkg/errors" + + "github.com/giantswarm/observability-operator/internal/controller/predicates" + "github.com/giantswarm/observability-operator/pkg/alertmanager" + "github.com/giantswarm/observability-operator/pkg/config" +) + +// AlertmanagerReconciler reconciles the Alertmanager secret created by the observability-operator Helm chart +// and configures the Alertmanager instance with the configuration stored in the secret. +// This controller do not make use of finalizers as the configuration is not removed from Alertmanager when the secret is deleted. +type AlertmanagerReconciler struct { + client client.Client + + alertmanagerJob alertmanager.Job +} + +// SetupAlertmanagerReconciler adds a controller into mgr that reconciles the Alertmanager secret. +func SetupAlertmanagerReconciler(mgr ctrl.Manager, conf config.Config) error { + r := &AlertmanagerReconciler{ + client: mgr.GetClient(), + alertmanagerJob: alertmanager.New(conf, mgr.GetClient()), + } + + // Filter only the Alertmanager secret created by the observability-operator Helm chart + secretPredicate := predicates.NewAlertmanagerSecretPredicate(conf.Monitoring.AlertmanagerSecretName, conf.Namespace) + + // Filter only the Mimir Alertmanager pod + podPredicate := predicates.NewAlertmanagerPodPredicate() + + // Requeue the Alertmanager secret when the Mimir Alertmanager pod changes + p := podEventHandler(conf.Monitoring.AlertmanagerSecretName, conf.Namespace) + + // Setup the controller + return ctrl.NewControllerManagedBy(mgr). + For(&v1.ConfigMap{}, builder.WithPredicates(secretPredicate)). + Watches(&v1.Pod{}, p, builder.WithPredicates(podPredicate)). + Complete(r) +} + +// podEventHandler returns an event handler that enqueues requests for the Alertmanager secret only. +// For now there is only one Alertmanager secret to be reconciled. +func podEventHandler(secretName, namespace string) handler.EventHandler { + return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []ctrl.Request { + return []reconcile.Request{ + { + NamespacedName: types.NamespacedName{ + Name: secretName, + Namespace: namespace, + }, + }, + } + }) +} + +// Reconcile main logic +func (r AlertmanagerReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + logger = logger.WithValues("controller", "alertmanager") + log.IntoContext(ctx, logger) + + logger.Info("Started reconciling") + defer logger.Info("Finished reconciling") + + // Retrieve the secret being reconciled + secret := &v1.Secret{} + if err := r.client.Get(ctx, req.NamespacedName, secret); err != nil { + return ctrl.Result{}, errors.WithStack(client.IgnoreNotFound(err)) + } + + if !secret.DeletionTimestamp.IsZero() { + // Nothing to do if the secret is being deleted + // Configuration is not removed from Alertmanager when the secret is deleted. + return ctrl.Result{}, nil + } + + return r.reconcileCreate(ctx, secret) +} + +// Handle create and update events +func (r AlertmanagerReconciler) reconcileCreate(ctx context.Context, secret *v1.Secret) (ctrl.Result, error) { // nolint: unparam + // Ensure the configuration is set and up to date in Alertmanager + err := r.alertmanagerJob.Configure(ctx) + if err != nil { + return ctrl.Result{}, errors.WithStack(err) + } + + return ctrl.Result{}, nil +} diff --git a/internal/controller/predicates/alertmanager_secret_predicate.go b/internal/controller/predicates/alertmanager_secret_predicate.go new file mode 100644 index 00000000..210133f1 --- /dev/null +++ b/internal/controller/predicates/alertmanager_secret_predicate.go @@ -0,0 +1,67 @@ +package predicates + +import ( + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// NewAlertmanagerSecretPredicate returns a predicate that filters only the Alertmanager secret created by the observability-operator Helm chart. +func NewAlertmanagerSecretPredicate(secretName, namespace string) predicate.Predicate { + filter := func(object client.Object) bool { + if object == nil { + return false + } + + secret, ok := object.(*v1.Secret) + if !ok { + return false + } + + labels := secret.GetLabels() + + ok = secret.GetName() == secretName && + secret.GetNamespace() == namespace && + labels != nil && + labels["app.kubernetes.io/name"] == "observability-operator" + + return ok + } + + p := predicate.NewPredicateFuncs(filter) + + return p +} + +const ( + mimirNamespace = "mimir" + mimirInstance = "mimir" + mimirAlertmanagerComponent = "alertmanager" +) + +// NewAlertmanagerPodPredicate returns a predicate that filters only the Mimir Alertmanager pod. +func NewAlertmanagerPodPredicate() predicate.Predicate { + filter := func(object client.Object) bool { + if object == nil { + return false + } + + pod, ok := object.(*v1.Pod) + if !ok { + return false + } + + labels := pod.GetLabels() + + ok = pod.GetNamespace() == mimirNamespace && + labels != nil && + labels["app.kubernetes.io/component"] == mimirAlertmanagerComponent && + labels["app.kubernetes.io/instance"] == mimirInstance + + return ok + } + + p := predicate.NewPredicateFuncs(filter) + + return p +} diff --git a/main.go b/main.go index e1efa6b4..2f461902 100644 --- a/main.go +++ b/main.go @@ -188,6 +188,13 @@ func main() { setupLog.Error(err, "unable to setup controller", "controller", "GrafanaOrganizationReconciler") os.Exit(1) } + + // Setup controller for Alertmanager + err = controller.SetupAlertmanagerReconciler(mgr, conf) + if err != nil { + setupLog.Error(err, "unable to setup controller", "controller", "AlertmanagerReconciler") + os.Exit(1) + } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { From cc9987ddf76085add749e9f6d11a716af7c34a41 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:10:40 +0100 Subject: [PATCH 35/44] revert grafana organization controller changes --- .../controller/grafanaorganization_controller.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/controller/grafanaorganization_controller.go b/internal/controller/grafanaorganization_controller.go index 89fb758a..0fa1b10f 100644 --- a/internal/controller/grafanaorganization_controller.go +++ b/internal/controller/grafanaorganization_controller.go @@ -54,23 +54,23 @@ type GrafanaOrganizationReconciler struct { GrafanaAPI *grafanaAPI.GrafanaHTTPAPI } -func SetupGrafanaOrganizationReconciler(mgr manager.Manager, conf config.Config) error { +func SetupGrafanaOrganizationReconciler(mgr manager.Manager, environment config.Environment) error { // Generate Grafana client // Get grafana admin-password and admin-user grafanaAdminCredentials := grafanaclient.AdminCredentials{ - Username: conf.Environment.GrafanaAdminUsername, - Password: conf.Environment.GrafanaAdminPassword, + Username: environment.GrafanaAdminUsername, + Password: environment.GrafanaAdminPassword, } if grafanaAdminCredentials.Username == "" { - return fmt.Errorf("GrafanaAdminUsername not set: %q", conf.Environment.GrafanaAdminUsername) + return fmt.Errorf("GrafanaAdminUsername not set: %q", environment.GrafanaAdminUsername) } if grafanaAdminCredentials.Password == "" { - return fmt.Errorf("GrafanaAdminPassword not set: %q", conf.Environment.GrafanaAdminPassword) + return fmt.Errorf("GrafanaAdminPassword not set: %q", environment.GrafanaAdminPassword) } grafanaTLSConfig := grafanaclient.TLSConfig{ - Cert: conf.Environment.GrafanaTLSCertFile, - Key: conf.Environment.GrafanaTLSKeyFile, + Cert: environment.GrafanaTLSCertFile, + Key: environment.GrafanaTLSKeyFile, } grafanaAPI, err := grafanaclient.GenerateGrafanaClient(grafanaAdminCredentials, grafanaTLSConfig) if err != nil { From 18935b1e80cc0b8650a4ed95c16ec349e6f21a30 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:12:47 +0100 Subject: [PATCH 36/44] update alertmanager > alerting in deployment.yaml --- helm/observability-operator/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/observability-operator/templates/deployment.yaml b/helm/observability-operator/templates/deployment.yaml index a64dd371..627b745c 100644 --- a/helm/observability-operator/templates/deployment.yaml +++ b/helm/observability-operator/templates/deployment.yaml @@ -32,7 +32,7 @@ spec: - --management-cluster-region={{ $.Values.managementCluster.region }} # Monitoring configuration - --alertmanager-secret-name={{ include "alertmanager-secret.name" . }} - - --alertmanager-url={{ $.Values.alertmanager.alertmanagerURL }} + - --alertmanager-url={{ $.Values.alerting.alertmanagerURL }} - --monitoring-enabled={{ $.Values.monitoring.enabled }} - --monitoring-agent={{ $.Values.monitoring.agent }} - --monitoring-sharding-scale-up-series-count={{ $.Values.monitoring.sharding.scaleUpSeriesCount }} From fbda645333bfc2c102f21c698c077effc927de67 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:16:48 +0100 Subject: [PATCH 37/44] revert grafana organization controller changes --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index e1efa6b4..2511ebc7 100644 --- a/main.go +++ b/main.go @@ -183,7 +183,7 @@ func main() { } // Setup controller for the GrafanaOrganization resource. - err = controller.SetupGrafanaOrganizationReconciler(mgr, conf) + err = controller.SetupGrafanaOrganizationReconciler(mgr, conf.Environment) if err != nil { setupLog.Error(err, "unable to setup controller", "controller", "GrafanaOrganizationReconciler") os.Exit(1) From b0eb4dc0fa0fddea55eb89f8089d026f36bdbf63 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:30:47 +0100 Subject: [PATCH 38/44] pass secret to Configure, add comment --- pkg/alertmanager/alertmanager.go | 36 ++++++++++++-------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 72e46810..361d3c15 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -13,7 +13,6 @@ import ( "github.com/pkg/errors" "github.com/prometheus/alertmanager/config" v1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/yaml" @@ -29,12 +28,13 @@ const ( orgIDHeader = "X-Scope-OrgID" alertmanagerAPIPath = "/api/v1/alerts" + + //TODO: get this from somewhere + tenantID = "anonymous" ) type Job struct { - client client.Client - alertmanagerURL string - alertmanagerSecret client.ObjectKey + alertmanagerURL string } // configRequest is the structure used to send the configuration to Alertmanager's API @@ -44,50 +44,38 @@ type configRequest struct { AlertmanagerConfig string `json:"alertmanager_config"` } -func New(conf pkgconfig.Config, c client.Client) Job { +func New(conf pkgconfig.Config) Job { job := Job{ - client: c, alertmanagerURL: strings.TrimSuffix(conf.Monitoring.AlertmanagerURL, "/"), - alertmanagerSecret: client.ObjectKey{ - Name: conf.Monitoring.AlertmanagerSecretName, - Namespace: conf.Namespace, - }, } return job } -func (j Job) Configure(ctx context.Context) error { +func (j Job) Configure(ctx context.Context, secret *v1.Secret) error { logger := log.FromContext(ctx) logger.Info("Alertmanager: configuring") - //TODO: get this from somewhere - tenantID := "anonymous" - - // Read secret used as source for Alertmanager configuration - alertmanagerSecret := v1.Secret{} - err := j.client.Get(ctx, j.alertmanagerSecret, &alertmanagerSecret) - - if err != nil { - return errors.WithStack(fmt.Errorf("alertmanager: failed to get secret: %w", err)) + if secret == nil { + return errors.WithStack(fmt.Errorf("alertmanager: failed to get secret")) } // Retrieve Alertmanager configuration from secret - alertmanagerConfigContent, ok := alertmanagerSecret.Data[alertmanagerConfigKey] + alertmanagerConfigContent, ok := secret.Data[alertmanagerConfigKey] if !ok { return errors.WithStack(fmt.Errorf("alertmanager: config not found")) } // Retrieve all alertmanager templates from secret templates := make(map[string]string) - for key, value := range alertmanagerSecret.Data { + for key, value := range secret.Data { if strings.HasSuffix(key, templatesSuffix) { templates[key] = string(value) } } - err = j.configure(ctx, alertmanagerConfigContent, templates, tenantID) + err := j.configure(ctx, alertmanagerConfigContent, templates, tenantID) if err != nil { return errors.WithStack(fmt.Errorf("alertmanager: failed to configure: %w", err)) } @@ -96,6 +84,8 @@ func (j Job) Configure(ctx context.Context) error { return nil } +// configure sends the configuration and templates to Mimir Alertmanager's API +// https://grafana.com/docs/mimir/latest/references/http-api/#set-alertmanager-configuration func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, templates map[string]string, tenantID string) error { logger := log.FromContext(ctx) From 6fbcf61be9eb1f576522a4bac92266b8e3c3de30 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:33:10 +0100 Subject: [PATCH 39/44] update alertmanager job --- internal/controller/alertmanager_controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/controller/alertmanager_controller.go b/internal/controller/alertmanager_controller.go index bde782f4..89488104 100644 --- a/internal/controller/alertmanager_controller.go +++ b/internal/controller/alertmanager_controller.go @@ -32,7 +32,7 @@ type AlertmanagerReconciler struct { func SetupAlertmanagerReconciler(mgr ctrl.Manager, conf config.Config) error { r := &AlertmanagerReconciler{ client: mgr.GetClient(), - alertmanagerJob: alertmanager.New(conf, mgr.GetClient()), + alertmanagerJob: alertmanager.New(conf), } // Filter only the Alertmanager secret created by the observability-operator Helm chart @@ -93,7 +93,7 @@ func (r AlertmanagerReconciler) Reconcile(ctx context.Context, req reconcile.Req // Handle create and update events func (r AlertmanagerReconciler) reconcileCreate(ctx context.Context, secret *v1.Secret) (ctrl.Result, error) { // nolint: unparam // Ensure the configuration is set and up to date in Alertmanager - err := r.alertmanagerJob.Configure(ctx) + err := r.alertmanagerJob.Configure(ctx, secret) if err != nil { return ctrl.Result{}, errors.WithStack(err) } From 8cda08b2a16c5d0a846f821b30c530351aa174bc Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:50:58 +0100 Subject: [PATCH 40/44] get base template name --- pkg/alertmanager/alertmanager.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/alertmanager/alertmanager.go b/pkg/alertmanager/alertmanager.go index 361d3c15..7bc6ae06 100644 --- a/pkg/alertmanager/alertmanager.go +++ b/pkg/alertmanager/alertmanager.go @@ -7,6 +7,7 @@ import ( "io" "maps" "net/http" + "path" "slices" "strings" @@ -71,7 +72,10 @@ func (j Job) Configure(ctx context.Context, secret *v1.Secret) error { templates := make(map[string]string) for key, value := range secret.Data { if strings.HasSuffix(key, templatesSuffix) { - templates[key] = string(value) + // Template key/name should not be a path otherwise the request will fail with: + // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path + baseKey := path.Base(key) + templates[baseKey] = string(value) } } @@ -95,9 +99,8 @@ func (j Job) configure(ctx context.Context, alertmanagerConfigContent []byte, te return errors.WithStack(fmt.Errorf("alertmanager: failed to load configuration: %w", err)) } - // Set notification template name - // This must match the key set for the template in configCompat.TemplateFiles. This value should not be a path otherwise the request will fail with: - // > error validating Alertmanager config: invalid template name "/etc/dummy.tmpl": the template name cannot contain any path + // Set template names + // Values set here must match the keys set in requestData.TemplateFiles alertmanagerConfig.Templates = slices.Collect(maps.Keys(templates)) alertmanagerConfigString := alertmanagerConfig.String() From 01ce0f3fe64414b3d54312af3987b53871712881 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:55:56 +0100 Subject: [PATCH 41/44] remove uneeded flags --- helm/observability-operator/templates/deployment.yaml | 2 -- main.go | 4 ---- pkg/config/config.go | 1 - pkg/monitoring/config.go | 3 +-- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/helm/observability-operator/templates/deployment.yaml b/helm/observability-operator/templates/deployment.yaml index 627b745c..3b8a0a91 100644 --- a/helm/observability-operator/templates/deployment.yaml +++ b/helm/observability-operator/templates/deployment.yaml @@ -31,14 +31,12 @@ spec: - --management-cluster-pipeline={{ $.Values.managementCluster.pipeline }} - --management-cluster-region={{ $.Values.managementCluster.region }} # Monitoring configuration - - --alertmanager-secret-name={{ include "alertmanager-secret.name" . }} - --alertmanager-url={{ $.Values.alerting.alertmanagerURL }} - --monitoring-enabled={{ $.Values.monitoring.enabled }} - --monitoring-agent={{ $.Values.monitoring.agent }} - --monitoring-sharding-scale-up-series-count={{ $.Values.monitoring.sharding.scaleUpSeriesCount }} - --monitoring-sharding-scale-down-percentage={{ $.Values.monitoring.sharding.scaleDownPercentage }} - --monitoring-wal-truncate-frequency={{ $.Values.monitoring.wal.truncateFrequency }} - - --namespace={{ include "resource.default.namespace" . }} {{- if .Values.monitoring.prometheusVersion }} - --prometheus-version={{ $.Values.monitoring.prometheusVersion }} {{- end }} diff --git a/main.go b/main.go index 2511ebc7..3e27f8a9 100644 --- a/main.go +++ b/main.go @@ -74,8 +74,6 @@ func main() { "If set the metrics endpoint is served securely") flag.BoolVar(&conf.EnableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") - flag.StringVar(&conf.Namespace, "namespace", "", - "The namespace where the observability-operator is running.") // Management cluster configuration flags. flag.StringVar(&conf.ManagementCluster.BaseDomain, "management-cluster-base-domain", "", @@ -92,8 +90,6 @@ func main() { "The region of the management cluster.") // Monitoring configuration flags. - flag.StringVar(&conf.Monitoring.AlertmanagerSecretName, "alertmanager-secret-name", "", - "The name of the secret containing the Alertmanager configuration.") flag.StringVar(&conf.Monitoring.AlertmanagerURL, "alertmanager-url", "", "The URL of the Alertmanager API.") flag.StringVar(&conf.Monitoring.MonitoringAgent, "monitoring-agent", commonmonitoring.MonitoringAgentAlloy, diff --git a/pkg/config/config.go b/pkg/config/config.go index 8589614e..03702834 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -11,7 +11,6 @@ type Config struct { ProbeAddr string SecureMetrics bool EnableHTTP2 bool - Namespace string ManagementCluster common.ManagementCluster diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go index 6ed9b006..b90c6653 100644 --- a/pkg/monitoring/config.go +++ b/pkg/monitoring/config.go @@ -15,8 +15,7 @@ const MonitoringLabel = "giantswarm.io/monitoring" type Config struct { Enabled bool - AlertmanagerSecretName string - AlertmanagerURL string + AlertmanagerURL string MonitoringAgent string DefaultShardingStrategy sharding.Strategy From a6660609098f6337a839833f53d9102442a3672a Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 18:56:34 +0100 Subject: [PATCH 42/44] restore flags --- helm/observability-operator/templates/deployment.yaml | 2 ++ main.go | 4 ++++ pkg/config/config.go | 1 + pkg/monitoring/config.go | 3 ++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/helm/observability-operator/templates/deployment.yaml b/helm/observability-operator/templates/deployment.yaml index 3b8a0a91..627b745c 100644 --- a/helm/observability-operator/templates/deployment.yaml +++ b/helm/observability-operator/templates/deployment.yaml @@ -31,12 +31,14 @@ spec: - --management-cluster-pipeline={{ $.Values.managementCluster.pipeline }} - --management-cluster-region={{ $.Values.managementCluster.region }} # Monitoring configuration + - --alertmanager-secret-name={{ include "alertmanager-secret.name" . }} - --alertmanager-url={{ $.Values.alerting.alertmanagerURL }} - --monitoring-enabled={{ $.Values.monitoring.enabled }} - --monitoring-agent={{ $.Values.monitoring.agent }} - --monitoring-sharding-scale-up-series-count={{ $.Values.monitoring.sharding.scaleUpSeriesCount }} - --monitoring-sharding-scale-down-percentage={{ $.Values.monitoring.sharding.scaleDownPercentage }} - --monitoring-wal-truncate-frequency={{ $.Values.monitoring.wal.truncateFrequency }} + - --namespace={{ include "resource.default.namespace" . }} {{- if .Values.monitoring.prometheusVersion }} - --prometheus-version={{ $.Values.monitoring.prometheusVersion }} {{- end }} diff --git a/main.go b/main.go index bba502f2..fef61049 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,8 @@ func main() { "If set the metrics endpoint is served securely") flag.BoolVar(&conf.EnableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") + flag.StringVar(&conf.Namespace, "namespace", "", + "The namespace where the observability-operator is running.") // Management cluster configuration flags. flag.StringVar(&conf.ManagementCluster.BaseDomain, "management-cluster-base-domain", "", @@ -90,6 +92,8 @@ func main() { "The region of the management cluster.") // Monitoring configuration flags. + flag.StringVar(&conf.Monitoring.AlertmanagerSecretName, "alertmanager-secret-name", "", + "The name of the secret containing the Alertmanager configuration.") flag.StringVar(&conf.Monitoring.AlertmanagerURL, "alertmanager-url", "", "The URL of the Alertmanager API.") flag.StringVar(&conf.Monitoring.MonitoringAgent, "monitoring-agent", commonmonitoring.MonitoringAgentAlloy, diff --git a/pkg/config/config.go b/pkg/config/config.go index 03702834..8589614e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -11,6 +11,7 @@ type Config struct { ProbeAddr string SecureMetrics bool EnableHTTP2 bool + Namespace string ManagementCluster common.ManagementCluster diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go index b90c6653..6ed9b006 100644 --- a/pkg/monitoring/config.go +++ b/pkg/monitoring/config.go @@ -15,7 +15,8 @@ const MonitoringLabel = "giantswarm.io/monitoring" type Config struct { Enabled bool - AlertmanagerURL string + AlertmanagerSecretName string + AlertmanagerURL string MonitoringAgent string DefaultShardingStrategy sharding.Strategy From 5b639a1a7bad2a62d13a75d0d7c414ffaaade9a1 Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 19:07:15 +0100 Subject: [PATCH 43/44] Revert "Merge remote-tracking branch 'origin/alertmanager-config-helm' into alertmanager-config" This reverts commit b3f9a8e5bb89cea7b2da3caf9e7331455dc340f3, reversing changes made to cc9987ddf76085add749e9f6d11a716af7c34a41. --- .../alertmanager.yaml.helm-template | 504 ------------------ .../alertmanager/notification-template.tmpl | 64 --- .../url-template.tmpl.helm-template | 18 - .../templates/alertmanager/secret.yaml | 20 - helm/observability-operator/values.yaml | 2 +- 5 files changed, 1 insertion(+), 607 deletions(-) delete mode 100644 helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template delete mode 100644 helm/observability-operator/files/alertmanager/notification-template.tmpl delete mode 100644 helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template delete mode 100644 helm/observability-operator/templates/alertmanager/secret.yaml diff --git a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template b/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template deleted file mode 100644 index 1ced9a3e..00000000 --- a/helm/observability-operator/files/alertmanager/alertmanager.yaml.helm-template +++ /dev/null @@ -1,504 +0,0 @@ -global: - resolve_timeout: 5m -{{- if .Values.alerting.proxyURL }} - http_config: - proxy_url: {{ .Values.alerting.proxyURL }} -{{- end }} -{{- if .Values.alerting.slackAPIToken }} - slack_api_url: "https://slack.com/api/chat.postMessage" -{{- else }} - slack_api_url: {{ .Values.alerting.slackAPIURL }} -{{- end }} - -route: - group_by: [alertname, cluster_id, installation, status, team] - group_interval: 15m - group_wait: 5m - repeat_interval: 4h - receiver: root - - routes: - - receiver: heartbeat - matchers: - - alertname="Heartbeat" - # TODO(@team-atlas): This label is needed for now because we support legacy and new heartbeat alerts. Lets remove it when we remove https://github.com/giantswarm/prometheus-rules/pull/1094/files#diff-2cc8f3328e242b6c86769bfb52b286c7146e074dd244ebb76a0025c838f33d0fR21 - - type="mimir-heartbeat" - continue: true - group_wait: 30s - group_interval: 30s - repeat_interval: 15m - {{- if eq .Values.managementCluster.pipeline "stable-testing" }} - - receiver: blackhole - matchers: - - cluster_type="workload_cluster" - continue: false - - receiver: blackhole - matchers: - - cluster_id=~"t-.*" - continue: false - - receiver: blackhole - matchers: - - alertname=~"WorkloadClusterApp.*" - continue: false - - receiver: blackhole - matchers: - - alertname="PrometheusMetaOperatorReconcileErrors" - continue: false - - receiver: blackhole - matchers: - - alertname="ClusterUnhealthyPhase" - continue: false - - receiver: blackhole - matchers: - - alertname="ClusterUnhealthyPhase" - - name=~"t-.*" - continue: false - # We don't want to get alerts by workload cluster apps that are failing. - # We select those by checking if the App CR is in a namespace starting with 'org-'. - - receiver: blackhole - matchers: - - alertname="ManagementClusterAppFailed" - - namespace=~"org-.*" - continue: false - {{- end }} - - # Falco noise Slack - - receiver: falco_noise_slack - matchers: - - alertname=~"Falco.*" - continue: false - - - receiver: team_tenet_slack - repeat_interval: 14d - matchers: - - severity=~"page|notify" - - team=~"tenet|tinkerers" - continue: false - - # Team Ops Opsgenie - - receiver: opsgenie_router - matchers: - - severity="page" - continue: true - - # Team Atlas Slack - - receiver: team_atlas_slack - matchers: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - severity="notify" - {{- else }} - - severity=~"page|notify" - {{- end }} - - team="atlas" - - type!="heartbeat" - - alertname!~"Inhibition.*" - - alertname!="Heartbeat" - continue: false - - # Team Celestial Slack - - receiver: team_phoenix_slack - matchers: - - severity=~"page|notify" - - team="celestial" - - sloth_severity=~"page|ticket" - continue: false - - # Team Firecracker Slack - - receiver: team_phoenix_slack - matchers: - - severity=~"page|notify" - - team="firecracker" - - sloth_severity=~"page|ticket" - continue: false - - # Team Phoenix Slack - - receiver: team_phoenix_slack - matchers: - - team="phoenix" - - sloth_severity="page" - - silence="true" - continue: false - - # Team Shield Slack - - receiver: team_shield_slack - matchers: - - severity=~"page|notify" - - team="shield" - continue: false - - # Team BigMac Slack - - receiver: team_bigmac_slack - matchers: - - severity=~"page|notify" - - team="bigmac" - continue: false - - # Team Clippy Slack - # ReRoute to `phoenix` until we change all team ownership labels - - receiver: team_phoenix_slack - matchers: - - severity=~"page|notify" - - team="clippy" - continue: false - - # Team Rocket Slack - - receiver: team_rocket_slack - matchers: - - severity=~"page|notify" - - team="rocket" - continue: false - - # Team Turtles Slack - - receiver: team_turtles_slack - matchers: - - severity=~"page|notify" - - team="turtles" - continue: false - - # Team Honeybadger Slack - - receiver: team_honeybadger_slack - matchers: - - severity=~"page|notify" - - team="honeybadger" - continue: false - -receivers: -- name: root - -- name: heartbeat - webhook_configs: - - send_resolved: false - http_config: - authorization: - type: GenieKey - credentials: {{ .Values.monitoring.opsgenieApiKey }} - follow_redirects: true - enable_http2: true - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - url: https://api.opsgenie.com/v2/heartbeats/{{ .Values.managementCluster.name }}/ping - -{{- if eq .Values.managementCluster.pipeline "stable-testing" }} -- name: blackhole -{{- end }} - -- name: falco_noise_slack - slack_configs: - - channel: '#noise-falco' - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: &slack-actions - - type: button - text: ':green_book: OpsRecipe' - url: '{{`{{ template "__runbookurl" . }}`}}' - style: '{{`{{ if eq .Status "firing" }}primary{{ else }}default{{ end }}`}}' - - type: button - text: ':coffin: Linked PMs' - url: '{{`{{ template "__alert_linked_postmortems" . }}`}}' - - type: button - text: ':mag: Query' - url: '{{`{{ template "__alerturl" . }}`}}' - - type: button - text: ':grafana: Dashboard' - url: '{{`{{ template "__dashboardurl" . }}`}}' - - type: button - text: ':no_bell: Silence' - url: '{{`{{ template "__alert_silence_link" .}}`}}' - style: '{{`{{ if eq .Status "firing" }}danger{{ else }}default{{ end }}`}}' - -- name: team_atlas_slack - slack_configs: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - channel: '#alert-atlas' - {{- else }} - - channel: '#alert-atlas-test' - {{- end }} - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_phoenix_slack - slack_configs: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - channel: '#alert-phoenix' - {{- else }} - - channel: '#alert-phoenix-test' - {{- end }} - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_bigmac_slack - slack_configs: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - channel: '#alert-bigmac' - {{- else }} - - channel: '#alert-bigmac-test' - {{- end }} - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_rocket_slack - slack_configs: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - channel: '#alert-rocket' - {{- else }} - - channel: '#alert-rocket-test' - {{- end }} - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_shield_slack - slack_configs: - - channel: '#alert-shield' - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_turtles_slack - slack_configs: - {{- if eq .Values.managementCluster.pipeline "stable" }} - - channel: '#alert-turtles' - {{- else }} - - channel: '#alert-turtles-test' - {{- end }} - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_tenet_slack - slack_configs: - - channel: '#alert-tenet' - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: team_honeybadger_slack - slack_configs: - - channel: '#alert-honeybadger' - {{- if .Values.alerting.slackAPIToken }} - http_config: - authorization: - type: Bearer - credentials: {{ .Values.alerting.slackAPIToken }} - {{- if .Values.alerting.proxyURL }} - proxy_url: {{ .Values.alerting.proxyURL }} - {{- end }} - {{- end }} - send_resolved: true - actions: *slack-actions - -- name: opsgenie_router - opsgenie_configs: - - api_key: {{ .Values.monitoring.opsgenieApiKey }} - tags: '{{`{{ (index .Alerts 0).Labels.alertname }},{{ (index .Alerts 0).Labels.cluster_type }},{{ (index .Alerts 0).Labels.severity }},{{ (index .Alerts 0).Labels.team }},{{ (index .Alerts 0).Labels.area }},{{ (index .Alerts 0).Labels.service_priority }},{{ (index .Alerts 0).Labels.provider }},{{ (index .Alerts 0).Labels.installation }},{{ (index .Alerts 0).Labels.pipeline }},{{ (index .Alerts 0).Labels.customer }}`}}' - -inhibit_rules: -- source_matchers: - - inhibit_kube_state_metrics_down=true - target_matchers: - - cancel_if_kube_state_metrics_down=true - equal: [cluster_id] - -- source_matchers: - - inhibit_kube_state_metrics_down=true - - cluster_id={{ .Values.managementCluster.name }} - target_matchers: - - cancel_if_mc_kube_state_metrics_down=true - -- source_matchers: - - inhibit_kube_state_metrics_down=true - target_matchers: - - cancel_if_any_kube_state_metrics_down=true - -- source_matchers: - - cluster_status_creating=true - target_matchers: - - cancel_if_cluster_status_creating=true - equal: [cluster_id] - -- source_matchers: - - cluster_status_created=true - target_matchers: - - cancel_if_cluster_status_created=true - equal: [cluster_id] - -- source_matchers: - - cluster_status_updating=true - target_matchers: - - cancel_if_cluster_status_updating=true - equal: [cluster_id] - -- source_matchers: - - cluster_status_updated=true - target_matchers: - - cancel_if_cluster_status_updated=true - equal: [cluster_id] - -- source_matchers: - - cluster_status_deleting=true - target_matchers: - - cancel_if_cluster_status_deleting=true - equal: [cluster_id] - -- source_matchers: - - cluster_with_no_nodepools=true - target_matchers: - - cancel_if_cluster_with_no_nodepools=true - equal: [cluster_id] - -- source_matchers: - - cluster_with_scaling_nodepools=true - target_matchers: - - cancel_if_cluster_with_scaling_nodepools=true - equal: [cluster_id] - -- source_matchers: - - cluster_with_notready_nodepools=true - target_matchers: - - cancel_if_cluster_with_notready_nodepools=true - equal: [cluster_id] - -- source_matchers: - - cluster_control_plane_unhealthy=true - target_matchers: - - cancel_if_cluster_control_plane_unhealthy=true - equal: [cluster_id] - -- source_matchers: - - cluster_control_plane_unhealthy=true - target_matchers: - - cancel_if_any_cluster_control_plane_unhealthy=true - -- source_matchers: - - instance_state_not_running=true - target_matchers: - - cancel_if_instance_state_not_running=true - equal: [node] - -- source_matchers: - - kiam_has_errors=true - target_matchers: - - cancel_if_kiam_has_errors=true - equal: [cluster_id] - -- source_matchers: - - kubelet_down=true - target_matchers: - - cancel_if_kubelet_down=true - equal: [cluster_id, ip] - -- source_matchers: - - control_plane_node_down=true - target_matchers: - - cancel_if_control_plane_node_down=true - equal: [cluster_id] - -- source_matchers: - - outside_working_hours=true - target_matchers: - - cancel_if_outside_working_hours=true - -- source_matchers: - - has_worker_nodes=false - target_matchers: - - cancel_if_cluster_has_no_workers=true - equal: [cluster_id] - -- source_matchers: - - cluster_is_not_running_monitoring_agent=true - target_matchers: - - cancel_if_cluster_is_not_running_monitoring_agent=true - equal: [cluster_id] - -- source_matchers: - - inhibit_monitoring_agent_down=true - target_matchers: - - cancel_if_monitoring_agent_down=true - equal: [cluster_id] - -- source_matchers: - - stack_failed=true - target_matchers: - - cancel_if_stack_failed=true - -# Source: https://github.com/giantswarm/prometheus-rules/blob/main/helm/prometheus-rules/templates/kaas/turtles/alerting-rules/inhibit.nodes.rules.yml -- source_matchers: - - node_not_ready=true - target_matchers: - - cancel_if_node_not_ready=true - equal: [cluster_id, node] - -# Source: https://github.com/giantswarm/prometheus-rules/blob/main/helm/prometheus-rules/templates/kaas/turtles/alerting-rules/inhibit.nodes.rules.yml -- source_matchers: - - node_unschedulable=true - target_matchers: - - cancel_if_node_unschedulable=true - equal: [cluster_id, node] diff --git a/helm/observability-operator/files/alertmanager/notification-template.tmpl b/helm/observability-operator/files/alertmanager/notification-template.tmpl deleted file mode 100644 index acc60e21..00000000 --- a/helm/observability-operator/files/alertmanager/notification-template.tmpl +++ /dev/null @@ -1,64 +0,0 @@ -{{ define "__alertmanager" }}Alertmanager{{ end }} - -{{ define "slack.default.title" }}{{ .Status | toUpper }}[{{ if eq .Status "firing" }}{{ .Alerts.Firing | len }}{{- else }}{{ .Alerts.Resolved | len }}{{- end }}] {{ (index .Alerts 0).Labels.alertname }} - Team {{ (index .Alerts 0).Labels.team }}{{ end }} -{{ define "slack.default.username" }}{{ template "__alertmanager" . }}{{ end }} -{{ define "slack.default.fallback" }}{{ template "slack.default.title" . }} | {{ template "slack.default.titlelink" . }}{{ end }} -{{ define "slack.default.pretext" }}{{ end }} -{{ define "slack.default.titlelink" }}{{ template "__alerturl" . }}{{ end }} -{{ define "slack.default.iconemoji" }}{{ end }} -{{ define "slack.default.iconurl" }}{{ end }} -{{ define "slack.default.text" }}*Cluster:* {{ (index .Alerts 0).Labels.installation }}{{ if (index .Alerts 0).Labels.cluster_id }} / {{ (index .Alerts 0).Labels.cluster_id }}{{ end }}{{ if (index .Alerts 0).Labels.service }} / {{ (index .Alerts 0).Labels.service }}{{ end }} -*Area:* {{ (index .Alerts 0).Labels.area }} / {{ (index .Alerts 0).Labels.topic }} -{{- if (index .Alerts 0).Annotations.description }} -*Instances* -{{ if eq .Status "firing" }} -{{ range .Alerts.Firing }} -:fire: {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{- end }} -{{ else }} -{{ range .Alerts.Resolved }} -:success: {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{- end }} -{{ end }} -{{- end }} -{{ end }} - -{{ define "opsgenie.default.message" }}{{ .GroupLabels.installation }} / {{ .GroupLabels.cluster_id }}{{ if (index .Alerts 0).Labels.service }} / {{ (index .Alerts 0).Labels.service }}{{ end }} - {{ index (index .Alerts.Firing 0).Labels `alertname`}}{{ end }} -{{ define "opsgenie.default.source" }}{{ template "__alertmanager" . }}{{ end }} -{{ define "opsgenie.default.description" }}* Team: {{ (index .Alerts 0).Labels.team }} -* Area: {{ (index .Alerts 0).Labels.area }} / {{ (index .Alerts 0).Labels.topic }} - -* Instances:{{ range .Alerts.Firing }} -🔥 {{ if .Labels.instance }}{{ .Labels.instance }}: {{ end }}{{ .Annotations.description }}{{ end }} - ---- - -{{ if (index .Alerts 0).Annotations.opsrecipe -}} -📗 Runbook: {{ template "__runbookurl" . }} -{{ end -}} -{{ if (index .Alerts 0).Annotations.dashboard -}} -📈 Dashboard: {{ template "__dashboardurl" . }} -{{ end -}} -👀 Explore: {{ template "__queryurl" . }} - ---- - -{{ if not (index .Alerts 0).Annotations.opsrecipe }}⚠️ There is no **runbook** for this alert, time to get your pen.{{- end }} -{{ if not (index .Alerts 0).Annotations.dashboard }}⚠️ There is no **dashboard** for this alert, time to sketch.{{- end }} -{{- end }} - -# This builds the silence URL. We exclude the alertname in the range -# to avoid the issue of having trailing comma separator (%2C) at the end -# of the generated URL -{{ define "__alert_silence_link" -}} - {{ .ExternalURL }}/#/silences/new?filter=%7B - {{- range .CommonLabels.SortedPairs -}} - {{- if ne .Name "alertname" -}} - {{- .Name }}%3D"{{- .Value -}}"%2C%20 - {{- end -}} - {{- end -}} - alertname%3D"{{ .CommonLabels.alertname }}"%7D -{{- end }} - -# Link to related PMs -{{ define "__alert_linked_postmortems" -}} -https://github.com/giantswarm/giantswarm/issues?q=is%3Aissue+is%3Aopen+label%3Apostmortem+label%3Aalert%2F{{ .CommonLabels.alertname }} -{{- end }} diff --git a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template b/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template deleted file mode 100644 index b93f8937..00000000 --- a/helm/observability-operator/files/alertmanager/url-template.tmpl.helm-template +++ /dev/null @@ -1,18 +0,0 @@ -{{` -{{ define "__alerturl" }} -`}}{{ .Values.alerting.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find -{{ end }} - -{{ define "__dashboardurl" -}} -{{ if match "^https://.+" (index .Alerts 0).Annotations.dashboard }}{{ (index .Alerts 0).Annotations.dashboard }} -{{ else }} -`}}{{ .Values.alerting.grafanaAddress }}{{`/d/{{ (index .Alerts 0).Annotations.dashboard }} -{{ end }} -{{- end }} - -{{ define "__queryurl" }} -`}}{{ .Values.alerting.grafanaAddress }}{{`/alerting/Mimir/{{ .CommonLabels.alertname }}/find -{{ end }} - -{{ define "__runbookurl" -}}https://intranet.giantswarm.io/docs/support-and-ops/ops-recipes/{{ (index .Alerts 0).Annotations.opsrecipe }}{{- end }} -`}} diff --git a/helm/observability-operator/templates/alertmanager/secret.yaml b/helm/observability-operator/templates/alertmanager/secret.yaml deleted file mode 100644 index 6c50a26a..00000000 --- a/helm/observability-operator/templates/alertmanager/secret.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - labels: - {{- include "labels.common" . | nindent 4 }} - name: {{ include "alertmanager-secret.name" . }} - namespace: {{ include "resource.default.namespace" . }} -data: - {{- /* Template all .helm-template files found in files/alertmanager with values under alertmanager key */ -}} - {{ range $path, $_ := .Files.Glob "files/alertmanager/*.helm-template" }} - {{ base $path | trimSuffix ".helm-template" }}: {{ tpl ($.Files.Get $path) $ | b64enc }} - {{ end }} - - {{- /* Add all other non .helm-template files found in files/alertmanager */ -}} - {{ range $path, $_ := .Files.Glob "files/alertmanager/*" }} - {{ if not (hasSuffix ".helm-template" $path) }} - {{ base $path }}: {{ ($.Files.Get $path) | b64enc }} - {{ end }} - {{ end }} -type: Opaque diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index 23e398b9..d3a8fa30 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -15,7 +15,7 @@ managementCluster: pipeline: pipeline region: region -alerting: +alertmanager: alertmanagerURL: "" grafanaAddress: "" proxyURL: "" From a91e5372c86aa76af4d3a198db574da8b66276db Mon Sep 17 00:00:00 2001 From: Theo Brigitte Date: Sun, 15 Dec 2024 19:07:52 +0100 Subject: [PATCH 44/44] rename alertmanager to alerting in values.yaml --- helm/observability-operator/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/observability-operator/values.yaml b/helm/observability-operator/values.yaml index d3a8fa30..23e398b9 100644 --- a/helm/observability-operator/values.yaml +++ b/helm/observability-operator/values.yaml @@ -15,7 +15,7 @@ managementCluster: pipeline: pipeline region: region -alertmanager: +alerting: alertmanagerURL: "" grafanaAddress: "" proxyURL: ""