mirror of https://github.com/statping/statping
gorm DB - issue fixes - DB seeds - benchmark tests
parent
e4ccdba34d
commit
1eb55a0c71
|
@ -12,6 +12,14 @@
|
|||
pruneopts = "UT"
|
||||
revision = "c02ca9a983da5807ddf7d796784928f5be4afd09"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e92f5581902c345eb4ceffdcd4a854fb8f73cf436d47d837d1ec98ef1fe0a214"
|
||||
name = "github.com/StackExchange/wmi"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5d049714c4a64225c3c79a7cf7d02f7fb5b96338"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4b79025e1eaa5726b92e409a46571f1998b56f0a2d881d6271ca616095eae46e"
|
||||
|
@ -44,6 +52,17 @@
|
|||
pruneopts = "UT"
|
||||
revision = "ebf56d35bba727c68ac77f56f2fcf90b181851aa"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:64a5a67c69b70c2420e607a8545d674a23778ed9c3e80607bfd17b77c6c87f6a"
|
||||
name = "github.com/go-ole/go-ole"
|
||||
packages = [
|
||||
".",
|
||||
"oleutil",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:70a20b8adf085489a342d033b68b7fc27f4017c51e015b857387249493ee0561"
|
||||
|
@ -68,6 +87,14 @@
|
|||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:664d37ea261f0fc73dd17f4a1f5f46d01fbb0b0d75f6375af064824424109b7d"
|
||||
name = "github.com/gorilla/handlers"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "7e0847f9db758cdebd26c149d0ae9d5d0b9c98ce"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:195b71563f8432dac9d9692aca2a9ae098bc35763999573eb1c7d52a02a47ce7"
|
||||
name = "github.com/gorilla/mux"
|
||||
|
@ -91,6 +118,14 @@
|
|||
revision = "03b6f63cc43ef9c7240a635a5e22b13180e822b8"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d"
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d166a4b3543a71d87e34767ace94e8b516e79ba45111730306f07c8d6f797f1f"
|
||||
|
@ -126,6 +161,17 @@
|
|||
pruneopts = "UT"
|
||||
revision = "b3511bfdd742af558b54eb6160aca9446d762a19"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4f4fd75cbdd5ad0696f4d762328f094b9c86061323c9a9f8d0de157f06197e89"
|
||||
name = "github.com/mkevac/debugcharts"
|
||||
packages = [
|
||||
".",
|
||||
"bindata",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "d3203a8fa92649b82dc35c214979861de918874a"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3891cc78541df6e4596b3e73978eb062d32967084069270ec881b959be5155ae"
|
||||
|
@ -150,6 +196,29 @@
|
|||
pruneopts = "UT"
|
||||
revision = "6283090d169f51a2410b4e260341a01c9a4c0ca7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7395b855a6078ad2e6c40311402a057a91125fb9f32cf228e1b32cdc57c33538"
|
||||
name = "github.com/shirou/gopsutil"
|
||||
packages = [
|
||||
"cpu",
|
||||
"host",
|
||||
"internal/common",
|
||||
"mem",
|
||||
"net",
|
||||
"process",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "8048a2e9c5773235122027dd585cf821b2af1249"
|
||||
version = "v2.18.07"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:99c6a6dab47067c9b898e8c8b13d130c6ab4ffbcc4b7cc6236c2cd0b1e344f5b"
|
||||
name = "github.com/shirou/w32"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "bb4de0191aa41b5507caa14b0650cdbddcd9280b"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83"
|
||||
name = "github.com/stretchr/testify"
|
||||
|
@ -168,6 +237,17 @@
|
|||
pruneopts = "UT"
|
||||
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:629034aef6b53eb8ea737e6d82cb5402907e2757fbab5ddf5e74c08b4c6473af"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "fa5fdf94c78965f1aa8423f0cc50b8b8d728b05a"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c25289f43ac4a68d88b02245742347c94f1e108c534dda442188015ff80669b3"
|
||||
name = "google.golang.org/appengine"
|
||||
|
@ -230,9 +310,11 @@
|
|||
"github.com/ararog/timeago",
|
||||
"github.com/fatih/structs",
|
||||
"github.com/go-yaml/yaml",
|
||||
"github.com/gorilla/handlers",
|
||||
"github.com/gorilla/mux",
|
||||
"github.com/gorilla/sessions",
|
||||
"github.com/joho/godotenv",
|
||||
"github.com/mkevac/debugcharts",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/rendon/testcli",
|
||||
"github.com/stretchr/testify/assert",
|
||||
|
|
6
Makefile
6
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.52
|
||||
VERSION=0.53
|
||||
BINARY_NAME=statup
|
||||
GOPATH:=$(GOPATH)
|
||||
GOCMD=go
|
||||
|
@ -26,6 +26,10 @@ docker-build-all: docker-build-base docker-dev docker
|
|||
|
||||
docker-publish-all: docker-push-base docker-push-dev docker-push-latest
|
||||
|
||||
seed:
|
||||
rm -f statup.db
|
||||
cat dev/seed.sql | sqlite3 statup.db
|
||||
|
||||
build: compile
|
||||
$(GOBUILD) $(BUILDVERSION) -o $(BINARY_NAME) -v ./cmd
|
||||
|
||||
|
|
21
cmd/cli.go
21
cmd/cli.go
|
@ -24,13 +24,13 @@ 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"
|
||||
"strings"
|
||||
"time"
|
||||
"upper.io/db.v3/sqlite"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -45,6 +45,8 @@ func CatchCLI(args []string) error {
|
|||
LoadDotEnvs()
|
||||
|
||||
switch args[0] {
|
||||
case "seed":
|
||||
handlers.DesktopInit(ipAddress, port)
|
||||
case "app":
|
||||
handlers.DesktopInit(ipAddress, port)
|
||||
case "version":
|
||||
|
@ -94,7 +96,7 @@ func CatchCLI(args []string) error {
|
|||
case "export":
|
||||
var err error
|
||||
fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(dir)
|
||||
if err != nil {
|
||||
utils.Log(4, "config.yml file not found")
|
||||
return err
|
||||
|
@ -132,11 +134,11 @@ func CatchCLI(args []string) error {
|
|||
|
||||
func RunOnce() {
|
||||
var err error
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(4, "config.yml file not found")
|
||||
}
|
||||
err = core.DbConnection(core.Configs.Connection, false, utils.Directory)
|
||||
err = core.Configs.Connect(false, utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
}
|
||||
|
@ -234,19 +236,16 @@ func FakeSeed(plug types.PluginActions) {
|
|||
fmt.Printf("\n" + BRAKER)
|
||||
|
||||
fmt.Println("\nCreating a SQLite database for testing, will be deleted automatically...")
|
||||
sqlFake := sqlite.ConnectionURL{
|
||||
Database: "./.plugin_test.db",
|
||||
}
|
||||
core.DbSession, err = sqlite.Open(sqlFake)
|
||||
core.DbSession, err = gorm.Open("sqlite", "./.plugin_test.db")
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
up, _ := source.SqlBox.String("sqlite_up.sql")
|
||||
requests := strings.Split(up, ";")
|
||||
for _, request := range requests {
|
||||
_, err := core.DbSession.Exec(request)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
db := core.DbSession.Exec(request)
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
cmd/main.go
20
cmd/main.go
|
@ -55,6 +55,8 @@ func parseFlags() {
|
|||
func main() {
|
||||
var err error
|
||||
parseFlags()
|
||||
LoadDotEnvs()
|
||||
source.Assets()
|
||||
utils.InitLogs()
|
||||
args := flag.Args()
|
||||
|
||||
|
@ -68,13 +70,8 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
source.Assets()
|
||||
LoadDotEnvs()
|
||||
|
||||
utils.Log(1, fmt.Sprintf("Starting Statup v%v", VERSION))
|
||||
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
core.SetupMode = true
|
||||
|
@ -94,15 +91,18 @@ func LoadDotEnvs() error {
|
|||
}
|
||||
|
||||
func mainProcess() {
|
||||
dir := utils.Directory
|
||||
var err error
|
||||
err = core.DbConnection(core.Configs.Connection, false, utils.Directory)
|
||||
core.Configs, err = core.LoadConfig(dir)
|
||||
if err != nil {
|
||||
utils.Log(4, fmt.Sprintf("could not load config.yml %v", err))
|
||||
}
|
||||
err = core.Configs.Connect(false, dir)
|
||||
if err != nil {
|
||||
utils.Log(4, fmt.Sprintf("could not connect to database: %v", err))
|
||||
}
|
||||
|
||||
core.RunDatabaseUpgrades()
|
||||
core.InitApp()
|
||||
|
||||
if !core.SetupMode {
|
||||
LoadPlugins(false)
|
||||
fmt.Println(handlers.RunHTTPServer(ipAddress, port))
|
||||
|
@ -170,7 +170,7 @@ func LoadPlugins(debug bool) {
|
|||
if debug {
|
||||
TestPlugin(plugActions)
|
||||
} else {
|
||||
plugActions.OnLoad(core.DbSession)
|
||||
plugActions.OnLoad(*core.DbSession)
|
||||
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||
}
|
||||
|
|
186
cmd/main_test.go
186
cmd/main_test.go
|
@ -31,27 +31,30 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
route *mux.Router
|
||||
testSession *sessions.Session
|
||||
dir string
|
||||
route *mux.Router
|
||||
testSession *sessions.Session
|
||||
dir string
|
||||
SERVICE_SINCE, _ = time.Parse(time.RFC3339, "2018-08-30T10:42:08-07:00")
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir = utils.Directory
|
||||
os.Remove(dir + "/statup.db")
|
||||
//os.Remove(gopath+"/cmd/config.yml")
|
||||
os.RemoveAll(dir + "/cmd/assets")
|
||||
os.RemoveAll(dir + "/logs")
|
||||
}
|
||||
|
||||
func Clean() {
|
||||
utils.DeleteFile(dir + "/config.yml")
|
||||
utils.DeleteFile(dir + "/statup.db")
|
||||
utils.DeleteDirectory(dir + "/assets")
|
||||
utils.DeleteDirectory(dir + "/logs")
|
||||
}
|
||||
|
||||
func RunInit(t *testing.T) {
|
||||
source.Assets()
|
||||
os.Remove(dir + "/statup.db")
|
||||
os.Remove(dir + "/cmd/config.yml")
|
||||
os.Remove(dir + "/cmd/index.html")
|
||||
Clean()
|
||||
route = handlers.Router()
|
||||
LoadDotEnvs()
|
||||
core.CoreApp = core.NewCore()
|
||||
|
@ -60,35 +63,56 @@ func RunInit(t *testing.T) {
|
|||
func TestRunAll(t *testing.T) {
|
||||
//t.Parallel()
|
||||
|
||||
databases := []string{"sqlite", "postgres", "mysql"}
|
||||
databases := []string{"postgres", "sqlite", "mysql"}
|
||||
if os.Getenv("ONLY_DB") != "" {
|
||||
databases = []string{os.Getenv("ONLY_DB")}
|
||||
}
|
||||
|
||||
for _, dbt := range databases {
|
||||
|
||||
t.Run(dbt+" init", func(t *testing.T) {
|
||||
RunInit(t)
|
||||
})
|
||||
t.Run(dbt+" load database config", func(t *testing.T) {
|
||||
RunMakeDatabaseConfig(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" run database migrations", func(t *testing.T) {
|
||||
RunDatabaseMigrations(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Sample Data", func(t *testing.T) {
|
||||
RunInsertSampleData(t)
|
||||
t.Run(dbt+" Save Config", func(t *testing.T) {
|
||||
RunSaveConfig(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Load Configs", func(t *testing.T) {
|
||||
RunLoadConfig(t)
|
||||
t.Log(core.Configs)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Drop Database", func(t *testing.T) {
|
||||
RunDropDatabase(t)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database Again", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Inserting Database Structure", func(t *testing.T) {
|
||||
RunCreateSchema(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Inserting Seed Data", func(t *testing.T) {
|
||||
RunInsertSampleData(t)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database Again", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Run Database Migrations", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
RunDatabaseMigrations(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Select Core", func(t *testing.T) {
|
||||
RunSelectCoreMYQL(t, dbt)
|
||||
t.Log(core.CoreApp)
|
||||
})
|
||||
t.Run(dbt+" Select Services", func(t *testing.T) {
|
||||
RunSelectAllMysqlServices(t)
|
||||
})
|
||||
t.Run(dbt+" Select Comms", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
RunSelectAllMysqlCommunications(t)
|
||||
})
|
||||
t.Run(dbt+" Create Users", func(t *testing.T) {
|
||||
|
@ -131,7 +155,7 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Create Failing Service", func(t *testing.T) {
|
||||
RunBadService_Create(t)
|
||||
})
|
||||
t.Run(dbt+" Check Service", func(t *testing.T) {
|
||||
t.Run(dbt+" Check Bad Service", func(t *testing.T) {
|
||||
RunBadService_Check(t)
|
||||
})
|
||||
t.Run(dbt+" Select Hits", func(t *testing.T) {
|
||||
|
@ -183,35 +207,24 @@ func TestRunAll(t *testing.T) {
|
|||
RunSettingsHandler(t)
|
||||
})
|
||||
t.Run(dbt+" Cleanup", func(t *testing.T) {
|
||||
//Cleanup(t)
|
||||
core.Configs.Close()
|
||||
core.DbSession = nil
|
||||
//Clean()
|
||||
})
|
||||
|
||||
//<-done
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Cleanup(t *testing.T) {
|
||||
core.DbSession.ClearCache()
|
||||
err := core.DbSession.Close()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunMakeDatabaseConfig(t *testing.T, db string) {
|
||||
func RunSaveConfig(t *testing.T, db string) {
|
||||
var err error
|
||||
port := 5432
|
||||
if db == "mysql" {
|
||||
port = 3306
|
||||
}
|
||||
|
||||
//Project string `yaml:"-"`
|
||||
//Description string `yaml:"-"`
|
||||
//Domain string `yaml:"-"`
|
||||
//Username string `yaml:"-"`
|
||||
//Password string `yaml:"-"`
|
||||
//Email string `yaml:"-"`
|
||||
//Error error `yaml:"-"`
|
||||
//Location string `yaml:"location"`
|
||||
|
||||
config := &core.DbConfig{&types.DbConfig{
|
||||
core.Configs = &core.DbConfig{DbConfig: &types.DbConfig{
|
||||
DbConn: db,
|
||||
DbHost: os.Getenv("DB_HOST"),
|
||||
DbUser: os.Getenv("DB_USER"),
|
||||
|
@ -227,14 +240,19 @@ func RunMakeDatabaseConfig(t *testing.T, db string) {
|
|||
Error: nil,
|
||||
Location: dir,
|
||||
}}
|
||||
err := config.Save()
|
||||
core.Configs, err = core.Configs.Save()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
_, err = core.LoadConfig()
|
||||
func RunCreateSchema(t *testing.T, db string) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, db, core.Configs.Connection)
|
||||
err = core.Configs.CreateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
err = core.DbConnection(core.Configs.Connection, false, dir)
|
||||
func RunConnectDatabase(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
|
@ -244,22 +262,32 @@ func RunDatabaseMigrations(t *testing.T, db string) {
|
|||
}
|
||||
|
||||
func RunInsertSampleData(t *testing.T) {
|
||||
err := core.LoadSampleData()
|
||||
_, _, err := core.Configs.SeedDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunLoadConfig(t *testing.T) {
|
||||
var err error
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(dir)
|
||||
t.Log(core.Configs)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, core.Configs)
|
||||
}
|
||||
|
||||
func RunDropDatabase(t *testing.T) {
|
||||
err := core.Configs.DropDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunSelectCoreMYQL(t *testing.T, db string) {
|
||||
var err error
|
||||
core.CoreApp, err = core.SelectCore()
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Testing "+db, core.CoreApp.Name)
|
||||
t.Log("core: ", core.CoreApp.Core)
|
||||
assert.Equal(t, "Awesome Status", core.CoreApp.Name)
|
||||
assert.Equal(t, db, core.CoreApp.DbConnection)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiKey)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiSecret)
|
||||
|
@ -270,12 +298,12 @@ func RunSelectAllMysqlServices(t *testing.T) {
|
|||
var err error
|
||||
services, err := core.CoreApp.SelectAllServices()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(services))
|
||||
assert.Equal(t, 18, len(services))
|
||||
}
|
||||
|
||||
func RunSelectAllMysqlCommunications(t *testing.T) {
|
||||
var err error
|
||||
notifiers.Collections = core.DbSession.Collection("communication")
|
||||
notifiers.Collections = core.DbSession.Table("communication").Model(¬ifiers.Notification{})
|
||||
comms := notifiers.Load()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(comms))
|
||||
|
@ -284,19 +312,19 @@ func RunSelectAllMysqlCommunications(t *testing.T) {
|
|||
func RunUser_SelectAll(t *testing.T) {
|
||||
users, err := core.SelectAllUsers()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(users))
|
||||
assert.Equal(t, 3, len(users))
|
||||
}
|
||||
|
||||
func RunUser_Create(t *testing.T) {
|
||||
user := core.ReturnUser(&types.User{
|
||||
Username: "admin",
|
||||
Password: "admin",
|
||||
Email: "info@testuser.com",
|
||||
Username: "hunterlong",
|
||||
Password: "password123",
|
||||
Email: "info@gmail.com",
|
||||
Admin: true,
|
||||
})
|
||||
id, err := user.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(1), id)
|
||||
assert.Equal(t, int64(2), id)
|
||||
user2 := core.ReturnUser(&types.User{
|
||||
Username: "superadmin",
|
||||
Password: "admin",
|
||||
|
@ -305,7 +333,7 @@ func RunUser_Create(t *testing.T) {
|
|||
})
|
||||
id, err = user2.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(2), id)
|
||||
assert.Equal(t, int64(3), id)
|
||||
}
|
||||
|
||||
func RunUser_Update(t *testing.T) {
|
||||
|
@ -342,7 +370,10 @@ func RunSelectAllServices(t *testing.T) {
|
|||
var err error
|
||||
services, err := core.CoreApp.SelectAllServices()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(services))
|
||||
assert.Equal(t, 18, len(services))
|
||||
for _, s := range services {
|
||||
assert.NotEmpty(t, s.CreatedAt)
|
||||
}
|
||||
}
|
||||
|
||||
func RunOneService_Check(t *testing.T) {
|
||||
|
@ -365,8 +396,7 @@ func RunService_Create(t *testing.T) {
|
|||
})
|
||||
id, err := service.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(6), id)
|
||||
t.Log(service)
|
||||
assert.Equal(t, int64(19), id)
|
||||
}
|
||||
|
||||
func RunService_ToJSON(t *testing.T) {
|
||||
|
@ -379,15 +409,20 @@ func RunService_ToJSON(t *testing.T) {
|
|||
func RunService_AvgTime(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
avg := service.AvgUptime()
|
||||
avg := service.AvgUptime24()
|
||||
assert.Equal(t, "100", avg)
|
||||
}
|
||||
|
||||
func RunService_Online24(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
online := service.Online24()
|
||||
assert.Equal(t, float32(100), online)
|
||||
online := service.OnlineSince(SERVICE_SINCE)
|
||||
assert.Equal(t, float32(80), online)
|
||||
|
||||
service = core.SelectService(18)
|
||||
assert.NotNil(t, service)
|
||||
online = service.OnlineSince(SERVICE_SINCE)
|
||||
assert.Equal(t, float32(0), online)
|
||||
}
|
||||
|
||||
func RunService_GraphData(t *testing.T) {
|
||||
|
@ -413,13 +448,13 @@ func RunBadService_Create(t *testing.T) {
|
|||
})
|
||||
id, err := service.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(7), id)
|
||||
assert.Equal(t, int64(20), id)
|
||||
}
|
||||
|
||||
func RunBadService_Check(t *testing.T) {
|
||||
service := core.SelectService(7)
|
||||
service := core.SelectService(18)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Bad Service", service.Name)
|
||||
assert.Equal(t, "Failing URL", service.Name)
|
||||
for i := 0; i <= 10; i++ {
|
||||
service.Check(true)
|
||||
}
|
||||
|
@ -431,9 +466,7 @@ func RunDeleteService(t *testing.T) {
|
|||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "JSON API Tester", service.Name)
|
||||
assert.True(t, service.IsRunning())
|
||||
t.Log(service.Running)
|
||||
err := service.Delete()
|
||||
t.Log(service.Running)
|
||||
assert.False(t, service.IsRunning())
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
@ -441,13 +474,10 @@ func RunDeleteService(t *testing.T) {
|
|||
func RunCreateService_Hits(t *testing.T) {
|
||||
services := core.CoreApp.Services()
|
||||
assert.NotNil(t, services)
|
||||
assert.Equal(t, 6, len(services))
|
||||
for i := 0; i <= 15; i++ {
|
||||
for _, s := range services {
|
||||
var service *core.Service
|
||||
service = s.Check(true)
|
||||
assert.NotNil(t, service)
|
||||
}
|
||||
assert.Equal(t, 19, len(services))
|
||||
for _, s := range services {
|
||||
service := s.Check(true)
|
||||
assert.NotNil(t, service)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,9 +490,9 @@ func RunService_Hits(t *testing.T) {
|
|||
}
|
||||
|
||||
func RunService_Failures(t *testing.T) {
|
||||
service := core.SelectService(7)
|
||||
service := core.SelectService(18)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Bad Service", service.Name)
|
||||
assert.Equal(t, "Failing URL", service.Name)
|
||||
assert.NotEmpty(t, service.Failures)
|
||||
}
|
||||
|
||||
|
@ -479,7 +509,7 @@ func RunIndexHandler(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "This is a test of Statup.io!"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "Awesome"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
}
|
||||
|
||||
|
@ -499,7 +529,7 @@ func RunPrometheusHandler(t *testing.T) {
|
|||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
t.Log(rr.Body.String())
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "statup_total_services 6"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "statup_total_services 19"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
|
@ -515,7 +545,7 @@ func RunFailingPrometheusHandler(t *testing.T) {
|
|||
func RunLoginHandler(t *testing.T) {
|
||||
form := url.Values{}
|
||||
form.Add("username", "admin")
|
||||
form.Add("password", "admin")
|
||||
form.Add("password", "password123")
|
||||
req, err := http.NewRequest("POST", "/dashboard", strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -210,7 +210,9 @@ func RecordSuccess(s *Service) {
|
|||
s.Online = true
|
||||
s.LastOnline = time.Now()
|
||||
data := &types.Hit{
|
||||
Latency: s.Latency,
|
||||
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)
|
||||
|
|
|
@ -48,26 +48,25 @@ func FindCheckin(api string) *types.Checkin {
|
|||
|
||||
func (s *Service) AllCheckins() []*types.Checkin {
|
||||
var checkins []*types.Checkin
|
||||
col := DbSession.Collection("checkins").Find("service", s.Id).OrderBy("-id")
|
||||
col.All(&checkins)
|
||||
col := checkinDB().Where("service = ?", s.Id).Order("-id")
|
||||
col.Scan(&checkins)
|
||||
s.Checkins = checkins
|
||||
return checkins
|
||||
}
|
||||
|
||||
func (u *Checkin) Create() (int64, error) {
|
||||
u.CreatedAt = time.Now()
|
||||
uuid, err := DbSession.Collection("checkins").Insert(u)
|
||||
if uuid == nil {
|
||||
utils.Log(2, err)
|
||||
return 0, err
|
||||
row := checkinDB().Create(&u)
|
||||
if row.Error == nil {
|
||||
utils.Log(2, row.Error)
|
||||
return 0, row.Error
|
||||
}
|
||||
fmt.Println("new checkin: ", uuid)
|
||||
return uuid.(int64), err
|
||||
return u.Id, row.Error
|
||||
}
|
||||
|
||||
func SelectCheckinApi(api string) *Checkin {
|
||||
var checkin *Checkin
|
||||
DbSession.Collection("checkins").Find("api", api).One(&checkin)
|
||||
checkinDB().Where("api = ?", api).Find(&checkin)
|
||||
return checkin
|
||||
}
|
||||
|
||||
|
|
|
@ -23,29 +23,28 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func LoadConfig() (*types.Config, error) {
|
||||
func LoadConfig(directory string) (*DbConfig, error) {
|
||||
var configs *types.DbConfig
|
||||
if os.Getenv("DB_CONN") != "" {
|
||||
utils.Log(1, "DB_CONN environment variable was found, waiting for database...")
|
||||
return LoadUsingEnv()
|
||||
}
|
||||
Configs = new(types.Config)
|
||||
file, err := ioutil.ReadFile(utils.Directory + "/config.yml")
|
||||
file, err := ioutil.ReadFile(directory + "/config.yml")
|
||||
if err != nil {
|
||||
return nil, errors.New("config.yml file not found - starting in setup mode")
|
||||
return nil, errors.New("config.yml file not found at " + directory + "/config.yml - starting in setup mode")
|
||||
}
|
||||
err = yaml.Unmarshal(file, &Configs)
|
||||
err = yaml.Unmarshal(file, &configs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
CoreApp.DbConnection = Configs.Connection
|
||||
Configs = &DbConfig{configs}
|
||||
return Configs, err
|
||||
}
|
||||
|
||||
func LoadUsingEnv() (*types.Config, error) {
|
||||
Configs = new(types.Config)
|
||||
func LoadUsingEnv() (*DbConfig, error) {
|
||||
Configs = new(DbConfig)
|
||||
if os.Getenv("DB_CONN") == "" {
|
||||
return nil, errors.New("Missing DB_CONN environment variable")
|
||||
}
|
||||
|
@ -61,12 +60,12 @@ func LoadUsingEnv() (*types.Config, error) {
|
|||
if os.Getenv("DB_DATABASE") == "" {
|
||||
return nil, errors.New("Missing DB_DATABASE environment variable")
|
||||
}
|
||||
Configs.Connection = os.Getenv("DB_CONN")
|
||||
Configs.Host = os.Getenv("DB_HOST")
|
||||
Configs.Port = os.Getenv("DB_PORT")
|
||||
Configs.User = os.Getenv("DB_USER")
|
||||
Configs.DbConn = os.Getenv("DB_CONN")
|
||||
Configs.DbHost = os.Getenv("DB_HOST")
|
||||
Configs.DbPort = int(utils.StringInt(os.Getenv("DB_PORT")))
|
||||
Configs.DbUser = os.Getenv("DB_USER")
|
||||
Configs.Password = os.Getenv("DB_PASS")
|
||||
Configs.Database = os.Getenv("DB_DATABASE")
|
||||
Configs.DbData = os.Getenv("DB_DATABASE")
|
||||
CoreApp.DbConnection = os.Getenv("DB_CONN")
|
||||
CoreApp.Name = os.Getenv("NAME")
|
||||
CoreApp.Domain = os.Getenv("DOMAIN")
|
||||
|
@ -89,32 +88,19 @@ func LoadUsingEnv() (*types.Config, error) {
|
|||
Email: "info@localhost.com",
|
||||
}}
|
||||
|
||||
err := DbConnection(dbConfig.DbConn, true, utils.Directory)
|
||||
err := dbConfig.Connect(true, utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exists, err := DbSession.Collection("core").Find().Exists()
|
||||
exists := DbSession.HasTable("core")
|
||||
if !exists {
|
||||
|
||||
utils.Log(1, fmt.Sprintf("Core database does not exist, creating now!"))
|
||||
DropDatabase()
|
||||
CreateDatabase()
|
||||
dbConfig.DropDatabase()
|
||||
dbConfig.CreateDatabase()
|
||||
|
||||
CoreApp = &Core{Core: &types.Core{
|
||||
Name: dbConfig.Project,
|
||||
Description: dbConfig.Description,
|
||||
Config: "config.yml",
|
||||
ApiKey: utils.NewSHA1Hash(9),
|
||||
ApiSecret: utils.NewSHA1Hash(16),
|
||||
Domain: dbConfig.Domain,
|
||||
MigrationId: time.Now().Unix(),
|
||||
}}
|
||||
|
||||
CoreApp.DbConnection = dbConfig.DbConn
|
||||
|
||||
err := InsertCore(CoreApp)
|
||||
CoreApp, err = dbConfig.InsertCore()
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
|
|
45
core/core.go
45
core/core.go
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -34,7 +33,7 @@ type Core struct {
|
|||
}
|
||||
|
||||
var (
|
||||
Configs *types.Config
|
||||
Configs *DbConfig
|
||||
CoreApp *Core
|
||||
SetupMode bool
|
||||
VERSION string
|
||||
|
@ -51,12 +50,6 @@ func NewCore() *Core {
|
|||
return CoreApp
|
||||
}
|
||||
|
||||
func InsertCore(c *Core) error {
|
||||
col := DbSession.Collection("core")
|
||||
_, err := col.Insert(c.Core)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Core) ToCore() *types.Core {
|
||||
return c.Core
|
||||
}
|
||||
|
@ -72,19 +65,18 @@ func InitApp() {
|
|||
|
||||
func InsertNotifierDB() error {
|
||||
if DbSession == nil {
|
||||
err := DbConnection(CoreApp.DbConnection, false, utils.Directory)
|
||||
err := Configs.Connect(false, utils.Directory)
|
||||
if err != nil {
|
||||
return errors.New("database connection has not been created")
|
||||
}
|
||||
}
|
||||
notifiers.Collections = DbSession.Collection("communication")
|
||||
notifiers.Collections = commDB()
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateCore(c *Core) (*Core, error) {
|
||||
res := DbSession.Collection("core").Find().Limit(1)
|
||||
err := res.Update(c.Core)
|
||||
return c, err
|
||||
db := coreDB().Update(c)
|
||||
return c, db.Error
|
||||
}
|
||||
|
||||
func (c Core) UsingAssets() bool {
|
||||
|
@ -122,36 +114,33 @@ func (c Core) AllOnline() bool {
|
|||
}
|
||||
|
||||
func SelectLastMigration() (int64, error) {
|
||||
var c *types.Core
|
||||
if DbSession == nil {
|
||||
return 0, errors.New("Database connection has not been created yet")
|
||||
}
|
||||
err := DbSession.Collection("core").Find().One(&c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.MigrationId, err
|
||||
row := coreDB().Take(&CoreApp)
|
||||
return CoreApp.MigrationId, row.Error
|
||||
}
|
||||
|
||||
func SelectCore() (*Core, error) {
|
||||
var c *types.Core
|
||||
exists := DbSession.Collection("core").Exists()
|
||||
if DbSession == nil {
|
||||
return nil, errors.New("database has not been initiated yet.")
|
||||
}
|
||||
exists := DbSession.HasTable("core")
|
||||
if !exists {
|
||||
return nil, errors.New("core database has not been setup yet.")
|
||||
}
|
||||
err := DbSession.Collection("core").Find().One(&c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
db := coreDB().Take(&CoreApp)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
CoreApp.Core = c
|
||||
CoreApp.DbConnection = Configs.Connection
|
||||
CoreApp.DbConnection = Configs.DbConn
|
||||
CoreApp.Version = VERSION
|
||||
CoreApp.SelectAllServices()
|
||||
if os.Getenv("USE_CDN") == "true" {
|
||||
CoreApp.UseCdn = true
|
||||
}
|
||||
//store = sessions.NewCookieStore([]byte(core.ApiSecret))
|
||||
return CoreApp, err
|
||||
return CoreApp, db.Error
|
||||
}
|
||||
|
||||
type ServiceOrder []*types.Service
|
||||
|
@ -163,7 +152,7 @@ func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
|
|||
func (c *Core) Services() []*Service {
|
||||
var services []*Service
|
||||
servs := CoreApp.GetServices()
|
||||
sort.Sort(ServiceOrder(servs))
|
||||
//sort.Sort(ServiceOrder(servs))
|
||||
for _, ser := range servs {
|
||||
services = append(services, ReturnService(ser))
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
testCore *Core
|
||||
testConfig *DbConfig
|
||||
dir string
|
||||
dir string
|
||||
)
|
||||
|
||||
const (
|
||||
SERVICE_SINCE = "2018-08-30T10:42:08-07:00" // "2006-01-02T15:04:05Z07:00"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -36,51 +38,65 @@ func init() {
|
|||
}
|
||||
|
||||
func TestNewCore(t *testing.T) {
|
||||
testCore = NewCore()
|
||||
assert.NotNil(t, testCore)
|
||||
testCore.Name = "Tester"
|
||||
utils.DeleteFile(dir + "/config.yml")
|
||||
utils.DeleteFile(dir + "/statup.db")
|
||||
CoreApp = NewCore()
|
||||
assert.NotNil(t, CoreApp)
|
||||
CoreApp.Name = "Tester"
|
||||
}
|
||||
|
||||
func TestDbConfig_Save(t *testing.T) {
|
||||
testConfig = &DbConfig{&types.DbConfig{
|
||||
var err error
|
||||
Configs = &DbConfig{&types.DbConfig{
|
||||
DbConn: "sqlite",
|
||||
Project: "Tester",
|
||||
Location: dir,
|
||||
}}
|
||||
err := testConfig.Save()
|
||||
Configs, err = Configs.Save()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "sqlite", Configs.DbConn)
|
||||
assert.NotEmpty(t, Configs.ApiKey)
|
||||
assert.NotEmpty(t, Configs.ApiSecret)
|
||||
}
|
||||
|
||||
func TestLoadDbConfig(t *testing.T) {
|
||||
Configs, err := LoadConfig(dir)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "sqlite", Configs.DbConn)
|
||||
}
|
||||
|
||||
func TestDbConnection(t *testing.T) {
|
||||
err := DbConnection(testConfig.DbConn, false, dir)
|
||||
err := Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestCreateDatabase(t *testing.T) {
|
||||
err := CreateDatabase()
|
||||
func TestSeedSchemaDatabase(t *testing.T) {
|
||||
_, _, err := Configs.SeedSchema()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestInsertCore(t *testing.T) {
|
||||
err := InsertCore(testCore)
|
||||
func TestSeedDatabase(t *testing.T) {
|
||||
_, _, err := Configs.SeedDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestReLoadDbConfig(t *testing.T) {
|
||||
err := Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "sqlite", Configs.DbConn)
|
||||
}
|
||||
|
||||
func TestSelectCore(t *testing.T) {
|
||||
core, err := SelectCore()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Tester", core.Name)
|
||||
}
|
||||
|
||||
func TestSampleData(t *testing.T) {
|
||||
err := LoadSampleData()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Awesome Status", core.Name)
|
||||
}
|
||||
|
||||
func TestSelectLastMigration(t *testing.T) {
|
||||
id, err := SelectLastMigration()
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, id)
|
||||
//assert.NotZero(t, id)
|
||||
t.Log("Last migration id: ", id)
|
||||
}
|
||||
|
||||
func TestInsertNotifierDB(t *testing.T) {
|
||||
|
|
324
core/database.go
324
core/database.go
|
@ -17,94 +17,176 @@ package core
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-yaml/yaml"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/mssql"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"upper.io/db.v3"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
"upper.io/db.v3/mysql"
|
||||
"upper.io/db.v3/postgresql"
|
||||
"upper.io/db.v3/sqlite"
|
||||
)
|
||||
|
||||
var (
|
||||
sqliteSettings sqlite.ConnectionURL
|
||||
postgresSettings postgresql.ConnectionURL
|
||||
mysqlSettings mysql.ConnectionURL
|
||||
DbSession sqlbuilder.Database
|
||||
DbSession *gorm.DB
|
||||
currentMigration int64
|
||||
)
|
||||
|
||||
func failuresDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Failure{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Failure{})
|
||||
}
|
||||
|
||||
func (s *Service) allHits() *gorm.DB {
|
||||
var hits []*Hit
|
||||
return servicesDB().Find(s).Related(&hits)
|
||||
}
|
||||
|
||||
func hitsDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Hit{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Hit{})
|
||||
}
|
||||
|
||||
func servicesDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Service{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Service{})
|
||||
}
|
||||
|
||||
func coreDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Table("core").Debug()
|
||||
}
|
||||
return DbSession.Table("core")
|
||||
}
|
||||
|
||||
func usersDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.User{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.User{})
|
||||
}
|
||||
|
||||
func commDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Table("communication").Model(¬ifiers.Notification{}).Debug()
|
||||
}
|
||||
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{})
|
||||
}
|
||||
|
||||
type DbConfig struct {
|
||||
*types.DbConfig
|
||||
}
|
||||
|
||||
func DbConnection(dbType string, retry bool, location string) error {
|
||||
func (db *DbConfig) Close() error {
|
||||
return DbSession.Close()
|
||||
}
|
||||
|
||||
func (db *DbConfig) InsertCore() (*Core, error) {
|
||||
CoreApp = &Core{Core: &types.Core{
|
||||
Name: db.Project,
|
||||
Description: db.Description,
|
||||
Config: "config.yml",
|
||||
ApiKey: utils.NewSHA1Hash(9),
|
||||
ApiSecret: utils.NewSHA1Hash(16),
|
||||
Domain: db.Domain,
|
||||
MigrationId: time.Now().Unix(),
|
||||
}}
|
||||
CoreApp.DbConnection = db.DbConn
|
||||
query := coreDB().Create(&CoreApp)
|
||||
return CoreApp, query.Error
|
||||
}
|
||||
|
||||
func (db *DbConfig) Connect(retry bool, location string) error {
|
||||
var err error
|
||||
if dbType == "sqlite" {
|
||||
sqliteSettings = sqlite.ConnectionURL{
|
||||
Database: location + "/statup.db",
|
||||
}
|
||||
DbSession, err = sqlite.Open(sqliteSettings)
|
||||
if DbSession != nil {
|
||||
DbSession = nil
|
||||
}
|
||||
switch Configs.DbConn {
|
||||
case "sqlite":
|
||||
DbSession, err = gorm.Open("sqlite3", utils.Directory+"/statup.db")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if dbType == "mysql" {
|
||||
if Configs.Port == "" {
|
||||
Configs.Port = "3306"
|
||||
case "mysql":
|
||||
if Configs.DbPort == 0 {
|
||||
Configs.DbPort = 3306
|
||||
}
|
||||
host := fmt.Sprintf("%v:%v", Configs.Host, Configs.Port)
|
||||
mysqlSettings = mysql.ConnectionURL{
|
||||
Database: Configs.Database,
|
||||
Host: host,
|
||||
User: Configs.User,
|
||||
Password: Configs.Password,
|
||||
Options: map[string]string{"parseTime": "true", "charset": "utf8"},
|
||||
}
|
||||
DbSession, err = mysql.Open(mysqlSettings)
|
||||
host := fmt.Sprintf("%v:%v", Configs.DbHost, Configs.DbPort)
|
||||
conn := fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8&parseTime=True&loc=Local", Configs.DbUser, Configs.DbPass, host, Configs.DbData)
|
||||
DbSession, err = gorm.Open("mysql", conn)
|
||||
DbSession.DB().SetConnMaxLifetime(time.Minute * 5)
|
||||
DbSession.DB().SetMaxIdleConns(0)
|
||||
DbSession.DB().SetMaxOpenConns(5)
|
||||
if err != nil {
|
||||
if retry {
|
||||
utils.Log(1, fmt.Sprintf("Database connection to '%v' is not available, trying again in 5 seconds...", host))
|
||||
return waitForDb(dbType)
|
||||
return db.waitForDb()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if Configs.Port == "" {
|
||||
Configs.Port = "5432"
|
||||
case "postgres":
|
||||
if Configs.DbPort == 0 {
|
||||
Configs.DbPort = 5432
|
||||
}
|
||||
host := fmt.Sprintf("%v:%v", Configs.Host, Configs.Port)
|
||||
postgresSettings = postgresql.ConnectionURL{
|
||||
Database: Configs.Database,
|
||||
Host: host,
|
||||
User: Configs.User,
|
||||
Password: Configs.Password,
|
||||
conn := fmt.Sprintf("host=%v port=%v user=%v dbname=%v password=%v sslmode=disable", Configs.DbHost, Configs.DbPort, Configs.DbUser, Configs.DbData, Configs.DbPass)
|
||||
DbSession, err = gorm.Open("postgres", conn)
|
||||
if err != nil {
|
||||
if retry {
|
||||
utils.Log(1, fmt.Sprintf("Database connection to '%v' is not available, trying again in 5 seconds...", Configs.DbHost))
|
||||
return db.waitForDb()
|
||||
} else {
|
||||
fmt.Println("ERROR:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
DbSession, err = postgresql.Open(postgresSettings)
|
||||
case "mssql":
|
||||
if Configs.DbPort == 0 {
|
||||
Configs.DbPort = 1433
|
||||
}
|
||||
host := fmt.Sprintf("%v:%v", Configs.DbHost, Configs.DbPort)
|
||||
conn := fmt.Sprintf("sqlserver://%v:%v@%v?database=%v", Configs.DbUser, Configs.DbPass, host, Configs.DbData)
|
||||
DbSession, err = gorm.Open("mssql", conn)
|
||||
if err != nil {
|
||||
if retry {
|
||||
utils.Log(1, fmt.Sprintf("Database connection to '%v' is not available, trying again in 5 seconds...", host))
|
||||
return waitForDb(dbType)
|
||||
return db.waitForDb()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err = DbSession.Ping()
|
||||
err = DbSession.DB().Ping()
|
||||
if err == nil {
|
||||
utils.Log(1, fmt.Sprintf("Database connection to '%v' was successful.", DbSession.Name()))
|
||||
utils.Log(1, fmt.Sprintf("Database connection to '%v' was successful.", Configs.DbData))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func waitForDb(dbType string) error {
|
||||
func (db *DbConfig) waitForDb() error {
|
||||
time.Sleep(5 * time.Second)
|
||||
return DbConnection(dbType, true, utils.Directory)
|
||||
return db.Connect(true, utils.Directory)
|
||||
}
|
||||
|
||||
func DatabaseMaintence() {
|
||||
|
@ -118,9 +200,10 @@ func DatabaseMaintence() {
|
|||
|
||||
func DeleteAllSince(table string, date time.Time) {
|
||||
sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, date.Format("2006-01-02"))
|
||||
_, err := DbSession.Exec(db.Raw(sql))
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
db := DbSession.Raw(sql)
|
||||
defer db.Close()
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,57 +224,44 @@ func (c *DbConfig) Update() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (c *DbConfig) Save() error {
|
||||
func (c *DbConfig) Save() (*DbConfig, error) {
|
||||
var err error
|
||||
config, err := os.Create(utils.Directory + "/config.yml")
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
c.ApiKey = utils.NewSHA1Hash(16)
|
||||
c.ApiSecret = utils.NewSHA1Hash(16)
|
||||
data, err := yaml.Marshal(c.DbConfig)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
config.WriteString(string(data))
|
||||
config.Close()
|
||||
|
||||
Configs, err = LoadConfig()
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return err
|
||||
}
|
||||
err = DbConnection(Configs.Connection, false, c.Location)
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
return err
|
||||
}
|
||||
DropDatabase()
|
||||
CreateDatabase()
|
||||
defer config.Close()
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (c *DbConfig) CreateCore() *Core {
|
||||
newCore := &types.Core{
|
||||
Name: c.Project,
|
||||
Description: c.Description,
|
||||
Config: "config.yml",
|
||||
ApiKey: utils.NewSHA1Hash(9),
|
||||
ApiSecret: utils.NewSHA1Hash(16),
|
||||
ApiKey: c.ApiKey,
|
||||
ApiSecret: c.ApiSecret,
|
||||
Domain: c.Domain,
|
||||
MigrationId: time.Now().Unix(),
|
||||
}
|
||||
col := DbSession.Collection("core")
|
||||
_, err = col.Insert(newCore)
|
||||
if err == nil {
|
||||
db := coreDB().Create(&newCore)
|
||||
if db.Error == nil {
|
||||
CoreApp = &Core{Core: newCore}
|
||||
}
|
||||
|
||||
CoreApp, err = SelectCore()
|
||||
CoreApp, err := SelectCore()
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
}
|
||||
CoreApp.DbConnection = c.DbConn
|
||||
c.ApiKey = CoreApp.ApiKey
|
||||
c.ApiSecret = CoreApp.ApiSecret
|
||||
return err
|
||||
return CoreApp
|
||||
}
|
||||
|
||||
func versionHigher(migrate int64) bool {
|
||||
|
@ -239,10 +309,10 @@ func RunDatabaseUpgrades() error {
|
|||
continue
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("Running Query: %v", m))
|
||||
_, err := DbSession.Exec(db.Raw(m + ";"))
|
||||
db := DbSession.Raw(m)
|
||||
ran++
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +322,7 @@ func RunDatabaseUpgrades() error {
|
|||
utils.Log(1, fmt.Sprintf("Database Upgraded %v queries ran, current #%v", ran, currentMigration))
|
||||
CoreApp, err = SelectCore()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
CoreApp.MigrationId = currentMigration
|
||||
UpdateCore(CoreApp)
|
||||
|
@ -260,43 +330,77 @@ func RunDatabaseUpgrades() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func DropDatabase() error {
|
||||
utils.Log(1, "Dropping Database Tables...")
|
||||
down, err := source.SqlBox.String("down.sql")
|
||||
func (db *DbConfig) SeedSchema() (string, string, error) {
|
||||
utils.Log(1, "Seeding Schema Database with Dummy Data...")
|
||||
dir := utils.Directory
|
||||
var cmd string
|
||||
switch db.DbConn {
|
||||
case "sqlite":
|
||||
cmd = fmt.Sprintf("cat %v/source/sql/sqlite_up.sql | sqlite3 %v/statup.db", dir, dir)
|
||||
case "mysql":
|
||||
cmd = fmt.Sprintf("mysql -h %v -P %v -u %v --password=%v %v < %v/source/sql/mysql_up.sql", Configs.DbHost, Configs.DbPort, Configs.DbUser, Configs.DbPass, Configs.DbData, dir)
|
||||
case "postgres":
|
||||
cmd = fmt.Sprintf("PGPASSWORD=%v psql -U %v -h %v -d %v -1 -f %v/source/sql/postgres_up.sql", db.DbPass, db.DbUser, db.DbHost, db.DbData, dir)
|
||||
}
|
||||
out, outErr, err := utils.Command(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
return out, outErr, err
|
||||
}
|
||||
requests := strings.Split(down, ";")
|
||||
for _, request := range requests {
|
||||
_, err := DbSession.Exec(request)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
return out, outErr, err
|
||||
}
|
||||
|
||||
func CreateDatabase() error {
|
||||
func (db *DbConfig) SeedDatabase() (string, string, error) {
|
||||
utils.Log(1, "Seeding Database with Dummy Data...")
|
||||
dir := utils.Directory
|
||||
var cmd string
|
||||
switch db.DbConn {
|
||||
case "sqlite":
|
||||
cmd = fmt.Sprintf("cat %v/dev/sqlite_seed.sql | sqlite3 %v/statup.db", dir, dir)
|
||||
case "mysql":
|
||||
cmd = fmt.Sprintf("mysql -h %v -P %v -u %v --password=%v %v < %v/dev/mysql_seed.sql", Configs.DbHost, Configs.DbPort, Configs.DbUser, Configs.DbPass, Configs.DbData, dir)
|
||||
case "postgres":
|
||||
cmd = fmt.Sprintf("PGPASSWORD=%v psql -U %v -h %v -d %v -1 -f %v/dev/postgres_seed.sql", db.DbPass, db.DbUser, db.DbHost, db.DbData, dir)
|
||||
}
|
||||
out, outErr, err := utils.Command(cmd)
|
||||
return out, outErr, err
|
||||
}
|
||||
|
||||
func (db *DbConfig) DropDatabase() error {
|
||||
utils.Log(1, "Dropping Database Tables...")
|
||||
err := DbSession.DropTableIfExists("checkins")
|
||||
err = DbSession.DropTableIfExists("communication")
|
||||
err = DbSession.DropTableIfExists("core")
|
||||
err = DbSession.DropTableIfExists("failures")
|
||||
err = DbSession.DropTableIfExists("hits")
|
||||
err = DbSession.DropTableIfExists("services")
|
||||
err = DbSession.DropTableIfExists("users")
|
||||
return err.Error
|
||||
}
|
||||
|
||||
func (db *DbConfig) CreateDatabase() error {
|
||||
utils.Log(1, "Creating Database Tables...")
|
||||
sql := "postgres_up.sql"
|
||||
if CoreApp.DbConnection == "mysql" {
|
||||
sql = "mysql_up.sql"
|
||||
} else if CoreApp.DbConnection == "sqlite" {
|
||||
sql = "sqlite_up.sql"
|
||||
}
|
||||
up, err := source.SqlBox.String(sql)
|
||||
requests := strings.Split(up, ";")
|
||||
for _, request := range requests {
|
||||
_, err := DbSession.Exec(request)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
}
|
||||
//secret := NewSHA1Hash()
|
||||
//db.QueryRow("INSERT INTO core (secret, version) VALUES ($1, $2);", secret, VERSION).Scan()
|
||||
utils.Log(1, "Database Created")
|
||||
//SampleData()
|
||||
return err
|
||||
err := DbSession.CreateTable(&types.Checkin{})
|
||||
err = DbSession.Table("communication").CreateTable(¬ifiers.Notification{})
|
||||
err = DbSession.Table("core").CreateTable(&types.Core{})
|
||||
err = DbSession.CreateTable(&types.Failure{})
|
||||
err = DbSession.CreateTable(&types.Hit{})
|
||||
err = DbSession.CreateTable(&types.Service{})
|
||||
err = DbSession.CreateTable(&types.User{})
|
||||
utils.Log(1, "Statup Database Created")
|
||||
return err.Error
|
||||
}
|
||||
|
||||
func (db *DbConfig) MigrateDatabase() error {
|
||||
utils.Log(1, "Migrating Database Tables...")
|
||||
err := DbSession.AutoMigrate(&types.Checkin{})
|
||||
err = DbSession.Table("communication").AutoMigrate(¬ifiers.Notification{})
|
||||
err = DbSession.Table("core").AutoMigrate(&types.Core{})
|
||||
err = DbSession.AutoMigrate(&types.Failure{})
|
||||
err = DbSession.AutoMigrate(&types.Hit{})
|
||||
err = DbSession.AutoMigrate(&types.Service{})
|
||||
err = DbSession.AutoMigrate(&types.User{})
|
||||
utils.Log(1, "Statup Database Migrated")
|
||||
return err.Error
|
||||
}
|
||||
|
||||
func (c *DbConfig) Clean() *DbConfig {
|
||||
|
|
|
@ -19,12 +19,12 @@ import (
|
|||
"github.com/fatih/structs"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func OnLoad(db sqlbuilder.Database) {
|
||||
func OnLoad(db *gorm.DB) {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnLoad(db)
|
||||
p.OnLoad(*db)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,11 @@ import (
|
|||
)
|
||||
|
||||
func injectDatabase() {
|
||||
DbConnection(Configs.Connection, false, utils.Directory)
|
||||
Configs.Connect(false, utils.Directory)
|
||||
}
|
||||
|
||||
func GenerateSeed() {
|
||||
|
||||
}
|
||||
|
||||
func ExportIndexHTML() string {
|
||||
|
|
|
@ -32,23 +32,19 @@ func (s *Service) CreateFailure(f *types.Failure) (int64, error) {
|
|||
f.CreatedAt = time.Now()
|
||||
f.Service = s.Id
|
||||
s.Failures = append(s.Failures, f)
|
||||
col := DbSession.Collection("failures")
|
||||
uuid, err := col.Insert(f)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return 0, err
|
||||
row := failuresDB().Create(f)
|
||||
if row.Error != nil {
|
||||
utils.Log(3, row.Error)
|
||||
return 0, row.Error
|
||||
}
|
||||
if uuid == nil {
|
||||
return 0, err
|
||||
}
|
||||
return uuid.(int64), err
|
||||
return f.Id, row.Error
|
||||
}
|
||||
|
||||
func (s *Service) AllFailures() []*types.Failure {
|
||||
var fails []*types.Failure
|
||||
col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id")
|
||||
err := col.All(&fails)
|
||||
if err != nil {
|
||||
col := failuresDB().Where("service = ?", s.Id).Order("id desc")
|
||||
err := col.Find(&fails)
|
||||
if err.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err))
|
||||
return nil
|
||||
}
|
||||
|
@ -56,8 +52,8 @@ func (s *Service) AllFailures() []*types.Failure {
|
|||
}
|
||||
|
||||
func (u *Service) DeleteFailures() {
|
||||
_, err := DbSession.Exec(`DELETE FROM failures WHERE service = ?`, u.Id)
|
||||
if err != nil {
|
||||
err := DbSession.Exec(`DELETE FROM failures WHERE service = ?`, u.Id)
|
||||
if err.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("failed to delete all failures: %v", err))
|
||||
}
|
||||
u.Failures = nil
|
||||
|
@ -65,8 +61,8 @@ func (u *Service) DeleteFailures() {
|
|||
|
||||
func (s *Service) LimitedFailures() []*Failure {
|
||||
var failArr []*Failure
|
||||
col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id").Limit(10)
|
||||
col.All(&failArr)
|
||||
col := failuresDB().Where("service = ?", s.Id).Order("id desc").Limit(10)
|
||||
col.Find(&failArr)
|
||||
return failArr
|
||||
}
|
||||
|
||||
|
@ -83,30 +79,37 @@ func (f *Failure) Ago() string {
|
|||
}
|
||||
|
||||
func (f *Failure) Delete() error {
|
||||
col := DbSession.Collection("failures").Find("id", f.Id)
|
||||
return col.Delete()
|
||||
db := failuresDB().Delete(f)
|
||||
return db.Error
|
||||
}
|
||||
|
||||
func CountFailures() uint64 {
|
||||
col := DbSession.Collection("failures").Find()
|
||||
amount, err := col.Count()
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
var count uint64
|
||||
err := failuresDB().Count(&count)
|
||||
if err.Error != nil {
|
||||
utils.Log(2, err.Error)
|
||||
return 0
|
||||
}
|
||||
return amount
|
||||
return count
|
||||
}
|
||||
|
||||
func (s *Service) TotalFailures24() (uint64, error) {
|
||||
ago := time.Now().Add(-24 * time.Hour)
|
||||
return s.TotalFailuresSince(ago)
|
||||
}
|
||||
|
||||
func (s *Service) TotalFailures() (uint64, error) {
|
||||
col := DbSession.Collection("failures").Find("service", s.Id)
|
||||
amount, err := col.Count()
|
||||
return amount, err
|
||||
var count uint64
|
||||
rows := failuresDB().Where("service = ?", s.Id)
|
||||
err := rows.Count(count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) TotalFailures24Hours() (uint64, error) {
|
||||
col := DbSession.Collection("failures").Find("service", s.Id)
|
||||
amount, err := col.Count()
|
||||
return amount, err
|
||||
func (s *Service) TotalFailuresSince(ago time.Time) (uint64, error) {
|
||||
var count uint64
|
||||
rows := failuresDB().Where("service = ? AND created_at > ?", s.Id, ago.Format("2006-01-02 15:04:05"))
|
||||
err := rows.Count(&count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
func (f *Failure) ParseError() string {
|
||||
|
|
53
core/hits.go
53
core/hits.go
|
@ -19,40 +19,33 @@ import (
|
|||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"time"
|
||||
"upper.io/db.v3"
|
||||
)
|
||||
|
||||
type Hit struct {
|
||||
*types.Hit
|
||||
}
|
||||
|
||||
func hitCol() db.Collection {
|
||||
return DbSession.Collection("hits")
|
||||
}
|
||||
|
||||
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
||||
h.CreatedAt = time.Now()
|
||||
h.Service = s.Id
|
||||
uuid, err := hitCol().Insert(h)
|
||||
if uuid == nil {
|
||||
utils.Log(2, err)
|
||||
return 0, err
|
||||
db := hitsDB().Create(&h)
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
return 0, db.Error
|
||||
}
|
||||
return uuid.(int64), err
|
||||
return h.Id, db.Error
|
||||
}
|
||||
|
||||
func (s *Service) Hits() ([]*Hit, error) {
|
||||
var hits []*Hit
|
||||
col := hitCol().Find("service", s.Id).OrderBy("-id")
|
||||
err := col.All(&hits)
|
||||
return hits, err
|
||||
col := hitsDB().Where("service = ?", s.Id).Order("id desc")
|
||||
err := col.Find(&hits)
|
||||
return hits, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) LimitedHits() ([]*Hit, error) {
|
||||
var hits []*Hit
|
||||
col := hitCol().Find("service", s.Id).OrderBy("-id").Limit(1024)
|
||||
err := col.All(&hits)
|
||||
return reverseHits(hits), err
|
||||
col := hitsDB().Where("service = ?", s.Id).Order("id desc").Limit(1024)
|
||||
err := col.Find(&hits)
|
||||
return reverseHits(hits), err.Error
|
||||
}
|
||||
|
||||
func reverseHits(input []*Hit) []*Hit {
|
||||
|
@ -64,15 +57,27 @@ func reverseHits(input []*Hit) []*Hit {
|
|||
|
||||
func (s *Service) SelectHitsGroupBy(group string) ([]*Hit, error) {
|
||||
var hits []*Hit
|
||||
col := hitCol().Find("service", s.Id)
|
||||
err := col.All(&hits)
|
||||
return hits, err
|
||||
col := hitsDB().Where("service = ?", s.Id)
|
||||
err := col.Find(&hits)
|
||||
return hits, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) hits() {
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) TotalHits() (uint64, error) {
|
||||
col := hitCol().Find("service", s.Id)
|
||||
amount, err := col.Count()
|
||||
return amount, err
|
||||
var count uint64
|
||||
col := hitsDB().Where("service = ?", s.Id)
|
||||
err := col.Count(&count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) TotalHitsSince(ago time.Time) (uint64, error) {
|
||||
var count uint64
|
||||
rows := hitsDB().Where("service = ? AND created_at > ?", s.Id, ago.Format("2006-01-02 15:04:05"))
|
||||
err := rows.Count(&count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) Sum() (float64, error) {
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
"upper.io/db.v3"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
|
@ -30,16 +29,12 @@ type Service struct {
|
|||
}
|
||||
|
||||
func ReturnService(s *types.Service) *Service {
|
||||
return &Service{Service: s}
|
||||
}
|
||||
|
||||
func serviceCol() db.Collection {
|
||||
return DbSession.Collection("services")
|
||||
return &Service{s}
|
||||
}
|
||||
|
||||
func SelectService(id int64) *Service {
|
||||
for _, s := range CoreApp.Services() {
|
||||
if s.Id == id {
|
||||
if s.Service.Id == id {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +44,10 @@ func SelectService(id int64) *Service {
|
|||
func (c *Core) SelectAllServices() ([]*types.Service, error) {
|
||||
var services []*types.Service
|
||||
var servs []*types.Service
|
||||
col := serviceCol().Find().OrderBy("order_id")
|
||||
err := col.All(&services)
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("service error: %v", err))
|
||||
return nil, err
|
||||
db := servicesDB().Find(&services)
|
||||
if db.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("service error: %v", db.Error))
|
||||
return nil, db.Error
|
||||
}
|
||||
for _, ser := range services {
|
||||
single := ReturnService(ser)
|
||||
|
@ -63,7 +57,7 @@ func (c *Core) SelectAllServices() ([]*types.Service, error) {
|
|||
servs = append(servs, single.Service)
|
||||
}
|
||||
CoreApp.SetServices(servs)
|
||||
return services, err
|
||||
return services, db.Error
|
||||
}
|
||||
|
||||
func (s *Service) ToJSON() string {
|
||||
|
@ -84,12 +78,17 @@ func (s *Service) AvgTime() float64 {
|
|||
}
|
||||
|
||||
func (s *Service) Online24() float32 {
|
||||
total, _ := s.TotalHits()
|
||||
failed, _ := s.TotalFailures24Hours()
|
||||
ago := time.Now().Add(-24 * time.Hour)
|
||||
return s.OnlineSince(ago)
|
||||
}
|
||||
|
||||
func (s *Service) OnlineSince(ago time.Time) float32 {
|
||||
failed, _ := s.TotalFailuresSince(ago)
|
||||
if failed == 0 {
|
||||
s.Online24Hours = 100.00
|
||||
return s.Online24Hours
|
||||
}
|
||||
total, _ := s.TotalHitsSince(ago)
|
||||
if total == 0 {
|
||||
s.Online24Hours = 0
|
||||
return s.Online24Hours
|
||||
|
@ -150,16 +149,17 @@ func (s *Service) GraphData() string {
|
|||
var d []*DateScan
|
||||
since := time.Now().Add(time.Hour*-24 + time.Minute*0 + time.Second*0)
|
||||
sql := GroupDataBy("hits", s.Id, since, "minute")
|
||||
dated, err := DbSession.Query(db.Raw(sql))
|
||||
rows, err := DbSession.Raw(sql).Rows()
|
||||
defer rows.Close()
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
return ""
|
||||
}
|
||||
for dated.Next() {
|
||||
for rows.Next() {
|
||||
gd := new(DateScan)
|
||||
var tt string
|
||||
var ff float64
|
||||
err := dated.Scan(&tt, &ff)
|
||||
err := rows.Scan(&tt, &ff)
|
||||
if err != nil {
|
||||
utils.Log(2, fmt.Sprintf("Issue loading chart data for service %v, %v", s.Name, err))
|
||||
}
|
||||
|
@ -178,13 +178,18 @@ func (s *Service) GraphData() string {
|
|||
return string(data)
|
||||
}
|
||||
|
||||
func (s *Service) AvgUptime() string {
|
||||
failed, _ := s.TotalFailures()
|
||||
total, _ := s.TotalHits()
|
||||
func (s *Service) AvgUptime24() string {
|
||||
ago := time.Now().Add(-24 * time.Hour)
|
||||
return s.AvgUptime(ago)
|
||||
}
|
||||
|
||||
func (s *Service) AvgUptime(ago time.Time) string {
|
||||
failed, _ := s.TotalFailuresSince(ago)
|
||||
if failed == 0 {
|
||||
s.TotalUptime = "100"
|
||||
return s.TotalUptime
|
||||
}
|
||||
total, _ := s.TotalHitsSince(ago)
|
||||
if total == 0 {
|
||||
s.TotalUptime = "0"
|
||||
return s.TotalUptime
|
||||
|
@ -217,25 +222,27 @@ func updateService(service *Service) {
|
|||
}
|
||||
|
||||
func (u *Service) Delete() error {
|
||||
res := serviceCol().Find("id", u.Id)
|
||||
err := res.Delete()
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err))
|
||||
return err
|
||||
err := servicesDB().Delete(u)
|
||||
if err.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err.Error))
|
||||
return err.Error
|
||||
}
|
||||
u.Close()
|
||||
CoreApp.RemoveService(u.index())
|
||||
OnDeletedService(u)
|
||||
return err
|
||||
return err.Error
|
||||
}
|
||||
|
||||
func (u *Service) UpdateSingle(attr ...interface{}) error {
|
||||
return servicesDB().Model(u).Update(attr).Error
|
||||
}
|
||||
|
||||
func (u *Service) Update(restart bool) error {
|
||||
u.CreatedAt = time.Now()
|
||||
res := serviceCol().Find("id", u.Id)
|
||||
err := res.Update(u)
|
||||
if err != nil {
|
||||
err := servicesDB().Update(u)
|
||||
if err.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", u.Name, err))
|
||||
return err
|
||||
return err.Error
|
||||
}
|
||||
if restart {
|
||||
u.Close()
|
||||
|
@ -245,20 +252,19 @@ func (u *Service) Update(restart bool) error {
|
|||
go u.CheckQueue(true)
|
||||
}
|
||||
OnUpdateService(u)
|
||||
return err
|
||||
return err.Error
|
||||
}
|
||||
|
||||
func (u *Service) Create() (int64, error) {
|
||||
u.CreatedAt = time.Now()
|
||||
uuid, err := serviceCol().Insert(u)
|
||||
if uuid == nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to create service %v. %v", u.Name, err))
|
||||
return 0, err
|
||||
db := servicesDB().Create(u)
|
||||
if db.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to create service %v #%v: %v", u.Name, u.Id, db.Error))
|
||||
return 0, db.Error
|
||||
}
|
||||
u.Id = uuid.(int64)
|
||||
u.Start()
|
||||
CoreApp.AddService(u.Service)
|
||||
return uuid.(int64), err
|
||||
return u.Id, nil
|
||||
}
|
||||
|
||||
func CountOnline() int {
|
||||
|
|
|
@ -26,23 +26,29 @@ var (
|
|||
newServiceId int64
|
||||
)
|
||||
|
||||
func TestSelectHTTPService(t *testing.T) {
|
||||
services, err := CoreApp.SelectAllServices()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 18, len(services))
|
||||
assert.Equal(t, "Google", services[0].Name)
|
||||
assert.Equal(t, "http", services[0].Type)
|
||||
}
|
||||
|
||||
func TestSelectAllServices(t *testing.T) {
|
||||
services := CoreApp.Services()
|
||||
for _, s := range services {
|
||||
service := s.Check(true)
|
||||
assert.True(t, service.Online)
|
||||
assert.True(t, service.IsRunning())
|
||||
t.Logf("ID: %v %v\n", s.Id, s.Name)
|
||||
}
|
||||
assert.Equal(t, 5, len(services))
|
||||
}
|
||||
|
||||
func TestSelectHTTPService(t *testing.T) {
|
||||
service := SelectService(1)
|
||||
assert.Equal(t, "Google", service.Name)
|
||||
assert.Equal(t, "http", service.Type)
|
||||
assert.Equal(t, 18, len(services))
|
||||
}
|
||||
|
||||
func TestSelectTCPService(t *testing.T) {
|
||||
services := CoreApp.Services()
|
||||
assert.Equal(t, 18, len(services))
|
||||
service := SelectService(5)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Google DNS", service.Name)
|
||||
assert.Equal(t, "tcp", service.Type)
|
||||
}
|
||||
|
@ -105,9 +111,14 @@ func TestCheckTCPService(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServiceOnline24Hours(t *testing.T) {
|
||||
service := SelectService(5)
|
||||
amount := service.Online24()
|
||||
assert.Equal(t, float32(100), amount)
|
||||
since, err := time.Parse(time.RFC3339, SERVICE_SINCE)
|
||||
assert.Nil(t, err)
|
||||
service := SelectService(1)
|
||||
assert.Equal(t, float32(83.33), service.OnlineSince(since))
|
||||
service2 := SelectService(5)
|
||||
assert.Equal(t, float32(100), service2.OnlineSince(since))
|
||||
service3 := SelectService(18)
|
||||
assert.Equal(t, float32(0), service3.OnlineSince(since))
|
||||
}
|
||||
|
||||
func TestServiceSmallText(t *testing.T) {
|
||||
|
@ -117,30 +128,35 @@ func TestServiceSmallText(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServiceAvgUptime(t *testing.T) {
|
||||
service := SelectService(5)
|
||||
uptime := service.AvgUptime()
|
||||
assert.Equal(t, "100", uptime)
|
||||
since, err := time.Parse(time.RFC3339, SERVICE_SINCE)
|
||||
assert.Nil(t, err)
|
||||
service := SelectService(1)
|
||||
assert.Equal(t, "83.33", service.AvgUptime(since))
|
||||
service2 := SelectService(5)
|
||||
assert.Equal(t, "100", service2.AvgUptime(since))
|
||||
service3 := SelectService(18)
|
||||
assert.Equal(t, "0.00", service3.AvgUptime(since))
|
||||
}
|
||||
|
||||
func TestServiceHits(t *testing.T) {
|
||||
service := SelectService(5)
|
||||
hits, err := service.Hits()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int(2), len(hits))
|
||||
assert.Equal(t, int(5), len(hits))
|
||||
}
|
||||
|
||||
func TestServiceLimitedHits(t *testing.T) {
|
||||
service := SelectService(5)
|
||||
hits, err := service.LimitedHits()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int(2), len(hits))
|
||||
assert.Equal(t, int(5), len(hits))
|
||||
}
|
||||
|
||||
func TestServiceTotalHits(t *testing.T) {
|
||||
service := SelectService(5)
|
||||
hits, err := service.TotalHits()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, uint64(0x2), hits)
|
||||
assert.Equal(t, uint64(0x5), hits)
|
||||
}
|
||||
|
||||
func TestServiceSum(t *testing.T) {
|
||||
|
@ -176,7 +192,6 @@ func TestCreateService(t *testing.T) {
|
|||
func TestViewNewService(t *testing.T) {
|
||||
newService := SelectService(newServiceId)
|
||||
assert.Equal(t, "That'll do 🐢", newService.Name)
|
||||
|
||||
}
|
||||
|
||||
func TestCreateFailingHTTPService(t *testing.T) {
|
||||
|
@ -195,10 +210,12 @@ func TestCreateFailingHTTPService(t *testing.T) {
|
|||
assert.NotZero(t, newServiceId)
|
||||
newService := SelectService(newServiceId)
|
||||
assert.Equal(t, "Bad URL", newService.Name)
|
||||
t.Log("new service ID: ", newServiceId)
|
||||
}
|
||||
|
||||
func TestServiceFailedCheck(t *testing.T) {
|
||||
service := SelectService(7)
|
||||
service := SelectService(20)
|
||||
assert.Equal(t, "Bad URL", service.Name)
|
||||
checked := service.Check(true)
|
||||
assert.Equal(t, "Bad URL", checked.Name)
|
||||
assert.False(t, checked.Online)
|
||||
|
@ -219,10 +236,11 @@ func TestCreateFailingTCPService(t *testing.T) {
|
|||
assert.NotZero(t, newServiceId)
|
||||
newService := SelectService(newServiceId)
|
||||
assert.Equal(t, "Bad TCP", newService.Name)
|
||||
t.Log("new failing tcp service ID: ", newServiceId)
|
||||
}
|
||||
|
||||
func TestServiceFailedTCPCheck(t *testing.T) {
|
||||
service := SelectService(8)
|
||||
service := SelectService(21)
|
||||
checked := service.Check(true)
|
||||
assert.Equal(t, "Bad TCP", checked.Name)
|
||||
assert.False(t, checked.Online)
|
||||
|
@ -244,13 +262,13 @@ func TestDeleteService(t *testing.T) {
|
|||
|
||||
count, err := CoreApp.SelectAllServices()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 8, len(count))
|
||||
assert.Equal(t, 21, len(count))
|
||||
|
||||
err = service.Delete()
|
||||
assert.Nil(t, err)
|
||||
|
||||
services := CoreApp.Services()
|
||||
assert.Equal(t, 7, len(services))
|
||||
assert.Equal(t, 20, len(services))
|
||||
}
|
||||
|
||||
func TestServiceCloseRoutine(t *testing.T) {
|
||||
|
|
|
@ -28,36 +28,29 @@ type User struct {
|
|||
}
|
||||
|
||||
func ReturnUser(u *types.User) *User {
|
||||
return &User{User: u}
|
||||
return &User{u}
|
||||
}
|
||||
|
||||
func SelectUser(id int64) (*User, error) {
|
||||
var user *User
|
||||
col := DbSession.Collection("users")
|
||||
res := col.Find("id", id)
|
||||
err := res.One(&user)
|
||||
return user, err
|
||||
var user User
|
||||
err := usersDB().First(&user, id)
|
||||
return &user, err.Error
|
||||
}
|
||||
|
||||
func SelectUsername(username string) (*User, error) {
|
||||
var user *User
|
||||
col := DbSession.Collection("users")
|
||||
res := col.Find("username", username)
|
||||
err := res.One(&user)
|
||||
return user, err
|
||||
var user User
|
||||
res := usersDB().Where("username = ?", username)
|
||||
err := res.First(&user)
|
||||
return &user, err.Error
|
||||
}
|
||||
|
||||
func (u *User) Delete() error {
|
||||
col := DbSession.Collection("users")
|
||||
user := col.Find("id", u.Id)
|
||||
return user.Delete()
|
||||
return usersDB().Delete(u).Error
|
||||
}
|
||||
|
||||
func (u *User) Update() error {
|
||||
u.CreatedAt = time.Now()
|
||||
col := DbSession.Collection("users")
|
||||
user := col.Find("id", u.Id)
|
||||
return user.Update(u)
|
||||
return usersDB().Update(u).Error
|
||||
}
|
||||
|
||||
func (u *User) Create() (int64, error) {
|
||||
|
@ -65,39 +58,36 @@ func (u *User) Create() (int64, error) {
|
|||
u.Password = utils.HashPassword(u.Password)
|
||||
u.ApiKey = utils.NewSHA1Hash(5)
|
||||
u.ApiSecret = utils.NewSHA1Hash(10)
|
||||
col := DbSession.Collection("users")
|
||||
uuid, err := col.Insert(u)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
db := usersDB().Create(u)
|
||||
if db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
if uuid == nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to create user %v. %v", u.Username, err))
|
||||
return 0, err
|
||||
if u.Id == 0 {
|
||||
utils.Log(3, fmt.Sprintf("Failed to create user %v. %v", u.Username, db.Error))
|
||||
return 0, db.Error
|
||||
}
|
||||
return uuid.(int64), err
|
||||
return u.Id, db.Error
|
||||
}
|
||||
|
||||
func SelectAllUsers() ([]*User, error) {
|
||||
var users []*User
|
||||
col := DbSession.Collection("users").Find()
|
||||
err := col.All(&users)
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to load all users. %v", err))
|
||||
db := usersDB().Find(&users)
|
||||
if db.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to load all users. %v", db.Error))
|
||||
}
|
||||
return users, err
|
||||
return users, db.Error
|
||||
}
|
||||
|
||||
func AuthUser(username, password string) (*User, bool) {
|
||||
var auth bool
|
||||
user, err := SelectUsername(username)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
return nil, false
|
||||
}
|
||||
if CheckHash(password, user.Password) {
|
||||
auth = true
|
||||
return user, true
|
||||
}
|
||||
return user, auth
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func CheckHash(password, hash string) bool {
|
||||
|
|
|
@ -36,13 +36,13 @@ func TestCreateUser(t *testing.T) {
|
|||
func TestSelectAllUsers(t *testing.T) {
|
||||
users, err := SelectAllUsers()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(users))
|
||||
assert.Equal(t, 2, len(users))
|
||||
}
|
||||
|
||||
func TestSelectUser(t *testing.T) {
|
||||
user, err := SelectUser(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "test@email.com", user.Email)
|
||||
assert.Equal(t, "info@statup.io", user.Email)
|
||||
assert.True(t, user.Admin)
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ func TestSelectUsername(t *testing.T) {
|
|||
user, err := SelectUsername("hunter")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "test@email.com", user.Email)
|
||||
assert.Equal(t, int64(1), user.Id)
|
||||
assert.Equal(t, int64(2), user.Id)
|
||||
assert.True(t, user.Admin)
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ func TestCreateUser2(t *testing.T) {
|
|||
func TestSelectAllUsersAgain(t *testing.T) {
|
||||
users, err := SelectAllUsers()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(users))
|
||||
assert.Equal(t, 3, len(users))
|
||||
}
|
||||
|
||||
func TestAuthUser(t *testing.T) {
|
||||
|
@ -88,12 +88,12 @@ func TestAuthUser(t *testing.T) {
|
|||
assert.True(t, auth)
|
||||
assert.NotNil(t, user)
|
||||
assert.Equal(t, "user@email.com", user.Email)
|
||||
assert.Equal(t, int64(2), user.Id)
|
||||
assert.Equal(t, int64(3), user.Id)
|
||||
assert.True(t, user.Admin)
|
||||
}
|
||||
|
||||
func TestFailedAuthUser(t *testing.T) {
|
||||
user, auth := AuthUser("hunter", "wrongpassword")
|
||||
user, auth := AuthUser("hunterlong", "wrongpassword")
|
||||
assert.False(t, auth)
|
||||
assert.Nil(t, user)
|
||||
}
|
||||
|
@ -111,3 +111,8 @@ func TestDeleteUser(t *testing.T) {
|
|||
err = user.Delete()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestDbConfig_Close(t *testing.T) {
|
||||
err := Configs.Close()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
INSERT INTO core (name,description,config,api_key,api_secret,style,footer,domain,version,migration_id,use_cdn) VALUES ('Awesome Status','This is from the seed file!','config.yml','d2fead3e459bd14f570cf08527175b88b32d7faa','e351393306ea245de5f9588cbe8627c74db007c6','','Created by Hunter Long','','',0,false);
|
||||
INSERT INTO services (name,domain,check_type,method,port,expected,expected_status,check_interval,post_data,order_id,timeout,created_at) VALUES
|
||||
('Google','https://google.com','http','GET',0,'',200,10,'',0,10,'2018-08-31 10:42:08'),
|
||||
('Statup Github','https://github.com/hunterlong/statup','http','GET',0,'',200,30,'',0,20,'2018-08-31 10:42:08'),
|
||||
('JSON Users Test','https://jsonplaceholder.typicode.com/users','http','GET',0,'',200,60,'',0,30,'2018-08-31 10:42:08'),
|
||||
('JSON API Tester','https://jsonplaceholder.typicode.com/posts','http','POST',0,'(title)": "((\\"|[statup])*)"',201,30,'{ "title": "statup", "body": "bar", "userId": 19999 }',0,30,'2018-08-31 10:42:08'),
|
||||
('Google DNS','8.8.8.8','tcp','',53,'',0,20,'',0,120,'2018-08-31 10:42:08'),
|
||||
('The Bravery - An Honest Mistake','https://www.youtube.com/watch?v=O8vzbezVru4','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14'),
|
||||
('Upper.io','https://upper.io/db.v3/','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14'),
|
||||
('CoinApp Status','https://status.coinapp.io','http','GET',0,'',200,1,'',0,30,'2018-08-31 10:42:16'),
|
||||
('Demo Page','https://demo.statup.io','http','GET',0,'',200,2,'',0,30,'2018-08-31 10:42:16'),
|
||||
('Golang','https://golang.org','http','GET',0,'',200,3,'',0,30,'2018-08-31 10:42:16'),
|
||||
('Github','https://github.com/hunterlong','http','GET',0,'',200,4,'',0,30,'2018-08-31 10:42:17'),
|
||||
('Santa Monica','https://www.santamonica.com','http','GET',0,'',200,5,'',0,30,'2018-08-31 10:42:17'),
|
||||
('Oeschs Die Dritten','https://www.oeschs-die-dritten.ch/en/','http','GET',0,'',200,6,'',0,30,'2018-08-31 10:42:18'),
|
||||
('EtherScan.io','https://etherscan.io','http','GET',0,'',200,7,'',0,30,'2018-08-31 10:42:20'),
|
||||
('Test Service 7','https://www.youtube.com/watch?v=ipvEIZMMILA','http','GET',0,'',200,8,'',0,30,'2018-08-31 10:42:20'),
|
||||
('Test Service 8','https://www.youtube.com/watch?v=UdaYVxYF1Ok','http','GET',0,'',200,9,'',0,30,'2018-08-31 10:42:20'),
|
||||
('Test Service 9','https://www.youtube.com/watch?v=yydZbVoCbn0&t=870s','http','GET',0,'',200,10,'',0,30,'2018-08-31 10:42:20'),
|
||||
('Failing URL','http://failingdomainsarenofunatall.com','http','GET',0,'',200,11,'',0,30,'2018-08-31 10:42:20');
|
||||
INSERT INTO users (username,password,email,api_key,api_secret,administrator,created_at) VALUES
|
||||
('admin','$2a$14$Aye3yHae0ml6WRtvdgkRnO19OFze0IKF6IOHrdLpETtwLjnPelMUm','info@statup.io','27aa701119fb561d734eb4469cf13ba2550007e2','29de07014d32fbbbb80053ef3c19b464b2b72f64',1,'2018-08-31 10:42:07');
|
||||
INSERT INTO hits (service,latency,created_at) VALUES
|
||||
(5,0.006504081,'2018-08-29 10:42:08'),
|
||||
(3,0.202164333,'2018-08-29 10:42:08'),
|
||||
(4,0.376675172,'2018-08-29 10:42:09'),
|
||||
(1,0.413912204,'2018-08-29 10:42:09'),
|
||||
(1,0.473912204,'2018-08-29 10:42:09'),
|
||||
(2,0.528427935,'2018-08-29 10:42:09'),
|
||||
(6,0.11930188,'2018-08-29 10:42:09'),
|
||||
(7,0.001062722,'2018-08-29 10:42:09'),
|
||||
(7,0.004046882,'2018-08-29 10:42:09'),
|
||||
(6,0.063360069,'2018-08-29 10:42:09'),
|
||||
(8,0.168951416,'2018-08-29 10:42:16'),
|
||||
(8,0.069032763,'2018-08-29 10:42:16'),
|
||||
(9,0.47712966,'2018-08-29 10:42:16'),
|
||||
(10,0.104510482,'2018-08-29 10:42:17'),
|
||||
(10,0.062536146,'2018-08-29 10:42:17'),
|
||||
(9,0.352823197,'2018-08-29 10:42:09'),
|
||||
(8,0.38226374,'2018-08-29 10:42:09'),
|
||||
(11,0.857324393,'2018-08-29 10:42:17'),
|
||||
(12,0.113320285,'2018-08-29 10:42:18'),
|
||||
(12,0.038532321,'2018-08-29 10:42:18'),
|
||||
(8,0.123430059,'2018-08-29 10:42:18'),
|
||||
(11,0.625290389,'2018-08-29 10:42:18'),
|
||||
(1,0.091823417,'2018-08-29 10:42:18'),
|
||||
(9,0.246651097,'2018-08-29 10:42:19'),
|
||||
(8,0.222901604,'2018-08-29 10:42:19'),
|
||||
(13,1.600367041,'2018-08-29 10:42:20'),
|
||||
(10,0.050076397,'2018-08-29 10:42:20'),
|
||||
(14,0.460363958,'2018-08-29 10:42:20'),
|
||||
(8,0.252590543,'2018-08-29 10:42:20'),
|
||||
(15,0.144109113,'2018-08-29 10:42:20'),
|
||||
(15,0.059993314,'2018-08-29 10:42:20'),
|
||||
(16,0.058810662,'2018-08-29 10:42:20'),
|
||||
(17,0.061824594,'2018-08-29 10:42:20'),
|
||||
(16,0.074584583,'2018-08-29 10:42:20'),
|
||||
(17,0.057086551,'2018-08-29 10:42:20'),
|
||||
(18,0.020983572,'2018-08-29 10:42:20'),
|
||||
(5,0.006504081,'2018-08-30 10:42:08'),
|
||||
(3,0.202164333,'2018-08-30 10:42:08'),
|
||||
(4,0.376675172,'2018-08-30 10:42:09'),
|
||||
(1,0.413912204,'2018-08-30 10:42:09'),
|
||||
(2,0.528427935,'2018-08-30 10:42:09'),
|
||||
(6,0.11930188,'2018-08-30 10:42:14'),
|
||||
(7,0.001062722,'2018-08-30 10:42:14'),
|
||||
(7,0.004046882,'2018-08-30 10:42:14'),
|
||||
(6,0.063360069,'2018-08-30 10:42:14'),
|
||||
(8,0.168951416,'2018-08-30 10:42:16'),
|
||||
(8,0.069032763,'2018-08-30 10:42:16'),
|
||||
(9,0.47712966,'2018-08-30 10:42:16'),
|
||||
(10,0.104510482,'2018-08-30 10:42:17'),
|
||||
(10,0.062536146,'2018-08-30 10:42:17'),
|
||||
(9,0.352823197,'2018-08-30 10:42:17'),
|
||||
(8,0.38226374,'2018-08-30 10:42:17'),
|
||||
(11,0.857324393,'2018-08-30 10:42:17'),
|
||||
(12,0.113320285,'2018-08-30 10:42:18'),
|
||||
(12,0.038532321,'2018-08-30 10:42:18'),
|
||||
(8,0.123430059,'2018-08-30 10:42:18'),
|
||||
(11,0.625290389,'2018-08-30 10:42:18'),
|
||||
(1,0.091823417,'2018-08-30 10:42:18'),
|
||||
(9,0.246651097,'2018-08-30 10:42:19'),
|
||||
(8,0.222901604,'2018-08-30 10:42:19'),
|
||||
(13,1.600367041,'2018-08-30 10:42:20'),
|
||||
(10,0.050076397,'2018-08-30 10:42:20'),
|
||||
(14,0.460363958,'2018-08-30 10:42:20'),
|
||||
(8,0.252590543,'2018-08-30 10:42:20'),
|
||||
(15,0.144109113,'2018-08-30 10:42:20'),
|
||||
(15,0.059993314,'2018-08-30 10:42:20'),
|
||||
(16,0.058810662,'2018-08-30 10:42:20'),
|
||||
(17,0.061824594,'2018-08-30 10:42:20'),
|
||||
(16,0.074584583,'2018-08-30 10:42:20'),
|
||||
(17,0.057086551,'2018-08-30 10:42:20'),
|
||||
(18,0.020983572,'2018-08-30 10:42:20'),
|
||||
(5,0.006504081,'2018-08-31 10:42:08'),
|
||||
(3,0.202164333,'2018-08-31 10:42:08'),
|
||||
(4,0.376675172,'2018-08-31 10:42:09'),
|
||||
(1,0.413912204,'2018-08-31 10:42:09'),
|
||||
(2,0.528427935,'2018-08-31 10:42:09'),
|
||||
(6,0.11930188,'2018-08-31 10:42:14'),
|
||||
(7,0.001062722,'2018-08-31 10:42:14'),
|
||||
(7,0.004046882,'2018-08-31 10:42:14'),
|
||||
(6,0.063360069,'2018-08-31 10:42:14'),
|
||||
(8,0.168951416,'2018-08-31 10:42:16'),
|
||||
(8,0.069032763,'2018-08-31 10:42:16'),
|
||||
(9,0.47712966,'2018-08-31 10:42:16'),
|
||||
(10,0.104510482,'2018-08-31 10:42:17'),
|
||||
(10,0.062536146,'2018-08-31 10:42:17'),
|
||||
(9,0.352823197,'2018-08-31 10:42:17'),
|
||||
(8,0.38226374,'2018-08-31 10:42:17'),
|
||||
(11,0.857324393,'2018-08-31 10:42:17'),
|
||||
(12,0.113320285,'2018-08-31 10:42:18'),
|
||||
(12,0.038532321,'2018-08-31 10:42:18'),
|
||||
(8,0.123430059,'2018-08-31 10:42:18'),
|
||||
(11,0.625290389,'2018-08-31 10:42:18'),
|
||||
(1,0.091823417,'2018-08-31 10:42:18'),
|
||||
(9,0.246651097,'2018-08-31 10:42:19'),
|
||||
(8,0.222901604,'2018-08-31 10:42:19'),
|
||||
(13,1.600367041,'2018-08-31 10:42:20'),
|
||||
(10,0.050076397,'2018-08-31 10:42:20'),
|
||||
(14,0.460363958,'2018-08-31 10:42:20'),
|
||||
(8,0.252590543,'2018-08-31 10:42:20'),
|
||||
(15,0.144109113,'2018-08-31 10:42:20'),
|
||||
(15,0.059993314,'2018-08-31 10:42:20'),
|
||||
(16,0.058810662,'2018-08-31 10:42:20'),
|
||||
(17,0.061824594,'2018-08-31 10:42:20'),
|
||||
(16,0.074584583,'2018-08-31 10:42:20'),
|
||||
(17,0.057086551,'2018-08-31 10:42:20'),
|
||||
(18,0.020983572,'2018-08-31 10:42:20');
|
||||
INSERT INTO failures (issue,method,service,created_at) VALUES
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-28 10:42:14'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-28 10:42:14'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-29 10:42:14'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-30 10:42:14'),
|
||||
('Incorrect Response','',1,'2018-08-31 10:40:14'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14'),
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-31 10:42:14');
|
||||
INSERT INTO communication (id,method,host,port,username,password,var1,var2,api_key,api_secret,enabled,removable,limits,created_at) VALUES
|
||||
(1,'email','smtp.emailer.com',587,'exampleuser','password123','info@betatude.com','sendto@gmail.com','','',1,0,7,'2018-08-31 10:42:15'),
|
||||
(2,'slack','https://webhooksurl.slack.com/***',0,'','','','','','',0,0,3,'2018-08-31 10:42:08'),
|
||||
(3,'twilio','',0,'','','','','','',0,0,3,'2018-08-31 10:42:08');
|
|
@ -0,0 +1,142 @@
|
|||
INSERT INTO core (name,description,config,api_key,api_secret,style,footer,domain,version,migration_id,use_cdn) VALUES ('Awesome Status','This is from the seed file!','config.yml','d2fead3e459bd14f570cf08527175b88b32d7faa','e351393306ea245de5f9588cbe8627c74db007c6','','Created by Hunter Long','DEV','',0,false);
|
||||
INSERT INTO services (name,domain,check_type,method,port,expected,expected_status,check_interval,post_data,order_id,timeout,created_at) VALUES
|
||||
('Google','https://google.com','http','GET',0,'',200,10,'',0,10,'2018-08-31 10:42:08.76390584-07:00'),
|
||||
('Statup Github','https://github.com/hunterlong/statup','http','GET',0,'',200,30,'',0,20,'2018-08-31 10:42:08.764977938-07:00'),
|
||||
('JSON Users Test','https://jsonplaceholder.typicode.com/users','http','GET',0,'',200,60,'',0,30,'2018-08-31 10:42:08.765794226-07:00'),
|
||||
('JSON API Tester','https://jsonplaceholder.typicode.com/posts','http','POST',0,'(title)": "((\\"|[statup])*)"',201,30,'{ "title": "statup", "body": "bar", "userId": 19999 }',0,30,'2018-08-31 10:42:08.766542311-07:00'),
|
||||
('Google DNS','8.8.8.8','tcp','',53,'',0,20,'',0,120,'2018-08-31 10:42:08.767327346-07:00'),
|
||||
('The Bravery - An Honest Mistake','https://www.youtube.com/watch?v=O8vzbezVru4','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14.201305666-07:00'),
|
||||
('Upper.io','https://upper.io/db.v3/','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14.201305666-07:00'),
|
||||
('CoinApp Status','https://status.coinapp.io','http','GET',0,'',200,1,'',0,30,'2018-08-31 10:42:16.097416218-07:00'),
|
||||
('Demo Page','https://demo.statup.io','http','GET',0,'',200,2,'',0,30,'2018-08-31 10:42:16.360051225-07:00'),
|
||||
('Golang','https://golang.org','http','GET',0,'',200,3,'',0,30,'2018-08-31 10:42:16.923478722-07:00'),
|
||||
('Github','https://github.com/hunterlong','http','GET',0,'',200,4,'',0,30,'2018-08-31 10:42:17.075544885-07:00'),
|
||||
('Santa Monica','https://www.santamonica.com','http','GET',0,'',200,5,'',0,30,'2018-08-31 10:42:17.946947674-07:00'),
|
||||
('Oeschs Die Dritten','https://www.oeschs-die-dritten.ch/en/','http','GET',0,'',200,6,'',0,30,'2018-08-31 10:42:18.083709297-07:00'),
|
||||
('EtherScan.io','https://etherscan.io','http','GET',0,'',200,7,'',0,30,'2018-08-31 10:42:20.020969513-07:00'),
|
||||
('Test Service 7','https://www.youtube.com/watch?v=ipvEIZMMILA','http','GET',0,'',200,8,'',0,30,'2018-08-31 10:42:20.50135711-07:00'),
|
||||
('Test Service 8','https://www.youtube.com/watch?v=UdaYVxYF1Ok','http','GET',0,'',200,9,'',0,30,'2018-08-31 10:42:20.651218082-07:00'),
|
||||
('Test Service 9','https://www.youtube.com/watch?v=yydZbVoCbn0&t=870s','http','GET',0,'',200,10,'',0,30,'2018-08-31 10:42:20.725479695-07:00'),
|
||||
('Failing URL','http://failingdomainsarenofunatall.com','http','GET',0,'',200,11,'',0,30,'2018-08-31 10:42:20.799471402-07:00');
|
||||
INSERT INTO users (username,password,email,api_key,api_secret,administrator,created_at) VALUES
|
||||
('admin','$2a$14$Aye3yHae0ml6WRtvdgkRnO19OFze0IKF6IOHrdLpETtwLjnPelMUm','info@statup.io','27aa701119fb561d734eb4469cf13ba2550007e2','29de07014d32fbbbb80053ef3c19b464b2b72f64',true,'2018-08-31 10:42:07.684406458-07:00');
|
||||
INSERT INTO hits (service,latency,created_at) VALUES
|
||||
(5,0.006504081,'2018-08-29 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-29 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-29 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-29 10:42:09.188850317-07:00'),
|
||||
(1,0.473912204,'2018-08-29 10:42:10.118850317-07:00'),
|
||||
(2,0.528427935,'2018-08-29 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-29 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-29 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-29 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-29 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-29 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-29 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-29 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-29 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-29 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-29 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-29 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-29 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-29 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-29 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-29 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-29 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-29 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-29 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-29 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-29 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-29 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-29 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-29 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-29 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-29 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-29 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-29 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-29 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-29 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-29 10:42:20.864610424-07:00'),
|
||||
(5,0.006504081,'2018-08-30 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-30 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-30 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-30 10:42:09.188850317-07:00'),
|
||||
(2,0.528427935,'2018-08-30 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-30 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-30 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-30 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-30 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-30 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-30 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-30 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-30 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-30 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-30 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-30 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-30 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-30 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-30 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-30 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-30 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-30 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-30 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-30 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-30 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-30 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-30 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-30 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-30 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-30 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-30 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-30 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-30 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-30 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-30 10:42:20.864610424-07:00'),
|
||||
(5,0.006504081,'2018-08-31 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-31 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-31 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-31 10:42:09.188850317-07:00'),
|
||||
(2,0.528427935,'2018-08-31 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-31 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-31 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-31 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-31 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-31 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-31 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-31 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-31 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-31 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-31 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-31 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-31 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-31 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-31 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-31 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-31 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-31 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-31 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-31 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-31 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-31 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-31 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-31 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-31 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-31 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-31 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-31 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-31 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-31 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-31 10:42:20.864610424-07:00');
|
||||
INSERT INTO failures (issue,method,service,created_at) VALUES
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-28 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-28 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-29 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-30 10:42:14.271162743-07:00'),
|
||||
('Incorrect Response','',1,'2018-08-31 10:40:14.272209564-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14.272209564-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-31 10:42:14.271162743-07:00');
|
||||
INSERT INTO communication (id,method,host,port,username,password,var1,var2,api_key,api_secret,enabled,removable,limits,created_at) VALUES
|
||||
(1,'email','smtp.emailer.com',587,'exampleuser','password123','info@betatude.com','sendto@gmail.com','','',true,false,7,'2018-08-31 10:42:15.000829706-07:00'),
|
||||
(2,'slack','https://webhooksurl.slack.com/***',0,'','','','','','',false,false,3,'2018-08-31 10:42:08.775366824-07:00'),
|
||||
(3,'twilio','',0,'','','','','','',false,false,3,'2018-08-31 10:42:08.776944923-07:00');
|
|
@ -0,0 +1,142 @@
|
|||
INSERT INTO core (name,description,config,api_key,api_secret,style,footer,domain,version,migration_id,use_cdn) VALUES ('Awesome Status','This is from the seed file!','config.yml','d2fead3e459bd14f570cf08527175b88b32d7faa','e351393306ea245de5f9588cbe8627c74db007c6','','Created by Hunter Long','','',0,0);
|
||||
INSERT INTO services (id,name,domain,check_type,method,port,expected,expected_status,check_interval,post_data,order_id,timeout,created_at) VALUES
|
||||
(1,'Google','https://google.com','http','GET',0,'',200,10,'',0,10,'2018-08-31 10:42:08.76390584-07:00'),
|
||||
(2,'Statup Github','https://github.com/hunterlong/statup','http','GET',0,'',200,30,'',0,20,'2018-08-31 10:42:08.764977938-07:00'),
|
||||
(3,'JSON Users Test','https://jsonplaceholder.typicode.com/users','http','GET',0,'',200,60,'',0,30,'2018-08-31 10:42:08.765794226-07:00'),
|
||||
(4,'JSON API Tester','https://jsonplaceholder.typicode.com/posts','http','POST',0,'(title)": "((\\"|[statup])*)"',201,30,'{ "title": "statup", "body": "bar", "userId": 19999 }',0,30,'2018-08-31 10:42:08.766542311-07:00'),
|
||||
(5,'Google DNS','8.8.8.8','tcp','',53,'',0,20,'',0,120,'2018-08-31 10:42:08.767327346-07:00'),
|
||||
(6,'The Bravery - An Honest Mistake','https://www.youtube.com/watch?v=O8vzbezVru4','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14.201305666-07:00'),
|
||||
(7,'Upper.io','https://upper.io/db.v3/','http','GET',0,'',0,30,'',0,15,'2018-08-31 10:42:14.201305666-07:00'),
|
||||
(8,'CoinApp Status','https://status.coinapp.io','http','GET',0,'',200,1,'',0,30,'2018-08-31 10:42:16.097416218-07:00'),
|
||||
(9,'Demo Page','https://demo.statup.io','http','GET',0,'',200,2,'',0,30,'2018-08-31 10:42:16.360051225-07:00'),
|
||||
(10,'Golang','https://golang.org','http','GET',0,'',200,3,'',0,30,'2018-08-31 10:42:16.923478722-07:00'),
|
||||
(11,'Github','https://github.com/hunterlong','http','GET',0,'',200,4,'',0,30,'2018-08-31 10:42:17.075544885-07:00'),
|
||||
(12,'Santa Monica','https://www.santamonica.com','http','GET',0,'',200,5,'',0,30,'2018-08-31 10:42:17.946947674-07:00'),
|
||||
(13,'Oeschs Die Dritten','https://www.oeschs-die-dritten.ch/en/','http','GET',0,'',200,6,'',0,30,'2018-08-31 10:42:18.083709297-07:00'),
|
||||
(14,'EtherScan.io','https://etherscan.io','http','GET',0,'',200,7,'',0,30,'2018-08-31 10:42:20.020969513-07:00'),
|
||||
(15,'Test Service 7','https://www.youtube.com/watch?v=ipvEIZMMILA','http','GET',0,'',200,8,'',0,30,'2018-08-31 10:42:20.50135711-07:00'),
|
||||
(16,'Test Service 8','https://www.youtube.com/watch?v=UdaYVxYF1Ok','http','GET',0,'',200,9,'',0,30,'2018-08-31 10:42:20.651218082-07:00'),
|
||||
(17,'Test Service 9','https://www.youtube.com/watch?v=yydZbVoCbn0&t=870s','http','GET',0,'',200,10,'',0,30,'2018-08-31 10:42:20.725479695-07:00'),
|
||||
(18,'Failing URL','http://failingdomainsarenofunatall.com','http','GET',0,'',200,11,'',0,30,'2018-08-31 10:42:20.799471402-07:00');
|
||||
INSERT INTO users (username,password,email,api_key,api_secret,administrator,created_at) VALUES
|
||||
('admin','$2a$14$Aye3yHae0ml6WRtvdgkRnO19OFze0IKF6IOHrdLpETtwLjnPelMUm','info@statup.io','27aa701119fb561d734eb4469cf13ba2550007e2','29de07014d32fbbbb80053ef3c19b464b2b72f64',1,'2018-08-31 10:42:07.684406458-07:00');
|
||||
INSERT INTO hits (service,latency,created_at) VALUES
|
||||
(5,0.006504081,'2018-08-29 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-29 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-29 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-29 10:42:09.188850317-07:00'),
|
||||
(1,0.473912204,'2018-08-29 10:42:10.118850317-07:00'),
|
||||
(2,0.528427935,'2018-08-29 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-29 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-29 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-29 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-29 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-29 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-29 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-29 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-29 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-29 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-29 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-29 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-29 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-29 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-29 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-29 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-29 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-29 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-29 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-29 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-29 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-29 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-29 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-29 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-29 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-29 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-29 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-29 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-29 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-29 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-29 10:42:20.864610424-07:00'),
|
||||
(5,0.006504081,'2018-08-30 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-30 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-30 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-30 10:42:09.188850317-07:00'),
|
||||
(2,0.528427935,'2018-08-30 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-30 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-30 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-30 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-30 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-30 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-30 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-30 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-30 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-30 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-30 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-30 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-30 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-30 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-30 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-30 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-30 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-30 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-30 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-30 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-30 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-30 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-30 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-30 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-30 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-30 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-30 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-30 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-30 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-30 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-30 10:42:20.864610424-07:00'),
|
||||
(5,0.006504081,'2018-08-31 10:42:08.779875117-07:00'),
|
||||
(3,0.202164333,'2018-08-31 10:42:08.977187173-07:00'),
|
||||
(4,0.376675172,'2018-08-31 10:42:09.151858662-07:00'),
|
||||
(1,0.413912204,'2018-08-31 10:42:09.188850317-07:00'),
|
||||
(2,0.528427935,'2018-08-31 10:42:09.310642068-07:00'),
|
||||
(6,0.11930188,'2018-08-31 10:42:14.133392018-07:00'),
|
||||
(7,0.001062722,'2018-08-31 10:42:14.148258553-07:00'),
|
||||
(7,0.004046882,'2018-08-31 10:42:14.156087817-07:00'),
|
||||
(6,0.063360069,'2018-08-31 10:42:14.205383358-07:00'),
|
||||
(8,0.168951416,'2018-08-31 10:42:16.346340211-07:00'),
|
||||
(8,0.069032763,'2018-08-31 10:42:16.421634189-07:00'),
|
||||
(9,0.47712966,'2018-08-31 10:42:16.91309317-07:00'),
|
||||
(10,0.104510482,'2018-08-31 10:42:17.065673146-07:00'),
|
||||
(10,0.062536146,'2018-08-31 10:42:17.134754949-07:00'),
|
||||
(9,0.352823197,'2018-08-31 10:42:17.272174866-07:00'),
|
||||
(8,0.38226374,'2018-08-31 10:42:17.738731999-07:00'),
|
||||
(11,0.857324393,'2018-08-31 10:42:17.939738264-07:00'),
|
||||
(12,0.113320285,'2018-08-31 10:42:18.073586363-07:00'),
|
||||
(12,0.038532321,'2018-08-31 10:42:18.119730063-07:00'),
|
||||
(8,0.123430059,'2018-08-31 10:42:18.479407581-07:00'),
|
||||
(11,0.625290389,'2018-08-31 10:42:18.5715553-07:00'),
|
||||
(1,0.091823417,'2018-08-31 10:42:18.868788983-07:00'),
|
||||
(9,0.246651097,'2018-08-31 10:42:19.165697332-07:00'),
|
||||
(8,0.222901604,'2018-08-31 10:42:19.57929225-07:00'),
|
||||
(13,1.600367041,'2018-08-31 10:42:20.010203546-07:00'),
|
||||
(10,0.050076397,'2018-08-31 10:42:20.12391038-07:00'),
|
||||
(14,0.460363958,'2018-08-31 10:42:20.495937751-07:00'),
|
||||
(8,0.252590543,'2018-08-31 10:42:20.609139136-07:00'),
|
||||
(15,0.144109113,'2018-08-31 10:42:20.64756516-07:00'),
|
||||
(15,0.059993314,'2018-08-31 10:42:20.710322678-07:00'),
|
||||
(16,0.058810662,'2018-08-31 10:42:20.712087274-07:00'),
|
||||
(17,0.061824594,'2018-08-31 10:42:20.791266761-07:00'),
|
||||
(16,0.074584583,'2018-08-31 10:42:20.797581163-07:00'),
|
||||
(17,0.057086551,'2018-08-31 10:42:20.854020864-07:00'),
|
||||
(18,0.020983572,'2018-08-31 10:42:20.864610424-07:00');
|
||||
INSERT INTO failures (issue,method,service,created_at) VALUES
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-28 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-28 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-29 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-30 10:42:14.271162743-07:00'),
|
||||
('Incorrect Response','',1,'2018-08-31 10:40:14.272209564-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14.271162743-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',6,'2018-08-31 10:42:14.272209564-07:00'),
|
||||
('HTTP Status Code 200 did not match 0','',18,'2018-08-31 10:42:14.271162743-07:00');
|
||||
INSERT INTO communication (id,method,host,port,username,password,var1,var2,api_key,api_secret,enabled,removable,limits,created_at) VALUES
|
||||
(1,'email','smtp.emailer.com',587,'exampleuser','password123','info@betatude.com','sendto@gmail.com','','',1,0,7,'2018-08-31 10:42:15.000829706-07:00'),
|
||||
(2,'slack','https://webhooksurl.slack.com/***',0,'','','','','','',0,0,3,'2018-08-31 10:42:08.775366824-07:00'),
|
||||
(3,'twilio','',0,'','','','','','',0,0,3,'2018-08-31 10:42:08.776944923-07:00');
|
|
@ -36,17 +36,23 @@ const (
|
|||
|
||||
func injectDatabase() {
|
||||
core.NewCore()
|
||||
core.Configs = new(types.Config)
|
||||
core.Configs.Connection = "sqlite"
|
||||
core.Configs = new(core.DbConfig)
|
||||
core.Configs.DbConn = "sqlite"
|
||||
core.CoreApp.DbConnection = "sqlite"
|
||||
core.CoreApp.Version = "DEV"
|
||||
core.DbConnection("sqlite", false, utils.Directory)
|
||||
core.Configs.Connect(false, utils.Directory)
|
||||
core.InitApp()
|
||||
}
|
||||
|
||||
func Clean() {
|
||||
utils.DeleteFile(dir + "/config.yml")
|
||||
utils.DeleteFile(dir + "/statup.db")
|
||||
utils.DeleteDirectory(dir + "/assets")
|
||||
utils.DeleteDirectory(dir + "/logs")
|
||||
}
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
t.SkipNow()
|
||||
injectDatabase()
|
||||
Clean()
|
||||
}
|
||||
|
||||
func formatJSON(res string, out interface{}) {
|
||||
|
|
|
@ -97,6 +97,8 @@ func TestProcessSetupHandler(t *testing.T) {
|
|||
rr := httptest.NewRecorder()
|
||||
Router().ServeHTTP(rr, req)
|
||||
assert.Equal(t, 303, rr.Code)
|
||||
assert.FileExists(t, dir+"/config.yml")
|
||||
assert.FileExists(t, dir+"/statup.db")
|
||||
}
|
||||
|
||||
func TestCheckSetupHandler(t *testing.T) {
|
||||
|
@ -143,7 +145,9 @@ func TestServiceChartHandler(t *testing.T) {
|
|||
assert.Equal(t, 200, rr.Code)
|
||||
t.Log(body)
|
||||
assert.Contains(t, body, "var ctx_1")
|
||||
assert.Contains(t, body, "var ctx_2")
|
||||
assert.Contains(t, body, "var ctx_3")
|
||||
assert.Contains(t, body, "var ctx_4")
|
||||
assert.Contains(t, body, "var ctx_5")
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ type index struct {
|
|||
}
|
||||
|
||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if core.CoreApp.DbConnection == "" {
|
||||
if core.Configs == nil {
|
||||
http.Redirect(w, r, "/setup", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ func DesktopInit(ip string, port int) {
|
|||
var err error
|
||||
exists := utils.FileExists(utils.Directory + "/statup.db")
|
||||
if exists {
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return
|
||||
}
|
||||
err = core.DbConnection(core.Configs.Connection, false, utils.Directory)
|
||||
err = core.Configs.Connect(false, utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return
|
||||
|
@ -68,24 +68,28 @@ func DesktopInit(ip string, port int) {
|
|||
Location: utils.Directory,
|
||||
}}
|
||||
|
||||
err = config.Save()
|
||||
config, err = config.Save()
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
}
|
||||
|
||||
config.DropDatabase()
|
||||
config.CreateDatabase()
|
||||
core.CoreApp = config.CreateCore()
|
||||
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return
|
||||
}
|
||||
|
||||
core.Configs, err = core.LoadConfig()
|
||||
core.Configs, err = core.LoadConfig(utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
config.Error = err
|
||||
return
|
||||
}
|
||||
|
||||
err = core.DbConnection(core.Configs.Connection, false, utils.Directory)
|
||||
err = core.Configs.Connect(false, utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
core.DeleteConfig()
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/hunterlong/statup/core"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
@ -53,6 +52,6 @@ func PluginsDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
//vars := mux.Vars(router)
|
||||
//name := vars["name"]
|
||||
//DownloadPlugin(name)
|
||||
core.LoadConfig()
|
||||
//core.LoadConfig(utils.Directory)
|
||||
http.Redirect(w, r, "/plugins", http.StatusSeeOther)
|
||||
}
|
||||
|
|
|
@ -61,13 +61,6 @@ func PrometheusHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte(output))
|
||||
}
|
||||
|
||||
func ResetDbHandler(w http.ResponseWriter, r *http.Request) {
|
||||
utils.Log(1, fmt.Sprintf("Prometheus /metrics Request From IP: %v\n", r.RemoteAddr))
|
||||
core.DropDatabase()
|
||||
core.CoreApp = nil
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func isAuthorized(r *http.Request) bool {
|
||||
var token string
|
||||
tokens, ok := r.Header["Authorization"]
|
||||
|
|
|
@ -51,7 +51,6 @@ func Router() *mux.Router {
|
|||
r.Handle("/setup", http.HandlerFunc(SetupHandler)).Methods("GET")
|
||||
r.Handle("/setup", http.HandlerFunc(ProcessSetupHandler)).Methods("POST")
|
||||
r.Handle("/dashboard", http.HandlerFunc(DashboardHandler)).Methods("GET")
|
||||
//r.Handle("/backups/create", http.HandlerFunc(BackupCreateHandler)).Methods("GET")
|
||||
r.Handle("/dashboard", http.HandlerFunc(LoginHandler)).Methods("POST")
|
||||
r.Handle("/logout", http.HandlerFunc(LogoutHandler))
|
||||
r.Handle("/services", http.HandlerFunc(ServicesHandler)).Methods("GET")
|
||||
|
|
|
@ -60,8 +60,7 @@ func ReorderServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|||
decoder.Decode(&newOrder)
|
||||
for _, s := range newOrder {
|
||||
service := core.SelectService(s.Id)
|
||||
service.Order = s.Order
|
||||
service.Update(false)
|
||||
service.UpdateSingle("order_id", s.Order)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
|
@ -56,6 +55,7 @@ func SetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
if core.CoreApp.Services() != nil {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
|
@ -75,7 +75,9 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
domain := r.PostForm.Get("domain")
|
||||
email := r.PostForm.Get("email")
|
||||
|
||||
config := &core.DbConfig{&types.DbConfig{
|
||||
dir := utils.Directory
|
||||
|
||||
config := &core.DbConfig{DbConfig: &types.DbConfig{
|
||||
DbConn: dbConn,
|
||||
DbHost: dbHost,
|
||||
DbUser: dbUser,
|
||||
|
@ -92,13 +94,15 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Location: utils.Directory,
|
||||
}}
|
||||
|
||||
fmt.Println(config)
|
||||
|
||||
err := config.Save()
|
||||
core.Configs, err = config.Save()
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
config.Error = err
|
||||
SetupResponseError(w, r, config)
|
||||
return
|
||||
}
|
||||
|
||||
core.Configs, err = core.LoadConfig(dir)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
config.Error = err
|
||||
|
@ -106,23 +110,26 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
core.Configs, err = core.LoadConfig()
|
||||
err = core.Configs.Connect(false, dir)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
config.Error = err
|
||||
SetupResponseError(w, r, config)
|
||||
return
|
||||
}
|
||||
|
||||
err = core.DbConnection(core.Configs.Connection, false, utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
utils.Log(4, err)
|
||||
core.DeleteConfig()
|
||||
config.Error = err
|
||||
SetupResponseError(w, r, config)
|
||||
return
|
||||
}
|
||||
|
||||
config.DropDatabase()
|
||||
config.CreateDatabase()
|
||||
|
||||
core.CoreApp, err = config.InsertCore()
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
config.Error = err
|
||||
SetupResponseError(w, r, config)
|
||||
return
|
||||
}
|
||||
|
||||
admin := core.ReturnUser(&types.User{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
|
|
|
@ -215,7 +215,7 @@ func (u *Email) OnSave() error {
|
|||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) Install() error {
|
||||
inDb, err := emailer.Notification.IsInDatabase()
|
||||
inDb := emailer.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
|
@ -224,7 +224,7 @@ func (u *Email) Install() error {
|
|||
}
|
||||
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Email) dialSend(email *EmailOutgoing) error {
|
||||
|
|
|
@ -19,34 +19,34 @@ import (
|
|||
"fmt"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/jinzhu/gorm"
|
||||
"strings"
|
||||
"time"
|
||||
"upper.io/db.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
AllCommunications []types.AllNotifiers
|
||||
Collections db.Collection
|
||||
Collections *gorm.DB
|
||||
Logs []*NotificationLog
|
||||
)
|
||||
|
||||
type Notification struct {
|
||||
Id int64 `db:"id,omitempty" json:"id"`
|
||||
Method string `db:"method" json:"method"`
|
||||
Host string `db:"host" json:"-"`
|
||||
Port int `db:"port" json:"-"`
|
||||
Username string `db:"username" json:"-"`
|
||||
Password string `db:"password" json:"-"`
|
||||
Var1 string `db:"var1" json:"-"`
|
||||
Var2 string `db:"var2" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Limits int `db:"limits" json:"-"`
|
||||
Removable bool `db:"removable" json:"-"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
Form []NotificationForm
|
||||
Routine chan struct{}
|
||||
Id int64 `gorm:"primary_key column:id" json:"id"`
|
||||
Method string `gorm:"column:method" json:"method"`
|
||||
Host string `gorm:"column:host" json:"-"`
|
||||
Port int `gorm:"column:port" json:"-"`
|
||||
Username string `gorm:"column:username" json:"-"`
|
||||
Password string `gorm:"column:password" json:"-"`
|
||||
Var1 string `gorm:"column:var1" json:"-"`
|
||||
Var2 string `gorm:"column:var2" json:"-"`
|
||||
ApiKey string `gorm:"column:api_key" json:"-"`
|
||||
ApiSecret string `gorm:"column:api_secret" json:"-"`
|
||||
Enabled bool `gorm:"column:enabled" json:"enabled"`
|
||||
Limits int `gorm:"column:limits" json:"-"`
|
||||
Removable bool `gorm:"column:removable" json:"-"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
Form []NotificationForm `gorm:"-" json:"-"`
|
||||
Routine chan struct{} `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
type Notifier interface {
|
||||
|
@ -115,30 +115,30 @@ func reverseLogs(input []*NotificationLog) []*NotificationLog {
|
|||
return append(reverseLogs(input[1:]), input[0])
|
||||
}
|
||||
|
||||
func (n *Notification) IsInDatabase() (bool, error) {
|
||||
return Collections.Find("id", n.Id).Exists()
|
||||
func (n *Notification) IsInDatabase() bool {
|
||||
return !Collections.Find(n).RecordNotFound()
|
||||
}
|
||||
|
||||
func SelectNotification(id int64) (*Notification, error) {
|
||||
var notifier *Notification
|
||||
err := Collections.Find("id", id).One(¬ifier)
|
||||
return notifier, err
|
||||
var notifier Notification
|
||||
err := Collections.Find(¬ifier, id)
|
||||
return ¬ifier, err.Error
|
||||
}
|
||||
|
||||
func (n *Notification) Update() (*Notification, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
err := Collections.Find("id", n.Id).Update(n)
|
||||
return n, err
|
||||
err := Collections.Update(n)
|
||||
return n, err.Error
|
||||
}
|
||||
|
||||
func InsertDatabase(n *Notification) (int64, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
n.Limits = 3
|
||||
newId, err := Collections.Insert(n)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
db := Collections.Create(n)
|
||||
if db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
return newId.(int64), err
|
||||
return n.Id, db.Error
|
||||
}
|
||||
|
||||
func SelectNotifier(id int64) Notifier {
|
||||
|
|
|
@ -18,10 +18,12 @@ package notifiers
|
|||
import (
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"upper.io/db.v3/sqlite"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -67,11 +69,8 @@ func init() {
|
|||
}
|
||||
|
||||
func injectDatabase() {
|
||||
sqliteDb := sqlite.ConnectionURL{
|
||||
Database: dir + "/statup.db",
|
||||
}
|
||||
dbSession, _ := sqlite.Open(sqliteDb)
|
||||
Collections = dbSession.Collection("communication")
|
||||
dbSession, _ := gorm.Open("sqlite3", dir+"/statup.db")
|
||||
Collections = dbSession.Table("communication").Model(&Notification{})
|
||||
}
|
||||
|
||||
type Tester struct {
|
||||
|
@ -100,8 +99,7 @@ func TestAdd(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIsInDatabase(t *testing.T) {
|
||||
in, err := testNotifier.IsInDatabase()
|
||||
assert.Nil(t, err)
|
||||
in := testNotifier.IsInDatabase()
|
||||
assert.False(t, in)
|
||||
}
|
||||
|
||||
|
@ -110,8 +108,7 @@ func TestInsertDatabase(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.NotZero(t, newId)
|
||||
|
||||
in, err := testNotifier.IsInDatabase()
|
||||
assert.Nil(t, err)
|
||||
in := testNotifier.IsInDatabase()
|
||||
assert.True(t, in)
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ func (u *Slack) OnSave() error {
|
|||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Slack) Install() error {
|
||||
inDb, err := slacker.Notification.IsInDatabase()
|
||||
inDb := slacker.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
|
@ -174,5 +174,5 @@ func (u *Slack) Install() error {
|
|||
}
|
||||
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ func (u *Twilio) OnSave() error {
|
|||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Twilio) Install() error {
|
||||
inDb, err := twilio.Notification.IsInDatabase()
|
||||
inDb := twilio.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
|
@ -188,5 +188,5 @@ func (u *Twilio) Install() error {
|
|||
}
|
||||
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@ DROP TABLE IF EXISTS failures;
|
|||
DROP TABLE IF EXISTS users;
|
||||
DROP TABLE IF EXISTS checkins;
|
||||
DROP TABLE IF EXISTS services;
|
||||
DROP TABLE IF EXISTS communication;
|
||||
DROP TABLE IF EXISTS communication;
|
||||
|
|
|
@ -10,21 +10,20 @@ CREATE TABLE core (
|
|||
version VARCHAR(50),
|
||||
migration_id INT(6) NOT NULL DEFAULT 0,
|
||||
use_cdn BOOL NOT NULL DEFAULT '0'
|
||||
);
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE users (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password text,
|
||||
email VARCHAR (50),
|
||||
api_key VARCHAR(50),
|
||||
api_secret VARCHAR(50),
|
||||
administrator BOOL NOT NULL DEFAULT '0',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX (id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (username, email)
|
||||
);
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE services (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
name VARCHAR(50),
|
||||
domain text,
|
||||
check_type text,
|
||||
|
@ -35,38 +34,34 @@ CREATE TABLE services (
|
|||
check_interval int(11),
|
||||
post_data text,
|
||||
order_id integer default 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
timeout INT(6) DEFAULT 30,
|
||||
INDEX (id)
|
||||
);
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
timeout INT(6) DEFAULT 30
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE hits (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
service INTEGER NOT NULL,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
latency float,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE failures (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE checkins (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
service INTEGER NOT NULL,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at DATETIME,
|
||||
INDEX (id, service),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
);
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE communication (
|
||||
id SERIAL PRIMARY KEY,
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
method text,
|
||||
host text,
|
||||
port integer,
|
||||
|
@ -79,5 +74,5 @@ CREATE TABLE communication (
|
|||
enabled BOOL NOT NULL DEFAULT '0',
|
||||
removable BOOL NOT NULL DEFAULT '0',
|
||||
limits integer,
|
||||
created_at DATETIME
|
||||
);
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=INNODB;
|
||||
|
|
|
@ -11,21 +11,19 @@ CREATE TABLE core (
|
|||
migration_id integer default 0,
|
||||
use_cdn bool default false
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
username text NOT NULL UNIQUE,
|
||||
password text,
|
||||
email text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
created_at DATETIME,
|
||||
created_at TIMESTAMP,
|
||||
UNIQUE (username, email)
|
||||
);
|
||||
|
||||
CREATE TABLE services (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
name text,
|
||||
domain text,
|
||||
check_type text,
|
||||
|
@ -37,34 +35,34 @@ CREATE TABLE services (
|
|||
post_data text,
|
||||
order_id integer default 0,
|
||||
timeout integer default 30,
|
||||
created_at DATETIME
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE hits (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
latency float,
|
||||
created_at DATETIME
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE failures (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
created_at DATETIME
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE checkins (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at DATETIME
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE communication (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
id INTEGER PRIMARY KEY,
|
||||
method text,
|
||||
host text,
|
||||
port integer,
|
||||
|
@ -77,10 +75,10 @@ CREATE TABLE communication (
|
|||
enabled boolean,
|
||||
removable boolean,
|
||||
limits integer,
|
||||
created_at DATETIME
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
CREATE INDEX idx_hits ON hits(service);
|
||||
CREATE INDEX idx_failures ON failures(service);
|
||||
CREATE INDEX idx_checkins ON checkins(service);
|
||||
CREATE INDEX idx_checkins ON checkins(service);
|
||||
|
|
|
@ -73,14 +73,14 @@
|
|||
Average Response
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{.AvgUptime}}%</span>
|
||||
Total Uptime
|
||||
<span class="lg_number">{{.AvgUptime24}}%</span>
|
||||
Uptime last 24 Hours
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{ if .AvgTime }}
|
||||
{{ if .AvgUptime24 }}
|
||||
<div class="chart-container">
|
||||
<canvas id="service_{{ .Id }}"></canvas>
|
||||
</div>
|
||||
|
@ -127,4 +127,4 @@
|
|||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{.AvgUptime}}%</span>
|
||||
<span class="lg_number">{{.AvgUptime24}}%</span>
|
||||
Total Uptime
|
||||
</div>
|
||||
</div>
|
||||
|
@ -277,4 +277,4 @@
|
|||
{{end}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package types
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Checkin struct {
|
||||
Id int `db:"id,omitempty"`
|
||||
Service int64 `db:"service"`
|
||||
Interval int64 `db:"check_interval"`
|
||||
Api string `db:"api"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
Id int64 `gorm:"primary_key;column:id"`
|
||||
Service int64 `gorm:"index;column:service"`
|
||||
Interval int64 `gorm:"column:check_interval"`
|
||||
Api string `gorm:"column:api"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
Hits int64 `json:"hits"`
|
||||
Last time.Time `json:"last"`
|
||||
CheckinInterface `json:"-"`
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
package types
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Core struct {
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description,omitempty"`
|
||||
Config string `db:"config" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Style string `db:"style" json:"style,omitempty"`
|
||||
Footer string `db:"footer" json:"footer,omitempty"`
|
||||
Domain string `db:"domain" json:"domain,omitempty"`
|
||||
Version string `db:"version" json:"version"`
|
||||
MigrationId int64 `db:"migration_id" json:"migration_id,omitempty"`
|
||||
UseCdn bool `db:"use_cdn" json:"using_cdn,omitempty"`
|
||||
DbConnection string `json:"database"`
|
||||
Started time.Time `json:"started_on"`
|
||||
dbServices []*Service `json:"services,omitempty"`
|
||||
Plugins []Info `json:"-"`
|
||||
Repos []PluginJSON `json:"-"`
|
||||
AllPlugins []PluginActions `json:"-"`
|
||||
Communications []AllNotifiers `json:"-"`
|
||||
CoreInterface `json:"-"`
|
||||
Name string `gorm:"column:name" json:"name"`
|
||||
Description string `gorm:"column:description" json:"description,omitempty"`
|
||||
Config string `gorm:"column:config" json:"-"`
|
||||
ApiKey string `gorm:"column:api_key" json:"-"`
|
||||
ApiSecret string `gorm:"column:api_secret" json:"-"`
|
||||
Style string `gorm:"column:style" json:"style,omitempty"`
|
||||
Footer string `gorm:"column:footer" json:"footer,omitempty"`
|
||||
Domain string `gorm:"column:domain" json:"domain,omitempty"`
|
||||
Version string `gorm:"column:version" json:"version"`
|
||||
MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"`
|
||||
UseCdn bool `gorm:"column:use_cdn" json:"using_cdn,omitempty"`
|
||||
DbConnection string `gorm:"-" json:database"`
|
||||
Started time.Time `gorm:"-" json:started_on"`
|
||||
dbServices []*Service `gorm:"-" json:services,omitempty"`
|
||||
Plugins []Info `gorm:"-" json:-"`
|
||||
Repos []PluginJSON `gorm:"-" json:-"`
|
||||
AllPlugins []PluginActions `gorm:"-" json:-"`
|
||||
Communications []AllNotifiers `gorm:"-" json:-"`
|
||||
CoreInterface `gorm:"-" json:-"`
|
||||
}
|
||||
|
||||
func (c *Core) SetServices(s []*Service) {
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package types
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Failure struct {
|
||||
Id int `db:"id,omitempty" json:"id"`
|
||||
Issue string `db:"issue" json:"issue"`
|
||||
Method string `db:"method" json:"method,omitempty"`
|
||||
Service int64 `db:"service" json:"service_id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
FailureInterface `json:"-"`
|
||||
Id int64 `gorm:"primary_key;column:id" json:"id"`
|
||||
Issue string `gorm:"column:issue" json:"issue"`
|
||||
Method string `gorm:"column:method" json:"method,omitempty"`
|
||||
Service int64 `gorm:"index;column:service" json:"service_id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
FailureInterface `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
type FailureInterface interface {
|
||||
|
|
|
@ -20,33 +20,33 @@ import (
|
|||
)
|
||||
|
||||
type Service struct {
|
||||
Id int64 `db:"id,omitempty" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Domain string `db:"domain" json:"domain"`
|
||||
Expected string `db:"expected" json:"expected"`
|
||||
ExpectedStatus int `db:"expected_status" json:"expected_status"`
|
||||
Interval int `db:"check_interval" json:"check_interval"`
|
||||
Type string `db:"check_type" json:"type"`
|
||||
Method string `db:"method" json:"method"`
|
||||
PostData string `db:"post_data" json:"post_data"`
|
||||
Port int `db:"port" json:"port"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
Timeout int `db:"timeout" json:"timeout"`
|
||||
Order int `db:"order_id" json:"order_id"`
|
||||
Online bool `json:"online"`
|
||||
Latency float64 `json:"latency"`
|
||||
Online24Hours float32 `json:"24_hours_online"`
|
||||
AvgResponse string `json:"avg_response"`
|
||||
TotalUptime string `json:"uptime"`
|
||||
Failures []*Failure `json:"failures"`
|
||||
Checkins []*Checkin `json:"checkins"`
|
||||
Running chan bool `json:"-"`
|
||||
Checkpoint time.Time `json:"-"`
|
||||
LastResponse string `json:"-"`
|
||||
LastStatusCode int `json:"status_code"`
|
||||
LastOnline time.Time `json:"last_online"`
|
||||
DnsLookup float64 `json:"dns_lookup_time"`
|
||||
ServiceInterface `json:"-"`
|
||||
Id int64 `gorm:"primary_key;column:id" json:"id"`
|
||||
Name string `gorm:"column:name" json:"name"`
|
||||
Domain string `gorm:"column:domain" json:"domain"`
|
||||
Expected string `gorm:"column:expected" json:"expected"`
|
||||
ExpectedStatus int `gorm:"column:expected_status" json:"expected_status"`
|
||||
Interval int `gorm:"column:check_interval" json:"check_interval"`
|
||||
Type string `gorm:"column:check_type" json:"type"`
|
||||
Method string `gorm:"column:method" json:"method"`
|
||||
PostData string `gorm:"column:post_data" json:"post_data"`
|
||||
Port int `gorm:"column:port" json:"port"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
Timeout int `gorm:"column:timeout" json:"timeout"`
|
||||
Order int `gorm:"column:order_id" json:"order_id"`
|
||||
Online bool `gorm:"-" json:"online"`
|
||||
Latency float64 `gorm:"-" json:"latency"`
|
||||
Online24Hours float32 `gorm:"-" json:"24_hours_online"`
|
||||
AvgResponse string `gorm:"-" json:"avg_response"`
|
||||
TotalUptime string `gorm:"-" json:"uptime"`
|
||||
Failures []*Failure `gorm:"-" json:"failures"`
|
||||
Checkins []*Checkin `gorm:"-" json:"checkins"`
|
||||
Running chan bool `gorm:"-" json:"-"`
|
||||
Checkpoint time.Time `gorm:"-" json:"-"`
|
||||
LastResponse string `gorm:"-" json:"-"`
|
||||
LastStatusCode int `gorm:"-" json:"status_code"`
|
||||
LastOnline time.Time `gorm:"-" json:"last_online"`
|
||||
DnsLookup float64 `gorm:"-" json:"dns_lookup_time"`
|
||||
ServiceInterface `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
type ServiceInterface interface {
|
||||
|
@ -56,6 +56,7 @@ type ServiceInterface interface {
|
|||
Delete() error
|
||||
// Basic Method functions
|
||||
AvgTime() float64
|
||||
OnlineSince(time.Time) float32
|
||||
Online24() float32
|
||||
SmallText() string
|
||||
GraphData() string
|
||||
|
@ -65,13 +66,15 @@ type ServiceInterface interface {
|
|||
CreateFailure(*Failure) (int64, error)
|
||||
LimitedFailures() []*Failure
|
||||
AllFailures() []*Failure
|
||||
TotalFailuresSince(time.Time) (uint64, error)
|
||||
TotalFailures24() (uint64, error)
|
||||
TotalFailures() (uint64, error)
|
||||
TotalFailures24Hours() (uint64, error)
|
||||
DeleteFailures()
|
||||
// Hits functions (successful responses)
|
||||
CreateHit(*Hit) (int64, error)
|
||||
Hits() ([]*Hit, error)
|
||||
TotalHits() (uint64, error)
|
||||
TotalHitsSince(time.Time) (uint64, error)
|
||||
Sum() (float64, error)
|
||||
LimitedHits() ([]*Hit, error)
|
||||
SelectHitsGroupBy(string) ([]*Hit, error)
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
"time"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
||||
type PluginInfo struct {
|
||||
|
@ -41,7 +41,7 @@ type Info struct {
|
|||
type PluginActions interface {
|
||||
GetInfo() Info
|
||||
GetForm() string
|
||||
OnLoad(sqlbuilder.Database)
|
||||
OnLoad(db gorm.DB)
|
||||
SetInfo(map[string]interface{}) Info
|
||||
Routes() []Routing
|
||||
OnSave(map[string]interface{})
|
||||
|
@ -62,20 +62,10 @@ type PluginActions interface {
|
|||
type AllNotifiers interface{}
|
||||
|
||||
type Hit struct {
|
||||
Id int `db:"id,omitempty"`
|
||||
Service int64 `db:"service"`
|
||||
Latency float64 `db:"latency"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Connection string `yaml:"connection"`
|
||||
Host string `yaml:"host"`
|
||||
Database string `yaml:"database"`
|
||||
User string `yaml:"user"`
|
||||
Password string `yaml:"password"`
|
||||
Port string `yaml:"port"`
|
||||
Secret string `yaml:"secret"`
|
||||
Id int64 `gorm:"primary_key;column:id"`
|
||||
Service int64 `gorm:"index;column:service"`
|
||||
Latency float64 `gorm:"column:latency"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
}
|
||||
|
||||
type DbConfig struct {
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package types
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int64 `db:"id,omitempty" json:"id"`
|
||||
Username string `db:"username" json:"username"`
|
||||
Password string `db:"password" json:"-"`
|
||||
Email string `db:"email" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"api_key"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Admin bool `db:"administrator" json:"admin"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UserInterface `json:"-"`
|
||||
Id int64 `gorm:"primary_key;column:id" json:"id"`
|
||||
Username string `gorm:"type:varchar(100);unique;column:username;" json:"username"`
|
||||
Password string `gorm:"column:password" json:"-"`
|
||||
Email string `gorm:"type:varchar(100);unique;column:email" json:"-"`
|
||||
ApiKey string `gorm:"column:api_key" json:"api_key"`
|
||||
ApiSecret string `gorm:"column:api_secret" json:"-"`
|
||||
Admin bool `gorm:"column:administrator" json:"admin"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UserInterface `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
type UserInterface interface {
|
||||
|
|
|
@ -34,6 +34,10 @@ var (
|
|||
LockLines sync.Mutex
|
||||
)
|
||||
|
||||
func Logger() *lumberjack.Logger {
|
||||
return ljLogger
|
||||
}
|
||||
|
||||
func createLog(dir string) error {
|
||||
var err error
|
||||
_, err = os.Stat(dir + "/logs")
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/ararog/timeago"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -97,6 +100,7 @@ func FileExists(name string) bool {
|
|||
}
|
||||
|
||||
func DeleteFile(file string) error {
|
||||
Log(1, "deleting file: "+file)
|
||||
err := os.Remove(file)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -107,3 +111,56 @@ func DeleteFile(file string) error {
|
|||
func DeleteDirectory(directory string) error {
|
||||
return os.RemoveAll(directory)
|
||||
}
|
||||
|
||||
func Command(cmd string) (string, string, error) {
|
||||
Log(1, "running command: "+cmd)
|
||||
testCmd := exec.Command("sh", "-c", cmd)
|
||||
var stdout, stderr []byte
|
||||
var errStdout, errStderr error
|
||||
stdoutIn, _ := testCmd.StdoutPipe()
|
||||
stderrIn, _ := testCmd.StderrPipe()
|
||||
testCmd.Start()
|
||||
|
||||
go func() {
|
||||
stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
stderr, errStderr = copyAndCapture(os.Stderr, stderrIn)
|
||||
}()
|
||||
|
||||
err := testCmd.Wait()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if errStdout != nil || errStderr != nil {
|
||||
return "", "", errors.New("failed to capture stdout or stderr")
|
||||
}
|
||||
|
||||
outStr, errStr := string(stdout), string(stderr)
|
||||
return outStr, errStr, err
|
||||
}
|
||||
|
||||
func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) {
|
||||
var out []byte
|
||||
buf := make([]byte, 1024, 1024)
|
||||
for {
|
||||
n, err := r.Read(buf[:])
|
||||
if n > 0 {
|
||||
d := buf[:n]
|
||||
out = append(out, d...)
|
||||
_, err := w.Write(d)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
// Read returns io.EOF at the end of file, which is not an error for us
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue