From b847345308c5ddd92d02f0a907c7841e127bc32b Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Sat, 6 Jul 2019 18:02:45 +0300 Subject: [PATCH] Add 5 seconds timeout to notifier --- Makefile | 1 - cmd/flagger/main.go | 38 +++++++++++++++++++++--------------- pkg/notifier/client.go | 43 +++++++++++++++++++++++++++++++++++++++++ pkg/notifier/factory.go | 10 +++------- pkg/notifier/slack.go | 21 ++------------------ pkg/notifier/teams.go | 21 ++------------------ 6 files changed, 72 insertions(+), 62 deletions(-) create mode 100644 pkg/notifier/client.go diff --git a/Makefile b/Makefile index 398e13b6..fbca7d9c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ TS=$(shell date +%Y-%m-%d_%H-%M-%S) run: GO111MODULE=on go run cmd/flagger/* -kubeconfig=$$HOME/.kube/config -log-level=info -mesh-provider=istio -namespace=test \ - -msteams-url=https://outlook.office.com/webhook/3ec1691c-c86d-41f7-af77-fb198f1e449c@512d0320-35b0-485e-8f12-39f8e36a7325/IncomingWebhook/f89b33444d3b4b17bb0c9f677bceb361/4a76478d-c25c-4200-9153-dcb9af901b75 \ -metrics-server=https://prometheus.istio.weavedx.com run-appmesh: diff --git a/cmd/flagger/main.go b/cmd/flagger/main.go index e0b3ecfc..f7a308d0 100644 --- a/cmd/flagger/main.go +++ b/cmd/flagger/main.go @@ -161,22 +161,7 @@ func main() { } // setup Slack or MS Teams notifications - notifierURL := slackURL - if msteamsURL != "" { - notifierURL = msteamsURL - } - notifierFactory := notifier.NewFactory(notifierURL, slackUser, slackChannel) - - var notifierClient notifier.Interface - if notifierURL != "" { - var err error - notifierClient, err = notifierFactory.Notifier() - if err != nil { - logger.Errorf("Notifier %v", err) - } else { - logger.Infof("Notifications enabled for %s", notifierURL[0:30]) - } - } + notifierClient := initNotifier(logger) // start HTTP server go server.ListenAndServe(port, 3*time.Second, logger, stopCh) @@ -218,3 +203,24 @@ func main() { <-stopCh } + +func initNotifier(logger *zap.SugaredLogger) (client notifier.Interface) { + provider := "slack" + notifierURL := slackURL + if msteamsURL != "" { + provider = "msteams" + notifierURL = msteamsURL + } + notifierFactory := notifier.NewFactory(notifierURL, slackUser, slackChannel) + + if notifierURL != "" { + var err error + client, err = notifierFactory.Notifier(provider) + if err != nil { + logger.Errorf("Notifier %v", err) + } else { + logger.Infof("Notifications enabled for %s", notifierURL[0:30]) + } + } + return +} diff --git a/pkg/notifier/client.go b/pkg/notifier/client.go new file mode 100644 index 00000000..72d0b1bd --- /dev/null +++ b/pkg/notifier/client.go @@ -0,0 +1,43 @@ +package notifier + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" +) + +func postMessage(address string, payload interface{}) error { + data, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("marshalling notification payload failed %v", err) + } + + b := bytes.NewBuffer(data) + + req, err := http.NewRequest("POST", address, b) + if err != nil { + return err + } + req.Header.Set("Content-type", "application/json") + + ctx, cancel := context.WithTimeout(req.Context(), 5*time.Second) + defer cancel() + + res, err := http.DefaultClient.Do(req.WithContext(ctx)) + if err != nil { + return fmt.Errorf("sending notification failed %v", err) + } + + defer res.Body.Close() + statusCode := res.StatusCode + if statusCode != 200 { + body, _ := ioutil.ReadAll(res.Body) + return fmt.Errorf("sending notification failed %v", string(body)) + } + + return nil +} diff --git a/pkg/notifier/factory.go b/pkg/notifier/factory.go index 54716973..d7ef2ec1 100644 --- a/pkg/notifier/factory.go +++ b/pkg/notifier/factory.go @@ -1,9 +1,5 @@ package notifier -import ( - "strings" -) - type Factory struct { URL string Username string @@ -18,11 +14,11 @@ func NewFactory(URL string, username string, channel string) *Factory { } } -func (f Factory) Notifier() (Interface, error) { +func (f Factory) Notifier(provider string) (Interface, error) { switch { - case strings.Contains(f.URL, "slack.com"): + case provider == "slack": return NewSlack(f.URL, f.Username, f.Channel) - case strings.Contains(f.URL, "office.com"): + case provider == "msteams": return NewMSTeams(f.URL) } diff --git a/pkg/notifier/slack.go b/pkg/notifier/slack.go index 8f247fbb..1ca4f9d2 100644 --- a/pkg/notifier/slack.go +++ b/pkg/notifier/slack.go @@ -1,12 +1,8 @@ package notifier import ( - "bytes" - "encoding/json" "errors" "fmt" - "io/ioutil" - "net/http" "net/url" ) @@ -93,22 +89,9 @@ func (s *Slack) Post(workload string, namespace string, message string, fields [ payload.Attachments = []SlackAttachment{a} - data, err := json.Marshal(payload) + err := postMessage(s.URL, payload) if err != nil { - return fmt.Errorf("marshalling slack payload failed %v", err) - } - - b := bytes.NewBuffer(data) - - if res, err := http.Post(s.URL, "application/json", b); err != nil { - return fmt.Errorf("sending data to slack failed %v", err) - } else { - defer res.Body.Close() - statusCode := res.StatusCode - if statusCode != 200 { - body, _ := ioutil.ReadAll(res.Body) - return fmt.Errorf("sending data to slack failed %v", string(body)) - } + return err } return nil diff --git a/pkg/notifier/teams.go b/pkg/notifier/teams.go index 8545837e..e463b908 100644 --- a/pkg/notifier/teams.go +++ b/pkg/notifier/teams.go @@ -1,11 +1,7 @@ package notifier import ( - "bytes" - "encoding/json" "fmt" - "io/ioutil" - "net/http" "net/url" ) @@ -72,22 +68,9 @@ func (s *MSTeams) Post(workload string, namespace string, message string, fields payload.ThemeColor = "FF0000" } - data, err := json.Marshal(payload) + err := postMessage(s.URL, payload) if err != nil { - return fmt.Errorf("marshalling slack payload failed %v", err) - } - - b := bytes.NewBuffer(data) - - if res, err := http.Post(s.URL, "application/json", b); err != nil { - return fmt.Errorf("sending data to MS Teams failed %v", err) - } else { - defer res.Body.Close() - statusCode := res.StatusCode - if statusCode != 200 { - body, _ := ioutil.ReadAll(res.Body) - return fmt.Errorf("sending data to MS Teams failed %v", string(body)) - } + return err } return nil