mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
Feature & Fix for Notify (#7714)
* feat(notify): Add 'get-types' action for ConfigManager The List interface is only open to administrators, because we don't want anyone other than administrators to see the details of the notify configuration. To let general user to kown available notification channels, add 'get-types' actions of ConfigManager. * feat(notify): Check the availability of contact type before creating notification Creating notification with unconfigured contact type will fail at sending message. Now, prevent creation in advance. * feat(notify): Add workwx for NotifyNormal/Important/Critical * feat(notify): Add Notify about robot in notifyclient * fix(notify): Init ParentContactType for SSubContact 1. ParentContactType of SSubContact with webconsole type is empty. 2. ParentContactType of others SSubContact is mobile. * fix(notify): Unverify SSubContact when ParentContactType match * fix(notify): When no data is initialized, exit directly
This commit is contained in:
@@ -17,6 +17,7 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
@@ -132,6 +133,55 @@ func (c *SConfig) PostUpdate(ctx context.Context, userCred mcclient.TokenCredent
|
||||
NotifyService.RestartService(ctx, configMap, c.Type)
|
||||
}
|
||||
|
||||
func (cm *SConfigManager) AllowPerformGetTypes(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cm *SConfigManager) PerformGetTypes(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ConfigManagerGetTypesInput) (api.ConfigManagerGetTypesOutput, error) {
|
||||
output := api.ConfigManagerGetTypesOutput{}
|
||||
allContactType, err := cm.allContactType()
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
var judge func(string) bool
|
||||
switch input.Robot {
|
||||
case "only":
|
||||
judge = func(ctype string) bool {
|
||||
return strings.Contains(ctype, "robot")
|
||||
}
|
||||
case "yes":
|
||||
judge = func(ctype string) bool {
|
||||
return true
|
||||
}
|
||||
default:
|
||||
judge = func(ctype string) bool {
|
||||
return !strings.Contains(ctype, "robot")
|
||||
}
|
||||
}
|
||||
for _, ctype := range allContactType {
|
||||
if judge(ctype) {
|
||||
output.Types = append(output.Types, ctype)
|
||||
}
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (cm *SConfigManager) allContactType() ([]string, error) {
|
||||
q := cm.Query("type")
|
||||
allTypes := make([]struct {
|
||||
Type string
|
||||
}, 0, 3)
|
||||
err := q.All(&allTypes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]string, len(allTypes))
|
||||
for i := range ret {
|
||||
ret[i] = allTypes[i].Type
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SConfigManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, input api.ConfigListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := self.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, input.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/notify"
|
||||
@@ -71,6 +72,14 @@ type SNotification struct {
|
||||
}
|
||||
|
||||
func (nm *SNotificationManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.NotificationCreateInput) (api.NotificationCreateInput, error) {
|
||||
// check contact type enabled
|
||||
allContactType, err := ConfigManager.allContactType()
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
if !utils.IsInStringArray(input.ContactType, allContactType) {
|
||||
return input, httperrors.NewInputParameterError("Unconfigured contact type %q", input.ContactType)
|
||||
}
|
||||
// check uids, rids and contacts
|
||||
if len(input.Receivers) == 0 && len(input.Contacts) == 0 {
|
||||
return input, httperrors.NewMissingParameterError("receivers | contacts")
|
||||
|
||||
@@ -119,6 +119,9 @@ func (rm *SReceiverManager) InitializeData() error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
if len(contacts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// build uid map
|
||||
uids := make([]string, 0, 10)
|
||||
@@ -186,6 +189,7 @@ func (rm *SReceiverManager) InitializeData() error {
|
||||
webconsole = true
|
||||
subContact.Contact = uid
|
||||
} else {
|
||||
subContact.ParentContactType = api.MOBILE
|
||||
subContact.Contact = contact.Contact
|
||||
}
|
||||
subContact.ReceiverID = uid
|
||||
@@ -338,11 +342,15 @@ func (r *SReceiver) setEnabledContactType(contactType string, enabled bool) {
|
||||
if sc, ok := r.subContactCache[contactType]; ok {
|
||||
sc.Enabled = tristate.NewFromBool(enabled)
|
||||
} else {
|
||||
r.subContactCache[contactType] = &SSubContact{
|
||||
subContact := &SSubContact{
|
||||
Type: contactType,
|
||||
ReceiverID: r.Id,
|
||||
Enabled: tristate.NewFromBool(enabled),
|
||||
}
|
||||
if contactType != api.WEBCONSOLE {
|
||||
subContact.ParentContactType = api.MOBILE
|
||||
}
|
||||
r.subContactCache[contactType] = subContact
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,10 +377,15 @@ func (r *SReceiver) MarkContactTypeVerified(contactType string) error {
|
||||
if sc, ok := r.subContactCache[contactType]; ok {
|
||||
sc.Verified = tristate.True
|
||||
} else {
|
||||
r.subContactCache[contactType] = &SSubContact{
|
||||
subContact := &SSubContact{
|
||||
Type: contactType,
|
||||
ReceiverID: r.Id,
|
||||
Verified: tristate.True,
|
||||
Enabled: tristate.True,
|
||||
}
|
||||
if contactType != api.WEBCONSOLE {
|
||||
subContact.ParentContactType = api.MOBILE
|
||||
}
|
||||
r.subContactCache[contactType] = subContact
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -387,10 +400,15 @@ func (r *SReceiver) setVerifiedContactType(contactType string, enabled bool) {
|
||||
if sc, ok := r.subContactCache[contactType]; ok {
|
||||
sc.Verified = tristate.NewFromBool(enabled)
|
||||
} else {
|
||||
r.subContactCache[contactType] = &SSubContact{
|
||||
subContact := &SSubContact{
|
||||
Type: contactType,
|
||||
ReceiverID: r.Id,
|
||||
Verified: tristate.NewFromBool(enabled),
|
||||
}
|
||||
if contactType != api.WEBCONSOLE {
|
||||
subContact.ParentContactType = api.MOBILE
|
||||
}
|
||||
r.subContactCache[contactType] = subContact
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,7 +648,7 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden
|
||||
if len(input.Email) != 0 && input.Email != r.Email {
|
||||
r.VerifiedEmail = tristate.False
|
||||
for _, c := range r.subContactCache {
|
||||
if c.ParentContactType == input.Email {
|
||||
if c.ParentContactType == api.EMAIL {
|
||||
c.Verified = tristate.False
|
||||
}
|
||||
}
|
||||
@@ -638,7 +656,7 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden
|
||||
if len(input.Mobile) != 0 && input.Mobile != r.Mobile {
|
||||
r.VerifiedMobile = tristate.False
|
||||
for _, c := range r.subContactCache {
|
||||
if c.ParentContactType == input.Mobile {
|
||||
if c.ParentContactType == api.MOBILE {
|
||||
c.Verified = tristate.False
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user