Remove HipChat (#2281)
Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
parent
ce5d523596
commit
1cba0c7a37
|
@ -1,5 +1,6 @@
|
|||
## 0.21.0-rc.0 / 2020-06-05
|
||||
|
||||
* [CHANGE] [HipChat] Remove HipChat integration as it is end-of-life. #2282
|
||||
* [CHANGE] [amtool] Remove default assignment of environment variables. #2161
|
||||
* [CHANGE] [PagerDuty] Enforce 512KB event size limit. #2225
|
||||
* [ENHANCEMENT] [amtool] Add `cluster` command to show cluster and peer statuses. #2256
|
||||
|
|
|
@ -525,15 +525,15 @@ func TestSilenceFiltering(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestReceiversMatchFilter(t *testing.T) {
|
||||
receivers := []string{"pagerduty", "slack", "hipchat"}
|
||||
receivers := []string{"pagerduty", "slack", "pushover"}
|
||||
|
||||
filter, err := regexp.Compile(fmt.Sprintf("^(?:%s)$", "hip.*"))
|
||||
filter, err := regexp.Compile(fmt.Sprintf("^(?:%s)$", "push.*"))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
}
|
||||
require.True(t, receiversMatchFilter(receivers, filter))
|
||||
|
||||
filter, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", "hip"))
|
||||
filter, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", "push"))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -48,7 +48,6 @@ import (
|
|||
"github.com/prometheus/alertmanager/nflog"
|
||||
"github.com/prometheus/alertmanager/notify"
|
||||
"github.com/prometheus/alertmanager/notify/email"
|
||||
"github.com/prometheus/alertmanager/notify/hipchat"
|
||||
"github.com/prometheus/alertmanager/notify/opsgenie"
|
||||
"github.com/prometheus/alertmanager/notify/pagerduty"
|
||||
"github.com/prometheus/alertmanager/notify/pushover"
|
||||
|
@ -157,9 +156,6 @@ func buildReceiverIntegrations(nc *config.Receiver, tmpl *template.Template, log
|
|||
for i, c := range nc.SlackConfigs {
|
||||
add("slack", i, c, func(l log.Logger) (notify.Notifier, error) { return slack.New(c, tmpl, l) })
|
||||
}
|
||||
for i, c := range nc.HipchatConfigs {
|
||||
add("hipchat", i, c, func(l log.Logger) (notify.Notifier, error) { return hipchat.New(c, tmpl, l) })
|
||||
}
|
||||
for i, c := range nc.VictorOpsConfigs {
|
||||
add("victorops", i, c, func(l log.Logger) (notify.Notifier, error) { return victorops.New(c, tmpl, l) })
|
||||
}
|
||||
|
|
|
@ -308,26 +308,6 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
sc.APIURL = c.Global.SlackAPIURL
|
||||
}
|
||||
}
|
||||
for _, hc := range rcv.HipchatConfigs {
|
||||
if hc.HTTPConfig == nil {
|
||||
hc.HTTPConfig = c.Global.HTTPConfig
|
||||
}
|
||||
if hc.APIURL == nil {
|
||||
if c.Global.HipchatAPIURL == nil {
|
||||
return fmt.Errorf("no global Hipchat API URL set")
|
||||
}
|
||||
hc.APIURL = c.Global.HipchatAPIURL
|
||||
}
|
||||
if !strings.HasSuffix(hc.APIURL.Path, "/") {
|
||||
hc.APIURL.Path += "/"
|
||||
}
|
||||
if hc.AuthToken == "" {
|
||||
if c.Global.HipchatAuthToken == "" {
|
||||
return fmt.Errorf("no global Hipchat Auth Token set")
|
||||
}
|
||||
hc.AuthToken = c.Global.HipchatAuthToken
|
||||
}
|
||||
}
|
||||
for _, poc := range rcv.PushoverConfigs {
|
||||
if poc.HTTPConfig == nil {
|
||||
poc.HTTPConfig = c.Global.HTTPConfig
|
||||
|
@ -459,7 +439,6 @@ func DefaultGlobalConfig() GlobalConfig {
|
|||
SMTPHello: "localhost",
|
||||
SMTPRequireTLS: true,
|
||||
PagerdutyURL: mustParseURL("https://events.pagerduty.com/v2/enqueue"),
|
||||
HipchatAPIURL: mustParseURL("https://api.hipchat.com/"),
|
||||
OpsGenieAPIURL: mustParseURL("https://api.opsgenie.com/"),
|
||||
WeChatAPIURL: mustParseURL("https://qyapi.weixin.qq.com/cgi-bin/"),
|
||||
VictorOpsAPIURL: mustParseURL("https://alert.victorops.com/integrations/generic/20131114/alert/"),
|
||||
|
@ -574,8 +553,6 @@ type GlobalConfig struct {
|
|||
SMTPRequireTLS bool `yaml:"smtp_require_tls,omitempty" json:"smtp_require_tls,omitempty"`
|
||||
SlackAPIURL *SecretURL `yaml:"slack_api_url,omitempty" json:"slack_api_url,omitempty"`
|
||||
PagerdutyURL *URL `yaml:"pagerduty_url,omitempty" json:"pagerduty_url,omitempty"`
|
||||
HipchatAPIURL *URL `yaml:"hipchat_api_url,omitempty" json:"hipchat_api_url,omitempty"`
|
||||
HipchatAuthToken Secret `yaml:"hipchat_auth_token,omitempty" json:"hipchat_auth_token,omitempty"`
|
||||
OpsGenieAPIURL *URL `yaml:"opsgenie_api_url,omitempty" json:"opsgenie_api_url,omitempty"`
|
||||
OpsGenieAPIKey Secret `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"`
|
||||
WeChatAPIURL *URL `yaml:"wechat_api_url,omitempty" json:"wechat_api_url,omitempty"`
|
||||
|
@ -708,7 +685,6 @@ type Receiver struct {
|
|||
|
||||
EmailConfigs []*EmailConfig `yaml:"email_configs,omitempty" json:"email_configs,omitempty"`
|
||||
PagerdutyConfigs []*PagerdutyConfig `yaml:"pagerduty_configs,omitempty" json:"pagerduty_configs,omitempty"`
|
||||
HipchatConfigs []*HipchatConfig `yaml:"hipchat_configs,omitempty" json:"hipchat_configs,omitempty"`
|
||||
SlackConfigs []*SlackConfig `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"`
|
||||
WebhookConfigs []*WebhookConfig `yaml:"webhook_configs,omitempty" json:"webhook_configs,omitempty"`
|
||||
OpsGenieConfigs []*OpsGenieConfig `yaml:"opsgenie_configs,omitempty" json:"opsgenie_configs,omitempty"`
|
||||
|
|
|
@ -326,7 +326,7 @@ func TestHideConfigSecrets(t *testing.T) {
|
|||
|
||||
// String method must not reveal authentication credentials.
|
||||
s := c.String()
|
||||
if strings.Count(s, "<secret>") != 15 || strings.Contains(s, "mysecret") {
|
||||
if strings.Count(s, "<secret>") != 13 || strings.Contains(s, "mysecret") {
|
||||
t.Fatal("config's String method reveals authentication credentials.")
|
||||
}
|
||||
}
|
||||
|
@ -548,18 +548,16 @@ func TestEmptyFieldsAndRegex(t *testing.T) {
|
|||
var expectedConf = Config{
|
||||
|
||||
Global: &GlobalConfig{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
ResolveTimeout: model.Duration(5 * time.Minute),
|
||||
SMTPSmarthost: HostPort{Host: "localhost", Port: "25"},
|
||||
SMTPFrom: "alertmanager@example.org",
|
||||
HipchatAuthToken: "mysecret",
|
||||
HipchatAPIURL: mustParseURL("https://hipchat.foobar.org/"),
|
||||
SlackAPIURL: (*SecretURL)(mustParseURL("http://slack.example.com/")),
|
||||
SMTPRequireTLS: true,
|
||||
PagerdutyURL: mustParseURL("https://events.pagerduty.com/v2/enqueue"),
|
||||
OpsGenieAPIURL: mustParseURL("https://api.opsgenie.com/"),
|
||||
WeChatAPIURL: mustParseURL("https://qyapi.weixin.qq.com/cgi-bin/"),
|
||||
VictorOpsAPIURL: mustParseURL("https://alert.victorops.com/integrations/generic/20131114/alert/"),
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
ResolveTimeout: model.Duration(5 * time.Minute),
|
||||
SMTPSmarthost: HostPort{Host: "localhost", Port: "25"},
|
||||
SMTPFrom: "alertmanager@example.org",
|
||||
SlackAPIURL: (*SecretURL)(mustParseURL("http://slack.example.com/")),
|
||||
SMTPRequireTLS: true,
|
||||
PagerdutyURL: mustParseURL("https://events.pagerduty.com/v2/enqueue"),
|
||||
OpsGenieAPIURL: mustParseURL("https://api.opsgenie.com/"),
|
||||
WeChatAPIURL: mustParseURL("https://qyapi.weixin.qq.com/cgi-bin/"),
|
||||
VictorOpsAPIURL: mustParseURL("https://alert.victorops.com/integrations/generic/20131114/alert/"),
|
||||
},
|
||||
|
||||
Templates: []string{
|
||||
|
|
|
@ -80,18 +80,6 @@ var (
|
|||
Footer: `{{ template "slack.default.footer" . }}`,
|
||||
}
|
||||
|
||||
// DefaultHipchatConfig defines default values for Hipchat configurations.
|
||||
DefaultHipchatConfig = HipchatConfig{
|
||||
NotifierConfig: NotifierConfig{
|
||||
VSendResolved: false,
|
||||
},
|
||||
Color: `{{ if eq .Status "firing" }}red{{ else }}green{{ end }}`,
|
||||
From: `{{ template "hipchat.default.from" . }}`,
|
||||
Notify: false,
|
||||
Message: `{{ template "hipchat.default.message" . }}`,
|
||||
MessageFormat: `text`,
|
||||
}
|
||||
|
||||
// DefaultOpsGenieConfig defines default values for OpsGenie configurations.
|
||||
DefaultOpsGenieConfig = OpsGenieConfig{
|
||||
NotifierConfig: NotifierConfig{
|
||||
|
@ -372,35 +360,6 @@ func (c *SlackConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
return unmarshal((*plain)(c))
|
||||
}
|
||||
|
||||
// HipchatConfig configures notifications via Hipchat.
|
||||
type HipchatConfig struct {
|
||||
NotifierConfig `yaml:",inline" json:",inline"`
|
||||
|
||||
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
|
||||
|
||||
APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"`
|
||||
AuthToken Secret `yaml:"auth_token,omitempty" json:"auth_token,omitempty"`
|
||||
RoomID string `yaml:"room_id,omitempty" json:"room_id,omitempty"`
|
||||
From string `yaml:"from,omitempty" json:"from,omitempty"`
|
||||
Notify bool `yaml:"notify,omitempty" json:"notify,omitempty"`
|
||||
Message string `yaml:"message,omitempty" json:"message,omitempty"`
|
||||
MessageFormat string `yaml:"message_format,omitempty" json:"message_format,omitempty"`
|
||||
Color string `yaml:"color,omitempty" json:"color,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *HipchatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
*c = DefaultHipchatConfig
|
||||
type plain HipchatConfig
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
return err
|
||||
}
|
||||
if c.RoomID == "" {
|
||||
return fmt.Errorf("missing room id in Hipchat config")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WebhookConfig configures notifications via a generic webhook.
|
||||
type WebhookConfig struct {
|
||||
NotifierConfig `yaml:",inline" json:",inline"`
|
||||
|
|
|
@ -148,23 +148,6 @@ details:
|
|||
}
|
||||
}
|
||||
|
||||
func TestHipchatRoomIDIsPresent(t *testing.T) {
|
||||
in := `
|
||||
room_id: ''
|
||||
`
|
||||
var cfg HipchatConfig
|
||||
err := yaml.UnmarshalStrict([]byte(in), &cfg)
|
||||
|
||||
expected := "missing room id in Hipchat config"
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("no error returned, expected:\n%v", expected)
|
||||
}
|
||||
if err.Error() != expected {
|
||||
t.Errorf("\nexpected:\n%v\ngot:\n%v", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWebhookURLIsPresent(t *testing.T) {
|
||||
in := `{}`
|
||||
var cfg WebhookConfig
|
||||
|
|
|
@ -4,8 +4,6 @@ global:
|
|||
smtp_auth_username: ''
|
||||
smtp_auth_password: ''
|
||||
smtp_hello: ''
|
||||
hipchat_auth_token: 'mysecret'
|
||||
hipchat_api_url: 'https://hipchat.foobar.org/'
|
||||
slack_api_url: 'https://slack.com/webhook'
|
||||
|
||||
|
||||
|
|
|
@ -5,10 +5,6 @@ global:
|
|||
smtp_auth_username: 'alertmanager'
|
||||
smtp_auth_password: "multiline\nmysecret"
|
||||
smtp_hello: "host.example.org"
|
||||
# The auth token for Hipchat.
|
||||
hipchat_auth_token: "mysecret"
|
||||
# Alternative host for Hipchat.
|
||||
hipchat_api_url: 'https://hipchat.foobar.org/'
|
||||
slack_api_url: "http://mysecret.example.com/"
|
||||
http_config:
|
||||
proxy_url: 'http://127.0.0.1:1025'
|
||||
|
@ -123,12 +119,6 @@ receivers:
|
|||
- name: 'team-DB-pager'
|
||||
pagerduty_configs:
|
||||
- routing_key: "mysecret"
|
||||
- name: 'team-X-hipchat'
|
||||
hipchat_configs:
|
||||
- auth_token: "mysecret"
|
||||
room_id: 85
|
||||
message_format: html
|
||||
notify: true
|
||||
- name: victorOps-receiver
|
||||
victorops_configs:
|
||||
- api_key: mysecret
|
||||
|
|
|
@ -4,10 +4,6 @@ global:
|
|||
smtp_from: 'alertmanager@example.org'
|
||||
smtp_auth_username: 'alertmanager'
|
||||
smtp_auth_password: 'password'
|
||||
# The auth token for Hipchat.
|
||||
hipchat_auth_token: '1234556789'
|
||||
# Alternative host for Hipchat.
|
||||
hipchat_api_url: 'https://hipchat.foobar.org/'
|
||||
|
||||
# The directory from which notification templates are read.
|
||||
templates:
|
||||
|
@ -126,10 +122,3 @@ receivers:
|
|||
- name: 'team-DB-pager'
|
||||
pagerduty_configs:
|
||||
- service_key: <team-DB-key>
|
||||
|
||||
- name: 'team-X-hipchat'
|
||||
hipchat_configs:
|
||||
- auth_token: <auth_token>
|
||||
room_id: 85
|
||||
message_format: html
|
||||
notify: true
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
// Copyright 2019 Prometheus Team
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package hipchat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
commoncfg "github.com/prometheus/common/config"
|
||||
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/notify"
|
||||
"github.com/prometheus/alertmanager/template"
|
||||
"github.com/prometheus/alertmanager/types"
|
||||
)
|
||||
|
||||
// Notifier implements a Notifier for Hipchat notifications.
|
||||
type Notifier struct {
|
||||
conf *config.HipchatConfig
|
||||
tmpl *template.Template
|
||||
logger log.Logger
|
||||
client *http.Client
|
||||
retrier *notify.Retrier
|
||||
}
|
||||
|
||||
// New returns a new Hipchat notification handler.
|
||||
func New(c *config.HipchatConfig, t *template.Template, l log.Logger) (*Notifier, error) {
|
||||
client, err := commoncfg.NewClientFromConfig(*c.HTTPConfig, "hipchat", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Notifier{
|
||||
conf: c,
|
||||
tmpl: t,
|
||||
logger: l,
|
||||
client: client,
|
||||
// Response codes 429 (rate limiting) and 5xx can potentially recover.
|
||||
// 2xx response codes indicate successful requests.
|
||||
// https://developer.atlassian.com/hipchat/guide/hipchat-rest-api/api-response-codes
|
||||
retrier: ¬ify.Retrier{RetryCodes: []int{http.StatusTooManyRequests}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type hipchatReq struct {
|
||||
From string `json:"from"`
|
||||
Notify bool `json:"notify"`
|
||||
Message string `json:"message"`
|
||||
MessageFormat string `json:"message_format"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
// Notify implements the Notifier interface.
|
||||
func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
|
||||
var err error
|
||||
var msg string
|
||||
var (
|
||||
data = notify.GetTemplateData(ctx, n.tmpl, as, n.logger)
|
||||
tmplText = notify.TmplText(n.tmpl, data, &err)
|
||||
tmplHTML = notify.TmplHTML(n.tmpl, data, &err)
|
||||
roomid = tmplText(n.conf.RoomID)
|
||||
apiURL = n.conf.APIURL.Copy()
|
||||
)
|
||||
apiURL.Path += fmt.Sprintf("v2/room/%s/notification", roomid)
|
||||
q := apiURL.Query()
|
||||
q.Set("auth_token", string(n.conf.AuthToken))
|
||||
apiURL.RawQuery = q.Encode()
|
||||
|
||||
if n.conf.MessageFormat == "html" {
|
||||
msg = tmplHTML(n.conf.Message)
|
||||
} else {
|
||||
msg = tmplText(n.conf.Message)
|
||||
}
|
||||
|
||||
req := &hipchatReq{
|
||||
From: tmplText(n.conf.From),
|
||||
Notify: n.conf.Notify,
|
||||
Message: msg,
|
||||
MessageFormat: n.conf.MessageFormat,
|
||||
Color: tmplText(n.conf.Color),
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := json.NewEncoder(&buf).Encode(req); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := notify.PostJSON(ctx, n.client, apiURL.String(), &buf)
|
||||
if err != nil {
|
||||
return true, notify.RedactURL(err)
|
||||
}
|
||||
defer notify.Drain(resp)
|
||||
|
||||
return n.retrier.Check(resp.StatusCode, nil)
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright 2019 Prometheus Team
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package hipchat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
commoncfg "github.com/prometheus/common/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/notify/test"
|
||||
)
|
||||
|
||||
func TestHipchatRetry(t *testing.T) {
|
||||
notifier, err := New(
|
||||
&config.HipchatConfig{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
},
|
||||
test.CreateTmpl(t),
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
retryCodes := append(test.DefaultRetryCodes(), http.StatusTooManyRequests)
|
||||
for statusCode, expected := range test.RetryTests(retryCodes) {
|
||||
actual, _ := notifier.retrier.Check(statusCode, nil)
|
||||
require.Equal(t, expected, actual, fmt.Sprintf("error on status %d", statusCode))
|
||||
}
|
||||
}
|
||||
|
||||
func TestHipchatRedactedURL(t *testing.T) {
|
||||
ctx, u, fn := test.GetContextWithCancelingURL()
|
||||
defer fn()
|
||||
|
||||
token := "secret_token"
|
||||
notifier, err := New(
|
||||
&config.HipchatConfig{
|
||||
APIURL: &config.URL{URL: u},
|
||||
AuthToken: config.Secret(token),
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
},
|
||||
test.CreateTmpl(t),
|
||||
log.NewNopLogger(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
test.AssertNotifyLeaksNoSecret(t, ctx, notifier, token)
|
||||
}
|
|
@ -239,7 +239,6 @@ func newMetrics(r prometheus.Registerer) *metrics {
|
|||
}
|
||||
for _, integration := range []string{
|
||||
"email",
|
||||
"hipchat",
|
||||
"pagerduty",
|
||||
"wechat",
|
||||
"pushover",
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
{{ define "slack.default.footer" }}{{ end }}
|
||||
|
||||
|
||||
{{ define "hipchat.default.from" }}{{ template "__alertmanager" . }}{{ end }}
|
||||
{{ define "hipchat.default.message" }}{{ template "__subject" . }}{{ end }}
|
||||
|
||||
|
||||
{{ define "pagerduty.default.description" }}{{ template "__subject" . }}{{ end }}
|
||||
{{ define "pagerduty.default.client" }}{{ template "__alertmanager" . }}{{ end }}
|
||||
{{ define "pagerduty.default.clientURL" }}{{ template "__alertmanagerURL" . }}{{ end }}
|
||||
|
|
Loading…
Reference in New Issue