huge refactor

- extendable backends
- better project structure
- better cli interface
This commit is contained in:
Matej Kramny
2019-02-20 11:14:45 +08:00
parent df31238a1f
commit 162d55b3f3
17 changed files with 946 additions and 705 deletions

146
config.go
View File

@@ -1,22 +1,130 @@
package cachet
import (
"encoding/json"
"errors"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/castawaylabs/cachet-monitor/backends"
cachetbackend "github.com/castawaylabs/cachet-monitor/backends/cachet"
"github.com/castawaylabs/cachet-monitor/monitors"
"github.com/mitchellh/mapstructure"
"github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
)
type CachetMonitor struct {
SystemName string `json:"system_name" yaml:"system_name"`
DateFormat string `json:"date_format" yaml:"date_format"`
API CachetAPI `json:"api"`
RawMonitors []map[string]interface{} `json:"monitors" yaml:"monitors"`
RawBackend map[string]interface{} `json:"backend" yaml:"backend"`
Monitors []MonitorInterface `json:"-" yaml:"-"`
Immediate bool `json:"-" yaml:"-"`
SystemName string `json:"system_name" yaml:"system_name"`
Backend backends.BackendInterface `json:"-" yaml:"-"`
Monitors []monitors.MonitorInterface `json:"-" yaml:"-"`
Immediate bool `json:"-" yaml:"-"`
}
func New(path string) (*CachetMonitor, error) {
var cfg *CachetMonitor
var data []byte
// test if its a url
url, err := url.ParseRequestURI(path)
if err == nil && len(url.Scheme) > 0 {
// download config
response, err := http.Get(path)
if err != nil {
logrus.Warn("Unable to download network configuration")
return nil, err
}
defer response.Body.Close()
data, _ = ioutil.ReadAll(response.Body)
logrus.Info("Downloaded network configuration.")
} else {
data, err = ioutil.ReadFile(path)
if err != nil {
return nil, errors.New("Unable to open file: '" + path + "'")
}
}
if strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml") {
err = yaml.Unmarshal(data, &cfg)
} else {
err = json.Unmarshal(data, &cfg)
}
if err != nil {
logrus.Warnf("Unable to parse configuration file")
return nil, err
}
// get default type
if backend, ok := cfg.RawBackend["type"].(string); !ok {
err = errors.New("Cannot determine backend type")
} else {
switch backend {
case "cachet":
var backend cachetbackend.CachetBackend
err = mapstructure.Decode(cfg.RawBackend, &backend)
cfg.Backend = &backend
// backend.config = cfg
default:
err = errors.New("Invalid backend type: %v" + backend)
}
}
if errs := cfg.Backend.Validate(); len(errs) > 0 {
logrus.Errorf("Backend validation errors: %v", errs)
os.Exit(1)
}
if err != nil {
logrus.Errorf("Unable to unmarshal backend: %v", err)
return nil, err
}
cfg.Monitors = make([]monitors.MonitorInterface, len(cfg.RawMonitors))
for index, rawMonitor := range cfg.RawMonitors {
var t monitors.MonitorInterface
// get default type
monType := GetMonitorType("")
if t, ok := rawMonitor["type"].(string); ok {
monType = GetMonitorType(t)
}
switch monType {
case "http":
var mon monitors.HTTPMonitor
err = mapstructure.Decode(rawMonitor, &mon)
t = &mon
case "dns":
var mon monitors.DNSMonitor
err = mapstructure.Decode(rawMonitor, &mon)
t = &mon
default:
logrus.Errorf("Invalid monitor type (index: %d) %v", index, monType)
continue
}
if err != nil {
logrus.Errorf("Unable to unmarshal monitor to type (index: %d): %v", index, err)
continue
}
mon := t.GetMonitor()
mon.Type = monType
cfg.Monitors[index] = t
}
return cfg, err
}
// Validate configuration
@@ -28,22 +136,13 @@ func (cfg *CachetMonitor) Validate() bool {
cfg.SystemName = getHostname()
}
if len(cfg.DateFormat) == 0 {
cfg.DateFormat = DefaultTimeFormat
}
if len(cfg.API.Token) == 0 || len(cfg.API.URL) == 0 {
logrus.Warnf("API URL or API Token missing.\nGet help at https://github.com/castawaylabs/cachet-monitor")
valid = false
}
if len(cfg.Monitors) == 0 {
logrus.Warnf("No monitors defined!\nSee help for example configuration")
valid = false
}
for index, monitor := range cfg.Monitors {
if errs := monitor.Validate(); len(errs) > 0 {
if errs := monitor.Validate(cfg.Backend.ValidateMonitor); len(errs) > 0 {
logrus.Warnf("Monitor validation errors (index %d): %v", index, "\n - "+strings.Join(errs, "\n - "))
valid = false
}
@@ -67,10 +166,6 @@ func getHostname() string {
return addrs[0].String()
}
func getMs() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
}
func GetMonitorType(t string) string {
if len(t) == 0 {
return "http"
@@ -78,12 +173,3 @@ func GetMonitorType(t string) string {
return strings.ToLower(t)
}
func getTemplateData(monitor *AbstractMonitor) map[string]interface{} {
return map[string]interface{}{
"SystemName": monitor.config.SystemName,
"API": monitor.config.API,
"Monitor": monitor,
"now": time.Now().Format(monitor.config.DateFormat),
}
}