-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added pull image to tests - Changed EmailSettings to Email
- Loading branch information
1 parent
3a9f5c1
commit aa0513c
Showing
8 changed files
with
306 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"net/smtp" | ||
"reflect" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
// Alerter is the interface which will handle alerting via different methods such as email | ||
// and twitter/slack | ||
type Alerter interface { | ||
Valid() error | ||
Alert(a *Alert) error | ||
} | ||
|
||
// Email implements the Alerter interface and sends emails | ||
type Email struct { | ||
SMTP string | ||
Password string | ||
Port string | ||
From string | ||
To []string | ||
Subject string | ||
} | ||
|
||
// Alert sends an email alert | ||
func (e Email) Alert(a *Alert) error { | ||
// alerts in string form | ||
alerts := a.Dump() | ||
|
||
// The email message formatted properly | ||
formattedMsg := []byte(fmt.Sprintf("To: %s\r\nSubject: %s\r\n\r\n%s\r\n", | ||
e.To, e.Subject, alerts)) | ||
|
||
// Set up authentication/address information | ||
auth := smtp.PlainAuth("", e.From, e.Password, e.SMTP) | ||
addr := fmt.Sprintf("%s:%s", e.SMTP, e.Port) | ||
|
||
err := smtp.SendMail(addr, auth, e.From, e.To, formattedMsg) | ||
if err != nil { | ||
return errors.Wrap(err, "error sending email") | ||
} | ||
|
||
log.Println("alert email sent") | ||
|
||
return nil | ||
} | ||
|
||
// Valid returns true if the email settings are complete | ||
func (e Email) Valid() error { | ||
errString := []string{} | ||
|
||
if reflect.DeepEqual(Email{}, e) { | ||
return nil // assume that email alerts were omitted | ||
} | ||
|
||
if e.SMTP == "" { | ||
errString = append(errString, ErrEmailNoSMTP.Error()) | ||
} | ||
|
||
if len(e.To) < 1 { | ||
errString = append(errString, ErrEmailNoTo.Error()) | ||
} | ||
|
||
if e.From == "" { | ||
errString = append(errString, ErrEmailNoFrom.Error()) | ||
} | ||
|
||
if e.Password == "" { | ||
errString = append(errString, ErrEmailNoPass.Error()) | ||
} | ||
|
||
if e.Port == "" { | ||
errString = append(errString, ErrEmailNoPort.Error()) | ||
} | ||
|
||
if e.Subject == "" { | ||
errString = append(errString, ErrEmailNoSubject.Error()) | ||
} | ||
|
||
if len(errString) == 0 { | ||
return nil | ||
} | ||
|
||
delimErr := strings.Join(errString, ", ") | ||
err := errors.New(delimErr) | ||
|
||
return errors.Wrap(err, "email settings validation fail") | ||
} | ||
|
||
// Slack contains all the info needed to connect to a slack channel | ||
type Slack struct { | ||
WebhookURL string | ||
} | ||
|
||
// Valid returns an error if slack settings are invalid | ||
func (s Slack) Valid() error { | ||
errString := []string{} | ||
|
||
if reflect.DeepEqual(Slack{}, s) { | ||
return nil // assume that slack was omitted | ||
} | ||
|
||
if s.WebhookURL == "" { | ||
errString = append(errString, ErrSlackNoWebHookURL.Error()) | ||
} | ||
|
||
if len(errString) == 0 { | ||
return nil | ||
} | ||
|
||
delimErr := strings.Join(errString, ", ") | ||
err := errors.New(delimErr) | ||
|
||
return errors.Wrap(err, "slack settings validation fail") | ||
} | ||
|
||
// Alert sends the alert to a slack channel | ||
func (s Slack) Alert(a *Alert) error { | ||
alerts := a.Dump() | ||
|
||
json := fmt.Sprintf("{\"text\": \"%s\"}", alerts) | ||
body := bytes.NewReader([]byte(json)) | ||
resp, err := http.Post(s.WebhookURL, "application/json", body) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
log.Println("sent alert to slack") | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package cmd | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
// these errors are for the purpose of being able to compare them later | ||
var ( | ||
ErrEmptyConfig = errors.New("The configuration is completely empty (check config file)") | ||
ErrEmailNoSMTP = errors.New("no email SMTP server") | ||
ErrEmailNoTo = errors.New("no email to addresses") | ||
ErrEmailNoFrom = errors.New("no email from addresses") | ||
ErrEmailNoPass = errors.New("no email password") | ||
ErrEmailNoPort = errors.New("no email port") | ||
ErrEmailNoSubject = errors.New("no email subject") | ||
ErrSlackNoWebHookURL = errors.New("no slack webhook url") | ||
ErrNoContainers = errors.New("There were no containers found in the configuration file") | ||
ErrExistCheckFail = errors.New("Existence check failure") | ||
ErrExistCheckRecovered = errors.New("Existence check recovered") | ||
ErrRunningCheckFail = errors.New("Running check failure") | ||
ErrRunningCheckRecovered = errors.New("Running check recovered") | ||
ErrCPUCheckFail = errors.New("CPU check failure") | ||
ErrCPUCheckRecovered = errors.New("CPU check recovered") | ||
ErrMemCheckFail = errors.New("Memory check failure") | ||
ErrMemCheckRecovered = errors.New("Memory check recovered") | ||
ErrMinPIDCheckFail = errors.New("Min PID check Failure") | ||
ErrMinPIDCheckRecovered = errors.New("Min PID check recovered") | ||
ErrMaxPIDCheckFail = errors.New("Max PID check Failure") | ||
ErrMaxPIDCheckRecovered = errors.New("Max PID check recovered") | ||
ErrUnknown = errors.New("Received an unknown error") | ||
) | ||
|
||
// ErrContainsErr returns true if the error string contains the message | ||
func ErrContainsErr(e, b error) bool { | ||
switch { | ||
case e == nil && b == nil: | ||
return true // they are both nil and essentially equal | ||
case e == nil || b == nil: | ||
return false // one of them is nil (previous case took care of both nils) | ||
case strings.Contains(e.Error(), b.Error()): | ||
return true // b is within a | ||
default: | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,14 +83,22 @@ containers: | |
maxMem: 20 | ||
minProcs: 4 | ||
# If email settings are present and active, then email alerts will be sent when an alert | ||
# is triggered. | ||
emailSettings: | ||
## ALERTERS... | ||
## If any of the below alerters are present, alerts will be sent through the proper | ||
## channels. Completely delete the relevant section to disable them. To Test if an alerter | ||
## authenticates properly, run the "testalert" command | ||
email: | ||
smtp: smtp.nonexistantserver.com | ||
password: s00p3rS33cret | ||
port: 587 | ||
from: [email protected] | ||
subject: "DOCKER_ALERTD" | ||
to: | ||
- [email protected] | ||
# You need to start a slack channel and activate an app to get a webhookURL for your channel | ||
# see https://api.slack.com/apps for more information | ||
slack: | ||
webhookURL: https://some.url/provided/by/slack/ | ||
`) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.