feat: WGRplane Hybrid - Go-native with nftables + Multi-Webhook

This commit is contained in:
datadunia
2026-05-03 18:03:38 +07:00
parent 477f7830bb
commit 3eae539a56
33 changed files with 3091 additions and 4 deletions
+134
View File
@@ -0,0 +1,134 @@
package main
import (
"bytes"
"fmt"
"net/smtp"
"text/template"
"github.com/jordan-wright/email"
"gorm.io/gorm"
)
type EmailTemplate struct {
Subject string
Body string
}
var emailTemplates = map[string]EmailTemplate{
"peer_created": {
Subject: "New Peer Created: {{.Peer.IP}}",
Body: "Peer {{.Peer.IP}} was created on server {{.Server.Name}}.\nPublic Key: {{.Peer.PublicKey}}",
},
"peer_deleted": {
Subject: "Peer Deleted: {{.Peer.IP}}",
Body: "Peer {{.Peer.IP}} was deleted from server {{.Server.Name}}.",
},
"policy_changed": {
Subject: "Policy Updated for {{.Peer.IP}}",
Body: "Policy updated for peer {{.Peer.IP}} on server {{.Server.Name}}.\nChanges: {{range .Policy.Changes}}{{.}} {{end}}",
},
}
func GetSMTPSettings() (settings SMTPSettings, err error) {
err = db.First(&settings).Error
if err == gorm.ErrRecordNotFound {
return SMTPSettings{}, nil
}
return
}
func SaveSMTPSettings(settings SMTPSettings) error {
var existing SMTPSettings
if err := db.First(&existing).Error; err == gorm.ErrRecordNotFound {
return db.Create(&settings).Error
}
return db.Model(&existing).Updates(settings).Error
}
func SendEmail(to, templateName string, data map[string]interface{}) error {
settings, err := GetSMTPSettings()
if err != nil {
return err
}
if !settings.Enabled {
return fmt.Errorf("SMTP is disabled")
}
template, ok := emailTemplates[templateName]
if !ok {
return fmt.Errorf("template %s not found", templateName)
}
subject, err := renderTemplate(template.Subject, data)
if err != nil {
return err
}
body, err := renderTemplate(template.Body, data)
if err != nil {
return err
}
e := email.NewEmail()
e.From = fmt.Sprintf("%s <%s>", settings.FromName, settings.FromEmail)
e.To = []string{to}
e.Subject = subject
e.Text = []byte(body)
addr := fmt.Sprintf("%s:%d", settings.Server, settings.Port)
if settings.UseAuth {
return e.Send(addr, smtp.PlainAuth("", settings.Username, settings.Password, settings.Server))
}
return e.Send(addr, nil)
}
func TestSMTP(settings SMTPSettings) error {
e := email.NewEmail()
e.From = fmt.Sprintf("%s <%s>", settings.FromName, settings.FromEmail)
e.To = []string{settings.FromEmail}
e.Subject = "WGRplane SMTP Test"
e.Text = []byte("This is a test email from WGRplane.")
addr := fmt.Sprintf("%s:%d", settings.Server, settings.Port)
if settings.UseAuth {
return e.Send(addr, smtp.PlainAuth("", settings.Username, settings.Password, settings.Server))
}
return e.Send(addr, nil)
}
func renderTemplate(tmpl string, data map[string]interface{}) (string, error) {
t, err := template.New("email").Parse(tmpl)
if err != nil {
return "", err
}
var buf bytes.Buffer
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func NotifyPeerCreated(server *Server, peer *Peer) error {
data := map[string]interface{}{
"Server": server,
"Peer": peer,
}
return SendEmail(server.Endpoint, "peer_created", data)
}
func NotifyPeerDeleted(server *Server, peer *Peer) error {
data := map[string]interface{}{
"Server": server,
"Peer": peer,
}
return SendEmail(server.Endpoint, "peer_deleted", data)
}
func NotifyPolicyChanged(server *Server, peer *Peer, changes []string) error {
data := map[string]interface{}{
"Server": server,
"Peer": peer,
"Policy": Policy{Action: "updated", Changes: changes},
}
return SendEmail(server.Endpoint, "policy_changed", data)
}