diff --git a/config/config.go b/config/config.go index b7dac403ab..7422dd8998 100644 --- a/config/config.go +++ b/config/config.go @@ -26,7 +26,7 @@ import ( commoncfg "github.com/prometheus/common/config" "github.com/prometheus/common/model" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) const secretToken = "" @@ -41,25 +41,76 @@ func init() { secretTokenJSON = string(b) } -// Secret is a string that must not be revealed on marshaling. -type Secret string +// Secret is a string that must not be revealed on marshaling unless unsafe flag is set. +type Secret struct { + string + + unsafe bool +} + +func NewSecret(str string) *Secret { + return &Secret{string: str, unsafe: false} +} + +func NewUnsafeSecret(str string) *Secret { + return &Secret{string: str, unsafe: true} +} + +func (s *Secret) String() string { + if s == nil { + return "" + } + return s.string +} // MarshalYAML implements the yaml.Marshaler interface for Secret. func (s Secret) MarshalYAML() (interface{}, error) { - if s != "" { + if s.unsafe { + return s.string, nil + } + + if s.string != "" { return secretToken, nil } + return nil, nil } // UnmarshalYAML implements the yaml.Unmarshaler interface for Secret. func (s *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error { - type plain Secret - return unmarshal((*plain)(s)) + var str string + if err := unmarshal(&str); err != nil { + return err + } + + if str == "" { + return errors.New("secret value cannot be empty") + } + + s.string = str + return nil +} + +// UnmarshalYAML implements the yaml.Unmarshaler interface for Secret. +func (s *Secret) UnmarshalJSON(data []byte) error { + var str string + if err := json.Unmarshal(data, &str); err != nil { + return err + } + + if str == "" { + return errors.New("secret value cannot be empty") + } + + s.string = str + return nil } // MarshalJSON implements the json.Marshaler interface for Secret. func (s Secret) MarshalJSON() ([]byte, error) { + if s.unsafe { + return json.Marshal(s.string) + } return json.Marshal(secretToken) } @@ -118,12 +169,28 @@ func (u *URL) UnmarshalJSON(data []byte) error { return nil } -// SecretURL is a URL that must not be revealed on marshaling. -type SecretURL URL +// SecretURL is a URL that must not be revealed on marshaling unless unsafe flag is set. +type SecretURL struct { + URL + + unsafe bool +} + +func NewSecretURL(u URL) *SecretURL { + return &SecretURL{URL: u, unsafe: false} +} + +func NewUnsafeSecretURL(u URL) *SecretURL { + return &SecretURL{URL: u, unsafe: true} +} // MarshalYAML implements the yaml.Marshaler interface for SecretURL. func (s SecretURL) MarshalYAML() (interface{}, error) { - if s.URL != nil { + if s.unsafe { + return s.URL.MarshalYAML() + } + + if s.URL.URL != nil { return secretToken, nil } return nil, nil @@ -139,14 +206,23 @@ func (s *SecretURL) UnmarshalYAML(unmarshal func(interface{}) error) error { // the Alertmanager API with amtool), `` needs to be treated // specially, as it isn't a valid URL. if str == secretToken { - s.URL = &url.URL{} + s.URL.URL = &url.URL{} return nil } - return unmarshal((*URL)(s)) + + var u URL + if err := unmarshal(&u); err != nil { + return err + } + s.URL = u + return nil } // MarshalJSON implements the json.Marshaler interface for SecretURL. func (s SecretURL) MarshalJSON() ([]byte, error) { + if s.unsafe { + return s.URL.MarshalJSON() + } return json.Marshal(secretToken) } @@ -156,10 +232,17 @@ func (s *SecretURL) UnmarshalJSON(data []byte) error { // the Alertmanager API with amtool), `` needs to be treated // specially, as it isn't a valid URL. if string(data) == secretToken || string(data) == secretTokenJSON { - s.URL = &url.URL{} + s.URL.URL = &url.URL{} return nil } - return json.Unmarshal(data, (*URL)(s)) + + var u URL + if err := json.Unmarshal(data, &u); err != nil { + return err + } + + s.URL = u + return nil } // Load parses the YAML input s into a Config. @@ -282,10 +365,10 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if ec.AuthUsername == "" { ec.AuthUsername = c.Global.SMTPAuthUsername } - if ec.AuthPassword == "" { + if ec.AuthPassword == nil { ec.AuthPassword = c.Global.SMTPAuthPassword } - if ec.AuthSecret == "" { + if ec.AuthSecret == nil { ec.AuthSecret = c.Global.SMTPAuthSecret } if ec.AuthIdentity == "" { @@ -320,8 +403,9 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if !strings.HasSuffix(hc.APIURL.Path, "/") { hc.APIURL.Path += "/" } - if hc.AuthToken == "" { - if c.Global.HipchatAuthToken == "" { + + if hc.AuthToken == nil { + if c.Global.HipchatAuthToken == nil { return fmt.Errorf("no global Hipchat Auth Token set") } hc.AuthToken = c.Global.HipchatAuthToken @@ -356,8 +440,8 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if !strings.HasSuffix(ogc.APIURL.Path, "/") { ogc.APIURL.Path += "/" } - if ogc.APIKey == "" { - if c.Global.OpsGenieAPIKey == "" { + if ogc.APIKey == nil { + if c.Global.OpsGenieAPIKey == nil { return fmt.Errorf("no global OpsGenie API Key set") } ogc.APIKey = c.Global.OpsGenieAPIKey @@ -375,8 +459,8 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { wcc.APIURL = c.Global.WeChatAPIURL } - if wcc.APISecret == "" { - if c.Global.WeChatAPISecret == "" { + if wcc.APISecret == nil { + if c.Global.WeChatAPISecret == nil { return fmt.Errorf("no global Wechat ApiSecret set") } wcc.APISecret = c.Global.WeChatAPISecret @@ -406,8 +490,8 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if !strings.HasSuffix(voc.APIURL.Path, "/") { voc.APIURL.Path += "/" } - if voc.APIKey == "" { - if c.Global.VictorOpsAPIKey == "" { + if voc.APIKey == nil { + if c.Global.VictorOpsAPIKey == nil { return fmt.Errorf("no global VictorOps API Key set") } voc.APIKey = c.Global.VictorOpsAPIKey @@ -500,21 +584,21 @@ type GlobalConfig struct { SMTPHello string `yaml:"smtp_hello,omitempty" json:"smtp_hello,omitempty"` SMTPSmarthost string `yaml:"smtp_smarthost,omitempty" json:"smtp_smarthost,omitempty"` SMTPAuthUsername string `yaml:"smtp_auth_username,omitempty" json:"smtp_auth_username,omitempty"` - SMTPAuthPassword Secret `yaml:"smtp_auth_password,omitempty" json:"smtp_auth_password,omitempty"` - SMTPAuthSecret Secret `yaml:"smtp_auth_secret,omitempty" json:"smtp_auth_secret,omitempty"` + SMTPAuthPassword *Secret `yaml:"smtp_auth_password,omitempty" json:"smtp_auth_password,omitempty"` + SMTPAuthSecret *Secret `yaml:"smtp_auth_secret,omitempty" json:"smtp_auth_secret,omitempty"` SMTPAuthIdentity string `yaml:"smtp_auth_identity,omitempty" json:"smtp_auth_identity,omitempty"` 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"` + 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"` + OpsGenieAPIKey *Secret `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"` WeChatAPIURL *URL `yaml:"wechat_api_url,omitempty" json:"wechat_api_url,omitempty"` - WeChatAPISecret Secret `yaml:"wechat_api_secret,omitempty" json:"wechat_api_secret,omitempty"` + WeChatAPISecret *Secret `yaml:"wechat_api_secret,omitempty" json:"wechat_api_secret,omitempty"` WeChatAPICorpID string `yaml:"wechat_api_corp_id,omitempty" json:"wechat_api_corp_id,omitempty"` VictorOpsAPIURL *URL `yaml:"victorops_api_url,omitempty" json:"victorops_api_url,omitempty"` - VictorOpsAPIKey Secret `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"` + VictorOpsAPIKey *Secret `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"` } // UnmarshalYAML implements the yaml.Unmarshaler interface for GlobalConfig. diff --git a/config/config_test.go b/config/config_test.go index 94aac38dba..fec01206ae 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -25,7 +25,7 @@ import ( commoncfg "github.com/prometheus/common/config" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) func TestLoadEmptyString(t *testing.T) { @@ -343,11 +343,11 @@ func TestJSONMarshal(t *testing.T) { } } -func TestJSONMarshalSecret(t *testing.T) { +func TestMarshalSecret(t *testing.T) { test := struct { - S Secret + S *Secret }{ - S: Secret("test"), + S: NewSecret("test"), } c, err := json.Marshal(test) @@ -358,6 +358,68 @@ func TestJSONMarshalSecret(t *testing.T) { // u003c -> "<" // u003e -> ">" require.Equal(t, "{\"S\":\"\\u003csecret\\u003e\"}", string(c), "Secret not properly elided.") + + c, err = yaml.Marshal(test) + if err != nil { + t.Fatal(err) + } + + // u003c -> "<" + // u003e -> ">" + require.Equal(t, "s: \u003csecret\u003e\n", string(c), "Secret not properly elided.") +} + +func TestMarshalUnsafeSecret(t *testing.T) { + test := struct { + S *Secret + }{ + S: NewUnsafeSecret("test"), + } + + c, err := json.Marshal(test) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, "{\"S\":\"test\"}", string(c), "Unsafe Secret not marshaled.") + + c, err = yaml.Marshal(test) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, "s: test\n", string(c), "Unsafe Secret not marshaled.") +} + +func TestUnmarshalSecret(t *testing.T) { + b := []byte(`"secret"`) + var u Secret + + err := json.Unmarshal(b, &u) + if err != nil { + t.Fatal(err) + } + require.Equal(t, "secret", u.String(), "Secret not properly unmarshalled from JSON.") + require.Equal(t, false, u.unsafe, "Secret unmarhalled as unsafe from JSON.") + + err = yaml.Unmarshal(b, &u) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, "secret", u.String(), "Secret not properly unmarshalled from YAML.") + require.Equal(t, false, u.unsafe, "Secret unmarhalled as unsafe from YAML.") +} + +func TestUnmarshalEmptySecret(t *testing.T) { + b := []byte(`""`) + var u Secret + + err := json.Unmarshal(b, &u) + require.Error(t, err, "expected error while unmarshalling empty secret from JSON.") + + err = yaml.Unmarshal(b, &u) + require.Error(t, err, "expected error while unmarshalling empty secret from YAML.") } func TestMarshalSecretURL(t *testing.T) { @@ -365,7 +427,7 @@ func TestMarshalSecretURL(t *testing.T) { if err != nil { t.Fatal(err) } - u := &SecretURL{urlp} + u := NewSecretURL(URL{urlp}) c, err := json.Marshal(u) if err != nil { @@ -394,6 +456,39 @@ func TestMarshalSecretURL(t *testing.T) { } } +func TestMarshalUnsafeSecretURL(t *testing.T) { + urlp, err := url.Parse("http://example.com/") + if err != nil { + t.Fatal(err) + } + u := NewUnsafeSecretURL(URL{urlp}) + + c, err := json.Marshal(u) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, "\"http://example.com/\"", string(c), "SecretURL not properly marshaled in JSON.") + // Check that the marshaled data can be unmarshaled again. + out := &SecretURL{} + err = json.Unmarshal(c, out) + if err != nil { + t.Fatal(err) + } + + c, err = yaml.Marshal(u) + if err != nil { + t.Fatal(err) + } + require.Equal(t, "http://example.com/\n", string(c), "SecretURL not properly marshaled in YAML.") + // Check that the marshaled data can be unmarshaled again. + out = &SecretURL{} + err = yaml.Unmarshal(c, &out) + if err != nil { + t.Fatal(err) + } +} + func TestUnmarshalSecretURL(t *testing.T) { b := []byte(`"http://example.com/se cret"`) var u SecretURL @@ -552,9 +647,9 @@ func TestEmptyFieldsAndRegex(t *testing.T) { ResolveTimeout: model.Duration(5 * time.Minute), SMTPSmarthost: "localhost:25", SMTPFrom: "alertmanager@example.org", - HipchatAuthToken: "mysecret", + HipchatAuthToken: NewSecret("mysecret"), HipchatAPIURL: mustParseURL("https://hipchat.foobar.org/"), - SlackAPIURL: (*SecretURL)(mustParseURL("http://slack.example.com/")), + SlackAPIURL: NewSecretURL(*mustParseURL("http://slack.example.com/")), SMTPRequireTLS: true, PagerdutyURL: mustParseURL("https://events.pagerduty.com/v2/enqueue"), OpsGenieAPIURL: mustParseURL("https://api.opsgenie.com/"), diff --git a/config/notifiers.go b/config/notifiers.go index afc5be3705..5231baf5a8 100644 --- a/config/notifiers.go +++ b/config/notifiers.go @@ -106,7 +106,7 @@ var ( VSendResolved: false, }, Message: `{{ template "wechat.default.message" . }}`, - APISecret: `{{ template "wechat.default.api_secret" . }}`, + APISecret: NewSecret(`{{ template "wechat.default.api_secret" . }}`), ToUser: `{{ template "wechat.default.to_user" . }}`, ToParty: `{{ template "wechat.default.to_party" . }}`, ToTag: `{{ template "wechat.default.to_tag" . }}`, @@ -158,8 +158,8 @@ type EmailConfig struct { Hello string `yaml:"hello,omitempty" json:"hello,omitempty"` Smarthost string `yaml:"smarthost,omitempty" json:"smarthost,omitempty"` AuthUsername string `yaml:"auth_username,omitempty" json:"auth_username,omitempty"` - AuthPassword Secret `yaml:"auth_password,omitempty" json:"auth_password,omitempty"` - AuthSecret Secret `yaml:"auth_secret,omitempty" json:"auth_secret,omitempty"` + AuthPassword *Secret `yaml:"auth_password,omitempty" json:"auth_password,omitempty"` + AuthSecret *Secret `yaml:"auth_secret,omitempty" json:"auth_secret,omitempty"` AuthIdentity string `yaml:"auth_identity,omitempty" json:"auth_identity,omitempty"` Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"` HTML string `yaml:"html,omitempty" json:"html,omitempty"` @@ -198,8 +198,8 @@ type PagerdutyConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - ServiceKey Secret `yaml:"service_key,omitempty" json:"service_key,omitempty"` - RoutingKey Secret `yaml:"routing_key,omitempty" json:"routing_key,omitempty"` + ServiceKey *Secret `yaml:"service_key,omitempty" json:"service_key,omitempty"` + RoutingKey *Secret `yaml:"routing_key,omitempty" json:"routing_key,omitempty"` URL *URL `yaml:"url,omitempty" json:"url,omitempty"` Client string `yaml:"client,omitempty" json:"client,omitempty"` ClientURL string `yaml:"client_url,omitempty" json:"client_url,omitempty"` @@ -233,7 +233,8 @@ func (c *PagerdutyConfig) UnmarshalYAML(unmarshal func(interface{}) error) error if err := unmarshal((*plain)(c)); err != nil { return err } - if c.RoutingKey == "" && c.ServiceKey == "" { + + if c.RoutingKey.String() == "" && c.ServiceKey.String() == "" { return fmt.Errorf("missing service or routing key in PagerDuty config") } if c.Details == nil { @@ -375,14 +376,14 @@ type HipchatConfig struct { 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"` + 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. @@ -392,6 +393,7 @@ func (c *HipchatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal((*plain)(c)); err != nil { return err } + if c.RoomID == "" { return fmt.Errorf("missing room id in Hipchat config") } @@ -430,14 +432,14 @@ type WechatConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - APISecret Secret `yaml:"api_secret,omitempty" json:"api_secret,omitempty"` - CorpID string `yaml:"corp_id,omitempty" json:"corp_id,omitempty"` - Message string `yaml:"message,omitempty" json:"message,omitempty"` - APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"` - ToUser string `yaml:"to_user,omitempty" json:"to_user,omitempty"` - ToParty string `yaml:"to_party,omitempty" json:"to_party,omitempty"` - ToTag string `yaml:"to_tag,omitempty" json:"to_tag,omitempty"` - AgentID string `yaml:"agent_id,omitempty" json:"agent_id,omitempty"` + APISecret *Secret `yaml:"api_secret,omitempty" json:"api_secret,omitempty"` + CorpID string `yaml:"corp_id,omitempty" json:"corp_id,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"` + ToUser string `yaml:"to_user,omitempty" json:"to_user,omitempty"` + ToParty string `yaml:"to_party,omitempty" json:"to_party,omitempty"` + ToTag string `yaml:"to_tag,omitempty" json:"to_tag,omitempty"` + AgentID string `yaml:"agent_id,omitempty" json:"agent_id,omitempty"` } // UnmarshalYAML implements the yaml.Unmarshaler interface. @@ -447,9 +449,7 @@ func (c *WechatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal((*plain)(c)); err != nil { return err } - if c.APISecret == "" { - return fmt.Errorf("missing Wechat APISecret in Wechat config") - } + if c.CorpID == "" { return fmt.Errorf("missing Wechat CorpID in Wechat config") } @@ -462,7 +462,7 @@ type OpsGenieConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - APIKey Secret `yaml:"api_key,omitempty" json:"api_key,omitempty"` + APIKey *Secret `yaml:"api_key,omitempty" json:"api_key,omitempty"` APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"` Message string `yaml:"message,omitempty" json:"message,omitempty"` Description string `yaml:"description,omitempty" json:"description,omitempty"` @@ -487,7 +487,7 @@ type VictorOpsConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - APIKey Secret `yaml:"api_key" json:"api_key"` + APIKey *Secret `yaml:"api_key" json:"api_key"` APIURL *URL `yaml:"api_url" json:"api_url"` RoutingKey string `yaml:"routing_key" json:"routing_key"` MessageType string `yaml:"message_type" json:"message_type"` @@ -538,8 +538,8 @@ type PushoverConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - UserKey Secret `yaml:"user_key,omitempty" json:"user_key,omitempty"` - Token Secret `yaml:"token,omitempty" json:"token,omitempty"` + UserKey *Secret `yaml:"user_key,omitempty" json:"user_key,omitempty"` + Token *Secret `yaml:"token,omitempty" json:"token,omitempty"` Title string `yaml:"title,omitempty" json:"title,omitempty"` Message string `yaml:"message,omitempty" json:"message,omitempty"` URL string `yaml:"url,omitempty" json:"url,omitempty"` @@ -558,10 +558,10 @@ func (c *PushoverConfig) UnmarshalYAML(unmarshal func(interface{}) error) error if err := unmarshal((*plain)(c)); err != nil { return err } - if c.UserKey == "" { + if c.UserKey.String() == "" { return fmt.Errorf("missing user key in Pushover config") } - if c.Token == "" { + if c.Token.String() == "" { return fmt.Errorf("missing token in Pushover config") } return nil diff --git a/config/notifiers_test.go b/config/notifiers_test.go index a91c874a40..952bc2a765 100644 --- a/config/notifiers_test.go +++ b/config/notifiers_test.go @@ -17,7 +17,7 @@ import ( "strings" "testing" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) func TestEmailToIsPresent(t *testing.T) { @@ -57,26 +57,9 @@ headers: } } -func TestPagerdutyRoutingKeyIsPresent(t *testing.T) { +func TestPagerdutyServiceKeyOrRoutingKeyIsPresent(t *testing.T) { in := ` -routing_key: '' -` - var cfg PagerdutyConfig - err := yaml.UnmarshalStrict([]byte(in), &cfg) - - expected := "missing service or routing key in PagerDuty 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 TestPagerdutyServiceKeyIsPresent(t *testing.T) { - in := ` -service_key: '' +client: '' ` var cfg PagerdutyConfig err := yaml.UnmarshalStrict([]byte(in), &cfg) @@ -243,7 +226,7 @@ api_secret: '' var cfg WechatConfig err := yaml.UnmarshalStrict([]byte(in), &cfg) - expected := "missing Wechat APISecret in Wechat config" + expected := "secret value cannot be empty" if err == nil { t.Fatalf("no error returned, expected:\n%v", expected) @@ -332,7 +315,7 @@ custom_fields: func TestPushoverUserKeyIsPresent(t *testing.T) { in := ` -user_key: '' +title: '' ` var cfg PushoverConfig err := yaml.UnmarshalStrict([]byte(in), &cfg) @@ -350,7 +333,6 @@ user_key: '' func TestPushoverTokenIsPresent(t *testing.T) { in := ` user_key: '' -token: '' ` var cfg PushoverConfig err := yaml.UnmarshalStrict([]byte(in), &cfg) diff --git a/config/testdata/conf.empty-fields.yml b/config/testdata/conf.empty-fields.yml index afba5f2877..1c59c17aa5 100644 --- a/config/testdata/conf.empty-fields.yml +++ b/config/testdata/conf.empty-fields.yml @@ -1,8 +1,6 @@ global: smtp_smarthost: 'localhost:25' smtp_from: 'alertmanager@example.org' - smtp_auth_username: '' - smtp_auth_password: '' smtp_hello: '' hipchat_auth_token: 'mysecret' hipchat_api_url: 'https://hipchat.foobar.org/' diff --git a/notify/impl.go b/notify/impl.go index d1d0dbdf5a..db87e82c32 100644 --- a/notify/impl.go +++ b/notify/impl.go @@ -640,7 +640,7 @@ func (n *Hipchat) Notify(ctx context.Context, as ...*types.Alert) (bool, error) ) apiURL.Path += fmt.Sprintf("v2/room/%s/notification", roomid) q := apiURL.Query() - q.Set("auth_token", string(n.conf.AuthToken)) + q.Set("auth_token", n.conf.AuthToken.String()) apiURL.RawQuery = q.Encode() if n.conf.MessageFormat == "html" {