@@ -2,26 +2,12 @@ package notification
22
33import (
44 "bytes"
5- "context"
6- "encoding/json"
7- "fmt"
85 slackapi "github.com/slack-go/slack"
96 "html/template"
10- "io"
117 "k8s.io/klog"
12- "net/http"
13- "net/url"
148 "os"
15- "strconv"
16- "strings"
17- "time"
189)
1910
20- // httpDo is a package-level variable to allow tests to stub HTTP requests easily.
21- var httpDo = func (req * http.Request ) (* http.Response , error ) {
22- return http .DefaultClient .Do (req )
23- }
24-
2511const (
2612 START = "start"
2713 SUCCESS = "success"
@@ -52,7 +38,6 @@ var slackColors = map[string]string{
5238
5339type slackClient interface {
5440 PostMessage (channelID string , options ... slackapi.MsgOption ) (string , string , error )
55- // Deprecated in Slack API: kept for backward compatibility in tests, but no longer used
5641 UploadFile (params slackapi.FileUploadParameters ) (file * slackapi.File , err error )
5742}
5843
@@ -266,126 +251,20 @@ func (s slack) notify(attachment slackapi.Attachment) (err error) {
266251}
267252
268253func (s slack ) uploadLog (param MessageTemplateParam ) (file * slackapi.File , err error ) {
269- // External upload flow per Slack deprecation of files.upload
270- // 1) Call files.getUploadURLExternal to obtain an upload URL and file ID
271- token := os .Getenv ("SLACK_TOKEN" )
272- if token == "" {
273- return nil , fmt .Errorf ("SLACK_TOKEN is not set" )
274- }
275-
276- title := param .Namespace + "_" + param .JobName
277- content := param .Log
278- contentBytes := []byte (content )
279- length := len (contentBytes )
280-
281- ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
282- defer cancel ()
283-
284- // Step 1: get upload URL
285- form := url.Values {}
286- form .Set ("filename" , title + ".txt" )
287- form .Set ("length" , strconv .Itoa (length ))
288- getURLReq , err := http .NewRequestWithContext (ctx , http .MethodPost , "https://slack.com/api/files.getUploadURLExternal" , strings .NewReader (form .Encode ()))
289- if err != nil {
290- return nil , err
291- }
292- getURLReq .Header .Set ("Authorization" , "Bearer " + token )
293- getURLReq .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
294-
295- resp , err := httpDo (getURLReq )
254+ file , err = s .client .UploadFile (
255+ slackapi.FileUploadParameters {
256+ Title : param .Namespace + "_" + param .JobName ,
257+ Content : param .Log ,
258+ Filetype : "txt" ,
259+ Channels : []string {s .channel },
260+ })
296261 if err != nil {
297- return nil , err
298- }
299- defer resp .Body .Close ()
300- if resp .StatusCode < 200 || resp .StatusCode >= 300 {
301- b , _ := io .ReadAll (resp .Body )
302- return nil , fmt .Errorf ("files.getUploadURLExternal failed: status=%d body=%s" , resp .StatusCode , string (b ))
303- }
304-
305- var getURLRes struct {
306- OK bool `json:"ok"`
307- UploadURL string `json:"upload_url"`
308- FileID string `json:"file_id"`
309- Error string `json:"error"`
310- }
311- if err := json .NewDecoder (resp .Body ).Decode (& getURLRes ); err != nil {
312- return nil , err
313- }
314- if ! getURLRes .OK {
315- return nil , fmt .Errorf ("files.getUploadURLExternal error: %s" , getURLRes .Error )
316- }
317-
318- // 2) Upload bytes to the pre-signed URL with PUT
319- putReq , err := http .NewRequestWithContext (ctx , http .MethodPut , getURLRes .UploadURL , bytes .NewReader (contentBytes ))
320- if err != nil {
321- return nil , err
322- }
323- putReq .Header .Set ("Content-Type" , "text/plain" )
324- putReq .Header .Set ("Content-Length" , strconv .Itoa (length ))
325- putResp , err := httpDo (putReq )
326- if err != nil {
327- return nil , err
328- }
329- defer putResp .Body .Close ()
330- if putResp .StatusCode < 200 || putResp .StatusCode >= 300 {
331- b , _ := io .ReadAll (putResp .Body )
332- return nil , fmt .Errorf ("upload to upload_url failed: status=%d body=%s" , putResp .StatusCode , string (b ))
333- }
334-
335- // 3) Complete upload to share into the channel
336- completeBody := struct {
337- ChannelID string `json:"channel_id"`
338- Files []struct {
339- ID string `json:"id"`
340- Title string `json:"title"`
341- } `json:"files"`
342- }{
343- ChannelID : s .channel ,
344- Files : []struct {
345- ID string `json:"id"`
346- Title string `json:"title"`
347- }{{ID : getURLRes .FileID , Title : title + ".txt" }},
348- }
349-
350- bodyBytes , err := json .Marshal (completeBody )
351- if err != nil {
352- return nil , err
353- }
354-
355- completeReq , err := http .NewRequestWithContext (ctx , http .MethodPost , "https://slack.com/api/files.completeUploadExternal" , bytes .NewReader (bodyBytes ))
356- if err != nil {
357- return nil , err
358- }
359- completeReq .Header .Set ("Authorization" , "Bearer " + token )
360- completeReq .Header .Set ("Content-Type" , "application/json" )
361-
362- completeResp , err := httpDo (completeReq )
363- if err != nil {
364- return nil , err
365- }
366- defer completeResp .Body .Close ()
367- if completeResp .StatusCode < 200 || completeResp .StatusCode >= 300 {
368- b , _ := io .ReadAll (completeResp .Body )
369- return nil , fmt .Errorf ("files.completeUploadExternal failed: status=%d body=%s" , completeResp .StatusCode , string (b ))
370- }
371-
372- var completeRes struct {
373- OK bool `json:"ok"`
374- Files []slackapi.File `json:"files"`
375- Error string `json:"error"`
376- }
377- if err := json .NewDecoder (completeResp .Body ).Decode (& completeRes ); err != nil {
378- return nil , err
379- }
380- if ! completeRes .OK {
381- return nil , fmt .Errorf ("files.completeUploadExternal error: %s" , completeRes .Error )
382- }
383- if len (completeRes .Files ) == 0 {
384- return nil , fmt .Errorf ("files.completeUploadExternal returned no files" )
262+ klog .Errorf ("File uploadLog failed %s\n " , err )
263+ return
385264 }
386265
387- klog .Infof ("File uploadLog successfully %s" , completeRes . Files [ 0 ] .Name )
388- return & completeRes . Files [ 0 ], nil
266+ klog .Infof ("File uploadLog successfully %s" , file .Name )
267+ return
389268}
390269
391270func isNotifyFromEnv (key string ) bool {
0 commit comments