tailscale: add a tsapi wrapper for making local API calls
- ID
bf5d9f2- date
2026-05-27 15:33:08+00:00- author
Alex Chan <alexc@tailscale.com>- parent
bbcbe1d- message
tailscale: add a tsapi wrapper for making local API calls- changed files
3 files, 82 additions, 3 deletions
Changed files
config.fish (6730) → config.fish (6778)
diff --git a/config.fish b/config.fish
index eaecfd1..333d52d 100644
--- a/config.fish
+++ b/config.fish
@@ -192,6 +192,7 @@ __create_python_script_alias images/reborder.py
__create_python_script_alias images/squarify.py
__create_python_script_alias images/srgbify.py
__create_python_script_alias images/tint_image.py
+__create_python_script_alias tailscale/tsapi.py
__create_python_script_alias text/fix_twemoji.py
__create_python_script_alias text/fix_twitter_thread.py
__create_python_script_alias text/natsize.py
tailscale/README.md (2638) → tailscale/README.md (3011)
diff --git a/tailscale/README.md b/tailscale/README.md
index 5115148..e323ea4 100644
--- a/tailscale/README.md
+++ b/tailscale/README.md
@@ -39,7 +39,11 @@ scripts = [
},
{
"usage": "lts NAME",
- "description": "run a CLi command on a local instance of tailscaled"
+ "description": "run a CLI command on a local instance of tailscaled"
+ },
+ {
+ "usage": "tsapi.py",
+ "description": "call the Tailscale API with a local instance of the Tailscale control plane"
},
]
@@ -98,7 +102,16 @@ cog_helpers.create_description_table(folder_name=folder_name, scripts=scripts)
</a>
</dt>
<dd>
- run a CLi command on a local instance of tailscaled
+ run a CLI command on a local instance of tailscaled
+ </dd>
+
+ <dt>
+ <a href="https://github.com/alexwlchan/scripts/blob/main/tailscale/tsapi.py">
+ <code>tsapi.py</code>
+ </a>
+ </dt>
+ <dd>
+ call the Tailscale API with a local instance of the Tailscale control plane
</dd>
</dl>
-<!-- [[[end]]] (sum: OoAOwOv+GI) -->
\ No newline at end of file
+<!-- [[[end]]] (sum: JQyvJ+o4WW) -->
\ No newline at end of file
tailscale/tsapi.py (0) → tailscale/tsapi.py (1562)
diff --git a/tailscale/tsapi.py b/tailscale/tsapi.py
new file mode 100755
index 0000000..d4f6f8d
--- /dev/null
+++ b/tailscale/tsapi.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+"""
+tsapi is a lightweight wrapper for calling the Tailscale API with
+a local instance of the Tailscale control plane. It's to save me
+remembering the exact set of curl commands I need.
+"""
+
+import argparse
+import json
+import shlex
+import subprocess
+from typing import TypedDict
+
+from chives.text import coloured
+
+Args = TypedDict(
+ "args",
+ {
+ "method": str,
+ "path": str,
+ "api_key": str,
+ "data": str,
+ },
+)
+
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ prog="tsapi",
+ description="Make API calls to a local instance of devcontrol",
+ )
+
+ parser.add_argument("--endpoint", help="API endpoint", required=True)
+ parser.add_argument("--api-key", help="API key", required=True)
+ parser.add_argument("--data", help="Body to POST with the request")
+
+ args = parser.parse_args()
+
+ method, path = args.endpoint.split()
+
+ return {
+ "method": method,
+ "path": path,
+ "api_key": args.api_key,
+ "data": args.data,
+ }
+
+
+if __name__ == "__main__":
+ args = parse_args()
+ cmd = [
+ "curl",
+ f"http://localhost:31544/api/v2{args['path']}",
+ "--silent",
+ "--request",
+ args["method"],
+ "--header",
+ f"Authorization: Bearer {args['api_key']}",
+ ]
+ if args["data"]:
+ cmd.extend(["--data", args["data"]])
+
+ print(coloured("-> " + " ".join(shlex.quote(c) for c in cmd), "blue"))
+ output = subprocess.check_output(cmd)
+ print(json.dumps(json.loads(output), indent=2))