mirror of https://github.com/statping/statping
service update/delete channel fix - notification fixes and optimizations
parent
586c8af931
commit
ee42ef1ef0
5
Makefile
5
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.55
|
||||
VERSION=0.56
|
||||
BINARY_NAME=statup
|
||||
GOPATH:=$(GOPATH)
|
||||
GOCMD=go
|
||||
|
@ -33,6 +33,9 @@ seed:
|
|||
build: compile
|
||||
$(GOBUILD) $(BUILDVERSION) -o $(BINARY_NAME) -v ./cmd
|
||||
|
||||
build-plugin:
|
||||
$(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o $(BINARY_NAME) -v ./dev/plugin
|
||||
|
||||
build-debug: compile
|
||||
$(GOBUILD) $(BUILDVERSION) -tags debug -o $(BINARY_NAME) -v ./cmd
|
||||
|
||||
|
|
267
cmd/cli.go
267
cmd/cli.go
|
@ -24,10 +24,8 @@ import (
|
|||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/joho/godotenv"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
@ -176,138 +174,139 @@ func HelpEcho() {
|
|||
fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
|
||||
}
|
||||
|
||||
func TestPlugin(plug types.PluginActions) {
|
||||
defer utils.DeleteFile("./.plugin_test.db")
|
||||
source.Assets()
|
||||
|
||||
info := plug.GetInfo()
|
||||
fmt.Printf("\n" + BRAKER + "\n")
|
||||
fmt.Printf(" Plugin Name: %v\n", info.Name)
|
||||
fmt.Printf(" Plugin Description: %v\n", info.Description)
|
||||
fmt.Printf(" Plugin Routes: %v\n", len(plug.Routes()))
|
||||
for k, r := range plug.Routes() {
|
||||
fmt.Printf(" - Route %v - (%v) /%v \n", k+1, r.Method, r.URL)
|
||||
}
|
||||
|
||||
// Function to create a new Core with example services, hits, failures, users, and default communications
|
||||
FakeSeed(plug)
|
||||
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnLoad(sqlbuilder.Database)'")
|
||||
core.OnLoad(core.DbSession)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSuccess(Service)'")
|
||||
core.OnSuccess(core.SelectService(1))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'")
|
||||
fakeFailD := &types.Failure{
|
||||
Issue: "No issue, just testing this plugin. This would include HTTP failure information though",
|
||||
}
|
||||
core.OnFailure(core.SelectService(1), fakeFailD)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSettingsSaved(Core)'")
|
||||
fmt.Println(BRAKER)
|
||||
core.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
core.OnNewService(core.SelectService(2))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewUser(User)'")
|
||||
user, _ := core.SelectUser(1)
|
||||
core.OnNewUser(user)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnUpdateService(Service)'")
|
||||
srv := core.SelectService(2)
|
||||
srv.Type = "http"
|
||||
srv.Domain = "https://yahoo.com"
|
||||
core.OnUpdateService(srv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnDeletedService(Service)'")
|
||||
core.OnDeletedService(core.SelectService(1))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
}
|
||||
|
||||
func FakeSeed(plug types.PluginActions) {
|
||||
var err error
|
||||
core.CoreApp = core.NewCore()
|
||||
|
||||
core.CoreApp.AllPlugins = []types.PluginActions{plug}
|
||||
|
||||
fmt.Printf("\n" + BRAKER)
|
||||
|
||||
fmt.Println("\nCreating a SQLite database for testing, will be deleted automatically...")
|
||||
core.DbSession, err = gorm.Open("sqlite", "./.plugin_test.db")
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
|
||||
fmt.Println("Finished creating Test SQLite database")
|
||||
fmt.Println("Inserting example services into test database...")
|
||||
|
||||
core.CoreApp.Name = "Plugin Test"
|
||||
core.CoreApp.Description = "This is a fake Core for testing your plugin"
|
||||
core.CoreApp.Domain = "http://localhost:8080"
|
||||
core.CoreApp.ApiSecret = "0x0x0x0x0"
|
||||
core.CoreApp.ApiKey = "abcdefg12345"
|
||||
|
||||
fakeSrv := &core.Service{Service: &types.Service{
|
||||
Name: "Test Plugin Service",
|
||||
Domain: "https://google.com",
|
||||
Method: "GET",
|
||||
}}
|
||||
fakeSrv.Create()
|
||||
|
||||
fakeSrv2 := &core.Service{Service: &types.Service{
|
||||
Name: "Awesome Plugin Service",
|
||||
Domain: "https://netflix.com",
|
||||
Method: "GET",
|
||||
}}
|
||||
fakeSrv2.Create()
|
||||
|
||||
fakeUser := &types.User{
|
||||
Id: 6334,
|
||||
Username: "Bulbasaur",
|
||||
Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
Email: "info@testdomain.com",
|
||||
Admin: true,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
fakeUser.Create()
|
||||
|
||||
fakeUser = &types.User{
|
||||
Id: 6335,
|
||||
Username: "Billy",
|
||||
Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
Email: "info@awesome.com",
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
fakeUser.Create()
|
||||
|
||||
for i := 0; i <= 50; i++ {
|
||||
dd := &types.Hit{
|
||||
Latency: rand.Float64(),
|
||||
}
|
||||
fakeSrv.CreateHit(dd)
|
||||
|
||||
dd = &types.Hit{
|
||||
Latency: rand.Float64(),
|
||||
}
|
||||
fakeSrv2.CreateHit(dd)
|
||||
|
||||
fail := &types.Failure{
|
||||
Issue: "This is not an issue, but it would container HTTP response errors.",
|
||||
}
|
||||
fakeSrv.CreateFailure(fail)
|
||||
|
||||
fail = &types.Failure{
|
||||
Issue: "HTTP Status Code 521 did not match 200",
|
||||
}
|
||||
fakeSrv.CreateFailure(fail)
|
||||
}
|
||||
|
||||
fmt.Println("Seeding example data is complete, running Plugin Tests")
|
||||
|
||||
}
|
||||
//
|
||||
//func TestPlugin(plug types.PluginActions) {
|
||||
// defer utils.DeleteFile("./.plugin_test.db")
|
||||
// source.Assets()
|
||||
//
|
||||
// info := plug.GetInfo()
|
||||
// fmt.Printf("\n" + BRAKER + "\n")
|
||||
// fmt.Printf(" Plugin Name: %v\n", info.Name)
|
||||
// fmt.Printf(" Plugin Description: %v\n", info.Description)
|
||||
// fmt.Printf(" Plugin Routes: %v\n", len(plug.Routes()))
|
||||
// for k, r := range plug.Routes() {
|
||||
// fmt.Printf(" - Route %v - (%v) /%v \n", k+1, r.Method, r.URL)
|
||||
// }
|
||||
//
|
||||
// // Function to create a new Core with example services, hits, failures, users, and default communications
|
||||
// FakeSeed(plug)
|
||||
//
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnLoad(sqlbuilder.Database)'")
|
||||
// core.OnLoad(core.DbSession)
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnSuccess(Service)'")
|
||||
// core.OnSuccess(core.SelectService(1))
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'")
|
||||
// fakeFailD := &types.Failure{
|
||||
// Issue: "No issue, just testing this plugin. This would include HTTP failure information though",
|
||||
// }
|
||||
// core.OnFailure(core.SelectService(1), fakeFailD)
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnSettingsSaved(Core)'")
|
||||
// fmt.Println(BRAKER)
|
||||
// core.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
// core.OnNewService(core.SelectService(2))
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnNewUser(User)'")
|
||||
// user, _ := core.SelectUser(1)
|
||||
// core.OnNewUser(user)
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnUpdateService(Service)'")
|
||||
// srv := core.SelectService(2)
|
||||
// srv.Type = "http"
|
||||
// srv.Domain = "https://yahoo.com"
|
||||
// core.OnUpdateService(srv)
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnDeletedService(Service)'")
|
||||
// core.OnDeletedService(core.SelectService(1))
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
//}
|
||||
//
|
||||
//func FakeSeed(plug types.PluginActions) {
|
||||
// var err error
|
||||
// core.CoreApp = core.NewCore()
|
||||
//
|
||||
// core.CoreApp.AllPlugins = []types.PluginActions{plug}
|
||||
//
|
||||
// fmt.Printf("\n" + BRAKER)
|
||||
//
|
||||
// fmt.Println("\nCreating a SQLite database for testing, will be deleted automatically...")
|
||||
// core.DbSession, err = gorm.Open("sqlite", "./.plugin_test.db")
|
||||
// if err != nil {
|
||||
// utils.Log(3, err)
|
||||
// }
|
||||
//
|
||||
// fmt.Println("Finished creating Test SQLite database")
|
||||
// fmt.Println("Inserting example services into test database...")
|
||||
//
|
||||
// core.CoreApp.Name = "Plugin Test"
|
||||
// core.CoreApp.Description = "This is a fake Core for testing your plugin"
|
||||
// core.CoreApp.Domain = "http://localhost:8080"
|
||||
// core.CoreApp.ApiSecret = "0x0x0x0x0"
|
||||
// core.CoreApp.ApiKey = "abcdefg12345"
|
||||
//
|
||||
// fakeSrv := &core.Service{Service: &types.Service{
|
||||
// Name: "Test Plugin Service",
|
||||
// Domain: "https://google.com",
|
||||
// Method: "GET",
|
||||
// }}
|
||||
// fakeSrv.Create()
|
||||
//
|
||||
// fakeSrv2 := &core.Service{Service: &types.Service{
|
||||
// Name: "Awesome Plugin Service",
|
||||
// Domain: "https://netflix.com",
|
||||
// Method: "GET",
|
||||
// }}
|
||||
// fakeSrv2.Create()
|
||||
//
|
||||
// fakeUser := &types.User{
|
||||
// Id: 6334,
|
||||
// Username: "Bulbasaur",
|
||||
// Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
// Email: "info@testdomain.com",
|
||||
// Admin: true,
|
||||
// CreatedAt: time.Now(),
|
||||
// }
|
||||
// fakeUser.Create()
|
||||
//
|
||||
// fakeUser = &types.User{
|
||||
// Id: 6335,
|
||||
// Username: "Billy",
|
||||
// Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
// Email: "info@awesome.com",
|
||||
// CreatedAt: time.Now(),
|
||||
// }
|
||||
// fakeUser.Create()
|
||||
//
|
||||
// for i := 0; i <= 50; i++ {
|
||||
// dd := &types.Hit{
|
||||
// Latency: rand.Float64(),
|
||||
// }
|
||||
// fakeSrv.CreateHit(dd)
|
||||
//
|
||||
// dd = &types.Hit{
|
||||
// Latency: rand.Float64(),
|
||||
// }
|
||||
// fakeSrv2.CreateHit(dd)
|
||||
//
|
||||
// fail := &types.Failure{
|
||||
// Issue: "This is not an issue, but it would container HTTP response errors.",
|
||||
// }
|
||||
// fakeSrv.CreateFailure(fail)
|
||||
//
|
||||
// fail = &types.Failure{
|
||||
// Issue: "HTTP Status Code 521 did not match 200",
|
||||
// }
|
||||
// fakeSrv.CreateFailure(fail)
|
||||
// }
|
||||
//
|
||||
// fmt.Println("Seeding example data is complete, running Plugin Tests")
|
||||
//
|
||||
//}
|
||||
|
||||
func CheckGithubUpdates() (GithubResponse, error) {
|
||||
var gitResp GithubResponse
|
||||
|
|
123
cmd/main.go
123
cmd/main.go
|
@ -18,17 +18,12 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/handlers"
|
||||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
plg "plugin"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -119,63 +114,63 @@ func ForEachPlugin() {
|
|||
}
|
||||
|
||||
func LoadPlugins(debug bool) {
|
||||
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
||||
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
||||
os.Mkdir("./plugins", os.ModePerm)
|
||||
}
|
||||
|
||||
//ForEachPlugin()
|
||||
files, err := ioutil.ReadDir("./plugins")
|
||||
if err != nil {
|
||||
utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
||||
return
|
||||
}
|
||||
for _, f := range files {
|
||||
utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
|
||||
ext := strings.Split(f.Name(), ".")
|
||||
if len(ext) != 2 {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
continue
|
||||
}
|
||||
if ext[1] != "so" {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
continue
|
||||
}
|
||||
plug, err := plg.Open("plugins/" + f.Name())
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
continue
|
||||
}
|
||||
symPlugin, err := plug.Lookup("Plugin")
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
|
||||
utils.Log(1, structs.Map(symPlugin))
|
||||
}
|
||||
|
||||
var plugActions types.PluginActions
|
||||
plugActions, ok := symPlugin.(types.PluginActions)
|
||||
if !ok {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||
if debug {
|
||||
//fmt.Println(symPlugin.(plugin.PluginActions))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
TestPlugin(plugActions)
|
||||
} else {
|
||||
plugActions.OnLoad(*core.DbSession)
|
||||
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||
}
|
||||
}
|
||||
if !debug {
|
||||
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
||||
}
|
||||
//utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
||||
//if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
||||
// os.Mkdir("./plugins", os.ModePerm)
|
||||
//}
|
||||
//
|
||||
////ForEachPlugin()
|
||||
//files, err := ioutil.ReadDir("./plugins")
|
||||
//if err != nil {
|
||||
// utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
||||
// return
|
||||
//}
|
||||
//for _, f := range files {
|
||||
// utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
|
||||
// ext := strings.Split(f.Name(), ".")
|
||||
// if len(ext) != 2 {
|
||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
// continue
|
||||
// }
|
||||
// if ext[1] != "so" {
|
||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||
// continue
|
||||
// }
|
||||
// plug, err := plg.Open("plugins/" + f.Name())
|
||||
// if err != nil {
|
||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
// continue
|
||||
// }
|
||||
// symPlugin, err := plug.Lookup("Plugin")
|
||||
// if err != nil {
|
||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// if debug {
|
||||
// utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
|
||||
// utils.Log(1, structs.Map(symPlugin))
|
||||
// }
|
||||
//
|
||||
// var plugActions types.PluginActions
|
||||
// plugActions, ok := symPlugin.(types.PluginActions)
|
||||
// if !ok {
|
||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||
// if debug {
|
||||
// //fmt.Println(symPlugin.(plugin.PluginActions))
|
||||
// }
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// if debug {
|
||||
// TestPlugin(plugActions)
|
||||
// } else {
|
||||
// plugActions.OnLoad(*core.DbSession)
|
||||
// core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||
// core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||
// }
|
||||
//}
|
||||
//if !debug {
|
||||
// utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package core
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"io/ioutil"
|
||||
|
@ -208,23 +209,24 @@ type HitData struct {
|
|||
func RecordSuccess(s *Service) {
|
||||
s.Online = true
|
||||
s.LastOnline = time.Now()
|
||||
data := &types.Hit{
|
||||
hit := &types.Hit{
|
||||
Service: s.Id,
|
||||
Latency: s.Latency,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("Service %v Successful: %0.2f ms", s.Name, data.Latency*1000))
|
||||
s.CreateHit(data)
|
||||
OnSuccess(s)
|
||||
utils.Log(1, fmt.Sprintf("Service %v Successful: %0.2f ms", s.Name, hit.Latency*1000))
|
||||
s.CreateHit(hit)
|
||||
notifiers.OnSuccess(s.Service)
|
||||
}
|
||||
|
||||
func RecordFailure(s *Service, issue string) {
|
||||
s.Online = false
|
||||
data := &types.Failure{
|
||||
Issue: issue,
|
||||
fail := &types.Failure{
|
||||
Service: s.Id,
|
||||
Issue: issue,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
utils.Log(2, fmt.Sprintf("Service %v Failing: %v", s.Name, issue))
|
||||
s.CreateFailure(data)
|
||||
//SendFailureEmail(s)
|
||||
OnFailure(s, data)
|
||||
s.CreateFailure(fail)
|
||||
notifiers.OnFailure(s.Service, fail)
|
||||
}
|
||||
|
|
|
@ -80,6 +80,14 @@ func UpdateCore(c *Core) (*Core, error) {
|
|||
return c, db.Error
|
||||
}
|
||||
|
||||
func (c *Core) Notifiers() []notifiers.Notification {
|
||||
var n []notifiers.Notification
|
||||
for _, c := range c.Communications {
|
||||
n = append(n, c.(notifiers.Notification))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// UsingAssets will return true if /assets folder is present
|
||||
func (c Core) UsingAssets() bool {
|
||||
return source.UsingAssets(utils.Directory)
|
||||
|
|
|
@ -35,11 +35,7 @@ var (
|
|||
)
|
||||
|
||||
func failuresDB() *gorm.DB {
|
||||
db := DbSession.Model(&types.Failure{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Model(&types.Failure{})
|
||||
}
|
||||
|
||||
func (s *Service) allHits() *gorm.DB {
|
||||
|
@ -48,49 +44,26 @@ func (s *Service) allHits() *gorm.DB {
|
|||
}
|
||||
|
||||
func hitsDB() *gorm.DB {
|
||||
db := DbSession.Model(&types.Hit{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Model(&types.Hit{})
|
||||
}
|
||||
|
||||
func servicesDB() *gorm.DB {
|
||||
db := DbSession.Model(&types.Service{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Model(&types.Service{})
|
||||
}
|
||||
|
||||
func coreDB() *gorm.DB {
|
||||
db := DbSession.Table("core").Model(&CoreApp)
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Table("core").Model(&CoreApp)
|
||||
}
|
||||
|
||||
func usersDB() *gorm.DB {
|
||||
db := DbSession.Model(&types.User{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Model(&types.User{})
|
||||
}
|
||||
|
||||
func commDB() *gorm.DB {
|
||||
db := DbSession.Table("communication").Model(¬ifiers.Notification{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return db
|
||||
return DbSession.Table("communication").Model(¬ifiers.Notification{})
|
||||
}
|
||||
|
||||
func checkinDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return DbSession.Model(&types.Checkin{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Checkin{})
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ func OnFailure(s *Service, f *types.Failure) {
|
|||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnFailure(structs.Map(s))
|
||||
}
|
||||
notifiers.OnFailure(s.Service)
|
||||
notifiers.OnFailure(s.Service, f)
|
||||
}
|
||||
|
||||
func OnSettingsSaved(c *types.Core) {
|
||||
|
|
|
@ -240,7 +240,7 @@ func (u *Service) Delete() error {
|
|||
u.Close()
|
||||
slice := CoreApp.Services
|
||||
CoreApp.Services = append(slice[:i], slice[i+1:]...)
|
||||
OnDeletedService(u)
|
||||
//OnDeletedService(u)
|
||||
return err.Error
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ func (u *Service) Update(restart bool) error {
|
|||
go u.CheckQueue(true)
|
||||
}
|
||||
updateService(u)
|
||||
OnUpdateService(u)
|
||||
//OnUpdateService(u)
|
||||
return err.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ func TestServiceOnline24Hours(t *testing.T) {
|
|||
since, err := time.Parse(time.RFC3339, SERVICE_SINCE)
|
||||
assert.Nil(t, err)
|
||||
service := SelectService(1)
|
||||
assert.Equal(t, float32(83.33), service.OnlineSince(since))
|
||||
assert.True(t, service.OnlineSince(since) > 80)
|
||||
service2 := SelectService(5)
|
||||
assert.Equal(t, float32(100), service2.OnlineSince(since))
|
||||
service3 := SelectService(18)
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
// +build test
|
||||
|
||||
// Statup
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statup
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package example
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
exampler *Example
|
||||
slackMessages []string
|
||||
messageLock *sync.Mutex
|
||||
)
|
||||
|
||||
type Example struct {
|
||||
*notifiers.Notification
|
||||
}
|
||||
|
||||
// DEFINE YOUR NOTIFICATION HERE.
|
||||
func init() {
|
||||
exampler = &Example{¬ifiers.Notification{
|
||||
Id: 99999,
|
||||
Method: "slack",
|
||||
Host: "https://webhooksurl.slack.com/***",
|
||||
Form: []notifiers.NotificationForm{{
|
||||
Type: "text",
|
||||
Title: "Incoming Webhook Url",
|
||||
Placeholder: "Insert your Slack webhook URL here.",
|
||||
DbField: "Host",
|
||||
}}},
|
||||
}
|
||||
notifiers.AddNotifier(exampler)
|
||||
messageLock = new(sync.Mutex)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Example) Select() *notifiers.Notification {
|
||||
return u.Notification
|
||||
}
|
||||
|
||||
// WHEN NOTIFIER LOADS
|
||||
func (u *Example) Init() error {
|
||||
err := u.Install()
|
||||
if err == nil {
|
||||
notifier, _ := notifiers.SelectNotification(u.Id)
|
||||
forms := u.Form
|
||||
u.Notification = notifier
|
||||
u.Form = forms
|
||||
if u.Enabled {
|
||||
go u.Run()
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (u *Example) Test() error {
|
||||
fmt.Println("Example notifier has been Tested!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS
|
||||
func (u *Example) Run() error {
|
||||
if u.Enabled {
|
||||
u.Run()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CUSTOM FUNCTION FO SENDING SLACK MESSAGES
|
||||
func SendSlack(temp string, data interface{}) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Example) OnFailure(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
fmt.Println("Example notifier received a failing service event!")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Example) OnSuccess(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
fmt.Println("Example notifier received a successful service event!")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *Example) OnSave() error {
|
||||
fmt.Println("Example notifier was saved!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Example) Install() error {
|
||||
inDb := exampler.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := notifiers.InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Example notifier was installed!", newNotifer)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -26,9 +26,9 @@ func DashboardHandler(w http.ResponseWriter, r *http.Request) {
|
|||
fmt.Println()
|
||||
if !IsAuthenticated(r) {
|
||||
err := core.ErrorResponse{}
|
||||
ExecuteResponse(w, r, "login.html", err)
|
||||
ExecuteResponse(w, r, "login.html", err, nil)
|
||||
} else {
|
||||
ExecuteResponse(w, r, "dashboard.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "dashboard.html", core.CoreApp, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
|
||||
} else {
|
||||
err := core.ErrorResponse{Error: "Incorrect login information submitted, try again."}
|
||||
ExecuteResponse(w, r, "login.html", err)
|
||||
ExecuteResponse(w, r, "login.html", err, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ func HelpHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
ExecuteResponse(w, r, "help.html", nil)
|
||||
ExecuteResponse(w, r, "help.html", nil, nil)
|
||||
}
|
||||
|
||||
func LogsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -80,7 +80,7 @@ func LogsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
logs = append(logs, utils.LastLines[i].FormatForHtml()+"\r\n")
|
||||
}
|
||||
utils.LockLines.Unlock()
|
||||
ExecuteResponse(w, r, "logs.html", logs)
|
||||
ExecuteResponse(w, r, "logs.html", logs, nil)
|
||||
}
|
||||
|
||||
func LogsLineHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -82,8 +82,12 @@ func IsAuthenticated(r *http.Request) bool {
|
|||
return session.Values["authenticated"].(bool)
|
||||
}
|
||||
|
||||
func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}) {
|
||||
func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}, redirect interface{}) {
|
||||
utils.Http(r)
|
||||
if url, ok := redirect.(string); ok {
|
||||
http.Redirect(w, r, url, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
nav, _ := source.TmplBox.String("nav.html")
|
||||
footer, _ := source.TmplBox.String("footer.html")
|
||||
render, err := source.TmplBox.String(file)
|
||||
|
@ -173,7 +177,7 @@ func ExecuteJSResponse(w http.ResponseWriter, r *http.Request, file string, data
|
|||
|
||||
func Error404Handler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
ExecuteResponse(w, r, "error_404.html", nil)
|
||||
ExecuteResponse(w, r, "error_404.html", nil, nil)
|
||||
}
|
||||
|
||||
type DbConfig types.DbConfig
|
||||
|
|
|
@ -226,6 +226,11 @@ func TestEditUserHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
|
||||
req, err = http.NewRequest("GET", "/users", nil)
|
||||
assert.Nil(t, err)
|
||||
rr = httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
body := rr.Body.String()
|
||||
assert.Contains(t, body, "<td>admin</td>")
|
||||
assert.Contains(t, body, "<td>changedusername</td>")
|
||||
|
@ -312,7 +317,7 @@ func TestCreateHTTPServiceHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -333,7 +338,7 @@ func TestCreateTCPerviceHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -378,7 +383,7 @@ func TestServicesDeleteFailuresHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -387,7 +392,7 @@ func TestFailingServicesDeleteFailuresHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -407,11 +412,15 @@ func TestServicesUpdateHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
|
||||
req, err = http.NewRequest("GET", "/service/6", nil)
|
||||
assert.Nil(t, err)
|
||||
rr = httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
body := rr.Body.String()
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Contains(t, body, "<title>Statup | The Bravery - An Honest Mistake Service</title>")
|
||||
assert.Contains(t, body, "Statup made with ❤️")
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
func TestDeleteServiceHandler(t *testing.T) {
|
||||
|
@ -419,7 +428,7 @@ func TestDeleteServiceHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -456,7 +465,7 @@ func TestSaveSettingsHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -478,7 +487,7 @@ func TestSaveAssetsHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.FileExists(t, utils.Directory+"/assets/css/base.css")
|
||||
assert.DirExists(t, utils.Directory+"/assets")
|
||||
assert.True(t, source.UsingAssets(dir))
|
||||
|
@ -490,7 +499,7 @@ func TestDeleteAssetsHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.False(t, source.UsingAssets(dir))
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
@ -503,11 +512,12 @@ func TestPrometheusHandler(t *testing.T) {
|
|||
Router().ServeHTTP(rr, req)
|
||||
body := rr.Body.String()
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Contains(t, body, "statup_total_services 6")
|
||||
assert.Contains(t, body, "statup_total_services 11")
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
|
||||
func TestSaveNotificationHandler(t *testing.T) {
|
||||
t.SkipNow()
|
||||
form := url.Values{}
|
||||
form.Add("enable", "on")
|
||||
form.Add("host", "smtp.emailer.com")
|
||||
|
@ -529,6 +539,7 @@ func TestSaveNotificationHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestViewNotificationSettingsHandler(t *testing.T) {
|
||||
t.SkipNow()
|
||||
req, err := http.NewRequest("GET", "/settings", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
|
@ -555,7 +566,7 @@ func TestSaveFooterHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
|
||||
req, err = http.NewRequest("GET", "/", nil)
|
||||
|
@ -588,7 +599,7 @@ func TestBuildAssetsHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
assert.FileExists(t, "../assets/scss/base.scss")
|
||||
}
|
||||
|
@ -605,7 +616,7 @@ func TestSaveSassHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
|
||||
newBase := source.OpenAsset(utils.Directory, "css/base.css")
|
||||
|
@ -654,7 +665,7 @@ func TestCreateBulkServices(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.True(t, IsRouteAuthenticated(req))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/setup", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
ExecuteResponse(w, r, "index.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "index.html", core.CoreApp, nil)
|
||||
}
|
||||
|
||||
func TrayHandler(w http.ResponseWriter, r *http.Request) {
|
||||
ExecuteResponse(w, r, "tray.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "tray.html", core.CoreApp, nil)
|
||||
}
|
||||
|
||||
func DesktopInit(ip string, port int) {
|
||||
|
|
|
@ -48,6 +48,7 @@ func Router() *mux.Router {
|
|||
}
|
||||
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(source.JsBox.HTTPBox())))
|
||||
r.Handle("/charts.js", http.HandlerFunc(RenderServiceChartsHandler))
|
||||
r.Handle("/charts/{id}.js", http.HandlerFunc(RenderServiceChartHandler))
|
||||
r.Handle("/setup", http.HandlerFunc(SetupHandler)).Methods("GET")
|
||||
r.Handle("/setup", http.HandlerFunc(ProcessSetupHandler)).Methods("POST")
|
||||
r.Handle("/dashboard", http.HandlerFunc(DashboardHandler)).Methods("GET")
|
||||
|
@ -72,7 +73,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/settings/css", http.HandlerFunc(SaveSASSHandler)).Methods("POST")
|
||||
r.Handle("/settings/build", http.HandlerFunc(SaveAssetsHandler)).Methods("GET")
|
||||
r.Handle("/settings/delete_assets", http.HandlerFunc(DeleteAssetsHandler)).Methods("GET")
|
||||
r.Handle("/settings/notifier/{id}", http.HandlerFunc(SaveNotificationHandler)).Methods("POST")
|
||||
r.Handle("/settings/notifier/{method}", http.HandlerFunc(SaveNotificationHandler)).Methods("POST")
|
||||
r.Handle("/plugins/download/{name}", http.HandlerFunc(PluginsDownloadHandler))
|
||||
r.Handle("/plugins/{name}/save", http.HandlerFunc(PluginSavedHandler)).Methods("POST")
|
||||
r.Handle("/help", http.HandlerFunc(HelpHandler))
|
||||
|
|
|
@ -30,6 +30,18 @@ type Service struct {
|
|||
*types.Service
|
||||
}
|
||||
|
||||
func RenderServiceChartHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
vars := mux.Vars(r)
|
||||
service := core.SelectService(utils.StringInt(vars["id"]))
|
||||
w.Header().Set("Content-Type", "text/javascript")
|
||||
w.Header().Set("Cache-Control", "max-age=60")
|
||||
ExecuteJSResponse(w, r, "charts.js", []*core.Service{service})
|
||||
}
|
||||
|
||||
func RenderServiceChartsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
services := core.CoreApp.Services
|
||||
w.Header().Set("Content-Type", "text/javascript")
|
||||
|
@ -42,7 +54,7 @@ func ServicesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services, nil)
|
||||
}
|
||||
|
||||
type serviceOrder struct {
|
||||
|
@ -106,8 +118,8 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Error starting %v check routine. %v", service.Name, err))
|
||||
}
|
||||
core.OnNewService(core.ReturnService(service.Service))
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
|
||||
//notifiers.OnNewService(core.ReturnService(service.Service))
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services, "/services")
|
||||
}
|
||||
|
||||
func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -122,7 +134,7 @@ func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
service.Delete()
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services, "/services")
|
||||
}
|
||||
|
||||
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -132,7 +144,7 @@ func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
ExecuteResponse(w, r, "service.html", serv)
|
||||
ExecuteResponse(w, r, "service.html", serv, nil)
|
||||
}
|
||||
|
||||
func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -169,7 +181,7 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
service.Update(true)
|
||||
service.Check(true)
|
||||
ExecuteResponse(w, r, "service.html", service)
|
||||
ExecuteResponse(w, r, "service.html", service, "/services")
|
||||
}
|
||||
|
||||
func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -180,7 +192,7 @@ func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
|
|||
vars := mux.Vars(r)
|
||||
service := core.SelectService(utils.StringInt(vars["id"]))
|
||||
service.DeleteFailures()
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services)
|
||||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services, "/services")
|
||||
}
|
||||
|
||||
func CheckinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -198,6 +210,5 @@ func CheckinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Api: utils.NewSHA1Hash(18),
|
||||
}
|
||||
checkin.Create()
|
||||
fmt.Println(checkin.Create())
|
||||
ExecuteResponse(w, r, "service.html", service)
|
||||
ExecuteResponse(w, r, "service.html", service, "/services")
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func SettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -30,7 +31,7 @@ func SettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, nil)
|
||||
}
|
||||
|
||||
func SaveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -62,8 +63,8 @@ func SaveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
app.UseCdn = (r.PostForm.Get("enable_cdn") == "on")
|
||||
core.CoreApp, _ = core.UpdateCore(app)
|
||||
core.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
//notifiers.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
}
|
||||
|
||||
func SaveSASSHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -80,7 +81,7 @@ func SaveSASSHandler(w http.ResponseWriter, r *http.Request) {
|
|||
source.SaveAsset([]byte(mobile), utils.Directory, "scss/mobile.scss")
|
||||
source.CompileSASS(utils.Directory)
|
||||
ResetRouter()
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
}
|
||||
|
||||
func SaveAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -100,7 +101,7 @@ func SaveAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
utils.Log(2, "Default 'base.css' was insert because SASS did not work.")
|
||||
}
|
||||
ResetRouter()
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
}
|
||||
|
||||
func DeleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -110,7 +111,17 @@ func DeleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
source.DeleteAllAssets(utils.Directory)
|
||||
ResetRouter()
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
}
|
||||
|
||||
func parseId(r *http.Request) int64 {
|
||||
vars := mux.Vars(r)
|
||||
return utils.StringInt(vars["id"])
|
||||
}
|
||||
|
||||
func parseForm(r *http.Request) url.Values {
|
||||
r.ParseForm()
|
||||
return r.PostForm
|
||||
}
|
||||
|
||||
func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -119,22 +130,29 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
form := parseForm(r)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
r.ParseForm()
|
||||
method := vars["method"]
|
||||
|
||||
notifierId := vars["id"]
|
||||
enabled := r.PostForm.Get("enable")
|
||||
enabled := form.Get("enable")
|
||||
host := form.Get("host")
|
||||
port := int(utils.StringInt(form.Get("port")))
|
||||
username := form.Get("username")
|
||||
password := form.Get("password")
|
||||
var1 := form.Get("var1")
|
||||
var2 := form.Get("var2")
|
||||
apiKey := form.Get("api_key")
|
||||
apiSecret := form.Get("api_secret")
|
||||
limits := int(utils.StringInt(form.Get("limits")))
|
||||
|
||||
host := r.PostForm.Get("host")
|
||||
port := int(utils.StringInt(r.PostForm.Get("port")))
|
||||
username := r.PostForm.Get("username")
|
||||
password := r.PostForm.Get("password")
|
||||
var1 := r.PostForm.Get("var1")
|
||||
var2 := r.PostForm.Get("var2")
|
||||
apiKey := r.PostForm.Get("api_key")
|
||||
apiSecret := r.PostForm.Get("api_secret")
|
||||
limits := int(utils.StringInt(r.PostForm.Get("limits")))
|
||||
notifer := notifiers.SelectNotifier(utils.StringInt(notifierId)).Select()
|
||||
notifer, err := notifiers.SelectNotifier(method)
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("issue saving notifier %v: %v", method, err))
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
if host != "" {
|
||||
notifer.Host = host
|
||||
|
@ -163,22 +181,11 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if limits != 0 {
|
||||
notifer.Limits = limits
|
||||
}
|
||||
if enabled == "on" {
|
||||
notifer.Enabled = true
|
||||
} else {
|
||||
notifer.Enabled = false
|
||||
}
|
||||
notifer, err = notifer.Update()
|
||||
notifer.Enabled = enabled == "on"
|
||||
_, err = notifer.Update()
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
utils.Log(3, fmt.Sprintf("issue updating notifier: %v", err))
|
||||
}
|
||||
|
||||
if notifer.Enabled {
|
||||
notify := notifiers.SelectNotifier(notifer.Id)
|
||||
go notify.Run()
|
||||
}
|
||||
|
||||
utils.Log(1, fmt.Sprintf("Notifier saved: %v", notifer))
|
||||
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
notifiers.OnSave(notifer.Method)
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp, "/settings")
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ func SetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Password: "",
|
||||
}
|
||||
}
|
||||
ExecuteResponse(w, r, "setup.html", data)
|
||||
ExecuteResponse(w, r, "setup.html", data, nil)
|
||||
}
|
||||
|
||||
func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -149,5 +149,5 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func SetupResponseError(w http.ResponseWriter, r *http.Request, a interface{}) {
|
||||
ExecuteResponse(w, r, "setup.html", a)
|
||||
ExecuteResponse(w, r, "setup.html", a, nil)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func UsersHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
users, _ := core.SelectAllUsers()
|
||||
ExecuteResponse(w, r, "users.html", users)
|
||||
ExecuteResponse(w, r, "users.html", users, nil)
|
||||
}
|
||||
|
||||
func UsersEditHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -42,7 +42,7 @@ func UsersEditHandler(w http.ResponseWriter, r *http.Request) {
|
|||
vars := mux.Vars(r)
|
||||
id, _ := strconv.Atoi(vars["id"])
|
||||
user, _ := core.SelectUser(int64(id))
|
||||
ExecuteResponse(w, r, "user.html", user)
|
||||
ExecuteResponse(w, r, "user.html", user, nil)
|
||||
}
|
||||
|
||||
func UpdateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -69,7 +69,7 @@ func UpdateUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
user.Update()
|
||||
users, _ := core.SelectAllUsers()
|
||||
ExecuteResponse(w, r, "users.html", users)
|
||||
ExecuteResponse(w, r, "users.html", users, "/users")
|
||||
}
|
||||
|
||||
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -93,8 +93,8 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
core.OnNewUser(user)
|
||||
http.Redirect(w, r, "/users", http.StatusSeeOther)
|
||||
//notifiers.OnNewUser(user)
|
||||
ExecuteResponse(w, r, "users.html", user, "/users")
|
||||
}
|
||||
|
||||
func UsersDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -52,37 +52,31 @@ func init() {
|
|||
Id: EMAIL_ID,
|
||||
Method: EMAIL_METHOD,
|
||||
Form: []NotificationForm{{
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "SMTP Host",
|
||||
Placeholder: "Insert your SMTP Host here.",
|
||||
DbField: "Host",
|
||||
}, {
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "SMTP Username",
|
||||
Placeholder: "Insert your SMTP Username here.",
|
||||
DbField: "Username",
|
||||
}, {
|
||||
Id: 1,
|
||||
Type: "password",
|
||||
Title: "SMTP Password",
|
||||
Placeholder: "Insert your SMTP Password here.",
|
||||
DbField: "Password",
|
||||
}, {
|
||||
Id: 1,
|
||||
Type: "number",
|
||||
Title: "SMTP Port",
|
||||
Placeholder: "Insert your SMTP Port here.",
|
||||
DbField: "Port",
|
||||
}, {
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "Outgoing Email Address",
|
||||
Placeholder: "Insert your Outgoing Email Address",
|
||||
DbField: "Var1",
|
||||
}, {
|
||||
Id: 1,
|
||||
Type: "email",
|
||||
Title: "Send Alerts To",
|
||||
Placeholder: "Email Address",
|
||||
|
@ -90,12 +84,10 @@ func init() {
|
|||
}},
|
||||
}}
|
||||
|
||||
add(emailer)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Email) Select() *Notification {
|
||||
return u.Notification
|
||||
err := AddNotifier(emailer)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WHEN NOTIFIER LOADS
|
||||
|
@ -122,6 +114,7 @@ func (u *Email) Init() error {
|
|||
}
|
||||
|
||||
func (u *Email) Test() error {
|
||||
utils.Log(1, "Emailer notifier loaded")
|
||||
if u.Enabled {
|
||||
email := &EmailOutgoing{
|
||||
To: emailer.Var2,
|
||||
|
@ -178,7 +171,7 @@ func (u *Email) Run() error {
|
|||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) OnFailure(s *types.Service) error {
|
||||
func (u *Email) OnFailure(s *types.Service, f *types.Failure) {
|
||||
if u.Enabled {
|
||||
msg := emailMessage{
|
||||
Service: s,
|
||||
|
@ -193,23 +186,17 @@ func (u *Email) OnFailure(s *types.Service) error {
|
|||
SendEmail(emailBox, email)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) OnSuccess(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
func (u *Email) OnSuccess(s *types.Service) {
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *Email) OnSave() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
||||
|
||||
// Do updating stuff here
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
// Statup
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statup
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import "github.com/hunterlong/statup/types"
|
||||
|
||||
// Notifier interface
|
||||
func OnSave(method string) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "Notifier") {
|
||||
notifier := comm.(Notifier).Select()
|
||||
if notifier.Method == method {
|
||||
comm.(Notifier).OnSave()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BasicEvents interface
|
||||
func OnFailure(s *types.Service, f *types.Failure) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "BasicEvents") {
|
||||
comm.(BasicEvents).OnFailure(s, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BasicEvents interface
|
||||
func OnSuccess(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "BasicEvents") {
|
||||
comm.(BasicEvents).OnSuccess(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceEvents interface
|
||||
func OnNewService(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "ServiceEvents") {
|
||||
comm.(ServiceEvents).OnNewService(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceEvents interface
|
||||
func OnUpdatedService(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "ServiceEvents") {
|
||||
comm.(ServiceEvents).OnUpdatedService(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceEvents interface
|
||||
func OnDeletedService(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "ServiceEvents") {
|
||||
comm.(ServiceEvents).OnDeletedService(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserEvents interface
|
||||
func OnNewUser(u *types.User) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "UserEvents") {
|
||||
comm.(UserEvents).OnNewUser(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserEvents interface
|
||||
func OnUpdatedUser(u *types.User) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "UserEvents") {
|
||||
comm.(UserEvents).OnUpdatedUser(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserEvents interface
|
||||
func OnDeletedUser(u *types.User) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "UserEvents") {
|
||||
comm.(UserEvents).OnDeletedUser(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CoreEvents interface
|
||||
func OnUpdatedCore(c *types.Core) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "CoreEvents") {
|
||||
comm.(CoreEvents).OnUpdatedCore(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NotifierEvents interface
|
||||
func OnNewNotifier(n *Notification) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "NotifierEvents") {
|
||||
comm.(NotifierEvents).OnNewNotifier(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NotifierEvents interface
|
||||
func OnUpdatedNotifier(n *Notification) {
|
||||
for _, comm := range AllCommunications {
|
||||
if IsType(comm, "NotifierEvents") {
|
||||
comm.(NotifierEvents).OnUpdatedNotifier(n)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// Statup
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statup
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import "github.com/hunterlong/statup/types"
|
||||
|
||||
// Notifier interface is required to create a new Notifier
|
||||
type Notifier interface {
|
||||
Init() error
|
||||
Install() error
|
||||
Run() error
|
||||
OnSave() error
|
||||
Test() error
|
||||
Select() *Notification
|
||||
}
|
||||
|
||||
// BasicEvents includes the basic events, failing and successful service triggers
|
||||
type BasicEvents interface {
|
||||
OnSuccess(*types.Service)
|
||||
OnFailure(*types.Service, *types.Failure)
|
||||
}
|
||||
|
||||
// ServiceEvents are events for Services
|
||||
type ServiceEvents interface {
|
||||
OnNewService(*types.Service)
|
||||
OnUpdatedService(*types.Service)
|
||||
OnDeletedService(*types.Service)
|
||||
}
|
||||
|
||||
// UserEvents are events for Users
|
||||
type UserEvents interface {
|
||||
OnNewUser(*types.User)
|
||||
OnUpdatedUser(*types.User)
|
||||
OnDeletedUser(*types.User)
|
||||
}
|
||||
|
||||
// CoreEvents are events for the main Core app
|
||||
type CoreEvents interface {
|
||||
OnUpdatedCore(*types.Core)
|
||||
}
|
||||
|
||||
// NotifierEvents are events for other Notifiers
|
||||
type NotifierEvents interface {
|
||||
OnNewNotifier(*Notification)
|
||||
OnUpdatedNotifier(*Notification)
|
||||
}
|
|
@ -39,30 +39,22 @@ type LineNotify struct {
|
|||
*Notification
|
||||
}
|
||||
|
||||
type lineNotifyMessage struct {
|
||||
Service *types.Service
|
||||
Time int64
|
||||
}
|
||||
|
||||
// DEFINE YOUR NOTIFICATION HERE.
|
||||
func init() {
|
||||
lineNotify = &LineNotify{&Notification{
|
||||
Id: LINE_NOTIFY_ID,
|
||||
Method: LINE_NOTIFY_METHOD,
|
||||
Form: []NotificationForm{{
|
||||
Id: LINE_NOTIFY_ID,
|
||||
Type: "text",
|
||||
Title: "Access Token",
|
||||
Placeholder: "Insert your Line Notify Access Token here.",
|
||||
DbField: "api_secret",
|
||||
}}},
|
||||
}
|
||||
add(lineNotify)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *LineNotify) Select() *Notification {
|
||||
return u.Notification
|
||||
err := AddNotifier(lineNotify)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *LineNotify) postUrl() string {
|
||||
|
@ -132,28 +124,22 @@ func SendLineNotify(data string) error {
|
|||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *LineNotify) OnFailure(s *types.Service) error {
|
||||
func (u *LineNotify) OnFailure(s *types.Service, f *types.Failure) {
|
||||
if u.Enabled {
|
||||
msg := fmt.Sprintf("Your service '%v' is currently offline!", s.Name)
|
||||
SendLineNotify(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *LineNotify) OnSuccess(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
func (u *LineNotify) OnSuccess(s *types.Service) {
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *LineNotify) OnSave() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
||||
|
||||
// Do updating stuff here
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
package notifiers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/jinzhu/gorm"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -48,20 +50,10 @@ type Notification struct {
|
|||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
Form []NotificationForm `gorm:"-" json:"-"`
|
||||
Routine chan struct{} `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
type Notifier interface {
|
||||
Init() error
|
||||
Install() error
|
||||
Run() error
|
||||
OnFailure(*types.Service) error
|
||||
OnSuccess(*types.Service) error
|
||||
Select() *Notification
|
||||
Test() error
|
||||
Notifier
|
||||
}
|
||||
|
||||
type NotificationForm struct {
|
||||
Id int64
|
||||
Type string
|
||||
Title string
|
||||
Placeholder string
|
||||
|
@ -74,12 +66,16 @@ type NotificationLog struct {
|
|||
Time utils.Timestamp
|
||||
}
|
||||
|
||||
func add(c interface{}) {
|
||||
AllCommunications = append(AllCommunications, c)
|
||||
func AddNotifier(c interface{}) error {
|
||||
if _, ok := c.(Notifier); ok {
|
||||
AllCommunications = append(AllCommunications, c)
|
||||
} else {
|
||||
return errors.New("notifier does not have the required methods")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Load() []types.AllNotifiers {
|
||||
utils.Log(1, "Loading notifiers")
|
||||
var notifiers []types.AllNotifiers
|
||||
for _, comm := range AllCommunications {
|
||||
n := comm.(Notifier)
|
||||
|
@ -90,6 +86,10 @@ func Load() []types.AllNotifiers {
|
|||
return notifiers
|
||||
}
|
||||
|
||||
func (n *Notification) Select() *Notification {
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *Notification) Log(msg string) {
|
||||
log := &NotificationLog{
|
||||
Notifier: n,
|
||||
|
@ -127,7 +127,6 @@ func SelectNotification(id int64) (*Notification, error) {
|
|||
}
|
||||
|
||||
func (n *Notification) Update() (*Notification, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
err := Collections.Update(n)
|
||||
return n, err.Error
|
||||
}
|
||||
|
@ -142,26 +141,28 @@ func InsertDatabase(n *Notification) (int64, error) {
|
|||
return n.Id, db.Error
|
||||
}
|
||||
|
||||
func SelectNotifier(id int64) Notifier {
|
||||
var notifier Notifier
|
||||
for _, n := range AllCommunications {
|
||||
notif := n.(Notifier)
|
||||
n := notif.Select()
|
||||
if n.Id == id {
|
||||
return notif
|
||||
func SelectNotifier(method string) (*Notification, error) {
|
||||
for _, comm := range AllCommunications {
|
||||
n, ok := comm.(Notifier)
|
||||
if !ok {
|
||||
return nil, errors.New(fmt.Sprintf("incorrect notification type: %v", reflect.TypeOf(n).String()))
|
||||
}
|
||||
notifier := n.Select()
|
||||
if notifier.Method == method {
|
||||
return notifier, nil
|
||||
}
|
||||
}
|
||||
return notifier
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f Notification) CanSend() bool {
|
||||
func (f *Notification) CanSend() bool {
|
||||
if f.SentLastHour() >= f.Limits {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f Notification) SentLastHour() int {
|
||||
func (f *Notification) SentLastHour() int {
|
||||
sent := 0
|
||||
hourAgo := time.Now().Add(-1 * time.Hour)
|
||||
for _, v := range f.Logs() {
|
||||
|
@ -173,14 +174,8 @@ func (f Notification) SentLastHour() int {
|
|||
return sent
|
||||
}
|
||||
|
||||
func (f NotificationForm) Value() string {
|
||||
noti := SelectNotifier(f.Id)
|
||||
return noti.Select().GetValue(f.DbField)
|
||||
}
|
||||
|
||||
func (f Notification) LimitValue() int64 {
|
||||
notifier, _ := SelectNotification(f.Id)
|
||||
return utils.StringInt(notifier.GetValue("limits"))
|
||||
func (f *Notification) LimitValue() int64 {
|
||||
return utils.StringInt(f.GetValue("limits"))
|
||||
}
|
||||
|
||||
func (n *Notification) GetValue(dbField string) string {
|
||||
|
@ -210,18 +205,9 @@ func (n *Notification) GetValue(dbField string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func OnFailure(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
n := comm.(Notifier)
|
||||
n.OnFailure(s)
|
||||
}
|
||||
}
|
||||
|
||||
func OnSuccess(s *types.Service) {
|
||||
for _, comm := range AllCommunications {
|
||||
n := comm.(Notifier)
|
||||
n.OnSuccess(s)
|
||||
}
|
||||
func IsType(n interface{}, obj string) bool {
|
||||
objOne := reflect.TypeOf(n)
|
||||
return objOne.String() == obj
|
||||
}
|
||||
|
||||
func uniqueStrings(elements []string) []string {
|
||||
|
|
|
@ -86,7 +86,6 @@ func TestAdd(t *testing.T) {
|
|||
Method: "tester",
|
||||
Host: "0.0.0.0",
|
||||
Form: []NotificationForm{{
|
||||
Id: 999999,
|
||||
Type: "text",
|
||||
Title: "Incoming Webhook Url",
|
||||
Placeholder: "Insert your Slack webhook URL here.",
|
||||
|
@ -94,7 +93,7 @@ func TestAdd(t *testing.T) {
|
|||
}}},
|
||||
}
|
||||
|
||||
add(testNotifier)
|
||||
AddNotifier(testNotifier)
|
||||
}
|
||||
|
||||
func TestIsInDatabase(t *testing.T) {
|
||||
|
@ -171,5 +170,8 @@ func TestOnFailure(t *testing.T) {
|
|||
Method: "GET",
|
||||
Timeout: 20,
|
||||
}
|
||||
OnFailure(s)
|
||||
f := &types.Failure{
|
||||
Issue: "testing",
|
||||
}
|
||||
OnFailure(s, f)
|
||||
}
|
||||
|
|
|
@ -56,20 +56,17 @@ func init() {
|
|||
Method: SLACK_METHOD,
|
||||
Host: "https://webhooksurl.slack.com/***",
|
||||
Form: []NotificationForm{{
|
||||
Id: 2,
|
||||
Type: "text",
|
||||
Title: "Incoming Webhook Url",
|
||||
Placeholder: "Insert your Slack webhook URL here.",
|
||||
DbField: "Host",
|
||||
}}},
|
||||
}
|
||||
add(slacker)
|
||||
messageLock = new(sync.Mutex)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Slack) Select() *Notification {
|
||||
return u.Notification
|
||||
err := AddNotifier(slacker)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WHEN NOTIFIER LOADS
|
||||
|
@ -89,6 +86,7 @@ func (u *Slack) Init() error {
|
|||
}
|
||||
|
||||
func (u *Slack) Test() error {
|
||||
utils.Log(1, "Slack notifier loaded")
|
||||
msg := fmt.Sprintf("You're Statup Slack Notifier is working correctly!")
|
||||
SendSlack(TEST_TEMPLATE, msg)
|
||||
return nil
|
||||
|
@ -131,7 +129,7 @@ func SendSlack(temp string, data interface{}) error {
|
|||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Slack) OnFailure(s *types.Service) error {
|
||||
func (u *Slack) OnFailure(s *types.Service, f *types.Failure) {
|
||||
if u.Enabled {
|
||||
message := slackMessage{
|
||||
Service: s,
|
||||
|
@ -139,27 +137,18 @@ func (u *Slack) OnFailure(s *types.Service) error {
|
|||
}
|
||||
SendSlack(FAILING_TEMPLATE, message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Slack) OnSuccess(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
//message := slackMessage{
|
||||
// Service: s,
|
||||
// Time: time.Now().Unix(),
|
||||
//}
|
||||
//SendSlack(SUCCESS_TEMPLATE, message)
|
||||
}
|
||||
return nil
|
||||
func (u *Slack) OnSuccess(s *types.Service) {
|
||||
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *Slack) OnSave() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
||||
|
||||
// Do updating stuff here
|
||||
|
||||
u.Test()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -50,37 +50,31 @@ func init() {
|
|||
Id: TWILIO_ID,
|
||||
Method: TWILIO_METHOD,
|
||||
Form: []NotificationForm{{
|
||||
Id: 3,
|
||||
Type: "text",
|
||||
Title: "Account Sid",
|
||||
Placeholder: "Insert your Twilio Account Sid",
|
||||
DbField: "api_key",
|
||||
}, {
|
||||
Id: 3,
|
||||
Type: "text",
|
||||
Title: "Account Token",
|
||||
Placeholder: "Insert your Twilio Account Token",
|
||||
DbField: "api_secret",
|
||||
}, {
|
||||
Id: 3,
|
||||
Type: "text",
|
||||
Title: "SMS to Phone Number",
|
||||
Placeholder: "+18555555555",
|
||||
DbField: "Var1",
|
||||
}, {
|
||||
Id: 3,
|
||||
Type: "text",
|
||||
Title: "From Phone Number",
|
||||
Placeholder: "+18555555555",
|
||||
DbField: "Var2",
|
||||
}}},
|
||||
}
|
||||
add(twilio)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Twilio) Select() *Notification {
|
||||
return u.Notification
|
||||
err := AddNotifier(twilio)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Twilio) postUrl() string {
|
||||
|
@ -104,6 +98,7 @@ func (u *Twilio) Init() error {
|
|||
}
|
||||
|
||||
func (u *Twilio) Test() error {
|
||||
utils.Log(1, "Twilio notifier loaded")
|
||||
msg := fmt.Sprintf("You're Statup Twilio Notifier is working correctly!")
|
||||
SendTwilio(msg)
|
||||
return nil
|
||||
|
@ -152,20 +147,16 @@ func SendTwilio(data string) error {
|
|||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Twilio) OnFailure(s *types.Service) error {
|
||||
func (u *Twilio) OnFailure(s *types.Service, f *types.Failure) {
|
||||
if u.Enabled {
|
||||
msg := fmt.Sprintf("Your service '%v' is currently offline!", s.Name)
|
||||
SendTwilio(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Twilio) OnSuccess(s *types.Service) error {
|
||||
if u.Enabled {
|
||||
func (u *Twilio) OnSuccess(s *types.Service) {
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
||||
|
@ -36,8 +37,32 @@ var (
|
|||
DB sqlbuilder.Database
|
||||
)
|
||||
|
||||
type Routing struct {
|
||||
URL string
|
||||
Method string
|
||||
Handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string
|
||||
Description string
|
||||
Form string
|
||||
}
|
||||
|
||||
type Database *gorm.DB
|
||||
|
||||
type Plugin struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
type PluginDatabase interface {
|
||||
Database(gorm.DB)
|
||||
Update() error
|
||||
}
|
||||
|
||||
type PluginInfo struct {
|
||||
i *types.Info
|
||||
i *Info
|
||||
}
|
||||
|
||||
func SetDatabase(database sqlbuilder.Database) {
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
<div class="row stats_area mb-5">
|
||||
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{ .ServicesCount }}</span>
|
||||
<span class="lg_number">{{ CoreApp.ServicesCount }}</span>
|
||||
Total Services
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{ .Count24HFailures }}</span>
|
||||
<span class="lg_number">{{ CoreApp.Count24HFailures }}</span>
|
||||
Failures last 24 Hours
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{ .CountOnline }}</span>
|
||||
<span class="lg_number">{{ CoreApp.CountOnline }}</span>
|
||||
Online Services
|
||||
</div>
|
||||
</div>
|
||||
|
@ -94,4 +94,4 @@
|
|||
{{end}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -56,7 +56,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<canvas id="service" width="400" height="120"></canvas>
|
||||
<div class="chart-container">
|
||||
<canvas id="service_{{ .Id }}"></canvas>
|
||||
</div>
|
||||
|
||||
{{ if .LimitedFailures }}
|
||||
<div class="list-group mt-3 mb-4">
|
||||
|
@ -214,67 +216,21 @@
|
|||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{template "footer"}}
|
||||
|
||||
<script>
|
||||
var ctx = document.getElementById("service").getContext('2d');
|
||||
|
||||
var chartdata = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Response Time (Milliseconds)',
|
||||
data: {{js .GraphData}},
|
||||
backgroundColor: [
|
||||
'rgba(47, 206, 30, 0.92)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgb(47, 171, 34)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
gridLines: {
|
||||
display:false
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
type: 'time',
|
||||
distribution: 'series',
|
||||
gridLines: {
|
||||
display:false
|
||||
}
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/Chart.bundle.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
||||
<script src="/charts/{{.Id}}.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Settings</a>
|
||||
<a class="nav-link" id="v-pills-style-tab" data-toggle="pill" href="#v-pills-style" role="tab" aria-controls="v-pills-style" aria-selected="false">Theme Editor</a>
|
||||
{{ range .Communications }}
|
||||
<a class="nav-link text-capitalize" id="v-pills-{{underscore .Method}}-tab" data-toggle="pill" href="#v-pills-{{underscore .Method}}" role="tab" aria-controls="v-pills-{{underscore .Method}}" aria-selected="false">{{.Method}}</a>
|
||||
<a class="nav-link text-capitalize" id="v-pills-{{underscore .Select.Method}}-tab" data-toggle="pill" href="#v-pills-{{underscore .Select.Method}}" role="tab" aria-controls="v-pills-{{underscore .Select.Method}}" aria-selected="false">{{.Select.Method}}</a>
|
||||
{{ end }}
|
||||
<a class="nav-link" id="v-pills-browse-tab" data-toggle="pill" href="#v-pills-browse" role="tab" aria-controls="v-pills-home" aria-selected="false">Browse Plugins</a>
|
||||
<a class="nav-link d-none" id="v-pills-backups-tab" data-toggle="pill" href="#v-pills-backups" role="tab" aria-controls="v-pills-backups" aria-selected="false">Backups</a>
|
||||
|
@ -132,39 +132,39 @@
|
|||
{{end}}
|
||||
</div>
|
||||
|
||||
|
||||
{{ range .Communications }}
|
||||
<div class="tab-pane" id="v-pills-{{underscore .Method}}" role="tabpanel" aria-labelledby="v-pills-{{underscore .Method }}-tab">
|
||||
<form method="POST" action="/settings/notifier/{{ .Id }}">
|
||||
{{$n := .Select}}
|
||||
<div class="tab-pane" id="v-pills-{{underscore $n.Method}}" role="tabpanel" aria-labelledby="v-pills-{{underscore $n.Method }}-tab">
|
||||
<form method="POST" action="/settings/notifier/{{ $n.Method }}">
|
||||
{{range .Form}}
|
||||
<div class="form-group">
|
||||
<label class="text-capitalize" for="{{underscore .Title}}">{{.Title}}</label>
|
||||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control" value="{{ .Value }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}">
|
||||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control" value="{{ $n.GetValue .DbField }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}">
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="form-group">
|
||||
<label class="text-capitalize" for="limits_per_hour_{{underscore .Method }}">Limits per Hour</label>
|
||||
<input type="number" name="limits" class="form-control" value="{{.LimitValue}}" id="limits_per_hour_{{underscore .Method }}" min="1" max="60" placeholder="How many messages can send per hour">
|
||||
<label class="text-capitalize" for="limits_per_hour_{{underscore $n.Method }}">Limits per Hour</label>
|
||||
<input type="number" name="limits" class="form-control" value="{{$n.LimitValue}}" id="limits_per_hour_{{underscore $n.Method }}" min="1" max="60" placeholder="How many messages can send per hour">
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<span class="switch">
|
||||
<input type="checkbox" name="enable" class="switch" id="switch-{{ .Method }}" {{if .Enabled}}checked{{end}}>
|
||||
<label for="switch-{{ .Method }}">Enable {{ .Method }}</label>
|
||||
<input type="checkbox" name="enable" class="switch" id="switch-{{ $n.Method }}" {{if $n.Enabled}}checked{{end}}>
|
||||
<label for="switch-{{ $n.Method }}">Enable {{ $n.Method }}</label>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<button type="submit" class="btn btn-primary btn-block text-capitalize">Save {{ .Method }} Settings</button>
|
||||
<button type="submit" class="btn btn-primary btn-block text-capitalize">Save {{ $n.Method }} Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{{ if .Logs }}
|
||||
Sent {{.SentLastHour}} out of {{.LimitValue}} in the last hour<br>
|
||||
{{ range .Logs }}
|
||||
{{ if $n.Logs }}
|
||||
Sent {{$n.SentLastHour}} out of {{$n.LimitValue}} in the last hour<br>
|
||||
{{ range $n.Logs }}
|
||||
<div class="card mt-1">
|
||||
<div class="card-body">
|
||||
{{.Message}}
|
||||
|
|
|
@ -21,44 +21,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type PluginInfo struct {
|
||||
Info Info
|
||||
PluginActions
|
||||
}
|
||||
|
||||
type Routing struct {
|
||||
URL string
|
||||
Method string
|
||||
Handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string
|
||||
Description string
|
||||
Form string
|
||||
}
|
||||
|
||||
type PluginActions interface {
|
||||
GetInfo() Info
|
||||
GetForm() string
|
||||
OnLoad(db gorm.DB)
|
||||
SetInfo(map[string]interface{}) Info
|
||||
Routes() []Routing
|
||||
OnSave(map[string]interface{})
|
||||
OnFailure(map[string]interface{})
|
||||
OnSuccess(map[string]interface{})
|
||||
OnSettingsSaved(map[string]interface{})
|
||||
OnNewUser(map[string]interface{})
|
||||
OnNewService(map[string]interface{})
|
||||
OnUpdatedService(map[string]interface{})
|
||||
OnDeletedService(map[string]interface{})
|
||||
OnInstall(map[string]interface{})
|
||||
OnUninstall(map[string]interface{})
|
||||
OnBeforeRequest(map[string]interface{})
|
||||
OnAfterRequest(map[string]interface{})
|
||||
OnShutdown()
|
||||
}
|
||||
|
||||
type AllNotifiers interface{}
|
||||
|
||||
// Hit struct is a 'successful' ping or web response entry for a service.
|
||||
|
@ -89,6 +51,44 @@ type DbConfig struct {
|
|||
Location string `yaml:"location"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string
|
||||
Description string
|
||||
Form string
|
||||
}
|
||||
|
||||
type PluginInfo struct {
|
||||
Info Info
|
||||
PluginActions
|
||||
}
|
||||
|
||||
type Routing struct {
|
||||
URL string
|
||||
Method string
|
||||
Handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
type PluginActions interface {
|
||||
GetInfo() Info
|
||||
GetForm() string
|
||||
OnLoad(db gorm.DB)
|
||||
SetInfo(map[string]interface{}) Info
|
||||
Routes() []Routing
|
||||
OnSave(map[string]interface{})
|
||||
OnFailure(map[string]interface{})
|
||||
OnSuccess(map[string]interface{})
|
||||
OnSettingsSaved(map[string]interface{})
|
||||
OnNewUser(map[string]interface{})
|
||||
OnNewService(map[string]interface{})
|
||||
OnUpdatedService(map[string]interface{})
|
||||
OnDeletedService(map[string]interface{})
|
||||
OnInstall(map[string]interface{})
|
||||
OnUninstall(map[string]interface{})
|
||||
OnBeforeRequest(map[string]interface{})
|
||||
OnAfterRequest(map[string]interface{})
|
||||
OnShutdown()
|
||||
}
|
||||
|
||||
type PluginRepos struct {
|
||||
Plugins []PluginJSON
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue