From 53f8e310e3b4c3ba77b13fc1ffe0b130302e98d9 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 17:51:50 -0600 Subject: [PATCH 01/17] adding auth and some updates --- main.go | 71 +++++++++++++++++++++++++++++++++++++++++------------- webhook.go | 16 ++++++++++++ 2 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 webhook.go diff --git a/main.go b/main.go index 13bb380..6720bfe 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" "net/http" "net/url" "os" @@ -14,26 +15,22 @@ import ( ) func main() { + + // plugin settings var repo = drone.Repo{} var build = drone.Build{} - var vargs = struct { - Urls []string `json:"urls"` - Headers map[string]string `json:"header"` - Method string `json:"method"` - Template string `json:"template"` - ContentType string `json:"content_type"` - }{} + var vargs = Webhook{} + // set plugin parameters plugin.Param("repo", &repo) plugin.Param("build", &build) plugin.Param("vargs", &vargs) - plugin.Parse() - // data structure - data := struct { - Repo drone.Repo `json:"repo"` - Build drone.Build `json:"build"` - }{repo, build} + // parse the parameters + if err := plugin.Parse(); err != nil { + fmt.Println(err) + os.Exit(1) + } // set default values if len(vargs.Method) == 0 { @@ -43,19 +40,26 @@ func main() { vargs.ContentType = "application/json" } + // data structure + data := struct { + Repo drone.Repo `json:"repo"` + Build drone.Build `json:"build"` + }{repo, build} + // creates the payload. by default the payload // is the build details in json format, but a custom // template may also be used. var buf bytes.Buffer if len(vargs.Template) == 0 { json.NewEncoder(&buf).Encode(&data) - } else { + t, err := template.New("_").Parse(vargs.Template) if err != nil { fmt.Printf("Error parsing content template. %s\n", err) os.Exit(1) } + t.Execute(&buf, &data) if err != nil { fmt.Printf("Error executing content template. %s\n", err) @@ -63,8 +67,11 @@ func main() { } } - // post payload to each url - for _, rawurl := range vargs.Urls { + // build and execute a request for each url. + // all auth, headers, method, template (payload), + // and content_type values will be applied to + // every webhook request. + for i, rawurl := range vargs.Urls { uri, err := url.Parse(rawurl) if err != nil { @@ -72,21 +79,51 @@ func main() { os.Exit(1) } + // vargs.Method defaults to POST, no need to check req, err := http.NewRequest(vargs.Method, uri.String(), &buf) if err != nil { fmt.Printf("Error creating http request. %s\n", err) os.Exit(1) } + + // vargs.ContentType defaults to application/json, no need to check req.Header.Set("Content-Type", vargs.ContentType) for key, value := range vargs.Headers { req.Header.Set(key, value) } + // set basic auth if a user or user and pass is provided + if len(vargs.Auth.Username) > 0 { + if len(vargs.Auth.Password) > 0 { + req.SetBasicAuth(vargs.Auth.Username, vargs.Auth.Password) + } else { + req.SetBasicAuth(vargs.Auth.Username, "") + } + } + resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Printf("Error executing http request. %s\n", err) os.Exit(1) } - resp.Body.Close() + defer resp.Body.Close() + + if vargs.Verbose { + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + // I do not think we need to os.Exit(1) if we are + // unable to read a http response body. + fmt.Printf("Error reading http response body. %s\n", err) + } + + // scrub out basic auth pass + if len(vargs.Auth.Password) > 0 { + req.SetBasicAuth(vargs.Auth.Username, "XXXXX") + } + + // print out + fmt.Printf("%d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s", i+1, req.URL, req.Method, req.Header, req.Body, resp.Status, string(body)) + } } } diff --git a/webhook.go b/webhook.go new file mode 100644 index 0000000..01f8ef0 --- /dev/null +++ b/webhook.go @@ -0,0 +1,16 @@ +package main + +type Webhook struct { + Urls []string `json:"urls"` + Verbose bool `json:"verbose"` + Auth BasicAuth `json:"auth"` + Headers map[string]string `json:"header"` + Method string `json:"method"` + Template string `json:"template"` + ContentType string `json:"content_type"` +} + +type BasicAuth struct { + Username string `json:"username"` + Password string `json:"password"` +} From 8086777e789245d8ac693f127ade7d204dc8baad Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 18:38:29 -0600 Subject: [PATCH 02/17] drone kickoff --- .drone.sec | 2 +- .drone.yml | 6 +++--- Dockerfile | 2 +- _.drone.sec | 1 + main.go | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 _.drone.sec diff --git a/.drone.sec b/.drone.sec index 3e37d3c..a300198 100644 --- a/.drone.sec +++ b/.drone.sec @@ -1 +1 @@ -eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ \ No newline at end of file +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.g60efJ7H--6u_vYyzosC_IOrWV9vMkMBqP8IowJ5q76e2s-R2h6Pd95bBkCy8-vlfL9Tj1znSCWGirL7JdkleN20uu1Nyk2_VXWdurATPAdze_uNCHj-lwbMRZlQmjmPq3avmaSYA-eKT5ABVUJv0tcu4rZcQL6fVixn8_2Q3ITxBlAxjRtB5ptnAlyNOenVej4WD5O5MOwJa0IYmHt0TEMIl8iPhzO9LjXcf6LrMExt4qROLCBzL0845FDUpjqicY-oPoqDgEJ7LBk8Qblmx5431OffhqD4jcXA0ogR8ouuwMR29HCVLKFSi_gzKo7zFz0xE-O4qk-EteKbRnjbqg.aQo0sF1JMMFYfoXg.mSfnDRfIl5MjlQQETHB7niU3ry1gfrehrCZxbV529PG5XwK_WPmrdTEx3u1MqESM2z-YPe6sGPiA-DKmGsU6WmM-G_y6bIVisfdXRQ.EW3XPMHWMPqfy9tV2VK1Mw diff --git a/.drone.yml b/.drone.yml index c7ba612..2c76b92 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,10 +12,10 @@ build: publish: docker: - username: drone + username: jackspirou password: $$DOCKER_PASS email: $$DOCKER_EMAIL - repo: plugins/drone-webhook + repo: jackspirou/drone-webhook when: branch: master @@ -23,7 +23,7 @@ plugin: name: Webhook desc: Send webhook notifications when your build completes. type: notify - image: plugins/drone-webhook + image: jackspirou/drone-webhook labels: - rest - json diff --git a/Dockerfile b/Dockerfile index 5ce7091..e1fb93b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # CGO_ENABLED=0 go build -a -tags netgo # docker build --rm=true -t plugins/drone-webhook . -FROM gliderlabs/alpine:3.1 +FROM gliderlabs/alpine:3.2 RUN apk-install ca-certificates ADD drone-webhook /bin/ ENTRYPOINT ["/bin/drone-webhook"] diff --git a/_.drone.sec b/_.drone.sec new file mode 100644 index 0000000..3e37d3c --- /dev/null +++ b/_.drone.sec @@ -0,0 +1 @@ +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ \ No newline at end of file diff --git a/main.go b/main.go index 6720bfe..2c3c469 100644 --- a/main.go +++ b/main.go @@ -108,7 +108,7 @@ func main() { } defer resp.Body.Close() - if vargs.Verbose { + if vargs.Verbose || os.Getenv("DEBUG") == "true" { body, err := ioutil.ReadAll(resp.Body) if err != nil { From f8261dbb59a84ef971f661161643bc0a07b5285e Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 18:48:16 -0600 Subject: [PATCH 03/17] updating print --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 2c3c469..a840a57 100644 --- a/main.go +++ b/main.go @@ -123,7 +123,7 @@ func main() { } // print out - fmt.Printf("%d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s", i+1, req.URL, req.Method, req.Header, req.Body, resp.Status, string(body)) + fmt.Printf("%d URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s", i+1, req.URL, req.Method, req.Header, req.Body, resp.Status, string(body)) } } } From e155afd9630c8cb706f32f5ceec10e9b901ab9e6 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:06:27 -0600 Subject: [PATCH 04/17] saving request bytes for debug print --- main.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index a840a57..bebb9b9 100644 --- a/main.go +++ b/main.go @@ -49,9 +49,13 @@ func main() { // creates the payload. by default the payload // is the build details in json format, but a custom // template may also be used. - var buf bytes.Buffer + var buf *bytes.Buffer + var reqBytes []byte if len(vargs.Template) == 0 { - json.NewEncoder(&buf).Encode(&data) + json.NewEncoder(buf).Encode(&data) + b := buf.Bytes() + buf = bytes.NewBuffer(b) + reqBytes = b } else { t, err := template.New("_").Parse(vargs.Template) @@ -60,11 +64,14 @@ func main() { os.Exit(1) } - t.Execute(&buf, &data) + t.Execute(buf, &data) if err != nil { fmt.Printf("Error executing content template. %s\n", err) os.Exit(1) } + b := buf.Bytes() + buf = bytes.NewBuffer(b) + reqBytes = b } // build and execute a request for each url. @@ -80,7 +87,7 @@ func main() { } // vargs.Method defaults to POST, no need to check - req, err := http.NewRequest(vargs.Method, uri.String(), &buf) + req, err := http.NewRequest(vargs.Method, uri.String(), buf) if err != nil { fmt.Printf("Error creating http request. %s\n", err) os.Exit(1) @@ -118,12 +125,14 @@ func main() { } // scrub out basic auth pass - if len(vargs.Auth.Password) > 0 { - req.SetBasicAuth(vargs.Auth.Username, "XXXXX") - } + /* + if len(vargs.Auth.Password) > 0 { + req.SetBasicAuth(vargs.Auth.Username, "XXXXX") + } + */ // print out - fmt.Printf("%d URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s", i+1, req.URL, req.Method, req.Header, req.Body, resp.Status, string(body)) + fmt.Printf("Webhook URL %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s\n", i+1, req.URL, req.Method, req.Header, string(reqBytes), resp.Status, string(body)) } } } From 5a516ac3f7185adc62c1ff44689e76b54e645205 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:10:08 -0600 Subject: [PATCH 05/17] catching template execute error --- main.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.go b/main.go index bebb9b9..67e7e96 100644 --- a/main.go +++ b/main.go @@ -64,8 +64,7 @@ func main() { os.Exit(1) } - t.Execute(buf, &data) - if err != nil { + if err := t.Execute(buf, &data); err != nil { fmt.Printf("Error executing content template. %s\n", err) os.Exit(1) } From 5a591e800a3372a39a07464a6c1b2cc27687e888 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:16:28 -0600 Subject: [PATCH 06/17] fixing nil pointer reference --- main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 67e7e96..a974fff 100644 --- a/main.go +++ b/main.go @@ -52,8 +52,9 @@ func main() { var buf *bytes.Buffer var reqBytes []byte if len(vargs.Template) == 0 { - json.NewEncoder(buf).Encode(&data) - b := buf.Bytes() + var t bytes.Buffer + json.NewEncoder(&t).Encode(&data) + b := t.Bytes() buf = bytes.NewBuffer(b) reqBytes = b } else { From 099c8ee9aae0929cdfbf3cb6b643fbc3dd3a2ac2 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:29:09 -0600 Subject: [PATCH 07/17] trying a better way to preserve the req body bytes --- main.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index a974fff..0218a19 100644 --- a/main.go +++ b/main.go @@ -49,14 +49,12 @@ func main() { // creates the payload. by default the payload // is the build details in json format, but a custom // template may also be used. - var buf *bytes.Buffer - var reqBytes []byte + var buf bytes.Buffer if len(vargs.Template) == 0 { - var t bytes.Buffer - json.NewEncoder(&t).Encode(&data) - b := t.Bytes() - buf = bytes.NewBuffer(b) - reqBytes = b + if err := json.NewEncoder(&buf).Encode(&data); err != nil { + fmt.Printf("Error encoding content template. %s\n", err) + os.Exit(1) + } } else { t, err := template.New("_").Parse(vargs.Template) @@ -65,13 +63,10 @@ func main() { os.Exit(1) } - if err := t.Execute(buf, &data); err != nil { + if err := t.Execute(&buf, &data); err != nil { fmt.Printf("Error executing content template. %s\n", err) os.Exit(1) } - b := buf.Bytes() - buf = bytes.NewBuffer(b) - reqBytes = b } // build and execute a request for each url. @@ -87,7 +82,9 @@ func main() { } // vargs.Method defaults to POST, no need to check - req, err := http.NewRequest(vargs.Method, uri.String(), buf) + b := buf.Bytes() + r := bytes.NewReader(b) + req, err := http.NewRequest(vargs.Method, uri.String(), r) if err != nil { fmt.Printf("Error creating http request. %s\n", err) os.Exit(1) @@ -132,7 +129,7 @@ func main() { */ // print out - fmt.Printf("Webhook URL %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s\n", i+1, req.URL, req.Method, req.Header, string(reqBytes), resp.Status, string(body)) + fmt.Printf("Webhook URL %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) } } } From d9380902f27ae8ca9c5b9c4904256b27438f291b Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:39:05 -0600 Subject: [PATCH 08/17] making the debug print pretty --- main.go | 13 +++---------- webhook.go | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 0218a19..03e5688 100644 --- a/main.go +++ b/main.go @@ -112,7 +112,7 @@ func main() { } defer resp.Body.Close() - if vargs.Verbose || os.Getenv("DEBUG") == "true" { + if vargs.Debug || os.Getenv("DEBUG") == "true" { body, err := ioutil.ReadAll(resp.Body) if err != nil { @@ -121,15 +121,8 @@ func main() { fmt.Printf("Error reading http response body. %s\n", err) } - // scrub out basic auth pass - /* - if len(vargs.Auth.Password) > 0 { - req.SetBasicAuth(vargs.Auth.Username, "XXXXX") - } - */ - - // print out - fmt.Printf("Webhook URL %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n BODY: %s\n RESPONSE STATUS: %s\n RESPONSE: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) + // debug print + fmt.Printf("[debug] Webhook %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n REQUEST BODY: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) } } } diff --git a/webhook.go b/webhook.go index 01f8ef0..80ffb2c 100644 --- a/webhook.go +++ b/webhook.go @@ -2,7 +2,7 @@ package main type Webhook struct { Urls []string `json:"urls"` - Verbose bool `json:"verbose"` + Debug bool `json:"debug"` Auth BasicAuth `json:"auth"` Headers map[string]string `json:"header"` Method string `json:"method"` From baf99f7c9e689c0874b339b980dba7dbe68c0aed Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:42:41 -0600 Subject: [PATCH 09/17] testing basic auth --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 03e5688..c626aad 100644 --- a/main.go +++ b/main.go @@ -98,6 +98,7 @@ func main() { // set basic auth if a user or user and pass is provided if len(vargs.Auth.Username) > 0 { + fmt.Println("setting basic auth") if len(vargs.Auth.Password) > 0 { req.SetBasicAuth(vargs.Auth.Username, vargs.Auth.Password) } else { From 3bf814670c11242010724dd3ca4ab6f622888cef Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 19:47:12 -0600 Subject: [PATCH 10/17] debuggin debug --- main.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.go b/main.go index c626aad..4122b5d 100644 --- a/main.go +++ b/main.go @@ -113,6 +113,9 @@ func main() { } defer resp.Body.Close() + fmt.Println(vargs.Debug) + fmt.Println(os.Getenv("DEBUG")) + if vargs.Debug || os.Getenv("DEBUG") == "true" { body, err := ioutil.ReadAll(resp.Body) From c51804fc5cdfaeef3dc5d362fa067343cf68191b Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 20:27:36 -0600 Subject: [PATCH 11/17] moving print debug test to top of file --- main.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 4122b5d..69219ca 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,8 @@ import ( func main() { + fmt.Println(os.Getenv("DEBUG")) + // plugin settings var repo = drone.Repo{} var build = drone.Build{} @@ -98,7 +100,6 @@ func main() { // set basic auth if a user or user and pass is provided if len(vargs.Auth.Username) > 0 { - fmt.Println("setting basic auth") if len(vargs.Auth.Password) > 0 { req.SetBasicAuth(vargs.Auth.Username, vargs.Auth.Password) } else { @@ -113,9 +114,6 @@ func main() { } defer resp.Body.Close() - fmt.Println(vargs.Debug) - fmt.Println(os.Getenv("DEBUG")) - if vargs.Debug || os.Getenv("DEBUG") == "true" { body, err := ioutil.ReadAll(resp.Body) From 2c97549581b4970aab18eee8b8d4a9f4bf4f334f Mon Sep 17 00:00:00 2001 From: jackspirou Date: Fri, 20 Nov 2015 21:09:59 -0600 Subject: [PATCH 12/17] adding info on http error response --- main.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/main.go b/main.go index 69219ca..6764414 100644 --- a/main.go +++ b/main.go @@ -125,6 +125,17 @@ func main() { // debug print fmt.Printf("[debug] Webhook %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n REQUEST BODY: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) + + } else if resp.StatusCode >= http.StatusBadRequest { + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + // I do not think we need to os.Exit(1) if we are + // unable to read a http response body. + fmt.Printf("Error reading http response body. %s\n", err) + } + + fmt.Printf("[info] Webhook %d\n URL: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, resp.Status, string(body)) } } } From fdef8d879dfa419d4f1eef483186f4ab8cb030f2 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Sat, 21 Nov 2015 10:47:06 -0600 Subject: [PATCH 13/17] removing DEBUG env for now --- main.go | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index 6764414..070a3aa 100644 --- a/main.go +++ b/main.go @@ -16,8 +16,6 @@ import ( func main() { - fmt.Println(os.Getenv("DEBUG")) - // plugin settings var repo = drone.Repo{} var build = drone.Build{} @@ -114,8 +112,10 @@ func main() { } defer resp.Body.Close() - if vargs.Debug || os.Getenv("DEBUG") == "true" { + // if debug is on or response status code is bad + if vargs.Debug || resp.StatusCode >= http.StatusBadRequest { + // read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { // I do not think we need to os.Exit(1) if we are @@ -123,19 +123,12 @@ func main() { fmt.Printf("Error reading http response body. %s\n", err) } - // debug print - fmt.Printf("[debug] Webhook %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n REQUEST BODY: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) - - } else if resp.StatusCode >= http.StatusBadRequest { - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - // I do not think we need to os.Exit(1) if we are - // unable to read a http response body. - fmt.Printf("Error reading http response body. %s\n", err) + // debug/info print + if vargs.Debug { + fmt.Printf("[debug] Webhook %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n REQUEST BODY: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) + } else { + fmt.Printf("[info] Webhook %d\n URL: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, resp.Status, string(body)) } - - fmt.Printf("[info] Webhook %d\n URL: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, resp.Status, string(body)) } } } From d1c4e0a0d649909214eb23aeaa9a6ea0ef977f3c Mon Sep 17 00:00:00 2001 From: jackspirou Date: Sat, 21 Nov 2015 11:22:20 -0600 Subject: [PATCH 14/17] adding documentation on debug and auth --- DOCS.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/DOCS.md b/DOCS.md index 637bb2e..091990a 100644 --- a/DOCS.md +++ b/DOCS.md @@ -83,4 +83,77 @@ notify: repo: {{.Repo.FullName}} build: {{.Build.Number}} commit: {{.Build.Commit}} -``` \ No newline at end of file +``` + +## Basic Authentication + +>It is important to note that with HTTP Basic Authentication the provided username and password are not encrypted. + +In some cases your webhook may need to authenticate with another service. You can set the basic `Authentication` header with a username and password. For these use cases we expose the following additional parameters: + +* `auth` - Sets the request's `Authorization` header to use HTTP Basic Authentication with the provided username and password below. + * `username` - The username as a string. + * `password` - The password as a string. + +Example configuration to include HTTP Basic Authentication: + +```yaml +notify: + webhook: + method: POST + auth: + username: $$USERNAME + password: $$PASSWORD + urls: + - https://tower.example.com/... + content_type: application/yaml + template: > + repo: {{.Repo.FullName}} + build: {{.Build.Number}} + commit: {{.Build.Commit}} +``` + +## Debugging Webhooks + +>If you have private variables that are encrypted and hidden in `.drone.sec`, remember that the `debug` flag may print out those sensitive values. Please use `dubug: true` wisely. + +In some cases complicated webhooks may need debugging to ensure `urls`, `template`, `auth` and more a properly configured. For these use cases we expose the following `debug` parameter: + +* `debug` - If `debug: true` it will print out each URL request and response information. + +Example configuration to include the `debug` parameter: + +```yaml +notify: + webhook: + debug: true + method: POST + auth: + username: $$TOWER_USER + password: $$TOWER_PASS + urls: + - http://tower.example.com/api/v1/job_templates/44/launch/ + - http://tower.example.com/api/v1/job_templates/45/launch/ + content_type: application/json + template: '{"name": "project.deploy","extra_vars": "{\"env\": \"dev\",\"git_branch\": \"{{ .Build.Branch }}\",\"hipchat_token\": \"$$HIPCHAT_TOKEN\"}"}' +``` + +Example of a debug print result: + +```yaml +[debug] Webhook 1 + URL: http://tower.example.com/api/v1/job_templates/44/launch/ + METHOD: POST + HEADERS: map[Content-Type:[application/json] Authorization:[Basic EMfNB3fakB8EMfNB3fakB8==]] + REQUEST BODY: {"name": "project.deploy","extra_vars": "{\"env\": \"dev\",\"git_branch\": \"develop\",\"hipchat_token\": \"h1pchatT0k3n\"}"} + RESPONSE STATUS: 202 ACCEPTED + RESPONSE BODY: {"job": 236} + +[debug] Webhook 2 + URL: http://tower.example.com/api/v1/job_templates/45/launch/ + METHOD: POST + HEADERS: map[Content-Type:[application/json] Authorization:[Basic EMfNB3fakB8EMfNB3fakB8==]] + REQUEST BODY: {"name": "project.deploy","extra_vars": "{\"env\": \"dev\",\"git_branch\": \"develop\",\"hipchat_token\": \"h1pchatT0k3n\"}"} + RESPONSE STATUS: 202 ACCEPTED + RESPONSE BODY: {"job": 406} +``` From e0494aee411b97b351dba728a8b572e260cc75d0 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Sat, 21 Nov 2015 12:01:42 -0600 Subject: [PATCH 15/17] updating readme --- README.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 494fafc..afdd537 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # drone-webhook -Drone plugin for sending Webhook notifications by [@chromakode](https://github.com/chromakode). +Drone plugin for sending Webhook notifications. ## Overview @@ -25,7 +25,18 @@ This plugin is responsible for sending build notifications via Webhooks: "author_email": "john.smith@gmail.com" }, "vargs": { - "urls": [ "https://your.webhook/..." ] + "urls": ["https://your.webhook/..."], + "debug": true, + "auth": { + "username": "johnsmith", + "password": "secretPass" + }, + "headers": { + "SomeHeader": "SomeHeaderValue" + }, + "method": "POST", + "template": "{\"git_branch\": \"{{ .Build.Branch }}\"}", + "content_type": "application/json" } } EOF @@ -63,7 +74,18 @@ docker run -i plugins/drone-webhook < Date: Sat, 21 Nov 2015 12:04:52 -0600 Subject: [PATCH 16/17] setting drone yaml file back --- .drone.sec | 2 +- .drone.yml | 6 +++--- _.drone.sec | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 _.drone.sec diff --git a/.drone.sec b/.drone.sec index a300198..3e37d3c 100644 --- a/.drone.sec +++ b/.drone.sec @@ -1 +1 @@ -eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.g60efJ7H--6u_vYyzosC_IOrWV9vMkMBqP8IowJ5q76e2s-R2h6Pd95bBkCy8-vlfL9Tj1znSCWGirL7JdkleN20uu1Nyk2_VXWdurATPAdze_uNCHj-lwbMRZlQmjmPq3avmaSYA-eKT5ABVUJv0tcu4rZcQL6fVixn8_2Q3ITxBlAxjRtB5ptnAlyNOenVej4WD5O5MOwJa0IYmHt0TEMIl8iPhzO9LjXcf6LrMExt4qROLCBzL0845FDUpjqicY-oPoqDgEJ7LBk8Qblmx5431OffhqD4jcXA0ogR8ouuwMR29HCVLKFSi_gzKo7zFz0xE-O4qk-EteKbRnjbqg.aQo0sF1JMMFYfoXg.mSfnDRfIl5MjlQQETHB7niU3ry1gfrehrCZxbV529PG5XwK_WPmrdTEx3u1MqESM2z-YPe6sGPiA-DKmGsU6WmM-G_y6bIVisfdXRQ.EW3XPMHWMPqfy9tV2VK1Mw +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ \ No newline at end of file diff --git a/.drone.yml b/.drone.yml index 2c76b92..c7ba612 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,10 +12,10 @@ build: publish: docker: - username: jackspirou + username: drone password: $$DOCKER_PASS email: $$DOCKER_EMAIL - repo: jackspirou/drone-webhook + repo: plugins/drone-webhook when: branch: master @@ -23,7 +23,7 @@ plugin: name: Webhook desc: Send webhook notifications when your build completes. type: notify - image: jackspirou/drone-webhook + image: plugins/drone-webhook labels: - rest - json diff --git a/_.drone.sec b/_.drone.sec deleted file mode 100644 index 3e37d3c..0000000 --- a/_.drone.sec +++ /dev/null @@ -1 +0,0 @@ -eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ \ No newline at end of file From cc4b691ac534fca56d21f62f82f89ccc0ecd7646 Mon Sep 17 00:00:00 2001 From: jackspirou Date: Sat, 21 Nov 2015 12:07:03 -0600 Subject: [PATCH 17/17] sync on .drone.sec --- .drone.sec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.sec b/.drone.sec index 3e37d3c..0fdefce 100644 --- a/.drone.sec +++ b/.drone.sec @@ -1 +1 @@ -eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ \ No newline at end of file +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Hsd15sfwSET0yXg92mosT1cs-1kiyW7VZlSZiWKkIu4EKDWnslBPZzbTKVi9OY4lXKJmXuAo38E3wtj5EvD7GA5azd090-Rnv-VOrQfXNmjZd9jxc7861IWQOFZb9XEDQZF6X2JM8fK_psSs6mrew9BjuOx6ws68h-zTl8ttcjHZC3Y7SZ5AjYj5i4T-Z0hJpLk2kwjCYF3SH599R3L3kZxDi6IcO9qW_Lj6zcBT5SttLgikUpvHwY409pbFBohl-AVhCZuDuyJPDns4n7jjWj4sELH4w-8dbc5oijzxI1FoxnUhXTRsrwNgfgCBAFM_umXGXLHAQlb2QzH2JHtB6g.rednhhAPc9V-KExp.qf0pSc_4pCgKIgK5T03yEmWz1yF5u2S0lSDBAvu7yOeCl469QBRIOxCv_RHImCG4tjOwYZjNaS8gaKVIoNNtxhKxC04Y2G7pxYDgNh2pU-sJOi05A1BaIbdIC209uK0r-mKkX_hfMDtNNWuOCyHXju4ugbNHwH64KvLzy4_RfFa0n9AOhpS1xNT3aa_eJvj0RQCfFs10BckWJoGlIfbS6VMyeeHeQEX6QWFSauxUwUPOAvrRlNjtNSxxVvNr1CbJso_8Cl0frD8DELaWxu3uKvLkSm2_GVMjPbvmZIqvcVxpxYnFMjwngQOAqnmiI-n_3LlO-dZb-Gf5AwN2F61PQDKXkdOcNiM4bNU_V11VKHP_BCJpVcaL6detQLNzHIuyU93zbw.fkefbX3B_-97eQdiQcyCYQ