mirror of https://github.com/statping/statping
vue
parent
d5ffa3a851
commit
eb5e291e56
4
Makefile
4
Makefile
|
@ -82,13 +82,13 @@ install:
|
||||||
|
|
||||||
generate:
|
generate:
|
||||||
cd source && go generate
|
cd source && go generate
|
||||||
cd handlers/graphql && go generate
|
|
||||||
|
|
||||||
# remove files for a clean compile/build
|
# remove files for a clean compile/build
|
||||||
clean:
|
clean:
|
||||||
rm -rf ./{logs,assets,plugins,*.db,config.yml,.sass-cache,config.yml,statping,build,.sass-cache,index.html,vendor}
|
rm -rf ./{logs,assets,plugins,*.db,config.yml,.sass-cache,config.yml,statping,build,.sass-cache,index.html,vendor}
|
||||||
rm -rf cmd/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log,*.html,*.json}
|
rm -rf cmd/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log,*.html,*.json}
|
||||||
rm -rf core/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
rm -rf core/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
||||||
|
rm -rf core/notifier/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
||||||
rm -rf handlers/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
rm -rf handlers/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
||||||
rm -rf notifiers/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
rm -rf notifiers/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
||||||
rm -rf source/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
rm -rf source/{logs,assets,plugins,*.db,config.yml,.sass-cache,*.log}
|
||||||
|
@ -104,7 +104,7 @@ clean:
|
||||||
find . -name "*.out" -type f -delete
|
find . -name "*.out" -type f -delete
|
||||||
find . -name "*.cpu" -type f -delete
|
find . -name "*.cpu" -type f -delete
|
||||||
find . -name "*.mem" -type f -delete
|
find . -name "*.mem" -type f -delete
|
||||||
rm -rf {build,tmp,docker}
|
rm -rf {build,tmp}
|
||||||
|
|
||||||
print_details:
|
print_details:
|
||||||
@echo \==== Statping Development Instance ====
|
@echo \==== Statping Development Instance ====
|
||||||
|
|
76
cmd/cli.go
76
cmd/cli.go
|
@ -19,14 +19,11 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statping/core"
|
"github.com/hunterlong/statping/core"
|
||||||
"github.com/hunterlong/statping/handlers"
|
|
||||||
"github.com/hunterlong/statping/source"
|
"github.com/hunterlong/statping/source"
|
||||||
"github.com/hunterlong/statping/types"
|
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http/httptest"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -72,25 +69,25 @@ func catchCLI(args []string) error {
|
||||||
updateDisplay()
|
updateDisplay()
|
||||||
return errors.New("end")
|
return errors.New("end")
|
||||||
case "static":
|
case "static":
|
||||||
var err error
|
//var err error
|
||||||
if err = runLogs(); err != nil {
|
//if err = runLogs(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
if err = runAssets(); err != nil {
|
//if err = runAssets(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
fmt.Printf("Statping v%v Exporting Static 'index.html' page...\n", VERSION)
|
//fmt.Printf("Statping v%v Exporting Static 'index.html' page...\n", VERSION)
|
||||||
if _, err = core.LoadConfigFile(dir); err != nil {
|
//if _, err = core.LoadConfigFile(dir); err != nil {
|
||||||
log.Errorln("config.yml file not found")
|
// log.Errorln("config.yml file not found")
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
indexSource := ExportIndexHTML()
|
//indexSource := ExportIndexHTML()
|
||||||
//core.CloseDB()
|
////core.CloseDB()
|
||||||
if err = utils.SaveFile(dir+"/index.html", indexSource); err != nil {
|
//if err = utils.SaveFile(dir+"/index.html", indexSource); err != nil {
|
||||||
log.Errorln(err)
|
// log.Errorln(err)
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
log.Infoln("Exported Statping index page: 'index.html'")
|
//log.Infoln("Exported Statping index page: 'index.html'")
|
||||||
case "help":
|
case "help":
|
||||||
HelpEcho()
|
HelpEcho()
|
||||||
return errors.New("end")
|
return errors.New("end")
|
||||||
|
@ -103,10 +100,11 @@ func catchCLI(args []string) error {
|
||||||
if err = runAssets(); err != nil {
|
if err = runAssets(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = core.LoadConfigFile(dir); err != nil {
|
configs, err := core.LoadConfigFile(dir)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = core.CoreApp.Connect(false, dir); err != nil {
|
if err = core.CoreApp.Connect(configs, false, dir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if data, err = core.ExportSettings(); err != nil {
|
if data, err = core.ExportSettings(); err != nil {
|
||||||
|
@ -167,19 +165,19 @@ func catchCLI(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportIndexHTML returns the HTML of the index page as a string
|
// ExportIndexHTML returns the HTML of the index page as a string
|
||||||
func ExportIndexHTML() []byte {
|
//func ExportIndexHTML() []byte {
|
||||||
source.Assets()
|
// source.Assets()
|
||||||
core.CoreApp.Connect(false, utils.Directory)
|
// core.CoreApp.Connect(core.CoreApp., utils.Directory)
|
||||||
core.SelectAllServices(false)
|
// core.SelectAllServices(false)
|
||||||
core.CoreApp.UseCdn = types.NewNullBool(true)
|
// core.CoreApp.UseCdn = types.NewNullBool(true)
|
||||||
for _, srv := range core.Services() {
|
// for _, srv := range core.Services() {
|
||||||
core.CheckService(srv, true)
|
// core.CheckService(srv, true)
|
||||||
}
|
// }
|
||||||
w := httptest.NewRecorder()
|
// w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest("GET", "/", nil)
|
// r := httptest.NewRequest("GET", "/", nil)
|
||||||
handlers.ExecuteResponse(w, r, "index.gohtml", nil, nil)
|
// handlers.ExecuteResponse(w, r, "index.gohtml", nil, nil)
|
||||||
return w.Body.Bytes()
|
// return w.Body.Bytes()
|
||||||
}
|
//}
|
||||||
|
|
||||||
func updateDisplay() error {
|
func updateDisplay() error {
|
||||||
gitCurrent, err := checkGithubUpdates()
|
gitCurrent, err := checkGithubUpdates()
|
||||||
|
@ -202,11 +200,11 @@ func updateDisplay() error {
|
||||||
|
|
||||||
// runOnce will initialize the Statping application and check each service 1 time, will not run HTTP server
|
// runOnce will initialize the Statping application and check each service 1 time, will not run HTTP server
|
||||||
func runOnce() error {
|
func runOnce() error {
|
||||||
_, err := core.LoadConfigFile(utils.Directory)
|
configs, err := core.LoadConfigFile(utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "config.yml file not found")
|
return errors.Wrap(err, "config.yml file not found")
|
||||||
}
|
}
|
||||||
err = core.CoreApp.Connect(false, utils.Directory)
|
err = core.CoreApp.Connect(configs, false, utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "issue connecting to database")
|
return errors.Wrap(err, "issue connecting to database")
|
||||||
}
|
}
|
||||||
|
|
46
cmd/main.go
46
cmd/main.go
|
@ -62,6 +62,13 @@ func parseFlags() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func exit(err error) {
|
||||||
|
fmt.Printf("%+v", core.Configs())
|
||||||
|
panic(err)
|
||||||
|
//log.Fatalln(err)
|
||||||
|
//os.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
// main will run the Statping application
|
// main will run the Statping application
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
var err error
|
||||||
|
@ -80,35 +87,54 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() == "end" {
|
if err.Error() == "end" {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(err)
|
exit(err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Info(fmt.Sprintf("Starting Statping v%v", VERSION))
|
log.Info(fmt.Sprintf("Starting Statping v%v", VERSION))
|
||||||
updateDisplay()
|
|
||||||
|
|
||||||
config, err := core.LoadConfigFile(utils.Directory)
|
if err := updateDisplay(); err != nil {
|
||||||
|
log.Warnln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if DB_CONN was set, and load config from that
|
||||||
|
autoConfigDb := utils.Getenv("DB_CONN", "").(string)
|
||||||
|
if autoConfigDb != "" {
|
||||||
|
log.Infof("Environment variable 'DB_CONN' was set to %s, loading configs from ENV.", autoConfigDb)
|
||||||
|
if _, err := core.LoadUsingEnv(); err != nil {
|
||||||
|
exit(err)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
afterConfigLoaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to load config.yml file from current directory, if no file, then start in setup mode.
|
||||||
|
_, err = core.LoadConfigFile(utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
core.CoreApp.Setup = false
|
core.CoreApp.Setup = false
|
||||||
writeAble, err := utils.DirWritable(utils.Directory)
|
writeAble, err := utils.DirWritable(utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
exit(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if !writeAble {
|
if !writeAble {
|
||||||
log.Fatalf("Statping does not have write permissions at: %v\nYou can change this directory by setting the STATPING_DIR environment variable to a dedicated path before starting.", utils.Directory)
|
log.Fatalf("Statping does not have write permissions at: %v\nYou can change this directory by setting the STATPING_DIR environment variable to a dedicated path before starting.", utils.Directory)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
if err := handlers.RunHTTPServer(ipAddress, port); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
afterConfigLoaded()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
core.CoreApp.Config = config.DbConfig
|
func afterConfigLoaded() {
|
||||||
|
|
||||||
if err := mainProcess(); err != nil {
|
if err := mainProcess(); err != nil {
|
||||||
log.Fatalln(err)
|
exit(err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +166,7 @@ func loadDotEnvs() error {
|
||||||
func mainProcess() error {
|
func mainProcess() error {
|
||||||
dir := utils.Directory
|
dir := utils.Directory
|
||||||
var err error
|
var err error
|
||||||
err = core.CoreApp.Connect(false, dir)
|
err = core.CoreApp.Connect(core.Configs(), false, dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(fmt.Sprintf("could not connect to database: %v", err))
|
log.Errorln(fmt.Sprintf("could not connect to database: %v", err))
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -17,7 +17,6 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ararog/timeago"
|
|
||||||
"github.com/hunterlong/statping/database"
|
"github.com/hunterlong/statping/database"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
|
@ -108,37 +107,6 @@ func SelectCheckin(api string) *Checkin {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllHits returns all of the CheckinHits for a given Checkin
|
|
||||||
func (c *Checkin) AllHits() []*types.CheckinHit {
|
|
||||||
var checkins []*types.CheckinHit
|
|
||||||
Database(&types.CheckinHit{}).Where("checkin = ?", c.Id).Order("id DESC").Find(&checkins)
|
|
||||||
return checkins
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hits returns all of the CheckinHits for a given Checkin
|
|
||||||
func (c *Checkin) AllFailures() []*types.Failure {
|
|
||||||
var failures []*types.Failure
|
|
||||||
Database(&types.Failure{}).
|
|
||||||
Where("checkin = ?", c.Id).
|
|
||||||
Where("method = 'checkin'").
|
|
||||||
Order("id desc").
|
|
||||||
Find(&failures)
|
|
||||||
|
|
||||||
return failures
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Checkin) GetFailures(count int) []*types.Failure {
|
|
||||||
var failures []*types.Failure
|
|
||||||
Database(&types.Failure{}).
|
|
||||||
Where("checkin = ?", c.Id).
|
|
||||||
Where("method = 'checkin'").
|
|
||||||
Limit(count).
|
|
||||||
Order("id desc").
|
|
||||||
Find(&failures)
|
|
||||||
|
|
||||||
return failures
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create will create a new Checkin
|
// Create will create a new Checkin
|
||||||
func (c *Checkin) Delete() {
|
func (c *Checkin) Delete() {
|
||||||
c.Close()
|
c.Close()
|
||||||
|
@ -171,35 +139,6 @@ func (c *Checkin) Create() (int64, error) {
|
||||||
return c.Id, err
|
return c.Id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update will update a Checkin
|
|
||||||
func (c *Checkin) Update() (int64, error) {
|
|
||||||
row := Database(c).Update(&c)
|
|
||||||
if row.Error() != nil {
|
|
||||||
log.Warnln(row.Error())
|
|
||||||
return 0, row.Error()
|
|
||||||
}
|
|
||||||
return c.Id, row.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create will create a new successful checkinHit
|
|
||||||
func (c *CheckinHit) Create() (int64, error) {
|
|
||||||
if c.CreatedAt.IsZero() {
|
|
||||||
c.CreatedAt = utils.Now()
|
|
||||||
}
|
|
||||||
row := Database(c).Create(&c)
|
|
||||||
if row.Error() != nil {
|
|
||||||
log.Warnln(row.Error())
|
|
||||||
return 0, row.Error()
|
|
||||||
}
|
|
||||||
return c.Id, row.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ago returns the duration of time between now and the last successful checkinHit
|
|
||||||
func (c *CheckinHit) Ago() string {
|
|
||||||
got, _ := timeago.TimeAgoWithTime(utils.Now(), c.CreatedAt)
|
|
||||||
return got
|
|
||||||
}
|
|
||||||
|
|
||||||
// RecheckCheckinFailure will check if a Service Checkin has been reported yet
|
// RecheckCheckinFailure will check if a Service Checkin has been reported yet
|
||||||
func (c *Checkin) RecheckCheckinFailure(guard chan struct{}) {
|
func (c *Checkin) RecheckCheckinFailure(guard chan struct{}) {
|
||||||
between := utils.Now().Sub(utils.Now()).Seconds()
|
between := utils.Now().Sub(utils.Now()).Seconds()
|
||||||
|
|
114
core/configs.go
114
core/configs.go
|
@ -30,15 +30,9 @@ type ErrorResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfigFile will attempt to load the 'config.yml' file in a specific directory
|
// LoadConfigFile will attempt to load the 'config.yml' file in a specific directory
|
||||||
func LoadConfigFile(directory string) (*DbConfig, error) {
|
func LoadConfigFile(directory string) (*types.DbConfig, error) {
|
||||||
var configs *DbConfig
|
var configs *types.DbConfig
|
||||||
|
|
||||||
dbConn := utils.Getenv("DB_CONN", "").(string)
|
|
||||||
|
|
||||||
if dbConn != "" {
|
|
||||||
log.Infof("DB_CONN=%s environment variable was found, waiting for database...", dbConn)
|
|
||||||
return LoadUsingEnv()
|
|
||||||
}
|
|
||||||
log.Debugln("Attempting to read config file at: " + directory + "/config.yml")
|
log.Debugln("Attempting to read config file at: " + directory + "/config.yml")
|
||||||
file, err := utils.OpenFile(directory + "/config.yml")
|
file, err := utils.OpenFile(directory + "/config.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,61 +44,75 @@ func LoadConfigFile(directory string) (*DbConfig, error) {
|
||||||
return nil, errors.Wrap(err, "yaml file not formatted correctly")
|
return nil, errors.Wrap(err, "yaml file not formatted correctly")
|
||||||
}
|
}
|
||||||
log.WithFields(utils.ToFields(configs)).Debugln("read config file: " + directory + "/config.yml")
|
log.WithFields(utils.ToFields(configs)).Debugln("read config file: " + directory + "/config.yml")
|
||||||
CoreApp.Config = configs.DbConfig
|
|
||||||
|
CoreApp.config = configs
|
||||||
|
|
||||||
return configs, err
|
return configs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Configs() *types.DbConfig {
|
||||||
|
return CoreApp.config
|
||||||
|
}
|
||||||
|
|
||||||
// LoadUsingEnv will attempt to load database configs based on environment variables. If DB_CONN is set if will force this function.
|
// LoadUsingEnv will attempt to load database configs based on environment variables. If DB_CONN is set if will force this function.
|
||||||
func LoadUsingEnv() (*DbConfig, error) {
|
func LoadUsingEnv() (*types.DbConfig, error) {
|
||||||
Configs, err := EnvToConfig()
|
configs, err := EnvToConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Configs, err
|
return configs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreApp.Name = utils.Getenv("NAME", "").(string)
|
CoreApp.Name = utils.Getenv("NAME", "").(string)
|
||||||
CoreApp.Domain = utils.Getenv("DOMAIN", Configs.LocalIP).(string)
|
CoreApp.Domain = utils.Getenv("DOMAIN", "").(string)
|
||||||
CoreApp.UseCdn = types.NewNullBool(utils.Getenv("USE_CDN", false).(bool))
|
CoreApp.UseCdn = types.NewNullBool(utils.Getenv("USE_CDN", false).(bool))
|
||||||
|
|
||||||
err = CoreApp.Connect(true, utils.Directory)
|
err = CoreApp.Connect(configs, true, utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error connecting to database")
|
return nil, errors.Wrap(err, "error connecting to database")
|
||||||
}
|
}
|
||||||
if err := Configs.Save(); err != nil {
|
if err := SaveConfig(configs); err != nil {
|
||||||
return nil, errors.Wrap(err, "error saving configuration")
|
return nil, errors.Wrap(err, "error saving configuration")
|
||||||
}
|
}
|
||||||
exists := DbSession.HasTable("core")
|
exists := database.Get().HasTable("core")
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Infoln(fmt.Sprintf("Core database does not exist, creating now!"))
|
return InitialSetup(configs)
|
||||||
if err := CoreApp.DropDatabase(); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error dropping database")
|
|
||||||
}
|
|
||||||
if err := CoreApp.CreateDatabase(); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error creating database")
|
|
||||||
}
|
|
||||||
CoreApp, err = Configs.InsertCore()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error creating the core database")
|
|
||||||
}
|
|
||||||
|
|
||||||
username := utils.Getenv("ADMIN_USER", "admin").(string)
|
|
||||||
password := utils.Getenv("ADMIN_PASSWORD", "admin").(string)
|
|
||||||
|
|
||||||
admin := &types.User{
|
|
||||||
Username: username,
|
|
||||||
Password: utils.HashPassword(password),
|
|
||||||
Email: "info@admin.com",
|
|
||||||
Admin: types.NewNullBool(true),
|
|
||||||
}
|
|
||||||
if _, err := database.Create(admin); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error creating admin")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := SampleData(); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error connecting sample data")
|
|
||||||
}
|
|
||||||
return Configs, err
|
|
||||||
}
|
}
|
||||||
return Configs, nil
|
|
||||||
|
CoreApp.config = configs
|
||||||
|
return configs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitialSetup(configs *types.DbConfig) (*types.DbConfig, error) {
|
||||||
|
log.Infoln(fmt.Sprintf("Core database does not exist, creating now!"))
|
||||||
|
if err := CoreApp.DropDatabase(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error dropping database")
|
||||||
|
}
|
||||||
|
if err := CoreApp.CreateDatabase(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error creating database")
|
||||||
|
}
|
||||||
|
CoreApp, err := InsertCore(configs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error creating the core database")
|
||||||
|
}
|
||||||
|
|
||||||
|
username := utils.Getenv("ADMIN_USER", "admin").(string)
|
||||||
|
password := utils.Getenv("ADMIN_PASSWORD", "admin").(string)
|
||||||
|
|
||||||
|
admin := &types.User{
|
||||||
|
Username: username,
|
||||||
|
Password: utils.HashPassword(password),
|
||||||
|
Email: "info@admin.com",
|
||||||
|
Admin: types.NewNullBool(true),
|
||||||
|
}
|
||||||
|
if _, err := database.Create(admin); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error creating admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SampleData(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error connecting sample data")
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreApp.config = configs
|
||||||
|
return configs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultPort accepts a database type and returns its default port
|
// defaultPort accepts a database type and returns its default port
|
||||||
|
@ -122,7 +130,7 @@ func defaultPort(db string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvToConfig converts environment variables to a DbConfig
|
// EnvToConfig converts environment variables to a DbConfig
|
||||||
func EnvToConfig() (*DbConfig, error) {
|
func EnvToConfig() (*types.DbConfig, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
dbConn := utils.Getenv("DB_CONN", "").(string)
|
dbConn := utils.Getenv("DB_CONN", "").(string)
|
||||||
|
@ -173,10 +181,7 @@ func EnvToConfig() (*DbConfig, error) {
|
||||||
Location: utils.Directory,
|
Location: utils.Directory,
|
||||||
SqlFile: sqlFile,
|
SqlFile: sqlFile,
|
||||||
}
|
}
|
||||||
|
return config, err
|
||||||
CoreApp.Config = config
|
|
||||||
|
|
||||||
return &DbConfig{config}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SampleData runs all the sample data for a new Statping installation
|
// SampleData runs all the sample data for a new Statping installation
|
||||||
|
@ -202,3 +207,10 @@ func DeleteConfig() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsSetup() bool {
|
||||||
|
if CoreApp.config != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
65
core/core.go
65
core/core.go
|
@ -35,6 +35,7 @@ type PluginRepos types.PluginRepos
|
||||||
type Core struct {
|
type Core struct {
|
||||||
*types.Core
|
*types.Core
|
||||||
services map[int64]*Service
|
services map[int64]*Service
|
||||||
|
config *types.DbConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -93,91 +94,45 @@ func InitApp() error {
|
||||||
|
|
||||||
// InsertNotifierDB inject the Statping database instance to the Notifier package
|
// InsertNotifierDB inject the Statping database instance to the Notifier package
|
||||||
func InsertNotifierDB() error {
|
func InsertNotifierDB() error {
|
||||||
if DbSession == nil {
|
if !database.Available() {
|
||||||
err := CoreApp.Connect(false, utils.Directory)
|
err := CoreApp.Connect(CoreApp.config, false, utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("database connection has not been created")
|
return errors.New("database connection has not been created")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifier.SetDB(DbSession)
|
notifier.SetDB(database.Get())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertIntegratorDB inject the Statping database instance to the Integrations package
|
// InsertIntegratorDB inject the Statping database instance to the Integrations package
|
||||||
func InsertIntegratorDB() error {
|
func InsertIntegratorDB() error {
|
||||||
if DbSession == nil {
|
if !database.Available() {
|
||||||
err := CoreApp.Connect(false, utils.Directory)
|
err := CoreApp.Connect(CoreApp.config, false, utils.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("database connection has not been created")
|
return errors.New("database connection has not been created")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
integrations.SetDB(DbSession)
|
integrations.SetDB(database.Get())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCore will update the CoreApp variable inside of the 'core' table in database
|
|
||||||
func UpdateCore(c *Core) (*Core, error) {
|
|
||||||
db := Database(&Core{}).Update(&c)
|
|
||||||
return c, db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentTime will return the current local time
|
|
||||||
func (c Core) CurrentTime() string {
|
|
||||||
t := time.Now().UTC()
|
|
||||||
current := utils.Timezoner(t, c.Timezone)
|
|
||||||
ansic := "Monday 03:04:05 PM"
|
|
||||||
return current.Format(ansic)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messages will return the current local time
|
|
||||||
func (c Core) Messages() []*Message {
|
|
||||||
var message []*Message
|
|
||||||
Database(&Message{}).Where("service = ?", 0).Limit(10).Find(&message)
|
|
||||||
return message
|
|
||||||
}
|
|
||||||
|
|
||||||
// UsingAssets will return true if /assets folder is present
|
// UsingAssets will return true if /assets folder is present
|
||||||
func (c Core) UsingAssets() bool {
|
func (c Core) UsingAssets() bool {
|
||||||
return source.UsingAssets(utils.Directory)
|
return source.UsingAssets(utils.Directory)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SassVars opens the file /assets/scss/variables.scss to be edited in Theme
|
|
||||||
func (c Core) SassVars() string {
|
|
||||||
if !source.UsingAssets(utils.Directory) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return source.OpenAsset("scss/variables.scss")
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseSASS is the base design , this opens the file /assets/scss/base.scss to be edited in Theme
|
|
||||||
func (c Core) BaseSASS() string {
|
|
||||||
if !source.UsingAssets(utils.Directory) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return source.OpenAsset("scss/base.scss")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MobileSASS is the -webkit responsive custom css designs. This opens the
|
|
||||||
// file /assets/scss/mobile.scss to be edited in Theme
|
|
||||||
func (c Core) MobileSASS() string {
|
|
||||||
if !source.UsingAssets(utils.Directory) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return source.OpenAsset("scss/mobile.scss")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SelectCore will return the CoreApp global variable and the settings/configs for Statping
|
// SelectCore will return the CoreApp global variable and the settings/configs for Statping
|
||||||
func SelectCore() (*Core, error) {
|
func SelectCore() (*Core, error) {
|
||||||
if DbSession == nil {
|
if !database.Available() {
|
||||||
log.Traceln("database has not been initiated yet.")
|
log.Traceln("database has not been initiated yet.")
|
||||||
return nil, errors.New("database has not been initiated yet.")
|
return nil, errors.New("database has not been initiated yet.")
|
||||||
}
|
}
|
||||||
exists := DbSession.HasTable("core")
|
exists := database.Get().HasTable("core")
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Errorf("core database has not been setup yet, does not have the 'core' table")
|
log.Errorf("core database has not been setup yet, does not have the 'core' table")
|
||||||
return nil, errors.New("core database has not been setup yet.")
|
return nil, errors.New("core database has not been setup yet.")
|
||||||
}
|
}
|
||||||
db := Database(&Core{}).First(&CoreApp)
|
db := database.Core().First(&CoreApp)
|
||||||
if db.Error() != nil {
|
if db.Error() != nil {
|
||||||
return nil, db.Error()
|
return nil, db.Error()
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ var (
|
||||||
skipNewDb bool
|
skipNewDb bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var configs *types.DbConfig
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dir = utils.Directory
|
dir = utils.Directory
|
||||||
utils.InitLogs()
|
utils.InitLogs()
|
||||||
|
@ -50,27 +52,29 @@ func TestDbConfig_Save(t *testing.T) {
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &DbConfig{&types.DbConfig{
|
config := &types.DbConfig{
|
||||||
DbConn: "sqlite",
|
DbConn: "sqlite",
|
||||||
Project: "Tester",
|
Project: "Tester",
|
||||||
Location: dir,
|
Location: dir,
|
||||||
}}
|
}
|
||||||
|
|
||||||
err := config.Save()
|
err := SaveConfig(config)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, "sqlite", CoreApp.Config.DbConn)
|
assert.Equal(t, "sqlite", config.DbConn)
|
||||||
assert.NotEmpty(t, CoreApp.Config.ApiKey)
|
assert.NotEmpty(t, config.ApiKey)
|
||||||
assert.NotEmpty(t, CoreApp.Config.ApiSecret)
|
assert.NotEmpty(t, config.ApiSecret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadDbConfig(t *testing.T) {
|
func TestLoadDbConfig(t *testing.T) {
|
||||||
Configs, err := LoadConfigFile(dir)
|
Configs, err := LoadConfigFile(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "sqlite", Configs.DbConn)
|
assert.Equal(t, "sqlite", Configs.DbConn)
|
||||||
|
|
||||||
|
configs = Configs
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDbConnection(t *testing.T) {
|
func TestDbConnection(t *testing.T) {
|
||||||
err := CoreApp.Connect(false, dir)
|
err := CoreApp.Connect(configs, false, dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +106,9 @@ func TestSeedDatabase(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReLoadDbConfig(t *testing.T) {
|
func TestReLoadDbConfig(t *testing.T) {
|
||||||
err := CoreApp.Connect(false, dir)
|
err := CoreApp.Connect(configs, false, dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "sqlite", CoreApp.Config.DbConn)
|
assert.Equal(t, "sqlite", CoreApp.config.DbConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectCore(t *testing.T) {
|
func TestSelectCore(t *testing.T) {
|
||||||
|
|
164
core/database.go
164
core/database.go
|
@ -18,70 +18,35 @@ package core
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
|
|
||||||
"github.com/go-yaml/yaml"
|
"github.com/go-yaml/yaml"
|
||||||
"github.com/hunterlong/statping/core/notifier"
|
"github.com/hunterlong/statping/core/notifier"
|
||||||
"github.com/hunterlong/statping/database"
|
"github.com/hunterlong/statping/database"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DbSession stores the Statping database session
|
// DbSession stores the Statping database session
|
||||||
DbSession database.Database
|
DbModels []interface{}
|
||||||
DbModels []interface{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Group{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}, &types.Incident{}, &types.IncidentUpdate{}, &types.Integration{}}
|
DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Group{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}, &types.Incident{}, &types.IncidentUpdate{}, &types.Integration{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DbConfig stores the config.yml file for the statup configuration
|
|
||||||
type DbConfig struct {
|
|
||||||
*types.DbConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func Database(obj interface{}) database.Database {
|
|
||||||
switch obj.(type) {
|
|
||||||
case *types.Service, *Service, []*Service:
|
|
||||||
return DbSession.Model(&types.Service{})
|
|
||||||
case *types.Hit, *Hit, []*Hit:
|
|
||||||
return DbSession.Model(&types.Hit{})
|
|
||||||
case *types.Failure, *Failure, []*Failure:
|
|
||||||
return DbSession.Model(&types.Failure{})
|
|
||||||
case *types.Core, *Core:
|
|
||||||
return DbSession.Table("core").Model(&CoreApp)
|
|
||||||
case *types.Checkin, *Checkin, []*Checkin:
|
|
||||||
return DbSession.Model(&types.Checkin{})
|
|
||||||
case *types.CheckinHit, *CheckinHit, []*CheckinHit:
|
|
||||||
return DbSession.Model(&types.CheckinHit{})
|
|
||||||
case *types.User, *User, []*User:
|
|
||||||
return DbSession.Model(&types.User{})
|
|
||||||
case *types.Group, *Group, []*Group:
|
|
||||||
return DbSession.Model(&types.Group{})
|
|
||||||
case *types.Incident, *Incident, []*Incident:
|
|
||||||
return DbSession.Model(&types.Incident{})
|
|
||||||
case *types.IncidentUpdate, *IncidentUpdate, []*IncidentUpdate:
|
|
||||||
return DbSession.Model(&types.IncidentUpdate{})
|
|
||||||
case *types.Message, *Message, []*Message:
|
|
||||||
return DbSession.Model(&types.Message{})
|
|
||||||
default:
|
|
||||||
return DbSession
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseDB will close the database connection if available
|
// CloseDB will close the database connection if available
|
||||||
func CloseDB() {
|
func CloseDB() {
|
||||||
if DbSession != nil {
|
database.Close()
|
||||||
DbSession.DB().Close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//// AfterFind for Core will set the timezone
|
//// AfterFind for Core will set the timezone
|
||||||
|
@ -140,11 +105,11 @@ func CloseDB() {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// InsertCore create the single row for the Core settings in Statping
|
// InsertCore create the single row for the Core settings in Statping
|
||||||
func (d *DbConfig) InsertCore() (*Core, error) {
|
func InsertCore(d *types.DbConfig) (*Core, error) {
|
||||||
apiKey := utils.Getenv("API_KEY", utils.NewSHA1Hash(40))
|
apiKey := utils.Getenv("API_KEY", utils.NewSHA1Hash(40))
|
||||||
apiSecret := utils.Getenv("API_SECRET", utils.NewSHA1Hash(40))
|
apiSecret := utils.Getenv("API_SECRET", utils.NewSHA1Hash(40))
|
||||||
|
|
||||||
CoreApp = &Core{Core: &types.Core{
|
core := &types.Core{
|
||||||
Name: d.Project,
|
Name: d.Project,
|
||||||
Description: d.Description,
|
Description: d.Description,
|
||||||
ConfigFile: "config.yml",
|
ConfigFile: "config.yml",
|
||||||
|
@ -152,22 +117,34 @@ func (d *DbConfig) InsertCore() (*Core, error) {
|
||||||
ApiSecret: apiSecret.(string),
|
ApiSecret: apiSecret.(string),
|
||||||
Domain: d.Domain,
|
Domain: d.Domain,
|
||||||
MigrationId: time.Now().Unix(),
|
MigrationId: time.Now().Unix(),
|
||||||
Config: d.DbConfig,
|
}
|
||||||
}}
|
|
||||||
query := DbSession.Create(CoreApp.Core)
|
CoreApp = &Core{Core: core}
|
||||||
return CoreApp, query.Error()
|
|
||||||
|
CoreApp.config = d
|
||||||
|
|
||||||
|
_, err := database.Create(CoreApp.Core)
|
||||||
|
return CoreApp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func findDbFile() string {
|
func findDbFile() string {
|
||||||
if CoreApp.Config.SqlFile != "" {
|
if CoreApp.config == nil {
|
||||||
return CoreApp.Config.SqlFile
|
return findSQLin(utils.Directory)
|
||||||
}
|
}
|
||||||
|
if CoreApp.config.SqlFile != "" {
|
||||||
|
return CoreApp.config.SqlFile
|
||||||
|
}
|
||||||
|
return utils.Directory + "/" + types.SqliteFilename
|
||||||
|
}
|
||||||
|
|
||||||
|
func findSQLin(path string) string {
|
||||||
filename := types.SqliteFilename
|
filename := types.SqliteFilename
|
||||||
err := filepath.Walk(utils.Directory, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if filepath.Ext(path) == ".db" {
|
if filepath.Ext(path) == ".db" {
|
||||||
|
fmt.Println("DB file is now: ", info.Name())
|
||||||
filename = info.Name()
|
filename = info.Name()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -179,20 +156,19 @@ func findDbFile() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect will attempt to connect to the sqlite, postgres, or mysql database
|
// Connect will attempt to connect to the sqlite, postgres, or mysql database
|
||||||
func (c *Core) Connect(retry bool, location string) error {
|
func (c *Core) Connect(configs *types.DbConfig, retry bool, location string) error {
|
||||||
postgresSSL := os.Getenv("POSTGRES_SSLMODE")
|
postgresSSL := os.Getenv("POSTGRES_SSLMODE")
|
||||||
if DbSession != nil {
|
if database.Available() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var conn string
|
var conn string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
configs := c.Config
|
|
||||||
switch configs.DbConn {
|
switch configs.DbConn {
|
||||||
case "sqlite":
|
case "sqlite", "sqlite3":
|
||||||
sqlFilename := findDbFile()
|
conn = findDbFile()
|
||||||
conn = sqlFilename
|
configs.SqlFile = fmt.Sprintf("%s/%s", utils.Directory, conn)
|
||||||
log.Infof("SQL database file at: %v/%v", utils.Directory, conn)
|
log.Infof("SQL database file at: %s", configs.SqlFile)
|
||||||
configs.DbConn = "sqlite3"
|
configs.DbConn = "sqlite3"
|
||||||
case "mysql":
|
case "mysql":
|
||||||
host := fmt.Sprintf("%v:%v", configs.DbHost, configs.DbPort)
|
host := fmt.Sprintf("%v:%v", configs.DbHost, configs.DbPort)
|
||||||
|
@ -210,10 +186,10 @@ func (c *Core) Connect(retry bool, location string) error {
|
||||||
log.WithFields(utils.ToFields(c, conn)).Debugln("attempting to connect to database")
|
log.WithFields(utils.ToFields(c, conn)).Debugln("attempting to connect to database")
|
||||||
dbSession, err := database.Openw(configs.DbConn, conn)
|
dbSession, err := database.Openw(configs.DbConn, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugln(fmt.Sprintf("Database connection error %v", err))
|
log.Debugln(fmt.Sprintf("Database connection error %s", err))
|
||||||
if retry {
|
if retry {
|
||||||
log.Errorln(fmt.Sprintf("Database connection to '%v' is not available, trying again in 5 seconds...", configs.DbHost))
|
log.Errorln(fmt.Sprintf("Database %s connection to '%s' is not available, trying again in 5 seconds...", configs.DbConn, configs.DbHost))
|
||||||
return c.waitForDb()
|
return c.waitForDb(configs)
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -229,19 +205,21 @@ func (c *Core) Connect(retry bool, location string) error {
|
||||||
dbSession.DB().SetConnMaxLifetime(maxLifeConn.(time.Duration))
|
dbSession.DB().SetConnMaxLifetime(maxLifeConn.(time.Duration))
|
||||||
|
|
||||||
if dbSession.DB().Ping() == nil {
|
if dbSession.DB().Ping() == nil {
|
||||||
DbSession = dbSession
|
|
||||||
if utils.VerboseMode >= 4 {
|
if utils.VerboseMode >= 4 {
|
||||||
DbSession.LogMode(true).Debug().SetLogger(gorm.Logger{log})
|
database.LogMode(true).Debug().SetLogger(gorm.Logger{log})
|
||||||
}
|
}
|
||||||
log.Infoln(fmt.Sprintf("Database %v connection was successful.", configs.DbConn))
|
log.Infoln(fmt.Sprintf("Database %v connection was successful.", configs.DbConn))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreApp.config = configs
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForDb will sleep for 5 seconds and try to connect to the database again
|
// waitForDb will sleep for 5 seconds and try to connect to the database again
|
||||||
func (c *Core) waitForDb() error {
|
func (c *Core) waitForDb(configs *types.DbConfig) error {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
return c.Connect(true, utils.Directory)
|
return c.Connect(configs, true, utils.Directory)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update will save the config.yml file
|
// Update will save the config.yml file
|
||||||
|
@ -252,18 +230,20 @@ func (c *Core) UpdateConfig() error {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
data, err := yaml.Marshal(c.Config)
|
defer config.Close()
|
||||||
|
|
||||||
|
data, err := yaml.Marshal(c.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
config.WriteString(string(data))
|
config.WriteString(string(data))
|
||||||
config.Close()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save will initially create the config.yml file
|
// Save will initially create the config.yml file
|
||||||
func (d *DbConfig) Save() error {
|
func SaveConfig(d *types.DbConfig) error {
|
||||||
config, err := os.Create(utils.Directory + "/config.yml")
|
config, err := os.Create(utils.Directory + "/config.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
|
@ -271,20 +251,28 @@ func (d *DbConfig) Save() error {
|
||||||
}
|
}
|
||||||
defer config.Close()
|
defer config.Close()
|
||||||
log.WithFields(utils.ToFields(d)).Debugln("saving config file at: " + utils.Directory + "/config.yml")
|
log.WithFields(utils.ToFields(d)).Debugln("saving config file at: " + utils.Directory + "/config.yml")
|
||||||
CoreApp.Config = d.DbConfig
|
|
||||||
|
|
||||||
apiKey := utils.Getenv("API_KEY", utils.NewSHA1Hash(16))
|
if d.ApiKey == "" || d.ApiSecret == "" {
|
||||||
apiSecret := utils.Getenv("API_SECRET", utils.NewSHA1Hash(16))
|
apiKey := utils.Getenv("API_KEY", utils.NewSHA1Hash(16))
|
||||||
|
apiSecret := utils.Getenv("API_SECRET", utils.NewSHA1Hash(16))
|
||||||
|
CoreApp.config.ApiKey = apiKey.(string)
|
||||||
|
CoreApp.config.ApiSecret = apiSecret.(string)
|
||||||
|
}
|
||||||
|
if d.DbConn == "sqlite3" {
|
||||||
|
d.DbConn = "sqlite"
|
||||||
|
}
|
||||||
|
|
||||||
CoreApp.Config.ApiKey = apiKey.(string)
|
|
||||||
CoreApp.Config.ApiSecret = apiSecret.(string)
|
|
||||||
data, err := yaml.Marshal(d)
|
data, err := yaml.Marshal(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
config.WriteString(string(data))
|
if _, err := config.WriteString(string(data)); err != nil {
|
||||||
log.WithFields(utils.ToFields(d)).Infoln("saved config file at: " + utils.Directory + "/config.yml")
|
return errors.Wrap(err, "error writing to config.yml")
|
||||||
|
}
|
||||||
|
log.WithFields(utils.ToFields(d)).Infoln("Saved config file at: " + utils.Directory + "/config.yml")
|
||||||
|
|
||||||
|
CoreApp.config = d
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,8 +287,8 @@ func (c *Core) CreateCore() *Core {
|
||||||
Domain: c.Domain,
|
Domain: c.Domain,
|
||||||
MigrationId: time.Now().Unix(),
|
MigrationId: time.Now().Unix(),
|
||||||
}
|
}
|
||||||
db := Database(newCore).Create(&newCore)
|
_, err := database.Create(&newCore)
|
||||||
if db.Error() == nil {
|
if err == nil {
|
||||||
CoreApp = &Core{Core: newCore}
|
CoreApp = &Core{Core: newCore}
|
||||||
}
|
}
|
||||||
CoreApp, err := SelectCore()
|
CoreApp, err := SelectCore()
|
||||||
|
@ -313,11 +301,11 @@ func (c *Core) CreateCore() *Core {
|
||||||
// DropDatabase will DROP each table Statping created
|
// DropDatabase will DROP each table Statping created
|
||||||
func (c *Core) DropDatabase() error {
|
func (c *Core) DropDatabase() error {
|
||||||
log.Infoln("Dropping Database Tables...")
|
log.Infoln("Dropping Database Tables...")
|
||||||
tables := []string{"checkins", "checkin_hits", "notifications", "core", "failures", "hits", "services", "users", "messages", "incidents", "incident_updates"}
|
for _, t := range DbModels {
|
||||||
for _, t := range tables {
|
if err := database.Get().DropTableIfExists(t); err != nil {
|
||||||
if err := DbSession.DropTableIfExists(t); err != nil {
|
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
log.Infof("Dropped table: %T\n", t)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -327,11 +315,11 @@ func (c *Core) CreateDatabase() error {
|
||||||
var err error
|
var err error
|
||||||
log.Infoln("Creating Database Tables...")
|
log.Infoln("Creating Database Tables...")
|
||||||
for _, table := range DbModels {
|
for _, table := range DbModels {
|
||||||
if err := DbSession.CreateTable(table); err.Error() != nil {
|
if err := database.Get().CreateTable(table); err.Error() != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := DbSession.Table("core").CreateTable(&types.Core{}); err.Error() != nil {
|
if err := database.Get().Table("core").CreateTable(&types.Core{}); err.Error() != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
log.Infoln("Statping Database Created")
|
log.Infoln("Statping Database Created")
|
||||||
|
@ -394,7 +382,7 @@ func (c *Core) ServicesFromEnvFile() error {
|
||||||
// If this function has an issue, it will ROLLBACK to the previous state.
|
// If this function has an issue, it will ROLLBACK to the previous state.
|
||||||
func (c *Core) MigrateDatabase() error {
|
func (c *Core) MigrateDatabase() error {
|
||||||
log.Infoln("Migrating Database Tables...")
|
log.Infoln("Migrating Database Tables...")
|
||||||
tx := DbSession.Begin()
|
tx := database.Begin("migration")
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
@ -412,11 +400,11 @@ func (c *Core) MigrateDatabase() error {
|
||||||
log.Errorln(fmt.Sprintf("Statping Database could not be migrated: %v", tx.Error()))
|
log.Errorln(fmt.Sprintf("Statping Database could not be migrated: %v", tx.Error()))
|
||||||
return tx.Error()
|
return tx.Error()
|
||||||
}
|
}
|
||||||
log.Infoln("Statping Database Migrated")
|
|
||||||
|
|
||||||
if err := tx.Commit().Error(); err != nil {
|
if err := tx.Commit().Error(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log.Infoln("Statping Database Migrated")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,3 @@ const (
|
||||||
limitedFailures = 32
|
limitedFailures = 32
|
||||||
limitedHits = 32
|
limitedHits = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
// Delete will remove a Failure record from the database
|
|
||||||
func (f *Failure) Delete() error {
|
|
||||||
db := Database(&types.Failure{}).Delete(f)
|
|
||||||
return db.Error()
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Incident struct {
|
type Incident struct {
|
||||||
|
@ -17,69 +16,3 @@ type IncidentUpdate struct {
|
||||||
func ReturnIncident(u *types.Incident) *Incident {
|
func ReturnIncident(u *types.Incident) *Incident {
|
||||||
return &Incident{u}
|
return &Incident{u}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectIncident returns the Incident based on the Incident's ID.
|
|
||||||
func SelectIncident(id int64) (*Incident, error) {
|
|
||||||
var incident Incident
|
|
||||||
err := Database(incident).Where("id = ?", id).First(&incident)
|
|
||||||
return &incident, err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllIncidents will return all incidents and updates recorded
|
|
||||||
func AllIncidents() []*Incident {
|
|
||||||
var incidents []*Incident
|
|
||||||
Database(incidents).Find(&incidents).Order("id desc")
|
|
||||||
for _, i := range incidents {
|
|
||||||
var updates []*types.IncidentUpdate
|
|
||||||
Database(updates).Find(&updates).Order("id desc")
|
|
||||||
i.Updates = updates
|
|
||||||
}
|
|
||||||
return incidents
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incidents will return the all incidents for a service
|
|
||||||
func (s *Service) Incidents() []*Incident {
|
|
||||||
var incidentArr []*Incident
|
|
||||||
Database(incidentArr).Where("service = ?", s.Id).Order("id desc").Find(&incidentArr)
|
|
||||||
return incidentArr
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllUpdates will return the all updates for an incident
|
|
||||||
func (i *Incident) AllUpdates() []*IncidentUpdate {
|
|
||||||
var updatesArr []*IncidentUpdate
|
|
||||||
Database(updatesArr).Where("incident = ?", i.Id).Order("id desc").Find(&updatesArr)
|
|
||||||
return updatesArr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete will remove a incident
|
|
||||||
func (i *Incident) Delete() error {
|
|
||||||
err := Database(i).Delete(i)
|
|
||||||
return err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create will create a incident and insert it into the database
|
|
||||||
func (i *Incident) Create() (int64, error) {
|
|
||||||
i.CreatedAt = time.Now().UTC()
|
|
||||||
db := Database(i).Create(i)
|
|
||||||
return i.Id, db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update will update a incident
|
|
||||||
func (i *Incident) Update() (int64, error) {
|
|
||||||
i.UpdatedAt = time.Now().UTC()
|
|
||||||
db := Database(i).Update(i)
|
|
||||||
return i.Id, db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete will remove a incident update
|
|
||||||
func (i *IncidentUpdate) Delete() error {
|
|
||||||
err := Database(i).Delete(i)
|
|
||||||
return err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create will create a incident update and insert it into the database
|
|
||||||
func (i *IncidentUpdate) Create() (int64, error) {
|
|
||||||
i.CreatedAt = time.Now().UTC()
|
|
||||||
db := Database(i).Create(i)
|
|
||||||
return i.Id, db.Error()
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,64 +16,14 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
*types.Message
|
*types.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectServiceMessages returns all messages for a service
|
|
||||||
func SelectServiceMessages(id int64) []*Message {
|
|
||||||
var message []*Message
|
|
||||||
Database(&Message{}).Where("service = ?", id).Limit(10).Find(&message)
|
|
||||||
return message
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReturnMessage will convert *types.Message to *core.Message
|
// ReturnMessage will convert *types.Message to *core.Message
|
||||||
func ReturnMessage(m *types.Message) *Message {
|
func ReturnMessage(m *types.Message) *Message {
|
||||||
return &Message{m}
|
return &Message{m}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectMessages returns all messages
|
|
||||||
func SelectMessages() ([]*Message, error) {
|
|
||||||
var messages []*Message
|
|
||||||
db := Database(&Message{}).Find(&messages).Order("id desc")
|
|
||||||
return messages, db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SelectMessage returns a Message based on the ID passed
|
|
||||||
func SelectMessage(id int64) (*Message, error) {
|
|
||||||
var message Message
|
|
||||||
db := Database(&Message{}).Where("id = ?", id).Find(&message)
|
|
||||||
return &message, db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create will create a Message and insert it into the database
|
|
||||||
func (m *Message) Create() (int64, error) {
|
|
||||||
m.CreatedAt = time.Now().UTC()
|
|
||||||
db := Database(&Message{}).Create(m)
|
|
||||||
if db.Error() != nil {
|
|
||||||
log.Errorln(fmt.Sprintf("Failed to create message %v #%v: %v", m.Title, m.Id, db.Error()))
|
|
||||||
return 0, db.Error()
|
|
||||||
}
|
|
||||||
return m.Id, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete will delete a Message from database
|
|
||||||
func (m *Message) Delete() error {
|
|
||||||
db := Database(&Message{}).Delete(m)
|
|
||||||
return db.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update will update a Message in the database
|
|
||||||
func (m *Message) Update() (*Message, error) {
|
|
||||||
db := Database(&Message{}).Update(m)
|
|
||||||
if db.Error() != nil {
|
|
||||||
log.Errorln(fmt.Sprintf("Failed to update message %v #%v: %v", m.Title, m.Id, db.Error()))
|
|
||||||
return nil, db.Error()
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,11 +21,12 @@ import (
|
||||||
"github.com/hunterlong/statping/database"
|
"github.com/hunterlong/statping/database"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -271,7 +272,7 @@ func insertSampleCheckins() error {
|
||||||
|
|
||||||
// InsertSampleHits will create a couple new hits for the sample services
|
// InsertSampleHits will create a couple new hits for the sample services
|
||||||
func InsertSampleHits() error {
|
func InsertSampleHits() error {
|
||||||
tx := Database(&Hit{}).Begin()
|
tx := database.Begin(&types.Hit{})
|
||||||
sg := new(sync.WaitGroup)
|
sg := new(sync.WaitGroup)
|
||||||
for i := int64(1); i <= 5; i++ {
|
for i := int64(1); i <= 5; i++ {
|
||||||
sg.Add(1)
|
sg.Add(1)
|
||||||
|
@ -280,7 +281,7 @@ func InsertSampleHits() error {
|
||||||
log.Infoln(fmt.Sprintf("Adding %v sample hit records to service %v", SampleHits, service.Name))
|
log.Infoln(fmt.Sprintf("Adding %v sample hit records to service %v", SampleHits, service.Name))
|
||||||
createdAt := sampleStart
|
createdAt := sampleStart
|
||||||
p := utils.NewPerlin(2., 2., 10, seed)
|
p := utils.NewPerlin(2., 2., 10, seed)
|
||||||
go func() {
|
go func(sg *sync.WaitGroup) {
|
||||||
defer sg.Done()
|
defer sg.Done()
|
||||||
for hi := 0.; hi <= float64(SampleHits); hi++ {
|
for hi := 0.; hi <= float64(SampleHits); hi++ {
|
||||||
latency := p.Noise1D(hi / 500)
|
latency := p.Noise1D(hi / 500)
|
||||||
|
@ -292,7 +293,7 @@ func InsertSampleHits() error {
|
||||||
}
|
}
|
||||||
tx = tx.Create(&hit)
|
tx = tx.Create(&hit)
|
||||||
}
|
}
|
||||||
}()
|
}(sg)
|
||||||
}
|
}
|
||||||
sg.Wait()
|
sg.Wait()
|
||||||
if err := tx.Commit().Error(); err != nil {
|
if err := tx.Commit().Error(); err != nil {
|
||||||
|
@ -626,14 +627,14 @@ func TmpRecords(dbFile string) error {
|
||||||
CoreApp = NewCore()
|
CoreApp = NewCore()
|
||||||
CoreApp.Name = "Tester"
|
CoreApp.Name = "Tester"
|
||||||
CoreApp.Setup = true
|
CoreApp.Setup = true
|
||||||
configs := &DbConfig{&types.DbConfig{
|
configs := &types.DbConfig{
|
||||||
DbConn: "sqlite",
|
DbConn: "sqlite",
|
||||||
Project: "Tester",
|
Project: "Tester",
|
||||||
Location: utils.Directory,
|
Location: utils.Directory,
|
||||||
SqlFile: sqlFile,
|
SqlFile: sqlFile,
|
||||||
}}
|
}
|
||||||
log.Infoln("saving config.yml in: " + utils.Directory)
|
log.Infoln("saving config.yml in: " + utils.Directory)
|
||||||
if err := configs.Save(); err != nil {
|
if err := SaveConfig(configs); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
log.Infoln("loading config.yml from: " + utils.Directory)
|
log.Infoln("loading config.yml from: " + utils.Directory)
|
||||||
|
@ -653,7 +654,7 @@ func TmpRecords(dbFile string) error {
|
||||||
}
|
}
|
||||||
log.Infoln("loading config.yml from: " + utils.Directory)
|
log.Infoln("loading config.yml from: " + utils.Directory)
|
||||||
|
|
||||||
if err := CoreApp.Connect(false, utils.Directory); err != nil {
|
if err := CoreApp.Connect(configs, false, utils.Directory); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
log.Infoln("selecting the Core variable")
|
log.Infoln("selecting the Core variable")
|
||||||
|
@ -684,7 +685,7 @@ func TmpRecords(dbFile string) error {
|
||||||
|
|
||||||
log.Infoln(tmpSqlFile + " not found, creating a new database...")
|
log.Infoln(tmpSqlFile + " not found, creating a new database...")
|
||||||
|
|
||||||
if err := CoreApp.Connect(false, utils.Directory); err != nil {
|
if err := CoreApp.Connect(configs, false, utils.Directory); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infoln("creating database")
|
log.Infoln("creating database")
|
||||||
|
|
|
@ -58,9 +58,9 @@ func TestSelectCheckin(t *testing.T) {
|
||||||
func TestUpdateCheckin(t *testing.T) {
|
func TestUpdateCheckin(t *testing.T) {
|
||||||
testCheckin.Interval = 60
|
testCheckin.Interval = 60
|
||||||
testCheckin.GracePeriod = 15
|
testCheckin.GracePeriod = 15
|
||||||
id, err := testCheckin.Update()
|
err := database.Update(testCheckin)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotZero(t, id)
|
assert.NotZero(t, testCheckin.Id)
|
||||||
assert.NotEmpty(t, testCheckin.ApiKey)
|
assert.NotEmpty(t, testCheckin.ApiKey)
|
||||||
service := SelectService(1)
|
service := SelectService(1)
|
||||||
checkin := service.Checkins()[0]
|
checkin := service.Checkins()[0]
|
||||||
|
@ -82,8 +82,9 @@ func TestCreateCheckinHits(t *testing.T) {
|
||||||
}
|
}
|
||||||
_, err := database.Create(hit)
|
_, err := database.Create(hit)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
hits := testCheckin.AllHits()
|
|
||||||
assert.Equal(t, 1, len(hits))
|
checks := service.Checkins()
|
||||||
|
assert.Equal(t, 1, len(checks))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectCheckinMethods(t *testing.T) {
|
func TestSelectCheckinMethods(t *testing.T) {
|
||||||
|
|
|
@ -33,13 +33,6 @@ func uwrap(u *database.UserObj) *User {
|
||||||
return &User{u}
|
return &User{u}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountUsers returns the amount of users
|
|
||||||
func CountUsers() int64 {
|
|
||||||
var amount int64
|
|
||||||
Database(&User{}).Count(&amount)
|
|
||||||
return amount
|
|
||||||
}
|
|
||||||
|
|
||||||
// SelectUser returns the User based on the User's ID.
|
// SelectUser returns the User based on the User's ID.
|
||||||
func SelectUser(id int64) (*User, error) {
|
func SelectUser(id int64) (*User, error) {
|
||||||
user, err := database.User(id)
|
user, err := database.User(id)
|
||||||
|
|
|
@ -112,6 +112,6 @@ func TestDeleteUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDbConfig_Close(t *testing.T) {
|
func TestDbConfig_Close(t *testing.T) {
|
||||||
err := DbSession.Close()
|
err := database.Close()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@ package database
|
||||||
import (
|
import (
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CrudObject interface {
|
type CrudObject interface {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -117,6 +118,7 @@ type Database interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Objects interface {
|
type Objects interface {
|
||||||
|
Core() Database
|
||||||
Services() Database
|
Services() Database
|
||||||
Users() Database
|
Users() Database
|
||||||
Groups() Database
|
Groups() Database
|
||||||
|
@ -130,6 +132,51 @@ type Objects interface {
|
||||||
Integrations() Database
|
Integrations() Database
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Close() error {
|
||||||
|
if database == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return database.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogMode(b bool) Database {
|
||||||
|
return database.LogMode(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Begin(model interface{}) Database {
|
||||||
|
if all, ok := model.(string); ok {
|
||||||
|
if all == "migration" {
|
||||||
|
return database.Begin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return database.Model(model).Begin()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Core() Database {
|
||||||
|
return database.Core()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get() Database {
|
||||||
|
if Available() {
|
||||||
|
return database
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Available() bool {
|
||||||
|
if database == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if err := database.DB().Ping(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Db) Core() Database {
|
||||||
|
return d.Table("core").Model(&types.Service{})
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Db) Services() Database {
|
func (d *Db) Services() Database {
|
||||||
return d.Model(&types.Service{})
|
return d.Model(&types.Service{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ import (
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -39,6 +43,8 @@ func StartMaintenceRoutine() {
|
||||||
func databaseMaintence(dur time.Duration) {
|
func databaseMaintence(dur time.Duration) {
|
||||||
deleteAfter := time.Now().UTC().Add(dur)
|
deleteAfter := time.Now().UTC().Add(dur)
|
||||||
|
|
||||||
|
time.Sleep(20 * types.Second)
|
||||||
|
|
||||||
for range time.Tick(maintenceDuration) {
|
for range time.Tick(maintenceDuration) {
|
||||||
log.Infof("Deleting failures older than %s", dur.String())
|
log.Infof("Deleting failures older than %s", dur.String())
|
||||||
DeleteAllSince("failures", deleteAfter)
|
DeleteAllSince("failures", deleteAfter)
|
||||||
|
|
|
@ -6,13 +6,13 @@ services:
|
||||||
container_name: postgres
|
container_name: postgres
|
||||||
image: postgres
|
image: postgres
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/databases/postgres:/var/lib/postgresql/data
|
- ../docker/databases/postgres:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: password123
|
POSTGRES_PASSWORD: password123
|
||||||
POSTGRES_DB: statping
|
POSTGRES_DB: statping
|
||||||
POSTGRES_USER: root
|
POSTGRES_USER: root
|
||||||
networks:
|
ports:
|
||||||
- statping
|
- 5432:5432
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U root"]
|
test: ["CMD-SHELL", "pg_isready -U root"]
|
||||||
interval: 15s
|
interval: 15s
|
||||||
|
@ -23,15 +23,15 @@ services:
|
||||||
container_name: mysql
|
container_name: mysql
|
||||||
image: mysql:5.7
|
image: mysql:5.7
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/databases/mysql:/var/lib/mysql
|
- ../docker/databases/mysql:/var/lib/mysql
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: password123
|
MYSQL_ROOT_PASSWORD: password123
|
||||||
MYSQL_DATABASE: statping
|
MYSQL_DATABASE: statping
|
||||||
MYSQL_USER: root
|
MYSQL_USER: root
|
||||||
MYSQL_PASSWORD: password
|
MYSQL_PASSWORD: password
|
||||||
networks:
|
ports:
|
||||||
- statping
|
- 3306:3306
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
|
@ -55,27 +55,18 @@ services:
|
||||||
PMA_USER: root
|
PMA_USER: root
|
||||||
PMA_PASSWORD: password123
|
PMA_PASSWORD: password123
|
||||||
PMA_PORT: 3306
|
PMA_PORT: 3306
|
||||||
networks:
|
|
||||||
- statping
|
|
||||||
|
|
||||||
sqlite-web:
|
sqlite-web:
|
||||||
container_name: sqlite-web
|
container_name: sqlite-web
|
||||||
image: coleifer/sqlite-web
|
image: coleifer/sqlite-web
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
command: sqlite_web -H 0.0.0.0 -r -x /data/statping.db
|
command: sqlite_web -H 0.0.0.0 -r -x /data/statping.db
|
||||||
depends_on:
|
|
||||||
statping:
|
|
||||||
condition: service_healthy
|
|
||||||
ports:
|
ports:
|
||||||
- 6050:8080
|
- 6050:8080
|
||||||
links:
|
|
||||||
- statping
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/statping/sqlite/statping.db:/data/statping.db:ro
|
- ../docker/statping/sqlite/statping.db:/data/statping.db:ro
|
||||||
environment:
|
environment:
|
||||||
SQLITE_DATABASE: /data/statping.db
|
SQLITE_DATABASE: /data/statping.db
|
||||||
networks:
|
|
||||||
- statping
|
|
||||||
|
|
||||||
pgadmin4:
|
pgadmin4:
|
||||||
container_name: pgadmin4
|
container_name: pgadmin4
|
||||||
|
@ -91,25 +82,16 @@ services:
|
||||||
- 7000:5050
|
- 7000:5050
|
||||||
links:
|
links:
|
||||||
- postgres:postgres
|
- postgres:postgres
|
||||||
networks:
|
|
||||||
- statping
|
|
||||||
|
|
||||||
prometheus:
|
prometheus:
|
||||||
container_name: prometheus
|
container_name: prometheus
|
||||||
image: prom/prometheus:v2.0.0
|
image: prom/prometheus:v2.0.0
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- ./dev/prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- ./docker/databases/prometheus:/prometheus
|
- ../docker/databases/prometheus:/prometheus
|
||||||
links:
|
|
||||||
- statping
|
|
||||||
- statping_mysql
|
|
||||||
- statping_postgres
|
|
||||||
- statping_dev
|
|
||||||
ports:
|
ports:
|
||||||
- 7050:9090
|
- 7050:9090
|
||||||
networks:
|
|
||||||
- statping
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: "/bin/wget -q -Y off http://localhost:9090/status -O /dev/null > /dev/null 2>&1"
|
test: "/bin/wget -q -Y off http://localhost:9090/status -O /dev/null > /dev/null 2>&1"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
|
|
|
@ -52,7 +52,7 @@ func apiRenewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var err error
|
var err error
|
||||||
core.CoreApp.ApiKey = utils.NewSHA1Hash(40)
|
core.CoreApp.ApiKey = utils.NewSHA1Hash(40)
|
||||||
core.CoreApp.ApiSecret = utils.NewSHA1Hash(40)
|
core.CoreApp.ApiSecret = utils.NewSHA1Hash(40)
|
||||||
core.CoreApp, err = core.UpdateCore(core.CoreApp)
|
err = database.Update(core.CoreApp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -91,7 +91,7 @@ func apiCoreHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
app.Timezone = c.Timezone
|
app.Timezone = c.Timezone
|
||||||
}
|
}
|
||||||
app.UseCdn = types.NewNullBool(c.UseCdn.Bool)
|
app.UseCdn = types.NewNullBool(c.UseCdn.Bool)
|
||||||
core.CoreApp, err = core.UpdateCore(app)
|
err = database.Update(app)
|
||||||
returnJson(core.CoreApp, w, r)
|
returnJson(core.CoreApp, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ func TestResetDatabase(t *testing.T) {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.NotNil(t, core.CoreApp)
|
require.NotNil(t, core.CoreApp)
|
||||||
require.NotNil(t, core.CoreApp.Config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFailedHTTPServer(t *testing.T) {
|
func TestFailedHTTPServer(t *testing.T) {
|
||||||
|
|
|
@ -24,17 +24,17 @@ func apiCreateIncidentHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newIncident := core.ReturnIncident(incident)
|
newIncident := core.ReturnIncident(incident)
|
||||||
_, err = newIncident.Create()
|
obj, err := database.Create(newIncident)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sendJsonAction(newIncident, "create", w, r)
|
sendJsonAction(obj, "create", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
incident, err := core.SelectIncident(utils.ToInt(vars["id"]))
|
incident, err := database.Incident(utils.ToInt(vars["id"]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -47,7 +47,7 @@ func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = incident.Update()
|
err = database.Update(&incident)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -57,12 +57,12 @@ func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiDeleteIncidentHandler(w http.ResponseWriter, r *http.Request) {
|
func apiDeleteIncidentHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
incident, err := core.SelectIncident(utils.ToInt(vars["id"]))
|
incident, err := database.Incident(utils.ToInt(vars["id"]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = incident.Delete()
|
err = database.Delete(incident)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
|
|
@ -32,7 +32,7 @@ func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
health := map[string]interface{}{
|
health := map[string]interface{}{
|
||||||
"services": len(core.Services()),
|
"services": len(core.Services()),
|
||||||
"online": true,
|
"online": true,
|
||||||
"setup": core.CoreApp.Config != nil,
|
"setup": core.IsSetup(),
|
||||||
}
|
}
|
||||||
returnJson(health, w, r)
|
returnJson(health, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,27 +19,15 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/hunterlong/statping/core"
|
"github.com/hunterlong/statping/database"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func apiAllMessagesHandler(r *http.Request) interface{} {
|
func apiAllMessagesHandler(r *http.Request) interface{} {
|
||||||
messages, err := core.SelectMessages()
|
messages := database.AllMessages()
|
||||||
if err != nil {
|
return messages
|
||||||
log.Error(err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return joinMessages(messages)
|
|
||||||
}
|
|
||||||
|
|
||||||
func joinMessages(messages []*core.Message) []*types.Message {
|
|
||||||
var m []*types.Message
|
|
||||||
for _, v := range messages {
|
|
||||||
m = append(m, v.Message)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -50,18 +38,17 @@ func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := core.ReturnMessage(message)
|
_, err = database.Create(message)
|
||||||
_, err = msg.Create()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sendJsonAction(msg, "create", w, r)
|
sendJsonAction(message, "create", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiMessageGetHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
|
message, err := database.Message(utils.ToInt(vars["id"]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -71,12 +58,12 @@ func apiMessageGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
|
message, err := database.Message(utils.ToInt(vars["id"]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = message.Delete()
|
err = database.Delete(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -86,7 +73,7 @@ func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
|
message, err := database.Message(utils.ToInt(vars["id"]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("message #%v was not found", vars["id"]), w, r)
|
sendErrorJson(fmt.Errorf("message #%v was not found", vars["id"]), w, r)
|
||||||
return
|
return
|
||||||
|
@ -97,7 +84,7 @@ func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = message.Update()
|
err = database.Update(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
|
|
@ -135,7 +135,7 @@ func cached(duration, contentType string, handler func(w http.ResponseWriter, r
|
||||||
content := CacheStorage.Get(r.RequestURI)
|
content := CacheStorage.Get(r.RequestURI)
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
if core.CoreApp.Config == nil {
|
if !core.IsSetup() {
|
||||||
handler(w, r)
|
handler(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
sample, _ := strconv.ParseBool(r.PostForm.Get("sample_data"))
|
sample, _ := strconv.ParseBool(r.PostForm.Get("sample_data"))
|
||||||
dir := utils.Directory
|
dir := utils.Directory
|
||||||
|
|
||||||
config := &core.DbConfig{DbConfig: &types.DbConfig{
|
configs := &types.DbConfig{
|
||||||
DbConn: dbConn,
|
DbConn: dbConn,
|
||||||
DbHost: dbHost,
|
DbHost: dbHost,
|
||||||
DbUser: dbUser,
|
DbUser: dbUser,
|
||||||
|
@ -67,11 +67,11 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Email: email,
|
Email: email,
|
||||||
Error: nil,
|
Error: nil,
|
||||||
Location: utils.Directory,
|
Location: utils.Directory,
|
||||||
}}
|
}
|
||||||
|
|
||||||
log.WithFields(utils.ToFields(core.CoreApp, config)).Debugln("new configs posted")
|
log.WithFields(utils.ToFields(core.CoreApp, configs)).Debugln("new configs posted")
|
||||||
|
|
||||||
if err := config.Save(); err != nil {
|
if err := core.SaveConfig(configs); err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -83,7 +83,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = core.CoreApp.Connect(false, dir); err != nil {
|
if err = core.CoreApp.Connect(configs, false, dir); err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
core.DeleteConfig()
|
core.DeleteConfig()
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
|
@ -100,7 +100,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
core.CoreApp, err = config.InsertCore()
|
core.CoreApp, err = core.InsertCore(configs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
|
@ -108,9 +108,9 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
admin := &types.User{
|
admin := &types.User{
|
||||||
Username: config.Username,
|
Username: configs.Username,
|
||||||
Password: config.Password,
|
Password: configs.Password,
|
||||||
Email: config.Email,
|
Email: configs.Email,
|
||||||
Admin: types.NewNullBool(true),
|
Admin: types.NewNullBool(true),
|
||||||
}
|
}
|
||||||
database.Create(admin)
|
database.Create(admin)
|
||||||
|
@ -129,8 +129,8 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
Config *types.DbConfig `json:"config"`
|
Config *types.DbConfig `json:"config"`
|
||||||
}{
|
}{
|
||||||
"okokok",
|
"success",
|
||||||
config.DbConfig,
|
configs,
|
||||||
}
|
}
|
||||||
returnJson(out, w, r)
|
returnJson(out, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,8 @@ func apiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
users := core.CountUsers()
|
users := database.AllUsers()
|
||||||
if users == 1 {
|
if len(users) == 1 {
|
||||||
sendErrorJson(errors.New("cannot delete the last user"), w, r)
|
sendErrorJson(errors.New("cannot delete the last user"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ func TestSaveAndCompileAsset(t *testing.T) {
|
||||||
themeCSS, err := utils.OpenFile(dir + "/assets/css/theme.css")
|
themeCSS, err := utils.OpenFile(dir + "/assets/css/theme.css")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, scssData, themeCSS)
|
assert.Contains(t, themeCSS, `color: #333;`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOpenAsset(t *testing.T) {
|
func TestOpenAsset(t *testing.T) {
|
||||||
|
@ -88,12 +88,7 @@ func TestOpenAsset(t *testing.T) {
|
||||||
|
|
||||||
func TestDeleteAssets(t *testing.T) {
|
func TestDeleteAssets(t *testing.T) {
|
||||||
assert.True(t, UsingAssets(dir))
|
assert.True(t, UsingAssets(dir))
|
||||||
//assert.Nil(t, DeleteAllAssets(dir))
|
assert.Nil(t, DeleteAllAssets(dir))
|
||||||
assert.False(t, UsingAssets(dir))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyToPluginFailed(t *testing.T) {
|
|
||||||
//assert.Nil(t, DeleteAllAssets(dir))
|
|
||||||
assert.False(t, UsingAssets(dir))
|
assert.False(t, UsingAssets(dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ type Core struct {
|
||||||
Started time.Time `gorm:"-" json:"started_on"`
|
Started time.Time `gorm:"-" json:"started_on"`
|
||||||
Plugins []*Info `gorm:"-" json:"-"`
|
Plugins []*Info `gorm:"-" json:"-"`
|
||||||
Notifications []AllNotifiers `gorm:"-" json:"-"`
|
Notifications []AllNotifiers `gorm:"-" json:"-"`
|
||||||
Config *DbConfig `gorm:"-" json:"-"`
|
|
||||||
Integrations []Integrator `gorm:"-" json:"-"`
|
Integrations []Integrator `gorm:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue