fix(monitor): monitor notify international and 3.6 bugfix

1.修复项目下无法查看报警记录
2.修复报警策略切换所属范围signature失败
3.国际化问题处理
This commit is contained in:
--global
2020-12-25 21:08:53 +08:00
parent ef30d23bbd
commit 4ac6d48c65
11 changed files with 136 additions and 66 deletions
@@ -6,4 +6,4 @@
资源数量:{{len .matches}}
资源名称:{{.resource_name}}
详情地址: {{.web_url}}/commonalerts
详情地址: {{.web_url}}
@@ -92,7 +92,7 @@
</table>
<table class="table" style="padding-top: 6px; padding-bottom: 10px;">
<tr>
<td style="padding-left: 20px; font-size: 14px;">若要查看详情信息,<a class="link" target="_blank" href="{{.web_url}}/commonalerts
<td style="padding-left: 20px; font-size: 14px;">若要查看详情信息,<a class="link" target="_blank" href="{{.web_url}}
">请登录平台进行查看</a></td>
</tr>
</table>
@@ -6,4 +6,4 @@ TriggerCondition: {{.description | unescaped}}
ResourceCount: {{len .matches}}
ResourceName: {{.resource_name}}
WebUrl: {{.web_url}}/commonalerts
WebUrl: {{.web_url}}
@@ -33,7 +33,7 @@
font-weight: bold;
}
.td {
width: 80px;
width: 120px;
padding-left: 20px;
height: 35px;
font-weight: 400;
@@ -92,8 +92,8 @@
</table>
<table class="table" style="padding-top: 6px; padding-bottom: 10px;">
<tr>
<td style="padding-left: 20px; font-size: 14px;">To view details<a class="link" target="_blank" href="{{.web_url}}/commonalerts
">Please log in to the platform to view</a></td>
<td style="padding-left: 20px; font-size: 14px;">To view details<a class="link" target="_blank" href="{{.web_url}}
">Please login to the platform to view</a></td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="table pb-3">
+6 -2
View File
@@ -128,7 +128,7 @@ func (c *EvalContext) GetCallbackURLPrefix() string {
return ""
}
url, _ := config.GetString("config", "default", "api_server")
return url
return url + "/alertrecord"
}
// GetNewState returns the new state from the alert rule evaluation.
@@ -207,7 +207,11 @@ func (c *EvalContext) GetNotificationTemplateConfig() monitor.NotificationTempla
func (c *EvalContext) GetEvalMatches() []monitor.EvalMatch {
ret := make([]monitor.EvalMatch, 0)
for _, c := range c.EvalMatches {
matches := c.EvalMatches
if !c.Firing {
matches = c.AlertOkEvalMatches
}
for _, c := range matches {
ret = append(ret, monitor.EvalMatch{
Condition: c.Condition,
Value: c.Value,
+14 -1
View File
@@ -170,10 +170,23 @@ func (n *notificationService) createAlertRecordWhenNotify(evalCtx *EvalContext)
}
recordCreateInput.ResType = recordCreateInput.AlertRule.ResType
createData := recordCreateInput.JSON(recordCreateInput)
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(), createData, evalCtx.UserCred)
alert, _ := models.CommonAlertManager.GetAlert(evalCtx.Rule.Id)
log.Errorf("alert:%v", jsonutils.Marshal(alert))
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(),
createData, evalCtx.UserCred)
if err != nil {
log.Errorf("create alert record err:%v", err)
}
alertData := jsonutils.Marshal(alert)
alertData.(*jsonutils.JSONDict).Set("project_id", jsonutils.NewString(alert.GetProjectId()))
db.PerformSetScope(evalCtx.Ctx, record.(*models.SAlertRecord), evalCtx.UserCred, alertData)
dbMatches, _ := record.(*models.SAlertRecord).GetEvalData()
if !evalCtx.Firing {
evalCtx.AlertOkEvalMatches = make([]*monitor.EvalMatch, len(dbMatches))
for i, _ := range dbMatches {
evalCtx.AlertOkEvalMatches[i] = &dbMatches[i]
}
}
record.PostCreate(evalCtx.Ctx, evalCtx.UserCred, evalCtx.UserCred, nil, createData)
}
+72 -8
View File
@@ -17,7 +17,9 @@ package notifiers
import (
"context"
"fmt"
"strings"
"golang.org/x/sync/errgroup"
"golang.org/x/text/language"
"yunion.io/x/jsonutils"
@@ -32,6 +34,7 @@ import (
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/monitor/alerting"
"yunion.io/x/onecloud/pkg/monitor/alerting/notifiers/templates"
@@ -39,7 +42,18 @@ import (
"yunion.io/x/onecloud/pkg/monitor/options"
)
const (
SUFFIX = "onecloudNotifier"
)
var (
i18nTable = i18n.Table{}
i18nEnTry = i18n.NewTableEntry().EN("en").CN("cn")
)
func init() {
i18nTable.Set(SUFFIX, i18nEnTry)
alerting.RegisterNotifier(&alerting.NotifierPlugin{
Type: monitor.AlertNotificationTypeOneCloud,
Factory: newOneCloudNotifier,
@@ -153,16 +167,42 @@ func GetNotifyTemplateConfigOfEN(ctx *alerting.EvalContext) monitor.Notification
// Notify sends the alert notification.
func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONObject) error {
log.Infof("Sending alert notification %s to onecloud", ctx.GetRuleTitle())
oc.Ctx = i18n.WithLangTag(oc.Ctx, language.Chinese)
langIdsMap, err := GetUserLangIdsMap(oc.Setting.UserIds)
if err != nil {
return errors.Wrapf(err, "OneCloudNotifier getIds:%s userLang err", oc.Setting.UserIds)
}
langNotifyGroup, _ := errgroup.WithContext(ctx.Ctx)
for lang, _ := range langIdsMap {
ids := langIdsMap[lang]
langTag, _ := language.Parse(lang)
langStr := i18nTable.LookupByLang(langTag, SUFFIX)
langContext := i18n.WithLangTag(context.Background(), getLangBystr(langStr))
langNotifyGroup.Go(func() error {
return oc.notifyByContextLang(langContext, ctx, ids)
})
}
return langNotifyGroup.Wait()
}
func getLangBystr(str string) language.Tag {
for lang, val := range i18nEnTry {
if val == str {
return lang
}
}
return language.English
}
func (oc *OneCloudNotifier) notifyByContextLang(ctx context.Context, evalCtx *alerting.EvalContext, uids []string) error {
var config monitor.NotificationTemplateConfig
lang := i18n.Lang(oc.Ctx)
lang := i18n.Lang(ctx)
switch lang {
case language.English:
config = GetNotifyTemplateConfigOfEN(ctx)
config = GetNotifyTemplateConfigOfEN(evalCtx)
default:
config = GetNotifyTemplateConfig(ctx)
config = GetNotifyTemplateConfig(evalCtx)
}
oc.filterMatchTagsForConfig(&config)
oc.filterMatchTagsForConfig(&config, ctx)
contentConfig := oc.buildContent(config)
@@ -179,7 +219,7 @@ func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONOb
}
msg := notify.SNotifyMessage{
Uid: oc.Setting.UserIds,
Uid: uids,
ContactType: notify.TNotifyChannel(oc.Setting.Channel),
Topic: config.Title,
Priority: notify.TNotifyPriority(config.Priority),
@@ -192,12 +232,36 @@ func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONOb
return sendImp.send()
}
func GetUserLangIdsMap(ids []string) (map[string][]string, error) {
session := auth.GetAdminSession(context.Background(), "", "")
langIdsMap := make(map[string][]string)
params := jsonutils.NewDict()
params.Set("filter", jsonutils.NewString(fmt.Sprintf("id.in(%s)", strings.Join(ids, ","))))
params.Set("details", jsonutils.JSONFalse)
params.Set("scope", jsonutils.NewString("system"))
params.Set("system", jsonutils.JSONTrue)
ret, err := modules.UsersV3.List(session, params)
if err != nil {
return nil, err
}
for i := range ret.Data {
id, _ := ret.Data[i].GetString("id")
langStr, _ := ret.Data[i].GetString("lang")
if _, ok := langIdsMap[langStr]; ok {
langIdsMap[langStr] = append(langIdsMap[langStr], id)
continue
}
langIdsMap[langStr] = []string{id}
}
return langIdsMap, nil
}
var (
companyInfo models.SCompanyInfo
)
func (oc *OneCloudNotifier) filterMatchTagsForConfig(config *monitor.NotificationTemplateConfig) {
sCompanyInfo, err := models.GetCompanyInfo(oc.Ctx)
func (oc *OneCloudNotifier) filterMatchTagsForConfig(config *monitor.NotificationTemplateConfig, ctx context.Context) {
sCompanyInfo, err := models.GetCompanyInfo(ctx)
if err != nil {
log.Errorf("GetCompanyInfo error:%#v", err)
return
+4 -40
View File
@@ -9,7 +9,6 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/timeutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis/monitor"
@@ -108,45 +107,6 @@ func (manager *SAlertRecordManager) ListItemFilter(
return q, nil
}
func (man *SAlertRecordManager) CustomizeFilterList(
ctx context.Context, q *sqlchemy.SQuery,
userCred mcclient.TokenCredential, query jsonutils.JSONObject) (
*db.CustomizeListFilters, error) {
filters := db.NewCustomizeListFilters()
input := new(monitor.AlertRecordListInput)
if err := query.Unmarshal(input); err != nil {
return nil, err
}
wrapF := func(f func(obj *SAlertRecord) (bool, error)) func(object jsonutils.JSONObject) (bool, error) {
return func(data jsonutils.JSONObject) (bool, error) {
id, err := data.GetString("id")
if err != nil {
return false, err
}
obj, err := man.GetAlertRecord(id)
if err != nil {
return false, err
}
return f(obj)
}
}
if len(input.ResType) != 0 {
mF := func(obj *SAlertRecord) (bool, error) {
rule := new(monitor.AlertRecordRule)
if err := obj.AlertRule.Unmarshal(rule); err != nil {
return false, errors.Wrapf(err, "alert %s unmarshal", obj.GetId())
}
if ok, _ := utils.InStringArray(rule.ResType, input.ResType); ok {
return true, nil
}
return false, nil
}
filters.Append(wrapF(mF))
}
return filters, nil
}
func (man *SAlertRecordManager) GetAlertRecord(id string) (*SAlertRecord, error) {
obj, err := man.FetchById(id)
if err != nil {
@@ -251,6 +211,10 @@ func (record *SAlertRecord) CustomizeCreate(
query jsonutils.JSONObject,
data jsonutils.JSONObject,
) error {
err := record.SMonitorScopedResource.CustomizeCreate(ctx, userCred, ownerId, query, data)
if err != nil {
return err
}
obj, err := db.NewModelObject(AlertRecordManager)
if err != nil {
return errors.Wrapf(err, "NewModelObject %s", AlertRecordManager.Keyword())
+11 -8
View File
@@ -7,6 +7,8 @@ import (
"strings"
"time"
"golang.org/x/text/language"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -20,6 +22,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostconsts"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -36,7 +39,7 @@ const (
CommonAlertMetadataPointStr = "point_str"
CommonAlertMetadataName = "meta_name"
COMPANY_COPYRIGHT_ONECLOUD = "北京云联万维技术有限公司"
COMPANY_COPYRIGHT_ONECLOUD = "云联"
BRAND_ONECLOUD_NAME_CN = "云联壹云"
BRAND_ONECLOUD_NAME_EN = "YunionCloud"
)
@@ -1101,13 +1104,13 @@ func GetCompanyInfo(ctx context.Context) (SCompanyInfo, error) {
return SCompanyInfo{}, err
}
if strings.Contains(info.Copyright, COMPANY_COPYRIGHT_ONECLOUD) {
//lang := i18n.Lang(ctx)
//switch lang {
//case language.English:
// info.Name = BRAND_ONECLOUD_NAME_EN
//default:
//}
info.Name = BRAND_ONECLOUD_NAME_CN
lang := i18n.Lang(ctx)
switch lang {
case language.English:
info.Name = BRAND_ONECLOUD_NAME_EN
default:
info.Name = BRAND_ONECLOUD_NAME_CN
}
}
return info, nil
}
+1
View File
@@ -32,6 +32,7 @@ func ValidateQuerySignature(input jsonutils.JSONObject) error {
return errors.Wrap(err, "get signature")
}
if signature != digestQuerySignature(data) {
return httperrors.NewBadRequestError("signature error")
}
return nil
+22 -1
View File
@@ -190,7 +190,9 @@ func (self *SUnifiedMonitorManager) AllowPerformQuery(ctx context.Context, userC
}
func (self *SUnifiedMonitorManager) PerformQuery(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if err := ValidateQuerySignature(data); err != nil {
tmp := jsonutils.DeepCopy(data)
self.handleDataPreSignature(tmp)
if err := ValidateQuerySignature(tmp); err != nil {
return nil, errors.Wrap(err, "ValidateQuerySignature")
}
inputQuery := new(monitor.MetricInputQuery)
@@ -233,6 +235,25 @@ func (self *SUnifiedMonitorManager) PerformQuery(ctx context.Context, userCred m
return jsonutils.Marshal(rtn), nil
}
func (self *SUnifiedMonitorManager) handleDataPreSignature(data jsonutils.JSONObject) {
scope, _ := data.GetString("scope")
switch scope {
case "system":
case "domain":
domain, err := data.GetString("project_domain")
if err == nil {
data.(*jsonutils.JSONDict).Remove("project_domain")
data.(*jsonutils.JSONDict).Set("domain_id", jsonutils.NewString(domain))
}
default:
project, err := data.GetString("project")
if err == nil {
data.(*jsonutils.JSONDict).Remove("project")
data.(*jsonutils.JSONDict).Set("project_id", jsonutils.NewString(project))
}
}
}
func doQuery(query monitor.MetricInputQuery) (*mq.Metrics, error) {
conditions := make([]*monitor.AlertCondition, 0)
for _, q := range query.MetricQuery {