Hide secret configuration data

This commit is contained in:
Fabian Reinartz 2015-12-03 12:40:50 +01:00
parent 62fda13894
commit 7581d974ff
4 changed files with 49 additions and 36 deletions

View File

@ -26,6 +26,16 @@ import (
"gopkg.in/yaml.v2"
)
var patAuthLine = regexp.MustCompile(`((?:api_token|api_key|service_key|api_url):\s+)(".+"|'.+'|[^\s]+)`)
// Secret is a string that must not be revealed on marshaling.
type Secret string
// MarshalYAML implements the yaml.Marshaler interface.
func (s Secret) MarshalYAML() (interface{}, error) {
return "<hidden>", nil
}
// Load parses the YAML input s into a Config.
func Load(s string) (*Config, error) {
cfg := &Config{}
@ -101,14 +111,17 @@ func checkOverflow(m map[string]interface{}, ctx string) error {
}
func (c Config) String() string {
var s string
if c.original != "" {
return c.original
s = c.original
} else {
b, err := yaml.Marshal(c)
if err != nil {
return fmt.Sprintf("<error creating config string: %s>", err)
}
s = string(b)
}
b, err := yaml.Marshal(c)
if err != nil {
return fmt.Sprintf("<error creating config string: %s>", err)
}
return string(b)
return patAuthLine.ReplaceAllString(s, "${1}<hidden>")
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
@ -149,11 +162,11 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
}
for _, sc := range rcv.SlackConfigs {
if sc.URL == "" {
if c.Global.SlackURL == "" {
return fmt.Errorf("no global Slack URL set")
if sc.APIURL == "" {
if c.Global.SlackAPIURL == "" {
return fmt.Errorf("no global Slack API URL set")
}
sc.URL = c.Global.SlackURL
sc.APIURL = c.Global.SlackAPIURL
}
}
for _, pdc := range rcv.PagerdutyConfigs {
@ -197,7 +210,7 @@ type GlobalConfig struct {
SMTPFrom string `yaml:"smtp_from"`
SMTPSmarthost string `yaml:"smtp_smarthost"`
SlackURL string `yaml:"slack_url"`
SlackAPIURL Secret `yaml:"slack_api_url"`
PagerdutyURL string `yaml:"pagerduty_url"`
OpsGenieAPIHost string `yaml:"opsgenie_api_host"`
}
@ -221,8 +234,8 @@ type Route struct {
GroupWait *model.Duration `yaml:"group_wait,omitempty"`
GroupInterval *model.Duration `yaml:"group_interval,omitempty"`
RepeatInterval *model.Duration `yaml:"repeat_interval"`
SendResolved *bool `yaml:"send_resolved"`
RepeatInterval *model.Duration `yaml:"repeat_interval,omitempty"`
SendResolved *bool `yaml:"send_resolved,omitempty"`
// Catches all undefined fields and must be empty after parsing.
XXX map[string]interface{} `yaml:",inline"`
@ -322,14 +335,14 @@ type Receiver struct {
// A unique identifier for this receiver.
Name string `yaml:"name"`
EmailConfigs []*EmailConfig `yaml:"email_configs"`
FlowdockConfigs []*FlowdockConfig `yaml:"flowdock_configs"`
HipchatConfigs []*HipchatConfig `yaml:"hipchat_configs"`
PagerdutyConfigs []*PagerdutyConfig `yaml:"pagerduty_configs"`
PushoverConfigs []*PushoverConfig `yaml:"pushover_configs"`
SlackConfigs []*SlackConfig `yaml:"slack_configs"`
WebhookConfigs []*WebhookConfig `yaml:"webhook_configs"`
OpsGenieConfigs []*OpsGenieConfig `yaml:"opsgenie_configs"`
EmailConfigs []*EmailConfig `yaml:"email_configs,omitempty"`
FlowdockConfigs []*FlowdockConfig `yaml:"flowdock_configs,omitempty"`
HipchatConfigs []*HipchatConfig `yaml:"hipchat_configs,omitempty"`
PagerdutyConfigs []*PagerdutyConfig `yaml:"pagerduty_configs,omitempty"`
PushoverConfigs []*PushoverConfig `yaml:"pushover_configs,omitempty"`
SlackConfigs []*SlackConfig `yaml:"slack_configs,omitempty"`
WebhookConfigs []*WebhookConfig `yaml:"webhook_configs,omitempty"`
OpsGenieConfigs []*OpsGenieConfig `yaml:"opsgenie_configs,omitempty"`
// Catches all undefined fields and must be empty after parsing.
XXX map[string]interface{} `yaml:",inline"`

View File

@ -39,10 +39,10 @@ var (
Client: `{{ template "pagerduty.default.client" . }}`,
ClientURL: `{{ template "pagerduty.default.clientURL" . }}`,
Details: map[string]string{
"firing": `{{ template "pagerduty.default.instances" (.Alerts | firing) }}`,
"resolved": `{{ template "pagerduty.default.instances" (.Alerts | resolved) }}`,
"num_firing": `{{ .Alerts | firing | len }}`,
"num_resolved": `{{ .Alerts | resolved | len }}`,
"firing": `{{ template "pagerduty.default.instances" .Alerts.Firing }}`,
"resolved": `{{ template "pagerduty.default.instances" .Alerts.Resolved }}`,
"num_firing": `{{ .Alerts.Firing | len }}`,
"num_resolved": `{{ .Alerts.Resolved | len }}`,
},
}
@ -68,7 +68,7 @@ var (
// FlowdockConfig configures notifications via Flowdock.
type FlowdockConfig struct {
// Flowdock flow API token.
APIToken string `yaml:"api_token"`
APIToken Secret `yaml:"api_token"`
// Flowdock from_address.
FromAddress string `yaml:"from_address"`
@ -155,7 +155,7 @@ const (
// https://www.hipchat.com/docs/apiv2/method/send_room_notification
type HipchatConfig struct {
// HipChat auth token, (https://www.hipchat.com/docs/api/auth).
AuthToken string `yaml:"auth_token"`
APIToken Secret `yaml:"api_token"`
// HipChat room id, (https://www.hipchat.com/rooms/ids).
RoomID int `yaml:"room_id"`
@ -183,8 +183,8 @@ func (c *HipchatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.AuthToken == "" {
return fmt.Errorf("missing auth token in HipChat config")
if c.APIToken == "" {
return fmt.Errorf("missing API token in HipChat config")
}
if c.MessageFormat != HipchatFormatHTML && c.MessageFormat != HipchatFormatText {
return fmt.Errorf("invalid message format %q", c.MessageFormat)
@ -194,7 +194,7 @@ func (c *HipchatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
// PagerdutyConfig configures notifications via PagerDuty.
type PagerdutyConfig struct {
ServiceKey string `yaml:"service_key"`
ServiceKey Secret `yaml:"service_key"`
URL string `yaml:"url"`
Client string `yaml:"client"`
ClientURL string `yaml:"client_url"`
@ -247,7 +247,7 @@ func (c *PushoverConfig) UnmarshalYAML(unmarshal func(interface{}) error) error
// SlackConfig configures notifications via Slack.
type SlackConfig struct {
URL string `yaml:"url"`
APIURL Secret `yaml:"api_url"`
// Slack channel override, (like #other-channel or @username).
Channel string `yaml:"channel"`
@ -300,7 +300,7 @@ func (c *WebhookConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
// OpsGenieConfig configures notifications via OpsGenie.
type OpsGenieConfig struct {
APIKey string `yaml:"api_key"`
APIKey Secret `yaml:"api_key"`
APIHost string `yaml:"api_host"`
Description string `yaml:"description"`
Source string `yaml:"source"`

View File

@ -308,7 +308,7 @@ func (n *PagerDuty) Notify(ctx context.Context, as ...*types.Alert) error {
}
msg := &pagerDutyMessage{
ServiceKey: tmpl(n.conf.ServiceKey),
ServiceKey: tmpl(string(n.conf.ServiceKey)),
EventType: eventType,
IncidentKey: key,
Description: tmpl(n.conf.Description),
@ -411,7 +411,7 @@ func (n *Slack) Notify(ctx context.Context, as ...*types.Alert) error {
return err
}
resp, err := ctxhttp.Post(ctx, http.DefaultClient, n.conf.URL, contentTypeJSON, &buf)
resp, err := ctxhttp.Post(ctx, http.DefaultClient, string(n.conf.APIURL), contentTypeJSON, &buf)
if err != nil {
return err
}
@ -474,7 +474,7 @@ func (n *OpsGenie) Notify(ctx context.Context, as ...*types.Alert) error {
apiURL string
apiMsg = opsGenieMessage{
APIKey: n.conf.APIKey,
APIKey: string(n.conf.APIKey),
Alias: key,
}
alerts = types.Alerts(as...)

View File

@ -301,7 +301,7 @@ func uiBindataGo() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "ui/bindata.go", size: 77824, mode: os.FileMode(420), modTime: time.Unix(1448991327, 0)}
info := bindataFileInfo{name: "ui/bindata.go", size: 77824, mode: os.FileMode(420), modTime: time.Unix(1449127936, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}