mirror of https://github.com/statping/statping
golint
parent
55cb0808bd
commit
9061a97955
|
@ -22,4 +22,4 @@ source/rice-box.go
|
|||
sass
|
||||
.DS_Store
|
||||
source/css/base.css.map
|
||||
/dev/test/node_modules/
|
||||
dev/test/node_modules
|
||||
|
|
1
Makefile
1
Makefile
|
@ -13,6 +13,7 @@ PATH:=/usr/local/bin:$(GOPATH)/bin:$(PATH)
|
|||
PUBLISH_BODY='{ "request": { "branch": "master", "config": { "env": { "VERSION": "$(VERSION)", "COMMIT": "$(TRAVIS_COMMIT)" } } } }'
|
||||
TRAVIS_BUILD_CMD='{ "request": { "branch": "master", "message": "Compile master for Statup v$(VERSION)", "config": { "os": [ "linux" ], "language": "go", "go": [ "1.10.x" ], "go_import_path": "github.com/hunterlong/statup", "install": true, "sudo": "required", "services": [ "docker" ], "env": { "VERSION": "$(VERSION)" }, "matrix": { "allow_failures": [ { "go": "master" } ], "fast_finish": true }, "before_deploy": [ "git config --local user.name \"hunterlong\"", "git config --local user.email \"info@socialeck.com\"", "make tag" ], "deploy": [ { "provider": "releases", "api_key": "$(GH_TOKEN)", "file": [ "build/statup-osx-x64.tar.gz", "build/statup-osx-x32.tar.gz", "build/statup-linux-x64.tar.gz", "build/statup-linux-x32.tar.gz", "build/statup-linux-arm64.tar.gz", "build/statup-linux-arm7.tar.gz", "build/statup-linux-alpine.tar.gz", "build/statup-windows-x64.zip" ], "skip_cleanup": true } ], "notifications": { "email": false }, "before_script": ["gem install sass"], "script": [ "travis_wait 30 docker pull karalabe/xgo-latest", "make release" ], "after_success": [], "after_deploy": [ "make publish-dev" ] } } }'
|
||||
TEST_DIR=$(GOPATH)/src/github.com/hunterlong/statup
|
||||
PATH:=$(PATH)
|
||||
|
||||
# build and compile Statup and then test
|
||||
all: dev-deps compile install test-all docker-build-all
|
||||
|
|
14
cmd/cli.go
14
cmd/cli.go
|
@ -92,7 +92,7 @@ func CatchCLI(args []string) error {
|
|||
return err
|
||||
}
|
||||
indexSource := core.ExportIndexHTML()
|
||||
err = core.SaveFile("./index.html", []byte(indexSource))
|
||||
err = utils.SaveFile("./index.html", []byte(indexSource))
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
return err
|
||||
|
@ -194,7 +194,7 @@ func HelpEcho() {
|
|||
// core.OnSuccess(core.SelectService(1))
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'")
|
||||
// fakeFailD := &types.Failure{
|
||||
// fakeFailD := &types.failure{
|
||||
// Issue: "No issue, just testing this plugin. This would include HTTP failure information though",
|
||||
// }
|
||||
// core.OnFailure(core.SelectService(1), fakeFailD)
|
||||
|
@ -206,7 +206,7 @@ func HelpEcho() {
|
|||
// fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
// core.OnNewService(core.SelectService(2))
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
// fmt.Println(POINT + "Sending 'OnNewUser(User)'")
|
||||
// fmt.Println(POINT + "Sending 'OnNewUser(user)'")
|
||||
// user, _ := core.SelectUser(1)
|
||||
// core.OnNewUser(user)
|
||||
// fmt.Println("\n" + BRAKER)
|
||||
|
@ -258,7 +258,7 @@ func HelpEcho() {
|
|||
// }}
|
||||
// fakeSrv2.Create()
|
||||
//
|
||||
// fakeUser := &types.User{
|
||||
// fakeUser := &types.user{
|
||||
// Id: 6334,
|
||||
// Username: "Bulbasaur",
|
||||
// Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
|
@ -268,7 +268,7 @@ func HelpEcho() {
|
|||
// }
|
||||
// fakeUser.Create()
|
||||
//
|
||||
// fakeUser = &types.User{
|
||||
// fakeUser = &types.user{
|
||||
// Id: 6335,
|
||||
// Username: "Billy",
|
||||
// Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
|
@ -288,12 +288,12 @@ func HelpEcho() {
|
|||
// }
|
||||
// fakeSrv2.CreateHit(dd)
|
||||
//
|
||||
// fail := &types.Failure{
|
||||
// fail := &types.failure{
|
||||
// Issue: "This is not an issue, but it would container HTTP response errors.",
|
||||
// }
|
||||
// fakeSrv.CreateFailure(fail)
|
||||
//
|
||||
// fail = &types.Failure{
|
||||
// fail = &types.failure{
|
||||
// Issue: "HTTP Status Code 521 did not match 200",
|
||||
// }
|
||||
// fakeSrv.CreateFailure(fail)
|
||||
|
|
|
@ -28,10 +28,10 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
VERSION string
|
||||
// VERSION stores the current version of Statup
|
||||
VERSION string
|
||||
// COMMIT stores the git commit hash for this version of Statup
|
||||
COMMIT string
|
||||
usingEnv bool
|
||||
directory string
|
||||
ipAddress string
|
||||
port int
|
||||
)
|
||||
|
|
|
@ -121,12 +121,12 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Create Users", func(t *testing.T) {
|
||||
RunUserCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Update User", func(t *testing.T) {
|
||||
RunUser_Update(t)
|
||||
t.Run(dbt+" Update user", func(t *testing.T) {
|
||||
runUserUpdate(t)
|
||||
})
|
||||
t.Run(dbt+" Create Non Unique Users", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
RunUser_NonUniqueCreate(t)
|
||||
runUserNonUniqueCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Select Users", func(t *testing.T) {
|
||||
RunUserSelectAll(t)
|
||||
|
@ -147,7 +147,7 @@ func TestRunAll(t *testing.T) {
|
|||
RunServiceToJSON(t)
|
||||
})
|
||||
t.Run(dbt+" Avg Time", func(t *testing.T) {
|
||||
RunService_AvgTime(t)
|
||||
runServiceAvgTime(t)
|
||||
})
|
||||
t.Run(dbt+" Online 24h", func(t *testing.T) {
|
||||
RunServiceOnline24(t)
|
||||
|
@ -173,7 +173,7 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Delete Service", func(t *testing.T) {
|
||||
RunDeleteService(t)
|
||||
})
|
||||
t.Run(dbt+" Delete User", func(t *testing.T) {
|
||||
t.Run(dbt+" Delete user", func(t *testing.T) {
|
||||
RunUserDelete(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /", func(t *testing.T) {
|
||||
|
@ -341,7 +341,7 @@ func RunUserCreate(t *testing.T) {
|
|||
assert.Equal(t, int64(4), id)
|
||||
}
|
||||
|
||||
func RunUser_Update(t *testing.T) {
|
||||
func runUserUpdate(t *testing.T) {
|
||||
user, err := core.SelectUser(1)
|
||||
user.Email = "info@updatedemail.com"
|
||||
assert.Nil(t, err)
|
||||
|
@ -352,7 +352,7 @@ func RunUser_Update(t *testing.T) {
|
|||
assert.Equal(t, "info@updatedemail.com", updatedUser.Email)
|
||||
}
|
||||
|
||||
func RunUser_NonUniqueCreate(t *testing.T) {
|
||||
func runUserNonUniqueCreate(t *testing.T) {
|
||||
user := core.ReturnUser(&types.User{
|
||||
Username: "admin",
|
||||
Password: "admin",
|
||||
|
@ -410,7 +410,7 @@ func RunServiceToJSON(t *testing.T) {
|
|||
assert.NotEmpty(t, jsoned)
|
||||
}
|
||||
|
||||
func RunService_AvgTime(t *testing.T) {
|
||||
func runServiceAvgTime(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
avg := service.AvgUptime24()
|
||||
|
|
|
@ -176,7 +176,7 @@ func (s *Service) checkHttp(record bool) *Service {
|
|||
return s
|
||||
}
|
||||
response.Header.Set("Connection", "close")
|
||||
response.Header.Set("User-Agent", "StatupMonitor")
|
||||
response.Header.Set("user-Agent", "StatupMonitor")
|
||||
t2 := time.Now()
|
||||
s.Latency = t2.Sub(t1).Seconds()
|
||||
if err != nil {
|
||||
|
|
|
@ -23,84 +23,84 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type Checkin struct {
|
||||
type checkin struct {
|
||||
*types.Checkin
|
||||
}
|
||||
|
||||
type CheckinHit struct {
|
||||
type checkinHit struct {
|
||||
*types.CheckinHit
|
||||
}
|
||||
|
||||
// String will return a Checkin API string
|
||||
func (c *Checkin) String() string {
|
||||
// String will return a checkin API string
|
||||
func (c *checkin) String() string {
|
||||
return c.ApiKey
|
||||
}
|
||||
|
||||
// ReturnCheckin converts *types.Checking to *core.Checkin
|
||||
func ReturnCheckin(s *types.Checkin) *Checkin {
|
||||
return &Checkin{Checkin: s}
|
||||
// ReturnCheckin converts *types.Checking to *core.checkin
|
||||
func ReturnCheckin(s *types.Checkin) *checkin {
|
||||
return &checkin{Checkin: s}
|
||||
}
|
||||
|
||||
// ReturnCheckinHit converts *types.CheckinHit to *core.CheckinHit
|
||||
func ReturnCheckinHit(h *types.CheckinHit) *CheckinHit {
|
||||
return &CheckinHit{CheckinHit: h}
|
||||
// ReturnCheckinHit converts *types.checkinHit to *core.checkinHit
|
||||
func ReturnCheckinHit(h *types.CheckinHit) *checkinHit {
|
||||
return &checkinHit{CheckinHit: h}
|
||||
}
|
||||
|
||||
// SelectCheckin will find a Checkin based on the API supplied
|
||||
func SelectCheckin(api string) *Checkin {
|
||||
var checkin Checkin
|
||||
// SelectCheckin will find a checkin based on the API supplied
|
||||
func SelectCheckin(api string) *checkin {
|
||||
var checkin checkin
|
||||
checkinDB().Where("api_key = ?", api).First(&checkin)
|
||||
return &checkin
|
||||
}
|
||||
|
||||
// Period will return the duration of the Checkin interval
|
||||
func (u *Checkin) Period() time.Duration {
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%vs", u.Interval))
|
||||
// Period will return the duration of the checkin interval
|
||||
func (c *checkin) Period() time.Duration {
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.Interval))
|
||||
return duration
|
||||
}
|
||||
|
||||
// Grace will return the duration of the Checkin Grace Period (after service hasn't responded, wait a bit for a response)
|
||||
func (u *Checkin) Grace() time.Duration {
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%vs", u.GracePeriod))
|
||||
// Grace will return the duration of the checkin Grace Period (after service hasn't responded, wait a bit for a response)
|
||||
func (c *checkin) Grace() time.Duration {
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.GracePeriod))
|
||||
return duration
|
||||
}
|
||||
|
||||
// Expected returns the duration of when the serviec should receive a checkin
|
||||
func (u *Checkin) Expected() time.Duration {
|
||||
last := u.Last().CreatedAt
|
||||
func (c *checkin) Expected() time.Duration {
|
||||
last := c.Last().CreatedAt
|
||||
now := time.Now()
|
||||
lastDir := now.Sub(last)
|
||||
sub := time.Duration(u.Period() - lastDir)
|
||||
sub := time.Duration(c.Period() - lastDir)
|
||||
return sub
|
||||
}
|
||||
|
||||
// Last returns the last CheckinHit for a Checkin
|
||||
func (u *Checkin) Last() CheckinHit {
|
||||
var hit CheckinHit
|
||||
checkinHitsDB().Where("checkin = ?", u.Id).Last(&hit)
|
||||
// Last returns the last checkinHit for a checkin
|
||||
func (c *checkin) Last() checkinHit {
|
||||
var hit checkinHit
|
||||
checkinHitsDB().Where("checkin = ?", c.Id).Last(&hit)
|
||||
return hit
|
||||
}
|
||||
|
||||
// Hits returns all of the CheckinHits for a given Checkin
|
||||
func (u *Checkin) Hits() []CheckinHit {
|
||||
var checkins []CheckinHit
|
||||
checkinHitsDB().Where("checkin = ?", u.Id).Order("id DESC").Find(&checkins)
|
||||
// Hits returns all of the CheckinHits for a given checkin
|
||||
func (c *checkin) Hits() []checkinHit {
|
||||
var checkins []checkinHit
|
||||
checkinHitsDB().Where("checkin = ?", c.Id).Order("id DESC").Find(&checkins)
|
||||
return checkins
|
||||
}
|
||||
|
||||
// Create will create a new Checkin
|
||||
func (u *Checkin) Create() (int64, error) {
|
||||
u.ApiKey = utils.RandomString(7)
|
||||
row := checkinDB().Create(&u)
|
||||
// Create will create a new checkin
|
||||
func (c *checkin) Create() (int64, error) {
|
||||
c.ApiKey = utils.RandomString(7)
|
||||
row := checkinDB().Create(&c)
|
||||
if row.Error != nil {
|
||||
utils.Log(2, row.Error)
|
||||
return 0, row.Error
|
||||
}
|
||||
return u.Id, row.Error
|
||||
return c.Id, row.Error
|
||||
}
|
||||
|
||||
// Update will update a Checkin
|
||||
func (u *Checkin) Update() (int64, error) {
|
||||
// Update will update a checkin
|
||||
func (u *checkin) Update() (int64, error) {
|
||||
row := checkinDB().Update(&u)
|
||||
if row.Error != nil {
|
||||
utils.Log(2, row.Error)
|
||||
|
@ -109,8 +109,8 @@ func (u *Checkin) Update() (int64, error) {
|
|||
return u.Id, row.Error
|
||||
}
|
||||
|
||||
// Create will create a new successful CheckinHit
|
||||
func (u *CheckinHit) Create() (int64, error) {
|
||||
// Create will create a new successful checkinHit
|
||||
func (u *checkinHit) Create() (int64, error) {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now()
|
||||
}
|
||||
|
@ -122,14 +122,14 @@ func (u *CheckinHit) Create() (int64, error) {
|
|||
return u.Id, row.Error
|
||||
}
|
||||
|
||||
// Ago returns the duration of time between now and the last successful CheckinHit
|
||||
func (f *CheckinHit) Ago() string {
|
||||
// Ago returns the duration of time between now and the last successful checkinHit
|
||||
func (f *checkinHit) Ago() string {
|
||||
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
|
||||
return got
|
||||
}
|
||||
|
||||
// RecheckCheckinFailure will check if a Service Checkin has been reported yet
|
||||
func (c *Checkin) RecheckCheckinFailure(guard chan struct{}) {
|
||||
// RecheckCheckinFailure will check if a Service checkin has been reported yet
|
||||
func (c *checkin) RecheckCheckinFailure(guard chan struct{}) {
|
||||
between := time.Now().Sub(time.Now()).Seconds()
|
||||
if between > float64(c.Interval) {
|
||||
fmt.Println("rechecking every 15 seconds!")
|
||||
|
|
|
@ -61,12 +61,12 @@ func usersDB() *gorm.DB {
|
|||
return DbSession.Model(&types.User{})
|
||||
}
|
||||
|
||||
// checkinDB returns the Checkin records for a service
|
||||
// checkinDB returns the checkin records for a service
|
||||
func checkinDB() *gorm.DB {
|
||||
return DbSession.Model(&types.Checkin{})
|
||||
}
|
||||
|
||||
// checkinHitsDB returns the 'hits' from the Checkin record
|
||||
// checkinHitsDB returns the 'hits' from the checkin record
|
||||
func checkinHitsDB() *gorm.DB {
|
||||
return DbSession.Model(&types.CheckinHit{})
|
||||
}
|
||||
|
@ -101,26 +101,26 @@ func (s *Hit) AfterFind() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// AfterFind for Failure will set the timezone
|
||||
func (f *Failure) AfterFind() (err error) {
|
||||
// AfterFind for failure will set the timezone
|
||||
func (f *failure) AfterFind() (err error) {
|
||||
f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
|
||||
return
|
||||
}
|
||||
|
||||
// AfterFind for USer will set the timezone
|
||||
func (u *User) AfterFind() (err error) {
|
||||
func (u *user) AfterFind() (err error) {
|
||||
u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
|
||||
return
|
||||
}
|
||||
|
||||
// AfterFind for Checkin will set the timezone
|
||||
func (s *Checkin) AfterFind() (err error) {
|
||||
// AfterFind for checkin will set the timezone
|
||||
func (s *checkin) AfterFind() (err error) {
|
||||
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
|
||||
return
|
||||
}
|
||||
|
||||
// AfterFind for CheckinHit will set the timezone
|
||||
func (s *CheckinHit) AfterFind() (err error) {
|
||||
// AfterFind for checkinHit will set the timezone
|
||||
func (s *checkinHit) AfterFind() (err error) {
|
||||
s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
|
||||
return
|
||||
}
|
||||
|
@ -133,16 +133,16 @@ func (u *Hit) BeforeCreate() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// BeforeCreate for Failure will set CreatedAt to UTC
|
||||
func (u *Failure) BeforeCreate() (err error) {
|
||||
// BeforeCreate for failure will set CreatedAt to UTC
|
||||
func (u *failure) BeforeCreate() (err error) {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now().UTC()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BeforeCreate for User will set CreatedAt to UTC
|
||||
func (u *User) BeforeCreate() (err error) {
|
||||
// BeforeCreate for user will set CreatedAt to UTC
|
||||
func (u *user) BeforeCreate() (err error) {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now().UTC()
|
||||
}
|
||||
|
@ -157,16 +157,16 @@ func (u *Service) BeforeCreate() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// BeforeCreate for Checkin will set CreatedAt to UTC
|
||||
func (u *Checkin) BeforeCreate() (err error) {
|
||||
// BeforeCreate for checkin will set CreatedAt to UTC
|
||||
func (u *checkin) BeforeCreate() (err error) {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now().UTC()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BeforeCreate for CheckinHit will set CreatedAt to UTC
|
||||
func (u *CheckinHit) BeforeCreate() (err error) {
|
||||
// BeforeCreate for checkinHit will set CreatedAt to UTC
|
||||
func (u *checkinHit) BeforeCreate() (err error) {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now().UTC()
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ import (
|
|||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func injectDatabase() {
|
||||
Configs.Connect(false, utils.Directory)
|
||||
}
|
||||
|
||||
// ExportIndexHTML returns the HTML of the index page as a string
|
||||
func ExportIndexHTML() string {
|
||||
source.Assets()
|
||||
injectDatabase()
|
||||
|
@ -83,6 +83,7 @@ func ExportIndexHTML() string {
|
|||
return result
|
||||
}
|
||||
|
||||
// ExportChartsJs renders the charts for the index page
|
||||
func ExportChartsJs() string {
|
||||
render, err := source.JsBox.String("charts.js")
|
||||
if err != nil {
|
||||
|
@ -102,8 +103,3 @@ func ExportChartsJs() string {
|
|||
result := tpl.String()
|
||||
return result
|
||||
}
|
||||
|
||||
func SaveFile(filename string, data []byte) error {
|
||||
err := ioutil.WriteFile(filename, data, 0644)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type Failure struct {
|
||||
type failure struct {
|
||||
*types.Failure
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@ func (s *Service) CreateFailure(f *types.Failure) (int64, error) {
|
|||
}
|
||||
|
||||
// AllFailures will return all failures attached to a service
|
||||
func (s *Service) AllFailures() []*Failure {
|
||||
var fails []*Failure
|
||||
func (s *Service) AllFailures() []*failure {
|
||||
var fails []*failure
|
||||
col := failuresDB().Where("service = ?", s.Id).Order("id desc")
|
||||
err := col.Find(&fails)
|
||||
if err.Error != nil {
|
||||
|
@ -56,30 +56,30 @@ func (s *Service) AllFailures() []*Failure {
|
|||
}
|
||||
|
||||
// DeleteFailures will delete all failures for a service
|
||||
func (u *Service) DeleteFailures() {
|
||||
err := DbSession.Exec(`DELETE FROM failures WHERE service = ?`, u.Id)
|
||||
func (s *Service) DeleteFailures() {
|
||||
err := DbSession.Exec(`DELETE FROM failures WHERE service = ?`, s.Id)
|
||||
if err.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("failed to delete all failures: %v", err))
|
||||
}
|
||||
u.Failures = nil
|
||||
s.Failures = nil
|
||||
}
|
||||
|
||||
// LimitedFailures will return the last 10 failures from a service
|
||||
func (s *Service) LimitedFailures() []*Failure {
|
||||
var failArr []*Failure
|
||||
func (s *Service) LimitedFailures() []*failure {
|
||||
var failArr []*failure
|
||||
col := failuresDB().Where("service = ?", s.Id).Order("id desc").Limit(10)
|
||||
col.Find(&failArr)
|
||||
return failArr
|
||||
}
|
||||
|
||||
// Ago returns a human readable timestamp for a failure
|
||||
func (f *Failure) Ago() string {
|
||||
func (f *failure) Ago() string {
|
||||
got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
|
||||
return got
|
||||
}
|
||||
|
||||
// Delete will remove a failure record from the database
|
||||
func (f *Failure) Delete() error {
|
||||
func (f *failure) Delete() error {
|
||||
db := failuresDB().Delete(f)
|
||||
return db.Error
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ func (s *Service) TotalFailuresSince(ago time.Time) (uint64, error) {
|
|||
}
|
||||
|
||||
// ParseError returns a human readable error for a failure
|
||||
func (f *Failure) ParseError() string {
|
||||
func (f *failure) ParseError() string {
|
||||
err := strings.Contains(f.Issue, "connection reset by peer")
|
||||
if err {
|
||||
return fmt.Sprintf("Connection Reset")
|
||||
|
|
|
@ -22,15 +22,15 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
allowed_vars = []string{"host", "username", "password", "port", "api_key", "api_secret", "var1", "var2"}
|
||||
allowedVars = []string{"host", "username", "password", "port", "api_key", "api_secret", "var1", "var2"}
|
||||
)
|
||||
|
||||
func checkNotifierForm(n Notifier) error {
|
||||
notifier := asNotification(n)
|
||||
for _, f := range notifier.Form {
|
||||
contains := contains(f.DbField, allowed_vars)
|
||||
contains := contains(f.DbField, allowedVars)
|
||||
if !contains {
|
||||
return errors.New(fmt.Sprintf("the DbField '%v' is not allowed, allowed vars: %v", f.DbField, allowed_vars))
|
||||
return errors.New(fmt.Sprintf("the DbField '%v' is not allowed, allowed vars: %v", f.DbField, allowedVars))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -110,7 +110,7 @@ func OnUpdatedCore(c *types.Core) {
|
|||
}
|
||||
}
|
||||
|
||||
// OnUpdatedCore is triggered when the CoreApp settings are saved - CoreEvents interface
|
||||
// OnStart is triggered when the Statup service has started
|
||||
func OnStart(c *types.Core) {
|
||||
for _, comm := range AllCommunications {
|
||||
if isType(comm, new(CoreEvents)) && isEnabled(comm) && inLimits(comm) {
|
||||
|
@ -128,7 +128,7 @@ func OnNewNotifier(n *Notification) {
|
|||
}
|
||||
}
|
||||
|
||||
// NotifierEvents interface
|
||||
// OnUpdatedNotifier is triggered when a notifier has been updated
|
||||
func OnUpdatedNotifier(n *Notification) {
|
||||
for _, comm := range AllCommunications {
|
||||
if isType(comm, new(NotifierEvents)) && isEnabled(comm) && inLimits(comm) {
|
||||
|
|
|
@ -28,8 +28,10 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
AllCommunications []types.AllNotifiers // AllCommunications holds all the loaded notifiers
|
||||
db *gorm.DB // db holds the Statup database connection
|
||||
// AllCommunications holds all the loaded notifiers
|
||||
AllCommunications []types.AllNotifiers
|
||||
// db holds the Statup database connection
|
||||
db *gorm.DB
|
||||
)
|
||||
|
||||
// Notification contains all the fields for a Statup Notifier.
|
||||
|
@ -225,7 +227,7 @@ func SelectNotifier(method string) (*Notification, Notifier, error) {
|
|||
for _, comm := range AllCommunications {
|
||||
n, ok := comm.(Notifier)
|
||||
if !ok {
|
||||
return nil, nil, errors.New(fmt.Sprintf("incorrect notification type: %v", reflect.TypeOf(n).String()))
|
||||
return nil, nil, fmt.Errorf("incorrect notification type: %v", reflect.TypeOf(n).String())
|
||||
}
|
||||
notifier := n.Select()
|
||||
if notifier.Method == method {
|
||||
|
@ -305,31 +307,31 @@ func install(n Notifier) error {
|
|||
}
|
||||
|
||||
// LastSent returns a time.Duration of the last sent notification for the notifier
|
||||
func (f *Notification) LastSent() time.Duration {
|
||||
if len(f.logs) == 0 {
|
||||
func (n *Notification) LastSent() time.Duration {
|
||||
if len(n.logs) == 0 {
|
||||
return time.Duration(0)
|
||||
}
|
||||
last := f.Logs()[0]
|
||||
last := n.Logs()[0]
|
||||
since := time.Since(last.Timestamp)
|
||||
return since
|
||||
}
|
||||
|
||||
// SentLastHour returns the total amount of notifications sent in last 1 hour
|
||||
func (f *Notification) SentLastHour() int {
|
||||
func (n *Notification) SentLastHour() int {
|
||||
since := time.Now().Add(-1 * time.Hour)
|
||||
return f.SentLast(since)
|
||||
return n.SentLast(since)
|
||||
}
|
||||
|
||||
// SentLastMinute returns the total amount of notifications sent in last 1 minute
|
||||
func (f *Notification) SentLastMinute() int {
|
||||
func (n *Notification) SentLastMinute() int {
|
||||
since := time.Now().Add(-1 * time.Minute)
|
||||
return f.SentLast(since)
|
||||
return n.SentLast(since)
|
||||
}
|
||||
|
||||
// SentLast accept a time.Time and returns the amount of sent notifications within your time to current
|
||||
func (f *Notification) SentLast(since time.Time) int {
|
||||
func (n *Notification) SentLast(since time.Time) int {
|
||||
sent := 0
|
||||
for _, v := range f.Logs() {
|
||||
for _, v := range n.Logs() {
|
||||
lastTime := time.Time(v.Time)
|
||||
if lastTime.After(since) {
|
||||
sent++
|
||||
|
@ -387,21 +389,21 @@ func inLimits(n interface{}) bool {
|
|||
}
|
||||
|
||||
// WithinLimits returns true if the notifier is within its sending limits
|
||||
func (notify *Notification) WithinLimits() (bool, error) {
|
||||
if notify.SentLastMinute() == 0 {
|
||||
func (n *Notification) WithinLimits() (bool, error) {
|
||||
if n.SentLastMinute() == 0 {
|
||||
return true, nil
|
||||
}
|
||||
if notify.SentLastMinute() >= notify.Limits {
|
||||
return false, errors.New(fmt.Sprintf("notifier sent %v out of %v in last minute", notify.SentLastMinute(), notify.Limits))
|
||||
if n.SentLastMinute() >= n.Limits {
|
||||
return false, fmt.Errorf("notifier sent %v out of %v in last minute", n.SentLastMinute(), n.Limits)
|
||||
}
|
||||
if notify.Delay.Seconds() == 0 {
|
||||
notify.Delay = time.Duration(500 * time.Millisecond)
|
||||
if n.Delay.Seconds() == 0 {
|
||||
n.Delay = time.Duration(500 * time.Millisecond)
|
||||
}
|
||||
if notify.LastSent().Seconds() == 0 {
|
||||
if n.LastSent().Seconds() == 0 {
|
||||
return true, nil
|
||||
}
|
||||
if notify.Delay.Seconds() >= notify.LastSent().Seconds() {
|
||||
return false, errors.New(fmt.Sprintf("notifiers delay (%v) is greater than last message sent (%v)", notify.Delay.Seconds(), notify.LastSent().Seconds()))
|
||||
if n.Delay.Seconds() >= n.LastSent().Seconds() {
|
||||
return false, fmt.Errorf("notifiers delay (%v) is greater than last message sent (%v)", n.Delay.Seconds(), n.LastSent().Seconds())
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ func insertSampleUsers() {
|
|||
u3.Create()
|
||||
}
|
||||
|
||||
// InsertSampleData will create the example/dummy services for a brand new Statup installation
|
||||
// InsertLargeSampleData will create the example/dummy services for testing the Statup server
|
||||
func InsertLargeSampleData() error {
|
||||
insertSampleCore()
|
||||
InsertSampleData()
|
||||
|
|
|
@ -52,8 +52,8 @@ func SelectService(id int64) *Service {
|
|||
}
|
||||
|
||||
// Checkins will return a slice of Checkins for a Service
|
||||
func (s *Service) Checkins() []*Checkin {
|
||||
var checkin []*Checkin
|
||||
func (s *Service) Checkins() []*checkin {
|
||||
var checkin []*checkin
|
||||
checkinDB().Where("service = ?", s.Id).Find(&checkin)
|
||||
return checkin
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ type DateScanObj struct {
|
|||
}
|
||||
|
||||
// lastFailure returns the last failure a service had
|
||||
func (s *Service) lastFailure() *Failure {
|
||||
func (s *Service) lastFailure() *failure {
|
||||
limited := s.LimitedFailures()
|
||||
if len(limited) == 0 {
|
||||
return nil
|
||||
|
|
|
@ -23,37 +23,37 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
type user struct {
|
||||
*types.User
|
||||
}
|
||||
|
||||
// ReturnUser returns *core.User based off a *types.User
|
||||
func ReturnUser(u *types.User) *User {
|
||||
return &User{u}
|
||||
// ReturnUser returns *core.user based off a *types.user
|
||||
func ReturnUser(u *types.User) *user {
|
||||
return &user{u}
|
||||
}
|
||||
|
||||
// SelectUser returns the User based on the user's ID.
|
||||
func SelectUser(id int64) (*User, error) {
|
||||
var user User
|
||||
// SelectUser returns the user based on the user's ID.
|
||||
func SelectUser(id int64) (*user, error) {
|
||||
var user user
|
||||
err := usersDB().First(&user, id)
|
||||
return &user, err.Error
|
||||
}
|
||||
|
||||
// SelectUser returns the User based on the user's username
|
||||
func SelectUsername(username string) (*User, error) {
|
||||
var user User
|
||||
// SelectUsername returns the user based on the user's username
|
||||
func SelectUsername(username string) (*user, error) {
|
||||
var user user
|
||||
res := usersDB().Where("username = ?", username)
|
||||
err := res.First(&user)
|
||||
return &user, err.Error
|
||||
}
|
||||
|
||||
// Delete will remove the user record from the database
|
||||
func (u *User) Delete() error {
|
||||
func (u *user) Delete() error {
|
||||
return usersDB().Delete(u).Error
|
||||
}
|
||||
|
||||
// Update will update the user's record in database
|
||||
func (u *User) Update() error {
|
||||
func (u *user) Update() error {
|
||||
u.Password = utils.HashPassword(u.Password)
|
||||
u.ApiKey = utils.NewSHA1Hash(5)
|
||||
u.ApiSecret = utils.NewSHA1Hash(10)
|
||||
|
@ -61,7 +61,7 @@ func (u *User) Update() error {
|
|||
}
|
||||
|
||||
// Create will insert a new user into the database
|
||||
func (u *User) Create() (int64, error) {
|
||||
func (u *user) Create() (int64, error) {
|
||||
u.CreatedAt = time.Now()
|
||||
u.Password = utils.HashPassword(u.Password)
|
||||
u.ApiKey = utils.NewSHA1Hash(5)
|
||||
|
@ -78,8 +78,8 @@ func (u *User) Create() (int64, error) {
|
|||
}
|
||||
|
||||
// SelectAllUsers returns all users
|
||||
func SelectAllUsers() ([]*User, error) {
|
||||
var users []*User
|
||||
func SelectAllUsers() ([]*user, error) {
|
||||
var users []*user
|
||||
db := usersDB().Find(&users)
|
||||
if db.Error != nil {
|
||||
utils.Log(3, fmt.Sprintf("Failed to load all users. %v", db.Error))
|
||||
|
@ -87,9 +87,9 @@ func SelectAllUsers() ([]*User, error) {
|
|||
return users, db.Error
|
||||
}
|
||||
|
||||
// AuthUser will return the User and a boolean if authentication was correct.
|
||||
// AuthUser will return the user and a boolean if authentication was correct.
|
||||
// AuthUser accepts username, and password as a string
|
||||
func AuthUser(username, password string) (*User, bool) {
|
||||
func AuthUser(username, password string) (*user, bool) {
|
||||
user, err := SelectUsername(username)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
|
|
|
@ -244,7 +244,7 @@ func TestUsersEditHandler(t *testing.T) {
|
|||
body := rr.Body.String()
|
||||
assert.Equal(t, 200, rr.Code)
|
||||
assert.Contains(t, body, "<title>Statup | admin</title>")
|
||||
assert.Contains(t, body, "<h3>User admin</h3>")
|
||||
assert.Contains(t, body, "<h3>user admin</h3>")
|
||||
assert.Contains(t, body, "value=\"info@statup.io\"")
|
||||
assert.Contains(t, body, "value=\"##########\"")
|
||||
assert.Contains(t, body, "Statup made with ❤️")
|
||||
|
|
|
@ -22,10 +22,6 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
type index struct {
|
||||
Core *core.Core
|
||||
}
|
||||
|
||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if core.Configs == nil {
|
||||
http.Redirect(w, r, "/setup", http.StatusSeeOther)
|
||||
|
@ -38,6 +34,7 @@ func trayHandler(w http.ResponseWriter, r *http.Request) {
|
|||
executeResponse(w, r, "tray.html", core.CoreApp, nil)
|
||||
}
|
||||
|
||||
// DesktopInit will run the Statup server on a specific IP and port using SQLite database
|
||||
func DesktopInit(ip string, port int) {
|
||||
var err error
|
||||
exists := utils.FileExists(utils.Directory + "/statup.db")
|
||||
|
|
|
@ -44,7 +44,7 @@ func prometheusHandler(w http.ResponseWriter, r *http.Request) {
|
|||
system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services))
|
||||
metrics = append(metrics, system)
|
||||
for _, ser := range core.CoreApp.Services {
|
||||
v := ser.(*core.Service)
|
||||
v := ser.Select()
|
||||
online := 1
|
||||
if !v.Online {
|
||||
online = 0
|
||||
|
|
|
@ -61,11 +61,16 @@ $('form').submit(function() {
|
|||
|
||||
$('select#service_type').on('change', function() {
|
||||
var selected = $('#service_type option:selected').val();
|
||||
var typeLabel = $('#service_type_label');
|
||||
if (selected === 'tcp' || selected === 'udp') {
|
||||
if (selected === 'tcp') {
|
||||
typeLabel.html('TCP Port')
|
||||
} else {
|
||||
typeLabel.html('UDP Port')
|
||||
}
|
||||
$('#service_port').parent().parent().removeClass('d-none');
|
||||
$('#service_check_type').parent().parent().addClass('d-none');
|
||||
$('#service_url').attr('placeholder', 'localhost');
|
||||
|
||||
$('#post_data').parent().parent().addClass('d-none');
|
||||
$('#service_response').parent().parent().addClass('d-none');
|
||||
$('#service_response_code').parent().parent().addClass('d-none');
|
||||
|
@ -75,10 +80,8 @@ $('select#service_type').on('change', function() {
|
|||
$('#service_response_code').parent().parent().removeClass('d-none');
|
||||
$('#service_check_type').parent().parent().removeClass('d-none');
|
||||
$('#service_url').attr('placeholder', 'https://google.com');
|
||||
|
||||
$('#service_port').parent().parent().addClass('d-none');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function AjaxChart(chart, service, start=0, end=9999999999, group="hour") {
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row{{if eq .Type ""}} d-none{{else if eq .Type "http"}} d-none{{end}}">
|
||||
<label for="service_port" class="col-sm-4 col-form-label">TCP Port</label>
|
||||
<label id="service_type_label" for="service_port" class="col-sm-4 col-form-label">TCP Port</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="number" name="port" class="form-control" value="{{if ne .Port 0}}{{.Port}}{{end}}" id="service_port" placeholder="8080">
|
||||
</div>
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// FormatDuration converts a time.Duration into a string
|
||||
func FormatDuration(d time.Duration) string {
|
||||
var out string
|
||||
if d.Hours() >= 24 {
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/ararog/timeago"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
@ -29,6 +30,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// Directory returns the current path or the STATUP_DIR environment variable
|
||||
Directory string
|
||||
)
|
||||
|
||||
|
@ -207,3 +209,9 @@ func DurationReadable(d time.Duration) string {
|
|||
}
|
||||
return d.String()
|
||||
}
|
||||
|
||||
// SaveFile
|
||||
func SaveFile(filename string, data []byte) error {
|
||||
err := ioutil.WriteFile(filename, data, 0644)
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue