allow custom config per boxID, fixes #5

develop
Norwin 6 years ago
parent 1bc0252b84
commit 8df4f6c753

@ -23,21 +23,32 @@ var configHelpCmd = &cobra.Command{
> Example configuration:
# override default health checks:
defaultHealthchecks:
notifications:
transport: email
options:
recipients:
- fridolina@example.com
- ruth.less@example.com
events:
- type: "measurement_age"
target: "all" # all sensors
threshold: "15m" # any duration
- type: "measurement_faulty"
target: "all"
threshold: ""
healthchecks:
# override default health checks for all boxes
default:
notifications:
transport: email
options:
recipients:
- fridolina@example.com
events:
- type: "measurement_age"
target: "all" # all sensors
threshold: "15m" # any duration
- type: "measurement_faulty"
target: "all"
threshold: ""
# override default health checks per box
593bcd656ccf3b0011791f5a:
notifications:
options:
recipients:
- ruth.less@example.com
events:
- type: "measurement_max"
target: "593bcd656ccf3b0011791f5b"
threshold: "40"
# only needed when sending notifications via email
email:
@ -48,14 +59,14 @@ var configHelpCmd = &cobra.Command{
from: hildegunst@example.com
> possible values for defaultHealthchecks.notifications:
> possible values for healthchecks.*.notifications:
transport | options
----------|-------------------------------------
email | recipients: list of email addresses
> possible values for defaultHealthchecks.events[]:
> possible values for healthchecks.*.events[]:
type | description
-------------------|---------------------------------------------------

@ -7,6 +7,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/noerw/osem_notify/core"
"github.com/noerw/osem_notify/utils"
)
@ -59,3 +60,55 @@ func validateConfig() {
}
}
}
func getNotifyConf(boxID string) (*core.NotifyConfig, error) {
// config used when no configuration is present at all
conf := &core.NotifyConfig{
Events: []core.NotifyEvent{
core.NotifyEvent{
Type: "measurement_age",
Target: "all",
Threshold: "15m",
},
core.NotifyEvent{
Type: "measurement_faulty",
Target: "all",
Threshold: "",
},
},
}
// override with default configuration from file
// considering the case that .events may be defined but empty
// to allow to define no events, and don't leak shorter lists into
// previous longer ones
if keyDefined("healthchecks.default.events") {
conf.Events = []core.NotifyEvent{}
}
err := viper.UnmarshalKey("healthchecks.default", conf)
if err != nil {
return nil, err
}
// override with per box configuration from file
if keyDefined("healthchecks."+boxID+".events") {
conf.Events = []core.NotifyEvent{}
}
err = viper.UnmarshalKey("healthchecks." + boxID, conf)
if err != nil {
return nil, err
}
return conf, nil
}
// implement our own keyCheck, as viper.InConfig() does not work
func keyDefined(key string) bool {
allConfKeys := viper.AllKeys()
for _, k := range allConfKeys {
if k == key {
return true
}
}
return false
}

@ -4,7 +4,6 @@ import (
"fmt"
"regexp"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -34,41 +33,16 @@ func BoxIdValidator(cmd *cobra.Command, args []string) error {
}
func checkAndNotify(boxIds []string) error {
defaultNotifyConf := &core.NotifyConfig{}
err := viper.UnmarshalKey("defaultHealthchecks", defaultNotifyConf)
if err != nil {
return err
}
// set default events, when no events are given. an empty events key indicates no checks are desired
if len(defaultNotifyConf.Events) == 0 {
allKeys := viper.AllKeys()
eventsDefined := false
for _, k := range allKeys {
if k == "defaulthealthchecks.events" {
eventsDefined = true
break
}
}
if !eventsDefined {
log.Debug("using default checks")
defaultNotifyConf.Events = []core.NotifyEvent{
core.NotifyEvent{
Type: "measurement_age",
Target: "all",
Threshold: "15m",
},
core.NotifyEvent{
Type: "measurement_faulty",
Target: "all",
Threshold: "",
},
}
boxLocalConfig := map[string]*core.NotifyConfig{}
for _, boxID := range boxIds {
c, err := getNotifyConf(boxID)
if err != nil {
return err
}
boxLocalConfig[boxID] = c
}
results, err := core.CheckBoxes(boxIds, defaultNotifyConf)
results, err := core.CheckBoxes(boxLocalConfig)
if err != nil {
return err
}

@ -50,18 +50,18 @@ func (results BoxCheckResults) Log() {
}
}
func CheckBoxes(boxIds []string, defaultConf *NotifyConfig) (BoxCheckResults, error) {
log.Debug("Checking notifications for ", len(boxIds), " box(es)")
func CheckBoxes(boxLocalConfs map[string]*NotifyConfig) (BoxCheckResults, error) {
log.Debug("Checking notifications for ", len(boxLocalConfs), " box(es)")
results := BoxCheckResults{}
errs := []string{}
// TODO: check boxes in parallel, capped at 5 at once
for _, boxId := range boxIds {
for boxId, localConf := range boxLocalConfs {
boxLogger := log.WithField("boxId", boxId)
boxLogger.Info("checking box for events")
box, res, err := checkBox(boxId, defaultConf)
box, res, err := checkBox(boxId, localConf)
if err != nil {
boxLogger.Errorf("could not run checks on box %s: %s", boxId, err)
errs = append(errs, err.Error())

@ -14,7 +14,7 @@ const (
eventTargetAll = "all" // if event.Target is this value, all sensors will be checked
)
type checkType = struct {
type checkType struct {
name string // name that is used in config
toString func(result CheckResult) string // error message when check failed
checkFunc func(event NotifyEvent, sensor Sensor, context Box) (CheckResult, error)

Loading…
Cancel
Save