-
-
Notifications
You must be signed in to change notification settings - Fork 409
/
Copy pathtypes.go
366 lines (333 loc) · 10.9 KB
/
types.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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
//go:generate go run github.com/safchain/easyjson/easyjson $GOFILE
/*
* Copyright (C) 2018 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy ofthe License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specificlanguage governing permissions and
* limitations under the License.
*
*/
// Package types defines the API resource types
//
// swagger:meta
package types
import (
"errors"
"time"
"github.com/skydive-project/skydive/flow"
"github.com/skydive-project/skydive/graffiti/graph"
"github.com/skydive-project/skydive/topology"
)
var schemaValidator *topology.SchemaValidator
// Resource used as interface resources for each API
type Resource interface {
ID() string
SetID(string)
GetName() string
}
// BasicResource is a resource with a unique identifier
// easyjson:json
// swagger:ignore
type BasicResource struct {
UUID string `yaml:"UUID"`
}
// ID returns the resource ID
func (b *BasicResource) ID() string {
return b.UUID
}
// SetID sets the resource ID
func (b *BasicResource) SetID(i string) {
b.UUID = i
}
// GetName returns the resource name
func (b *BasicResource) GetName() string {
return "BasicResource"
}
// Alert object
//
// Alerts provide a way to be notified when a Gremlin expression
// is evaluated to true.
//
// easyjson:json
// swagger:model Alert
type Alert struct {
// swagger:allOf
BasicResource `yaml:",inline"`
// Alert name
Name string `json:",omitempty" yaml:"Name"`
// Alert description
Description string `json:",omitempty" yaml:"Description"`
// Gremlin or JavaScript expression evaluated to trigger the alarm
Expression string `json:",omitempty" valid:"nonzero" yaml:"Expression"`
// Action to execute when the alert is triggered.
// Can be either an empty string, or a URL (use 'file://' for local scripts)
Action string `json:",omitempty" valid:"regexp=^(|http://|https://|file://).*$" yaml:"Action"`
// Event that triggers the alert evaluation
Trigger string `json:",omitempty" valid:"regexp=^(graph|duration:.+|)$" yaml:"Trigger"`
CreateTime time.Time
}
// GetName returns the resource name
func (a *Alert) GetName() string {
return "Alert"
}
// NewAlert creates a New empty Alert, only CreateTime is set.
func NewAlert() *Alert {
return &Alert{
CreateTime: time.Now().UTC(),
}
}
// Capture object
//
// Captures provide a way to capture network traffic on the nodes
// matching a Gremlin expression.
//
// easyjson:json
// swagger:model Capture
type Capture struct {
// swagger:allOf
BasicResource `yaml:",inline"`
// Gremlin Query
// required: true
GremlinQuery string `json:"GremlinQuery,omitempty" valid:"isGremlinExpr" yaml:"GremlinQuery"`
// BPF filter
BPFFilter string `json:"BPFFilter,omitempty" valid:"isBPFFilter" yaml:"BPFFilter"`
// Capture name
Name string `json:"Name,omitempty" yaml:"Name"`
// Capture description
Description string `json:"Description,omitempty" yaml:"Description"`
// Capture type. Can be afpacket, pcap, ebpf, sflow, pcapsocket, ovsmirror, dpdk, ovssflow or ovsnetflow
Type string `json:"Type,omitempty" valid:"isValidCaptureType" yaml:"Type"`
// Number of active captures
// swagger:ignore
Count int `json:"Count" yaml:"Count"`
// SFlow port
Port int `json:"Port,omitempty" yaml:"Port"`
// Sampling rate for SFlow flows. 0: no flow samples
SamplingRate uint32 `json:"SamplingRate" yaml:"SamplingRate"`
// Polling interval for SFlow counters, 0: no counter samples
PollingInterval uint32 `json:"PollingInterval" yaml:"PollingInterval"`
// Maximum number of raw packets captured, 0: no packet, -1: unlimited
RawPacketLimit int `json:"RawPacketLimit,omitempty" valid:"isValidRawPacketLimit" yaml:"RawPacketLimit"`
// Packet header size to consider
HeaderSize int `json:"HeaderSize,omitempty" valid:"isValidCaptureHeaderSize" yaml:"HeaderSize"`
// Add additional TCP metrics to flows
ExtraTCPMetric bool `json:"ExtraTCPMetric" yaml:"ExtraTCPMetric"`
// Defragment IPv4 packets
IPDefrag bool `json:"IPDefrag" yaml:"IPDefrag"`
// Reassemble TCP packets
ReassembleTCP bool `json:"ReassembleTCP" yaml:"ReassembleTCP"`
// First layer used by flow key calculation, L2 or L3
LayerKeyMode string `json:"LayerKeyMode,omitempty" valid:"isValidLayerKeyMode" yaml:"LayerKeyMode"`
// List of extra layers to be added to the flow, available: DNS|DHCPv4|VRRP
ExtraLayers flow.ExtraLayers `json:"ExtraLayers,omitempty" yaml:"ExtraLayers"`
// sFlow/NetFlow target, if empty the agent will be used
Target string `json:"Target,omitempty" valid:"isValidAddress" yaml:"Target"`
// target type (netflowv5, erspanv1), ignored in case of sFlow/NetFlow capture
TargetType string `json:"TargetType,omitempty" yaml:"TargetType"`
}
// GetName returns the resource name
func (c *Capture) GetName() string {
return "Capture"
}
// NewCapture creates a new capture
func NewCapture(query string, bpfFilter string) *Capture {
return &Capture{
GremlinQuery: query,
BPFFilter: bpfFilter,
}
}
// EdgeRule object
//
// Edge rules allow the dynamic creation of links between nodes of the graph.
//
// easyjson:json
// swagger:model
type EdgeRule struct {
// swagger:allOf
BasicResource `yaml:",inline"`
// Edge rule name
Name string `yaml:"Name"`
// Edge rule description
Description string `yaml:"Description"`
// Gremlin expression of the edges source nodes
Src string `valid:"isGremlinExpr" yaml:"Src"`
// Gremlin expression of the edges destination nodes
Dst string `valid:"isGremlinExpr" yaml:"Dst"`
// Metadata of the edges to create
Metadata graph.Metadata `yaml:"Metadata"`
}
// GetName returns the resource name
func (e *EdgeRule) GetName() string {
return "EdgeRule"
}
// Validate verifies the edge rule does not create invalid edges
func (e *EdgeRule) Validate() error {
n1 := graph.CreateNode(graph.GenID(), nil, graph.TimeUTC(), "", "")
n2 := graph.CreateNode(graph.GenID(), nil, graph.TimeUTC(), "", "")
edge := graph.CreateEdge(graph.GenID(), n1, n2, e.Metadata, graph.TimeUTC(), "", "")
return schemaValidator.ValidateEdge(edge)
}
// NodeRule object
//
// Node rules allow the dynamic creation of nodes in the graph.
//
// easyjson:json
// swagger:model
type NodeRule struct {
// swagger:allOf
BasicResource `yaml:",inline"`
// Node rule name
Name string `yaml:"Name"`
// Node rule description
Description string `yaml:"Description"`
// Metadata of the nodes to create
Metadata graph.Metadata `yaml:"Metadata"`
// 'create' to create nodes, 'update' to updates nodes
Action string `valid:"regexp=^(create|update)$" yaml:"Action"`
// Gremlin expression of the nodes to update
Query string `valid:"isGremlinOrEmpty" yaml:"Query"`
}
// GetName returns the resource name
func (n *NodeRule) GetName() string {
return "NodeRule"
}
// Validate verifies the node rule does not create invalid node or change
// important attributes of an existing node
func (n *NodeRule) Validate() error {
switch n.Action {
case "create":
// TODO: we should modify the JSON schema so that we can validate only the metadata
node := graph.CreateNode(graph.GenID(), n.Metadata, graph.TimeUTC(), "", "")
return schemaValidator.ValidateNode(node)
case "update":
if n.Metadata["Type"] != nil || n.Metadata["Name"] != nil {
return errors.New("Name and Type fields can not be changed")
}
}
return nil
}
const (
// PIModeUniqPerNode use a unique packet identifier per source node
PIModeUniqPerNode = iota
// PIModeRandom use random packet identifier for each packet
PIModeRandom
// PiTypeICMP4 icmpv4 packet
PiTypeICMP4 = "icmp4"
// PiTypeICMP6 icmpv6 packet
PiTypeICMP6 = "icmp6"
// PiTypeTCP4 ipv4 + tcp packet
PiTypeTCP4 = "tcp4"
// PiTypeTCP6 ipv6 + tcp packet
PiTypeTCP6 = "tcp6"
// PiTypeUDP4 ipv4 + udp packet
PiTypeUDP4 = "udp4"
// PiTypeUDP6 ipv6 + udp packet
PiTypeUDP6 = "udp6"
)
// PacketInjection packet injector API parameters
// easyjson:json
// swagger:model
type PacketInjection struct {
// swagger:allOf
BasicResource `yaml:",inline"`
Src string `yaml:"Src"`
Dst string `yaml:"Dst"`
SrcIP string `valid:"isIPOrCIDR" yaml:"SrcIP"`
DstIP string `valid:"isIPOrCIDR" yaml:"DstIP"`
SrcMAC string `valid:"isMAC" yaml:"SrcMAC"`
DstMAC string `valid:"isMAC" yaml:"DstMAC"`
SrcPort uint16 `yaml:"SrcPort"`
DstPort uint16 `yaml:"DstPort"`
Type string `yaml:"Type"`
Payload string `yaml:"Payload"`
ICMPID uint16 `yaml:"ICMPID"`
Count uint64 `yaml:"Count"`
Interval uint64 `yaml:"Interval"`
Mode int `yaml:"Mode"`
IncrementPayload int64 `yaml:"IncrementPayload"`
StartTime time.Time
Pcap []byte `yaml:"Pcap"`
TTL uint8 `yaml:"TTL"`
}
// GetName returns the resource name
func (pi *PacketInjection) GetName() string {
return "PacketInjection"
}
// Validate verifies the packet injection type is supported
func (pi *PacketInjection) Validate() error {
allowedTypes := map[string]bool{
PiTypeICMP4: true,
PiTypeICMP6: true,
PiTypeTCP4: true,
PiTypeTCP6: true,
PiTypeUDP4: true,
PiTypeUDP6: true,
}
if _, ok := allowedTypes[pi.Type]; !ok {
return errors.New("given type is not supported")
}
return nil
}
// TopologyParams topology query parameters
// easyjson:json
// swagger:model
type TopologyParams struct {
GremlinQuery string `json:"GremlinQuery,omitempty" valid:"isGremlinExpr" yaml:"GremlinQuery"`
}
// WorkflowChoice describes one value within a choice
// easyjson:json
// swagger:model
type WorkflowChoice struct {
Value string `yaml:"Value"`
Description string `yaml:"Description"`
}
// WorkflowParam describes a workflow parameter
// easyjson:json
// swagger:model
type WorkflowParam struct {
Name string `yaml:"Name"`
Description string `yaml:"Description"`
Type string `yaml:"Type"`
Default interface{} `yaml:"Default"`
Values []WorkflowChoice `yaml:"Values"`
}
// Workflow object
//
// Workflow allows to automate actions using JavaScript.
//
// easyjson:json
// swagger:model
type Workflow struct {
// swagger:allOf
BasicResource `yaml:",inline"`
// Workflow name
Name string `yaml:"Name" valid:"nonzero"`
// Workflow title
Title string `yaml:"Title"`
// Workflow abstract
Abstract string `yaml:"Abstract"`
// Workflow description
Description string `yaml:"Description"`
// Workflow parameters
Parameters []WorkflowParam `yaml:"Parameters"`
Source string `valid:"isValidWorkflow" yaml:"Source"`
}
// WorkflowCall describes workflow call
// swagger:model
type WorkflowCall struct {
Params []interface{}
}
func init() {
var err error
if schemaValidator, err = topology.NewSchemaValidator(); err != nil {
panic(err)
}
}