mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #5357 from rainzm/automated-cherry-pick-of-#5353-upstream-release-3.1
Automated cherry pick of #5353: feature(notify): Add query and return value for contact UPDATE interface
This commit is contained in:
+23
-12
@@ -29,11 +29,11 @@ func init() {
|
||||
* 操作用户的通信地址(如果用户的通信地址不存在则进行添加;如果已存在则进行修改;如果设置空则进行删除。)
|
||||
*/
|
||||
type ContactsUpdateOptions struct {
|
||||
UID string `help:"The user you wanna add contact to (Keystone User ID)"`
|
||||
CONTACTTYPE string `help:"The contact type email|mobile" choices:"email|mobile|dingtalk"`
|
||||
CONTACT string `help:"The contacts details mobile number or email address or dingtalk's userid, if set it the empty str means delete"`
|
||||
Status string `help:"Enabled or disabled contact status" choices:"enable|disable"`
|
||||
UpdateDingtalk bool `help:"if update dingtalk"`
|
||||
UID string `help:"The user you wanna add contact to (Keystone User ID)"`
|
||||
CONTACTTYPE string `help:"The contact type email|mobile" choices:"email|mobile|dingtalk"`
|
||||
CONTACT string `help:"The contacts details mobile number or email address or dingtalk's userid, if set it the empty str means delete"`
|
||||
Status string `help:"Enabled or disabled contact status" choices:"enable|disable"`
|
||||
Pull string `help:"pull some subcontacts(e.g., dingtalk, feishu, etc) related to mobile"`
|
||||
}
|
||||
R(&ContactsUpdateOptions{}, "contact-update", "Create, delete or update contact for user", func(s *mcclient.ClientSession, args *ContactsUpdateOptions) error {
|
||||
arr := jsonutils.NewArray()
|
||||
@@ -52,12 +52,8 @@ func init() {
|
||||
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(arr, "contacts")
|
||||
if args.UpdateDingtalk {
|
||||
params.Add(jsonutils.JSONTrue, "update_dingtalk")
|
||||
}
|
||||
|
||||
contact, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "update-contact", params)
|
||||
|
||||
contact, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "update-contact", args.Pull, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,6 +62,21 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type ContactsPullOptions struct {
|
||||
UID string `help:"The user you wanna pull contact"`
|
||||
CONTACTTYPE string `help:"The contact type"`
|
||||
}
|
||||
R(&ContactsPullOptions{}, "contact-pull", "Pull contact", func(s *mcclient.ClientSession, args *ContactsPullOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("contacts", jsonutils.NewArray())
|
||||
contact, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "update-contact", args.CONTACTTYPE, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(contact)
|
||||
return nil
|
||||
})
|
||||
|
||||
type ContactsDeleteOptions struct {
|
||||
UID string `help:"The user you wanna add contact to (Keystone User ID)"`
|
||||
CONTACTTYPE string `help:"The contact type email|mobile|dingtalk" choices:"email|mobile|dingtalk"`
|
||||
@@ -78,7 +89,7 @@ func init() {
|
||||
arr.Add(tmpObj)
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(arr, "contacts")
|
||||
contact, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "update-contact", params)
|
||||
contact, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "update-contact", "", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -169,7 +180,7 @@ func init() {
|
||||
tmpDict := jsonutils.NewDict()
|
||||
tmpDict.Add(jsonutils.NewString(args.CONTACT_TYPE), "contact_type")
|
||||
tmpDict.Add(jsonutils.NewString(args.CONTACT), "contact")
|
||||
_, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "verify", tmpDict)
|
||||
_, err := modules.Contacts.CustomizedPerformAction(s, args.UID, "verify", "", tmpDict)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func init() {
|
||||
*/
|
||||
|
||||
type NotificationCreateOptions struct {
|
||||
CONTACTTYPE string `help:"User's contacts type" choices:"email|mobile|dingtalk|webconsole"`
|
||||
CONTACTTYPE string `help:"User's contacts type"`
|
||||
TOPIC string `help:"Title or topic of the notification"`
|
||||
PRIORITY string `help:"Priority of the notification" choices:"normal|important|fatal"`
|
||||
MSG string `help:"The content of the notification"`
|
||||
|
||||
@@ -115,10 +115,15 @@ func (manager *SUserCacheManager) FetchUserFromKeystone(ctx context.Context, idS
|
||||
user, err := modules.UsersV3.GetById(s, idStr, nil)
|
||||
if err != nil {
|
||||
if je, ok := err.(*httputils.JSONClientError); ok && je.Code == 404 {
|
||||
return nil, sql.ErrNoRows
|
||||
user, err = modules.UsersV3.GetByName(s, idStr, nil)
|
||||
if je, ok := err.(*httputils.JSONClientError); ok && je.Code == 404 {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("fetch user %s fail %s", idStr, err)
|
||||
return nil, errors.Wrap(err, "modules.UsersV3.Get")
|
||||
}
|
||||
log.Errorf("fetch user %s fail %s", idStr, err)
|
||||
return nil, errors.Wrap(err, "modules.UsersV3.Get")
|
||||
}
|
||||
id, _ := user.GetString("id")
|
||||
name, _ := user.GetString("name")
|
||||
@@ -133,7 +138,7 @@ func (manager *SUserCacheManager) Save(ctx context.Context, idStr string, name s
|
||||
|
||||
objo, err := manager.FetchById(idStr)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("FetchTenantbyId fail %s", err)
|
||||
log.Errorf("FetchUserbyId fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
if err == nil {
|
||||
|
||||
@@ -45,7 +45,7 @@ func (this *ContactsManager) DoBatchDeleteContacts(s *mcclient.ClientSession, pa
|
||||
return modulebase.Post(this.ResourceManager, s, path, params, this.Keyword)
|
||||
}
|
||||
|
||||
func (this *ContactsManager) CustomizedPerformAction(session *mcclient.ClientSession, id string, action string,
|
||||
func (this *ContactsManager) CustomizedPerformAction(session *mcclient.ClientSession, id, action, pull string,
|
||||
params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
|
||||
body := jsonutils.NewDict()
|
||||
@@ -53,7 +53,10 @@ func (this *ContactsManager) CustomizedPerformAction(session *mcclient.ClientSes
|
||||
body.Add(params, this.Keyword)
|
||||
}
|
||||
path := fmt.Sprintf("/%s/%s/%s?uname=true", this.ContextPath(nil), url.PathEscape(id), url.PathEscape(action))
|
||||
return modulebase.Post(this.ResourceManager, session, path, params, this.KeywordPlural)
|
||||
if len(pull) > 0 {
|
||||
path += fmt.Sprintf("&pull=%s", pull)
|
||||
}
|
||||
return modulebase.Post(this.ResourceManager, session, path, body, this.KeywordPlural)
|
||||
}
|
||||
|
||||
func (this *ContactsManager) CustomizedGet(session *mcclient.ClientSession, id string,
|
||||
|
||||
@@ -379,7 +379,7 @@ func (self *NotifyModelDispatcher) DeleteContacts(ctx context.Context, uids2 []j
|
||||
|
||||
// UpdateContacts analysis the data and update corresponding contacts if they exist in the database create new ones.
|
||||
func (self *NotifyModelDispatcher) UpdateContacts(ctx context.Context, idstr string, query jsonutils.JSONObject,
|
||||
datas []jsonutils.JSONObject, ctxIds []dispatcher.SResourceContext) error {
|
||||
datas []jsonutils.JSONObject, ctxIds []dispatcher.SResourceContext) (jsonutils.JSONObject, error) {
|
||||
|
||||
type pair struct {
|
||||
contact string
|
||||
@@ -406,7 +406,7 @@ func (self *NotifyModelDispatcher) UpdateContacts(ctx context.Context, idstr str
|
||||
|
||||
records, err := models.ContactManager.FetchByUIDAndCType(idstr, contactTypes)
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(err)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
|
||||
// updateFailed record the information of failed update
|
||||
@@ -482,13 +482,29 @@ func (self *NotifyModelDispatcher) UpdateContacts(ctx context.Context, idstr str
|
||||
errInfoBuffer.WriteString(" create failed. ")
|
||||
}
|
||||
errInfo := errInfoBuffer.String()
|
||||
return httperrors.NewGeneralError(errors.Error(errInfo))
|
||||
return nil, httperrors.NewGeneralError(errors.Error(errInfo))
|
||||
}
|
||||
|
||||
if query.Contains("update_dingtalk") {
|
||||
models.UpdateDingtalk(idstr)
|
||||
if query.Contains("pull") {
|
||||
cType, _ := query.GetString("pull")
|
||||
models.PullContact(idstr, cType)
|
||||
}
|
||||
return nil
|
||||
|
||||
// keep the return value same as this of the GET interface
|
||||
ret := jsonutils.NewDict()
|
||||
contact, err := models.ContactManager.FetchByUIDs(ctx, []string{idstr}, false)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return ret, nil
|
||||
}
|
||||
outDetails, err := contact[0].GetExtraDetails(ctx, userCred, ret, false)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return ret, nil
|
||||
}
|
||||
out := jsonutils.Marshal(outDetails)
|
||||
out.(*jsonutils.JSONDict).Set("created_at", jsonutils.NewString(contact[0].CreatedAt.String()))
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (self *NotifyModelDispatcher) UpdateTemplate(ctx context.Context, ctype string, query jsonutils.JSONObject,
|
||||
|
||||
@@ -306,19 +306,13 @@ func contactUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
|
||||
uid := params["<uid>"]
|
||||
queryDict := mergeQueryParams(params, query)
|
||||
update, _ := body.Bool(manager.Keyword(), "update_dingtalk")
|
||||
if update {
|
||||
dict := queryDict.(*jsonutils.JSONDict)
|
||||
dict.Add(jsonutils.JSONTrue, "update_dingtalk")
|
||||
}
|
||||
err = manager.UpdateContacts(ctx, uid, queryDict, data, nil)
|
||||
out, err := manager.UpdateContacts(ctx, uid, mergeQueryParams(params, query), data, nil)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
httperrors.BadRequestError(w, "")
|
||||
return
|
||||
}
|
||||
return
|
||||
appsrv.SendJSON(w, wrap(out, manager.Keyword()))
|
||||
}
|
||||
|
||||
// delete contact handler
|
||||
|
||||
@@ -115,6 +115,8 @@ func (self *SContactManager) InitializeData() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FetchByUIDs fetch all SContancts whose uid included in uids.
|
||||
// If some elements of uids are uname of users, setting param 'uname' as true will fetch correct results.
|
||||
func (self *SContactManager) FetchByUIDs(ctx context.Context, uids []string, uname bool) ([]SContact, error) {
|
||||
var err error
|
||||
if uname {
|
||||
|
||||
+17
-17
@@ -108,60 +108,60 @@ func SendVerifyMessage(ctx context.Context, userCred mcclient.TokenCredential, v
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateDingtalk(uid string) {
|
||||
func PullContact(uid string, contactType string) {
|
||||
workMan.Run(func() {
|
||||
updateDingtalk(context.Background(), uid)
|
||||
pullContact(context.Background(), uid, contactType)
|
||||
}, nil, nil)
|
||||
}
|
||||
|
||||
func updateDingtalk(ctx context.Context, uid string) {
|
||||
contacts, err := ContactManager.FetchByUIDAndCType(uid, []string{MOBILE, DINGTALK})
|
||||
func pullContact(ctx context.Context, uid string, contactType string) {
|
||||
contacts, err := ContactManager.FetchByUIDAndCType(uid, []string{MOBILE, contactType})
|
||||
if err != nil {
|
||||
log.Errorf("fetch contacts error")
|
||||
}
|
||||
if len(contacts) == 0 {
|
||||
return
|
||||
}
|
||||
var mobileContact, dingtalkContact *SContact
|
||||
var mobileContact, subContact *SContact
|
||||
for i := range contacts {
|
||||
if contacts[i].ContactType == MOBILE {
|
||||
mobileContact = &contacts[i]
|
||||
} else {
|
||||
dingtalkContact = &contacts[i]
|
||||
subContact = &contacts[i]
|
||||
}
|
||||
}
|
||||
if mobileContact == nil {
|
||||
return
|
||||
}
|
||||
|
||||
userid, err := NotifyService.ContactByMobile(ctx, mobileContact.Contact, DINGTALK)
|
||||
userid, err := NotifyService.ContactByMobile(ctx, mobileContact.Contact, contactType)
|
||||
if err != nil {
|
||||
log.Errorf("fetch dingtalk userid by mobile failed: %s", err.Error())
|
||||
log.Errorf("fetch %s contact by mobile failed: %s", contactType, err.Error())
|
||||
}
|
||||
if dingtalkContact != nil {
|
||||
dingtalkContact.SetModelManager(ContactManager, dingtalkContact)
|
||||
origin := dingtalkContact.Contact
|
||||
_, err := db.Update(dingtalkContact, func() error {
|
||||
dingtalkContact.Contact = userid
|
||||
if subContact != nil {
|
||||
subContact.SetModelManager(ContactManager, subContact)
|
||||
origin := subContact.Contact
|
||||
_, err := db.Update(subContact, func() error {
|
||||
subContact.Contact = userid
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("update dingtalk userid %s => %s failed", origin, userid)
|
||||
log.Errorf("update %s contact userid %s => %s failed", contactType, origin, userid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
contact := SContact{
|
||||
UID: uid,
|
||||
ContactType: DINGTALK,
|
||||
ContactType: contactType,
|
||||
Contact: userid,
|
||||
Enabled: "1",
|
||||
VerifiedAt: time.Now(),
|
||||
}
|
||||
contact.Status = CONTACT_VERIFIED
|
||||
|
||||
err = ContactManager.TableSpec().InsertOrUpdate(&contact)
|
||||
err = ContactManager.TableSpec().Insert(&contact)
|
||||
if err != nil {
|
||||
log.Errorf("create new dingtalk contact failed")
|
||||
log.Errorf("create new %s contact failed", contactType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func (self *SRpcService) InitAll() error {
|
||||
}
|
||||
}
|
||||
if self.SendServices.Len() == 0 {
|
||||
log.Errorf("No available send service.")
|
||||
log.Infof("No available send service.")
|
||||
} else {
|
||||
log.Infof("Total %d send service init successful", self.SendServices.Len())
|
||||
}
|
||||
@@ -285,12 +285,14 @@ func (self *SRpcService) startNewService(ctx context.Context, serviceName string
|
||||
_, err = sendService.UpdateConfig(ctx, &args)
|
||||
if err != nil {
|
||||
st := status.Convert(err)
|
||||
if st.Code() == codes.Unavailable {
|
||||
if st.Code() == codes.FailedPrecondition {
|
||||
// no such rpc serve
|
||||
os.Remove(filename)
|
||||
return nil, fmt.Errorf("no such rpc serve")
|
||||
err = fmt.Errorf(st.Message())
|
||||
}
|
||||
return nil, fmt.Errorf(st.Message())
|
||||
if st.Code() == codes.Unavailable {
|
||||
err = fmt.Errorf("service is unavailable for now: %s", st.Message())
|
||||
}
|
||||
return nil, errors.Wrap(err, "UpdateConfig")
|
||||
}
|
||||
|
||||
return sendService, nil
|
||||
|
||||
Reference in New Issue
Block a user