diff --git a/pkg/notify/models/config.go b/pkg/notify/models/config.go index 5316b365bd..23c603dc2d 100644 --- a/pkg/notify/models/config.go +++ b/pkg/notify/models/config.go @@ -27,7 +27,6 @@ import ( "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" - "yunion.io/x/onecloud/pkg/apis/notify" api "yunion.io/x/onecloud/pkg/apis/notify" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -111,7 +110,8 @@ func (c *SConfig) PostCreate(ctx context.Context, userCred mcclient.TokenCredent if err != nil { log.Errorf("unable to StartRepullSubcontactTask: %v", err) } - ConfigMap[fmt.Sprintf("%s-%s", c.Type, c.DomainId)] = *c + driver := GetDriver(c.Type) + driver.RegisterConfig(*c) } func (c *SConfig) GetNotifyConfig() api.NotifyConfig { @@ -335,6 +335,7 @@ func (cm *SConfigManager) PerformValidate(ctx context.Context, userCred mcclient driver := GetDriver(input.Type) message, err := driver.ValidateConfig(api.NotifyConfig{ SNotifyConfigContent: *input.Content, + DomainId: userCred.GetDomainId(), }) if err != nil { return output, errors.Wrapf(err, message) @@ -353,15 +354,9 @@ func (confManager *SConfigManager) InitializeData() error { } ConfigMap = make(map[string]SConfig) for _, config := range res { - ConfigMap[fmt.Sprintf("%s-%s", config.Type, config.DomainId)] = config - if config.Type == api.EMAIL { - ConfigMap[config.Type] = config - } driver := GetDriver(config.Type) - if config.Type == notify.EMAIL || config.Type == notify.MOBILE { - continue - } - err := driver.GetAccessToken(fmt.Sprintf("%s-%s", config.Type, config.DomainId)) + driver.RegisterConfig(config) + err := driver.GetAccessToken(config.DomainId) if err != nil { session := auth.GetAdminSession(context.Background(), options.Options.Region) logclient.AddSimpleActionLog(&config, logclient.ACT_INIT_NOTIFY_CONFIGMAP, err, session.GetToken(), false) diff --git a/pkg/notify/models/notification.go b/pkg/notify/models/notification.go index 73412808ff..1885ce02f7 100644 --- a/pkg/notify/models/notification.go +++ b/pkg/notify/models/notification.go @@ -146,7 +146,11 @@ func (nm *SNotificationManager) ValidateCreateData(ctx context.Context, userCred if len(topicRunes) < 10 { length = len(topicRunes) } - input.GenerateName = fmt.Sprintf("%s-%s-%s", string(topicRunes[:length]), input.ContactType, nowStr) + name := fmt.Sprintf("%s-%s-%s", string(topicRunes[:length]), input.ContactType, nowStr) + input.Name, err = db.GenerateName(ctx, nm, ownerId, name) + if err != nil { + return input, errors.Wrapf(err, "unable to generate name for %s", name) + } return input, nil } @@ -463,7 +467,6 @@ func (nm *SNotificationManager) FetchCustomizeColumns( fields stringutils2.SSortedStrings, isList bool, ) []api.NotificationDetails { - log.Infoln("this is objs:", objs) rows := make([]api.NotificationDetails, len(objs)) resRows := nm.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) @@ -532,7 +535,7 @@ func (n *SNotification) getMoreDetails(ctx context.Context, userCred mcclient.To return out, err } // p, err := n.TemplateStore().FillWithTemplate(ctx, lang, nn) - p, _ := LocalTemplateManager.FillWithTemplate(ctx, lang, nn) + p, _ := n.FillWithTemplate(ctx, lang, nn) if err != nil { return out, err } diff --git a/pkg/notify/models/plugindriver.go b/pkg/notify/models/plugindriver.go index 545b5994c2..000a364bd8 100644 --- a/pkg/notify/models/plugindriver.go +++ b/pkg/notify/models/plugindriver.go @@ -28,7 +28,8 @@ type ISenderDriver interface { IsSystemConfigContactType() bool IsValid() bool IsPullType() bool - GetAccessToken(key string) error + GetAccessToken(domainId string) error + RegisterConfig(config SConfig) } var ( diff --git a/pkg/notify/models/receiver.go b/pkg/notify/models/receiver.go index 4ca169e180..973fa720da 100644 --- a/pkg/notify/models/receiver.go +++ b/pkg/notify/models/receiver.go @@ -675,15 +675,12 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden } } mobile := input.InternationalMobile.String() - log.Infof("this is r.Mobile:%s,this is mobile:%s", r.Mobile, mobile) if len(mobile) != 0 && mobile != r.Mobile { - log.Infoln("this is update v.VerifiedMobile") db.Update(r, func() error { r.VerifiedMobile = tristate.False return nil }) subs, _ := r.GetSubContacts() - log.Infoln("this is subs:", jsonutils.Marshal(subs)) for i := range subs { if subs[i].ParentContactType == api.MOBILE { db.Update(&subs[i], func() error { @@ -694,6 +691,7 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden } } } + // 管理后台修改联系人,如果修改或者启用手机号和邮箱,无需进行校验 if input.ForceVerified { allowScope, _ := policy.PolicyManager.AllowScope(userCred, api.SERVICE_TYPE, ReceiverManager.KeywordPlural(), policy.PolicyActionCreate) @@ -717,6 +715,11 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden }) } } + r.Mobile = mobile + err := ReceiverManager.TableSpec().InsertOrUpdate(ctx, r) + if err != nil { + log.Errorf("InsertOrUpdate: %v", err) + } } func (r *SReceiver) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { diff --git a/pkg/notify/models/template.go b/pkg/notify/models/template.go index a7b0894512..b2927d7af7 100644 --- a/pkg/notify/models/template.go +++ b/pkg/notify/models/template.go @@ -222,6 +222,9 @@ func (tm *STemplateManager) FillWithTemplate(ctx context.Context, lang string, n } params.Topic = no.Topic templates := make([]STemplate, 0, 3) + // if strings.Contains(no.Topic, "-cn") || strings.Contains(no.Topic, "-en") { + // no.Topic = no.Topic[:len(no.Topic)-3] + // } var q *sqlchemy.SQuery q = tm.Query().Equals("topic", strings.ToUpper(no.Topic)).Equals("lang", lang).In("contact_type", []string{CONTACTTYPE_ALL, no.ContactType}) err = db.FetchModelObjects(tm, q, &templates) diff --git a/pkg/notify/sender/dingtalk.go b/pkg/notify/sender/dingtalk.go index 9ae67141d9..f6cb6ef8e4 100644 --- a/pkg/notify/sender/dingtalk.go +++ b/pkg/notify/sender/dingtalk.go @@ -93,7 +93,6 @@ func (dingSender *SDingTalkSender) ValidateConfig(config api.NotifyConfig) (stri } return "", err } - models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, config.DomainId)].Content.AppKey, models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, config.DomainId)].Content.AppSecret = config.AppKey, config.AppSecret return "", nil } @@ -134,7 +133,12 @@ func (dingSender *SDingTalkSender) IsSystemConfigContactType() bool { return true } -func (dingSender *SDingTalkSender) GetAccessToken(key string) error { +func (dingSender *SDingTalkSender) RegisterConfig(config models.SConfig) { + models.ConfigMap[fmt.Sprintf("%s-%s", config.Type, config.DomainId)] = config +} + +func (dingSender *SDingTalkSender) GetAccessToken(domainId string) error { + key := fmt.Sprintf("%s-%s", api.DINGTALK, domainId) appKey, appSecret := models.ConfigMap[key].Content.AppKey, models.ConfigMap[key].Content.AppSecret token, err := dingSender.getAccessToken(appKey, appSecret) if err != nil { diff --git a/pkg/notify/sender/dingtalk_robot.go b/pkg/notify/sender/dingtalk_robot.go index f3e0da4830..21ff1d60d0 100644 --- a/pkg/notify/sender/dingtalk_robot.go +++ b/pkg/notify/sender/dingtalk_robot.go @@ -103,6 +103,9 @@ func (dingRobotSender *SDingTalkRobotSender) GetAccessToken(key string) error { return nil } +func (dingRobotSender *SDingTalkRobotSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SDingTalkRobotSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/email.go b/pkg/notify/sender/email.go index 97aaba0362..789c0242bd 100644 --- a/pkg/notify/sender/email.go +++ b/pkg/notify/sender/email.go @@ -206,6 +206,10 @@ func (emailSender *SEmailSender) sendMessageWithToken(uri string, method httputi return sendRequest(uri, httputils.POST, nil, params, jsonutils.Marshal(body)) } +func (emailSender *SEmailSender) RegisterConfig(config models.SConfig) { + models.ConfigMap[config.Type] = config +} + func init() { models.Register(&SEmailSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/feishu.go b/pkg/notify/sender/feishu.go index 5998b8bdd3..c5cca408f1 100644 --- a/pkg/notify/sender/feishu.go +++ b/pkg/notify/sender/feishu.go @@ -143,8 +143,13 @@ func (feishuSender *SFeishuSender) IsSystemConfigContactType() bool { return true } +func (feishuSender *SFeishuSender) RegisterConfig(config models.SConfig) { + models.ConfigMap[fmt.Sprintf("%s-%s", config.Type, config.DomainId)] = config +} + // 获取token -func (feishuSender *SFeishuSender) GetAccessToken(key string) error { +func (feishuSender *SFeishuSender) GetAccessToken(domainId string) error { + key := fmt.Sprintf("%s-%s", api.FEISHU, domainId) appId, appSecret := models.ConfigMap[key].Content.AppId, models.ConfigMap[key].Content.AppSecret resp, err := feishuSender.getAccessToken(appId, appSecret) models.ConfigMap[key].Content.AccessToken = resp.TenantAccessToken diff --git a/pkg/notify/sender/feishu_robot.go b/pkg/notify/sender/feishu_robot.go index 3617932532..e2446ccacc 100644 --- a/pkg/notify/sender/feishu_robot.go +++ b/pkg/notify/sender/feishu_robot.go @@ -105,6 +105,9 @@ func (feishuRobotSender *SFeishuRobotSender) GetAccessToken(key string) error { return nil } +func (feishuRobotSender *SFeishuRobotSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SFeishuRobotSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/mobile.go b/pkg/notify/sender/mobile.go index 0b58d18cc4..0b82fcbc03 100644 --- a/pkg/notify/sender/mobile.go +++ b/pkg/notify/sender/mobile.go @@ -15,6 +15,8 @@ package sender import ( + "strings" + "yunion.io/x/cloudmux/pkg/cloudprovider" "yunion.io/x/pkg/errors" @@ -33,8 +35,10 @@ func (smsSender *SMobileSender) GetSenderType() string { func (smsSender *SMobileSender) Send(args api.SendParams) error { smsSendParams := api.SSMSSendParams{ - From: "", - To: args.Receivers.Contact, + TemplateId: strings.Split(args.RemoteTemplate, "/")[1], + TemplateParas: args.Message, + To: args.Receivers.Contact, + From: strings.Split(args.RemoteTemplate, "/")[0], } smsdriver := models.GetSMSDriver(models.ConfigMap[api.MOBILE].Content.SmsDriver) return smsdriver.Send(smsSendParams, false, &api.NotifyConfig{ @@ -46,7 +50,10 @@ func (smsSender *SMobileSender) Send(args api.SendParams) error { func (smsSender *SMobileSender) ValidateConfig(config api.NotifyConfig) (string, error) { driver := models.GetSMSDriver(config.SmsDriver) - return "", driver.Verify(&config) + if driver == nil { + return "", errors.Wrap(errors.ErrNotFound, "driver disabled") + } + return "", nil } func (smsSender *SMobileSender) UpdateConfig(config api.NotifyConfig) error { @@ -106,6 +113,10 @@ func (smsSender *SMobileSender) GetAccessToken(key string) error { return nil } +func (smsSender *SMobileSender) RegisterConfig(config models.SConfig) { + models.ConfigMap[config.Type] = config +} + func init() { models.Register(&SMobileSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/smsdriver/huawei.go b/pkg/notify/sender/smsdriver/huawei.go index dd67cbe973..4493921c8d 100644 --- a/pkg/notify/sender/smsdriver/huawei.go +++ b/pkg/notify/sender/smsdriver/huawei.go @@ -78,10 +78,14 @@ func (d *SHuaweiSMSDriver) sendSms(args api.SSMSSendParams) error { params.Set("templateId", args.TemplateId) params.Set("templateParas", args.TemplateParas) params.Set("signature", args.Signature) - _, err := sendRequest(uri, httputils.POST, header, params, nil) + resp, err := sendRequest(uri, httputils.POST, header, params, nil) if err != nil { return errors.Wrap(err, "huawei sendRequest") } + code, _ := resp.GetString("code") + if code != "000000" { + return errors.Wrap(errors.ErrInvalidFormat, resp.PrettyString()) + } return nil } diff --git a/pkg/notify/sender/webconsole.go b/pkg/notify/sender/webconsole.go index 2a6e065064..d564b32a1b 100644 --- a/pkg/notify/sender/webconsole.go +++ b/pkg/notify/sender/webconsole.go @@ -76,6 +76,9 @@ func (websender *SWebconsoleSender) GetAccessToken(key string) error { return nil } +func (websender *SWebconsoleSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SWebconsoleSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/webhook.go b/pkg/notify/sender/webhook.go index be40a247aa..c28939a343 100644 --- a/pkg/notify/sender/webhook.go +++ b/pkg/notify/sender/webhook.go @@ -96,6 +96,9 @@ func (websender *SWebhookSender) GetAccessToken(key string) error { return nil } +func (websender *SWebhookSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SWebhookSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/websocket.go b/pkg/notify/sender/websocket.go index db61170030..5b3bd688a4 100644 --- a/pkg/notify/sender/websocket.go +++ b/pkg/notify/sender/websocket.go @@ -113,6 +113,9 @@ func (websocket *SWebsocketSender) ValidateConfig(config api.NotifyConfig) (stri return "", cloudprovider.ErrNotImplemented } +func (websocket *SWebsocketSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SWebsocketSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/sender/workwx.go b/pkg/notify/sender/workwx.go index 84d98207f5..72b0b6b50e 100644 --- a/pkg/notify/sender/workwx.go +++ b/pkg/notify/sender/workwx.go @@ -103,7 +103,12 @@ func (workwxSender *SWorkwxSender) IsSystemConfigContactType() bool { return true } -func (workwxSender *SWorkwxSender) GetAccessToken(key string) error { +func (workwxSender *SWorkwxSender) RegisterConfig(config models.SConfig) { + models.ConfigMap[fmt.Sprintf("%s-%s", config.Type, config.DomainId)] = config +} + +func (workwxSender *SWorkwxSender) GetAccessToken(domainId string) error { + key := fmt.Sprintf("%s-%s", api.WORKWX, domainId) corpId, secret := models.ConfigMap[key].Content.CorpId, models.ConfigMap[key].Content.Secret token, err := workwxSender.getAccessToken(corpId, secret) if err != nil { diff --git a/pkg/notify/sender/workwx_robot.go b/pkg/notify/sender/workwx_robot.go index a84fd8a42b..d269b2def6 100644 --- a/pkg/notify/sender/workwx_robot.go +++ b/pkg/notify/sender/workwx_robot.go @@ -88,6 +88,9 @@ func (workwxRobotSender *SWorkwxRobotSender) GetAccessToken(key string) error { return nil } +func (workwxRobotSender *SWorkwxRobotSender) RegisterConfig(config models.SConfig) { +} + func init() { models.Register(&SWorkwxRobotSender{ config: map[string]api.SNotifyConfigContent{}, diff --git a/pkg/notify/tasks/notifications_send_task.go b/pkg/notify/tasks/notifications_send_task.go index 3756e2b8e3..5ab54a36ec 100644 --- a/pkg/notify/tasks/notifications_send_task.go +++ b/pkg/notify/tasks/notifications_send_task.go @@ -75,8 +75,10 @@ func (self *NotificationSendTask) OnInit(ctx context.Context, obj db.IStandalone } event, err := models.EventManager.GetEvent(notification.EventId) if err != nil { - self.taskFailed(ctx, notification, errors.Wrapf(err, "GetEvent").Error(), true) - return + if !strings.Contains(err.Error(), "no rows in result set") { + self.taskFailed(ctx, notification, errors.Wrapf(err, "GetEvent").Error(), true) + return + } } notification.SetStatus(self.UserCred, apis.NOTIFICATION_STATUS_SENDING, "") @@ -205,12 +207,16 @@ func (self *NotificationSendTask) OnInit(ctx context.Context, obj db.IStandalone logclient.AddSimpleActionLog(notification, logclient.ACT_SEND_NOTIFICATION, errors.Wrapf(err, "FillWithTemplate(%s)", lang), self.GetUserCred(), false) continue } - p.Event = event.Event - switch lang { - case apis.TEMPLATE_LANG_CN: - p.Message += "\n来自 " + options.Options.ApiServer - case apis.TEMPLATE_LANG_EN: - p.Message += "\nfrom " + options.Options.ApiServer + if event != nil { + p.Event = event.Event + } + if notification.ContactType != apis.MOBILE { + switch lang { + case apis.TEMPLATE_LANG_CN: + p.Message += "\n来自 " + options.Options.ApiServer + case apis.TEMPLATE_LANG_EN: + p.Message += "\nfrom " + options.Options.ApiServer + } } p.DomainId = self.UserCred.GetDomainId() @@ -281,7 +287,9 @@ func (notificationSendTask *NotificationSendTask) batchSend(ctx context.Context, } } if notification.ContactType == apis.MOBILE { - params.Receivers.Contact = receiver.Mobile + mobileArr := strings.Split(receiver.Mobile, " ") + mobile := strings.Join(mobileArr, "") + params.Receivers.Contact = mobile } err = driver.Send(params) if err != nil { diff --git a/pkg/notify/tasks/verification_send_task.go b/pkg/notify/tasks/verification_send_task.go index 5437d880fa..e309c10b50 100644 --- a/pkg/notify/tasks/verification_send_task.go +++ b/pkg/notify/tasks/verification_send_task.go @@ -17,6 +17,7 @@ package tasks import ( "context" "fmt" + "strings" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -55,6 +56,8 @@ func (self *VerificationSendTask) OnInit(ctx context.Context, obj db.IStandalone return } + emailMsg := &api.SEmailMessage{} + notifyReceiver := api.SNotifyReceiver{} // build message var message string switch contactType { @@ -74,8 +77,19 @@ func (self *VerificationSendTask) OnInit(ctx context.Context, obj db.IStandalone SCompanyInfo: info, } message = jsonutils.Marshal(data).String() + notifyReceiver = api.SNotifyReceiver{ + Contact: receiver.Email, + DomainId: receiver.DomainId, + } + emailMsg.To = append(emailMsg.To, receiver.Email) case api.MOBILE: message = fmt.Sprintf("[\"%s\"]", verification.Token) + mobileArr := strings.Split(receiver.Mobile, " ") + mobile := strings.Join(mobileArr, "") + notifyReceiver = api.SNotifyReceiver{ + Contact: mobile, + DomainId: receiver.DomainId, + } default: // no way } @@ -92,10 +106,8 @@ func (self *VerificationSendTask) OnInit(ctx context.Context, obj db.IStandalone self.taskFailed(ctx, receiver, err.Error()) return } - param.Receivers = api.SNotifyReceiver{ - Contact: receiver.Mobile, - DomainId: receiver.DomainId, - } + param.Receivers = notifyReceiver + param.EmailMsg = emailMsg driver := models.GetDriver(contactType) err = driver.Send(param) // err = models.NotifyService.Send(ctx, contactType, param)