mirror of https://github.com/statping/statping
notification fixes, tests
parent
f331e9bbf9
commit
7d385b4da2
|
@ -1,3 +1,8 @@
|
|||
# 0.90.17
|
||||
- Fixed notification fields for frontend
|
||||
- Fixed notification JSON form to send integer if value is an integer.
|
||||
- Added testing for notifiers
|
||||
|
||||
# 0.90.16
|
||||
- Added Notify After (int) field for Services. Will send notifications after x amount of failures.
|
||||
- Added new method in utils package for replacing `{{.Service.*}}` and `{{.Failure.*}}` variables from string to it's true value
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/statping/statping/notifiers"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/utils"
|
||||
)
|
||||
|
||||
func InitApp() error {
|
||||
|
@ -22,5 +23,6 @@ func InitApp() error {
|
|||
|
||||
database.StartMaintenceRoutine()
|
||||
core.App.Setup = true
|
||||
core.App.Started = utils.Now()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -92,7 +92,11 @@ export default {
|
|||
this.form.method = this.notifier.method
|
||||
this.notifier.form.forEach((f) => {
|
||||
let field = f.field.toLowerCase()
|
||||
this.form[field] = this.notifier[field]
|
||||
let val = this.notifier[field]
|
||||
if (this.isNumeric(val)) {
|
||||
val = parseInt(val)
|
||||
}
|
||||
this.form[field] = val
|
||||
});
|
||||
await Api.notifier_save(this.form)
|
||||
// const notifiers = await Api.notifiers()
|
||||
|
@ -109,12 +113,16 @@ export default {
|
|||
let form = {}
|
||||
this.notifier.form.forEach((f) => {
|
||||
let field = f.field.toLowerCase()
|
||||
this.form[field] = this.notifier[field]
|
||||
let val = this.notifier[field]
|
||||
if (this.isNumeric(val)) {
|
||||
val = parseInt(val)
|
||||
}
|
||||
this.form[field] = val
|
||||
});
|
||||
form.enabled = this.notifier.enabled
|
||||
form.limits = parseInt(this.notifier.limits)
|
||||
form.method = this.notifier.method
|
||||
const tested = await Api.notifier_test(form)
|
||||
this.form.enabled = this.notifier.enabled
|
||||
this.form.limits = parseInt(this.notifier.limits)
|
||||
this.form.method = this.notifier.method
|
||||
const tested = await Api.notifier_test(this.form)
|
||||
if (tested === 'ok') {
|
||||
this.ok = true
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,9 @@ export default Vue.mixin({
|
|||
now() {
|
||||
return new Date()
|
||||
},
|
||||
isNumeric: function (n) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
},
|
||||
current() {
|
||||
return parseISO(new Date())
|
||||
},
|
||||
|
|
|
@ -17,7 +17,6 @@ package handlers
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
|
@ -34,16 +33,14 @@ func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
notifier := vars["notifier"]
|
||||
notifiers := services.AllNotifiers()
|
||||
for _, n := range notifiers {
|
||||
notf := n.Select()
|
||||
if notifier == notf.Method {
|
||||
returnJson(n, w, r)
|
||||
return
|
||||
}
|
||||
notif := services.FindNotifier(vars["notifier"])
|
||||
notifer, err := notifications.Find(notif.Method)
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
sendErrorJson(errors.New("notifier not found"), w, r)
|
||||
notif = notif.UpdateFields(notifer)
|
||||
returnJson(notif, w, r)
|
||||
}
|
||||
|
||||
func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -53,14 +50,15 @@ func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var notif *notifications.Notification
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err = decoder.Decode(¬ifer)
|
||||
err = decoder.Decode(¬if)
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
notifer = notifer.UpdateFields(notif)
|
||||
err = notifer.Update()
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
|
|
|
@ -102,6 +102,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
//ApiSecret: apiSecret.(string),
|
||||
Domain: "http://localhost:8080",
|
||||
Version: core.App.Version,
|
||||
Started: utils.Now(),
|
||||
CreatedAt: utils.Now(),
|
||||
UseCdn: null.NewNullBool(false),
|
||||
Footer: null.NewNullString(""),
|
||||
|
|
|
@ -72,25 +72,25 @@ func runCommand(app string, cmd ...string) (string, string, error) {
|
|||
}
|
||||
|
||||
// OnFailure for commandLine will trigger failing service
|
||||
func (u *commandLine) OnFailure(s *services.Service, f *failures.Failure) error {
|
||||
msg := u.GetValue("var2")
|
||||
func (c *commandLine) OnFailure(s *services.Service, f *failures.Failure) error {
|
||||
msg := c.GetValue("var2")
|
||||
tmpl := ReplaceVars(msg, s, f)
|
||||
_, _, err := runCommand(u.Host, tmpl)
|
||||
_, _, err := runCommand(c.Host, tmpl)
|
||||
return err
|
||||
}
|
||||
|
||||
// OnSuccess for commandLine will trigger successful service
|
||||
func (u *commandLine) OnSuccess(s *services.Service) error {
|
||||
msg := u.GetValue("var1")
|
||||
func (c *commandLine) OnSuccess(s *services.Service) error {
|
||||
msg := c.GetValue("var1")
|
||||
tmpl := ReplaceVars(msg, s, nil)
|
||||
_, _, err := runCommand(u.Host, tmpl)
|
||||
_, _, err := runCommand(c.Host, tmpl)
|
||||
return err
|
||||
}
|
||||
|
||||
// OnTest for commandLine triggers when this notifier has been saved
|
||||
func (u *commandLine) OnTest() error {
|
||||
cmds := strings.Split(u.Var1, " ")
|
||||
in, out, err := runCommand(u.Host, cmds...)
|
||||
func (c *commandLine) OnTest() error {
|
||||
cmds := strings.Split(c.Var1, " ")
|
||||
in, out, err := runCommand(c.Host, cmds...)
|
||||
utils.Log.Infoln(in)
|
||||
utils.Log.Infoln(out)
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCommandNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
t.Run("Load Command", func(t *testing.T) {
|
||||
Command.Host = "/bin/echo"
|
||||
Command.Var1 = "service {{.Service.Domain}} is online"
|
||||
Command.Var2 = "service {{.Service.Domain}} is offline"
|
||||
Command.Delay = time.Duration(100 * time.Millisecond)
|
||||
Command.Limits = 99
|
||||
Command.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Command)
|
||||
|
||||
assert.Equal(t, "Hunter Long", Command.Author)
|
||||
assert.Equal(t, "/bin/echo", Command.Host)
|
||||
})
|
||||
|
||||
t.Run("Command Notifier Tester", func(t *testing.T) {
|
||||
assert.True(t, Command.CanSend())
|
||||
})
|
||||
|
||||
t.Run("Command OnFailure", func(t *testing.T) {
|
||||
err := Command.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Command OnSuccess", func(t *testing.T) {
|
||||
err := Command.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Command Test", func(t *testing.T) {
|
||||
err := Command.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
DISCORD_URL = os.Getenv("DISCORD_URL")
|
||||
discordMessage = `{"content": "The discord notifier on Statping has been tested!"}`
|
||||
)
|
||||
|
||||
func init() {
|
||||
DISCORD_URL = os.Getenv("DISCORD_URL")
|
||||
}
|
||||
|
||||
func TestDiscordNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
if DISCORD_URL == "" {
|
||||
t.Log("discord notifier testing skipped, missing DISCORD_URL environment variable")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("Load discord", func(t *testing.T) {
|
||||
Discorder.Host = DISCORD_URL
|
||||
Discorder.Delay = time.Duration(100 * time.Millisecond)
|
||||
Discorder.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Discorder)
|
||||
|
||||
assert.Equal(t, "Hunter Long", Discorder.Author)
|
||||
assert.Equal(t, DISCORD_URL, Discorder.Host)
|
||||
})
|
||||
|
||||
t.Run("discord Notifier Tester", func(t *testing.T) {
|
||||
assert.True(t, Discorder.CanSend())
|
||||
})
|
||||
|
||||
t.Run("discord OnFailure", func(t *testing.T) {
|
||||
err := Discorder.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("discord OnSuccess", func(t *testing.T) {
|
||||
err := Discorder.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("discord Test", func(t *testing.T) {
|
||||
err := Discorder.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
package notifiers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/go-mail/mail"
|
||||
|
@ -26,7 +25,6 @@ import (
|
|||
"github.com/statping/statping/types/null"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/utils"
|
||||
"html/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -183,7 +181,7 @@ func (e *emailer) OnFailure(s *services.Service, f *failures.Failure) error {
|
|||
To: e.Var2,
|
||||
Subject: fmt.Sprintf("Service %v is Failing", s.Name),
|
||||
Template: mainEmailTemplate,
|
||||
Data: interface{}(s),
|
||||
Data: ToMap(s, f),
|
||||
From: e.Var1,
|
||||
}
|
||||
return e.dialSend(email)
|
||||
|
@ -196,7 +194,7 @@ func (e *emailer) OnSuccess(s *services.Service) error {
|
|||
To: e.Var2,
|
||||
Subject: msg,
|
||||
Template: mainEmailTemplate,
|
||||
Data: interface{}(s),
|
||||
Data: ToMap(s, nil),
|
||||
From: e.Var1,
|
||||
}
|
||||
return e.dialSend(email)
|
||||
|
@ -230,7 +228,6 @@ func (e *emailer) OnTest() error {
|
|||
|
||||
func (e *emailer) dialSend(email *emailOutgoing) error {
|
||||
mailer = mail.NewDialer(e.Host, e.Port, e.Username, e.Password)
|
||||
emailSource(email)
|
||||
m := mail.NewMessage()
|
||||
// if email setting TLS is Disabled
|
||||
if e.ApiKey == "true" {
|
||||
|
@ -241,29 +238,11 @@ func (e *emailer) dialSend(email *emailOutgoing) error {
|
|||
m.SetHeader("From", email.From)
|
||||
m.SetHeader("To", email.To)
|
||||
m.SetHeader("Subject", email.Subject)
|
||||
m.SetBody("text/html", email.Source)
|
||||
m.SetBody("text/html", utils.ReplaceTemplate(email.Template, email.Data))
|
||||
|
||||
if err := mailer.DialAndSend(m); err != nil {
|
||||
utils.Log.Errorln(fmt.Sprintf("email '%v' sent to: %v (size: %v) %v", email.Subject, email.To, len([]byte(email.Source)), err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func emailSource(email *emailOutgoing) {
|
||||
source := emailTemplate(email.Template, email.Data)
|
||||
email.Source = source
|
||||
}
|
||||
|
||||
func emailTemplate(contents string, data interface{}) string {
|
||||
t := template.New("email")
|
||||
t, err := t.Parse(contents)
|
||||
if err != nil {
|
||||
utils.Log.Errorln(err)
|
||||
}
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, data); err != nil {
|
||||
utils.Log.Warnln(err)
|
||||
}
|
||||
result := tpl.String()
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/statping/statping/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
EMAIL_HOST string
|
||||
EMAIL_USER string
|
||||
EMAIL_PASS string
|
||||
EMAIL_OUTGOING string
|
||||
EMAIL_SEND_TO string
|
||||
EMAIL_PORT int64
|
||||
)
|
||||
|
||||
var testEmail *emailOutgoing
|
||||
|
||||
func init() {
|
||||
EMAIL_HOST = os.Getenv("EMAIL_HOST")
|
||||
EMAIL_USER = os.Getenv("EMAIL_USER")
|
||||
EMAIL_PASS = os.Getenv("EMAIL_PASS")
|
||||
EMAIL_OUTGOING = os.Getenv("EMAIL_OUTGOING")
|
||||
EMAIL_SEND_TO = os.Getenv("EMAIL_SEND_TO")
|
||||
EMAIL_PORT = utils.ToInt(os.Getenv("EMAIL_PORT"))
|
||||
}
|
||||
|
||||
func TestEmailNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
if EMAIL_HOST == "" || EMAIL_USER == "" || EMAIL_PASS == "" {
|
||||
t.Log("email notifier testing skipped, missing EMAIL_ environment variables")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("New email", func(t *testing.T) {
|
||||
email.Host = EMAIL_HOST
|
||||
email.Username = EMAIL_USER
|
||||
email.Password = EMAIL_PASS
|
||||
email.Var1 = EMAIL_OUTGOING
|
||||
email.Var2 = EMAIL_SEND_TO
|
||||
email.Port = int(EMAIL_PORT)
|
||||
email.Delay = time.Duration(100 * time.Millisecond)
|
||||
email.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(email)
|
||||
assert.Equal(t, "Hunter Long", email.Author)
|
||||
assert.Equal(t, EMAIL_HOST, email.Host)
|
||||
|
||||
testEmail = &emailOutgoing{
|
||||
To: email.GetValue("var2"),
|
||||
Subject: fmt.Sprintf("Service %v is Failing", exampleService.Name),
|
||||
Template: mainEmailTemplate,
|
||||
Data: exampleService,
|
||||
From: email.GetValue("var1"),
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("email Within Limits", func(t *testing.T) {
|
||||
ok := email.CanSend()
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("email OnFailure", func(t *testing.T) {
|
||||
err := email.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("email OnSuccess", func(t *testing.T) {
|
||||
err := email.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("email Check Back Online", func(t *testing.T) {
|
||||
assert.True(t, exampleService.Online)
|
||||
})
|
||||
|
||||
t.Run("email OnSuccess Again", func(t *testing.T) {
|
||||
err := email.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("email Test", func(t *testing.T) {
|
||||
err := email.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
MOBILE_ID string
|
||||
MOBILE_NUMBER string
|
||||
)
|
||||
|
||||
func init() {
|
||||
MOBILE_ID = os.Getenv("MOBILE_ID")
|
||||
MOBILE_NUMBER = os.Getenv("MOBILE_NUMBER")
|
||||
Mobile.Var1 = MOBILE_ID
|
||||
}
|
||||
|
||||
func TestMobileNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
Mobile.Var1 = MOBILE_ID
|
||||
Mobile.Var2 = os.Getenv("MOBILE_NUMBER")
|
||||
if MOBILE_ID == "" {
|
||||
t.Log("Mobile notifier testing skipped, missing MOBILE_ID environment variable")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("Load Mobile", func(t *testing.T) {
|
||||
Mobile.Var1 = MOBILE_ID
|
||||
Mobile.Var2 = MOBILE_NUMBER
|
||||
Mobile.Delay = time.Duration(100 * time.Millisecond)
|
||||
Mobile.Limits = 10
|
||||
Mobile.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Mobile)
|
||||
|
||||
assert.Equal(t, "Hunter Long", Mobile.Author)
|
||||
assert.Equal(t, MOBILE_ID, Mobile.Var1)
|
||||
assert.Equal(t, MOBILE_NUMBER, Mobile.Var2)
|
||||
})
|
||||
|
||||
t.Run("Mobile Notifier Tester", func(t *testing.T) {
|
||||
assert.True(t, Mobile.CanSend())
|
||||
})
|
||||
|
||||
t.Run("Mobile OnFailure", func(t *testing.T) {
|
||||
err := Mobile.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Mobile OnSuccess", func(t *testing.T) {
|
||||
err := Mobile.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Mobile Test", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
err := Mobile.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -32,6 +32,13 @@ func Add(notifs ...services.ServiceNotifier) {
|
|||
}
|
||||
}
|
||||
|
||||
func ToMap(srv *services.Service, f *failures.Failure) map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
m["Service"] = srv
|
||||
m["Failure"] = f
|
||||
return m
|
||||
}
|
||||
|
||||
func ReplaceVars(input string, s *services.Service, f *failures.Failure) string {
|
||||
input = utils.ReplaceTemplate(input, s)
|
||||
if f != nil {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
SLACK_URL string
|
||||
)
|
||||
|
||||
func TestSlackNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
SLACK_URL = os.Getenv("SLACK_URL")
|
||||
slacker.Host = SLACK_URL
|
||||
slacker.Enabled = null.NewNullBool(true)
|
||||
|
||||
if SLACK_URL == "" {
|
||||
t.Log("slack notifier testing skipped, missing SLACK_URL environment variable")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("Load slack", func(t *testing.T) {
|
||||
slacker.Host = SLACK_URL
|
||||
slacker.Delay = time.Duration(100 * time.Millisecond)
|
||||
slacker.Limits = 3
|
||||
Add(slacker)
|
||||
assert.Equal(t, "Hunter Long", slacker.Author)
|
||||
assert.Equal(t, SLACK_URL, slacker.Host)
|
||||
})
|
||||
|
||||
t.Run("slack Within Limits", func(t *testing.T) {
|
||||
ok := slacker.CanSend()
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("slack OnFailure", func(t *testing.T) {
|
||||
err := slacker.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("slack OnSuccess", func(t *testing.T) {
|
||||
err := slacker.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// Statup
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
telegramToken string
|
||||
telegramChannel string
|
||||
telegramMessage = "The Telegram notifier on Statping has been tested!"
|
||||
)
|
||||
|
||||
func init() {
|
||||
telegramToken = os.Getenv("TELEGRAM_TOKEN")
|
||||
telegramChannel = os.Getenv("TELEGRAM_CHANNEL")
|
||||
Telegram.ApiSecret = telegramToken
|
||||
Telegram.Var1 = telegramChannel
|
||||
}
|
||||
|
||||
func TestTelegramNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
if telegramToken == "" || telegramChannel == "" {
|
||||
t.Log("Telegram notifier testing skipped, missing TELEGRAM_TOKEN and TELEGRAM_CHANNEL environment variable")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("Load Telegram", func(t *testing.T) {
|
||||
Telegram.ApiSecret = telegramToken
|
||||
Telegram.Var1 = telegramChannel
|
||||
Telegram.Delay = time.Duration(1 * time.Second)
|
||||
Telegram.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Telegram)
|
||||
|
||||
assert.Equal(t, "Hunter Long", Telegram.Author)
|
||||
assert.Equal(t, telegramToken, Telegram.ApiSecret)
|
||||
assert.Equal(t, telegramChannel, Telegram.Var1)
|
||||
})
|
||||
|
||||
t.Run("Telegram Within Limits", func(t *testing.T) {
|
||||
assert.True(t, Telegram.CanSend())
|
||||
})
|
||||
|
||||
t.Run("Telegram OnFailure", func(t *testing.T) {
|
||||
err := Telegram.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Telegram OnSuccess", func(t *testing.T) {
|
||||
err := Telegram.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Telegram Test", func(t *testing.T) {
|
||||
err := Telegram.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
TWILIO_SID = os.Getenv("TWILIO_SID")
|
||||
TWILIO_SECRET = os.Getenv("TWILIO_SECRET")
|
||||
TWILIO_FROM = os.Getenv("TWILIO_FROM")
|
||||
TWILIO_TO = os.Getenv("TWILIO_TO")
|
||||
)
|
||||
|
||||
func init() {
|
||||
TWILIO_SID = os.Getenv("TWILIO_SID")
|
||||
TWILIO_SECRET = os.Getenv("TWILIO_SECRET")
|
||||
TWILIO_FROM = os.Getenv("TWILIO_FROM")
|
||||
TWILIO_TO = os.Getenv("TWILIO_TO")
|
||||
}
|
||||
|
||||
func TestTwilioNotifier(t *testing.T) {
|
||||
t.SkipNow()
|
||||
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
if TWILIO_SID == "" || TWILIO_SECRET == "" || TWILIO_FROM == "" {
|
||||
t.Log("twilio notifier testing skipped, missing TWILIO_SID environment variable")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
t.Run("Load Twilio", func(t *testing.T) {
|
||||
Twilio.ApiKey = TWILIO_SID
|
||||
Twilio.ApiSecret = TWILIO_SECRET
|
||||
Twilio.Var1 = TWILIO_TO
|
||||
Twilio.Var2 = TWILIO_FROM
|
||||
Twilio.Delay = time.Duration(100 * time.Millisecond)
|
||||
Twilio.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Twilio)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Hunter Long", Twilio.Author)
|
||||
assert.Equal(t, TWILIO_SID, Twilio.ApiKey)
|
||||
})
|
||||
|
||||
t.Run("Twilio Within Limits", func(t *testing.T) {
|
||||
assert.True(t, Twilio.CanSend())
|
||||
})
|
||||
|
||||
t.Run("Twilio OnFailure", func(t *testing.T) {
|
||||
err := Twilio.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Twilio OnSuccess", func(t *testing.T) {
|
||||
err := Twilio.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Twilio Test", func(t *testing.T) {
|
||||
err := Twilio.OnTest()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
// Statping
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statping
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/notifications"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
webhookTestUrl = "http://localhost:5555"
|
||||
webhookMessage = `{"id": {{.Service.Id}},"name": "{{.Service.Name}}","online": {{.Service.Online}},"issue": "{{.Failure.Issue}}"}`
|
||||
apiKey = "application/json"
|
||||
fullMsg string
|
||||
)
|
||||
|
||||
func TestWebhookNotifier(t *testing.T) {
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.AutoMigrate(¬ifications.Notification{})
|
||||
notifications.SetDB(db)
|
||||
|
||||
t.Run("Load webhooker", func(t *testing.T) {
|
||||
Webhook.Host = webhookTestUrl
|
||||
Webhook.Var1 = "POST"
|
||||
Webhook.Var2 = webhookMessage
|
||||
Webhook.ApiKey = "application/json"
|
||||
Webhook.Enabled = null.NewNullBool(true)
|
||||
|
||||
Add(Webhook)
|
||||
|
||||
assert.Equal(t, "Hunter Long", Webhook.Author)
|
||||
assert.Equal(t, webhookTestUrl, Webhook.Host)
|
||||
assert.Equal(t, apiKey, Webhook.ApiKey)
|
||||
})
|
||||
|
||||
t.Run("webhooker Notifier Tester", func(t *testing.T) {
|
||||
assert.True(t, Webhook.CanSend())
|
||||
})
|
||||
|
||||
t.Run("webhooker OnFailure", func(t *testing.T) {
|
||||
err := Webhook.OnFailure(exampleService, exampleFailure)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("webhooker OnSuccess", func(t *testing.T) {
|
||||
err := Webhook.OnSuccess(exampleService)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("webhooker Send", func(t *testing.T) {
|
||||
err := Webhook.Send(fullMsg)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package core
|
|||
|
||||
import (
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/statping/statping/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -12,6 +13,7 @@ var (
|
|||
func New(version string) {
|
||||
App = new(Core)
|
||||
App.Version = version
|
||||
App.Started = utils.Now()
|
||||
}
|
||||
|
||||
// Core struct contains all the required fields for Statping. All application settings
|
||||
|
|
|
@ -32,7 +32,23 @@ func (n *Notification) Create() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (n *Notification) UpdateFields(notif *Notification) *Notification {
|
||||
n.Enabled = notif.Enabled
|
||||
n.Host = notif.Host
|
||||
n.Port = notif.Port
|
||||
n.Username = notif.Username
|
||||
n.Password = notif.Password
|
||||
n.ApiKey = notif.ApiKey
|
||||
n.ApiSecret = notif.ApiSecret
|
||||
n.Var1 = notif.Var1
|
||||
n.Var2 = notif.Var2
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *Notification) Update() error {
|
||||
if err := db.Update(n); err.Error() != nil {
|
||||
return err.Error()
|
||||
}
|
||||
n.ResetQueue()
|
||||
if n.Enabled.Bool {
|
||||
n.Close()
|
||||
|
@ -40,8 +56,7 @@ func (n *Notification) Update() error {
|
|||
} else {
|
||||
n.Close()
|
||||
}
|
||||
err := db.Update(n)
|
||||
return err.Error()
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadAll() []*Notification {
|
||||
|
|
|
@ -64,7 +64,7 @@ func (n *Notification) CanSend() bool {
|
|||
//fmt.Println("Last sent before now: ", n.lastSent.Add(60*time.Second).Before(utils.Now()))
|
||||
|
||||
// the last sent notification was past 1 minute (limit per minute)
|
||||
if n.lastSent.Add(60 * time.Second).Before(utils.Now()) {
|
||||
if n.lastSent.Add(60 * time.Minute).Before(utils.Now()) {
|
||||
if n.lastSentCount != 0 {
|
||||
n.lastSentCount--
|
||||
}
|
||||
|
|
|
@ -13,6 +13,16 @@ func AllNotifiers() []ServiceNotifier {
|
|||
return allNotifiers
|
||||
}
|
||||
|
||||
func FindNotifier(method string) *notifications.Notification {
|
||||
for _, n := range allNotifiers {
|
||||
notif := n.Select()
|
||||
if notif.Method == method {
|
||||
return notif
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ServiceNotifier interface {
|
||||
OnSuccess(*Service) error // OnSuccess is triggered when a service is successful
|
||||
OnFailure(*Service, *failures.Failure) error // OnFailure is triggered when a service is failing
|
||||
|
|
|
@ -3,6 +3,7 @@ package services
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/statping/statping/types/core"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -259,6 +260,12 @@ func sendSuccess(s *Service) {
|
|||
if s.SuccessNotified {
|
||||
return
|
||||
}
|
||||
|
||||
// dont send notification if server recently started (60 seconds)
|
||||
if core.App.Started.Add(60 * time.Second).After(utils.Now()) {
|
||||
s.SuccessNotified = true
|
||||
return
|
||||
}
|
||||
for _, n := range allNotifiers {
|
||||
notif := n.Select()
|
||||
if notif.CanSend() {
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.90.16
|
||||
0.90.17
|
||||
|
|
Loading…
Reference in New Issue