aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSupremist <sergkarv@gmail.com>2026-07-06 19:34:48 +0300
committerSupremist <sergkarv@gmail.com>2026-07-06 19:34:48 +0300
commitba9e4bb19424866e77b97513e75141155bd5bcbf (patch)
tree49406e8df500af4992acf1f1a7da2525cebc9aa7
parentc1904389a5cd69663f2641941f5d2e287db4bc3f (diff)
downloadnetbird-ba9e4bb19424866e77b97513e75141155bd5bcbf.tar.xz
netbird-ba9e4bb19424866e77b97513e75141155bd5bcbf.zip
Generate nft commands for changed netbird peers/groups
-rw-r--r--api/netbird-api.nu10
-rw-r--r--api/netbird-nft-sets.nu46
-rw-r--r--test-data/nft-sets.json75
3 files changed, 131 insertions, 0 deletions
diff --git a/api/netbird-api.nu b/api/netbird-api.nu
index 21f69e5..121abcd 100644
--- a/api/netbird-api.nu
+++ b/api/netbird-api.nu
@@ -42,4 +42,14 @@ export def clean-rules-for-write [] {
| update sources $id_or_self
| update destinations $id_or_self
}
+}
+
+export def groups [] {}
+
+export def "groups list" [] {
+ http get -H (headers) (url 'groups')
+}
+
+export def "peers list" [] {
+ http get -H (headers) (url 'peers')
} \ No newline at end of file
diff --git a/api/netbird-nft-sets.nu b/api/netbird-nft-sets.nu
new file mode 100644
index 0000000..2187aa6
--- /dev/null
+++ b/api/netbird-nft-sets.nu
@@ -0,0 +1,46 @@
+# Usage:
+# ^nft --json list sets | nu --stdin api/netbird-nft-sets.nu
+# open --raw test-data/nft-sets.json | nu --stdin api/netbird-nft-sets.nu
+
+use netbird-api.nu
+
+def mangle-name [prefix: string, name: string] {
+ $prefix + ($name
+ | str replace -ar '\s+' '_'
+ | str replace -ar '\W' '')
+}
+
+def find-changed-sets [] {
+ let sets = $in # nft_sets
+ | rename --column { name: nft_name }
+ let peers = netbird-api peers list
+ | insert nft_name { mangle-name 'nbp_' $in.name | str downcase }
+ | insert new_elem { [$in.ip] }
+ let groups = netbird-api groups list
+ | where peers != null
+ | each { update peers { select id | join $peers id } }
+ | insert nft_name { mangle-name 'nbg_' $in.name } # allow uppercase
+ | insert new_elem { $in.peers.ip }
+
+ let set_changes = [$peers, $groups] | flatten
+ | join $sets nft_name
+ | where { $in.new_elem != $in.elem }
+ return $set_changes
+}
+
+def generate-nft-commands [] {
+# nft add talbe inet <name> # ignore if table already exists
+# nft destroy table inet <name> # ignore if table already removed
+ let set_changes = $in
+ for $s in $set_changes {
+ let path = [$s.family $s.table $s.nft_name] | str join ' '
+ print $"flush set ($path)"
+ print $"add element ($path) { ($s.new_elem | str join ', ') }"
+ }
+}
+
+def main [] {
+ $in | from json | get nftables | skip 1 | get set
+ | find-changed-sets
+ | generate-nft-commands
+}
diff --git a/test-data/nft-sets.json b/test-data/nft-sets.json
new file mode 100644
index 0000000..85b7dfb
--- /dev/null
+++ b/test-data/nft-sets.json
@@ -0,0 +1,75 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "1.1.5",
+ "release_name": "Commodore Bullmoose #6",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nbg_Admin",
+ "table": "netbird",
+ "type": "ipv4_addr",
+ "handle": 60,
+ "flags": [
+ "dynamic"
+ ],
+ "elem": [
+ "100.66.53.204",
+ "100.66.202.201",
+ "100.66.218.182"
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nbg_Guest",
+ "table": "netbird",
+ "type": "ipv4_addr",
+ "handle": 65,
+ "flags": [
+ "interval"
+ ],
+ "elem": [
+ "100.66.53.204",
+ "100.66.202.201",
+ "100.66.218.182"
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nbg_GuestLOL",
+ "table": "netbird",
+ "type": "ipv4_addr",
+ "handle": 65,
+ "flags": [
+ "interval"
+ ],
+ "elem": [
+ "100.66.218.182"
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nbp_flow",
+ "table": "netbird",
+ "type": "ipv4_addr",
+ "handle": 65,
+ "flags": [
+ "interval"
+ ],
+ "elem": [
+ "100.66.202.201"
+ ]
+ }
+ }
+ ]
+} \ No newline at end of file