From bf6a035b5349d891ed06bfef720ef0471af24c20 Mon Sep 17 00:00:00 2001 From: gouqi11 <66834753+gouqi11@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:14:35 +0800 Subject: [PATCH] feat(notify): SupportReceiverGetContactTypeByRoleId (#19296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 马鸿飞 --- cmd/climc/shell/notify/receiver.go | 1 + pkg/apis/notify/receiver.go | 11 +++++ pkg/mcclient/options/notify/receiver.go | 15 +++++++ pkg/notify/models/receiver.go | 55 +++++++++++++++++++++++++ pkg/notify/sender/dingtalk.go | 3 ++ pkg/notify/sender/feishu.go | 5 ++- pkg/notify/sender/workwx.go | 6 +++ 7 files changed, 95 insertions(+), 1 deletion(-) diff --git a/cmd/climc/shell/notify/receiver.go b/cmd/climc/shell/notify/receiver.go index 7f659b62be..a58f9eae9a 100644 --- a/cmd/climc/shell/notify/receiver.go +++ b/cmd/climc/shell/notify/receiver.go @@ -35,4 +35,5 @@ func init() { cmd.PerformClass("intellij-get", new(options.ReceiverIntellijGetOptions)) cmd.PerformClass("get-types", new(options.ReceiverGetTypeOptions)) cmd.Perform("get-subscription", new(options.ReceiverGetSubscriptionOptions)) + cmd.GetProperty(new(options.SReceiverRoleContactType)) } diff --git a/pkg/apis/notify/receiver.go b/pkg/apis/notify/receiver.go index 4602efa127..a16f594c54 100644 --- a/pkg/apis/notify/receiver.go +++ b/pkg/apis/notify/receiver.go @@ -206,3 +206,14 @@ type ReceiverGetSubscriptionOptions struct { Id string ShowDisabled bool } + +type SRoleContactInput struct { + RoleIds []string + Scope string + ProjectDomainId string + ProjectId string `json:"project_id"` +} + +type SRoleContactOutput struct { + ContactType []string +} diff --git a/pkg/mcclient/options/notify/receiver.go b/pkg/mcclient/options/notify/receiver.go index 04309bb9bf..4108431d86 100644 --- a/pkg/mcclient/options/notify/receiver.go +++ b/pkg/mcclient/options/notify/receiver.go @@ -156,3 +156,18 @@ type ReceiverGetTypeOptions struct { func (rg *ReceiverGetTypeOptions) Params() (jsonutils.JSONObject, error) { return jsonutils.Marshal(rg), nil } + +type SReceiverRoleContactType struct { + ROLE_IDS []string + Scope string + ProjectDomainId string + ProjectId string +} + +func (rg *SReceiverRoleContactType) Property() string { + return "role-contact-type" +} + +func (rg *SReceiverRoleContactType) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(rg), nil +} diff --git a/pkg/notify/models/receiver.go b/pkg/notify/models/receiver.go index 15221ca6e9..bbcc3bd084 100644 --- a/pkg/notify/models/receiver.go +++ b/pkg/notify/models/receiver.go @@ -44,6 +44,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/informer" identity_modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity" + modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity" notify_modules "yunion.io/x/onecloud/pkg/mcclient/modules/notify" "yunion.io/x/onecloud/pkg/notify/options" "yunion.io/x/onecloud/pkg/util/logclient" @@ -1298,3 +1299,57 @@ func (r *SReceiver) IsReceiver() bool { func (r *SReceiver) GetName() string { return r.Name } + +func (manager *SReceiverManager) GetPropertyRoleContactType(ctx context.Context, userCred mcclient.TokenCredential, input api.SRoleContactInput) (jsonutils.JSONObject, error) { + out := api.SRoleContactOutput{ + ContactType: []string{}, + } + if len(input.RoleIds) == 0 { + return nil, httperrors.NewMissingParameterError("role_ids") + } + receiverIds := []string{} + params := jsonutils.NewDict() + params.Set("roles", jsonutils.NewStringArray(input.RoleIds)) + params.Set("effective", jsonutils.JSONTrue) + switch input.Scope { + case api.SUBSCRIBER_SCOPE_SYSTEM: + case api.SUBSCRIBER_SCOPE_DOMAIN: + if len(input.ProjectDomainId) == 0 { + return nil, httperrors.NewMissingParameterError("project_domain_id") + } + params.Set("project_domain_id", jsonutils.NewString(input.ProjectDomainId)) + case api.SUBSCRIBER_SCOPE_PROJECT: + if len(input.ProjectId) == 0 { + return nil, httperrors.NewMissingParameterError("project_id") + } + params.Add(jsonutils.NewString(input.ProjectId), "scope", "project", "id") + } + s := auth.GetAdminSession(ctx, "") + listRet, err := modules.RoleAssignments.List(s, params) + if err != nil { + return nil, errors.Wrap(err, "unable to list RoleAssignments") + } + + roleAssignmentOut := []identity_api.SRoleAssignment{} + jsonutils.Update(&roleAssignmentOut, listRet.Data) + for i := range roleAssignmentOut { + receiverIds = append(receiverIds, roleAssignmentOut[i].User.Id) + } + + subContacts, err := manager.FetchSubContacts(receiverIds) + if err != nil { + return nil, errors.Wrap(err, "fetch subcontacts") + } + contactMap := map[string]struct{}{} + for i := range receiverIds { + for _, contact := range subContacts[receiverIds[i]] { + if contact.Enabled.Bool() { + contactMap[contact.Type] = struct{}{} + } + } + } + for contactType := range contactMap { + out.ContactType = append(out.ContactType, contactType) + } + return jsonutils.Marshal(out), nil +} diff --git a/pkg/notify/sender/dingtalk.go b/pkg/notify/sender/dingtalk.go index 42fb9cf7e7..0687b2c6f5 100644 --- a/pkg/notify/sender/dingtalk.go +++ b/pkg/notify/sender/dingtalk.go @@ -144,6 +144,9 @@ func (dingSender *SDingTalkSender) RegisterConfig(config models.SConfig) { func (dingSender *SDingTalkSender) GetAccessToken(ctx context.Context, domainId string) error { key := fmt.Sprintf("%s-%s", api.DINGTALK, domainId) + if _, ok := models.ConfigMap[key]; !ok { + return errors.Wrapf(errors.ErrNotSupported, "contact-type:%s,domain_id:%s is missing config", api.DINGTALK, domainId) + } appKey, appSecret := models.ConfigMap[key].Content.AppKey, models.ConfigMap[key].Content.AppSecret token, err := dingSender.getAccessToken(ctx, appKey, appSecret) if err != nil { diff --git a/pkg/notify/sender/feishu.go b/pkg/notify/sender/feishu.go index ce9ca20c41..5e6f07ec35 100644 --- a/pkg/notify/sender/feishu.go +++ b/pkg/notify/sender/feishu.go @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -158,6 +158,9 @@ func (feishuSender *SFeishuSender) RegisterConfig(config models.SConfig) { // 获取token func (feishuSender *SFeishuSender) GetAccessToken(ctx context.Context, domainId string) error { key := fmt.Sprintf("%s-%s", api.FEISHU, domainId) + if _, ok := models.ConfigMap[key]; !ok { + return errors.Wrapf(errors.ErrNotSupported, "contact-type:%s,domain_id:%s is missing config", api.FEISHU, domainId) + } appId, appSecret := models.ConfigMap[key].Content.AppId, models.ConfigMap[key].Content.AppSecret resp, err := feishuSender.getAccessToken(appId, appSecret) if err != nil { diff --git a/pkg/notify/sender/workwx.go b/pkg/notify/sender/workwx.go index 4e270a3cfb..7c9954876c 100644 --- a/pkg/notify/sender/workwx.go +++ b/pkg/notify/sender/workwx.go @@ -133,6 +133,9 @@ func (workwxSender *SWorkwxSender) RegisterConfig(config models.SConfig) { func (workwxSender *SWorkwxSender) GetAccessToken(ctx context.Context, domainId string) error { key := fmt.Sprintf("%s-%s", api.WORKWX, domainId) + if _, ok := models.ConfigMap[key]; !ok { + return errors.Wrapf(errors.ErrNotSupported, "contact-type:%s,domain_id:%s is missing config", api.WORKWX, domainId) + } corpId, secret := models.ConfigMap[key].Content.CorpId, models.ConfigMap[key].Content.Secret token, err := workwxSender.getAccessToken(ctx, corpId, secret) if err != nil { @@ -157,6 +160,9 @@ func (workwxSender *SWorkwxSender) sendMessageWithToken(ctx context.Context, uri if params == nil { params = url.Values{} } + if _, ok := models.ConfigMap[key]; !ok { + return nil, errors.Wrapf(errors.ErrNotSupported, "contact-type:%s,domain_id:%s is missing config", strings.Split(key, "-")[0], strings.Split(key, "-")[1]) + } params.Set("access_token", models.ConfigMap[key].Content.AccessToken) return sendRequest(ctx, uri, httputils.POST, nil, params, jsonutils.Marshal(body)) }