diff --git a/cloudevents-server/pkg/config/config.go b/cloudevents-server/pkg/config/config.go index fffeecf..19d1d28 100644 --- a/cloudevents-server/pkg/config/config.go +++ b/cloudevents-server/pkg/config/config.go @@ -18,7 +18,7 @@ type Lark struct { AppID string `yaml:"app_id,omitempty" json:"app_id,omitempty"` AppSecret string `yaml:"app_secret,omitempty" json:"app_secret,omitempty"` // TODO: how to get the receiver? - Receiver string `yaml:"receiver,omitempty" json:"receiver,omitempty"` + Receivers []string `yaml:"receivers,omitempty" json:"receiver,omitempty"` } type Config struct { diff --git a/cloudevents-server/pkg/events/custom/tekton/handler.go b/cloudevents-server/pkg/events/custom/tekton/handler.go index 114a2c8..f8803b0 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler.go @@ -6,9 +6,12 @@ import ( ) func NewHandler(cfg config.Lark) (handler.EventHandler, error) { - return &pipelineRunHandler{ - LarkClient: newLarkClient(cfg), - Receiver: cfg.Receiver, - RunDetailBaseURL: "https://do.pingcap.net/tekton", - }, nil + larkClient := newLarkClient(cfg) + baseURL := "https://do.pingcap.net/tekton" + ret := new(handler.CompositeEventHandler).AddHandlers( + &pipelineRunHandler{LarkClient: larkClient, Receivers: cfg.Receivers, RunDetailBaseURL: baseURL}, + &taskRunHandler{LarkClient: larkClient, Receivers: cfg.Receivers, RunDetailBaseURL: baseURL}, + ) + + return ret, nil } diff --git a/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun.go b/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun.go index 11ed1b6..48a678a 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun.go @@ -1,7 +1,6 @@ package tekton import ( - "context" "net/http" cloudevents "github.com/cloudevents/sdk-go/v2" @@ -13,7 +12,7 @@ import ( type pipelineRunHandler struct { LarkClient *lark.Client RunDetailBaseURL string - Receiver string + Receivers []string } func (h *pipelineRunHandler) SupportEventTypes() []string { @@ -36,34 +35,9 @@ func (h *pipelineRunHandler) Handle(event cloudevents.Event) cloudevents.Result case tektoncloudevent.PipelineRunStartedEventV1, tektoncloudevent.PipelineRunFailedEventV1, tektoncloudevent.PipelineRunSuccessfulEventV1: - return h.notifyRunStatus(event) + return sendLarkMessages(h.LarkClient, h.Receivers, event, h.RunDetailBaseURL) default: log.Debug().Str("ce-type", event.Type()).Msg("skip notifing for the event type.") return cloudevents.ResultACK } } - -func (h *pipelineRunHandler) notifyRunStatus(event cloudevents.Event) cloudevents.Result { - createMsgReq, err := newLarkMessage(h.Receiver, event, h.RunDetailBaseURL) - if err != nil { - log.Error().Err(err).Msg("compose lark message failed") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "compose lark message failed: %v", err) - } - - resp, err := h.LarkClient.Im.Message.Create(context.Background(), createMsgReq) - if err != nil { - log.Error().Err(err).Msg("send lark message failed") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "send lark message failed: %v", err) - } - - if resp.Success() { - log.Info(). - Str("request-id", resp.RequestId()). - Str("message-id", *resp.Data.MessageId). - Msg("send lark message successfully.") - return cloudevents.ResultACK - } - - log.Error().Err(resp).Msg("send lark message failed!") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "send lark message failed!") -} diff --git a/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun_test.go b/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun_test.go index eb4e102..c212dab 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun_test.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler_pipelinerun_test.go @@ -50,6 +50,7 @@ func Test_pipelineRunHandler_Handle(t *testing.T) { h := &pipelineRunHandler{ LarkClient: lark.NewClient(larkAppID, larkAppSecret, lark.WithLogReqAtDebug(true), lark.WithEnableTokenCache(true)), + Receivers: []string{receiver}, RunDetailBaseURL: baseURL, } for _, tt := range tests { diff --git a/cloudevents-server/pkg/events/custom/tekton/handler_taskrun.go b/cloudevents-server/pkg/events/custom/tekton/handler_taskrun.go index ebd279a..d8a4cdf 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler_taskrun.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler_taskrun.go @@ -1,7 +1,6 @@ package tekton import ( - "context" "net/http" cloudevents "github.com/cloudevents/sdk-go/v2" @@ -13,7 +12,7 @@ import ( type taskRunHandler struct { LarkClient *lark.Client RunDetailBaseURL string - Receiver string + Receivers []string } func (h *taskRunHandler) SupportEventTypes() []string { @@ -34,34 +33,9 @@ func (h *taskRunHandler) Handle(event cloudevents.Event) cloudevents.Result { switch event.Type() { case string(tektoncloudevent.TaskRunFailedEventV1): - return h.notifyRunStatus(event) + return sendLarkMessages(h.LarkClient, h.Receivers, event, h.RunDetailBaseURL) default: log.Debug().Str("ce-type", event.Type()).Msg("skip notifing for the event type.") return cloudevents.ResultACK } } - -func (h *taskRunHandler) notifyRunStatus(event cloudevents.Event) cloudevents.Result { - createMsgReq, err := newLarkMessage(h.Receiver, event, h.RunDetailBaseURL) - if err != nil { - log.Error().Err(err).Msg("compose lark message failed") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "compose lark message failed: %v", err) - } - - resp, err := h.LarkClient.Im.Message.Create(context.Background(), createMsgReq) - if err != nil { - log.Error().Err(err).Msg("send lark message failed") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "send lark message failed: %v", err) - } - - if resp.Success() { - log.Info(). - Str("request-id", resp.RequestId()). - Str("message-id", *resp.Data.MessageId). - Msg("send lark message successfully.") - return cloudevents.ResultACK - } - - log.Error().Err(resp).Msg("send lark message failed!") - return cloudevents.NewHTTPResult(http.StatusInternalServerError, "send lark message failed!") -} diff --git a/cloudevents-server/pkg/events/custom/tekton/handler_taskrun_test.go b/cloudevents-server/pkg/events/custom/tekton/handler_taskrun_test.go index 7df04da..8e96264 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler_taskrun_test.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler_taskrun_test.go @@ -46,6 +46,7 @@ func Test_taskRunHandler_Handle(t *testing.T) { h := &taskRunHandler{ LarkClient: lark.NewClient(larkAppID, larkAppSecret, lark.WithLogReqAtDebug(true), lark.WithEnableTokenCache(true)), + Receivers: []string{receiver}, RunDetailBaseURL: baseURL, } for _, tt := range tests { diff --git a/cloudevents-server/pkg/events/custom/tekton/handler_test.go b/cloudevents-server/pkg/events/custom/tekton/handler_test.go index 11faaf0..137f7cf 100644 --- a/cloudevents-server/pkg/events/custom/tekton/handler_test.go +++ b/cloudevents-server/pkg/events/custom/tekton/handler_test.go @@ -1,8 +1,10 @@ package tekton -const ( - larkAppID = "" - larkAppSecret = "" - receiver = "@xxx.com" - baseURL = "https://chagne.me.com/" +import "os" + +var ( + larkAppID = os.Getenv("LARK_APP_ID") + larkAppSecret = os.Getenv("LARK_APP_SECRET") + receiver = os.Getenv("LARK_RECEIVER") + baseURL = os.Getenv("LINK_BASE_URL") ) diff --git a/cloudevents-server/pkg/events/custom/tekton/lark.go b/cloudevents-server/pkg/events/custom/tekton/lark.go index b6eedb6..5f28a41 100644 --- a/cloudevents-server/pkg/events/custom/tekton/lark.go +++ b/cloudevents-server/pkg/events/custom/tekton/lark.go @@ -1,15 +1,18 @@ package tekton import ( + "context" "crypto/tls" "fmt" "net/http" "strings" cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/cloudevents/sdk-go/v2/protocol" lark "github.com/larksuite/oapi-sdk-go/v3" larkcard "github.com/larksuite/oapi-sdk-go/v3/card" larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1" + "github.com/rs/zerolog/log" tektoncloudevent "github.com/tektoncd/pipeline/pkg/reconciler/events/cloudevent" "github.com/PingCAP-QE/ee-apps/cloudevents-server/pkg/config" @@ -29,25 +32,57 @@ func newLarkClient(cfg config.Lark) *lark.Client { ) } -func newLarkMessage(receiveEmail string, event cloudevents.Event, detailBaseUrl string) (*larkim.CreateMessageReq, error) { +func sendLarkMessages(client *lark.Client, receiveEmails []string, event cloudevents.Event, detailBaseUrl string) protocol.Result { + createMsgReqs, err := newLarkMessages(receiveEmails, event, detailBaseUrl) + if err != nil { + log.Error().Err(err).Msg("compose lark message failed") + return cloudevents.NewHTTPResult(http.StatusInternalServerError, "compose lark message failed: %v", err) + } + + for _, createMsgReq := range createMsgReqs { + resp, err := client.Im.Message.Create(context.Background(), createMsgReq) + if err != nil { + log.Error().Err(err).Msg("send lark message failed") + return cloudevents.NewHTTPResult(http.StatusInternalServerError, "send lark message failed: %v", err) + } + + if !resp.Success() { + return cloudevents.ResultNACK + } + + log.Info(). + Str("request-id", resp.RequestId()). + Str("message-id", *resp.Data.MessageId). + Msg("send lark message successfully.") + } + + return cloudevents.ResultACK +} + +func newLarkMessages(receiveEmails []string, event cloudevents.Event, detailBaseUrl string) ([]*larkim.CreateMessageReq, error) { messageCard := newLarkCard(event.Type(), event.Subject(), event.Source(), detailBaseUrl) messageRawStr, err := messageCard.String() if err != nil { return nil, err } - req := larkim.NewCreateMessageReqBuilder(). - ReceiveIdType(larkim.ReceiveIdTypeEmail). - Body( - larkim.NewCreateMessageReqBodyBuilder(). - MsgType(larkim.MsgTypeInteractive). - ReceiveId(receiveEmail). - Content(messageRawStr). - Build(), - ). - Build() - - return req, nil + var reqs []*larkim.CreateMessageReq + for _, receiveEmail := range receiveEmails { + req := larkim.NewCreateMessageReqBuilder(). + ReceiveIdType(larkim.ReceiveIdTypeEmail). + Body( + larkim.NewCreateMessageReqBodyBuilder(). + MsgType(larkim.MsgTypeInteractive). + ReceiveId(receiveEmail). + Content(messageRawStr). + Build(), + ). + Build() + + reqs = append(reqs, req) + } + + return reqs, nil } func newLarkCard(etype, subject, source, baseURL string) *larkcard.MessageCard {