mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #18396 from gouqi11/supportDirectNotificationSending
feat(notify): Allow direct notification sending
This commit is contained in:
@@ -138,4 +138,28 @@ func init() {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
type NotificationContactInput struct {
|
||||
Subject string
|
||||
Body string
|
||||
ContactType []string
|
||||
ReceiverIds []string
|
||||
RobotIds []string
|
||||
RoleIds []string
|
||||
}
|
||||
|
||||
R(&NotificationContactInput{}, "notify-contact-send", "Send notify event message", func(s *mcclient.ClientSession, args *NotificationContactInput) error {
|
||||
params := api.NotificationManagerContactNotifyInput{
|
||||
Subject: args.Subject,
|
||||
Body: args.Body,
|
||||
ReceiverIds: args.ReceiverIds,
|
||||
ContactTypes: args.ContactType,
|
||||
RobotIds: args.RobotIds,
|
||||
RoleIds: args.RoleIds,
|
||||
}
|
||||
_, err := modules.Notification.PerformClassAction(s, "contact-notify", jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to ContactNotify: %s", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -147,3 +147,24 @@ type FailedElem struct {
|
||||
ContactType string
|
||||
Reason string
|
||||
}
|
||||
|
||||
type NotificationManagerContactNotifyInput struct {
|
||||
// description: ids or names of receiver
|
||||
// required: false
|
||||
// example: {"adfb720ccdd34c638346ea4fa7a713a8"}
|
||||
ReceiverIds []string `json:"receiver_ids"`
|
||||
// description: contact types
|
||||
// required: false
|
||||
// example: email
|
||||
ContactTypes []string `json:"contact_type"`
|
||||
// description: resource details
|
||||
// required: ture
|
||||
|
||||
// description: ids of robot
|
||||
// required: false
|
||||
// example: {"adfb720ccdd34c638346ea4fa7a713a8"}
|
||||
RobotIds []string `json:"robot_ids"`
|
||||
RoleIds []string `json:"role_ids"`
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
|
||||
@@ -37,7 +37,10 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/notify/options"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
@@ -334,6 +337,111 @@ func (nm *SNotificationManager) PerformEventNotify(ctx context.Context, userCred
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (nm *SNotificationManager) PerformContactNotify(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.NotificationManagerContactNotifyInput) (api.NotificationManagerEventNotifyOutput, error) {
|
||||
var output api.NotificationManagerEventNotifyOutput
|
||||
|
||||
params := api.SendParams{
|
||||
Title: input.Subject,
|
||||
Message: input.Body,
|
||||
EmailMsg: api.SEmailMessage{
|
||||
Body: input.Body,
|
||||
},
|
||||
DomainId: userCred.GetDomainId(),
|
||||
}
|
||||
// 机器人订阅
|
||||
if len(input.RobotIds) > 0 {
|
||||
robots := []SRobot{}
|
||||
q := RobotManager.Query().In("id", input.RobotIds)
|
||||
err := db.FetchModelObjects(RobotManager, q, &robots)
|
||||
if err != nil {
|
||||
output.FailedList = append(output.FailedList, api.FailedElem{ContactType: "robot", Reason: errors.Wrapf(err, "unable to fetch robots:%s", jsonutils.Marshal(input.RobotIds).String()).Error()})
|
||||
return output, errors.Wrapf(err, "unable to fetch robots:%s", jsonutils.Marshal(input.RobotIds).String())
|
||||
}
|
||||
for _, robot := range robots {
|
||||
go func(ctx context.Context, userCred mcclient.TokenCredential, robot SRobot, params api.SendParams) {
|
||||
params.Header = robot.Header
|
||||
params.Body = robot.Body
|
||||
params.MsgKey = robot.MsgKey
|
||||
params.Receivers = api.SNotifyReceiver{
|
||||
Contact: robot.Address,
|
||||
}
|
||||
driver := GetDriver(fmt.Sprintf("%s-robot", robot.Type))
|
||||
err = driver.Send(ctx, params)
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(&robot, "contact send", err, userCred, false)
|
||||
}
|
||||
}(ctx, userCred, robot, params)
|
||||
}
|
||||
}
|
||||
// 传入接受人id声明map保证唯一
|
||||
receivermap := map[string]struct{}{}
|
||||
for _, receiverId := range input.ReceiverIds {
|
||||
receivermap[receiverId] = struct{}{}
|
||||
}
|
||||
// 存在角色接受人
|
||||
if len(input.RoleIds) > 0 {
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region)
|
||||
query := jsonutils.NewDict()
|
||||
query.Set("roles", jsonutils.NewStringArray(input.RoleIds))
|
||||
query.Set("effective", jsonutils.JSONTrue)
|
||||
listRet, err := modules.RoleAssignments.List(s, query)
|
||||
if err != nil {
|
||||
return output, errors.Wrap(err, "unable to list RoleAssignments")
|
||||
}
|
||||
userList := []struct {
|
||||
User struct {
|
||||
Id string `json:"id"`
|
||||
} `json:"user"`
|
||||
}{}
|
||||
jsonutils.Update(&userList, listRet.Data)
|
||||
for _, user := range userList {
|
||||
receivermap[user.User.Id] = struct{}{}
|
||||
}
|
||||
}
|
||||
// 声明接受人数组
|
||||
receiverIds := []string{}
|
||||
// 输入接受人与角色去重
|
||||
for receiverId := range receivermap {
|
||||
receiverIds = append(receiverIds, receiverId)
|
||||
}
|
||||
// 接受人ID存在的情况下
|
||||
if len(receiverIds) > 0 {
|
||||
receivers, err := ReceiverManager.FetchByIDs(ctx, receiverIds...)
|
||||
if err != nil {
|
||||
return output, errors.Wrap(err, "FetchByIDs")
|
||||
}
|
||||
// 对于每个接受人根据通知渠道逐一发送
|
||||
for _, receiver := range receivers {
|
||||
// 用户没有启用的情况
|
||||
if receiver.Enabled.IsNone() {
|
||||
continue
|
||||
}
|
||||
// 获取启用的通知渠道
|
||||
enabledContactTypes, err := receiver.GetEnabledContactTypes()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, contactType := range input.ContactTypes {
|
||||
// 通知渠道没有启用
|
||||
if !utils.IsInStringArray(contactType, enabledContactTypes) {
|
||||
continue
|
||||
}
|
||||
// 发送
|
||||
go func(ctx context.Context, userCred mcclient.TokenCredential, contactType string, receiver SReceiver, params api.SendParams) {
|
||||
contact, _ := receiver.GetContact(contactType)
|
||||
params.Receivers = api.SNotifyReceiver{Contact: contact}
|
||||
driver := GetDriver(contactType)
|
||||
err = driver.Send(ctx, params)
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(&receiver, "contact send", err, userCred, false)
|
||||
}
|
||||
}(ctx, userCred, contactType, receiver, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (nm *SNotificationManager) needWebconsole(topics []STopic) bool {
|
||||
for i := range topics {
|
||||
if topics[i].WebconsoleDisable.IsFalse() || topics[i].WebconsoleDisable.IsNone() {
|
||||
|
||||
@@ -1294,3 +1294,7 @@ func (r *SReceiver) IsRobot() bool {
|
||||
func (r *SReceiver) IsReceiver() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *SReceiver) GetName() string {
|
||||
return r.Name
|
||||
}
|
||||
|
||||
@@ -296,3 +296,7 @@ func GetRobotTypeById(id string) (string, error) {
|
||||
robot := imode.(*SRobot)
|
||||
return robot.Type, nil
|
||||
}
|
||||
|
||||
func (r *SRobot) GetName() string {
|
||||
return r.Name
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ var notificationGroupLock sync.Mutex
|
||||
func init() {
|
||||
notificationGroupLock = sync.Mutex{}
|
||||
}
|
||||
|
||||
func (self *NotificationSendTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
notification := obj.(*models.SNotification)
|
||||
if notification.Status == apis.NOTIFICATION_STATUS_OK {
|
||||
|
||||
Reference in New Issue
Block a user