mirror of https://github.com/statping/statping
removed sql files - db updates - migrations - beginning to comment on funcs
parent
1eb55a0c71
commit
3f056125ae
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.53
|
||||
VERSION=0.54
|
||||
BINARY_NAME=statup
|
||||
GOPATH:=$(GOPATH)
|
||||
GOCMD=go
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -240,14 +239,6 @@ func FakeSeed(plug types.PluginActions) {
|
|||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
up, _ := source.SqlBox.String("sqlite_up.sql")
|
||||
requests := strings.Split(up, ";")
|
||||
for _, request := range requests {
|
||||
db := core.DbSession.Exec(request)
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Finished creating Test SQLite database")
|
||||
fmt.Println("Inserting example services into test database...")
|
||||
|
|
|
@ -101,7 +101,7 @@ func mainProcess() {
|
|||
if err != nil {
|
||||
utils.Log(4, fmt.Sprintf("could not connect to database: %v", err))
|
||||
}
|
||||
core.RunDatabaseUpgrades()
|
||||
core.Configs.MigrateDatabase()
|
||||
core.InitApp()
|
||||
if !core.SetupMode {
|
||||
LoadPlugins(false)
|
||||
|
|
|
@ -101,7 +101,6 @@ func TestRunAll(t *testing.T) {
|
|||
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) {
|
||||
|
@ -251,13 +250,8 @@ func RunCreateSchema(t *testing.T, db string) {
|
|||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunConnectDatabase(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunDatabaseMigrations(t *testing.T, db string) {
|
||||
err := core.RunDatabaseUpgrades()
|
||||
err := core.Configs.MigrateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
|
@ -493,7 +487,7 @@ func RunService_Failures(t *testing.T) {
|
|||
service := core.SelectService(18)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Failing URL", service.Name)
|
||||
assert.NotEmpty(t, service.Failures)
|
||||
assert.NotEmpty(t, service.AllFailures())
|
||||
}
|
||||
|
||||
func RunService_LimitedHits(t *testing.T) {
|
||||
|
|
|
@ -48,15 +48,15 @@ func FindCheckin(api string) *types.Checkin {
|
|||
|
||||
func (s *Service) AllCheckins() []*types.Checkin {
|
||||
var checkins []*types.Checkin
|
||||
col := checkinDB().Where("service = ?", s.Id).Order("-id")
|
||||
col.Scan(&checkins)
|
||||
col := checkinDB().Where("service = ?", s.Id).Order("id desc")
|
||||
col.Find(&checkins)
|
||||
s.Checkins = checkins
|
||||
return checkins
|
||||
}
|
||||
|
||||
func (u *Checkin) Create() (int64, error) {
|
||||
u.CreatedAt = time.Now()
|
||||
row := checkinDB().Create(&u)
|
||||
row := checkinDB().Create(u)
|
||||
if row.Error == nil {
|
||||
utils.Log(2, row.Error)
|
||||
return 0, row.Error
|
||||
|
|
34
core/core.go
34
core/core.go
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -33,10 +34,10 @@ type Core struct {
|
|||
}
|
||||
|
||||
var (
|
||||
Configs *DbConfig
|
||||
CoreApp *Core
|
||||
SetupMode bool
|
||||
VERSION string
|
||||
Configs *DbConfig // Configs holds all of the config.yml and database info
|
||||
CoreApp *Core // CoreApp is a global variable that contains many elements
|
||||
SetupMode bool // SetupMode will be true if Statup does not have a database connection
|
||||
VERSION string // VERSION is set on build automatically by setting a -ldflag
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -74,15 +75,18 @@ func InsertNotifierDB() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// UpdateCore will update the CoreApp variable inside of the 'core' table in database
|
||||
func UpdateCore(c *Core) (*Core, error) {
|
||||
db := coreDB().Update(c)
|
||||
db := coreDB().Update(&c)
|
||||
return c, db.Error
|
||||
}
|
||||
|
||||
// UsingAssets will return true if /assets folder is present
|
||||
func (c Core) UsingAssets() bool {
|
||||
return source.UsingAssets(utils.Directory)
|
||||
}
|
||||
|
||||
// SassVars opens the file /assets/scss/variables.scss to be edited in Theme
|
||||
func (c Core) SassVars() string {
|
||||
if !source.UsingAssets(utils.Directory) {
|
||||
return ""
|
||||
|
@ -90,6 +94,7 @@ func (c Core) SassVars() string {
|
|||
return source.OpenAsset(utils.Directory, "scss/variables.scss")
|
||||
}
|
||||
|
||||
// BaseSASS is the base design , this opens the file /assets/scss/base.scss to be edited in Theme
|
||||
func (c Core) BaseSASS() string {
|
||||
if !source.UsingAssets(utils.Directory) {
|
||||
return ""
|
||||
|
@ -97,6 +102,8 @@ func (c Core) BaseSASS() string {
|
|||
return source.OpenAsset(utils.Directory, "scss/base.scss")
|
||||
}
|
||||
|
||||
// MobileSASS is the -webkit responsive custom css designs. This opens the
|
||||
// file /assets/scss/mobile.scss to be edited in Theme
|
||||
func (c Core) MobileSASS() string {
|
||||
if !source.UsingAssets(utils.Directory) {
|
||||
return ""
|
||||
|
@ -104,6 +111,7 @@ func (c Core) MobileSASS() string {
|
|||
return source.OpenAsset(utils.Directory, "scss/mobile.scss")
|
||||
}
|
||||
|
||||
// AllOnline will be true if all services are online
|
||||
func (c Core) AllOnline() bool {
|
||||
for _, s := range CoreApp.Services() {
|
||||
if !s.Online {
|
||||
|
@ -113,14 +121,7 @@ func (c Core) AllOnline() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func SelectLastMigration() (int64, error) {
|
||||
if DbSession == nil {
|
||||
return 0, errors.New("Database connection has not been created yet")
|
||||
}
|
||||
row := coreDB().Take(&CoreApp)
|
||||
return CoreApp.MigrationId, row.Error
|
||||
}
|
||||
|
||||
// SelectCore will return the CoreApp global variable and the settings/configs for Statup
|
||||
func SelectCore() (*Core, error) {
|
||||
if DbSession == nil {
|
||||
return nil, errors.New("database has not been initiated yet.")
|
||||
|
@ -129,7 +130,7 @@ func SelectCore() (*Core, error) {
|
|||
if !exists {
|
||||
return nil, errors.New("core database has not been setup yet.")
|
||||
}
|
||||
db := coreDB().Take(&CoreApp)
|
||||
db := coreDB().First(&CoreApp)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
|
@ -143,16 +144,19 @@ func SelectCore() (*Core, error) {
|
|||
return CoreApp, db.Error
|
||||
}
|
||||
|
||||
// ServiceOrder will reorder the services based on 'order_id' (Order)
|
||||
type ServiceOrder []*types.Service
|
||||
|
||||
func (c ServiceOrder) Len() int { return len(c) }
|
||||
func (c ServiceOrder) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
|
||||
|
||||
// Services returns each Service that is attached to this instance
|
||||
func (c *Core) Services() []*Service {
|
||||
var services []*Service
|
||||
servs := CoreApp.GetServices()
|
||||
//sort.Sort(ServiceOrder(servs))
|
||||
sort.Sort(ServiceOrder(servs))
|
||||
CoreApp.SetServices(servs)
|
||||
for _, ser := range servs {
|
||||
services = append(services, ReturnService(ser))
|
||||
}
|
||||
|
|
|
@ -70,8 +70,18 @@ func TestDbConnection(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestDropDatabase(t *testing.T) {
|
||||
err := Configs.DropDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestSeedSchemaDatabase(t *testing.T) {
|
||||
_, _, err := Configs.SeedSchema()
|
||||
err := Configs.CreateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestMigrateDatabase(t *testing.T) {
|
||||
err := Configs.MigrateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
|
@ -92,13 +102,6 @@ func TestSelectCore(t *testing.T) {
|
|||
assert.Equal(t, "Awesome Status", core.Name)
|
||||
}
|
||||
|
||||
func TestSelectLastMigration(t *testing.T) {
|
||||
id, err := SelectLastMigration()
|
||||
assert.Nil(t, err)
|
||||
//assert.NotZero(t, id)
|
||||
t.Log("Last migration id: ", id)
|
||||
}
|
||||
|
||||
func TestInsertNotifierDB(t *testing.T) {
|
||||
err := InsertNotifierDB()
|
||||
assert.Nil(t, err)
|
||||
|
|
234
core/database.go
234
core/database.go
|
@ -17,10 +17,8 @@ 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"
|
||||
|
@ -28,23 +26,20 @@ import (
|
|||
_ "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"
|
||||
)
|
||||
|
||||
var (
|
||||
DbSession *gorm.DB
|
||||
currentMigration int64
|
||||
DbSession *gorm.DB
|
||||
)
|
||||
|
||||
func failuresDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Failure{}).Debug()
|
||||
db := DbSession.Model(&types.Failure{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Failure{})
|
||||
return db
|
||||
}
|
||||
|
||||
func (s *Service) allHits() *gorm.DB {
|
||||
|
@ -53,42 +48,47 @@ func (s *Service) allHits() *gorm.DB {
|
|||
}
|
||||
|
||||
func hitsDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Hit{}).Debug()
|
||||
db := DbSession.Model(&types.Hit{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Hit{})
|
||||
return db
|
||||
}
|
||||
|
||||
func servicesDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.Service{}).Debug()
|
||||
db := DbSession.Model(&types.Service{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Service{})
|
||||
return db
|
||||
}
|
||||
|
||||
func coreDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Table("core").Debug()
|
||||
db := DbSession.Table("core").Model(&CoreApp)
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Table("core")
|
||||
return db
|
||||
}
|
||||
|
||||
func usersDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Model(&types.User{}).Debug()
|
||||
db := DbSession.Model(&types.User{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Model(&types.User{})
|
||||
return db
|
||||
}
|
||||
|
||||
func commDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
return DbSession.Table("communication").Model(¬ifiers.Notification{}).Debug()
|
||||
db := DbSession.Table("communication").Model(¬ifiers.Notification{})
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return db.Debug()
|
||||
}
|
||||
return DbSession.Table("communication").Model(¬ifiers.Notification{})
|
||||
return db
|
||||
}
|
||||
|
||||
func checkinDB() *gorm.DB {
|
||||
if os.Getenv("GO_ENV") == "TEST" {
|
||||
if os.Getenv("GO_ENV") == "test" {
|
||||
return DbSession.Model(&types.Checkin{}).Debug()
|
||||
}
|
||||
return DbSession.Model(&types.Checkin{})
|
||||
|
@ -98,10 +98,12 @@ type DbConfig struct {
|
|||
*types.DbConfig
|
||||
}
|
||||
|
||||
// Close shutsdown the database connection
|
||||
func (db *DbConfig) Close() error {
|
||||
return DbSession.Close()
|
||||
return DbSession.DB().Close()
|
||||
}
|
||||
|
||||
// InsertCore create the single row for the Core settings in Statup
|
||||
func (db *DbConfig) InsertCore() (*Core, error) {
|
||||
CoreApp = &Core{Core: &types.Core{
|
||||
Name: db.Project,
|
||||
|
@ -117,64 +119,44 @@ func (db *DbConfig) InsertCore() (*Core, error) {
|
|||
return CoreApp, query.Error
|
||||
}
|
||||
|
||||
// Connect will attempt to connect to the sqlite, postgres, or mysql database
|
||||
func (db *DbConfig) Connect(retry bool, location string) error {
|
||||
var err error
|
||||
if DbSession != nil {
|
||||
DbSession = nil
|
||||
}
|
||||
switch Configs.DbConn {
|
||||
var conn, dbType string
|
||||
dbType = Configs.DbConn
|
||||
switch dbType {
|
||||
case "sqlite":
|
||||
DbSession, err = gorm.Open("sqlite3", utils.Directory+"/statup.db")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conn = utils.Directory + "/statup.db"
|
||||
dbType = "sqlite3"
|
||||
case "mysql":
|
||||
if Configs.DbPort == 0 {
|
||||
Configs.DbPort = 3306
|
||||
}
|
||||
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 db.waitForDb()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
conn = fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8&parseTime=True&loc=Local", Configs.DbUser, Configs.DbPass, host, Configs.DbData)
|
||||
case "postgres":
|
||||
if Configs.DbPort == 0 {
|
||||
Configs.DbPort = 5432
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
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)
|
||||
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 db.waitForDb()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
conn = fmt.Sprintf("sqlserver://%v:%v@%v?database=%v", Configs.DbUser, Configs.DbPass, host, Configs.DbData)
|
||||
}
|
||||
DbSession, err = gorm.Open(dbType, 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
|
||||
}
|
||||
}
|
||||
err = DbSession.DB().Ping()
|
||||
|
@ -189,6 +171,8 @@ func (db *DbConfig) waitForDb() error {
|
|||
return db.Connect(true, utils.Directory)
|
||||
}
|
||||
|
||||
// DatabaseMaintence will automatically delete old records from 'failures' and 'hits'
|
||||
// this function is currently set to delete records 7+ days old every 60 minutes
|
||||
func DatabaseMaintence() {
|
||||
for range time.Tick(60 * time.Minute) {
|
||||
utils.Log(1, "Checking for database records older than 7 days...")
|
||||
|
@ -198,6 +182,7 @@ func DatabaseMaintence() {
|
|||
}
|
||||
}
|
||||
|
||||
// DeleteAllSince will delete a specific table's records based on a time.
|
||||
func DeleteAllSince(table string, date time.Time) {
|
||||
sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, date.Format("2006-01-02"))
|
||||
db := DbSession.Raw(sql)
|
||||
|
@ -207,6 +192,7 @@ func DeleteAllSince(table string, date time.Time) {
|
|||
}
|
||||
}
|
||||
|
||||
// Update will save the config.yml file
|
||||
func (c *DbConfig) Update() error {
|
||||
var err error
|
||||
config, err := os.Create(utils.Directory + "/config.yml")
|
||||
|
@ -224,6 +210,7 @@ func (c *DbConfig) Update() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Save will initially create the config.yml file
|
||||
func (c *DbConfig) Save() (*DbConfig, error) {
|
||||
var err error
|
||||
config, err := os.Create(utils.Directory + "/config.yml")
|
||||
|
@ -243,6 +230,7 @@ func (c *DbConfig) Save() (*DbConfig, error) {
|
|||
return c, err
|
||||
}
|
||||
|
||||
// CreateCore will initialize the global variable 'CoreApp". This global variable contains most of Statup app.
|
||||
func (c *DbConfig) CreateCore() *Core {
|
||||
newCore := &types.Core{
|
||||
Name: c.Project,
|
||||
|
@ -264,91 +252,7 @@ func (c *DbConfig) CreateCore() *Core {
|
|||
return CoreApp
|
||||
}
|
||||
|
||||
func versionHigher(migrate int64) bool {
|
||||
if CoreApp.MigrationId < migrate {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func reverseSlice(s []string) []string {
|
||||
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func RunDatabaseUpgrades() error {
|
||||
var err error
|
||||
currentMigration, err = SelectLastMigration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("Checking for Database Upgrades since #%v", currentMigration))
|
||||
upgrade, _ := source.SqlBox.String(CoreApp.DbConnection + "_upgrade.sql")
|
||||
// parse db version and upgrade file
|
||||
ups := strings.Split(upgrade, "=========================================== ")
|
||||
ups = reverseSlice(ups)
|
||||
var ran int
|
||||
var lastMigration int64
|
||||
for _, v := range ups {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
vers := strings.Split(v, "\n")
|
||||
lastMigration = utils.StringInt(vers[0])
|
||||
data := vers[1:]
|
||||
|
||||
//fmt.Printf("Checking Migration from v%v to v%v - %v\n", CoreApp.Version, version, versionHigher(version))
|
||||
if currentMigration >= lastMigration {
|
||||
continue
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("Migrating Database from #%v to #%v", currentMigration, lastMigration))
|
||||
for _, m := range data {
|
||||
if m == "" {
|
||||
continue
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("Running Query: %v", m))
|
||||
db := DbSession.Raw(m)
|
||||
ran++
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
continue
|
||||
}
|
||||
}
|
||||
currentMigration = lastMigration
|
||||
}
|
||||
if ran > 0 {
|
||||
utils.Log(1, fmt.Sprintf("Database Upgraded %v queries ran, current #%v", ran, currentMigration))
|
||||
CoreApp, err = SelectCore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
CoreApp.MigrationId = currentMigration
|
||||
UpdateCore(CoreApp)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
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 out, outErr, err
|
||||
}
|
||||
return out, outErr, err
|
||||
}
|
||||
|
||||
// SeedDatabase will insert many elements into the database. This is only ran in Dev/Test move
|
||||
func (db *DbConfig) SeedDatabase() (string, string, error) {
|
||||
utils.Log(1, "Seeding Database with Dummy Data...")
|
||||
dir := utils.Directory
|
||||
|
@ -365,6 +269,7 @@ func (db *DbConfig) SeedDatabase() (string, string, error) {
|
|||
return out, outErr, err
|
||||
}
|
||||
|
||||
// DropDatabase will DROP each table Statup created
|
||||
func (db *DbConfig) DropDatabase() error {
|
||||
utils.Log(1, "Dropping Database Tables...")
|
||||
err := DbSession.DropTableIfExists("checkins")
|
||||
|
@ -377,6 +282,7 @@ func (db *DbConfig) DropDatabase() error {
|
|||
return err.Error
|
||||
}
|
||||
|
||||
// CreateDatabase will CREATE TABLES for each of the Statup elements
|
||||
func (db *DbConfig) CreateDatabase() error {
|
||||
utils.Log(1, "Creating Database Tables...")
|
||||
err := DbSession.CreateTable(&types.Checkin{})
|
||||
|
@ -390,17 +296,29 @@ func (db *DbConfig) CreateDatabase() error {
|
|||
return err.Error
|
||||
}
|
||||
|
||||
// MigrateDatabase will migrate the database structure to current version.
|
||||
// This function will NOT remove previous records, tables or columns from the database.
|
||||
// If this function has an issue, it will ROLLBACK to the previous state.
|
||||
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{})
|
||||
|
||||
tx := DbSession.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
if tx.Error != nil {
|
||||
return tx.Error
|
||||
}
|
||||
tx = tx.AutoMigrate(&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Checkin{}).Table("core").AutoMigrate(&types.Core{}).Table("communication").AutoMigrate(¬ifiers.Notification{})
|
||||
if tx.Error != nil {
|
||||
tx.Rollback()
|
||||
utils.Log(3, fmt.Sprintf("Statup Database could not be migrated: %v", tx.Error))
|
||||
return tx.Error
|
||||
}
|
||||
utils.Log(1, "Statup Database Migrated")
|
||||
return err.Error
|
||||
return tx.Commit().Error
|
||||
}
|
||||
|
||||
func (c *DbConfig) Clean() *DbConfig {
|
||||
|
|
|
@ -66,13 +66,6 @@ func (s *Service) LimitedFailures() []*Failure {
|
|||
return failArr
|
||||
}
|
||||
|
||||
func reverseFailures(input []*Failure) []*Failure {
|
||||
if len(input) == 0 {
|
||||
return input
|
||||
}
|
||||
return append(reverseFailures(input[1:]), input[0])
|
||||
}
|
||||
|
||||
func (f *Failure) Ago() string {
|
||||
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
|
||||
return got
|
||||
|
@ -101,7 +94,7 @@ func (s *Service) TotalFailures24() (uint64, error) {
|
|||
func (s *Service) TotalFailures() (uint64, error) {
|
||||
var count uint64
|
||||
rows := failuresDB().Where("service = ?", s.Id)
|
||||
err := rows.Count(count)
|
||||
err := rows.Count(&count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ type Hit struct {
|
|||
}
|
||||
|
||||
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
||||
db := hitsDB().Create(&h)
|
||||
db := hitsDB().Create(h)
|
||||
if db.Error != nil {
|
||||
utils.Log(2, db.Error)
|
||||
return 0, db.Error
|
||||
|
@ -62,10 +62,6 @@ func (s *Service) SelectHitsGroupBy(group string) ([]*Hit, error) {
|
|||
return hits, err.Error
|
||||
}
|
||||
|
||||
func (s *Service) hits() {
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) TotalHits() (uint64, error) {
|
||||
var count uint64
|
||||
col := hitsDB().Where("service = ?", s.Id)
|
||||
|
|
|
@ -44,7 +44,7 @@ func SelectService(id int64) *Service {
|
|||
func (c *Core) SelectAllServices() ([]*types.Service, error) {
|
||||
var services []*types.Service
|
||||
var servs []*types.Service
|
||||
db := servicesDB().Find(&services)
|
||||
db := servicesDB().Find(&services).Order("order_id desc")
|
||||
if db.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("service error: %v", db.Error))
|
||||
return nil, db.Error
|
||||
|
@ -186,24 +186,37 @@ func (s *Service) AvgUptime24() string {
|
|||
func (s *Service) AvgUptime(ago time.Time) string {
|
||||
failed, _ := s.TotalFailuresSince(ago)
|
||||
if failed == 0 {
|
||||
s.TotalUptime = "100"
|
||||
return s.TotalUptime
|
||||
return "100"
|
||||
}
|
||||
total, _ := s.TotalHitsSince(ago)
|
||||
if total == 0 {
|
||||
s.TotalUptime = "0"
|
||||
return s.TotalUptime
|
||||
return "0"
|
||||
}
|
||||
percent := float64(failed) / float64(total) * 100
|
||||
percent = 100 - percent
|
||||
if percent < 0 {
|
||||
percent = 0
|
||||
}
|
||||
s.TotalUptime = fmt.Sprintf("%0.2f", percent)
|
||||
if s.TotalUptime == "100.00" {
|
||||
s.TotalUptime = "100"
|
||||
amount := fmt.Sprintf("%0.2f", percent)
|
||||
if amount == "100.00" {
|
||||
amount = "100"
|
||||
}
|
||||
return s.TotalUptime
|
||||
return amount
|
||||
}
|
||||
|
||||
func (s *Service) TotalUptime() string {
|
||||
hits, _ := s.TotalHits()
|
||||
failures, _ := s.TotalFailures()
|
||||
percent := float64(failures) / float64(hits) * 100
|
||||
percent = 100 - percent
|
||||
if percent < 0 {
|
||||
percent = 0
|
||||
}
|
||||
amount := fmt.Sprintf("%0.2f", percent)
|
||||
if amount == "100.00" {
|
||||
amount = "100"
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
func (s *Service) index() int {
|
||||
|
|
|
@ -59,8 +59,10 @@ func ReorderServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|||
decoder := json.NewDecoder(r.Body)
|
||||
decoder.Decode(&newOrder)
|
||||
for _, s := range newOrder {
|
||||
fmt.Println("updating: ", s.Id, " to be order_id: ", s.Order)
|
||||
service := core.SelectService(s.Id)
|
||||
service.UpdateSingle("order_id", s.Order)
|
||||
service.Order = s.Order
|
||||
service.Update(false)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
|
|
@ -33,18 +33,19 @@ var (
|
|||
type Notification 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:"-"`
|
||||
Host string `gorm:"not null;column:host" json:"-"`
|
||||
Port int `gorm:"not null;column:port" json:"-"`
|
||||
Username string `gorm:"not null;column:username" json:"-"`
|
||||
Password string `gorm:"not null;column:password" json:"-"`
|
||||
Var1 string `gorm:"not null;column:var1" json:"-"`
|
||||
Var2 string `gorm:"not null;column:var2" json:"-"`
|
||||
ApiKey string `gorm:"not null;column:api_key" json:"-"`
|
||||
ApiSecret string `gorm:"not null;column:api_secret" json:"-"`
|
||||
Enabled bool `gorm:"column:enabled;type:boolean;default:false" json:"enabled"`
|
||||
Limits int `gorm:"not null;column:limits" json:"-"`
|
||||
Removable bool `gorm:"column:removable" json:"-"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
Form []NotificationForm `gorm:"-" json:"-"`
|
||||
Routine chan struct{} `gorm:"-" json:"-"`
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
SqlBox *rice.Box
|
||||
CssBox *rice.Box
|
||||
ScssBox *rice.Box
|
||||
JsBox *rice.Box
|
||||
|
@ -35,7 +34,6 @@ var (
|
|||
)
|
||||
|
||||
func Assets() {
|
||||
SqlBox = rice.MustFindBox("sql")
|
||||
CssBox = rice.MustFindBox("css")
|
||||
ScssBox = rice.MustFindBox("scss")
|
||||
JsBox = rice.MustFindBox("js")
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
DROP TABLE IF EXISTS core;
|
||||
DROP TABLE IF EXISTS hits;
|
||||
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;
|
|
@ -1,78 +0,0 @@
|
|||
CREATE TABLE core (
|
||||
name VARCHAR(50),
|
||||
description text,
|
||||
config VARCHAR(50),
|
||||
api_key VARCHAR(50),
|
||||
api_secret VARCHAR(50),
|
||||
style text,
|
||||
footer text,
|
||||
domain text,
|
||||
version VARCHAR(50),
|
||||
migration_id INT(6) NOT NULL DEFAULT 0,
|
||||
use_cdn BOOL NOT NULL DEFAULT '0'
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE users (
|
||||
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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (username, email)
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE services (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
name VARCHAR(50),
|
||||
domain text,
|
||||
check_type text,
|
||||
method VARCHAR(50),
|
||||
port INT(6),
|
||||
expected text,
|
||||
expected_status INT(6),
|
||||
check_interval int(11),
|
||||
post_data text,
|
||||
order_id integer default 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
timeout INT(6) DEFAULT 30
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE hits (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
latency float,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE failures (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
issue text,
|
||||
method text,
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE checkins (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
service BIGINT(20) UNSIGNED NOT NULL,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (service) REFERENCES services(id) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE communication (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
|
||||
method text,
|
||||
host text,
|
||||
port integer,
|
||||
username text,
|
||||
password text,
|
||||
var1 text,
|
||||
var2 text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
enabled BOOL NOT NULL DEFAULT '0',
|
||||
removable BOOL NOT NULL DEFAULT '0',
|
||||
limits integer,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=INNODB;
|
|
@ -1,9 +0,0 @@
|
|||
=========================================== 1534178020
|
||||
UPDATE services SET order_id=0 WHERE order_id IS NULL;
|
||||
=========================================== 1532068515
|
||||
ALTER TABLE services ALTER COLUMN order_id integer DEFAULT 0;
|
||||
ALTER TABLE services ADD COLUMN timeout integer DEFAULT 30;
|
||||
=========================================== 1530841150
|
||||
ALTER TABLE core ADD COLUMN use_cdn BOOL NOT NULL DEFAULT '0';
|
||||
=========================================== 1
|
||||
ALTER TABLE core ADD COLUMN migration_id INT(6) NOT NULL DEFAULT 0;
|
|
@ -1,84 +0,0 @@
|
|||
CREATE TABLE core (
|
||||
name text,
|
||||
description text,
|
||||
config text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
style text,
|
||||
footer text,
|
||||
domain text,
|
||||
version text,
|
||||
migration_id integer default 0,
|
||||
use_cdn bool default false
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username VARCHAR (50) UNIQUE,
|
||||
password text,
|
||||
email VARCHAR (50) UNIQUE,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE services (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name text,
|
||||
domain text,
|
||||
check_type text,
|
||||
method text,
|
||||
port integer,
|
||||
expected text,
|
||||
expected_status integer,
|
||||
check_interval integer,
|
||||
post_data text,
|
||||
order_id integer default 0,
|
||||
timeout integer default 30,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE hits (
|
||||
id SERIAL PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
latency float,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE failures (
|
||||
id SERIAL PRIMARY KEY,
|
||||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE checkins (
|
||||
id SERIAL PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE communication (
|
||||
id SERIAL PRIMARY KEY,
|
||||
method text,
|
||||
host text,
|
||||
port integer,
|
||||
username text,
|
||||
password text,
|
||||
var1 text,
|
||||
var2 text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
enabled boolean,
|
||||
removable boolean,
|
||||
limits integer,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_hits ON hits(service);
|
||||
CREATE INDEX idx_failures ON failures(service);
|
||||
CREATE INDEX idx_checkins ON checkins(service);
|
|
@ -1,9 +0,0 @@
|
|||
=========================================== 1534178020
|
||||
UPDATE services SET order_id=0 WHERE order_id IS NULL;
|
||||
=========================================== 1532068515
|
||||
ALTER TABLE services ALTER COLUMN order_id integer DEFAULT 0;
|
||||
ALTER TABLE services ADD COLUMN timeout integer DEFAULT 30;
|
||||
=========================================== 1530841150
|
||||
ALTER TABLE core ADD COLUMN use_cdn bool DEFAULT FALSE;
|
||||
=========================================== 1
|
||||
ALTER TABLE core ADD COLUMN migration_id integer default 0 NOT NULL;
|
|
@ -1,84 +0,0 @@
|
|||
CREATE TABLE core (
|
||||
name text,
|
||||
description text,
|
||||
config text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
style text,
|
||||
footer text,
|
||||
domain text,
|
||||
version text,
|
||||
migration_id integer default 0,
|
||||
use_cdn bool default false
|
||||
);
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
username text NOT NULL UNIQUE,
|
||||
password text,
|
||||
email text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
created_at TIMESTAMP,
|
||||
UNIQUE (username, email)
|
||||
);
|
||||
CREATE TABLE services (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name text,
|
||||
domain text,
|
||||
check_type text,
|
||||
method text,
|
||||
port integer,
|
||||
expected text,
|
||||
expected_status integer,
|
||||
check_interval integer,
|
||||
post_data text,
|
||||
order_id integer default 0,
|
||||
timeout integer default 30,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE hits (
|
||||
id INTEGER PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
latency float,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE failures (
|
||||
id INTEGER PRIMARY KEY,
|
||||
issue text,
|
||||
method text,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE checkins (
|
||||
id INTEGER PRIMARY KEY,
|
||||
service INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
check_interval integer,
|
||||
api text,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE communication (
|
||||
id INTEGER PRIMARY KEY,
|
||||
method text,
|
||||
host text,
|
||||
port integer,
|
||||
username text,
|
||||
password text,
|
||||
var1 text,
|
||||
var2 text,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
enabled boolean,
|
||||
removable boolean,
|
||||
limits integer,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
CREATE INDEX idx_hits ON hits(service);
|
||||
CREATE INDEX idx_failures ON failures(service);
|
||||
CREATE INDEX idx_checkins ON checkins(service);
|
|
@ -1,9 +0,0 @@
|
|||
=========================================== 1534178020
|
||||
UPDATE services SET order_id=0 WHERE order_id IS NULL;
|
||||
=========================================== 1532068515
|
||||
ALTER TABLE services ALTER COLUMN order_id integer DEFAULT 0;
|
||||
ALTER TABLE services ADD COLUMN timeout integer DEFAULT 30;
|
||||
=========================================== 1530841150
|
||||
ALTER TABLE core ADD COLUMN use_cdn bool DEFAULT FALSE;
|
||||
=========================================== 1
|
||||
ALTER TABLE core ADD COLUMN migration_id integer NOT NULL DEFAULT 0;
|
|
@ -1,9 +1,9 @@
|
|||
{{ define "footer"}}
|
||||
<div class="footer text-center mb-4">
|
||||
{{ if CoreApp.Footer }}
|
||||
{{ safe CoreApp.Footer }}
|
||||
{{ if ne CoreApp.Footer "" }}
|
||||
{{ safe CoreApp.Footer }}
|
||||
{{ else }}
|
||||
<a href="https://github.com/hunterlong/statup" target="_blank">Statup {{VERSION}} made with ❤️</a> | <a href="/dashboard">Dashboard</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{.AvgUptime24}}%</span>
|
||||
<span class="lg_number">{{.TotalUptime}}%</span>
|
||||
Total Uptime
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -237,4 +237,4 @@
|
|||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -9,7 +9,8 @@ type Checkin struct {
|
|||
Service int64 `gorm:"index;column:service"`
|
||||
Interval int64 `gorm:"column:check_interval"`
|
||||
Api string `gorm:"column:api"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
Hits int64 `json:"hits"`
|
||||
Last time.Time `json:"last"`
|
||||
CheckinInterface `json:"-"`
|
||||
|
|
|
@ -1,32 +1,45 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Core struct contains all the required fields for Statup. All application settings
|
||||
// will be saved into 1 row in the 'core' table. You can use the core.CoreApp
|
||||
// global variable to interact with the attributes to the application, such as services.
|
||||
type Core struct {
|
||||
Name string `gorm:"column:name" json:"name"`
|
||||
Description string `gorm:"column:description" json:"description,omitempty"`
|
||||
Name string `gorm:"not null;column:name" json:"name"`
|
||||
Description string `gorm:"not null;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"`
|
||||
Style string `gorm:"not null;column:style" json:"style,omitempty"`
|
||||
Footer string `gorm:"not null;column:footer" json:"footer,omitempty"`
|
||||
Domain string `gorm:"not null;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:-"`
|
||||
UseCdn bool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
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:"-"`
|
||||
}
|
||||
|
||||
type ServiceOrder []*Service
|
||||
|
||||
func (c ServiceOrder) Len() int { return len(c) }
|
||||
func (c ServiceOrder) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
|
||||
|
||||
func (c *Core) SetServices(s []*Service) {
|
||||
sort.Sort(ServiceOrder(c.dbServices))
|
||||
c.dbServices = s
|
||||
}
|
||||
|
||||
|
|
|
@ -23,21 +23,21 @@ type Service struct {
|
|||
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"`
|
||||
Expected string `gorm:"not null;column:expected" json:"expected"`
|
||||
ExpectedStatus int `gorm:"default:200;column:expected_status" json:"expected_status"`
|
||||
Interval int `gorm:"default:30;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"`
|
||||
PostData string `gorm:"not null;column:post_data" json:"post_data"`
|
||||
Port int `gorm:"not null;column:port" json:"port"`
|
||||
Timeout int `gorm:"default:30;column:timeout" json:"timeout"`
|
||||
Order int `gorm:"default:0;column:order_id" json:"order_id"`
|
||||
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"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
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:"-"`
|
||||
|
|
|
@ -61,6 +61,7 @@ type PluginActions interface {
|
|||
|
||||
type AllNotifiers interface{}
|
||||
|
||||
// Hit struct is a 'successful' ping or web response entry for a service.
|
||||
type Hit struct {
|
||||
Id int64 `gorm:"primary_key;column:id"`
|
||||
Service int64 `gorm:"index;column:service"`
|
||||
|
@ -68,6 +69,7 @@ type Hit struct {
|
|||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
}
|
||||
|
||||
// DbConfig struct is used for the database connection and creates the 'config.yml' file
|
||||
type DbConfig struct {
|
||||
DbConn string `yaml:"connection"`
|
||||
DbHost string `yaml:"host"`
|
||||
|
|
|
@ -13,6 +13,7 @@ type User struct {
|
|||
ApiSecret string `gorm:"column:api_secret" json:"-"`
|
||||
Admin bool `gorm:"column:administrator" json:"admin"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
UserInterface `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue