diff --git a/.gitignore b/.gitignore index 323a4ffb..ae61a010 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,11 @@ assets *.log .env logs -dev/test/node_modules +/dev/test/node_modules dev/test/cypress/videos dev/test/cypress/screenshots dev/test/app source/rice-box.go -sass \ No newline at end of file +sass +.DS_Store +source/css/base.css.map diff --git a/.travis.yml b/.travis.yml index b66c780b..0451fd59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ before_script: script: - make test-all - - if [[ "$TRAVIS_BRANCH" == "master" ]]; then make coverage; fi + - if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then make coverage; fi after_success: - - if [[ "$TRAVIS_BRANCH" == "master" ]]; then make travis-build; fi + - if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then make travis-build; fi diff --git a/Makefile b/Makefile index 0882ee6a..e489ff94 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=0.46 +VERSION=0.47 BINARY_NAME=statup GOPATH:=$(GOPATH) GOCMD=go @@ -72,10 +72,10 @@ docker-run: docker docker-dev: clean docker build -t hunterlong/statup:dev -f dev/Dockerfile-dev . -docker-push-dev: docker-base docker-dev docker-test +docker-push-dev: docker-base docker-dev docker-cypress docker push hunterlong/statup:dev docker push hunterlong/statup:base - docker push hunterlong/statup:test + docker push hunterlong/statup:cypress docker-push-latest: docker docker push hunterlong/statup:latest @@ -83,15 +83,17 @@ docker-push-latest: docker docker-run-dev: docker-dev docker run -t -p 8080:8080 hunterlong/statup:dev -docker-test: docker-dev clean - docker build -t hunterlong/statup:test -f dev/Dockerfile-test . +docker-cypress: clean + GOPATH=$(GOPATH) xgo -out statup -go 1.10.x -ldflags "-X main.VERSION=$(VERSION) -X main.COMMIT=$(TRAVIS_COMMIT)" --targets=linux/amd64 ./cmd + docker build -t hunterlong/statup:cypress -f dev/Dockerfile-cypress . + rm -f statup -docker-run-test: docker-test - docker run -t -p 8080:8080 --entrypoint "go test -v -p=1 $(BUILDVERSION) ./..." hunterlong/statup:test +docker-run-cypress: docker-cypress + docker run -t hunterlong/statup:cypress docker-base: clean wget -q https://assets.statup.io/sass && chmod +x sass - $(XGO) --targets=linux/amd64 -ldflags="-X main.VERSION=$(VERSION) -X main.COMMIT=$(TRAVIS_COMMIT) -linkmode external -extldflags -static" -out alpine ./cmd + $(XGO) --targets=linux/amd64 -ldflags="-X main.VERSION=$(VERSION) -linkmode external -extldflags -static" -out alpine ./cmd docker build -t hunterlong/statup:base -f dev/Dockerfile-base . docker-build-base: @@ -124,13 +126,13 @@ dev-deps: dep clean: rm -rf ./{logs,assets,plugins,statup.db,config.yml,.sass-cache,config.yml,statup,build} - rm -rf cmd/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf core/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf handlers/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf notifiers/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf source/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf types/{logs,assets,plugins,statup.db,config.yml,.sass-cache} - rm -rf utils/{logs,assets,plugins,statup.db,config.yml,.sass-cache} + rm -rf cmd/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf core/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf handlers/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf notifiers/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf source/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf types/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} + rm -rf utils/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log} rm -rf dev/test/cypress/videos rm -rf .sass-cache rm -f coverage.out @@ -167,7 +169,7 @@ publish-homebrew: curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token $(TRAVIS_API)" -d $(PUBLISH_BODY) https://api.travis-ci.com/repo/hunterlong%2Fhomebrew-statup/requests cypress-install: - cd /test && npm install + cd dev/test && npm install cypress-test: clean cypress-install cd dev/test && npm test diff --git a/cmd/cli.go b/cmd/cli.go index f44d7cb9..96d4fe77 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -132,7 +132,7 @@ func RunOnce() { if err != nil { utils.Log(4, "config.yml file not found") } - err = core.DbConnection(core.Configs.Connection, false, ".") + err = core.DbConnection(core.Configs.Connection, false, utils.Directory) if err != nil { utils.Log(4, err) } @@ -140,12 +140,12 @@ func RunOnce() { if err != nil { fmt.Println("Core database was not found, Statup is not setup yet.") } - core.CoreApp.Services, err = core.SelectAllServices() + core.CoreApp.SelectAllServices() if err != nil { utils.Log(4, err) } - for _, s := range core.CoreApp.Services { - out := core.ServiceCheck(s, true) + for _, s := range core.CoreApp.DbServices { + out := core.ServiceCheck(core.ReturnService(s), true) fmt.Printf(" Service %v | URL: %v | Latency: %0.0fms | Online: %v\n", out.Name, out.Domain, (out.Latency * 1000), out.Online) } } @@ -194,7 +194,7 @@ func TestPlugin(plug types.PluginActions) { core.OnSuccess(core.SelectService(1)) fmt.Println("\n" + BRAKER) fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'") - fakeFailD := core.FailureData{ + fakeFailD := &types.Failure{ Issue: "No issue, just testing this plugin. This would include HTTP failure information though", } core.OnFailure(core.SelectService(1), fakeFailD) @@ -260,14 +260,14 @@ func FakeSeed(plug types.PluginActions) { Domain: "https://google.com", Method: "GET", }} - core.CreateService(fakeSrv) + fakeSrv.Create() fakeSrv2 := &core.Service{Service: &types.Service{ Name: "Awesome Plugin Service", Domain: "https://netflix.com", Method: "GET", }} - core.CreateService(fakeSrv2) + fakeSrv2.Create() fakeUser := &types.User{ Id: 6334, @@ -277,7 +277,7 @@ func FakeSeed(plug types.PluginActions) { Admin: true, CreatedAt: time.Now(), } - core.CreateUser(fakeUser) + fakeUser.Create() fakeUser = &types.User{ Id: 6335, @@ -286,28 +286,28 @@ func FakeSeed(plug types.PluginActions) { Email: "info@awesome.com", CreatedAt: time.Now(), } - core.CreateUser(fakeUser) + fakeUser.Create() for i := 0; i <= 50; i++ { - dd := core.HitData{ + dd := &types.Hit{ Latency: rand.Float64(), } - core.CreateServiceHit(fakeSrv, dd) + fakeSrv.CreateHit(dd) - dd = core.HitData{ + dd = &types.Hit{ Latency: rand.Float64(), } - core.CreateServiceHit(fakeSrv2, dd) + fakeSrv2.CreateHit(dd) - fail := core.FailureData{ + fail := &types.Failure{ Issue: "This is not an issue, but it would container HTTP response errors.", } - core.CreateServiceFailure(fakeSrv, fail) + fakeSrv.CreateFailure(fail) - fail = core.FailureData{ + fail = &types.Failure{ Issue: "HTTP Status Code 521 did not match 200", } - core.CreateServiceFailure(fakeSrv, fail) + fakeSrv.CreateFailure(fail) } fmt.Println("Seeding example data is complete, running Plugin Tests") diff --git a/cmd/main.go b/cmd/main.go index 999c48bb..74104546 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -95,7 +95,7 @@ func LoadDotEnvs() error { func mainProcess() { var err error - err = core.DbConnection(core.Configs.Connection, false, ".") + err = core.DbConnection(core.Configs.Connection, false, utils.Directory) if err != nil { utils.Log(4, fmt.Sprintf("could not connect to database: %v", err)) } diff --git a/cmd/main_test.go b/cmd/main_test.go index 048bcd7a..caa3ca2a 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -85,7 +85,7 @@ func TestRunAll(t *testing.T) { t.Run(dbt+" Select Core", func(t *testing.T) { RunSelectCoreMYQL(t, dbt) }) - t.Run(dbt+" Select Services", func(t *testing.T) { + t.Run(dbt+" Select DbServices", func(t *testing.T) { RunSelectAllMysqlServices(t) }) t.Run(dbt+" Select Comms", func(t *testing.T) { @@ -104,7 +104,7 @@ func TestRunAll(t *testing.T) { t.Run(dbt+" Select Users", func(t *testing.T) { RunUser_SelectAll(t) }) - t.Run(dbt+" Select Services", func(t *testing.T) { + t.Run(dbt+" Select DbServices", func(t *testing.T) { RunSelectAllServices(t) }) t.Run(dbt+" Select One Service", func(t *testing.T) { @@ -116,6 +116,9 @@ func TestRunAll(t *testing.T) { t.Run(dbt+" Create Hits", func(t *testing.T) { RunCreateService_Hits(t) }) + t.Run(dbt+" Service ToJSON()", func(t *testing.T) { + RunService_ToJSON(t) + }) t.Run(dbt+" Avg Time", func(t *testing.T) { RunService_AvgTime(t) }) @@ -208,7 +211,7 @@ func RunMakeDatabaseConfig(t *testing.T, db string) { //Error error `yaml:"-"` //Location string `yaml:"location"` - config := &core.DbConfig{DbConfig: &types.DbConfig{ + config := &core.DbConfig{&types.DbConfig{ DbConn: db, DbHost: os.Getenv("DB_HOST"), DbUser: os.Getenv("DB_USER"), @@ -265,7 +268,7 @@ func RunSelectCoreMYQL(t *testing.T, db string) { func RunSelectAllMysqlServices(t *testing.T) { var err error - services, err := core.SelectAllServices() + services, err := core.CoreApp.SelectAllServices() assert.Nil(t, err) assert.Equal(t, 5, len(services)) } @@ -285,22 +288,22 @@ func RunUser_SelectAll(t *testing.T) { } func RunUser_Create(t *testing.T) { - user := &types.User{ + user := core.ReturnUser(&types.User{ Username: "admin", Password: "admin", Email: "info@testuser.com", Admin: true, - } - id, err := core.CreateUser(user) + }) + id, err := user.Create() assert.Nil(t, err) assert.Equal(t, int64(1), id) - user2 := &types.User{ + user2 := core.ReturnUser(&types.User{ Username: "superadmin", Password: "admin", Email: "info@adminer.com", Admin: true, - } - id, err = core.CreateUser(user2) + }) + id, err = user2.Create() assert.Nil(t, err) assert.Equal(t, int64(2), id) } @@ -309,7 +312,7 @@ func RunUser_Update(t *testing.T) { user, err := core.SelectUser(1) user.Email = "info@updatedemail.com" assert.Nil(t, err) - err = core.UpdateUser(user) + err = user.Update() assert.Nil(t, err) updatedUser, err := core.SelectUser(1) assert.Nil(t, err) @@ -317,12 +320,12 @@ func RunUser_Update(t *testing.T) { } func RunUser_NonUniqueCreate(t *testing.T) { - user := &types.User{ + user := core.ReturnUser(&types.User{ Username: "admin", Password: "admin", Email: "info@testuser.com", - } - admin, err := core.CreateUser(user) + }) + admin, err := user.Create() assert.Error(t, err) assert.Nil(t, admin) } @@ -331,13 +334,13 @@ func RunUser_Delete(t *testing.T) { user, err := core.SelectUser(2) assert.Nil(t, err) assert.NotNil(t, user) - err = core.DeleteUser(user) + err = user.Delete() assert.Nil(t, err) } func RunSelectAllServices(t *testing.T) { var err error - services, err := core.SelectAllServices() + services, err := core.CoreApp.SelectAllServices() assert.Nil(t, err) assert.Equal(t, 5, len(services)) } @@ -360,12 +363,19 @@ func RunService_Create(t *testing.T) { Method: "GET", Timeout: 30, }} - id, err := core.CreateService(service) + id, err := service.Create() assert.Nil(t, err) assert.Equal(t, int64(6), id) t.Log(service) } +func RunService_ToJSON(t *testing.T) { + service := core.SelectService(1) + assert.NotNil(t, service) + jsoned := service.ToJSON() + assert.NotEmpty(t, jsoned) +} + func RunService_AvgTime(t *testing.T) { service := core.SelectService(1) assert.NotNil(t, service) @@ -401,7 +411,7 @@ func RunBadService_Create(t *testing.T) { Method: "GET", Timeout: 30, }} - id, err := core.CreateService(service) + id, err := service.Create() assert.Nil(t, err) assert.Equal(t, int64(7), id) } @@ -422,14 +432,14 @@ func RunDeleteService(t *testing.T) { assert.Equal(t, "JSON API Tester", service.Name) assert.True(t, service.IsRunning()) t.Log(service.Running) - err := core.DeleteService(service) + err := service.Delete() t.Log(service.Running) assert.False(t, service.IsRunning()) assert.Nil(t, err) } func RunCreateService_Hits(t *testing.T) { - services, err := core.SelectAllServices() + services, err := core.CoreApp.SelectAllServices() assert.Nil(t, err) assert.NotNil(t, services) assert.Equal(t, 6, len(services)) @@ -437,9 +447,9 @@ func RunCreateService_Hits(t *testing.T) { for _, s := range services { var service *core.Service if s.Type == "http" { - service = core.ServiceHTTPCheck(s, true) + service = core.ServiceHTTPCheck(core.ReturnService(s), true) } else { - service = core.ServiceTCPCheck(s, true) + service = core.ServiceTCPCheck(core.ReturnService(s), true) } assert.NotNil(t, service) } diff --git a/core/checker.go b/core/checker.go index ca349b3e..d95eba32 100644 --- a/core/checker.go +++ b/core/checker.go @@ -31,17 +31,16 @@ import ( type FailureData types.FailureData func CheckServices() { - CoreApp.Services, _ = SelectAllServices() - utils.Log(1, fmt.Sprintf("Starting monitoring process for %v Services", len(CoreApp.Services))) - for _, s := range CoreApp.Services { + CoreApp.SelectAllServices() + utils.Log(1, fmt.Sprintf("Starting monitoring process for %v DbServices", len(CoreApp.DbServices))) + for _, ser := range CoreApp.DbServices { //go obj.StartCheckins() - go CheckQueue(s, true) + s := ReturnService(ser) + go s.CheckQueue(true) } } -func CheckQueue(s *Service, record bool) { - s.Checkpoint = time.Now() - +func (s *Service) CheckQueue(record bool) { CheckLoop: for { select { @@ -194,21 +193,21 @@ type HitData struct { func RecordSuccess(s *Service) { s.Online = true s.LastOnline = time.Now() - data := HitData{ + data := &types.Hit{ Latency: s.Latency, } utils.Log(1, fmt.Sprintf("Service %v Successful: %0.2f ms", s.Name, data.Latency*1000)) - CreateServiceHit(s, data) + s.CreateHit(data) OnSuccess(s) } func RecordFailure(s *Service, issue string) { s.Online = false - data := FailureData{ + data := &types.Failure{ Issue: issue, } utils.Log(2, fmt.Sprintf("Service %v Failing: %v", s.Name, issue)) - CreateServiceFailure(s, data) + s.CreateFailure(data) //SendFailureEmail(s) OnFailure(s, data) } diff --git a/core/checkin.go b/core/checkin.go index 80083e28..2099491a 100644 --- a/core/checkin.go +++ b/core/checkin.go @@ -23,14 +23,20 @@ import ( "time" ) -type Checkin types.Checkin +type Checkin struct { + *types.Checkin +} func (c *Checkin) String() string { return c.Api } +func ReturnCheckin(s *types.Checkin) *Checkin { + return &Checkin{Checkin: s} +} + func FindCheckin(api string) *types.Checkin { - for _, ser := range CoreApp.Services { + for _, ser := range CoreApp.DbServices { for _, c := range ser.Checkins { if c.Api == api { return c @@ -40,7 +46,7 @@ func FindCheckin(api string) *types.Checkin { return nil } -func SelectAllCheckins(s *types.Service) []*types.Checkin { +func (s *Service) AllCheckins() []*types.Checkin { var checkins []*types.Checkin col := DbSession.Collection("checkins").Find("service", s.Id).OrderBy("-id") col.All(&checkins) @@ -116,7 +122,7 @@ func (f *Checkin) Ago() string { //} // //func CheckinProcess() { -// for _, s := range CoreApp.Services { +// for _, s := range CoreApp.DbServices { // for _, c := range s.Checkins { // checkin := c // go checkin.Run() diff --git a/core/configs.go b/core/configs.go index 7f162859..b04665b6 100644 --- a/core/configs.go +++ b/core/configs.go @@ -32,7 +32,7 @@ func LoadConfig() (*types.Config, error) { return LoadUsingEnv() } Configs = new(types.Config) - file, err := ioutil.ReadFile("config.yml") + file, err := ioutil.ReadFile(utils.Directory + "/config.yml") if err != nil { return nil, errors.New("config.yml file not found - starting in setup mode") } @@ -74,7 +74,7 @@ func LoadUsingEnv() (*types.Config, error) { CoreApp.UseCdn = true } - dbConfig := &DbConfig{DbConfig: &types.DbConfig{ + dbConfig := &DbConfig{&types.DbConfig{ DbConn: os.Getenv("DB_CONN"), DbHost: os.Getenv("DB_HOST"), DbUser: os.Getenv("DB_USER"), @@ -89,7 +89,7 @@ func LoadUsingEnv() (*types.Config, error) { Email: "info@localhost.com", }} - err := DbConnection(dbConfig.DbConn, true, ".") + err := DbConnection(dbConfig.DbConn, true, utils.Directory) if err != nil { utils.Log(4, err) return nil, err @@ -125,7 +125,7 @@ func LoadUsingEnv() (*types.Config, error) { Email: "info@admin.com", Admin: true, } - CreateUser(admin) + admin.Create() LoadSampleData() diff --git a/core/core.go b/core/core.go index 38947286..9ffa8bfc 100644 --- a/core/core.go +++ b/core/core.go @@ -30,7 +30,6 @@ type PluginRepos types.PluginRepos type Core struct { *types.Core - Services []*Service } var ( @@ -64,7 +63,7 @@ func (c *Core) ToCore() *types.Core { func InitApp() { SelectCore() InsertNotifierDB() - SelectAllServices() + CoreApp.SelectAllServices() CheckServices() CoreApp.Communications = notifiers.Load() go DatabaseMaintence() @@ -72,7 +71,7 @@ func InitApp() { func InsertNotifierDB() error { if DbSession == nil { - err := DbConnection(CoreApp.DbConnection, false, ".") + err := DbConnection(CoreApp.DbConnection, false, utils.Directory) if err != nil { return errors.New("database connection has not been created") } @@ -113,7 +112,7 @@ func (c Core) MobileSASS() string { } func (c Core) AllOnline() bool { - for _, s := range CoreApp.Services { + for _, s := range CoreApp.DbServices { if !s.Online { return false } @@ -146,10 +145,18 @@ func SelectCore() (*Core, error) { CoreApp.Core = c CoreApp.DbConnection = Configs.Connection CoreApp.Version = VERSION - CoreApp.Services, _ = SelectAllServices() + CoreApp.SelectAllServices() if os.Getenv("USE_CDN") == "true" { CoreApp.UseCdn = true } //store = sessions.NewCookieStore([]byte(core.ApiSecret)) return CoreApp, err } + +func (c *Core) Services() []*Service { + var services []*Service + for _, ser := range CoreApp.DbServices { + services = append(services, ReturnService(ser)) + } + return services +} diff --git a/core/core_test.go b/core/core_test.go index 4e76d718..a746bc43 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -42,7 +42,7 @@ func TestNewCore(t *testing.T) { } func TestDbConfig_Save(t *testing.T) { - testConfig = &DbConfig{DbConfig: &types.DbConfig{ + testConfig = &DbConfig{&types.DbConfig{ DbConn: "sqlite", Project: "Tester", Location: dir, diff --git a/core/database.go b/core/database.go index 68789c92..f42dddfc 100644 --- a/core/database.go +++ b/core/database.go @@ -104,7 +104,7 @@ func DbConnection(dbType string, retry bool, location string) error { func waitForDb(dbType string) error { time.Sleep(5 * time.Second) - return DbConnection(dbType, true, ".") + return DbConnection(dbType, true, utils.Directory) } func DatabaseMaintence() { @@ -126,12 +126,12 @@ func DeleteAllSince(table string, date time.Time) { func (c *DbConfig) Save() error { var err error - config, err := os.Create("config.yml") + config, err := os.Create(utils.Directory + "/config.yml") if err != nil { utils.Log(4, err) return err } - data, err := yaml.Marshal(c) + data, err := yaml.Marshal(c.DbConfig) if err != nil { utils.Log(3, err) return err diff --git a/core/events.go b/core/events.go index bce6d6fe..e2525e77 100644 --- a/core/events.go +++ b/core/events.go @@ -35,7 +35,7 @@ func OnSuccess(s *Service) { // TODO convert notifiers to correct type } -func OnFailure(s *Service, f FailureData) { +func OnFailure(s *Service, f *types.Failure) { for _, p := range CoreApp.AllPlugins { p.OnFailure(structs.Map(s)) } @@ -49,7 +49,7 @@ func OnSettingsSaved(c *types.Core) { } } -func OnNewUser(u *types.User) { +func OnNewUser(u *User) { for _, p := range CoreApp.AllPlugins { p.OnNewUser(structs.Map(u)) } diff --git a/core/export.go b/core/export.go index a8878d78..47aed68a 100644 --- a/core/export.go +++ b/core/export.go @@ -26,7 +26,7 @@ import ( func ExportIndexHTML() string { source.Assets() CoreApp.UseCdn = true - //out := index{*CoreApp, CoreApp.Services} + //out := index{*CoreApp, CoreApp.DbServices} nav, _ := source.TmplBox.String("nav.html") footer, _ := source.TmplBox.String("footer.html") render, err := source.TmplBox.String("index.html") diff --git a/core/failures.go b/core/failures.go index fbddf587..b503d74e 100644 --- a/core/failures.go +++ b/core/failures.go @@ -24,17 +24,19 @@ import ( "time" ) -func CreateServiceFailure(s *Service, data FailureData) (int64, error) { - fail := &types.Failure{ - Issue: data.Issue, - Service: s.Id, - CreatedAt: time.Now(), - } - s.Failures = append(s.Failures, fail) +type Failure struct { + *types.Failure +} + +func (s *Service) CreateFailure(f *types.Failure) (int64, error) { + f.CreatedAt = time.Now() + f.Service = s.Id + s.Failures = append(s.Failures, f) col := DbSession.Collection("failures") - uuid, err := col.Insert(fail) + uuid, err := col.Insert(f) if err != nil { utils.Log(3, err) + return 0, err } if uuid == nil { return 0, err @@ -42,12 +44,13 @@ func CreateServiceFailure(s *Service, data FailureData) (int64, error) { return uuid.(int64), err } -func SelectAllFailures(s *types.Service) []*types.Failure { +func (s *Service) AllFailures() []*types.Failure { var fails []*types.Failure col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id") err := col.All(&fails) if err != nil { utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err)) + return nil } return fails } @@ -62,31 +65,25 @@ func DeleteFailures(u *Service) { } func (s *Service) LimitedFailures() []*Failure { - var fails []*types.Failure var failArr []*Failure col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id").Limit(10) - col.All(&fails) - for _, f := range fails { - failArr = append(failArr, MakeFailure(f)) - } + col.All(&failArr) return failArr } -func reverseFailures(input []*types.Failure) []*types.Failure { +func reverseFailures(input []*Failure) []*Failure { if len(input) == 0 { return input } return append(reverseFailures(input[1:]), input[0]) } -func (fail *Failure) Ago() string { - f := fail.ToFailure() +func (f *Failure) Ago() string { got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt) return got } -func (fail *Failure) Delete() error { - f := fail.ToFailure() +func (f *Failure) Delete() error { col := DbSession.Collection("failures").Find("id", f.Id) return col.Delete() } @@ -113,17 +110,7 @@ func (s *Service) TotalFailures24Hours() (uint64, error) { return amount, err } -func (f *Failure) ToFailure() *types.Failure { - return f.F.(*types.Failure) -} - -func MakeFailure(f *types.Failure) *Failure { - fail := &Failure{f} - return fail -} - -func (fail *Failure) ParseError() string { - f := fail.ToFailure() +func (f *Failure) ParseError() string { err := strings.Contains(f.Issue, "operation timed out") if err { return fmt.Sprintf("HTTP Request Timed Out") diff --git a/core/hits.go b/core/hits.go index 07a937d6..9b2f38a3 100644 --- a/core/hits.go +++ b/core/hits.go @@ -22,18 +22,17 @@ import ( "upper.io/db.v3" ) -type Hit types.Hit +type Hit struct { + *types.Hit +} func hitCol() db.Collection { return DbSession.Collection("hits") } -func CreateServiceHit(s *Service, d HitData) (int64, error) { - h := Hit{ - Service: s.Id, - Latency: d.Latency, - CreatedAt: time.Now(), - } +func (s *Service) CreateHit(h *types.Hit) (int64, error) { + h.CreatedAt = time.Now() + h.Service = s.Id uuid, err := hitCol().Insert(h) if uuid == nil { utils.Log(2, err) @@ -42,8 +41,8 @@ func CreateServiceHit(s *Service, d HitData) (int64, error) { return uuid.(int64), err } -func (s *Service) Hits() ([]Hit, error) { - var hits []Hit +func (s *Service) Hits() ([]*Hit, error) { + var hits []*Hit col := hitCol().Find("service", s.Id).OrderBy("-id") err := col.All(&hits) return hits, err @@ -63,8 +62,8 @@ func reverseHits(input []*Hit) []*Hit { return append(reverseHits(input[1:]), input[0]) } -func (s *Service) SelectHitsGroupBy(group string) ([]Hit, error) { - var hits []Hit +func (s *Service) SelectHitsGroupBy(group string) ([]*Hit, error) { + var hits []*Hit col := hitCol().Find("service", s.Id) err := col.All(&hits) return hits, err diff --git a/core/services.go b/core/services.go index fbbcea96..4db96081 100644 --- a/core/services.go +++ b/core/services.go @@ -29,8 +29,8 @@ type Service struct { *types.Service } -type Failure struct { - F interface{} +func ReturnService(s *types.Service) *Service { + return &Service{Service: s} } func serviceCol() db.Collection { @@ -38,32 +38,37 @@ func serviceCol() db.Collection { } func SelectService(id int64) *Service { - for _, s := range CoreApp.Services { + for _, s := range CoreApp.DbServices { if s.Id == id { - return s + return ReturnService(s) } } return nil } -func SelectAllServices() ([]*Service, error) { +func (c *Core) SelectAllServices() ([]*types.Service, error) { var services []*types.Service - var sers []*Service + var servs []*types.Service col := serviceCol().Find() err := col.All(&services) if err != nil { utils.Log(3, fmt.Sprintf("service error: %v", err)) return nil, err } - for _, s := range services { - ser := NewService(s) - ser.Start() - ser.Checkins = SelectAllCheckins(s) - ser.Failures = SelectAllFailures(s) - sers = append(sers, ser) + for _, ser := range services { + single := ReturnService(ser) + single.Start() + single.AllCheckins() + single.AllFailures() + servs = append(servs, single.Service) } - CoreApp.Services = sers - return sers, err + CoreApp.DbServices = servs + return services, err +} + +func (s *Service) ToJSON() string { + data, _ := json.Marshal(s) + return string(data) } func (s *Service) AvgTime() float64 { @@ -104,8 +109,10 @@ type DateScan struct { Value int64 `json:"y"` } -func NewService(s *types.Service) *Service { - return &Service{s} +func (s *Service) lastFailure() *Failure { + limited := s.LimitedFailures() + last := limited[len(limited)-1] + return last } func (s *Service) SmallText() string { @@ -119,8 +126,8 @@ func (s *Service) SmallText() string { } } if len(last) > 0 { - lastFailure := MakeFailure(last[0].ToFailure()) - return fmt.Sprintf("%v on %v", lastFailure.ParseError(), last[0].ToFailure().CreatedAt.Format("Monday 3:04PM, Jan _2 2006")) + lastFailure := s.lastFailure() + return fmt.Sprintf("%v on %v", lastFailure.ParseError(), last[0].CreatedAt.Format("Monday 3:04PM, Jan _2 2006")) } else { return fmt.Sprintf("%v is currently offline", s.Name) } @@ -142,9 +149,7 @@ func GroupDataBy(column string, id int64, tm time.Time, increment string) string func (s *Service) GraphData() string { var d []*DateScan since := time.Now().Add(time.Hour*-24 + time.Minute*0 + time.Second*0) - sql := GroupDataBy("hits", s.Id, since, "minute") - dated, err := DbSession.Query(db.Raw(sql)) if err != nil { utils.Log(2, err) @@ -196,18 +201,29 @@ func (s *Service) AvgUptime() string { return s.TotalUptime } -func RemoveArray(u *Service) []*Service { - var srvcs []*Service - for _, s := range CoreApp.Services { +func RemoveArray(u *Service) []*types.Service { + var srvcs []*types.Service + for _, s := range CoreApp.DbServices { if s.Id != u.Id { srvcs = append(srvcs, s) } } - CoreApp.Services = srvcs + CoreApp.DbServices = srvcs return srvcs } -func DeleteService(u *Service) error { +func updateService(new *Service) { + var services []*types.Service + for _, s := range CoreApp.DbServices { + if s.Id == new.Id { + s = new.Service + } + services = append(services, s) + } + CoreApp.DbServices = services +} + +func (u *Service) Delete() error { res := serviceCol().Find("id", u.Id) err := res.Delete() if err != nil { @@ -220,36 +236,25 @@ func DeleteService(u *Service) error { return err } -func UpdateService(service *Service) *Service { - service.CreatedAt = time.Now() - res := serviceCol().Find("id", service.Id) - err := res.Update(service) +func (u *Service) Update() error { + u.CreatedAt = time.Now() + res := serviceCol().Find("id", u.Id) + err := res.Update(u) if err != nil { - utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", service.Name, err)) - return service + utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", u.Name, err)) + return err } - updateService(service) - CoreApp.Services, err = SelectAllServices() + updateService(u) + CoreApp.SelectAllServices() if err != nil { utils.Log(3, fmt.Sprintf("error selecting all services: %v", err)) - return service + return err } - OnUpdateService(service) - return service + OnUpdateService(u) + return err } -func updateService(new *Service) { - var services []*Service - for _, s := range CoreApp.Services { - if s.Id == new.Id { - s = new - } - services = append(services, s) - } - CoreApp.Services = services -} - -func CreateService(u *Service) (int64, error) { +func (u *Service) Create() (int64, error) { u.CreatedAt = time.Now() uuid, err := serviceCol().Insert(u) if uuid == nil { @@ -258,13 +263,13 @@ func CreateService(u *Service) (int64, error) { } u.Id = uuid.(int64) u.Start() - CoreApp.Services = append(CoreApp.Services, u) + CoreApp.DbServices = append(CoreApp.DbServices, u.Service) return uuid.(int64), err } func CountOnline() int { amount := 0 - for _, s := range CoreApp.Services { + for _, s := range CoreApp.DbServices { if s.Online { amount++ } diff --git a/core/services_test.go b/core/services_test.go index c16e7c0b..640d7810 100644 --- a/core/services_test.go +++ b/core/services_test.go @@ -27,7 +27,7 @@ var ( ) func TestSelectAllServices(t *testing.T) { - services, err := SelectAllServices() + services, err := CoreApp.SelectAllServices() assert.Nil(t, err) assert.Equal(t, 5, len(services)) } @@ -49,19 +49,19 @@ func TestUpdateService(t *testing.T) { assert.Equal(t, "Google", service.Name) srv := service srv.Name = "Updated Google" - newService := UpdateService(srv) - assert.Equal(t, "Updated Google", newService.Name) + err := srv.Update() + assert.Nil(t, err) } func TestUpdateAllServices(t *testing.T) { - services, err := SelectAllServices() + services, err := CoreApp.SelectAllServices() assert.Nil(t, err) for k, s := range services { - srv := s + srv := ReturnService(s) srv.Name = "Changed " + srv.Name srv.Interval = k + 3 - newService := UpdateService(srv) - assert.Contains(t, newService.Name, "Changed") + err := srv.Update() + assert.Nil(t, err) } } @@ -146,7 +146,7 @@ func TestCountOnline(t *testing.T) { } func TestCreateService(t *testing.T) { - s := &Service{Service: &types.Service{ + s := ReturnService(&types.Service{ Name: "That'll do 🐢", Domain: "https://www.youtube.com/watch?v=rjQtzV9IZ0Q", ExpectedStatus: 200, @@ -154,9 +154,9 @@ func TestCreateService(t *testing.T) { Type: "http", Method: "GET", Timeout: 20, - }} + }) var err error - newServiceId, err = CreateService(s) + newServiceId, err = s.Create() assert.Nil(t, err) assert.NotZero(t, newServiceId) newService := SelectService(newServiceId) @@ -170,7 +170,7 @@ func TestViewNewService(t *testing.T) { } func TestCreateFailingHTTPService(t *testing.T) { - s := &Service{Service: &types.Service{ + s := ReturnService(&types.Service{ Name: "Bad URL", Domain: "http://localhost/iamnothere", ExpectedStatus: 200, @@ -178,9 +178,9 @@ func TestCreateFailingHTTPService(t *testing.T) { Type: "http", Method: "GET", Timeout: 5, - }} + }) var err error - newServiceId, err = CreateService(s) + newServiceId, err = s.Create() assert.Nil(t, err) assert.NotZero(t, newServiceId) newService := SelectService(newServiceId) @@ -195,16 +195,16 @@ func TestServiceFailedCheck(t *testing.T) { } func TestCreateFailingTCPService(t *testing.T) { - s := &Service{Service: &types.Service{ + s := ReturnService(&types.Service{ Name: "Bad TCP", Domain: "localhost", Port: 5050, Interval: 30, Type: "tcp", Timeout: 5, - }} + }) var err error - newServiceId, err = CreateService(s) + newServiceId, err = s.Create() assert.Nil(t, err) assert.NotZero(t, newServiceId) newService := SelectService(newServiceId) @@ -219,13 +219,12 @@ func TestServiceFailedTCPCheck(t *testing.T) { } func TestCreateServiceFailure(t *testing.T) { - - fail := FailureData{ - Issue: "This is not an issue, but it would container HTTP response errors.", + fail := &types.Failure{ + Issue: "This is not an issue, but it would container HTTP response errors.", + Method: "http", } service := SelectService(8) - - id, err := CreateServiceFailure(service, fail) + id, err := service.CreateFailure(fail) assert.Nil(t, err) assert.NotZero(t, id) } @@ -233,34 +232,33 @@ func TestCreateServiceFailure(t *testing.T) { func TestDeleteService(t *testing.T) { service := SelectService(newServiceId) - count, err := SelectAllServices() + count, err := CoreApp.SelectAllServices() assert.Nil(t, err) assert.Equal(t, 8, len(count)) - err = DeleteService(service) + err = service.Delete() assert.Nil(t, err) - count, err = SelectAllServices() + count, err = CoreApp.SelectAllServices() assert.Nil(t, err) assert.Equal(t, 7, len(count)) } func TestServiceCloseRoutine(t *testing.T) { - s := new(types.Service) + s := ReturnService(new(types.Service)) s.Name = "example" s.Domain = "https://google.com" s.Type = "http" s.Method = "GET" s.ExpectedStatus = 200 s.Interval = 1 - service := NewService(s) - service.Start() - assert.True(t, service.IsRunning()) - go CheckQueue(service, false) + s.Start() + assert.True(t, s.IsRunning()) + go s.CheckQueue(false) time.Sleep(5 * time.Second) - assert.True(t, service.IsRunning()) - service.Close() - assert.False(t, service.IsRunning()) - service.Close() - assert.False(t, service.IsRunning()) + assert.True(t, s.IsRunning()) + s.Close() + assert.False(t, s.IsRunning()) + s.Close() + assert.False(t, s.IsRunning()) } diff --git a/core/setup.go b/core/setup.go index bfe5df81..6bf38244 100644 --- a/core/setup.go +++ b/core/setup.go @@ -23,7 +23,7 @@ import ( ) func DeleteConfig() { - err := os.Remove("./config.yml") + err := os.Remove(utils.Directory + "/config.yml") if err != nil { utils.Log(3, err) } @@ -35,7 +35,7 @@ type ErrorResponse struct { func LoadSampleData() error { utils.Log(1, "Inserting Sample Data...") - s1 := &Service{Service: &types.Service{ + s1 := ReturnService(&types.Service{ Name: "Google", Domain: "https://google.com", ExpectedStatus: 200, @@ -43,8 +43,8 @@ func LoadSampleData() error { Type: "http", Method: "GET", Timeout: 10, - }} - s2 := &Service{Service: &types.Service{ + }) + s2 := ReturnService(&types.Service{ Name: "Statup Github", Domain: "https://github.com/hunterlong/statup", ExpectedStatus: 200, @@ -52,8 +52,8 @@ func LoadSampleData() error { Type: "http", Method: "GET", Timeout: 20, - }} - s3 := &Service{Service: &types.Service{ + }) + s3 := ReturnService(&types.Service{ Name: "JSON Users Test", Domain: "https://jsonplaceholder.typicode.com/users", ExpectedStatus: 200, @@ -61,8 +61,8 @@ func LoadSampleData() error { Type: "http", Method: "GET", Timeout: 30, - }} - s4 := &Service{Service: &types.Service{ + }) + s4 := ReturnService(&types.Service{ Name: "JSON API Tester", Domain: "https://jsonplaceholder.typicode.com/posts", ExpectedStatus: 201, @@ -72,32 +72,32 @@ func LoadSampleData() error { Method: "POST", PostData: `{ "title": "statup", "body": "bar", "userId": 19999 }`, Timeout: 30, - }} - s5 := &Service{Service: &types.Service{ + }) + s5 := ReturnService(&types.Service{ Name: "Google DNS", Domain: "8.8.8.8", Interval: 20, Type: "tcp", Port: 53, Timeout: 120, - }} - id, err := CreateService(s1) + }) + id, err := s1.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error creating Service %v: %v", id, err)) } - id, err = CreateService(s2) + id, err = s2.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error creating Service %v: %v", id, err)) } - id, err = CreateService(s3) + id, err = s3.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error creating Service %v: %v", id, err)) } - id, err = CreateService(s4) + id, err = s4.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error creating Service %v: %v", id, err)) } - id, err = CreateService(s5) + id, err = s5.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error creating TCP Service %v: %v", id, err)) } diff --git a/core/users.go b/core/users.go index 8c42a468..b4586314 100644 --- a/core/users.go +++ b/core/users.go @@ -23,38 +23,44 @@ import ( "time" ) -type User types.User +type User struct { + *types.User +} -func SelectUser(id int64) (*types.User, error) { - var user *types.User +func ReturnUser(u *types.User) *User { + return &User{User: u} +} + +func SelectUser(id int64) (*User, error) { + var user *User col := DbSession.Collection("users") res := col.Find("id", id) err := res.One(&user) return user, err } -func SelectUsername(username string) (*types.User, error) { - var user *types.User +func SelectUsername(username string) (*User, error) { + var user *User col := DbSession.Collection("users") res := col.Find("username", username) err := res.One(&user) return user, err } -func DeleteUser(u *types.User) error { +func (u *User) Delete() error { col := DbSession.Collection("users") user := col.Find("id", u.Id) return user.Delete() } -func UpdateUser(u *types.User) error { +func (u *User) Update() error { u.CreatedAt = time.Now() col := DbSession.Collection("users") user := col.Find("id", u.Id) return user.Update(u) } -func CreateUser(u *types.User) (int64, error) { +func (u *User) Create() (int64, error) { u.CreatedAt = time.Now() u.Password = utils.HashPassword(u.Password) u.ApiKey = utils.NewSHA1Hash(5) @@ -71,8 +77,8 @@ func CreateUser(u *types.User) (int64, error) { return uuid.(int64), err } -func SelectAllUsers() ([]User, error) { - var users []User +func SelectAllUsers() ([]*User, error) { + var users []*User col := DbSession.Collection("users").Find() err := col.All(&users) if err != nil { @@ -81,7 +87,7 @@ func SelectAllUsers() ([]User, error) { return users, err } -func AuthUser(username, password string) (*types.User, bool) { +func AuthUser(username, password string) (*User, bool) { var auth bool user, err := SelectUsername(username) if err != nil { diff --git a/core/users_test.go b/core/users_test.go index 88878396..6f069193 100644 --- a/core/users_test.go +++ b/core/users_test.go @@ -22,13 +22,13 @@ import ( ) func TestCreateUser(t *testing.T) { - user := &types.User{ + user := ReturnUser(&types.User{ Username: "hunter", Password: "password123", Email: "test@email.com", Admin: true, - } - userId, err := CreateUser(user) + }) + userId, err := user.Create() assert.Nil(t, err) assert.NotZero(t, userId) } @@ -58,7 +58,7 @@ func TestUpdateUser(t *testing.T) { user, err := SelectUser(1) assert.Nil(t, err) user.Username = "updated" - err = UpdateUser(user) + err = user.Update() assert.Nil(t, err) updatedUser, err := SelectUser(1) assert.Nil(t, err) @@ -66,13 +66,13 @@ func TestUpdateUser(t *testing.T) { } func TestCreateUser2(t *testing.T) { - user := &types.User{ + user := ReturnUser(&types.User{ Username: "hunterlong", Password: "password123", Email: "user@email.com", Admin: true, - } - userId, err := CreateUser(user) + }) + userId, err := user.Create() assert.Nil(t, err) assert.NotZero(t, userId) } @@ -108,6 +108,6 @@ func TestCheckPassword(t *testing.T) { func TestDeleteUser(t *testing.T) { user, err := SelectUser(2) assert.Nil(t, err) - err = DeleteUser(user) + err = user.Delete() assert.Nil(t, err) } diff --git a/dev/Dockerfile-cypress b/dev/Dockerfile-cypress new file mode 100644 index 00000000..a921d5be --- /dev/null +++ b/dev/Dockerfile-cypress @@ -0,0 +1,15 @@ +FROM cypress/browsers:chrome67 +MAINTAINER "Hunter Long (https://github.com/hunterlong)" +# Statup 'test' image for running a full test using the production environment + +WORKDIR $HOME/statup +ADD dev/test . + +RUN npm install node-sass +ENV SASS=node-sass +RUN npm install + +ADD ./statup-linux-amd64 /usr/local/bin/statup +RUN statup version + +RUN npm run test-docker \ No newline at end of file diff --git a/dev/Dockerfile-test b/dev/Dockerfile-test deleted file mode 100644 index edc8b087..00000000 --- a/dev/Dockerfile-test +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:1.10.3-alpine -MAINTAINER "Hunter Long (https://github.com/hunterlong)" -# Statup 'test' image for running a full test using the production environment - -RUN apk add --no-cache libstdc++ gcc g++ make git ca-certificates linux-headers wget curl - -RUN curl -L -s https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64 -o /go/bin/dep && \ - chmod +x /go/bin/dep - -RUN curl -L -s https://assets.statup.io/sass -o /usr/local/bin/sass && \ - chmod +x /usr/local/bin/sass - -WORKDIR /go/src/github.com/hunterlong/statup -ADD . /go/src/github.com/hunterlong/statup - -ENV VERSION=$(VERSION) -ENV IS_DOCKER=true - -RUN make dev-deps -RUN make install - -EXPOSE 8080 -ENTRYPOINT make test \ No newline at end of file diff --git a/dev/test/package.json b/dev/test/package.json index 07f64e9f..e08cb7ef 100644 --- a/dev/test/package.json +++ b/dev/test/package.json @@ -14,6 +14,7 @@ "cy:run-video": "cypress run --record --key $CYPRESS_KEY", "cy:run": "cypress run", "test": "bash -c \"./test.sh\"", + "test-docker": "bash -c \"./test-docker.sh\"", "testnovid": "cypress run", "open": "cypress open" }, diff --git a/dev/test/test-docker.sh b/dev/test/test-docker.sh new file mode 100755 index 00000000..7296e230 --- /dev/null +++ b/dev/test/test-docker.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +statup > /dev/null & + +./node_modules/.bin/start-server-and-test start http://localhost:8080/robots.txt cy:run \ No newline at end of file diff --git a/handlers/api.go b/handlers/api.go index 402259fd..c45ef8be 100644 --- a/handlers/api.go +++ b/handlers/api.go @@ -79,8 +79,7 @@ func ApiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) { var s *types.Service decoder := json.NewDecoder(r.Body) decoder.Decode(&s) - service := serv - core.UpdateService(service) + serv.Update() json.NewEncoder(w).Encode(s) } @@ -89,7 +88,7 @@ func ApiAllServicesHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } - services, _ := core.SelectAllServices() + services, _ := core.CoreApp.SelectAllServices() json.NewEncoder(w).Encode(services) } diff --git a/handlers/dashboard.go b/handlers/dashboard.go index a726f48a..140213c6 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -22,7 +22,6 @@ import ( ) type dashboard struct { - Services []*core.Service Core *core.Core CountOnline int CountServices int @@ -35,7 +34,7 @@ func DashboardHandler(w http.ResponseWriter, r *http.Request) { ExecuteResponse(w, r, "login.html", err) } else { fails := core.CountFailures() - out := dashboard{core.CoreApp.Services, core.CoreApp, core.CountOnline(), len(core.CoreApp.Services), fails} + out := dashboard{core.CoreApp, core.CountOnline(), len(core.CoreApp.Services()), fails} ExecuteResponse(w, r, "dashboard.html", out) } } diff --git a/handlers/handlers.go b/handlers/handlers.go index 8c9185f7..a0aef36f 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -112,10 +112,22 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i return utils.UnderScoreString(html) }, }) - t, _ = t.Parse(nav) - t, _ = t.Parse(footer) - t.Parse(render) - t.Execute(w, data) + t, err = t.Parse(nav) + if err != nil { + utils.Log(4, err) + } + t, err = t.Parse(footer) + if err != nil { + utils.Log(4, err) + } + _, err = t.Parse(render) + if err != nil { + utils.Log(4, err) + } + err = t.Execute(w, data) + if err != nil { + utils.Log(4, err) + } } func ExecuteJSResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}) { diff --git a/handlers/handlers_test.go b/handlers/handlers_test.go index 4727e420..6f6bcb65 100644 --- a/handlers/handlers_test.go +++ b/handlers/handlers_test.go @@ -142,7 +142,9 @@ func TestServiceChartHandler(t *testing.T) { assert.Equal(t, 200, rr.Code) t.Log(body) assert.Contains(t, body, "var ctx_1") - assert.Contains(t, body, "var ctx_2") + assert.Contains(t, body, "var ctx_3") + assert.Contains(t, body, "var ctx_4") + assert.Contains(t, body, "var ctx_5") } func TestDashboardHandler(t *testing.T) { diff --git a/handlers/prometheus.go b/handlers/prometheus.go index e110d45b..a9a041f9 100644 --- a/handlers/prometheus.go +++ b/handlers/prometheus.go @@ -41,9 +41,9 @@ func PrometheusHandler(w http.ResponseWriter, r *http.Request) { } metrics := []string{} system := fmt.Sprintf("statup_total_failures %v\n", core.CountFailures()) - system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services)) + system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.DbServices)) metrics = append(metrics, system) - for _, ser := range core.CoreApp.Services { + for _, ser := range core.CoreApp.DbServices { v := ser online := 1 if !v.Online { diff --git a/handlers/routes.go b/handlers/routes.go index 01154d8e..f0cc48eb 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -23,7 +23,6 @@ import ( "github.com/hunterlong/statup/source" "github.com/hunterlong/statup/utils" "net/http" - "os" "time" ) @@ -89,9 +88,6 @@ func Router() *mux.Router { r.Handle("/api/users", http.HandlerFunc(ApiAllUsersHandler)) r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserHandler)) r.Handle("/metrics", http.HandlerFunc(PrometheusHandler)) - if os.Getenv("GO_ENV") == "test" { - r.Handle("/reset", http.HandlerFunc(ResetDbHandler)) - } r.NotFoundHandler = http.HandlerFunc(Error404Handler) return r } diff --git a/handlers/services.go b/handlers/services.go index 82fde90f..006434ce 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -30,7 +30,7 @@ type Service struct { } func RenderServiceChartsHandler(w http.ResponseWriter, r *http.Request) { - services := core.CoreApp.Services + services := core.CoreApp.Services() w.Header().Set("Content-Type", "text/javascript") w.Header().Set("Cache-Control", "max-age=60") ExecuteJSResponse(w, r, "charts.js", services) @@ -41,7 +41,7 @@ func ServicesHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/", http.StatusSeeOther) return } - ExecuteResponse(w, r, "services.html", core.CoreApp.Services) + ExecuteResponse(w, r, "services.html", core.CoreApp.DbServices) } func CreateServiceHandler(w http.ResponseWriter, r *http.Request) { @@ -73,15 +73,15 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) { PostData: postData, Timeout: timeout, }} - _, err := core.CreateService(service) + _, err := service.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error starting %v check routine. %v", service.Name, err)) } - go core.CheckQueue(service, true) + go service.CheckQueue(true) core.OnNewService(service) - ExecuteResponse(w, r, "services.html", core.CoreApp.Services) + ExecuteResponse(w, r, "services.html", core.CoreApp.DbServices) } func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) { @@ -96,8 +96,8 @@ func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) { return } service := serv - core.DeleteService(service) - ExecuteResponse(w, r, "services.html", core.CoreApp.Services) + service.Delete() + ExecuteResponse(w, r, "services.html", core.CoreApp.DbServices) } func ServicesViewHandler(w http.ResponseWriter, r *http.Request) { @@ -142,10 +142,10 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) { PostData: postData, Timeout: timeout, }} - service = core.UpdateService(serviceUpdate) - core.CoreApp.Services, _ = core.SelectAllServices() + serviceUpdate.Update() + core.CoreApp.SelectAllServices() - serv = core.SelectService(service.Id) + serv = core.SelectService(serviceUpdate.Id) ExecuteResponse(w, r, "service.html", serv) } @@ -158,8 +158,8 @@ func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) { serv := core.SelectService(utils.StringInt(vars["id"])) service := serv core.DeleteFailures(service) - core.CoreApp.Services, _ = core.SelectAllServices() - ExecuteResponse(w, r, "services.html", core.CoreApp.Services) + core.CoreApp.SelectAllServices() + ExecuteResponse(w, r, "services.html", core.CoreApp.DbServices) } func CheckinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) { @@ -171,7 +171,7 @@ func CheckinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) { interval := utils.StringInt(r.PostForm.Get("interval")) serv := core.SelectService(utils.StringInt(vars["id"])) service := serv - checkin := &core.Checkin{ + checkin := &types.Checkin{ Service: service.Id, Interval: interval, Api: utils.NewSHA1Hash(18), diff --git a/handlers/setup.go b/handlers/setup.go index 4746e3e9..b94e52fc 100644 --- a/handlers/setup.go +++ b/handlers/setup.go @@ -16,6 +16,7 @@ package handlers import ( + "fmt" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" @@ -26,7 +27,7 @@ import ( ) func SetupHandler(w http.ResponseWriter, r *http.Request) { - if core.CoreApp.Services != nil { + if core.CoreApp.DbServices != nil { http.Redirect(w, r, "/", http.StatusSeeOther) return } @@ -55,7 +56,7 @@ func SetupHandler(w http.ResponseWriter, r *http.Request) { } func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) { - if core.CoreApp.Services != nil { + if core.CoreApp.DbServices != nil { http.Redirect(w, r, "/", http.StatusSeeOther) return } @@ -74,7 +75,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) { domain := r.PostForm.Get("domain") email := r.PostForm.Get("email") - config := &core.DbConfig{DbConfig: &types.DbConfig{ + config := &core.DbConfig{&types.DbConfig{ DbConn: dbConn, DbHost: dbHost, DbUser: dbUser, @@ -88,9 +89,11 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) { Password: password, Email: email, Error: nil, - Location: ".", + Location: utils.Directory, }} + fmt.Println(config) + err := config.Save() if err != nil { utils.Log(4, err) @@ -111,7 +114,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) { return } - err = core.DbConnection(core.Configs.Connection, false, ".") + err = core.DbConnection(core.Configs.Connection, false, utils.Directory) if err != nil { utils.Log(3, err) core.DeleteConfig() @@ -120,13 +123,13 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) { return } - admin := &types.User{ + admin := core.ReturnUser(&types.User{ Username: config.Username, Password: config.Password, Email: config.Email, Admin: true, - } - core.CreateUser(admin) + }) + admin.Create() if sample == "on" { core.LoadSampleData() diff --git a/handlers/users.go b/handlers/users.go index 14d165ef..7eb93b0b 100644 --- a/handlers/users.go +++ b/handlers/users.go @@ -16,6 +16,7 @@ package handlers import ( + "fmt" "github.com/gorilla/mux" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/types" @@ -52,7 +53,12 @@ func UpdateUserHandler(w http.ResponseWriter, r *http.Request) { r.ParseForm() vars := mux.Vars(r) id, _ := strconv.Atoi(vars["id"]) - user, _ := core.SelectUser(int64(id)) + user, err := core.SelectUser(int64(id)) + if err != nil { + utils.Log(3, fmt.Sprintf("user error: %v", err)) + w.WriteHeader(http.StatusInternalServerError) + return + } user.Username = r.PostForm.Get("username") user.Email = r.PostForm.Get("email") @@ -61,7 +67,7 @@ func UpdateUserHandler(w http.ResponseWriter, r *http.Request) { if password != "##########" { user.Password = utils.HashPassword(password) } - core.UpdateUser(user) + user.Update() users, _ := core.SelectAllUsers() ExecuteResponse(w, r, "users.html", users) } @@ -77,15 +83,15 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) { email := r.PostForm.Get("email") admin := r.PostForm.Get("admin") - user := &types.User{ + user := core.ReturnUser(&types.User{ Username: username, Password: password, Email: email, Admin: (admin == "on"), - } - _, err := core.CreateUser(user) + }) + _, err := user.Create() if err != nil { - utils.Log(2, err) + utils.Log(3, err) } core.OnNewUser(user) http.Redirect(w, r, "/users", http.StatusSeeOther) @@ -106,6 +112,6 @@ func UsersDeleteHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/users", http.StatusSeeOther) return } - core.DeleteUser(user) + user.Delete() http.Redirect(w, r, "/users", http.StatusSeeOther) } diff --git a/notifiers/notifiers_test.go b/notifiers/notifiers_test.go index e0206ecb..a43922fb 100644 --- a/notifiers/notifiers_test.go +++ b/notifiers/notifiers_test.go @@ -20,14 +20,13 @@ import ( "github.com/hunterlong/statup/utils" "github.com/pkg/errors" "github.com/stretchr/testify/assert" - "os" "testing" "upper.io/db.v3/sqlite" ) var ( testNotifier *Tester - testDatabase string + dir string ) // @@ -63,15 +62,13 @@ func (n *Tester) Test() error { } func init() { - testDatabase = os.Getenv("GOPATH") - testDatabase += "/src/github.com/hunterlong/statup" - + dir = utils.Directory utils.InitLogs() } func injectDatabase() { sqliteDb := sqlite.ConnectionURL{ - Database: testDatabase + "/statup.db", + Database: dir + "/statup.db", } dbSession, _ := sqlite.Open(sqliteDb) Collections = dbSession.Collection("communication") @@ -87,11 +84,11 @@ func TestInit(t *testing.T) { func TestAdd(t *testing.T) { testNotifier = &Tester{&Notification{ - Id: 1, + Id: 999999, Method: "tester", Host: "0.0.0.0", Form: []NotificationForm{{ - Id: 1, + Id: 999999, Type: "text", Title: "Incoming Webhook Url", Placeholder: "Insert your Slack webhook URL here.", @@ -119,14 +116,14 @@ func TestInsertDatabase(t *testing.T) { } func TestSelectNotification(t *testing.T) { - notifier, err := SelectNotification(1) + notifier, err := SelectNotification(999999) assert.Nil(t, err) assert.Equal(t, "tester", notifier.Method) assert.False(t, notifier.Enabled) } func TestNotification_Update(t *testing.T) { - notifier, err := SelectNotification(1) + notifier, err := SelectNotification(999999) assert.Nil(t, err) notifier.Method = "updatedName" notifier.Enabled = true @@ -139,7 +136,7 @@ func TestNotification_Update(t *testing.T) { } func TestNotification_GetValue(t *testing.T) { - notifier, err := SelectNotification(1) + notifier, err := SelectNotification(999999) assert.Nil(t, err) val := notifier.GetValue("Host") assert.Equal(t, "0.0.0.0", val) diff --git a/source/tmpl/dashboard.html b/source/tmpl/dashboard.html index 9cbb362e..2e0415b6 100644 --- a/source/tmpl/dashboard.html +++ b/source/tmpl/dashboard.html @@ -47,31 +47,28 @@
{{.SmallText}}
{{ end }}{{$f.Issue}}
+{{.Issue}}
{{ end }}{{$f.Issue}}
+{{.Issue}}
{{ end }}