Skip to content

Instantly share code, notes, and snippets.

@fakuivan
Last active February 28, 2021 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fakuivan/de7da6158c8913d05ebc51de6a0868fa to your computer and use it in GitHub Desktop.
Save fakuivan/de7da6158c8913d05ebc51de6a0868fa to your computer and use it in GitHub Desktop.
Sets flow rules on a zerotier controller from a capabilities and rules file, abuses jq <3
#!/usr/bin/env bash
eval_on_ztncui () {
# shellcheck disable=1090
(source ~/containers/ztncui.sh && ztncui-compose exec -T ztncui bash -c "$1"); return $?
}
# Arguments are escaped, last argument gets the address of the server prepended, auth token is added to the header
curl_on_ztncui () {
# shellcheck disable=2016
eval_on_ztncui 'curl -s --header "X-ZT1-Auth: $ZT_TOKEN" '"$(printf "%q " "${@:1:$#-1}")"'"$ZT_ADDR"/'"$(printf "%q " "${@: -1}")"
}
NETWORKS="$(curl_on_ztncui -X GET controller/network)"
for rules_file in ./rules/*.ztrules; do
nwid="$(python3 -c "import pathlib, sys; print(pathlib.Path(sys.argv[1]).stem)" "$rules_file")" &&
# Check if network id matches any network on the controller
{ [[ "$(echo "$NETWORKS" | jq --arg nwid "$nwid" 'any(. == $nwid)')" == "true" ]] || continue; } &&
config="$(curl_on_ztncui -X GET controller/network/"$nwid")" &&
#npm install -g zerotier-rule-compiler
rules_compiled="$(node /usr/local/lib/node_modules/zerotier-rule-compiler/cli.js "$rules_file")" &&
config_merged="$(jq -s '.[1] * .[0].config' <(echo "$rules_compiled") <(echo "$config"))" &&
echo Writing final config
final_config="$(echo "$config_merged" | curl_on_ztncui -X POST -d @- controller/network/"$nwid")" &&
# jd could be used instead
diff -u <(echo "$config" | jq .) <(echo "$final_config" | jq .) --color &&
rules_file="./rules/$nwid.caps.json"
if [[ ! -r "$rules_file" ]]; then
echo Skipping rules for network "$nwid"
continue
fi
members="$(curl_on_ztncui -X GET controller/network/"$nwid"/member)"
caps="$(jq -s '.[0] as $members |
.[1].capabilitiesByName as $caps |
.[2] |
with_entries(select(.key | in($members))) |
with_entries(.value |= map(select(. | in($caps)) | $caps[.]))' \
<(echo "$members") <(echo "$rules_compiled") "$rules_file")"
i=0; while [[ "$i" < "$(echo "$caps" | jq 'keys | length')" ]]; do
member="$(echo "$caps" | jq -r --arg iter "$i" 'keys | .[$iter | tonumber]')"
member_config="$(curl_on_ztncui -X GET controller/network/"$nwid"/member/"$member")"
member_caps="$(echo "$caps" | jq --arg member "$member" '.[$member]')"
member_config_merged="$(jq -s --arg member "$member" '.[0] * {"capabilities": .[1][$member]}' <(echo "$member_config") <(echo "$caps"))"
member_final_config="$(echo "$member_config_merged" | curl_on_ztncui -X POST -d @- controller/network/"$nwid"/member/"$member")"
diff -u <(echo "$member_config" | jq .) <(echo "$member_final_config" | jq .) --color
i=$(("$i" + 1))
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment