90 lines
2.8 KiB
Python
Executable File
90 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (C) 2026 Bryan Joshua Pedini - gpl-3-or-later
|
|
|
|
import subprocess
|
|
import json
|
|
import sys
|
|
|
|
def get_tailscale_prefs():
|
|
"""
|
|
Executes 'tailscale debug prefs' and returns the parsed JSON output.
|
|
"""
|
|
try:
|
|
# Run the command and capture stdout
|
|
result = subprocess.run(
|
|
["tailscale", "debug", "prefs"],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True
|
|
)
|
|
return json.loads(result.stdout)
|
|
except FileNotFoundError:
|
|
print("Error: 'tailscale' command not found. Please ensure Tailscale is installed.", file=sys.stderr)
|
|
sys.exit(1)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error running 'tailscale debug prefs': {e.stderr}", file=sys.stderr)
|
|
sys.exit(1)
|
|
except json.JSONDecodeError as e:
|
|
print(f"Error parsing JSON output: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def process_advertise_routes(routes_array, append_func):
|
|
"""
|
|
Processes the AdvertiseRoutes array according to the specific logic:
|
|
- Separates exit node routes (0.0.0.0/0, ::/0) from standard routes.
|
|
- Appends '--advertise-exit-node' if exit node routes are found.
|
|
- Appends '--advertise-routes=' with a comma-separated list of standard routes.
|
|
"""
|
|
exit_node_routes = {"0.0.0.0/0", "::/0"}
|
|
has_exit_node = False
|
|
standard_routes = []
|
|
|
|
if routes_array:
|
|
for route in routes_array:
|
|
if route in exit_node_routes:
|
|
has_exit_node = True
|
|
else:
|
|
standard_routes.append(route)
|
|
|
|
# If exit node routes are present, append the specific flag
|
|
if has_exit_node:
|
|
append_func("--advertise-exit-node")
|
|
|
|
# If standard routes are present, append them as a comma-separated list
|
|
if standard_routes:
|
|
routes_str = ",".join(standard_routes)
|
|
append_func(f"--advertise-routes={routes_str}")
|
|
|
|
def main():
|
|
# 1. Get the JSON data from the command
|
|
prefs = get_tailscale_prefs()
|
|
|
|
# Initialize the main string list
|
|
cmd_parts = ["tailscale up"]
|
|
|
|
# Helper function to append to the main string list
|
|
def append_to_cmd(string_part):
|
|
cmd_parts.append(string_part)
|
|
|
|
# 2. Process RouteAll
|
|
# Default is false, so we only append if it is true
|
|
if prefs.get("RouteAll", False):
|
|
append_to_cmd("--accept-routes")
|
|
|
|
# 3. Process CorpDNS
|
|
# Default is true, so we only append if it is false (to set --accept-dns=false)
|
|
if not prefs.get("CorpDNS", True):
|
|
append_to_cmd("--accept-dns=false")
|
|
|
|
# 4. Process AdvertiseRoutes
|
|
# We use the dedicated function for the array logic
|
|
routes = prefs.get("AdvertiseRoutes")
|
|
if routes:
|
|
process_advertise_routes(routes, append_to_cmd)
|
|
|
|
# Output the resulting string
|
|
print(" ".join(cmd_parts))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|