softwatch/main.go

120 lines
2.8 KiB
Go

package main
import (
"errors"
"fmt"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
gomail "gopkg.in/mail.v2"
"gopkg.in/yaml.v3"
"os"
)
type config struct {
Software []software `yaml:"software"`
StoreFile string `yaml:"storeFile"`
SMTP struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
User string `yaml:"user"`
Password string `yaml:"password"`
From string `yaml:"from"`
To string `yaml:"to"`
} `yaml:"smtp"`
}
type software struct {
Name string `yaml:"name"`
Plugin string `yaml:"plugin"`
//URL string
Data map[string]string `yaml:"data"`
}
func getConfig() config {
data, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatal().Err(err).Msg("cant read config")
}
c := config{}
err = yaml.Unmarshal(data, &c)
if err != nil {
log.Fatal().Err(err).Msg("cant pars config file")
}
return c
}
type Plugin interface {
getLastVersion(s software) (string, error)
}
func getPlugin(name string) (Plugin, error) {
switch name {
case "github":
return Github{}, nil
case "forgejo":
return Forgejo{}, nil
}
return nil, errors.New("cant get plugin")
}
func init() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}
func main() {
log.Info().Msg("Start")
c := getConfig()
lastData, err := getLastData(c.StoreFile)
log.Debug().Interface("data", lastData).Msg("Got LastData")
if err != nil {
log.Warn().Err(err).Msg("cant get store")
}
for _, s := range c.Software {
logger := log.With().Str("software", s.Name).Str("plugin", s.Plugin).Interface("data", s.Data).Logger()
logger.Debug().Msg("start checking for update")
p, err := getPlugin(s.Plugin)
if err != nil {
logger.Error().Err(err).Msg("cant get plugin")
continue
}
version, err := p.getLastVersion(s)
if err != nil {
panic(err)
}
logger.Info().Str("version", version).Msg("get version")
if v, ok := lastData.LastVersionen[s.Name]; !ok || v != version {
err = notifyNewRelease(s, version, c)
if err != nil {
panic(err)
}
lastData.LastVersionen[s.Name] = version
} else {
log.Debug().Msg("Everything up to date")
}
}
err = saveLastData(lastData, c.StoreFile)
if err != nil {
panic(err)
}
log.Info().Msg("Done")
}
func notifyNewRelease(s software, version string, c config) error {
log.Info().Interface("software", s).Str("version", version).Msg("inform about new version")
m := gomail.NewMessage()
m.SetHeader("From", c.SMTP.From)
m.SetHeader("To", c.SMTP.To)
m.SetHeader("Subject", fmt.Sprintf("Release %s %s", s.Name, version))
m.SetBody("text/plain", fmt.Sprintf("Hello Admin\r\n\r\nthe Software %s is not avalibel in Versio %s please consider to upgrade.", s.Name, version))
d := gomail.NewDialer(c.SMTP.Host, c.SMTP.Port, c.SMTP.User, c.SMTP.Password)
err := d.DialAndSend(m)
if err != nil {
return err
}
return nil
}