blob: 0554c6fc5e592f159418a47132975ac7af7c0e75 (
plain)
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
|
def "job recv pending" []: nothing -> list {
"marker" | job send (job id) # send a marker to self
mut events = []
mut ev = job recv # marker will prevent wait here
while $ev != "marker" {
$events = $events | append $ev
$ev = job recv
}
$events
}
# may wait up to two intervals, because event timestamps are not accounted
def create-debounce-queue [interval: duration, handler: closure] {
job spawn -d "debounce queue" {
mut event = job recv
loop {
sleep $interval
let new_events = job recv pending
if ($new_events | is-empty) {
do $handler $event
$event = job recv
} else {
$event = ($new_events | last)
}
}
}
}
def single [] {
let $data = $in
if ($data | length) != 1 {
make error "Expected single element"
}
$data | first
}
def parse-nft-mon-event [] {
mut rest = $in
mut result = {}
for key_name in ['action', 'type'] {
let key = $rest | items {|k, v| $k} | single
$rest = $rest | get $key
$result = $result | insert $key_name $key
}
$result | merge $rest
}
def main [--test] {
let debounce_interval = 2sec
let debounce_queue = create-debounce-queue $debounce_interval {|ev|
print "Triggered" $ev
# nu update-netbird-nftables.nu --apply
}
try {
if $test {
nu test-data/mock-nft-mon.nu
} else {
^nft --json monitor rules
} | lines
| each { from json | parse-nft-mon-event }
| where action == add and type == rule and table == netbird # TODO filter update evenets
| each { job send $debounce_queue }
| ignore
print "Exiting gracefully..."
sleep $debounce_interval
sleep $debounce_interval
} catch { |e|
print $e.rendered
} finally {
job kill $debounce_queue
}
}
|