All checks were successful
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-fakeroot Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-qemu" Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-vm-manager-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-vm-manager-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-vm-manager Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-vm-manager Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
checks / checks-impure (pull_request) Successful in 2m19s
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-eval Build done.
136 lines
3.8 KiB
Python
Executable File
136 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
import argparse
|
|
import http.client
|
|
import ipaddress
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ZEROTIER_STATE_DIR = Path("/var/lib/zerotier-one")
|
|
|
|
|
|
class ClanError(Exception):
|
|
pass
|
|
|
|
|
|
def compute_zerotier_ip(network_id: str, identity: str) -> ipaddress.IPv6Address:
|
|
assert (
|
|
len(network_id) == 16
|
|
), "network_id must be 16 characters long, got {network_id}"
|
|
nwid = int(network_id, 16)
|
|
node_id = int(identity, 16)
|
|
addr_parts = bytearray(
|
|
[
|
|
0xFD,
|
|
(nwid >> 56) & 0xFF,
|
|
(nwid >> 48) & 0xFF,
|
|
(nwid >> 40) & 0xFF,
|
|
(nwid >> 32) & 0xFF,
|
|
(nwid >> 24) & 0xFF,
|
|
(nwid >> 16) & 0xFF,
|
|
(nwid >> 8) & 0xFF,
|
|
(nwid) & 0xFF,
|
|
0x99,
|
|
0x93,
|
|
(node_id >> 32) & 0xFF,
|
|
(node_id >> 24) & 0xFF,
|
|
(node_id >> 16) & 0xFF,
|
|
(node_id >> 8) & 0xFF,
|
|
(node_id) & 0xFF,
|
|
]
|
|
)
|
|
return ipaddress.IPv6Address(bytes(addr_parts))
|
|
|
|
|
|
def compute_member_id(ipv6_addr: str) -> str:
|
|
addr = ipaddress.IPv6Address(ipv6_addr)
|
|
addr_bytes = bytearray(addr.packed)
|
|
|
|
# Extract the bytes corresponding to the member_id (node_id)
|
|
node_id_bytes = addr_bytes[10:16]
|
|
node_id = int.from_bytes(node_id_bytes, byteorder="big")
|
|
|
|
member_id = format(node_id, "x").zfill(10)[-10:]
|
|
|
|
return member_id
|
|
|
|
|
|
# this is managed by the nixos module
|
|
def get_network_id() -> str:
|
|
p = Path("/etc/zerotier/network-id")
|
|
if not p.exists():
|
|
raise ClanError(
|
|
f"{p} file not found. Have you enabled the zerotier controller on this host?"
|
|
)
|
|
return p.read_text().strip()
|
|
|
|
|
|
def allow_member(args: argparse.Namespace) -> None:
|
|
member_id = args.member_id
|
|
if args.member_ip:
|
|
member_ip = args.member_id
|
|
member_id = compute_member_id(member_ip)
|
|
print(member_id)
|
|
exit(0)
|
|
network_id = get_network_id()
|
|
token = ZEROTIER_STATE_DIR.joinpath("authtoken.secret").read_text()
|
|
conn = http.client.HTTPConnection("localhost", 9993)
|
|
conn.request(
|
|
"POST",
|
|
f"/controller/network/{network_id}/member/{member_id}",
|
|
'{"authorized": true}',
|
|
{"X-ZT1-AUTH": token},
|
|
)
|
|
resp = conn.getresponse()
|
|
if resp.status != 200:
|
|
raise ClanError(
|
|
f"the zerotier daemon returned this error: {resp.status} {resp.reason}"
|
|
)
|
|
print(resp.status, resp.reason)
|
|
|
|
|
|
def list_members(args: argparse.Namespace) -> None:
|
|
network_id = get_network_id()
|
|
networks = ZEROTIER_STATE_DIR / "controller.d" / "network" / network_id / "member"
|
|
if not networks.exists():
|
|
return
|
|
for member in networks.iterdir():
|
|
with member.open() as f:
|
|
data = json.load(f)
|
|
try:
|
|
member_id = data["id"]
|
|
except KeyError:
|
|
raise ClanError(f"error: {member} does not contain an id")
|
|
print(
|
|
member_id,
|
|
compute_zerotier_ip(network_id, data["id"]),
|
|
data["authorized"] or "false",
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
subparser = parser.add_subparsers(dest="command")
|
|
parser_allow = subparser.add_parser("allow", help="Allow a member to join")
|
|
parser_allow.add_argument(
|
|
"--member-ip",
|
|
help="Allow a member to join by their zerotier ipv6 address",
|
|
action="store_true",
|
|
)
|
|
parser_allow.add_argument("member_id")
|
|
parser_allow.set_defaults(func=allow_member)
|
|
|
|
parser_list = subparser.add_parser("list", help="List members")
|
|
parser_list.set_defaults(func=list_members)
|
|
|
|
args = parser.parse_args()
|
|
try:
|
|
args.func(args)
|
|
except ClanError as e:
|
|
print(e)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|