From ba9e4bb19424866e77b97513e75141155bd5bcbf Mon Sep 17 00:00:00 2001 From: Supremist Date: Mon, 6 Jul 2026 19:34:48 +0300 Subject: Generate nft commands for changed netbird peers/groups --- api/netbird-api.nu | 10 +++++++ api/netbird-nft-sets.nu | 46 ++++++++++++++++++++++++++++++ test-data/nft-sets.json | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 api/netbird-nft-sets.nu create mode 100644 test-data/nft-sets.json 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 # ignore if table already exists +# nft destroy table inet # 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 -- cgit v1.2.3