Skip to content

Commit

Permalink
add basic notifer scaffolding and new config file
Browse files Browse the repository at this point in the history
  • Loading branch information
equinox0815 committed Oct 16, 2023
1 parent 3805655 commit c0acfe1
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/whawty-alerts
/cmd/whawty-alerts/whawty-alerts
.coverprofile
/test.db
/contrib/test.db
68 changes: 68 additions & 0 deletions cmd/whawty-alerts/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// Copyright (c) 2023 whawty contributors (see AUTHORS file)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of whawty.alerts nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package main

import (
"fmt"
"os"

"github.com/spreadspace/tlsconfig"
"github.com/whawty/alerts/notifier"
"github.com/whawty/alerts/store"
"gopkg.in/yaml.v3"
)

type WebConfig struct {
TLS *tlsconfig.TLSConfig `yaml:"tls"`
}

type Config struct {
Store store.Config `yaml:"store"`
Notifier notifier.Config `yaml:"notifer"`
Web WebConfig `yaml:"web"`
}

func readConfig(configfile string) (*Config, error) {
file, err := os.Open(configfile)
if err != nil {
return nil, fmt.Errorf("Error opening config file: %s", err)
}
defer file.Close()

decoder := yaml.NewDecoder(file)
decoder.KnownFields(true)

c := &Config{}
if err = decoder.Decode(c); err != nil {
return nil, fmt.Errorf("Error parsing config file: %s", err)
}
return c, nil
}
39 changes: 22 additions & 17 deletions cmd/whawty-alerts/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"sync"

"github.com/urfave/cli"
"github.com/whawty/alerts/notifier"
"github.com/whawty/alerts/store"
)

Expand All @@ -53,27 +54,30 @@ func init() {
}

func cmdRun(c *cli.Context) error {
s, err := store.Open("test.db")
conf, err := readConfig(c.GlobalString("config"))
if err != nil {
return cli.NewExitError(err.Error(), 3)
return cli.NewExitError(err.Error(), 1)
}

var webc *webConfig
if c.String("web-config") != "" {
webc, err = readWebConfig(c.String("web-config"))
if err != nil {
return cli.NewExitError(err.Error(), 1)
}
s, err := store.Open(&conf.Store, wl, wdl)
if err != nil {
return cli.NewExitError(err.Error(), 3)
}
webAddrs := c.StringSlice("web-addr")
defer s.Close()
n, err := notifier.NewNotifier(&conf.Notifier, s, wl, wdl)
if err != nil {
return cli.NewExitError(err.Error(), 3)
}
defer n.Close()

webAddrs := c.StringSlice("web-addr")
var wg sync.WaitGroup
for _, webAddr := range webAddrs {
a := webAddr
wg.Add(1)
go func() {
defer wg.Done()
if err := runWebAddr(a, webc, s); err != nil {
if err := runWebAddr(a, &conf.Web, s); err != nil {
fmt.Printf("warning running web interface(%s) failed: %s\n", a, err)
}
}()
Expand All @@ -88,18 +92,19 @@ func main() {
app.Name = "whawty-alerts"
app.Version = "0.1"
app.Usage = "simple alert manager"
app.Flags = []cli.Flag{}
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "config",
Value: "/etc/whawty/alerts.yaml",
Usage: "path to the configuration file",
EnvVar: "WHAWTY_ALERTS_CONFIG",
},
}
app.Commands = []cli.Command{
{
Name: "run",
Usage: "run the alert manager",
Flags: []cli.Flag{
cli.StringFlag{
Name: "web-config",
Value: "",
Usage: "path to the web configuration file",
EnvVar: "WHAWTY_ALERTS_WEB_CONFIG",
},
cli.StringSliceFlag{
Name: "web-addr",
Usage: "address to listen on for web API",
Expand Down
31 changes: 3 additions & 28 deletions cmd/whawty-alerts/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,47 +31,22 @@
package main

import (
"fmt"
"net"
"net/http"
"os"
"time"

"github.com/gin-gonic/gin"
"github.com/spreadspace/tlsconfig"
apiV1 "github.com/whawty/alerts/api/v1"
"github.com/whawty/alerts/store"
"github.com/whawty/alerts/ui"
"gopkg.in/yaml.v3"
)

const (
WebUIPathPrefix = "/admin/"
WebAPIv1Prefix = "/api/v1/"
)

type webConfig struct {
TLS *tlsconfig.TLSConfig `yaml:"tls"`
}

func readWebConfig(configfile string) (*webConfig, error) {
file, err := os.Open(configfile)
if err != nil {
return nil, err
}
defer file.Close()

decoder := yaml.NewDecoder(file)
decoder.KnownFields(true)

c := &webConfig{}
if err = decoder.Decode(c); err != nil {
return nil, fmt.Errorf("Error parsing config file: %s", err)
}
return c, nil
}

func runWeb(listener net.Listener, config *webConfig, st *store.Store) (err error) {
func runWeb(listener net.Listener, config *WebConfig, st *store.Store) (err error) {
gin.SetMode(gin.ReleaseMode)

r := gin.New()
Expand All @@ -97,7 +72,7 @@ func runWeb(listener net.Listener, config *webConfig, st *store.Store) (err erro
return server.Serve(listener)
}

func runWebAddr(addr string, config *webConfig, store *store.Store) (err error) {
func runWebAddr(addr string, config *WebConfig, store *store.Store) (err error) {
if addr == "" {
addr = ":http"
}
Expand All @@ -108,6 +83,6 @@ func runWebAddr(addr string, config *webConfig, store *store.Store) (err error)
return runWeb(ln.(*net.TCPListener), config, store)
}

func runWebListener(listener *net.TCPListener, config *webConfig, store *store.Store) (err error) {
func runWebListener(listener *net.TCPListener, config *WebConfig, store *store.Store) (err error) {
return runWeb(listener, config, store)
}
2 changes: 2 additions & 0 deletions contrib/sample-cfg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
store:
path: ./contrib/test.db
74 changes: 74 additions & 0 deletions notifier/notifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// Copyright (c) 2023 whawty contributors (see AUTHORS file)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of whawty.alerts nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package notifier

import (
"context"
"io"
"log"
"time"

"github.com/whawty/alerts/store"
)

type Notifier struct {
conf *Config
store *store.Store
infoLog *log.Logger
dbgLog *log.Logger
ctx context.Context
cancel context.CancelFunc
}

func (n *Notifier) Close() error {
n.cancel()
return nil
}

func NewNotifier(conf *Config, st *store.Store, infoLog, dbgLog *log.Logger) (n *Notifier, err error) {
if infoLog == nil {
infoLog = log.New(io.Discard, "", 0)
}
if dbgLog == nil {
dbgLog = log.New(io.Discard, "", 0)
}

n = &Notifier{conf: conf, store: st, infoLog: infoLog, dbgLog: dbgLog}
n.ctx, n.cancel = context.WithCancel(context.Background())
if n.conf.Interval <= 0 {
n.conf.Interval = 1 * time.Minute
}

// TODO: start go-routine to handle notfications

infoLog.Printf("notifier: started with evaluation interval %s", conf.Interval.String())
return
}
45 changes: 45 additions & 0 deletions notifier/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Copyright (c) 2023 whawty contributors (see AUTHORS file)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of whawty.alerts nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package notifier

import (
"time"
)

type NotifierTarget struct {
Type string `yaml:"type"`
// TODO: other fields?
}

type Config struct {
Interval time.Duration `yaml:"interval"`
Targets []NotifierTarget `yaml:"targets"`
}
22 changes: 18 additions & 4 deletions store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,30 @@
package store

import (
"io"
"log"

bolt "go.etcd.io/bbolt"
)

type Store struct {
db *bolt.DB
conf *Config
db *bolt.DB
infoLog *log.Logger
dbgLog *log.Logger
}

func Open(path string) (s *Store, err error) {
s = &Store{}
s.db, err = bolt.Open(path, 0600, nil)
func Open(conf *Config, infoLog, dbgLog *log.Logger) (s *Store, err error) {
if infoLog == nil {
infoLog = log.New(io.Discard, "", 0)
}
if dbgLog == nil {
dbgLog = log.New(io.Discard, "", 0)
}

s = &Store{conf: conf, infoLog: infoLog, dbgLog: dbgLog}
s.db, err = bolt.Open(conf.Path, 0600, nil)
infoLog.Printf("store: opened database %s", s.conf.Path)
return
}

Expand Down
6 changes: 6 additions & 0 deletions store/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ import (
"time"
)

// Configuration

type Config struct {
Path string `yaml:"path"`
}

// Errors

var (
Expand Down

0 comments on commit c0acfe1

Please sign in to comment.