This repository was archived by the owner on Apr 19, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcleanup.py
More file actions
114 lines (93 loc) · 3.63 KB
/
cleanup.py
File metadata and controls
114 lines (93 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3
import os
import requests
from dotenv import load_dotenv
load_dotenv()
# Environment variables.
TS_API_DOMAIN = os.getenv("TS_API_DOMAIN")
TS_TAG = os.getenv("TS_TAG")
TS_API_TOKEN = os.getenv("TS_API_TOKEN")
# Endponts.
API_ENDPOINT = f"https://api.tailscale.com/api/v2"
API_DEVICE_ENDPOINT = f"{API_ENDPOINT}/device"
API_TAILNET_ENDPOINT = f"{API_ENDPOINT}/tailnet/{TS_API_DOMAIN}"
# Fly.io Regions <https://fly.io/docs/reference/regions/#fly-io-regions>.
# Region ID: (Region Location, WireGuard Gateway)
FLY_IO_REGIONS = {
"ams": ("Amsterdam, Netherlands", True),
"arn": ("Stockholm, Sweden", False),
"bog": ("Bogotá, Colombia", False),
"bos": ("Boston, MA, USA", False),
"cdg": ("Paris, France", True),
"den": ("Denver, CO, USA", True),
"dfw": ("Dallas, TX, USA", True),
"ewr": ("Secaucus, NJ, USA", False),
"fra": ("Frankfurt, Germany", True),
"gdl": ("Guadalajara, Mexico", False),
"gig": ("Rio de Janeiro, Brazil", False),
"gru": ("Sao Paulo, Brazil", False),
"hkg": ("Hong Kong, China", True),
"iad": ("Ashburn, VA, USA", False),
"jnb": ("Johannesburg, South Africa", False),
"lax": ("Los Angeles, CA, USA", True),
"lhr": ("London, United Kingdom", True),
"maa": ("Chennai, India", True),
"mad": ("Madrid, Spain", False),
"mia": ("Miami, FL, USA", False),
"nrt": ("Tokyo, Japan", True),
"ord": ("Chicago, IL, USA", True),
"otp": ("Bucharest, Romania", False),
"qro": ("Querétaro, Mexico", False),
"scl": ("Santiago, Chile", True),
"sea": ("Seattle, WA, USA", True),
"sin": ("Singapore, Singapore", True),
"sjc": ("Sunnyvale, CA, USA", True),
"syd": ("Sydney, Australia", True),
"waw": ("Warsaw, Poland", False),
"yul": ("Montreal, Canada", False),
"yyz": ("Toronto, Canada", True),
}
def get_fly_io_exit_routes() -> dict:
"""
API Documentation: <https://github.com/tailscale/tailscale/blob/main/api.md#tailnet-devices>.
:return: dict{"hostname": "id"}.
"""
response = requests.get(f"{API_TAILNET_ENDPOINT}/devices",
auth=requests.auth.HTTPBasicAuth(TS_API_TOKEN, "")).json()
devices = {}
for device in response["devices"]:
try:
# Only match machines both have expected ACL tag and is in Fly.io region.
if TS_TAG in device["tags"] and device["hostname"][-3:] in FLY_IO_REGIONS:
devices[device["hostname"]] = device["id"]
except KeyError:
pass
return devices
def delete_device(device_id: str) -> int:
"""
API Documentation: <https://github.com/tailscale/tailscale/blob/main/api.md#device-delete>.
:return: status.
"""
return requests.delete(f"{API_DEVICE_ENDPOINT}/{device_id}",
auth=requests.auth.HTTPBasicAuth(TS_API_TOKEN, "")).status_code
def main() -> int:
"""
:return: status.
"""
print("Checking existing exit routes on Tailnet...")
devices = get_fly_io_exit_routes()
for hostname in devices.keys():
print(f"\tFound an exit route in {FLY_IO_REGIONS[hostname[-3:]][0]}.")
print(f"Total: {len(devices)} exit routes.")
print("Cleaning up...")
for hostname, id in devices.items():
print(f"\tDeleting exit route in {FLY_IO_REGIONS[hostname[-3:]][0]}:\n"
f"\tStatus code: {delete_device(id)}.")
if len(get_fly_io_exit_routes()) != 0:
print("Something went wrong, existing VPN machines were not deleted successfully.")
return 1
else:
print("All existing VPN machines were deleted successfully.")
return 0
if __name__ == "__main__":
raise SystemExit(main())