Skip to content

Commit 8693035

Browse files
committed
Implement DSL based on goyacc
1 parent 4748826 commit 8693035

File tree

9 files changed

+883
-142
lines changed

9 files changed

+883
-142
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/confgenerator
33
/bin/
44
cover.out
5+
y.output

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ require (
2424
github.com/prometheus/client_golang v1.22.0
2525
github.com/prometheus/client_model v0.6.2
2626
github.com/prometheus/common v0.63.0
27+
github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24
2728
github.com/segmentio/kafka-go v0.4.47
2829
github.com/sirupsen/logrus v1.9.3
2930
github.com/spf13/cobra v1.9.1
@@ -114,7 +115,6 @@ require (
114115
github.com/pion/transport/v2 v2.2.10 // indirect
115116
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
116117
github.com/prometheus/procfs v0.16.0 // indirect
117-
github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24 // indirect
118118
github.com/rs/xid v1.6.0 // indirect
119119
github.com/russross/blackfriday/v2 v2.1.0 // indirect
120120
github.com/safchain/ethtool v0.5.10 // indirect

pkg/dsl/dsl.go

Lines changed: 0 additions & 56 deletions
This file was deleted.

pkg/dsl/dsl_test.go

Lines changed: 0 additions & 85 deletions
This file was deleted.

pkg/dsl/eval.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dsl
2+
3+
import (
4+
"github.com/netobserv/flowlogs-pipeline/pkg/config"
5+
"github.com/netobserv/flowlogs-pipeline/pkg/utils/filters"
6+
)
7+
8+
type tree struct {
9+
logicalOp string
10+
children []*tree
11+
predicate filters.Predicate
12+
}
13+
14+
func (t *tree) apply(flow config.GenericMap) bool {
15+
if t.predicate != nil {
16+
return t.predicate(flow)
17+
}
18+
if t.logicalOp == operatorAnd {
19+
for _, child := range t.children {
20+
if !child.apply(flow) {
21+
return false
22+
}
23+
}
24+
return true
25+
}
26+
// t.logicalOp == operatorOr
27+
for _, child := range t.children {
28+
if child.apply(flow) {
29+
return true
30+
}
31+
}
32+
return false
33+
}

pkg/dsl/eval_test.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package dsl
2+
3+
import (
4+
"testing"
5+
6+
"github.com/netobserv/flowlogs-pipeline/pkg/config"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestAndOrEqual(t *testing.T) {
11+
yyErrorVerbose = true
12+
predicate, err := Parse(`(srcnamespace="netobserv" OR (srcnamespace="ingress" AND dstnamespace="netobserv")) AND srckind!="service"`)
13+
assert.NoError(t, err)
14+
assert.NotNil(t, predicate)
15+
16+
result := predicate(config.GenericMap{
17+
"srcnamespace": "plop",
18+
"dstnamespace": "netobserv",
19+
"srckind": "pod",
20+
})
21+
assert.False(t, result)
22+
23+
result = predicate(config.GenericMap{
24+
"srcnamespace": "ingress",
25+
"dstnamespace": "netobserv",
26+
"srckind": "pod",
27+
})
28+
assert.True(t, result)
29+
30+
result = predicate(config.GenericMap{
31+
"srcnamespace": "ingress",
32+
"dstnamespace": "netobserv",
33+
"srckind": "service",
34+
})
35+
assert.False(t, result)
36+
}
37+
38+
func TestRegexp(t *testing.T) {
39+
yyErrorVerbose = true
40+
predicate, err := Parse(`srcnamespace=~"openshift.*" and dstnamespace!~"openshift.*"`)
41+
assert.NoError(t, err)
42+
assert.NotNil(t, predicate)
43+
44+
result := predicate(config.GenericMap{
45+
"srcnamespace": "openshift-ingress",
46+
"dstnamespace": "my-app",
47+
"srckind": "pod",
48+
})
49+
assert.True(t, result, "Should accept flows from OpenShift to App")
50+
51+
result = predicate(config.GenericMap{
52+
"srcnamespace": "my-app",
53+
"dstnamespace": "openshift-ingress",
54+
"srckind": "pod",
55+
})
56+
assert.False(t, result, "Should reject flows from App to OpenShift")
57+
58+
result = predicate(config.GenericMap{
59+
"srcnamespace": "my-app",
60+
"dstnamespace": "my-app",
61+
"srckind": "pod",
62+
})
63+
assert.False(t, result, "Should reject flows from App to App")
64+
65+
result = predicate(config.GenericMap{
66+
"srcnamespace": "openshift-operators",
67+
"dstnamespace": "openshift-ingress",
68+
"srckind": "pod",
69+
})
70+
assert.False(t, result, "Should reject flows from OpenShift to OpenShift")
71+
}
72+
73+
func TestWith(t *testing.T) {
74+
yyErrorVerbose = true
75+
predicate, err := Parse(`srcnamespace="foo" and with(rtt)`)
76+
assert.NoError(t, err)
77+
assert.NotNil(t, predicate)
78+
79+
result := predicate(config.GenericMap{
80+
"srcnamespace": "foo",
81+
"rtt": 4.5,
82+
})
83+
assert.True(t, result, "Should accept flows from foo with rtt")
84+
85+
result = predicate(config.GenericMap{
86+
"srcnamespace": "foo",
87+
})
88+
assert.False(t, result, "Should reject flows from foo without rtt")
89+
}
90+
91+
func TestWithout(t *testing.T) {
92+
yyErrorVerbose = true
93+
predicate, err := Parse(`srcnamespace="foo" or without(srcnamespace)`)
94+
assert.NoError(t, err)
95+
assert.NotNil(t, predicate)
96+
97+
result := predicate(config.GenericMap{
98+
"srcnamespace": "foo",
99+
})
100+
assert.True(t, result, "Should accept flows from foo")
101+
102+
result = predicate(config.GenericMap{})
103+
assert.True(t, result, "Should accept flows without srcnamespace")
104+
105+
result = predicate(config.GenericMap{
106+
"srcnamespace": "bar",
107+
})
108+
assert.False(t, result, "Should reject flows from bar")
109+
}

pkg/dsl/expr.y

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
%{
2+
package dsl
3+
%}
4+
5+
%union{
6+
expr Expression
7+
value string
8+
}
9+
10+
%type <expr> root
11+
%type <expr> expr
12+
13+
%token <value> VAR STRING NUMBER AND OR EQ NEQ REG NREG OPEN_PARENTHESIS CLOSE_PARENTHESIS WITH WITHOUT
14+
%left AND
15+
%left OR
16+
%%
17+
18+
root:
19+
expr {
20+
$$ = $1
21+
yylex.(*Lexer).result = $$
22+
}
23+
24+
expr:
25+
OPEN_PARENTHESIS expr CLOSE_PARENTHESIS { $$ = ParenthesisExpr{inner: $2} }
26+
| expr AND expr { $$ = LogicalExpr{left: $1, operator: operatorAnd, right: $3} }
27+
| expr OR expr { $$ = LogicalExpr{left: $1, operator: operatorOr, right: $3} }
28+
| WITH OPEN_PARENTHESIS VAR CLOSE_PARENTHESIS { $$ = WithExpr{key: $3} }
29+
| WITHOUT OPEN_PARENTHESIS VAR CLOSE_PARENTHESIS { $$ = WithoutExpr{key: $3} }
30+
| VAR EQ STRING { $$ = EqExpr{key: $1, value: $3} }
31+
| VAR NEQ STRING { $$ = NEqExpr{key: $1, value: $3} }
32+
| VAR REG STRING { $$ = RegExpr{key: $1, value: $3} }
33+
| VAR NREG STRING { $$ = NRegExpr{key: $1, value: $3} }
34+
%%

0 commit comments

Comments
 (0)