mirror of
https://github.com/adnanh/webhook.git
synced 2025-06-04 11:42:29 +00:00
Allow hooks file to be parsed as a template
Add a -template command line option that instructs webhook to parse the hooks files as Go text templates. Includes a `getenv` template func for retrieving environment variables.
This commit is contained in:
parent
ba0adb117a
commit
f5f04ddaa2
5 changed files with 157 additions and 11 deletions
31
hook/hook.go
31
hook/hook.go
|
@ -1,6 +1,7 @@
|
|||
package hook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
|
@ -18,6 +19,7 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
@ -544,8 +546,10 @@ func (h *Hook) ExtractCommandArgumentsForFile(headers, query, payload *map[strin
|
|||
// Hooks is an array of Hook objects
|
||||
type Hooks []Hook
|
||||
|
||||
// LoadFromFile attempts to load hooks from specified JSON file
|
||||
func (h *Hooks) LoadFromFile(path string) error {
|
||||
// LoadFromFile attempts to load hooks from the specified file, which
|
||||
// can be either JSON or YAML. The asTemplate parameter causes the file
|
||||
// contents to be parsed as a Go text/template prior to unmarshalling.
|
||||
func (h *Hooks) LoadFromFile(path string, asTemplate bool) error {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
|
@ -557,6 +561,24 @@ func (h *Hooks) LoadFromFile(path string) error {
|
|||
return e
|
||||
}
|
||||
|
||||
if asTemplate {
|
||||
funcMap := template.FuncMap{"getenv": getenv}
|
||||
|
||||
tmpl, err := template.New("hooks").Funcs(funcMap).Parse(string(file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
err = tmpl.Execute(&buf, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file = buf.Bytes()
|
||||
}
|
||||
|
||||
e = yaml.Unmarshal(file, h)
|
||||
return e
|
||||
}
|
||||
|
@ -705,3 +727,8 @@ func (r MatchRule) Evaluate(headers, query, payload *map[string]interface{}, bod
|
|||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// getenv provides a template function to retrieve OS environment variables.
|
||||
func getenv(s string) string {
|
||||
return os.Getenv(s)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package hook
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -229,26 +230,55 @@ func TestHookExtractCommandArgumentsForEnv(t *testing.T) {
|
|||
}
|
||||
|
||||
var hooksLoadFromFileTests = []struct {
|
||||
path string
|
||||
ok bool
|
||||
path string
|
||||
asTemplate bool
|
||||
ok bool
|
||||
}{
|
||||
{"../hooks.json.example", true},
|
||||
{"../hooks.yaml.example", true},
|
||||
{"", true},
|
||||
{"../hooks.json.example", false, true},
|
||||
{"../hooks.yaml.example", false, true},
|
||||
{"../hooks.json.tmpl.example", true, true},
|
||||
{"../hooks.yaml.tmpl.example", true, true},
|
||||
{"", false, true},
|
||||
// failures
|
||||
{"missing.json", false},
|
||||
{"missing.json", false, false},
|
||||
}
|
||||
|
||||
func TestHooksLoadFromFile(t *testing.T) {
|
||||
secret := `foo"123`
|
||||
os.Setenv("XXXTEST_SECRET", secret)
|
||||
|
||||
for _, tt := range hooksLoadFromFileTests {
|
||||
h := &Hooks{}
|
||||
err := h.LoadFromFile(tt.path)
|
||||
err := h.LoadFromFile(tt.path, tt.asTemplate)
|
||||
if (err == nil) != tt.ok {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHooksTemplateLoadFromFile(t *testing.T) {
|
||||
secret := `foo"123`
|
||||
os.Setenv("XXXTEST_SECRET", secret)
|
||||
|
||||
for _, tt := range hooksLoadFromFileTests {
|
||||
if !tt.asTemplate {
|
||||
continue
|
||||
}
|
||||
|
||||
h := &Hooks{}
|
||||
err := h.LoadFromFile(tt.path, tt.asTemplate)
|
||||
if (err == nil) != tt.ok {
|
||||
t.Errorf(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
s := (*h.Match("webhook").TriggerRule.And)[0].Match.Secret
|
||||
if s != secret {
|
||||
t.Errorf("Expected secret of %q, got %q", secret, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var hooksMatchTests = []struct {
|
||||
id string
|
||||
hooks Hooks
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue