From ab42fcaade3ff7e651208e88e6a0dcfded0e8ce9 Mon Sep 17 00:00:00 2001 From: mhf Date: Tue, 28 Feb 2023 14:31:53 +0800 Subject: [PATCH] fix(notify): bugFix --- pkg/apis/notify/config.go | 1 + pkg/notify/models/config.go | 16 +- pkg/notify/models/plugindriver.go | 2 +- pkg/notify/sender/dingtalk.go | 22 +-- pkg/notify/sender/dingtalk_robot.go | 2 +- pkg/notify/sender/email.go | 20 +-- pkg/notify/sender/feishu.go | 23 +-- pkg/notify/sender/feishu_robot.go | 2 +- pkg/notify/sender/mobile.go | 2 +- pkg/notify/sender/webconsole.go | 37 +---- pkg/notify/sender/webhook.go | 2 +- pkg/notify/sender/websocket.go | 2 +- pkg/notify/sender/workwx.go | 18 +- pkg/notify/sender/workwx_robot.go | 2 +- pkg/notify/tasks/notifications_send_task.go | 1 + pkg/notify/tasks/subcontact_pull_task.go | 175 ++++++++++++++------ 16 files changed, 176 insertions(+), 151 deletions(-) diff --git a/pkg/apis/notify/config.go b/pkg/apis/notify/config.go index 3a93b1297e..bdcbd4a64d 100644 --- a/pkg/apis/notify/config.go +++ b/pkg/apis/notify/config.go @@ -149,6 +149,7 @@ type SendParams struct { Event string Receivers SNotifyReceiver EmailMsg *SEmailMessage + DomainId string } type SSMSSendParams struct { diff --git a/pkg/notify/models/config.go b/pkg/notify/models/config.go index 714f010d04..5316b365bd 100644 --- a/pkg/notify/models/config.go +++ b/pkg/notify/models/config.go @@ -17,6 +17,7 @@ package models import ( "context" "database/sql" + "fmt" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -110,7 +111,7 @@ func (c *SConfig) PostCreate(ctx context.Context, userCred mcclient.TokenCredent if err != nil { log.Errorf("unable to StartRepullSubcontactTask: %v", err) } - ConfigMap[c.Type] = *c + ConfigMap[fmt.Sprintf("%s-%s", c.Type, c.DomainId)] = *c } func (c *SConfig) GetNotifyConfig() api.NotifyConfig { @@ -151,7 +152,7 @@ func (c *SConfig) ValidateUpdateData(ctx context.Context, userCred mcclient.Toke func (c *SConfig) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { c.SStandaloneResourceBase.PostUpdate(ctx, userCred, query, data) config := c.GetNotifyConfig() - ConfigMap[c.Type] = SConfig{ + ConfigMap[fmt.Sprintf("%s-%s", c.Type, c.DomainId)] = SConfig{ Content: &config.SNotifyConfigContent, } err := c.StartRepullSubcontactTask(ctx, userCred, false) @@ -162,7 +163,7 @@ func (c *SConfig) PostUpdate(ctx context.Context, userCred mcclient.TokenCredent func (c *SConfig) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) { c.SStandaloneResourceBase.PreDelete(ctx, userCred) - delete(ConfigMap, c.Type) + delete(ConfigMap, fmt.Sprintf("%s-%s", c.Type, c.DomainId)) } func (c *SConfig) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { @@ -178,7 +179,7 @@ func (c *SConfig) Delete(ctx context.Context, userCred mcclient.TokenCredential) } func (c *SConfig) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error { - delete(ConfigMap, c.Type) + delete(ConfigMap, fmt.Sprintf("%s-%s", c.Type, c.DomainId)) return c.SDomainLevelResourceBase.Delete(ctx, userCred) } @@ -352,12 +353,15 @@ func (confManager *SConfigManager) InitializeData() error { } ConfigMap = make(map[string]SConfig) for _, config := range res { - ConfigMap[config.Type] = config + 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() + err := driver.GetAccessToken(fmt.Sprintf("%s-%s", config.Type, 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/plugindriver.go b/pkg/notify/models/plugindriver.go index 36f5c476c1..545b5994c2 100644 --- a/pkg/notify/models/plugindriver.go +++ b/pkg/notify/models/plugindriver.go @@ -28,7 +28,7 @@ type ISenderDriver interface { IsSystemConfigContactType() bool IsValid() bool IsPullType() bool - GetAccessToken() error + GetAccessToken(key string) error } var ( diff --git a/pkg/notify/sender/dingtalk.go b/pkg/notify/sender/dingtalk.go index 9b1f0f3dad..9ae67141d9 100644 --- a/pkg/notify/sender/dingtalk.go +++ b/pkg/notify/sender/dingtalk.go @@ -38,7 +38,7 @@ func (dingSender *SDingTalkSender) GetSenderType() string { func (dingSender *SDingTalkSender) Send(args api.SendParams) error { body := map[string]interface{}{ - "agent_id": models.ConfigMap[api.DINGTALK].Content.AgentId, + "agent_id": models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AgentId, "msg": map[string]interface{}{ "msgtype": "markdown", "markdown": map[string]interface{}{ @@ -49,7 +49,7 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error { "userid_list": args.Receivers.Contact, } params := url.Values{} - params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken) + params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AccessToken) req, err := sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body)) if err != nil { subCode, _ := req.GetString("sub_code") @@ -57,13 +57,13 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error { // token失效或不合法 case "40014": // 尝试重新获取token - err = dingSender.GetAccessToken() + err = dingSender.GetAccessToken(fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)) if err != nil { return errors.Wrap(err, "reset token") } // 重新发送通知 params = url.Values{} - params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken) + params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AccessToken) req, err = sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body)) if err != nil { return errors.Wrap(err, "dingtalk resend message") @@ -77,7 +77,7 @@ func (dingSender *SDingTalkSender) Send(args api.SendParams) error { // 获取消息通知发送结果 task_id, _ := req.GetString("task_id") body = map[string]interface{}{ - "agent_id": models.ConfigMap[api.DINGTALK].Content.AgentId, + "agent_id": models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, args.DomainId)].Content.AgentId, "task_id": task_id, } _, err = sendRequest(ApiDingtalkSendMessage, httputils.POST, nil, params, jsonutils.Marshal(body)) @@ -93,12 +93,12 @@ func (dingSender *SDingTalkSender) ValidateConfig(config api.NotifyConfig) (stri } return "", err } - models.ConfigMap[api.DINGTALK].Content.AppKey, models.ConfigMap[api.DINGTALK].Content.AppSecret = config.AppKey, config.AppSecret + 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 } func (dingSender *SDingTalkSender) ContactByMobile(mobile, domainId string) (string, error) { - err := dingSender.GetAccessToken() + err := dingSender.GetAccessToken(fmt.Sprintf("%s-%s", api.DINGTALK, domainId)) if err != nil { return "", err } @@ -106,7 +106,7 @@ func (dingSender *SDingTalkSender) ContactByMobile(mobile, domainId string) (str "mobile": mobile, }) params := url.Values{} - params.Set("access_token", models.ConfigMap[api.DINGTALK].Content.AccessToken) + params.Set("access_token", models.ConfigMap[fmt.Sprintf("%s-%s", api.DINGTALK, domainId)].Content.AccessToken) res, err := sendRequest(ApiDingtalkGetUserByMobile, httputils.POST, nil, params, body) if err != nil { return "", errors.Wrap(err, "get user by mobile") @@ -134,13 +134,13 @@ func (dingSender *SDingTalkSender) IsSystemConfigContactType() bool { return true } -func (dingSender *SDingTalkSender) GetAccessToken() error { - appKey, appSecret := models.ConfigMap[api.DINGTALK].Content.AppKey, models.ConfigMap[api.DINGTALK].Content.AppSecret +func (dingSender *SDingTalkSender) GetAccessToken(key string) error { + appKey, appSecret := models.ConfigMap[key].Content.AppKey, models.ConfigMap[key].Content.AppSecret token, err := dingSender.getAccessToken(appKey, appSecret) if err != nil { return errors.Wrap(err, "dingtalk getAccessToken") } - models.ConfigMap[api.DINGTALK].Content.AccessToken = token + models.ConfigMap[key].Content.AccessToken = token return nil } diff --git a/pkg/notify/sender/dingtalk_robot.go b/pkg/notify/sender/dingtalk_robot.go index d381fc795d..f3e0da4830 100644 --- a/pkg/notify/sender/dingtalk_robot.go +++ b/pkg/notify/sender/dingtalk_robot.go @@ -99,7 +99,7 @@ func (dingRobotSender *SDingTalkRobotSender) IsSystemConfigContactType() bool { return true } -func (dingRobotSender *SDingTalkRobotSender) GetAccessToken() error { +func (dingRobotSender *SDingTalkRobotSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/email.go b/pkg/notify/sender/email.go index 4c87de26bf..353fb51fc4 100644 --- a/pkg/notify/sender/email.go +++ b/pkg/notify/sender/email.go @@ -187,28 +187,10 @@ func (emailSender *SEmailSender) IsSystemConfigContactType() bool { return true } -func (emailSender *SEmailSender) GetAccessToken() error { - corpId, secret := models.ConfigMap[api.WORKWX].Content.CorpId, models.ConfigMap[api.WORKWX].Content.Secret - token, err := emailSender.getAccessToken(corpId, secret) - if err != nil { - return errors.Wrap(err, "workwx getAccessToken") - } - models.ConfigMap[api.WORKWX].Content.AccessToken = token +func (emailSender *SEmailSender) GetAccessToken(key string) error { return nil } -func (emailSender *SEmailSender) getAccessToken(corpId, secret string) (string, error) { - // url := ApiWorkwxGetToken + fmt.Sprintf("?corpid=%s&corpsecret=%s", corpId, secret) - params := url.Values{} - params.Set("corpid", corpId) - params.Set("corpsecret", secret) - res, err := sendRequest(ApiWorkwxGetToken, httputils.GET, nil, params, nil) - if err != nil { - return "", errors.Wrap(err, "get workwx token") - } - return res.GetString("access_token") -} - func (emailSender *SEmailSender) sendMessageWithToken(uri string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { if params == nil { params = url.Values{} diff --git a/pkg/notify/sender/feishu.go b/pkg/notify/sender/feishu.go index 28de7eeb59..5998b8bdd3 100644 --- a/pkg/notify/sender/feishu.go +++ b/pkg/notify/sender/feishu.go @@ -48,20 +48,23 @@ func (feishuSender *SFeishuSender) Send(args api.SendParams) error { }, } // 添加bearer token请求头 header := http.Header{} - header.Add("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken)) - req, err := sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body)) + header.Add("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId)].Content.AccessToken)) + rep, err := sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body)) if err == nil { return nil } // 发送通知失败的情况 - code, _ := req.GetString("code") + code, err := rep.GetString("code") + if err != nil { + return err + } switch code { case "99991663": //token过期 - err = feishuSender.GetAccessToken() + err = feishuSender.GetAccessToken(fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId)) if err != nil { return errors.Wrap(err, "tenant token invalid && getToken err") } - header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken)) + header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, args.DomainId)].Content.AccessToken)) _, err = sendRequest(ApiSendMessageForFeishuByOpenId, httputils.POST, header, nil, jsonutils.Marshal(body)) if err == nil { return nil @@ -95,7 +98,7 @@ func (feishuSender *SFeishuSender) ContactByMobile(mobile, domainId string) (str body.Set("mobiles", jsonutils.NewArray(jsonutils.NewString(mobile))) header := http.Header{} // 考虑到获取用户id需求较少,可通过直接更新token来避免token失效 - err := feishuSender.GetAccessToken() + err := feishuSender.GetAccessToken(fmt.Sprintf("%s-%s", api.FEISHU, domainId)) if err != nil { return "", errors.Wrap(err, "GetAccessToken") } @@ -103,7 +106,7 @@ func (feishuSender *SFeishuSender) ContactByMobile(mobile, domainId string) (str params := url.Values{} params.Set("mobiles", mobile) - header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[api.FEISHU].Content.AccessToken)) + header.Set("Authorization", fmt.Sprintf("Bearer %s", models.ConfigMap[fmt.Sprintf("%s-%s", api.FEISHU, domainId)].Content.AccessToken)) resp, err := sendRequest(ApiFetchUserID, httputils.GET, header, params, body) if err != nil { return "", err @@ -141,10 +144,10 @@ func (feishuSender *SFeishuSender) IsSystemConfigContactType() bool { } // 获取token -func (feishuSender *SFeishuSender) GetAccessToken() error { - appId, appSecret := models.ConfigMap[api.FEISHU].Content.AppId, models.ConfigMap[api.FEISHU].Content.AppSecret +func (feishuSender *SFeishuSender) GetAccessToken(key string) error { + appId, appSecret := models.ConfigMap[key].Content.AppId, models.ConfigMap[key].Content.AppSecret resp, err := feishuSender.getAccessToken(appId, appSecret) - models.ConfigMap[api.FEISHU].Content.AccessToken = resp.TenantAccessToken + models.ConfigMap[key].Content.AccessToken = resp.TenantAccessToken return err } diff --git a/pkg/notify/sender/feishu_robot.go b/pkg/notify/sender/feishu_robot.go index 731767ee61..3617932532 100644 --- a/pkg/notify/sender/feishu_robot.go +++ b/pkg/notify/sender/feishu_robot.go @@ -101,7 +101,7 @@ func (feishuRobotSender *SFeishuRobotSender) IsSystemConfigContactType() bool { return true } -func (feishuRobotSender *SFeishuRobotSender) GetAccessToken() error { +func (feishuRobotSender *SFeishuRobotSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/mobile.go b/pkg/notify/sender/mobile.go index f3ff839b2f..0b58d18cc4 100644 --- a/pkg/notify/sender/mobile.go +++ b/pkg/notify/sender/mobile.go @@ -102,7 +102,7 @@ func (smsSender *SMobileSender) IsSystemConfigContactType() bool { return true } -func (smsSender *SMobileSender) GetAccessToken() error { +func (smsSender *SMobileSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/webconsole.go b/pkg/notify/sender/webconsole.go index eaa2646a22..2a6e065064 100644 --- a/pkg/notify/sender/webconsole.go +++ b/pkg/notify/sender/webconsole.go @@ -29,41 +29,6 @@ func (self *SWebconsoleSender) GetSenderType() string { } func (self *SWebconsoleSender) Send(args api.SendParams) error { - // var token string - // var errs []error - // title, msg := args.Title, args.Message - // // for _, recevier := range args.Receivers { - // webhook := args.Receivers.Contact - // switch { - // case strings.HasPrefix(webhook, ApiWebhookRobotV2SendMessage): - // token = webhook[len(ApiWebhookRobotV2SendMessage):] - // case strings.HasPrefix(webhook, feishu.ApiWebhookRobotSendMessage): - // token = webhook[len(feishu.ApiWebhookRobotSendMessage):] - // default: - // return errors.Wrap(InvalidWebhook, webhook) - // } - // req := feishu.WebhookRobotMsgReq{ - // Title: title, - // Text: msg, - // } - // rep, err := feishu.SendWebhookRobotMessage(token, req) - // if err != nil { - // return errors.Wrap(err, "SendWebhookRobotMessage") - // } - // if !rep.Ok { - // if strings.Contains(rep.Error, "token") { - // return ErrNoSuchWebhook - // } else { - // return fmt.Errorf("SendWebhookRobotMessage failed: %s", rep.Error) - // } - // } - // if err != nil { - // if errs == nil { - // errs = []error{} - // } - // errs = append(errs, err) - // } - // return errors.NewAggregate(errs) return nil } @@ -107,7 +72,7 @@ func (websender *SWebconsoleSender) IsSystemConfigContactType() bool { return true } -func (websender *SWebconsoleSender) GetAccessToken() error { +func (websender *SWebconsoleSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/webhook.go b/pkg/notify/sender/webhook.go index 80a8869614..be40a247aa 100644 --- a/pkg/notify/sender/webhook.go +++ b/pkg/notify/sender/webhook.go @@ -92,7 +92,7 @@ func (websender *SWebhookSender) IsSystemConfigContactType() bool { return true } -func (websender *SWebhookSender) GetAccessToken() error { +func (websender *SWebhookSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/websocket.go b/pkg/notify/sender/websocket.go index c88510ee75..db61170030 100644 --- a/pkg/notify/sender/websocket.go +++ b/pkg/notify/sender/websocket.go @@ -105,7 +105,7 @@ func (websocket *SWebsocketSender) ContactByMobile(mobile, domainId string) (str return "", nil } -func (websocket *SWebsocketSender) GetAccessToken() error { +func (websocket *SWebsocketSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/sender/workwx.go b/pkg/notify/sender/workwx.go index 5d175be6bb..84d98207f5 100644 --- a/pkg/notify/sender/workwx.go +++ b/pkg/notify/sender/workwx.go @@ -38,14 +38,14 @@ func (workwxSender *SWorkwxSender) GetSenderType() string { func (workwxSender *SWorkwxSender) Send(args api.SendParams) error { body := map[string]interface{}{ - "agentid": models.ConfigMap[api.WORKWX].Content.AgentId, + "agentid": models.ConfigMap[fmt.Sprintf("%s-%s", api.WORKWX, args.DomainId)].Content.AgentId, "msgtype": "markdown", "markdown": map[string]interface{}{ "content": fmt.Sprintf("# %s\n\n%s", args.Title, args.Message), }, "touser": args.Receivers.Contact, } - _, err := workwxSender.sendMessageWithToken(ApiWorkwxSendMessage, httputils.POST, nil, nil, jsonutils.Marshal(body)) + _, err := workwxSender.sendMessageWithToken(ApiWorkwxSendMessage, fmt.Sprintf("%s-%s", api.WORKWX, args.DomainId), httputils.POST, nil, nil, jsonutils.Marshal(body)) if err != nil { return errors.Wrap(err, "workwx send message") } @@ -69,14 +69,14 @@ func (workwxSender *SWorkwxSender) ValidateConfig(config api.NotifyConfig) (stri } func (workwxSender *SWorkwxSender) ContactByMobile(mobile, domainId string) (string, error) { - err := workwxSender.GetAccessToken() + err := workwxSender.GetAccessToken(fmt.Sprintf("%s-%s", api.WORKWX, domainId)) if err != nil { return "", err } body := jsonutils.Marshal(map[string]interface{}{ "mobile": mobile, }) - res, err := workwxSender.sendMessageWithToken(ApiWorkwxGetUserByMobile, httputils.POST, nil, nil, jsonutils.Marshal(body)) + res, err := workwxSender.sendMessageWithToken(ApiWorkwxGetUserByMobile, fmt.Sprintf("%s-%s", api.WORKWX, domainId), httputils.POST, nil, nil, jsonutils.Marshal(body)) if err != nil { return "", errors.Wrap(err, "get user by mobile") } @@ -103,13 +103,13 @@ func (workwxSender *SWorkwxSender) IsSystemConfigContactType() bool { return true } -func (workwxSender *SWorkwxSender) GetAccessToken() error { - corpId, secret := models.ConfigMap[api.WORKWX].Content.CorpId, models.ConfigMap[api.WORKWX].Content.Secret +func (workwxSender *SWorkwxSender) GetAccessToken(key string) error { + corpId, secret := models.ConfigMap[key].Content.CorpId, models.ConfigMap[key].Content.Secret token, err := workwxSender.getAccessToken(corpId, secret) if err != nil { return errors.Wrap(err, "workwx getAccessToken") } - models.ConfigMap[api.WORKWX].Content.AccessToken = token + models.ConfigMap[key].Content.AccessToken = token return nil } @@ -125,11 +125,11 @@ func (workwxSender *SWorkwxSender) getAccessToken(corpId, secret string) (string return res.GetString("access_token") } -func (workwxSender *SWorkwxSender) sendMessageWithToken(uri string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { +func (workwxSender *SWorkwxSender) sendMessageWithToken(uri, key string, method httputils.THttpMethod, header http.Header, params url.Values, body jsonutils.JSONObject) (jsonutils.JSONObject, error) { if params == nil { params = url.Values{} } - params.Set("access_token", models.ConfigMap[api.WORKWX].Content.AccessToken) + params.Set("access_token", models.ConfigMap[key].Content.AccessToken) return sendRequest(uri, httputils.POST, nil, params, jsonutils.Marshal(body)) } diff --git a/pkg/notify/sender/workwx_robot.go b/pkg/notify/sender/workwx_robot.go index de4c174e75..a84fd8a42b 100644 --- a/pkg/notify/sender/workwx_robot.go +++ b/pkg/notify/sender/workwx_robot.go @@ -84,7 +84,7 @@ func (workwxRobotSender *SWorkwxRobotSender) IsSystemConfigContactType() bool { return true } -func (workwxRobotSender *SWorkwxRobotSender) GetAccessToken() error { +func (workwxRobotSender *SWorkwxRobotSender) GetAccessToken(key string) error { return nil } diff --git a/pkg/notify/tasks/notifications_send_task.go b/pkg/notify/tasks/notifications_send_task.go index 7707f24606..3756e2b8e3 100644 --- a/pkg/notify/tasks/notifications_send_task.go +++ b/pkg/notify/tasks/notifications_send_task.go @@ -213,6 +213,7 @@ func (self *NotificationSendTask) OnInit(ctx context.Context, obj db.IStandalone p.Message += "\nfrom " + options.Options.ApiServer } + p.DomainId = self.UserCred.GetDomainId() // set status before send now := time.Now() for _, rn := range receivers { diff --git a/pkg/notify/tasks/subcontact_pull_task.go b/pkg/notify/tasks/subcontact_pull_task.go index 89cc1b3a7a..2fd9ed6a3a 100644 --- a/pkg/notify/tasks/subcontact_pull_task.go +++ b/pkg/notify/tasks/subcontact_pull_task.go @@ -41,6 +41,19 @@ var PullContactType = []string{ apis.WORKWX, } +var UserContactType = []string{ + apis.EMAIL, + apis.MOBILE, +} + +var allContactTypes = []string{ + apis.DINGTALK, + apis.FEISHU, + apis.WORKWX, + apis.EMAIL, + apis.MOBILE, +} + type SubcontactPullTask struct { taskman.STask } @@ -82,67 +95,123 @@ func (self *SubcontactPullTask) OnInit(ctx context.Context, obj db.IStandaloneMo if self.Params.Contains("contact_types") { jArray, _ := self.Params.Get("contact_types") contactTypes = jArray.(*jsonutils.JSONArray).GetStringArray() - } else { - contactTypes, _ = receiver.GetEnabledContactTypes() } - for _, cType := range contactTypes { - if !utils.IsInStringArray(cType, PullContactType) { - continue - } - content := "" - switch cType { - case apis.EMAIL: - content = receiver.Email - default: - driver := models.GetDriver(cType) - content, err = driver.ContactByMobile(mobile, "") - } - if err != nil { - var reason string - if errors.Cause(err) == apis.ErrNoSuchMobile { - receiver.MarkContactTypeUnVerified(ctx, cType, apis.ErrNoSuchMobile.Error()) - reason = fmt.Sprintf("%q: no such mobile %s", cType, receiver.Mobile) - } else if errors.Cause(err) == apis.ErrIncompleteConfig { - receiver.MarkContactTypeUnVerified(ctx, cType, apis.ErrIncompleteConfig.Error()) - reason = fmt.Sprintf("%q: %v", cType, err) + // 遍历所有通知渠道 + for _, contactType := range allContactTypes { + // 若该渠道在输入渠道内,则设为enable + if utils.IsInStringArray(contactType, contactTypes) { + // 常规渠道 + if utils.IsInStringArray(contactType, PullContactType) { + content := "" + driver := models.GetDriver(contactType) + content, err = driver.ContactByMobile(mobile, self.UserCred.GetDomainId()) + if err != nil { + var reason string + if errors.Cause(err) == apis.ErrNoSuchMobile { + receiver.MarkContactTypeUnVerified(ctx, contactType, apis.ErrNoSuchMobile.Error()) + reason = fmt.Sprintf("%q: no such mobile %s", contactType, receiver.Mobile) + } else if errors.Cause(err) == apis.ErrIncompleteConfig { + receiver.MarkContactTypeUnVerified(ctx, contactType, apis.ErrIncompleteConfig.Error()) + reason = fmt.Sprintf("%q: %v", contactType, err) + } else { + receiver.MarkContactTypeUnVerified(ctx, contactType, "service exceptions") + reason = fmt.Sprintf("%q: %v", contactType, err) + } + failedReasons = append(failedReasons, reason) + continue + } + subcontact := []models.SSubContact{} + q := models.SubContactManager.Query() + cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), contactType)) + q.Filter(cond) + err = db.FetchModelObjects(models.SubContactManager, q, &subcontact) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } + subid := "" + if len(subcontact) > 0 { + subid = subcontact[0].Id + } + err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{ + SStandaloneResourceBase: db.SStandaloneResourceBase{ + SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid}, + }, + ReceiverID: receiver.Id, + Type: contactType, + Contact: content, + ParentContactType: "mobile", + Enabled: tristate.True, + }) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } + receiver.SetContact(contactType, content) + receiver.MarkContactTypeVerified(ctx, contactType) } else { - receiver.MarkContactTypeUnVerified(ctx, cType, "service exceptions") - reason = fmt.Sprintf("%q: %v", cType, err) + _, err := db.Update(receiver, func() error { + if contactType == apis.MOBILE { + receiver.EnabledMobile = tristate.True + } + if contactType == apis.EMAIL { + receiver.EnabledEmail = tristate.True + } + return nil + }) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } } - failedReasons = append(failedReasons, reason) - continue } else { - q := models.SubContactManager.Query() - cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), cType)) - q.Filter(cond) - subcontact := []models.SSubContact{} - err := db.FetchModelObjects(models.SubContactManager, q, &subcontact) - if err != nil { - failedReasons = append(failedReasons, err.Error()) - continue - } - subid := "" - if len(subcontact) > 0 { - subid = subcontact[0].Id - } - err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{ - SStandaloneResourceBase: db.SStandaloneResourceBase{ - SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid}, - }, - ReceiverID: receiver.Id, - Type: cType, - Contact: content, - ParentContactType: "mobile", - Enabled: tristate.True, - }) - if err != nil { - log.Errorln("this is err:", err) + // 若该渠道在输入渠道内,则设为disable + if utils.IsInStringArray(contactType, PullContactType) { + subcontact := []models.SSubContact{} + q := models.SubContactManager.Query() + cond := sqlchemy.AND(sqlchemy.Equals(q.Field("receiver_id"), receiver.Id), sqlchemy.Equals(q.Field("type"), contactType)) + q.Filter(cond) + err = db.FetchModelObjects(models.SubContactManager, q, &subcontact) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } + subid := "" + if len(subcontact) > 0 { + subid = subcontact[0].Id + } + err = models.SubContactManager.TableSpec().InsertOrUpdate(ctx, &models.SSubContact{ + SStandaloneResourceBase: db.SStandaloneResourceBase{ + SStandaloneAnonResourceBase: db.SStandaloneAnonResourceBase{Id: subid}, + }, + ReceiverID: receiver.Id, + Type: contactType, + ParentContactType: "mobile", + Enabled: tristate.False, + }) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } + } else { + _, err := db.Update(receiver, func() error { + if contactType == apis.MOBILE { + receiver.EnabledMobile = tristate.False + } + if contactType == apis.EMAIL { + receiver.EnabledEmail = tristate.False + } + return nil + }) + if err != nil { + failedReasons = append(failedReasons, err.Error()) + continue + } } } - receiver.SetContact(cType, content) - receiver.MarkContactTypeVerified(ctx, cType) } + if len(failedReasons) > 0 { reason := strings.Join(failedReasons, "; ") self.taskFailed(ctx, receiver, reason)