forked from sensu/sensu-go
/
handler.go
184 lines (152 loc) · 4.57 KB
/
handler.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package v2
import (
"errors"
fmt "fmt"
"net/url"
"path"
"sort"
"strings"
)
const (
// HandlersResource is the name of this resource type
HandlersResource = "handlers"
// HandlerPipeType represents handlers that pipes event data // into arbitrary
// commands via STDIN
HandlerPipeType = "pipe"
// HandlerSetType represents handlers that groups event handlers, making it
// easy to manage groups of actions that should be executed for certain types
// of events.
HandlerSetType = "set"
// HandlerTCPType represents handlers that send event data to a remote TCP
// socket
HandlerTCPType = "tcp"
// HandlerUDPType represents handlers that send event data to a remote UDP
// socket
HandlerUDPType = "udp"
// HandlerGRPCType is a special kind of handler that represents an extension
HandlerGRPCType = "grpc"
)
// StorePrefix returns the path prefix to this resource in the store
func (h *Handler) StorePrefix() string {
return HandlersResource
}
// URIPath returns the path component of a handler URI.
func (h *Handler) URIPath() string {
return path.Join(URLPrefix, "namespaces", url.PathEscape(h.Namespace), HandlersResource, url.PathEscape(h.Name))
}
// Validate returns an error if the handler does not pass validation tests.
func (h *Handler) Validate() error {
if err := ValidateName(h.Name); err != nil {
return errors.New("handler name " + err.Error())
}
if err := h.validateType(); err != nil {
return err
}
if h.Namespace == "" {
return errors.New("namespace must be set")
}
return nil
}
func (h *Handler) validateType() error {
if h.Type == "" {
return errors.New("empty handler type")
}
switch h.Type {
case "pipe", "set", "grpc":
return nil
case "tcp", "udp":
return h.Socket.Validate()
}
return fmt.Errorf("unknown handler type: %s", h.Type)
}
// Validate returns an error if the handler socket does not pass validation tests.
func (s *HandlerSocket) Validate() error {
if s == nil {
return errors.New("tcp and udp handlers need a valid socket")
}
if len(s.Host) == 0 {
return errors.New("socket host undefined")
}
if s.Port == 0 {
return errors.New("socket port undefined")
}
return nil
}
// NewHandler creates a new Handler.
func NewHandler(meta ObjectMeta) *Handler {
return &Handler{ObjectMeta: meta}
}
//
// Sorting
type cmpHandler func(a, b *Handler) bool
// SortHandlersByPredicate is used to sort a given collection using a given predicate.
func SortHandlersByPredicate(hs []*Handler, fn cmpHandler) sort.Interface {
return &handlerSorter{handlers: hs, byFn: fn}
}
// SortHandlersByName is used to sort a given collection of handlers by their names.
func SortHandlersByName(hs []*Handler, asc bool) sort.Interface {
if asc {
return SortHandlersByPredicate(hs, func(a, b *Handler) bool {
return a.Name < b.Name
})
}
return SortHandlersByPredicate(hs, func(a, b *Handler) bool {
return a.Name > b.Name
})
}
type handlerSorter struct {
handlers []*Handler
byFn cmpHandler
}
// Len implements sort.Interface
func (s *handlerSorter) Len() int {
return len(s.handlers)
}
// Swap implements sort.Interface
func (s *handlerSorter) Swap(i, j int) {
s.handlers[i], s.handlers[j] = s.handlers[j], s.handlers[i]
}
// Less implements sort.Interface
func (s *handlerSorter) Less(i, j int) bool {
return s.byFn(s.handlers[i], s.handlers[j])
}
// FixtureHandler returns a Handler fixture for testing.
func FixtureHandler(name string) *Handler {
return &Handler{
Type: HandlerPipeType,
Command: "command",
ObjectMeta: NewObjectMeta(name, "default"),
}
}
// FixtureSocketHandler returns a Handler fixture for testing.
func FixtureSocketHandler(name string, proto string) *Handler {
handler := FixtureHandler(name)
handler.Type = proto
handler.Socket = &HandlerSocket{
Host: "127.0.0.1",
Port: 3001,
}
return handler
}
// FixtureSetHandler returns a Handler fixture for testing.
func FixtureSetHandler(name string, handlers ...string) *Handler {
handler := FixtureHandler(name)
handler.Handlers = handlers
return handler
}
// HandlerFields returns a set of fields that represent that resource
func HandlerFields(r Resource) map[string]string {
resource := r.(*Handler)
return map[string]string{
"handler.name": resource.ObjectMeta.Name,
"handler.namespace": resource.ObjectMeta.Namespace,
"handler.filters": strings.Join(resource.Filters, ","),
"handler.handlers": strings.Join(resource.Handlers, ","),
"handler.mutator": resource.Mutator,
"handler.type": resource.Type,
}
}
// SetNamespace sets the namespace of the resource.
func (h *Handler) SetNamespace(namespace string) {
h.Namespace = namespace
}