-
Notifications
You must be signed in to change notification settings - Fork 0
/
rule.go
125 lines (95 loc) · 2.82 KB
/
rule.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package captainhook
import (
"bytes"
"errors"
"fmt"
"github.com/Masterminds/sprig"
"github.com/lukemgriffith/captainhook/util"
"html/template"
"io"
)
// Contains rule state, is assigned a function based on type.
// Type mapped by AssignFunction.
type Rule struct {
Type string `yaml:type`
Destination string `yaml:destination`
Arguments map[string]string `yaml:arguments`
Secrets []string `yaml:secrets`
Headers map[string]string `yaml:headers`
Echo bool `yaml:echo`
function func(iw io.Writer, dataMap map[string]interface{}, r *Rule) error
}
// Executes the function poitner associated to the rule.
func (r *Rule) Execute(iw io.Writer, dataMap map[string]interface{}) error {
if r.function == nil {
return errors.New("No function pointer assigned.")
}
return r.function(iw, dataMap, r)
}
// Sets the function pointer of the rule.
func (r *Rule) SetFunction(f func(iw io.Writer, dataMap map[string]interface{}, r *Rule) error) error {
if r.function != nil {
return errors.New("Function already exists.")
}
r.function = f
return nil
}
// TODO make this mapping more configurable./find out if there's a better way to do this.
// Maps the function to the rule type.
func AssignFunction(rule *Rule) {
switch t := rule.Type; t {
case "template":
rule.SetFunction(TemplateFunc)
case "display":
rule.SetFunction(DisplayFunc)
default:
rule.SetFunction(NoOp)
}
}
// Checks the rule arguments map for value and returns it or error.
func (rule Rule) GetArg(name string) (string, error) {
val, ok := rule.Arguments[name]
if !ok {
return "", errors.New(fmt.Sprintf("Unable to find argument %s", name))
}
return val, nil
}
// RULE FUNCTIONS.
// Rules are passed a io.Writer, what wil be used in the POST request to downstream services.
// dataMaps are arguments of the executing rule, passed in from the configuration or input.
// secrets map is passed in.
// NoOp, do nothing.
func NoOp(iw io.Writer, dataMap map[string]interface{}, rule *Rule) error {
return nil
}
// Uses go templating to create a new json string from the input recieved.
func TemplateFunc(iw io.Writer, dataMap map[string]interface{}, rule *Rule) error {
tmplStr, err := rule.GetArg("template")
if err != nil {
return err
}
tmpl, err := template.New("tmpl").Funcs(sprig.FuncMap()).Parse(tmplStr)
if err != nil {
return err
}
buf := make([]byte, 0, 1)
var tpl *bytes.Buffer = bytes.NewBuffer(buf)
err = tmpl.Execute(tpl, dataMap)
if err != nil {
return err
}
_, err = iw.Write(tpl.Bytes())
if err != nil {
return err
}
return nil
}
func DisplayFunc(iw io.Writer, dataMap map[string]interface{}, rule *Rule) error {
err := TemplateFunc(iw, dataMap, rule)
if err != nil {
return err
}
displayLog := util.NewLog(rule.Type)
displayLog.Println(iw)
return nil
}