diff --git a/cli.go b/cli.go index 125438f8..2103accb 100644 --- a/cli.go +++ b/cli.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" "github.com/hunterlong/statup/core" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/plugin" - "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" "github.com/joho/godotenv" "io/ioutil" @@ -246,13 +246,13 @@ func FakeSeed(plug plugin.PluginActions) { } fakeUser.Create() - comm := &types.Communication{ + comm := ¬ifiers.Notification{ Id: 1, Method: "email", } core.Create(comm) - comm2 := &types.Communication{ + comm2 := ¬ifiers.Notification{ Id: 2, Method: "slack", } diff --git a/core/communication.go b/core/communication.go index 9bccb2f6..1cf7872f 100644 --- a/core/communication.go +++ b/core/communication.go @@ -1,37 +1,34 @@ package core import ( - "fmt" - "github.com/hunterlong/statup/notifications" - "github.com/hunterlong/statup/types" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/utils" - "time" ) func LoadDefaultCommunications() { - notifications.EmailComm = SelectCommunication(1) - emailer := notifications.EmailComm - if emailer.Enabled { - admin, _ := SelectUser(1) - notifications.LoadEmailer(emailer) - email := &types.Email{ - To: admin.Email, - Subject: "Test Email", - Template: "message.html", - Data: nil, - From: emailer.Var1, - } - notifications.SendEmail(EmailBox, email) - go notifications.EmailRoutine() - } - notifications.SlackComm = SelectCommunication(2) - slack := notifications.SlackComm - if slack.Enabled { - notifications.LoadSlack(slack.Host) - msg := fmt.Sprintf("Slack loaded on your Statup Status Page!") - notifications.SendSlack(msg) - go notifications.SlackRoutine() - } + //communications.EmailComm = SelectCommunication(1) + //emailer := communications.EmailComm + //if emailer.Enabled { + // admin, _ := SelectUser(1) + // communications.LoadEmailer(emailer) + // email := &types.Email{ + // To: admin.Email, + // Subject: "Test Email", + // Template: "message.html", + // Data: nil, + // From: emailer.Var1, + // } + // communications.SendEmail(EmailBox, email) + // go communications.EmailRoutine() + //} + //communications.SlackComm = SelectCommunication(2) + //slack := communications.SlackComm + //if slack.Enabled { + // communications.LoadSlack(slack.Host) + // msg := fmt.Sprintf("Slack loaded on your Statup Status Page!") + // communications.SendSlack(msg) + // go communications.SlackRoutine() + //} } func LoadComms() { @@ -42,51 +39,53 @@ func LoadComms() { } } -func SelectAllCommunications() ([]*types.Communication, error) { - var c []*types.Communication +func SelectAllCommunications() ([]*notifiers.Notification, error) { + var c []*notifiers.Notification col := DbSession.Collection("communication").Find() err := col.OrderBy("id").All(&c) - CoreApp.Communications = c + //CoreApp.Communications = c + //communications.LoadComms(c) return c, err } -func Create(c *types.Communication) (int64, error) { - c.CreatedAt = time.Now() - uuid, err := DbSession.Collection("communication").Insert(c) - if err != nil { - utils.Log(3, err) - } - if uuid == nil { - utils.Log(2, err) - return 0, err - } - c.Id = uuid.(int64) - c.Routine = make(chan struct{}) - if CoreApp != nil { - CoreApp.Communications = append(CoreApp.Communications, c) - } - return uuid.(int64), err +func Create(c *notifiers.Notification) (int64, error) { + //c.CreatedAt = time.Now() + //uuid, err := DbSession.Collection("communication").Insert(c) + //if err != nil { + // utils.Log(3, err) + //} + //if uuid == nil { + // utils.Log(2, err) + // return 0, err + //} + //c.Id = uuid.(int64) + //c.Routine = make(chan struct{}) + //if CoreApp != nil { + // CoreApp.Communications = append(CoreApp.Communications, c.Communicator) + //} + //return uuid.(int64), err + return 0, nil } -func Disable(c *types.Communication) { +func Disable(c *notifiers.Notification) { c.Enabled = false Update(c) } -func Enable(c *types.Communication) { +func Enable(c *notifiers.Notification) { c.Enabled = true Update(c) } -func Update(c *types.Communication) *types.Communication { +func Update(c *notifiers.Notification) *notifiers.Notification { col := DbSession.Collection("communication").Find("id", c.Id) col.Update(c) SelectAllCommunications() return c } -func SelectCommunication(id int64) *types.Communication { - var comm *types.Communication +func SelectCommunication(id int64) *notifiers.Notification { + var comm *notifiers.Notification col := DbSession.Collection("communication").Find("id", id) err := col.One(&comm) if err != nil { diff --git a/core/core.go b/core/core.go index d6804229..1d149efc 100644 --- a/core/core.go +++ b/core/core.go @@ -2,6 +2,7 @@ package core import ( "github.com/GeertJohan/go.rice" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/plugin" "github.com/hunterlong/statup/types" "github.com/pkg/errors" @@ -28,7 +29,7 @@ type Core struct { Plugins []plugin.Info Repos []PluginJSON AllPlugins []plugin.PluginActions - Communications []*types.Communication + Communications []*notifiers.Notification DbConnection string started time.Time } @@ -59,11 +60,19 @@ func NewCore() *Core { func InitApp() { SelectCore() + + notifiers.Collections = DbSession.Collection("communication") + SelectAllCommunications() InsertDefaultComms() LoadDefaultCommunications() SelectAllServices() CheckServices() + + notifiers.Load() + + CoreApp.Communications = notifiers.AllCommunications + go DatabaseMaintence() } diff --git a/core/events.go b/core/events.go index 29796333..aa4c919a 100644 --- a/core/events.go +++ b/core/events.go @@ -3,7 +3,7 @@ package core import ( "fmt" "github.com/fatih/structs" - "github.com/hunterlong/statup/notifications" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/plugin" "github.com/hunterlong/statup/types" "upper.io/db.v3/lib/sqlbuilder" @@ -25,10 +25,10 @@ func OnFailure(s *Service, f FailureData) { for _, p := range CoreApp.AllPlugins { p.OnFailure(structs.Map(s)) } - if notifications.SlackComm != nil { + if notifiers.SendSlack("im failing") != nil { onFailureSlack(s, f) } - if notifications.EmailComm != nil { + if notifiers.EmailComm != nil { onFailureEmail(s, f) } } @@ -36,8 +36,8 @@ func OnFailure(s *Service, f FailureData) { func onFailureSlack(s *Service, f FailureData) { slack := SelectCommunication(2) if slack.Enabled { - msg := fmt.Sprintf("Service %v is currently offline! Issue: %v", s.Name, f.Issue) - notifications.SendSlack(msg) + //msg := fmt.Sprintf("Service %v is currently offline! Issue: %v", s.Name, f.Issue) + //communications.SendSlack(msg) } } @@ -59,7 +59,7 @@ func onFailureEmail(s *Service, f FailureData) { Data: data, From: email.Var1, } - notifications.SendEmail(EmailBox, email) + notifiers.SendEmail(EmailBox, email) } } diff --git a/core/setup.go b/core/setup.go index f81bde73..38f14052 100644 --- a/core/setup.go +++ b/core/setup.go @@ -2,7 +2,7 @@ package core import ( "fmt" - "github.com/hunterlong/statup/types" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/utils" "os" ) @@ -10,7 +10,7 @@ import ( func InsertDefaultComms() { emailer := SelectCommunication(1) if emailer == nil { - emailer := &types.Communication{ + emailer := ¬ifiers.Notification{ Method: "email", Removable: false, Enabled: false, @@ -19,7 +19,7 @@ func InsertDefaultComms() { } slack := SelectCommunication(2) if slack == nil { - slack := &types.Communication{ + slack := ¬ifiers.Notification{ Method: "slack", Removable: false, Enabled: false, diff --git a/handlers/settings.go b/handlers/settings.go index f95d95ec..8a19650d 100644 --- a/handlers/settings.go +++ b/handlers/settings.go @@ -2,7 +2,7 @@ package handlers import ( "github.com/hunterlong/statup/core" - "github.com/hunterlong/statup/notifications" + "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" "net/http" @@ -117,12 +117,12 @@ func SaveEmailSettingsHandler(w http.ResponseWriter, r *http.Request) { Template: "message.html", From: emailer.Var1, } - notifications.LoadEmailer(emailer) - notifications.SendEmail(core.EmailBox, sample) - notifications.EmailComm = emailer + notifiers.LoadEmailer(emailer) + notifiers.SendEmail(core.EmailBox, sample) + notifiers.EmailComm = emailer if emailer.Enabled { utils.Log(1, "Starting Email Routine, 1 unique email per 60 seconds") - go notifications.EmailRoutine() + go notifiers.EmailRoutine() } http.Redirect(w, r, "/settings", http.StatusSeeOther) @@ -140,7 +140,7 @@ func SaveSlackSettingsHandler(w http.ResponseWriter, r *http.Request) { slack.Enabled = false if enable == "on" && slackWebhook != "" { slack.Enabled = true - go notifications.SlackRoutine() + //go communications.SlackRoutine() } slack.Host = slackWebhook core.Update(slack) diff --git a/nocmmitthis.env b/nocmmitthis.env new file mode 100644 index 00000000..ee160523 --- /dev/null +++ b/nocmmitthis.env @@ -0,0 +1,29 @@ +########################### +## Database Information # +########################### +DB_CONNECTION=postgres +DB_HOST=0.0.0.0 +DB_PORT=5432 +DB_USER=root +DB_PASS=password123 +DB_DATABASE=root + +########################### +## STATUP PAGE SETTINGS # +########################### +NAME=Demo +DESCRIPTION=This is an awesome page +DOMAIN=https://domain.com +ADMIN_USER=admin +ADMIN_PASS=admin +ADMIN_EMAIL=info@admin.com +USE_CDN=true + +########################### +## System Values ## +########################### +IS_DOCKER=true +IS_AWS=true +SASS=/usr/local/bin/sass +BASH_ENV=/bin/bash + diff --git a/notifications/slack.go b/notifications/slack.go deleted file mode 100644 index f6e78480..00000000 --- a/notifications/slack.go +++ /dev/null @@ -1,61 +0,0 @@ -package notifications - -import ( - "bytes" - "fmt" - "github.com/hunterlong/statup/types" - "github.com/hunterlong/statup/utils" - "github.com/pkg/errors" - "net/http" - "time" -) - -var ( - slackUrl string - sentLastMin int - slackMessages []string - SlackComm *types.Communication -) - -func LoadSlack(url string) { - if url == "" { - utils.Log(1, "Slack Webhook URL is empty") - return - } - slackUrl = url -} - -func SlackRoutine() { - for _, msg := range slackMessages { - utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook: %v", msg)) - client := http.Client{Timeout: 15 * time.Second} - _, err := client.Post(slackUrl, "application/json", bytes.NewBuffer([]byte(msg))) - if err != nil { - utils.Log(3, fmt.Sprintf("Issue sending Slack notification: %v", err)) - } - slackMessages = removeStrArray(slackMessages, msg) - } - time.Sleep(60 * time.Second) - if SlackComm.Enabled { - SlackRoutine() - } -} - -func removeStrArray(arr []string, v string) []string { - var newArray []string - for _, i := range arr { - if i != v { - newArray = append(newArray, v) - } - } - return newArray -} - -func SendSlack(msg string) error { - if slackUrl == "" { - return errors.New("Slack Webhook URL has not been set in settings") - } - fullMessage := fmt.Sprintf("{\"text\":\"%v\"}", msg) - slackMessages = append(slackMessages, fullMessage) - return nil -} diff --git a/notifications/email.go b/notifiers/email_old.go similarity index 96% rename from notifications/email.go rename to notifiers/email_old.go index 49001ee5..5db3b99e 100644 --- a/notifications/email.go +++ b/notifiers/email_old.go @@ -1,4 +1,4 @@ -package notifications +package notifiers import ( "bytes" @@ -15,7 +15,7 @@ import ( var ( mailer *gomail.Dialer emailQueue []*types.Email - EmailComm *types.Communication + EmailComm *Notification ) func EmailRoutine() { @@ -55,7 +55,7 @@ func dialSend(email *types.Email) error { return nil } -func LoadEmailer(mail *types.Communication) { +func LoadEmailer(mail *Notification) { utils.Log(1, fmt.Sprintf("Loading SMTP Emailer using host: %v:%v", mail.Host, mail.Port)) mailer = gomail.NewDialer(mail.Host, mail.Port, mail.Username, mail.Password) mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true} diff --git a/notifiers/notifiers.go b/notifiers/notifiers.go new file mode 100644 index 00000000..343aea42 --- /dev/null +++ b/notifiers/notifiers.go @@ -0,0 +1,77 @@ +package notifiers + +import ( + "github.com/hunterlong/statup/utils" + "time" + "upper.io/db.v3" +) + +var ( + AllCommunications []*Notification + Collections db.Collection +) + +func add(c *Notification) { + AllCommunications = append(AllCommunications, c) +} + +func Load() { + utils.Log(1, "Loading notifiers") + for _, comm := range AllCommunications { + comm.Init() + } +} + +type Notification struct { + Id int64 `db:"id,omitempty" json:"id"` + Method string `db:"method" json:"method"` + Host string `db:"host" json:"-"` + Port int `db:"port" json:"-"` + Username string `db:"username" json:"-"` + Password string `db:"password" json:"-"` + Var1 string `db:"var1" json:"-"` + Var2 string `db:"var2" json:"-"` + ApiKey string `db:"api_key" json:"-"` + ApiSecret string `db:"api_secret" json:"-"` + Enabled bool `db:"enabled" json:"enabled"` + Limits int64 `db:"limits" json:"-"` + Removable bool `db:"removable" json:"-"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + Form []NotificationForm + Routine chan struct{} +} + +type Notifier interface { + Init() error + Run() error + OnFailure() error + OnSuccess() error +} + +type NotificationForm struct { + Type string + Title string + Placeholder string +} + +func OnFailure() { + for _, comm := range AllCommunications { + comm.OnFailure() + } +} + +func OnSuccess() { + for _, comm := range AllCommunications { + comm.OnSuccess() + } +} + +func uniqueMessages(arr []string, v string) []string { + var newArray []string + for _, i := range arr { + if i != v { + newArray = append(newArray, v) + } + } + return newArray +} diff --git a/notifiers/slack.go b/notifiers/slack.go new file mode 100644 index 00000000..783ec229 --- /dev/null +++ b/notifiers/slack.go @@ -0,0 +1,96 @@ +package notifiers + +import ( + "bytes" + "fmt" + "github.com/hunterlong/statup/utils" + "net/http" + "time" +) + +const ( + SLACK_ID int64 = 2 + SLACK_METHOD = "slack" +) + +var ( + slacker *Notification + slackMessages []string +) + +// DEFINE YOUR NOTIFICATION HERE. +func init() { + slacker = &Notification{ + Id: SLACK_ID, + Method: SLACK_METHOD, + Host: "https://webhooksurl.slack.com/***", + Form: []NotificationForm{{ + Type: "text", + Title: "Incoming Webhook Url", + Placeholder: "Insert your Slack webhook URL here.", + }}, + } + add(slacker) +} + +// WHEN NOTIFIER LOADS +func (u *Notification) Init() error { + err := SendSlack("its online") + go u.Run() + return err +} + +// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS +func (u *Notification) Run() error { + for _, msg := range slackMessages { + utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook: %v", msg)) + client := http.Client{Timeout: 15 * time.Second} + _, err := client.Post("https://hooks.slack.com/services/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", "application/json", bytes.NewBuffer([]byte(msg))) + if err != nil { + utils.Log(3, fmt.Sprintf("Issue sending Slack notification: %v", err)) + } + slackMessages = uniqueMessages(slackMessages, msg) + } + time.Sleep(60 * time.Second) + if u.Enabled { + u.Run() + } + return nil +} + +// CUSTOM FUNCTION FO SENDING SLACK MESSAGES +func SendSlack(msg string) error { + //if slackUrl == "" { + // return errors.New("Slack Webhook URL has not been set in settings") + //} + fullMessage := fmt.Sprintf("{\"text\":\"%v\"}", msg) + slackMessages = append(slackMessages, fullMessage) + return nil +} + +// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS +func (u *Notification) OnFailure() error { + utils.Log(1, fmt.Sprintf("Notification %v is receiving a failure notification.", u.Method)) + + // Do failing stuff here! + + return nil +} + +// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS +func (u *Notification) OnSuccess() error { + utils.Log(1, fmt.Sprintf("Notification %v is receiving a successful notification.", u.Method)) + + // Do checking or any successful things here + + return nil +} + +// ON SAVE OR UPDATE OF THE NOTIFIER FORM +func (u *Notification) OnSave() error { + utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method)) + + // Do updating stuff here + + return nil +} diff --git a/notifiers/structs.go b/notifiers/structs.go new file mode 100644 index 00000000..48b634c4 --- /dev/null +++ b/notifiers/structs.go @@ -0,0 +1 @@ +package notifiers diff --git a/source/tmpl/settings.html b/source/tmpl/settings.html index 926eea21..b2df7958 100644 --- a/source/tmpl/settings.html +++ b/source/tmpl/settings.html @@ -33,10 +33,11 @@ Settings Theme Editor Email Settings - Slack Updates - {{ range .Communications }} + {{ range .Communications }} + {{.Method}} {{ end }} + Browse Plugins {{ range .Plugins }} {{.Name}} @@ -122,6 +123,33 @@ {{end}} + + {{ range .Communications }} +