diff --git a/checker.go b/checker.go
index e5040bf3..3c5a2a8c 100644
--- a/checker.go
+++ b/checker.go
@@ -10,8 +10,6 @@ import (
func CheckServices() {
services, _ = SelectAllServices()
- core.Communications, _ = SelectAllCommunications()
- LoadDefaultCommunications()
for _, v := range services {
obj := v
go obj.StartCheckins()
@@ -42,18 +40,24 @@ func (s *Service) Check() *Service {
return s
}
defer response.Body.Close()
+ contents, _ := ioutil.ReadAll(response.Body)
if s.Expected != "" {
- contents, _ := ioutil.ReadAll(response.Body)
match, _ := regexp.MatchString(s.Expected, string(contents))
if !match {
+ s.LastResponse = string(contents)
+ s.LastStatusCode = response.StatusCode
s.Failure(fmt.Sprintf("HTTP Response Body did not match '%v'", s.Expected))
return s
}
}
if s.ExpectedStatus != response.StatusCode {
+ s.LastResponse = string(contents)
+ s.LastStatusCode = response.StatusCode
s.Failure(fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
return s
}
+ s.LastResponse = string(contents)
+ s.LastStatusCode = response.StatusCode
s.Online = true
s.Record(response)
return s
@@ -65,6 +69,7 @@ type HitData struct {
func (s *Service) Record(response *http.Response) {
s.Online = true
+ s.LastOnline = time.Now()
data := HitData{
Latency: s.Latency,
}
@@ -82,5 +87,8 @@ func (s *Service) Failure(issue string) {
Issue: issue,
}
s.CreateFailure(data)
+
+ SendFailureEmail(s)
+
OnFailure(s)
}
diff --git a/comms/emailer.go b/comms/emailer.go
deleted file mode 100644
index fd7aaa49..00000000
--- a/comms/emailer.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package comms
-
-import (
- "bytes"
- "crypto/tls"
- "fmt"
- "github.com/hunterlong/statup/types"
- "gopkg.in/gomail.v2"
- "html/template"
- "log"
- "time"
-)
-
-var (
- Emailer *gomail.Dialer
- Outgoing []*types.Email
-)
-
-func AddEmail(email *types.Email) {
- Outgoing = append(Outgoing, email)
-}
-
-func EmailerQueue() {
- defer EmailerQueue()
- for _, out := range Outgoing {
- fmt.Printf("sending email to: %v \n", out.To)
- Send(out)
- }
- Outgoing = nil
- fmt.Println("running emailer queue")
- time.Sleep(10 * time.Second)
-}
-
-func Send(em *types.Email) {
- source := EmailTemplate("comms/templates/error.html", nil)
- m := gomail.NewMessage()
- m.SetHeader("From", "info@betatude.com")
- m.SetHeader("To", em.To)
- m.SetHeader("Subject", em.Subject)
- m.SetBody("text/html", source)
- if err := Emailer.DialAndSend(m); err != nil {
- fmt.Println(err)
- }
-}
-
-func SendSample(em *types.Email) {
- source := EmailTemplate("comms/templates/error.html", nil)
- m := gomail.NewMessage()
- m.SetHeader("From", "info@betatude.com")
- m.SetHeader("To", em.To)
- m.SetHeader("Subject", em.Subject)
- m.SetBody("text/html", source)
- if err := Emailer.DialAndSend(m); err != nil {
- fmt.Println(err)
- }
-}
-
-func LoadMailer(config *types.Communication) *gomail.Dialer {
- Emailer = gomail.NewDialer(config.Host, config.Port, config.Username, config.Password)
- Emailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
- return Emailer
-}
-
-func EmailTemplate(tmpl string, data interface{}) string {
- t := template.New("error.html")
- var err error
- t, err = t.ParseFiles(tmpl)
- if err != nil {
- panic(err)
- }
- var tpl bytes.Buffer
- if err := t.Execute(&tpl, data); err != nil {
- log.Println(err)
- }
- result := tpl.String()
- return result
-}
diff --git a/communication.go b/communication.go
index 942c842f..0817f311 100644
--- a/communication.go
+++ b/communication.go
@@ -1,15 +1,16 @@
package main
import (
- "github.com/hunterlong/statup/comms"
+ "fmt"
"github.com/hunterlong/statup/types"
"time"
)
func LoadDefaultCommunications() {
emailer := SelectCommunication(1)
- comms.LoadMailer(emailer)
- go comms.EmailerQueue()
+ fmt.Println(emailer)
+ LoadMailer(emailer)
+ go EmailerQueue()
}
func LoadComms() {
@@ -27,7 +28,7 @@ func Run(c *types.Communication) {
Subject: "Test Email from Statup",
}
- comms.AddEmail(sample)
+ AddEmail(sample)
}
func SelectAllCommunications() ([]*types.Communication, error) {
diff --git a/emailer.go b/emailer.go
new file mode 100644
index 00000000..029065f5
--- /dev/null
+++ b/emailer.go
@@ -0,0 +1,101 @@
+package main
+
+import (
+ "bytes"
+ "crypto/tls"
+ "fmt"
+ "github.com/hunterlong/statup/types"
+ "gopkg.in/gomail.v2"
+ "html/template"
+ "log"
+ "time"
+)
+
+var (
+ emailQue *Que
+)
+
+type Que struct {
+ Mailer *gomail.Dialer
+ Outgoing []*types.Email
+ LastSent int
+ LastSentTime time.Time
+}
+
+func AddEmail(email *types.Email) {
+ emailQue.Outgoing = append(emailQue.Outgoing, email)
+}
+
+func EmailerQueue() {
+ defer EmailerQueue()
+ uniques := []*types.Email{}
+ for _, out := range emailQue.Outgoing {
+ if isUnique(uniques, out) {
+ fmt.Printf("sending email to: %v \n", out.To)
+ Send(out)
+ uniques = append(uniques, out)
+ }
+ }
+ emailQue.Outgoing = nil
+ fmt.Println("running emailer queue")
+ time.Sleep(60 * time.Second)
+}
+
+func isUnique(arr []*types.Email, obj *types.Email) bool {
+ for _, v := range arr {
+ if v.To == obj.To && v.Subject == obj.Subject {
+ return false
+ }
+ }
+ return true
+}
+
+func Send(em *types.Email) {
+ source := EmailTemplate(em.Template, em.Data)
+ m := gomail.NewMessage()
+ m.SetHeader("From", "info@betatude.com")
+ m.SetHeader("To", em.To)
+ m.SetHeader("Subject", em.Subject)
+ m.SetBody("text/html", source)
+ if err := emailQue.Mailer.DialAndSend(m); err != nil {
+ fmt.Println(err)
+ }
+ emailQue.LastSent++
+ emailQue.LastSentTime = time.Now()
+}
+
+func SendFailureEmail(service *Service) {
+ email := &types.Email{
+ To: "info@socialeck.com",
+ Subject: fmt.Sprintf("Service %v is Failing", service.Name),
+ Template: "failure.html",
+ Data: service,
+ }
+ AddEmail(email)
+}
+
+func LoadMailer(config *types.Communication) *gomail.Dialer {
+ emailQue = &Que{}
+ emailQue.Outgoing = []*types.Email{}
+ emailQue.Mailer = gomail.NewDialer(config.Host, config.Port, config.Username, config.Password)
+ emailQue.Mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
+ return emailQue.Mailer
+}
+
+func EmailTemplate(tmpl string, data interface{}) string {
+ emailTpl, err := emailBox.String(tmpl)
+ if err != nil {
+ panic(err)
+ }
+ t := template.New("email")
+ t, err = t.Parse(emailTpl)
+ if err != nil {
+ panic(err)
+ }
+ var tpl bytes.Buffer
+ if err := t.Execute(&tpl, data); err != nil {
+ log.Println(err)
+ }
+ result := tpl.String()
+ return result
+}
diff --git a/exporter.go b/exporter.go
index 9bebe904..069c1328 100644
--- a/exporter.go
+++ b/exporter.go
@@ -9,9 +9,16 @@ import (
var httpFunctions template.FuncMap
-func init() {
-
- httpFunctions = template.FuncMap{
+func ExportIndexHTML() string {
+ out := index{*core, services}
+ nav, _ := tmplBox.String("nav.html")
+ footer, _ := tmplBox.String("footer.html")
+ render, err := tmplBox.String("index.html")
+ if err != nil {
+ panic(err)
+ }
+ t := template.New("message")
+ t.Funcs(template.FuncMap{
"js": func(html string) template.JS {
return template.JS(html)
},
@@ -24,20 +31,7 @@ func init() {
"underscore": func(html string) string {
return UnderScoreString(html)
},
- }
-
-}
-
-func ExportIndexHTML() string {
- out := index{*core, services}
- nav, _ := tmplBox.String("nav.html")
- footer, _ := tmplBox.String("footer.html")
- render, err := tmplBox.String("index.html")
- if err != nil {
- panic(err)
- }
- t := template.New("message")
- t.Funcs(httpFunctions)
+ })
t, _ = t.Parse(nav)
t, _ = t.Parse(footer)
t.Parse(render)
diff --git a/comms/templates/error.html b/html/emails/error.html
similarity index 100%
rename from comms/templates/error.html
rename to html/emails/error.html
diff --git a/html/emails/failure.html b/html/emails/failure.html
new file mode 100644
index 00000000..f3abd13e
--- /dev/null
+++ b/html/emails/failure.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+ Sample Email
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ .Name }} is Offline!
+
+ Your Statup service named '{{.Name}}' has been triggered with a HTTP status code of '{{.LastStatusCode}}' and is currently offline based on your requirements.
+
+
+ Last Response
+
+ {{ .LastResponse }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/html/tmpl/service.html b/html/tmpl/service.html
index 0d78f8dc..10570ca5 100644
--- a/html/tmpl/service.html
+++ b/html/tmpl/service.html
@@ -163,6 +163,20 @@
+
+
+
Last Response
+
+
+
+
+
+
{{end}}
diff --git a/html/tmpl/setup.html b/html/tmpl/setup.html
index 70a421ca..28b31474 100644
--- a/html/tmpl/setup.html
+++ b/html/tmpl/setup.html
@@ -74,6 +74,11 @@
+
+ Admin Email Address
+
+
+
Admin Password
diff --git a/main.go b/main.go
index 58c18b0d..5a846b42 100644
--- a/main.go
+++ b/main.go
@@ -26,6 +26,7 @@ var (
cssBox *rice.Box
jsBox *rice.Box
tmplBox *rice.Box
+ emailBox *rice.Box
setupMode bool
allPlugins []plugin.PluginActions
)
@@ -152,6 +153,8 @@ func mainProcess() {
RunHTTPServer()
}
CheckServices()
+ core.Communications, _ = SelectAllCommunications()
+ LoadDefaultCommunications()
if !setupMode {
LoadPlugins()
RunHTTPServer()
@@ -221,6 +224,7 @@ func RenderBoxes() {
cssBox = rice.MustFindBox("html/css")
jsBox = rice.MustFindBox("html/js")
tmplBox = rice.MustFindBox("html/tmpl")
+ emailBox = rice.MustFindBox("html/emails")
}
func LoadConfig() (*Config, error) {
diff --git a/services.go b/services.go
index 3d5ecb77..04e05134 100644
--- a/services.go
+++ b/services.go
@@ -35,6 +35,9 @@ type Service struct {
Failures []*Failure `json:"failures"`
Checkins []*Checkin `json:"checkins"`
runRoutine bool
+ LastResponse string
+ LastStatusCode int
+ LastOnline time.Time
}
func serviceCol() db.Collection {
diff --git a/setup.go b/setup.go
index 05ae241b..0b7e5752 100644
--- a/setup.go
+++ b/setup.go
@@ -45,6 +45,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
sample := r.PostForm.Get("sample_data")
description := r.PostForm.Get("description")
domain := r.PostForm.Get("domain")
+ email := r.PostForm.Get("email")
config := &DbConfig{
dbConn,
@@ -85,6 +86,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
admin := &User{
Username: config.Username,
Password: config.Password,
+ Email: email,
Admin: true,
}
admin.Create()
diff --git a/types/types.go b/types/types.go
index c6483ab2..a1085574 100644
--- a/types/types.go
+++ b/types/types.go
@@ -24,5 +24,4 @@ type Email struct {
Subject string
Template string
Data interface{}
- Body string
}
diff --git a/users.go b/users.go
index 30681868..a57ccee3 100644
--- a/users.go
+++ b/users.go
@@ -2,6 +2,7 @@ package main
import (
"golang.org/x/crypto/bcrypt"
+ "net/http"
"time"
)
@@ -16,6 +17,19 @@ type User struct {
CreatedAt time.Time `db:"created_at" json:"created_at"`
}
+func SessionUser(r *http.Request) *User {
+ session, _ := store.Get(r, cookieKey)
+ if session == nil {
+ return nil
+ }
+ uuid := session.Values["user_id"]
+ var user *User
+ col := dbSession.Collection("users")
+ res := col.Find("id", uuid)
+ res.One(&user)
+ return user
+}
+
func SelectUser(id int64) (*User, error) {
var user User
col := dbSession.Collection("users")
@@ -40,8 +54,7 @@ func (u *User) Delete() error {
func (u *User) Create() (int64, error) {
u.CreatedAt = time.Now()
- password := HashPassword(u.Password)
- u.Password = password
+ u.Password = HashPassword(u.Password)
u.ApiKey = NewSHA1Hash(5)
u.ApiSecret = NewSHA1Hash(10)
col := dbSession.Collection("users")
diff --git a/web.go b/web.go
index 7a0bec13..13e2c0a6 100644
--- a/web.go
+++ b/web.go
@@ -5,7 +5,6 @@ import (
"github.com/fatih/structs"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
- "github.com/hunterlong/statup/comms"
"github.com/hunterlong/statup/types"
"html/template"
"net/http"
@@ -96,9 +95,10 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
- _, auth := AuthUser(username, password)
+ user, auth := AuthUser(username, password)
if auth {
session.Values["authenticated"] = true
+ session.Values["user_id"] = user.Id
session.Save(r, w)
http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
} else {
@@ -265,13 +265,11 @@ func SaveEmailSettingsHandler(w http.ResponseWriter, r *http.Request) {
Update(emailer)
sample := &types.Email{
- To: "info@socialeck.com",
+ To: SessionUser(r).Email,
Subject: "Sample Email",
- Template: "templates/error.html",
- Body: "okkokkok",
+ Template: "error.html",
}
-
- comms.AddEmail(sample)
+ AddEmail(sample)
http.Redirect(w, r, "/settings", http.StatusSeeOther)
}
@@ -416,11 +414,6 @@ func ServicesBadgeHandler(w http.ResponseWriter, r *http.Request) {
}
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
- auth := IsAuthenticated(r)
- if !auth {
- http.Redirect(w, r, "/", http.StatusSeeOther)
- return
- }
vars := mux.Vars(r)
service := SelectService(StringInt(vars["id"]))
ExecuteResponse(w, r, "service.html", service)
@@ -450,6 +443,9 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
"underscore": func(html string) string {
return UnderScoreString(html)
},
+ "User": func() *User {
+ return SessionUser(r)
+ },
})
t, _ = t.Parse(nav)
t, _ = t.Parse(footer)