mirror of https://github.com/statping/statping
error handling, tests, fixes
parent
03e490afb9
commit
25d6f3b66a
|
@ -72,6 +72,8 @@ jobs:
|
||||||
DB_CONN: sqlite3
|
DB_CONN: sqlite3
|
||||||
STATPING_DIR: /home/runner/work/statping/statping
|
STATPING_DIR: /home/runner/work/statping/statping
|
||||||
API_KEY: demopassword123
|
API_KEY: demopassword123
|
||||||
|
DISABLE_LOGS: true
|
||||||
|
ALLOW_REPORTS: true
|
||||||
DISCORD_URL: ${{ secrets.DISCORD_URL }}
|
DISCORD_URL: ${{ secrets.DISCORD_URL }}
|
||||||
EMAIL_HOST: ${{ secrets.EMAIL_HOST }}
|
EMAIL_HOST: ${{ secrets.EMAIL_HOST }}
|
||||||
EMAIL_USER: ${{ secrets.EMAIL_USER }}
|
EMAIL_USER: ${{ secrets.EMAIL_USER }}
|
||||||
|
@ -90,7 +92,7 @@ jobs:
|
||||||
TWILIO_SECRET: ${{ secrets.TWILIO_SECRET }}
|
TWILIO_SECRET: ${{ secrets.TWILIO_SECRET }}
|
||||||
TWILIO_FROM: ${{ secrets.TWILIO_FROM }}
|
TWILIO_FROM: ${{ secrets.TWILIO_FROM }}
|
||||||
TWILIO_TO: ${{ secrets.TWILIO_TO }}
|
TWILIO_TO: ${{ secrets.TWILIO_TO }}
|
||||||
run: SASS=`which sass` go test -v -covermode=count -coverprofile=coverage.out -p=1 ./...
|
run: go test -v -covermode=count -coverprofile=coverage.out -p=1 ./...
|
||||||
|
|
||||||
- name: Build Binaries
|
- name: Build Binaries
|
||||||
run: make build-bin build-win
|
run: make build-bin build-win
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
- Added Viper and Cobra config/env parsing package
|
- Added Viper and Cobra config/env parsing package
|
||||||
- Added more golang tests
|
- Added more golang tests
|
||||||
- Modified handlers to use a more generic find method
|
- Modified handlers to use a more generic find method
|
||||||
|
- Added 'env' command to show variables used in config
|
||||||
|
- Added 'reset' command that will delete files and backup .db file for a fresh install
|
||||||
|
- Added error type that has common errors with http status code based on error
|
||||||
|
|
||||||
|
|
||||||
# 0.90.27 (04-15-2020)
|
# 0.90.27 (04-15-2020)
|
||||||
- Fixed postgres database table creation process
|
- Fixed postgres database table creation process
|
||||||
|
|
85
cmd/cli.go
85
cmd/cli.go
|
@ -79,6 +79,61 @@ func sassCli() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resetCli() error {
|
||||||
|
d := utils.Directory
|
||||||
|
fmt.Println("Statping directory: ", d)
|
||||||
|
assets := d + "/assets"
|
||||||
|
if utils.FolderExists(assets) {
|
||||||
|
fmt.Printf("Deleting %s folder.\n", assets)
|
||||||
|
if err := utils.DeleteDirectory(assets); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Assets folder does not exist %s\n", assets)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDir := d + "/logs"
|
||||||
|
if utils.FolderExists(logDir) {
|
||||||
|
fmt.Printf("Deleting %s directory.\n", logDir)
|
||||||
|
if err := utils.DeleteDirectory(logDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Logs folder does not exist %s\n", logDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := d + "/config.yml"
|
||||||
|
if utils.FileExists(c) {
|
||||||
|
fmt.Printf("Deleting %s file.\n", c)
|
||||||
|
if err := utils.DeleteFile(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Config file does not exist %s\n", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbFile := d + "/statping.db"
|
||||||
|
if utils.FileExists(dbFile) {
|
||||||
|
fmt.Printf("Backuping up %s file.\n", dbFile)
|
||||||
|
if err := utils.RenameDirectory(dbFile, d+"/statping.db.backup"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Statping SQL Database file does not exist %s\n", dbFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Statping has been reset")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func envCli() error {
|
||||||
|
fmt.Println("Statping Configuration")
|
||||||
|
for k, v := range utils.Params.AllSettings() {
|
||||||
|
fmt.Printf("%s=%v\n", strings.ToUpper(k), v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func onceCli() error {
|
func onceCli() error {
|
||||||
if err := utils.InitLogs(); err != nil {
|
if err := utils.InitLogs(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -182,21 +237,6 @@ func ask(format string) bool {
|
||||||
return strings.ToLower(text) == "y"
|
return strings.ToLower(text) == "y"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportIndexHTML returns the HTML of the index page as a string
|
|
||||||
//func ExportIndexHTML() []byte {
|
|
||||||
// source.Assets()
|
|
||||||
// core.CoreApp.Connect(core.CoreApp., utils.Directory)
|
|
||||||
// core.SelectAllServices(false)
|
|
||||||
// core.CoreApp.UseCdn = types.NewNullBool(true)
|
|
||||||
// for _, srv := range core.Services() {
|
|
||||||
// core.CheckService(srv, true)
|
|
||||||
// }
|
|
||||||
// w := httptest.NewRecorder()
|
|
||||||
// r := httptest.NewRequest("GET", "/", nil)
|
|
||||||
// handlers.ExecuteResponse(w, r, "index.gohtml", nil, nil)
|
|
||||||
// return w.Body.Bytes()
|
|
||||||
//}
|
|
||||||
|
|
||||||
func updateDisplay() error {
|
func updateDisplay() error {
|
||||||
gitCurrent, err := checkGithubUpdates()
|
gitCurrent, err := checkGithubUpdates()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -426,3 +466,18 @@ func ExportSettings() ([]byte, error) {
|
||||||
export, err := json.Marshal(data)
|
export, err := json.Marshal(data)
|
||||||
return export, err
|
return export, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExportIndexHTML returns the HTML of the index page as a string
|
||||||
|
//func ExportIndexHTML() []byte {
|
||||||
|
// source.Assets()
|
||||||
|
// core.CoreApp.Connect(core.CoreApp., utils.Directory)
|
||||||
|
// core.SelectAllServices(false)
|
||||||
|
// core.CoreApp.UseCdn = types.NewNullBool(true)
|
||||||
|
// for _, srv := range core.Services() {
|
||||||
|
// core.CheckService(srv, true)
|
||||||
|
// }
|
||||||
|
// w := httptest.NewRecorder()
|
||||||
|
// r := httptest.NewRequest("GET", "/", nil)
|
||||||
|
// handlers.ExecuteResponse(w, r, "index.gohtml", nil, nil)
|
||||||
|
// return w.Body.Bytes()
|
||||||
|
//}
|
||||||
|
|
194
cmd/cli_test.go
194
cmd/cli_test.go
|
@ -2,15 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/rendon/testcli"
|
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -18,102 +14,31 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dir = utils.Directory
|
utils.InitCLI()
|
||||||
//core.SampleHits = 480
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStartServerCommand(t *testing.T) {
|
func TestStatpingDirectory(t *testing.T) {
|
||||||
t.SkipNow()
|
dir := utils.Directory
|
||||||
cmd := helperCommand(nil, "")
|
require.NotContains(t, dir, "/cmd")
|
||||||
var got = make(chan string)
|
require.NotEmpty(t, dir)
|
||||||
commandAndSleep(cmd, time.Duration(60*time.Second), got)
|
|
||||||
os.Unsetenv("DB_CONN")
|
dir = utils.Params.GetString("STATPING_DIR")
|
||||||
gg, _ := <-got
|
require.NotContains(t, dir, "/cmd")
|
||||||
assert.Contains(t, gg, "DB_CONN environment variable was found")
|
require.NotEmpty(t, dir)
|
||||||
assert.Contains(t, gg, "Core database does not exist, creating now!")
|
|
||||||
assert.Contains(t, gg, "Starting monitoring process for 5 Services")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVersionCommand(t *testing.T) {
|
func TestEnvCLI(t *testing.T) {
|
||||||
c := testcli.Command("statping", "version")
|
cmd := rootCmd
|
||||||
c.Run()
|
b := bytes.NewBufferString("")
|
||||||
assert.True(t, c.StdoutContains(VERSION))
|
cmd.SetOut(b)
|
||||||
}
|
cmd.SetArgs([]string{"env"})
|
||||||
|
err := cmd.Execute()
|
||||||
func TestHelpCommand(t *testing.T) {
|
|
||||||
c := testcli.Command("statping", "help")
|
|
||||||
c.Run()
|
|
||||||
t.Log(c.Stdout())
|
|
||||||
assert.True(t, c.StdoutContains("statping help - Shows the user basic information about Statping"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStaticCommand(t *testing.T) {
|
|
||||||
t.SkipNow()
|
|
||||||
cmd := helperCommand(nil, "static")
|
|
||||||
var got = make(chan string)
|
|
||||||
commandAndSleep(cmd, time.Duration(10*time.Second), got)
|
|
||||||
gg, _ := <-got
|
|
||||||
t.Log(gg)
|
|
||||||
assert.Contains(t, gg, "Exporting Static 'index.html' page...")
|
|
||||||
assert.Contains(t, gg, "Exported Statping index page: 'index.html'")
|
|
||||||
assert.FileExists(t, dir+"/index.html")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExportCommand(t *testing.T) {
|
|
||||||
t.SkipNow()
|
|
||||||
cmd := helperCommand(nil, "export")
|
|
||||||
var got = make(chan string)
|
|
||||||
commandAndSleep(cmd, time.Duration(10*time.Second), got)
|
|
||||||
gg, _ := <-got
|
|
||||||
t.Log(gg)
|
|
||||||
assert.FileExists(t, dir+"/statping-export.json")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdateCommand(t *testing.T) {
|
|
||||||
t.SkipNow()
|
|
||||||
cmd := helperCommand(nil, "version")
|
|
||||||
var got = make(chan string)
|
|
||||||
commandAndSleep(cmd, time.Duration(15*time.Second), got)
|
|
||||||
gg, _ := <-got
|
|
||||||
t.Log(gg)
|
|
||||||
assert.Contains(t, gg, VERSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAssetsCommand(t *testing.T) {
|
|
||||||
t.SkipNow()
|
|
||||||
c := testcli.Command("statping", "assets")
|
|
||||||
c.Run()
|
|
||||||
t.Log(c.Stdout())
|
|
||||||
t.Log("Directory for Assets: ", dir)
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
err := utils.DeleteDirectory(dir + "/assets")
|
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.FileExists(t, dir+"/assets/robots.txt")
|
out, err := ioutil.ReadAll(b)
|
||||||
assert.FileExists(t, dir+"/assets/scss/base.scss")
|
|
||||||
assert.FileExists(t, dir+"/assets/scss/main.scss")
|
|
||||||
assert.FileExists(t, dir+"/assets/scss/variables.scss")
|
|
||||||
assert.FileExists(t, dir+"/assets/css/main.css")
|
|
||||||
assert.FileExists(t, dir+"/assets/css/vendor.css")
|
|
||||||
assert.FileExists(t, dir+"/assets/css/style.css")
|
|
||||||
err = utils.DeleteDirectory(dir + "/assets")
|
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
assert.Contains(t, string(out), VERSION)
|
||||||
|
assert.Contains(t, utils.Directory, string(out))
|
||||||
func TestRunCommand(t *testing.T) {
|
assert.Contains(t, "SAMPLE_DATA=true", string(out))
|
||||||
t.SkipNow()
|
|
||||||
cmd := helperCommand(nil, "run")
|
|
||||||
var got = make(chan string)
|
|
||||||
commandAndSleep(cmd, time.Duration(15*time.Second), got)
|
|
||||||
gg, _ := <-got
|
|
||||||
t.Log(gg)
|
|
||||||
assert.Contains(t, gg, "Running 1 time and saving to database...")
|
|
||||||
assert.Contains(t, gg, "Check is complete.")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnvironmentVarsCommand(t *testing.T) {
|
|
||||||
c := testcli.Command("statping", "env")
|
|
||||||
c.Run()
|
|
||||||
assert.True(t, c.StdoutContains("Statping Environment Variable"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVersionCLI(t *testing.T) {
|
func TestVersionCLI(t *testing.T) {
|
||||||
|
@ -121,10 +46,11 @@ func TestVersionCLI(t *testing.T) {
|
||||||
b := bytes.NewBufferString("")
|
b := bytes.NewBufferString("")
|
||||||
cmd.SetOut(b)
|
cmd.SetOut(b)
|
||||||
cmd.SetArgs([]string{"version"})
|
cmd.SetArgs([]string{"version"})
|
||||||
cmd.Execute()
|
err := cmd.Execute()
|
||||||
|
require.Nil(t, err)
|
||||||
out, err := ioutil.ReadAll(b)
|
out, err := ioutil.ReadAll(b)
|
||||||
assert.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Contains(t, string(out), VERSION)
|
assert.Contains(t, VERSION, string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAssetsCLI(t *testing.T) {
|
func TestAssetsCLI(t *testing.T) {
|
||||||
|
@ -132,51 +58,51 @@ func TestAssetsCLI(t *testing.T) {
|
||||||
b := bytes.NewBufferString("")
|
b := bytes.NewBufferString("")
|
||||||
cmd.SetOut(b)
|
cmd.SetOut(b)
|
||||||
cmd.SetArgs([]string{"assets"})
|
cmd.SetArgs([]string{"assets"})
|
||||||
cmd.Execute()
|
err := cmd.Execute()
|
||||||
|
require.Nil(t, err)
|
||||||
out, err := ioutil.ReadAll(b)
|
out, err := ioutil.ReadAll(b)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Contains(t, string(out), VERSION)
|
assert.Contains(t, string(out), VERSION)
|
||||||
assert.FileExists(t, dir+"/assets/css/main.css")
|
assert.FileExists(t, utils.Directory+"/assets/css/main.css")
|
||||||
assert.FileExists(t, dir+"/assets/css/style.css")
|
assert.FileExists(t, utils.Directory+"/assets/css/style.css")
|
||||||
assert.FileExists(t, dir+"/assets/css/vendor.css")
|
assert.FileExists(t, utils.Directory+"/assets/css/vendor.css")
|
||||||
assert.FileExists(t, dir+"/assets/scss/base.scss")
|
assert.FileExists(t, utils.Directory+"/assets/scss/base.scss")
|
||||||
assert.FileExists(t, dir+"/assets/scss/mobile.scss")
|
assert.FileExists(t, utils.Directory+"/assets/scss/mobile.scss")
|
||||||
assert.FileExists(t, dir+"/assets/scss/variables.scss")
|
assert.FileExists(t, utils.Directory+"/assets/scss/variables.scss")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSassCLI(t *testing.T) {
|
func TestHelpCLI(t *testing.T) {
|
||||||
c := testcli.Command("statping", "assets")
|
cmd := rootCmd
|
||||||
c.Run()
|
b := bytes.NewBufferString("")
|
||||||
t.Log(c.Stdout())
|
cmd.SetOut(b)
|
||||||
assert.FileExists(t, dir+"/assets/css/main.css")
|
cmd.SetArgs([]string{"help"})
|
||||||
assert.FileExists(t, dir+"/assets/css/style.css")
|
err := cmd.Execute()
|
||||||
assert.FileExists(t, dir+"/assets/css/vendor.css")
|
require.Nil(t, err)
|
||||||
|
out, err := ioutil.ReadAll(b)
|
||||||
|
require.Nil(t, err)
|
||||||
|
assert.Contains(t, string(out), VERSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateCLI(t *testing.T) {
|
func TestResetCLI(t *testing.T) {
|
||||||
t.SkipNow()
|
err := utils.SaveFile(utils.Directory+"/statping.db", []byte("test data"))
|
||||||
cmd := helperCommand(nil, "update")
|
require.Nil(t, err)
|
||||||
var got = make(chan string)
|
|
||||||
commandAndSleep(cmd, time.Duration(15*time.Second), got)
|
|
||||||
gg, _ := <-got
|
|
||||||
t.Log(gg)
|
|
||||||
assert.Contains(t, gg, "version")
|
|
||||||
}
|
|
||||||
|
|
||||||
func commandAndSleep(cmd *exec.Cmd, duration time.Duration, out chan<- string) {
|
cmd := rootCmd
|
||||||
go func(out chan<- string) {
|
b := bytes.NewBufferString("")
|
||||||
runCommand(cmd, out)
|
cmd.SetOut(b)
|
||||||
}(out)
|
cmd.SetArgs([]string{"reset"})
|
||||||
time.Sleep(duration)
|
err = cmd.Execute()
|
||||||
cmd.Process.Kill()
|
require.Nil(t, err)
|
||||||
}
|
out, err := ioutil.ReadAll(b)
|
||||||
|
require.Nil(t, err)
|
||||||
|
assert.Contains(t, string(out), VERSION)
|
||||||
|
|
||||||
func helperCommand(envs []string, s ...string) *exec.Cmd {
|
assert.NoDirExists(t, utils.Directory+"/assets")
|
||||||
cmd := exec.Command("statping", s...)
|
assert.NoDirExists(t, utils.Directory+"/logs")
|
||||||
return cmd
|
assert.NoFileExists(t, utils.Directory+"/config.yml")
|
||||||
}
|
assert.NoFileExists(t, utils.Directory+"/statping.db")
|
||||||
|
assert.FileExists(t, utils.Directory+"/statping.db.backup")
|
||||||
|
|
||||||
func runCommand(c *exec.Cmd, out chan<- string) {
|
err = utils.DeleteFile(utils.Directory + "/statping.db.backup")
|
||||||
bout, _ := c.CombinedOutput()
|
require.Nil(t, err)
|
||||||
out <- string(bout)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,22 @@ var sassCmd = &cobra.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var envCmd = &cobra.Command{
|
||||||
|
Use: "env",
|
||||||
|
Short: "Return the configs that will be ran",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return envCli()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var resetCmd = &cobra.Command{
|
||||||
|
Use: "reset",
|
||||||
|
Short: "Start a fresh copy of Statping",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return resetCli()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var onceCmd = &cobra.Command{
|
var onceCmd = &cobra.Command{
|
||||||
Use: "once",
|
Use: "once",
|
||||||
Short: "Check all services 1 time and then quit",
|
Short: "Check all services 1 time and then quit",
|
||||||
|
|
|
@ -32,14 +32,16 @@ var (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
core.New(VERSION)
|
core.New(VERSION)
|
||||||
utils.InitCLI()
|
|
||||||
parseFlags(rootCmd)
|
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
rootCmd.AddCommand(assetsCmd)
|
rootCmd.AddCommand(assetsCmd)
|
||||||
rootCmd.AddCommand(exportCmd)
|
rootCmd.AddCommand(exportCmd)
|
||||||
rootCmd.AddCommand(importCmd)
|
rootCmd.AddCommand(importCmd)
|
||||||
rootCmd.AddCommand(sassCmd)
|
rootCmd.AddCommand(sassCmd)
|
||||||
rootCmd.AddCommand(onceCmd)
|
rootCmd.AddCommand(onceCmd)
|
||||||
|
rootCmd.AddCommand(envCmd)
|
||||||
|
rootCmd.AddCommand(resetCmd)
|
||||||
|
utils.InitCLI()
|
||||||
|
parseFlags(rootCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit will return an error and return an exit code 1 due to this error
|
// exit will return an error and return an exit code 1 due to this error
|
||||||
|
|
|
@ -92,6 +92,7 @@ type Database interface {
|
||||||
|
|
||||||
// extra
|
// extra
|
||||||
Error() error
|
Error() error
|
||||||
|
Status() int
|
||||||
RowsAffected() int64
|
RowsAffected() int64
|
||||||
|
|
||||||
Since(time.Time) Database
|
Since(time.Time) Database
|
||||||
|
@ -504,6 +505,34 @@ func (it *Db) Error() error {
|
||||||
return it.Database.Error
|
return it.Database.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it *Db) Status() int {
|
||||||
|
switch it.Database.Error {
|
||||||
|
case gorm.ErrRecordNotFound:
|
||||||
|
return 404
|
||||||
|
case gorm.ErrCantStartTransaction:
|
||||||
|
return 422
|
||||||
|
case gorm.ErrInvalidSQL:
|
||||||
|
return 500
|
||||||
|
case gorm.ErrUnaddressable:
|
||||||
|
return 500
|
||||||
|
default:
|
||||||
|
return 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *Db) Loggable() bool {
|
||||||
|
switch it.Database.Error {
|
||||||
|
case gorm.ErrCantStartTransaction:
|
||||||
|
return true
|
||||||
|
case gorm.ErrInvalidSQL:
|
||||||
|
return true
|
||||||
|
case gorm.ErrUnaddressable:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (it *Db) Since(ago time.Time) Database {
|
func (it *Db) Since(ago time.Time) Database {
|
||||||
return it.Where("created_at > ?", it.FormatTime(ago))
|
return it.Where("created_at > ?", it.FormatTime(ago))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/statping/statping/types/checkins"
|
"github.com/statping/statping/types/checkins"
|
||||||
"github.com/statping/statping/types/core"
|
"github.com/statping/statping/types/core"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/groups"
|
"github.com/statping/statping/types/groups"
|
||||||
"github.com/statping/statping/types/incidents"
|
"github.com/statping/statping/types/incidents"
|
||||||
"github.com/statping/statping/types/messages"
|
"github.com/statping/statping/types/messages"
|
||||||
|
@ -22,7 +21,7 @@ type apiResponse struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Object string `json:"type,omitempty"`
|
Object string `json:"type,omitempty"`
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Error string `json:"error,omitempty"`
|
Error error `json:"error,omitempty"`
|
||||||
Id int64 `json:"id,omitempty"`
|
Id int64 `json:"id,omitempty"`
|
||||||
Output interface{} `json:"output,omitempty"`
|
Output interface{} `json:"output,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -54,8 +53,7 @@ func apiRenewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiCoreHandler(w http.ResponseWriter, r *http.Request) {
|
func apiCoreHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var c *core.Core
|
var c *core.Core
|
||||||
decoder := json.NewDecoder(r.Body)
|
err := DecodeJSON(r, &c)
|
||||||
err := decoder.Decode(&c)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
|
@ -111,17 +109,18 @@ func apiClearCacheHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
returnJson(output, w, r)
|
returnJson(output, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendErrorJson(err error, w http.ResponseWriter, r *http.Request, statusCode ...int) {
|
func sendErrorJson(err error, w http.ResponseWriter, r *http.Request) {
|
||||||
|
errCode := 0
|
||||||
|
e, ok := err.(errors.Error)
|
||||||
|
if ok {
|
||||||
|
errCode = e.Status()
|
||||||
|
}
|
||||||
log.WithField("url", r.URL.String()).
|
log.WithField("url", r.URL.String()).
|
||||||
WithField("method", r.Method).
|
WithField("method", r.Method).
|
||||||
WithField("code", statusCode).
|
WithField("code", errCode).
|
||||||
Errorln(fmt.Errorf("sending error response for %s: %s", r.URL.String(), err.Error()))
|
Errorln(fmt.Errorf("sending error response for %s: %s", r.URL.String(), err.Error()))
|
||||||
|
|
||||||
output := apiResponse{
|
returnJson(err, w, r)
|
||||||
Status: "error",
|
|
||||||
Error: err.Error(),
|
|
||||||
}
|
|
||||||
returnJson(output, w, r, statusCode...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendJsonAction(obj interface{}, method string, w http.ResponseWriter, r *http.Request) {
|
func sendJsonAction(obj interface{}, method string, w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -173,11 +172,6 @@ func sendJsonAction(obj interface{}, method string, w http.ResponseWriter, r *ht
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendUnauthorizedJson(w http.ResponseWriter, r *http.Request) {
|
func sendUnauthorizedJson(w http.ResponseWriter, r *http.Request) {
|
||||||
output := apiResponse{
|
|
||||||
Status: "error",
|
|
||||||
Error: errors.New("not authorized").Error(),
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
returnJson(errors.NotAuthenticated, w, r)
|
||||||
returnJson(output, w, r)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ func TestSetupRoutes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMainApiRoutes(t *testing.T) {
|
func TestMainApiRoutes(t *testing.T) {
|
||||||
date := utils.Now().Format("2006-01-02")
|
date := utils.Now().Format("2006-01")
|
||||||
tests := []HTTPTest{
|
tests := []HTTPTest{
|
||||||
{
|
{
|
||||||
Name: "Statping Details",
|
Name: "Statping Details",
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/statping/statping/types/checkins"
|
"github.com/statping/statping/types/checkins"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/services"
|
"github.com/statping/statping/types/services"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"net"
|
"net"
|
||||||
|
@ -13,14 +13,15 @@ import (
|
||||||
|
|
||||||
func findCheckin(r *http.Request) (*checkins.Checkin, string, error) {
|
func findCheckin(r *http.Request) (*checkins.Checkin, string, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
if vars["api"] == "" {
|
id := vars["api"]
|
||||||
return nil, "", errors.New("missing checkin API in URL")
|
if id == "" {
|
||||||
|
return nil, "", errors.IDMissing
|
||||||
}
|
}
|
||||||
checkin, err := checkins.FindByAPI(vars["api"])
|
checkin, err := checkins.FindByAPI(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vars["api"], err
|
return nil, id, errors.Missing(checkins.Checkin{}, id)
|
||||||
}
|
}
|
||||||
return checkin, vars["api"], nil
|
return checkin, id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiAllCheckinsHandler(w http.ResponseWriter, r *http.Request) {
|
func apiAllCheckinsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -29,9 +30,9 @@ func apiAllCheckinsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiCheckinHandler(w http.ResponseWriter, r *http.Request) {
|
func apiCheckinHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
checkin, id, err := findCheckin(r)
|
checkin, _, err := findCheckin(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("checkin %v was not found", id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
returnJson(checkin, w, r)
|
returnJson(checkin, w, r)
|
||||||
|
|
|
@ -73,6 +73,20 @@ func TestApiCheckinRoutes(t *testing.T) {
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: SetTestENV,
|
||||||
Skip: true,
|
Skip: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Statping Missing Trigger Checkin",
|
||||||
|
URL: "/checkin/" + apiToken,
|
||||||
|
Method: "GET",
|
||||||
|
BeforeTest: SetTestENV,
|
||||||
|
ExpectedStatus: 404,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Statping Missing Checkin",
|
||||||
|
URL: "/api/checkins/missing123",
|
||||||
|
Method: "GET",
|
||||||
|
BeforeTest: SetTestENV,
|
||||||
|
ExpectedStatus: 404,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range tests {
|
for _, v := range tests {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/errors"
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/groups"
|
"github.com/statping/statping/types/groups"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,14 +10,22 @@ import (
|
||||||
|
|
||||||
func findGroup(r *http.Request) (*groups.Group, error) {
|
func findGroup(r *http.Request) (*groups.Group, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
if utils.NotNumber(vars["id"]) {
|
||||||
|
return nil, errors.NotNumber
|
||||||
|
}
|
||||||
id := utils.ToInt(vars["id"])
|
id := utils.ToInt(vars["id"])
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
return nil, errors.New("missing group id")
|
return nil, errors.IDMissing
|
||||||
}
|
}
|
||||||
g, err := groups.Find(id)
|
g, err := groups.Find(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if !g.Public.Bool {
|
||||||
|
if !IsReadAuthenticated(r) {
|
||||||
|
return nil, errors.NotAuthenticated
|
||||||
|
}
|
||||||
|
}
|
||||||
return g, nil
|
return g, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +39,7 @@ func apiAllGroupHandler(r *http.Request) interface{} {
|
||||||
func apiGroupHandler(w http.ResponseWriter, r *http.Request) {
|
func apiGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
group, err := findGroup(r)
|
group, err := findGroup(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.Wrap(err, "group not found"), w, r, http.StatusNotFound)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
returnJson(group, w, r)
|
returnJson(group, w, r)
|
||||||
|
@ -41,8 +49,7 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func apiGroupUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiGroupUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
group, err := findGroup(r)
|
group, err := findGroup(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
sendErrorJson(err, w, r)
|
||||||
sendErrorJson(errors.Wrap(err, "group not found"), w, r)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +86,7 @@ func apiCreateGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func apiGroupDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func apiGroupDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
group, err := findGroup(r)
|
group, err := findGroup(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.Wrap(err, "group not found"), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/statping/statping/types/core"
|
"github.com/statping/statping/types/core"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -248,12 +248,14 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func returnJson(d interface{}, w http.ResponseWriter, r *http.Request, statusCode ...int) {
|
func returnJson(d interface{}, w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if len(statusCode) != 0 {
|
if e, ok := d.(errors.Error); ok {
|
||||||
code := statusCode[0]
|
w.WriteHeader(e.Status())
|
||||||
w.WriteHeader(code)
|
json.NewEncoder(w).Encode(e)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
json.NewEncoder(w).Encode(d)
|
json.NewEncoder(w).Encode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,5 +265,5 @@ func error404Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
ExecuteResponse(w, r, "index.html", nil, nil)
|
ExecuteResponse(w, r, "base.gohtml", nil, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/errors"
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/incidents"
|
"github.com/statping/statping/types/incidents"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,13 +10,16 @@ import (
|
||||||
|
|
||||||
func findIncident(r *http.Request) (*incidents.Incident, int64, error) {
|
func findIncident(r *http.Request) (*incidents.Incident, int64, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
if utils.NotNumber(vars["id"]) {
|
||||||
|
return nil, 0, errors.NotNumber
|
||||||
|
}
|
||||||
id := utils.ToInt(vars["id"])
|
id := utils.ToInt(vars["id"])
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
return nil, id, errors.New("missing checkin API in URL")
|
return nil, id, errors.IDMissing
|
||||||
}
|
}
|
||||||
checkin, err := incidents.Find(id)
|
checkin, err := incidents.Find(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, id, err
|
return nil, id, errors.Missing(&incidents.Incident{}, id)
|
||||||
}
|
}
|
||||||
return checkin, id, nil
|
return checkin, id, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/messages"
|
"github.com/statping/statping/types/messages"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,12 +10,15 @@ import (
|
||||||
|
|
||||||
func findMessage(r *http.Request) (*messages.Message, int64, error) {
|
func findMessage(r *http.Request) (*messages.Message, int64, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
num := utils.ToInt(vars["id"])
|
if utils.NotNumber(vars["id"]) {
|
||||||
message, err := messages.Find(num)
|
return nil, 0, errors.NotNumber
|
||||||
if err != nil {
|
|
||||||
return nil, num, err
|
|
||||||
}
|
}
|
||||||
return message, num, nil
|
id := utils.ToInt(vars["id"])
|
||||||
|
message, err := messages.Find(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, id, err
|
||||||
|
}
|
||||||
|
return message, id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiAllMessagesHandler(r *http.Request) interface{} {
|
func apiAllMessagesHandler(r *http.Request) interface{} {
|
||||||
|
@ -37,17 +40,17 @@ func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiMessageGetHandler(r *http.Request) interface{} {
|
func apiMessageGetHandler(r *http.Request) interface{} {
|
||||||
message, id, err := findMessage(r)
|
message, _, err := findMessage(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("message #%d was not found", id)
|
return err
|
||||||
}
|
}
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
message, id, err := findMessage(r)
|
message, _, err := findMessage(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("message #%d was not found", id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = message.Delete()
|
err = message.Delete()
|
||||||
|
@ -59,9 +62,9 @@ func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
message, id, err := findMessage(r)
|
message, _, err := findMessage(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("message #%d was not found", id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := DecodeJSON(r, &message); err != nil {
|
if err := DecodeJSON(r, &message); err != nil {
|
||||||
|
|
|
@ -29,7 +29,7 @@ func TestMessagesApiRoutes(t *testing.T) {
|
||||||
"notify_before_scale": "hour"
|
"notify_before_scale": "hour"
|
||||||
}`,
|
}`,
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
ExpectedContains: []string{`"status":"success"`, `"type":"message"`, `"method":"create"`, `"title":"API Message"`},
|
ExpectedContains: []string{Success, `"type":"message"`, `"method":"create"`, `"title":"API Message"`},
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: SetTestENV,
|
||||||
AfterTest: UnsetTestENV,
|
AfterTest: UnsetTestENV,
|
||||||
SecureRoute: true,
|
SecureRoute: true,
|
||||||
|
@ -40,7 +40,8 @@ func TestMessagesApiRoutes(t *testing.T) {
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
ExpectedContains: []string{`"title":"Routine Downtime"`},
|
ExpectedContains: []string{`"title":"Routine Downtime"`},
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
Name: "Statping Update Message",
|
Name: "Statping Update Message",
|
||||||
URL: "/api/messages/1",
|
URL: "/api/messages/1",
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
|
@ -68,7 +69,14 @@ func TestMessagesApiRoutes(t *testing.T) {
|
||||||
ExpectedContains: []string{`"status":"success"`, `"method":"delete"`},
|
ExpectedContains: []string{`"status":"success"`, `"method":"delete"`},
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: SetTestENV,
|
||||||
SecureRoute: true,
|
SecureRoute: true,
|
||||||
}}
|
},
|
||||||
|
{
|
||||||
|
Name: "Statping Missing Message",
|
||||||
|
URL: "/api/messages/999999",
|
||||||
|
Method: "GET",
|
||||||
|
ExpectedStatus: 404,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range tests {
|
for _, v := range tests {
|
||||||
t.Run(v.Name, func(t *testing.T) {
|
t.Run(v.Name, func(t *testing.T) {
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/statping/statping/types/core"
|
"github.com/statping/statping/types/core"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -167,7 +167,7 @@ func DecodeJSON(r *http.Request, obj interface{}) error {
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
err := decoder.Decode(&obj)
|
err := decoder.Decode(&obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.DecodeJSON
|
||||||
}
|
}
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -2,8 +2,8 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/statping/statping/database"
|
"github.com/statping/statping/database"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/failures"
|
"github.com/statping/statping/types/failures"
|
||||||
"github.com/statping/statping/types/hits"
|
"github.com/statping/statping/types/hits"
|
||||||
"github.com/statping/statping/types/services"
|
"github.com/statping/statping/types/services"
|
||||||
|
@ -21,7 +21,11 @@ func findService(r *http.Request) (*services.Service, error) {
|
||||||
id := utils.ToInt(vars["id"])
|
id := utils.ToInt(vars["id"])
|
||||||
servicer, err := services.Find(id)
|
servicer, err := services.Find(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("service %d not found", id)
|
return nil, err
|
||||||
|
}
|
||||||
|
user := IsUser(r)
|
||||||
|
if !servicer.Public.Bool && !user {
|
||||||
|
return nil, errors.NotAuthenticated
|
||||||
}
|
}
|
||||||
return servicer, nil
|
return servicer, nil
|
||||||
}
|
}
|
||||||
|
@ -37,7 +41,7 @@ func reorderServiceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
for _, s := range newOrder {
|
for _, s := range newOrder {
|
||||||
service, err := services.Find(s.Id)
|
service, err := services.Find(s.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.Errorf("service %d not found", s.Id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.Order = s.Order
|
service.Order = s.Order
|
||||||
|
@ -51,10 +55,6 @@ func apiServiceHandler(r *http.Request) interface{} {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user := IsUser(r)
|
|
||||||
if !srv.Public.Bool && !user {
|
|
||||||
return errors.New("not authenticated")
|
|
||||||
}
|
|
||||||
srv = srv.UpdateStats()
|
srv = srv.UpdateStats()
|
||||||
return *srv
|
return *srv
|
||||||
}
|
}
|
||||||
|
@ -78,11 +78,11 @@ func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
service, err := findService(r)
|
service, err := findService(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r, http.StatusNotFound)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := DecodeJSON(r, &service); err != nil {
|
if err := DecodeJSON(r, &service); err != nil {
|
||||||
sendErrorJson(err, w, r, http.StatusBadRequest)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +110,9 @@ func apiServiceRunningHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiServiceDataHandler(w http.ResponseWriter, r *http.Request) {
|
func apiServiceDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
service, err := findService(r)
|
||||||
service, err := services.Find(utils.ToInt(vars["id"]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.New("service data not found"), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +131,9 @@ func apiServiceDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiServiceFailureDataHandler(w http.ResponseWriter, r *http.Request) {
|
func apiServiceFailureDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
service, err := findService(r)
|
||||||
service, err := services.Find(utils.ToInt(vars["id"]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.New("service data not found"), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +155,7 @@ func apiServiceFailureDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func apiServicePingDataHandler(w http.ResponseWriter, r *http.Request) {
|
func apiServicePingDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
service, err := findService(r)
|
service, err := findService(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.New("service data not found"), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@ func apiServicePingDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func apiServiceTimeDataHandler(w http.ResponseWriter, r *http.Request) {
|
func apiServiceTimeDataHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
service, err := findService(r)
|
service, err := findService(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(errors.New("service data not found"), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,12 +256,10 @@ func servicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiServiceFailuresHandler(r *http.Request) interface{} {
|
func apiServiceFailuresHandler(r *http.Request) interface{} {
|
||||||
vars := mux.Vars(r)
|
service, err := findService(r)
|
||||||
service, err := services.Find(utils.ToInt(vars["id"]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("service not found")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var fails []*failures.Failure
|
var fails []*failures.Failure
|
||||||
query, err := database.ParseQueries(r, service.AllFailures())
|
query, err := database.ParseQueries(r, service.AllFailures())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -274,12 +270,10 @@ func apiServiceFailuresHandler(r *http.Request) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiServiceHitsHandler(r *http.Request) interface{} {
|
func apiServiceHitsHandler(r *http.Request) interface{} {
|
||||||
vars := mux.Vars(r)
|
service, err := findService(r)
|
||||||
service, err := services.Find(utils.ToInt(vars["id"]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("service not found")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var hts []*hits.Hit
|
var hts []*hits.Hit
|
||||||
query, err := database.ParseQueries(r, service.AllHits())
|
query, err := database.ParseQueries(r, service.AllHits())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -60,13 +60,20 @@ func TestApiServiceRoutes(t *testing.T) {
|
||||||
BeforeTest: UnsetTestENV,
|
BeforeTest: UnsetTestENV,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Statping Private Service 1",
|
Name: "Statping Private Service 6",
|
||||||
URL: "/api/services/6",
|
URL: "/api/services/6",
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedContains: []string{`"error":"not authenticated"`},
|
ExpectedContains: []string{`"error":"user not authenticated"`},
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 401,
|
||||||
BeforeTest: UnsetTestENV,
|
BeforeTest: UnsetTestENV,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Statping Authenticated Private Service 6",
|
||||||
|
URL: "/api/services/6",
|
||||||
|
Method: "GET",
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
BeforeTest: SetTestENV,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "Statping Service 1 with Private responses",
|
Name: "Statping Service 1 with Private responses",
|
||||||
URL: "/api/services/1",
|
URL: "/api/services/1",
|
||||||
|
@ -122,14 +129,14 @@ func TestApiServiceRoutes(t *testing.T) {
|
||||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=24h",
|
URL: "/api/services/1/failure_data" + startEndQuery + "&group=24h",
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
GreaterThan: 4,
|
GreaterThan: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Statping Service 1 Failure Data - 12 Hour",
|
Name: "Statping Service 1 Failure Data - 12 Hour",
|
||||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=12h",
|
URL: "/api/services/1/failure_data" + startEndQuery + "&group=12h",
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
GreaterThan: 7,
|
GreaterThan: 6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Statping Service 1 Failure Data - 1 Hour",
|
Name: "Statping Service 1 Failure Data - 1 Hour",
|
||||||
|
@ -162,7 +169,7 @@ func TestApiServiceRoutes(t *testing.T) {
|
||||||
if err := json.Unmarshal(resp, &uptime); err != nil {
|
if err := json.Unmarshal(resp, &uptime); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
assert.GreaterOrEqual(t, uptime.Uptime, int64(259100000))
|
assert.GreaterOrEqual(t, uptime.Uptime, int64(200000000))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/types/users"
|
"github.com/statping/statping/types/users"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -11,10 +11,13 @@ import (
|
||||||
|
|
||||||
func findUser(r *http.Request) (*users.User, int64, error) {
|
func findUser(r *http.Request) (*users.User, int64, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
if utils.NotNumber(vars["id"]) {
|
||||||
|
return nil, 0, errors.NotNumber
|
||||||
|
}
|
||||||
num := utils.ToInt(vars["id"])
|
num := utils.ToInt(vars["id"])
|
||||||
user, err := users.Find(num)
|
user, err := users.Find(num)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, num, err
|
return nil, num, errors.Missing(&users.User{}, num)
|
||||||
}
|
}
|
||||||
return user, num, nil
|
return user, num, nil
|
||||||
}
|
}
|
||||||
|
@ -22,7 +25,7 @@ func findUser(r *http.Request) (*users.User, int64, error) {
|
||||||
func apiUserHandler(w http.ResponseWriter, r *http.Request) {
|
func apiUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
user, _, err := findUser(r)
|
user, _, err := findUser(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(err, w, r, http.StatusNotFound)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Password = ""
|
user.Password = ""
|
||||||
|
@ -30,15 +33,15 @@ func apiUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
user, id, err := findUser(r)
|
user, _, err := findUser(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("user #%d was not found", id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = DecodeJSON(r, &user)
|
err = DecodeJSON(r, &user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrorJson(fmt.Errorf("user #%d was not found", id), w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ func scssRendered(name string) string {
|
||||||
|
|
||||||
// CompileSASS will attempt to compile the SASS files into CSS
|
// CompileSASS will attempt to compile the SASS files into CSS
|
||||||
func CompileSASS(files ...string) error {
|
func CompileSASS(files ...string) error {
|
||||||
sassBin := utils.Getenv("SASS", "sass").(string)
|
sassBin := utils.Params.GetString("SASS")
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
scssFile := fmt.Sprintf("%v/assets/%v", utils.Directory, file)
|
scssFile := fmt.Sprintf("%v/assets/%v", utils.Directory, file)
|
||||||
|
|
|
@ -16,6 +16,9 @@ func (c *Checkin) Expected() time.Duration {
|
||||||
|
|
||||||
func (c *Checkin) Period() time.Duration {
|
func (c *Checkin) Period() time.Duration {
|
||||||
duration, _ := time.ParseDuration(fmt.Sprintf("%ds", c.Interval))
|
duration, _ := time.ParseDuration(fmt.Sprintf("%ds", c.Interval))
|
||||||
|
if duration.Seconds() <= 15 {
|
||||||
|
return 15 * time.Second
|
||||||
|
}
|
||||||
return duration
|
return duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package errors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
NotAuthenticated = &appError{
|
||||||
|
Err: "user not authenticated",
|
||||||
|
Code: 401,
|
||||||
|
}
|
||||||
|
DecodeJSON = &appError{
|
||||||
|
Err: "could not decode incoming JSON",
|
||||||
|
Code: 422,
|
||||||
|
}
|
||||||
|
IDMissing = &appError{
|
||||||
|
Err: "ID missing in URL",
|
||||||
|
Code: 422,
|
||||||
|
}
|
||||||
|
NotNumber = &appError{
|
||||||
|
Err: "ID needs to be an integer",
|
||||||
|
Code: 422,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func Missing(object interface{}, id interface{}) error {
|
||||||
|
outErr := fmt.Errorf("%s with id %v was not found", splitVar(object), id)
|
||||||
|
return &appError{
|
||||||
|
Err: outErr.Error(),
|
||||||
|
Code: 404,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitVar(val interface{}) string {
|
||||||
|
s := strings.Split(fmt.Sprintf("%T", val), ".")
|
||||||
|
return strings.ToLower(s[len(s)-1])
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package errors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type appError struct {
|
||||||
|
Err string `json:"error"`
|
||||||
|
Code int `json:"-"`
|
||||||
|
DbCode int `json:"code,omitempty"`
|
||||||
|
Id int64 `json:"id,omitempty"`
|
||||||
|
loggable bool `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Error interface {
|
||||||
|
Error() string
|
||||||
|
Status() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(err string) Error {
|
||||||
|
return &appError{
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Err(err Error) Error {
|
||||||
|
return &appError{
|
||||||
|
Err: err.Error(),
|
||||||
|
Code: err.Status(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Wrap(err error, message string) Error {
|
||||||
|
return &appError{
|
||||||
|
Err: errors.Wrap(err, message).Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *appError) Error() string {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e appError) Status() int {
|
||||||
|
if e.Code == 0 {
|
||||||
|
return 200
|
||||||
|
}
|
||||||
|
return e.Code
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package groups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/statping/statping/database"
|
"github.com/statping/statping/database"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,6 +15,9 @@ func SetDB(database database.Database) {
|
||||||
func Find(id int64) (*Group, error) {
|
func Find(id int64) (*Group, error) {
|
||||||
var group Group
|
var group Group
|
||||||
q := db.Where("id = ?", id).Find(&group)
|
q := db.Where("id = ?", id).Find(&group)
|
||||||
|
if q.Error() != nil {
|
||||||
|
return nil, errors.Missing(group, id)
|
||||||
|
}
|
||||||
return &group, q.Error()
|
return &group, q.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package messages
|
package messages
|
||||||
|
|
||||||
import "github.com/statping/statping/database"
|
import (
|
||||||
|
"github.com/statping/statping/database"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
|
)
|
||||||
|
|
||||||
var db database.Database
|
var db database.Database
|
||||||
|
|
||||||
|
@ -11,6 +14,9 @@ func SetDB(database database.Database) {
|
||||||
func Find(id int64) (*Message, error) {
|
func Find(id int64) (*Message, error) {
|
||||||
var message Message
|
var message Message
|
||||||
q := db.Where("id = ?", id).Find(&message)
|
q := db.Where("id = ?", id).Find(&message)
|
||||||
|
if q.Error() != nil {
|
||||||
|
return nil, errors.Missing(message, id)
|
||||||
|
}
|
||||||
return &message, q.Error()
|
return &message, q.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/statping/statping/database"
|
"github.com/statping/statping/database"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,7 @@ func SetDB(database database.Database) {
|
||||||
func Find(id int64) (*Service, error) {
|
func Find(id int64) (*Service, error) {
|
||||||
srv := allServices[id]
|
srv := allServices[id]
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
return nil, errors.New("service not found")
|
return nil, errors.Missing(&Service{}, id)
|
||||||
}
|
}
|
||||||
return srv, nil
|
return srv, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prometheus/common/log"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -13,35 +12,34 @@ var (
|
||||||
|
|
||||||
func InitCLI() {
|
func InitCLI() {
|
||||||
Params = viper.New()
|
Params = viper.New()
|
||||||
|
Params.AutomaticEnv()
|
||||||
|
Directory = Params.GetString("STATPING_DIR")
|
||||||
|
//Params.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||||
setDefaults()
|
setDefaults()
|
||||||
Params.SetConfigName("config")
|
Params.SetConfigName("config")
|
||||||
Params.SetConfigType("yml")
|
Params.SetConfigType("yml")
|
||||||
Params.AddConfigPath(".")
|
Params.AddConfigPath(Directory)
|
||||||
err := Params.ReadInConfig()
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("config.yml Fatal error config file: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
Params.AddConfigPath(".")
|
Params.ReadInConfig()
|
||||||
|
|
||||||
|
Params.AddConfigPath(Directory)
|
||||||
Params.SetConfigFile(".env")
|
Params.SetConfigFile(".env")
|
||||||
err = Params.ReadInConfig()
|
Params.ReadInConfig()
|
||||||
if err != nil {
|
|
||||||
log.Debugf(".env Fatal error config file: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
Params.AutomaticEnv()
|
Params.Set("VERSION", version)
|
||||||
if err != nil {
|
|
||||||
log.Debugf("No environment variables found: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDefaults() {
|
func setDefaults() {
|
||||||
defaultDir, err := os.Getwd()
|
if Directory == "" {
|
||||||
if err != nil {
|
defaultDir, err := os.Getwd()
|
||||||
defaultDir = "."
|
if err != nil {
|
||||||
|
defaultDir = "."
|
||||||
|
}
|
||||||
|
Params.SetDefault("STATPING_DIR", defaultDir)
|
||||||
|
Directory = defaultDir
|
||||||
}
|
}
|
||||||
Params.SetDefault("STATPING_DIR", defaultDir)
|
|
||||||
Directory = Params.GetString("STATPING_DIR")
|
Directory = Params.GetString("STATPING_DIR")
|
||||||
|
Params.SetDefault("STATPING_DIR", Directory)
|
||||||
Params.SetDefault("GO_ENV", "")
|
Params.SetDefault("GO_ENV", "")
|
||||||
Params.SetDefault("DISABLE_LOGS", false)
|
Params.SetDefault("DISABLE_LOGS", false)
|
||||||
Params.SetDefault("BASE_PATH", "")
|
Params.SetDefault("BASE_PATH", "")
|
||||||
|
@ -51,9 +49,8 @@ func setDefaults() {
|
||||||
Params.SetDefault("SAMPLE_DATA", true)
|
Params.SetDefault("SAMPLE_DATA", true)
|
||||||
Params.SetDefault("USE_CDN", false)
|
Params.SetDefault("USE_CDN", false)
|
||||||
Params.SetDefault("ALLOW_REPORTS", false)
|
Params.SetDefault("ALLOW_REPORTS", false)
|
||||||
Params.SetDefault("AUTH_USERNAME", "")
|
|
||||||
Params.SetDefault("AUTH_PASSWORD", "")
|
|
||||||
Params.SetDefault("POSTGRES_SSLMODE", "disable")
|
Params.SetDefault("POSTGRES_SSLMODE", "disable")
|
||||||
|
Params.SetDefault("SASS", "sass")
|
||||||
|
|
||||||
dbConn := Params.GetString("DB_CONN")
|
dbConn := Params.GetString("DB_CONN")
|
||||||
dbInt := Params.GetInt("DB_PORT")
|
dbInt := Params.GetInt("DB_PORT")
|
||||||
|
|
|
@ -24,7 +24,7 @@ func CreateDirectory(directory string) error {
|
||||||
|
|
||||||
// FolderExists will return true if the folder exists
|
// FolderExists will return true if the folder exists
|
||||||
func FolderExists(folder string) bool {
|
func FolderExists(folder string) bool {
|
||||||
if _, err := os.Stat(folder); os.IsExist(err) {
|
if stat, err := os.Stat(folder); err == nil && stat.IsDir() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -45,13 +45,13 @@ func FileExists(name string) bool {
|
||||||
// DeleteFile will attempt to delete a file
|
// DeleteFile will attempt to delete a file
|
||||||
// DeleteFile("newfile.json")
|
// DeleteFile("newfile.json")
|
||||||
func DeleteFile(file string) error {
|
func DeleteFile(file string) error {
|
||||||
Log.Debugln("deleting file: " + file)
|
Log.Warn("deleting file: " + file)
|
||||||
return os.Remove(file)
|
return os.Remove(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenameDirectory will attempt rename a directory to a new name
|
// RenameDirectory will attempt rename a directory to a new name
|
||||||
func RenameDirectory(fromDir string, toDir string) error {
|
func RenameDirectory(fromDir string, toDir string) error {
|
||||||
Log.Debugln("renaming directory: " + fromDir + "to: " + toDir)
|
Log.Warn("renaming directory: " + fromDir + "to: " + toDir)
|
||||||
return os.Rename(fromDir, toDir)
|
return os.Rename(fromDir, toDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,11 @@ type env struct {
|
||||||
data interface{}
|
data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NotNumber(val string) bool {
|
||||||
|
_, err := strconv.ParseInt(val, 10, 64)
|
||||||
|
return err != nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetenvAs(key string, defaultValue interface{}) *env {
|
func GetenvAs(key string, defaultValue interface{}) *env {
|
||||||
return &env{
|
return &env{
|
||||||
data: Getenv(key, defaultValue),
|
data: Getenv(key, defaultValue),
|
||||||
|
|
|
@ -201,6 +201,5 @@ func TestConfigLoad(t *testing.T) {
|
||||||
assert.Equal(t, "sqlite", s("DB_CONN"))
|
assert.Equal(t, "sqlite", s("DB_CONN"))
|
||||||
assert.Equal(t, Directory, s("STATPING_DIR"))
|
assert.Equal(t, Directory, s("STATPING_DIR"))
|
||||||
assert.True(t, b("SAMPLE_DATA"))
|
assert.True(t, b("SAMPLE_DATA"))
|
||||||
assert.False(t, b("DISABLE_LOGS"))
|
|
||||||
assert.False(t, b("ALLOW_REPORTS"))
|
assert.False(t, b("ALLOW_REPORTS"))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue