fix: send system notification to specific users or groups

This commit is contained in:
Qiu Jian
2019-02-16 01:46:39 +08:00
parent cf3631983c
commit a72ae86082
9 changed files with 102 additions and 41 deletions
+9
View File
@@ -1,10 +1,12 @@
package cloudcommon
import (
"context"
"fmt"
"os"
"time"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/mcclient/auth"
)
@@ -41,6 +43,13 @@ func InitAuth(options *CommonOptions, authComplete auth.AuthCompletedCallback) {
auth.Init(a, options.DebugClient, true, options.SslCertfile, options.SslKeyfile) // , authComplete)
users := options.NotifyAdminUsers
groups := options.NotifyAdminGroups
if len(users) == 0 && len(groups) == 0 {
users = []string{"sysadmin"}
}
notifyclient.FetchNotifyAdminRecipients(context.Background(), options.Region, users, groups)
authComplete()
if options.EnableRbac {
+77 -26
View File
@@ -14,12 +14,16 @@ import (
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
)
var (
templatesTable map[string]*template.Template
notifyClientWorkerMan *appsrv.SWorkerManager
notifyAdminUsers []string
notifyAdminGroups []string
)
func init() {
@@ -39,10 +43,10 @@ func getTemplateString(topic string, contType string, channel notify.TNotifyChan
return ioutil.ReadFile(path)
}
func getTemplate(topic string, contType string) (*template.Template, error) {
key := fmt.Sprintf("%s.%s", topic, contType)
func getTemplate(topic string, contType string, channel notify.TNotifyChannel) (*template.Template, error) {
key := fmt.Sprintf("%s.%s.%s", topic, contType, channel)
if _, ok := templatesTable[key]; !ok {
cont, err := getTemplateString(topic, contType, "")
cont, err := getTemplateString(topic, contType, channel)
if err != nil {
return nil, err
}
@@ -55,8 +59,8 @@ func getTemplate(topic string, contType string) (*template.Template, error) {
return templatesTable[key], nil
}
func getContent(topic string, contType string, data jsonutils.JSONObject) (string, error) {
tmpl, err := getTemplate(topic, contType)
func getContent(topic string, contType string, channel notify.TNotifyChannel, data jsonutils.JSONObject) (string, error) {
tmpl, err := getTemplate(topic, contType, channel)
if err != nil {
return "", err
}
@@ -80,7 +84,7 @@ func Notify(recipientId string, isGroup bool, priority notify.TNotifyPriority, e
}
}
func RawNotify(recipientId string, isGroup bool, channels []notify.TNotifyChannel, priority notify.TNotifyPriority, event string, data jsonutils.JSONObject) {
func RawNotify(recipientId string, isGroup bool, channel notify.TNotifyChannel, priority notify.TNotifyPriority, event string, data jsonutils.JSONObject) {
log.Infof("notify %s event %s priority %s", recipientId, event, priority)
msg := notify.SNotifyMessage{}
if isGroup {
@@ -89,13 +93,13 @@ func RawNotify(recipientId string, isGroup bool, channels []notify.TNotifyChanne
msg.Uid = recipientId
}
msg.Priority = priority
msg.ContactType = channels
topic, _ := getContent(event, "title", data)
msg.ContactType = channel
topic, _ := getContent(event, "title", channel, data)
if len(topic) == 0 {
topic = event
}
msg.Topic = topic
body, _ := getContent(event, "content", data)
body, _ := getContent(event, "content", channel, data)
if len(body) == 0 {
body = data.String()
}
@@ -108,32 +112,57 @@ func RawNotify(recipientId string, isGroup bool, channels []notify.TNotifyChanne
}
func NotifyNormal(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk},
notify.NotifyPriorityNormal,
event, data)
for _, c := range []notify.TNotifyChannel{
notify.NotifyByEmail,
notify.NotifyByDingTalk,
notify.NotifyByWebConsole,
} {
RawNotify(recipientId, isGroup,
c,
notify.NotifyPriorityNormal,
event, data)
}
}
func NotifyImportant(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk, notify.NotifyByMobile},
notify.NotifyPriorityImportant,
event, data)
for _, c := range []notify.TNotifyChannel{
notify.NotifyByEmail,
notify.NotifyByDingTalk,
notify.NotifyByMobile,
notify.NotifyByWebConsole,
} {
RawNotify(recipientId, isGroup,
c,
notify.NotifyPriorityImportant,
event, data)
}
}
func NotifyCritical(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk, notify.NotifyByMobile},
notify.NotifyPriorityCritical,
event, data)
for _, c := range []notify.TNotifyChannel{
notify.NotifyByEmail,
notify.NotifyByDingTalk,
notify.NotifyByMobile,
notify.NotifyByWebConsole,
} {
RawNotify(recipientId, isGroup,
c,
notify.NotifyPriorityCritical,
event, data)
}
}
func SystemNotify(event string, data jsonutils.JSONObject) {
NotifyCritical(auth.AdminCredential().GetProjectId(), true, event, data)
func SystemNotify(priority notify.TNotifyPriority, event string, data jsonutils.JSONObject) {
for _, uid := range notifyAdminUsers {
Notify(uid, false, priority, event, data)
}
for _, gid := range notifyAdminGroups {
Notify(gid, true, priority, event, data)
}
}
func NotifyGeneralSystemError(data jsonutils.JSONObject) {
SystemNotify(SYSTEM_ERROR, data)
SystemNotify(notify.NotifyPriorityCritical, SYSTEM_ERROR, data)
}
type sSystemErrorMsg struct {
@@ -150,9 +179,31 @@ func NotifySystemError(idstr string, name string, event string, reason string) {
Event: event,
Reason: reason,
}
SystemNotify(SYSTEM_ERROR, jsonutils.Marshal(msg))
SystemNotify(notify.NotifyPriorityCritical, SYSTEM_ERROR, jsonutils.Marshal(msg))
}
func NotifySystemWarning(data jsonutils.JSONObject) {
SystemNotify(SYSTEM_WARNING, data)
SystemNotify(notify.NotifyPriorityImportant, SYSTEM_WARNING, data)
}
func FetchNotifyAdminRecipients(ctx context.Context, region string, users []string, groups []string) {
s := auth.GetAdminSession(ctx, region, "v1")
notifyAdminUsers = make([]string, 0)
for _, u := range users {
uId, err := modules.UsersV3.GetId(s, u, nil)
if err != nil {
log.Warningf("fetch user %s fail: %s", u, err)
} else {
notifyAdminUsers = append(notifyAdminUsers, uId)
}
}
notifyAdminGroups = make([]string, 0)
for _, g := range groups {
gId, err := modules.Groups.GetId(s, g, nil)
if err != nil {
log.Errorf("fetch group %s fail: %s", g, err)
} else {
notifyAdminGroups = append(notifyAdminGroups, gId)
}
}
}
+2 -1
View File
@@ -36,7 +36,8 @@ type CommonOptions struct {
ApplicationID string `help:"Application ID"`
RequestWorkerCount int `default:"4" help:"Request worker thread count, default is 4"`
NotifyAdminUser string `default:"sysadmin" help:"System administrator user ID or name to notify"`
NotifyAdminUsers []string `default:"sysadmin" help:"System administrator user ID or name to notify system events"`
NotifyAdminGroups []string `help:"System administrator group ID or name to notify system events"`
EnableSsl bool `help:"Enable https"`
SslCaCerts string `help:"ssl certificate ca root file, separating ca and cert file is not encouraged" alias:"ca-file"`
+3 -3
View File
@@ -509,7 +509,7 @@ func (self *SGuest) StartGuestDeployTask(ctx context.Context, userCred mcclient.
return nil
}
func (self *SGuest) NotifyServerEvent(event string, priority notify.TNotifyPriority, loginInfo bool) {
func (self *SGuest) NotifyServerEvent(userCred mcclient.TokenCredential, event string, priority notify.TNotifyPriority, loginInfo bool) {
meta, err := self.GetAllMetadata(nil)
if err != nil {
return
@@ -539,7 +539,7 @@ func (self *SGuest) NotifyServerEvent(event string, priority notify.TNotifyPrior
}
}
}
notifyclient.Notify(self.ProjectId, true, priority, event, kwargs)
notifyclient.Notify(userCred.GetUserId(), false, priority, event, kwargs)
}
func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, priority notify.TNotifyPriority) {
@@ -551,7 +551,7 @@ func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, pr
} else {
kwargs.Add(jsonutils.NewString(self.ProjectId), "tenant")
}
notifyclient.Notify(options.Options.NotifyAdminUser, true, priority, event, kwargs)
notifyclient.SystemNotify(priority, event, kwargs)
}
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce bool, parentTaskId string) error {
+1 -1
View File
@@ -101,7 +101,7 @@ func (self *GuestCreateTask) OnDeployGuestDescComplete(ctx context.Context, obj
}
func (self *GuestCreateTask) notifyServerCreated(ctx context.Context, guest *models.SGuest) {
guest.NotifyServerEvent(notifyclient.SERVER_CREATED, notify.NotifyPriorityImportant, true)
guest.NotifyServerEvent(self.UserCred, notifyclient.SERVER_CREATED, notify.NotifyPriorityImportant, true)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_CREATED_ADMIN, notify.NotifyPriorityImportant)
}
+1 -1
View File
@@ -266,6 +266,6 @@ func (self *GuestDeleteTask) DeleteGuest(ctx context.Context, guest *models.SGue
}
func (self *GuestDeleteTask) NotifyServerDeleted(ctx context.Context, guest *models.SGuest) {
guest.NotifyServerEvent(notifyclient.SERVER_DELETED, notify.NotifyPriorityImportant, false)
guest.NotifyServerEvent(self.UserCred, notifyclient.SERVER_DELETED, notify.NotifyPriorityImportant, false)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_DELETED_ADMIN, notify.NotifyPriorityImportant)
}
+1 -1
View File
@@ -149,7 +149,7 @@ func (self *GuestRebuildRootTask) OnRebuildAllDisksComplete(ctx context.Context,
}
}
db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT, "", self.UserCred)
guest.NotifyServerEvent(notifyclient.SERVER_REBUILD_ROOT, notify.NotifyPriorityImportant, true)
guest.NotifyServerEvent(self.UserCred, notifyclient.SERVER_REBUILD_ROOT, notify.NotifyPriorityImportant, true)
self.SetStage("OnSyncStatusComplete", nil)
guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId())
}
+1 -1
View File
@@ -26,7 +26,7 @@ func ParsePropStr(lines string) map[string]string {
func BuildPropStr(prop map[string]string) string {
keys := []string{}
for k, _ := range prop {
for k := range prop {
keys = append(keys, k)
}
sort.Strings(keys)
@@ -12,13 +12,13 @@ var (
)
type SNotifyMessage struct {
Uid string `json:"uid,omitempty"`
Gid string `json:"uid,omitempty"`
ContactType []TNotifyChannel `json:"contact_type,omitempty"`
Topic string `json:"topic,omitempty"`
Priority TNotifyPriority `json:"priority,omitempty"`
Msg string `json:"msg,omitempty"`
Remark string `json:"remark,omitempty"`
Uid string `json:"uid,omitempty"`
Gid string `json:"uid,omitempty"`
ContactType TNotifyChannel `json:"contact_type,omitempty"`
Topic string `json:"topic,omitempty"`
Priority TNotifyPriority `json:"priority,omitempty"`
Msg string `json:"msg,omitempty"`
Remark string `json:"remark,omitempty"`
}
type NotificationManager struct {