feat: 添加oam模块

This commit is contained in:
TsMask
2025-09-25 15:20:49 +08:00
parent 1f0e0cfce2
commit 960a31645b
39 changed files with 4810 additions and 124 deletions

View File

@@ -0,0 +1,126 @@
package service
import (
"bytes"
"crypto/tls"
"fmt"
ht "html/template"
"strings"
"time"
"github.com/wneessen/go-mail"
"be.ems/src/framework/config"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/parse"
neDataModel "be.ems/src/modules/network_data/model"
)
// EmailAlarm 发告警邮件
func EmailAlarm(a neDataModel.Alarm, neIP string) error {
emailList := fmt.Sprint(config.Get("alarm.alarmEmailForward.emailList"))
if len(emailList) == 0 {
return fmt.Errorf("email list is empty")
}
// 模板
htmlBodyTemplate := `
<strong>Alarm information</strong>
<p style="text-indent: 2.5em;">Sequence: {{.AlarmSeq}}</p>
<p style="text-indent: 2.5em;">NE Name: {{.NeName}}</p>
<p style="text-indent: 4.5em;">NE IP: {{.NeIp}}</p>
<p style="text-indent: 5em;">Title: {{.AlarmTitle}}</p>
<p style="text-indent: 3.5em;">Severity: {{.OrigSeverity}}</p>
<p style="text-indent: 2.5em;">Event Time: {{.AlarmTime}}</p>
<p style="text-indent: 2em;">Alarm Status: {{.AlarmStatus}}</p>
<i>Automatic sent by OMC, please do not reply!</i>
`
htmlTpl, err := ht.New("htmltpl").Parse(htmlBodyTemplate)
if err != nil {
return fmt.Errorf("EmailAlarm Parse alarmId:%s fail %s", a.AlarmId, err.Error())
}
// 参数值
data := map[string]any{
"AlarmSeq": a.AlarmSeq,
"NeName": a.NeName,
"NeIp": neIP,
"AlarmTitle": a.AlarmTitle,
"OrigSeverity": a.OrigSeverity,
"AlarmTime": date.ParseDateToStr(a.EventTime, time.RFC3339),
"AlarmStatus": a.AlarmStatus,
}
buffer := bytes.NewBuffer(nil)
if err := htmlTpl.Execute(buffer, data); err != nil {
return fmt.Errorf("EmailAlarm Execute alarmId:%s fail %s", a.AlarmId, err.Error())
}
htmlStr := buffer.String()
// 发送邮件
err = EmailSendHTML(htmlStr, strings.Split(emailList, ","))
if err != nil {
return fmt.Errorf("EmailAlarm alarmId:%s fail %s", a.AlarmId, err.Error())
}
return err
}
// EmailSendHTML 发送HTML邮件
func EmailSendHTML(htmlStr string, toEmailArr []string) error {
// QQ 邮箱:
// SMTP 服务器地址smtp.qq.comSSL协议端口465/994 | 非SSL协议端口25
// 163 邮箱:
// SMTP 服务器地址smtp.163.com端口25
// host := "mail.agrandtech.com"
// port := 25
// userName := "smtpext@agrandtech.com"
// password := "1000smtp@omc!"
emailConf := config.Get("alarm.alarmEmailForward").(map[string]any)
enable := parse.Boolean(emailConf["enable"])
if !enable {
return fmt.Errorf("email notification not enable")
}
title := fmt.Sprint(emailConf["title"])
smtp := fmt.Sprint(emailConf["smtp"])
port := parse.Number(emailConf["port"])
user := fmt.Sprint(emailConf["user"])
password := fmt.Sprint(emailConf["password"])
message := mail.NewMsg()
// 发件人
if err := message.From(user); err != nil {
return fmt.Errorf("failed to set From address: %s", err)
}
// 收件人
hasTo := false
for _, v := range toEmailArr {
if err := message.AddTo(v); err != nil {
logger.Errorf("failed to set To address: %v %s", v, err)
continue
}
hasTo = true
}
if !hasTo {
return fmt.Errorf("failed to set To address not has")
}
// 邮件主题
message.Subject(title)
// 邮件HTML内容
message.SetBodyString(mail.TypeTextHTML, htmlStr)
// 连接到邮件SMTP服务器
client, err := mail.NewClient(smtp,
mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover),
mail.WithUsername(user),
mail.WithPort(int(port)),
mail.WithPassword(password),
mail.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
)
if err != nil {
return fmt.Errorf("failed to create mail client: %s", err)
}
// 发送
if err := client.DialAndSend(message); err != nil {
return fmt.Errorf("failed to send mail: %s", err)
}
return nil
}