mirror of
https://github.com/openziti/zrok.git
synced 2024-11-25 17:43:53 +01:00
roughed in limit warning email actions (#276)
This commit is contained in:
parent
bb61bdb664
commit
d279fbb8cb
@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/openziti/zrok/controller/env"
|
||||
"github.com/openziti/zrok/controller/limits"
|
||||
"github.com/openziti/zrok/controller/metrics"
|
||||
@ -19,7 +20,7 @@ type Config struct {
|
||||
Admin *AdminConfig
|
||||
Bridge *metrics.BridgeConfig
|
||||
Endpoint *EndpointConfig
|
||||
Email *EmailConfig
|
||||
Email *emailUi.Config
|
||||
Limits *limits.Config
|
||||
Maintenance *MaintenanceConfig
|
||||
Metrics *metrics.Config
|
||||
@ -39,14 +40,6 @@ type EndpointConfig struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string `cf:"+secret"`
|
||||
From string
|
||||
}
|
||||
|
||||
type RegistrationConfig struct {
|
||||
RegistrationUrlTemplate string
|
||||
TokenStrategy string
|
||||
|
@ -84,7 +84,7 @@ func Run(inCfg *config.Config) error {
|
||||
defer func() { ma.Stop() }()
|
||||
|
||||
if cfg.Limits != nil && cfg.Limits.Enforcing {
|
||||
limitsAgent, err = limits.NewAgent(cfg.Limits, cfg.Metrics.Influx, cfg.Ziti, str)
|
||||
limitsAgent, err = limits.NewAgent(cfg.Limits, cfg.Metrics.Influx, cfg.Ziti, cfg.Email, str)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating limits agent")
|
||||
}
|
||||
|
9
controller/emailUi/config.go
Normal file
9
controller/emailUi/config.go
Normal file
@ -0,0 +1,9 @@
|
||||
package emailUi
|
||||
|
||||
type Config struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string `cf:"+secret"`
|
||||
From string
|
||||
}
|
24
controller/emailUi/model.go
Normal file
24
controller/emailUi/model.go
Normal file
@ -0,0 +1,24 @@
|
||||
package emailUi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/pkg/errors"
|
||||
"html/template"
|
||||
)
|
||||
|
||||
type WarningEmail struct {
|
||||
EmailAddress string
|
||||
Detail string
|
||||
}
|
||||
|
||||
func (we WarningEmail) MergeTemplate(filename string) (string, error) {
|
||||
t, err := template.ParseFS(FS, filename)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "error parsing warning email template '%v'", filename)
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
if err := t.Execute(buf, we); err != nil {
|
||||
return "", errors.Wrapf(err, "error executing warning email template '%v'", filename)
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
@ -3,20 +3,28 @@ package limits
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/openziti/edge/rest_management_api_client"
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/openziti/zrok/controller/store"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type accountWarningAction struct {
|
||||
str *store.Store
|
||||
edge *rest_management_api_client.ZitiEdgeManagement
|
||||
cfg *emailUi.Config
|
||||
}
|
||||
|
||||
func newAccountWarningAction(str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *accountWarningAction {
|
||||
return &accountWarningAction{str, edge}
|
||||
func newAccountWarningAction(cfg *emailUi.Config, str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *accountWarningAction {
|
||||
return &accountWarningAction{str, edge, cfg}
|
||||
}
|
||||
|
||||
func (a *accountWarningAction) HandleAccount(acct *store.Account, rxBytes, txBytes int64, limit *BandwidthPerPeriod, trx *sqlx.Tx) error {
|
||||
logrus.Infof("warning '%v'", acct.Email)
|
||||
|
||||
if err := sendLimitWarningEmail(a.cfg, acct.Email, limit, rxBytes, txBytes); err != nil {
|
||||
return errors.Wrapf(err, "error sending limit warning email to '%v'", acct.Email)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -3,6 +3,7 @@ package limits
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/openziti/zrok/controller/metrics"
|
||||
"github.com/openziti/zrok/controller/store"
|
||||
"github.com/openziti/zrok/controller/zrokEdgeSdk"
|
||||
@ -31,7 +32,7 @@ type Agent struct {
|
||||
join chan struct{}
|
||||
}
|
||||
|
||||
func NewAgent(cfg *Config, ifxCfg *metrics.InfluxConfig, zCfg *zrokEdgeSdk.Config, str *store.Store) (*Agent, error) {
|
||||
func NewAgent(cfg *Config, ifxCfg *metrics.InfluxConfig, zCfg *zrokEdgeSdk.Config, emailCfg *emailUi.Config, str *store.Store) (*Agent, error) {
|
||||
edge, err := zrokEdgeSdk.Client(zCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -42,13 +43,13 @@ func NewAgent(cfg *Config, ifxCfg *metrics.InfluxConfig, zCfg *zrokEdgeSdk.Confi
|
||||
zCfg: zCfg,
|
||||
str: str,
|
||||
queue: make(chan *metrics.Usage, 1024),
|
||||
acctWarningActions: []AccountAction{newAccountWarningAction(str, edge)},
|
||||
acctWarningActions: []AccountAction{newAccountWarningAction(emailCfg, str, edge)},
|
||||
acctLimitActions: []AccountAction{newAccountLimitAction(str, edge)},
|
||||
acctRelaxActions: []AccountAction{newAccountRelaxAction(str, edge)},
|
||||
envWarningActions: []EnvironmentAction{newEnvironmentWarningAction(str, edge)},
|
||||
envWarningActions: []EnvironmentAction{newEnvironmentWarningAction(emailCfg, str, edge)},
|
||||
envLimitActions: []EnvironmentAction{newEnvironmentLimitAction(str, edge)},
|
||||
envRelaxActions: []EnvironmentAction{newEnvironmentRelaxAction(str, edge)},
|
||||
shrWarningActions: []ShareAction{newShareWarningAction(str, edge)},
|
||||
shrWarningActions: []ShareAction{newShareWarningAction(emailCfg, str, edge)},
|
||||
shrLimitActions: []ShareAction{newShareLimitAction(str, edge)},
|
||||
shrRelaxActions: []ShareAction{newShareRelaxAction(str, edge)},
|
||||
close: make(chan struct{}),
|
||||
@ -550,7 +551,7 @@ func (a *Agent) checkShareLimit(shrToken string) (enforce, warning bool, rxBytes
|
||||
|
||||
enforce, warning = a.checkLimit(limit, rx, tx)
|
||||
if enforce || warning {
|
||||
logrus.Debugf("'%v': %v", shrToken, a.describeLimit(limit, rx, tx))
|
||||
logrus.Debugf("'%v': %v", shrToken, describeLimit(limit, rx, tx))
|
||||
}
|
||||
|
||||
return enforce, warning, rx, tx, nil
|
||||
@ -580,7 +581,7 @@ func (a *Agent) checkLimit(cfg *BandwidthPerPeriod, rx, tx int64) (enforce, warn
|
||||
return false, false
|
||||
}
|
||||
|
||||
func (a *Agent) describeLimit(cfg *BandwidthPerPeriod, rx, tx int64) string {
|
||||
func describeLimit(cfg *BandwidthPerPeriod, rx, tx int64) string {
|
||||
out := ""
|
||||
|
||||
if cfg.Limit.Rx != Unlimited && rx > cfg.Limit.Rx {
|
||||
|
58
controller/limits/email.go
Normal file
58
controller/limits/email.go
Normal file
@ -0,0 +1,58 @@
|
||||
package limits
|
||||
|
||||
import (
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/wneessen/go-mail"
|
||||
)
|
||||
|
||||
func sendLimitWarningEmail(cfg *emailUi.Config, emailTo string, limit *BandwidthPerPeriod, rxBytes, txBytes int64) error {
|
||||
emailData := &emailUi.WarningEmail{
|
||||
EmailAddress: emailTo,
|
||||
Detail: describeLimit(limit, rxBytes, txBytes),
|
||||
}
|
||||
|
||||
plainBody, err := emailData.MergeTemplate("limitWarning.gotext")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
htmlBody, err := emailData.MergeTemplate("resetPassword.gohtml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := mail.NewMsg()
|
||||
if err := msg.From(cfg.From); err != nil {
|
||||
return errors.Wrap(err, "failed to set from address in limit warning email")
|
||||
}
|
||||
if err := msg.To(emailTo); err != nil {
|
||||
return errors.Wrap(err, "failed to set to address in limit warning email")
|
||||
}
|
||||
|
||||
msg.Subject("Limit Warning Notification")
|
||||
msg.SetDate()
|
||||
msg.SetMessageID()
|
||||
msg.SetBulk()
|
||||
msg.SetImportance(mail.ImportanceHigh)
|
||||
msg.SetBodyString(mail.TypeTextPlain, plainBody)
|
||||
msg.SetBodyString(mail.TypeTextHTML, htmlBody)
|
||||
|
||||
client, err := mail.NewClient(cfg.Host,
|
||||
mail.WithPort(cfg.Port),
|
||||
mail.WithSMTPAuth(mail.SMTPAuthPlain),
|
||||
mail.WithUsername(cfg.Username),
|
||||
mail.WithPassword(cfg.Password),
|
||||
mail.WithTLSPolicy(mail.TLSMandatory),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating limit warning email client")
|
||||
}
|
||||
if err := client.DialAndSend(msg); err != nil {
|
||||
return errors.Wrap(err, "error sending limit warning email")
|
||||
}
|
||||
|
||||
logrus.Infof("limit warning email sent to '%v'", emailTo)
|
||||
return nil
|
||||
}
|
@ -3,20 +3,35 @@ package limits
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/openziti/edge/rest_management_api_client"
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/openziti/zrok/controller/store"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type environmentWarningAction struct {
|
||||
str *store.Store
|
||||
edge *rest_management_api_client.ZitiEdgeManagement
|
||||
cfg *emailUi.Config
|
||||
}
|
||||
|
||||
func newEnvironmentWarningAction(str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *environmentWarningAction {
|
||||
return &environmentWarningAction{str, edge}
|
||||
func newEnvironmentWarningAction(cfg *emailUi.Config, str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *environmentWarningAction {
|
||||
return &environmentWarningAction{str, edge, cfg}
|
||||
}
|
||||
|
||||
func (a *environmentWarningAction) HandleEnvironment(e *store.Environment, rxBytes, txBytes int64, limit *BandwidthPerPeriod, trx *sqlx.Tx) error {
|
||||
logrus.Infof("warning '%v'", e.ZId)
|
||||
func (a *environmentWarningAction) HandleEnvironment(env *store.Environment, rxBytes, txBytes int64, limit *BandwidthPerPeriod, trx *sqlx.Tx) error {
|
||||
logrus.Infof("warning '%v'", env.ZId)
|
||||
|
||||
if env.AccountId != nil {
|
||||
acct, err := a.str.GetAccount(*env.AccountId, trx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sendLimitWarningEmail(a.cfg, acct.Email, limit, rxBytes, txBytes); err != nil {
|
||||
return errors.Wrapf(err, "error sending limit warning email to '%v'", acct.Email)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -3,20 +3,38 @@ package limits
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/openziti/edge/rest_management_api_client"
|
||||
"github.com/openziti/zrok/controller/emailUi"
|
||||
"github.com/openziti/zrok/controller/store"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type shareWarningAction struct {
|
||||
str *store.Store
|
||||
edge *rest_management_api_client.ZitiEdgeManagement
|
||||
cfg *emailUi.Config
|
||||
}
|
||||
|
||||
func newShareWarningAction(str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *shareWarningAction {
|
||||
return &shareWarningAction{str, edge}
|
||||
func newShareWarningAction(cfg *emailUi.Config, str *store.Store, edge *rest_management_api_client.ZitiEdgeManagement) *shareWarningAction {
|
||||
return &shareWarningAction{str, edge, cfg}
|
||||
}
|
||||
|
||||
func (a *shareWarningAction) HandleShare(s *store.Share, rxBytes, txBytes int64, limit *BandwidthPerPeriod, trx *sqlx.Tx) error {
|
||||
logrus.Infof("warning '%v'", s.Token)
|
||||
func (a *shareWarningAction) HandleShare(shr *store.Share, rxBytes, txBytes int64, limit *BandwidthPerPeriod, trx *sqlx.Tx) error {
|
||||
logrus.Infof("warning '%v'", shr.Token)
|
||||
|
||||
env, err := a.str.GetEnvironment(shr.EnvironmentId, trx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acct, err := a.str.GetAccount(env.Id, trx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sendLimitWarningEmail(a.cfg, acct.Email, limit, rxBytes, txBytes); err != nil {
|
||||
return errors.Wrapf(err, "error sending limit warning email to '%v'", acct.Email)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user