diff --git a/.gitignore b/.gitignore index fd1d97de..402c82c0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ source/rice-box.go sass .DS_Store source/css/base.css.map -/dev/test/node_modules/ +dev/test/node_modules diff --git a/Makefile b/Makefile index f1f77b06..6f8f7707 100644 --- a/Makefile +++ b/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 diff --git a/cmd/cli.go b/cmd/cli.go index c8dc3949..64199af6 100644 --- a/cmd/cli.go +++ b/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) diff --git a/cmd/main.go b/cmd/main.go index 959258d2..e82159db 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -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 ) diff --git a/cmd/main_test.go b/cmd/main_test.go index 5e5dec06..96eeba95 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -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() diff --git a/core/checker.go b/core/checker.go index 39857dac..bf0df359 100644 --- a/core/checker.go +++ b/core/checker.go @@ -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 { diff --git a/core/checkin.go b/core/checkin.go index c40e8986..477d8ff3 100644 --- a/core/checkin.go +++ b/core/checkin.go @@ -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!") diff --git a/core/database.go b/core/database.go index c5ec8a92..85272878 100644 --- a/core/database.go +++ b/core/database.go @@ -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() } diff --git a/core/export.go b/core/export.go index c6608242..fe4b6529 100644 --- a/core/export.go +++ b/core/export.go @@ -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 -} diff --git a/core/failures.go b/core/failures.go index d4b2e698..116b56b5 100644 --- a/core/failures.go +++ b/core/failures.go @@ -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") diff --git a/core/notifier/audit.go b/core/notifier/audit.go index 0a3ea413..ea1b83ef 100644 --- a/core/notifier/audit.go +++ b/core/notifier/audit.go @@ -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 diff --git a/core/notifier/events.go b/core/notifier/events.go index 8cbe88a2..384a2260 100644 --- a/core/notifier/events.go +++ b/core/notifier/events.go @@ -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) { diff --git a/core/notifier/notifiers.go b/core/notifier/notifiers.go index 5aa590d8..c746afc6 100644 --- a/core/notifier/notifiers.go +++ b/core/notifier/notifiers.go @@ -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 } diff --git a/core/sample.go b/core/sample.go index 477045c7..5e355d3f 100644 --- a/core/sample.go +++ b/core/sample.go @@ -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() diff --git a/core/services.go b/core/services.go index 5a811cc6..02c32b71 100644 --- a/core/services.go +++ b/core/services.go @@ -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 diff --git a/core/users.go b/core/users.go index f83fc898..b1b3f4eb 100644 --- a/core/users.go +++ b/core/users.go @@ -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) diff --git a/handlers/handlers_test.go b/handlers/handlers_test.go index 936e2348..8b55e7ba 100644 --- a/handlers/handlers_test.go +++ b/handlers/handlers_test.go @@ -244,7 +244,7 @@ func TestUsersEditHandler(t *testing.T) { body := rr.Body.String() assert.Equal(t, 200, rr.Code) assert.Contains(t, body, "Statup | admin") - assert.Contains(t, body, "

User admin

") + assert.Contains(t, body, "

user admin

") assert.Contains(t, body, "value=\"info@statup.io\"") assert.Contains(t, body, "value=\"##########\"") assert.Contains(t, body, "Statup made with ❤️") diff --git a/handlers/index.go b/handlers/index.go index 05fddf0f..56c756eb 100644 --- a/handlers/index.go +++ b/handlers/index.go @@ -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") diff --git a/handlers/prometheus.go b/handlers/prometheus.go index 3369b0ea..5b338024 100644 --- a/handlers/prometheus.go +++ b/handlers/prometheus.go @@ -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 diff --git a/source/js/main.js b/source/js/main.js index afdc286a..28c3237d 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -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") { diff --git a/source/tmpl/form_service.html b/source/tmpl/form_service.html index 0f34575c..0575068c 100644 --- a/source/tmpl/form_service.html +++ b/source/tmpl/form_service.html @@ -54,7 +54,7 @@
- +
diff --git a/utils/time.go b/utils/time.go index c0688840..71777617 100644 --- a/utils/time.go +++ b/utils/time.go @@ -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 { diff --git a/utils/utils.go b/utils/utils.go index d18b8a70..6c607ef9 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -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 +}