vssh 3.7.0__tar.gz → 3.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vssh-3.7.0/vssh.egg-info → vssh-3.7.2}/PKG-INFO +1 -1
- {vssh-3.7.0 → vssh-3.7.2}/pyproject.toml +1 -1
- {vssh-3.7.0 → vssh-3.7.2/vssh.egg-info}/PKG-INFO +1 -1
- {vssh-3.7.0 → vssh-3.7.2}/vssh.py +44 -16
- {vssh-3.7.0 → vssh-3.7.2}/LICENSE +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/README.md +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/setup.cfg +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh.egg-info/SOURCES.txt +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh.egg-info/dependency_links.txt +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh.egg-info/entry_points.txt +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh.egg-info/top_level.txt +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh_mcp_server.py +0 -0
- {vssh-3.7.0 → vssh-3.7.2}/vssh_p2p.py +0 -0
|
@@ -81,7 +81,17 @@ def _load_tailscale_map() -> dict:
|
|
|
81
81
|
pass
|
|
82
82
|
|
|
83
83
|
# 3. Auto-detect: cross-reference `tailscale status --json` + wire /peers
|
|
84
|
-
if
|
|
84
|
+
# Re-run if: no map yet, OR tailscale_map file is older than 24 hours
|
|
85
|
+
_stale = False
|
|
86
|
+
if ts_map and ts_file.exists():
|
|
87
|
+
try:
|
|
88
|
+
_age = time.time() - ts_file.stat().st_mtime
|
|
89
|
+
if _age > 86400: # 24 hours
|
|
90
|
+
_stale = True
|
|
91
|
+
except OSError:
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
if not ts_map or _stale:
|
|
85
95
|
try:
|
|
86
96
|
import urllib.request as _ur, subprocess as _sp2
|
|
87
97
|
ts_out = _sp2.run(['tailscale', 'status', '--json'],
|
|
@@ -96,18 +106,32 @@ def _load_tailscale_map() -> dict:
|
|
|
96
106
|
ips = [ip for ip in peer.get('TailscaleIPs', []) if ':' not in ip]
|
|
97
107
|
if name and ips:
|
|
98
108
|
ts_host[name] = ips[0]
|
|
99
|
-
|
|
109
|
+
detected = {}
|
|
110
|
+
for srv_url in WIRE_SERVERS:
|
|
100
111
|
try:
|
|
101
|
-
with _ur.urlopen(f'
|
|
112
|
+
with _ur.urlopen(f'{srv_url}/peers', timeout=3) as r:
|
|
102
113
|
for p in json.loads(r.read()).get('peers', []):
|
|
103
114
|
name = p.get('node_name', '').lower()
|
|
104
115
|
wire_ip = p.get('vpn_ip', '')
|
|
105
116
|
ts_ip = ts_host.get(name)
|
|
106
117
|
if wire_ip and ts_ip:
|
|
107
|
-
|
|
118
|
+
detected[wire_ip] = ts_ip
|
|
108
119
|
break
|
|
109
120
|
except Exception:
|
|
110
121
|
continue
|
|
122
|
+
if detected:
|
|
123
|
+
ts_map.update(detected)
|
|
124
|
+
# Save auto-detected map to file for future runs
|
|
125
|
+
try:
|
|
126
|
+
VSSH_DIR_CONF.mkdir(parents=True, exist_ok=True)
|
|
127
|
+
lines = [f"{wire_ip} {ts_ip}\n"
|
|
128
|
+
for wire_ip, ts_ip in sorted(detected.items())]
|
|
129
|
+
ts_file.write_text(
|
|
130
|
+
"# Auto-generated by vssh — wire VPN IP → Tailscale IP\n"
|
|
131
|
+
+ "".join(lines)
|
|
132
|
+
)
|
|
133
|
+
except OSError:
|
|
134
|
+
pass
|
|
111
135
|
except Exception:
|
|
112
136
|
pass
|
|
113
137
|
|
|
@@ -531,19 +555,23 @@ def check_transfer_safety(host: str) -> bool:
|
|
|
531
555
|
# Dynamically read from /etc/wire/config.json (server_url field)
|
|
532
556
|
# Falls back to hardcoded list only if config is missing
|
|
533
557
|
def _load_wire_servers() -> list:
|
|
558
|
+
"""Return list of wire coordinator base URLs (e.g. ['http://1.2.3.4:8790']).
|
|
559
|
+
Reads from /etc/wire/config.json or ~/.wire/config.json — no hardcoded IPs.
|
|
560
|
+
"""
|
|
534
561
|
import json as _json, re as _re
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
562
|
+
for _cfg_path in ["/etc/wire/config.json",
|
|
563
|
+
os.path.expanduser("~/.wire/config.json")]:
|
|
564
|
+
try:
|
|
565
|
+
with open(_cfg_path) as _f:
|
|
566
|
+
_cfg = _json.load(_f)
|
|
567
|
+
_url = _cfg.get("server_url", "").rstrip("/")
|
|
568
|
+
if _re.match(r'https?://', _url):
|
|
569
|
+
return [_url]
|
|
570
|
+
except (OSError, ValueError, KeyError):
|
|
571
|
+
continue
|
|
544
572
|
return []
|
|
545
573
|
|
|
546
|
-
WIRE_SERVERS = _load_wire_servers()
|
|
574
|
+
WIRE_SERVERS = _load_wire_servers() # list of coordinator base URLs
|
|
547
575
|
_name_cache = {} # name -> vpn_ip
|
|
548
576
|
_name_cache_time = 0
|
|
549
577
|
|
|
@@ -568,7 +596,7 @@ def resolve_name(host: str) -> str:
|
|
|
568
596
|
import urllib.request
|
|
569
597
|
for srv_ip in WIRE_SERVERS:
|
|
570
598
|
try:
|
|
571
|
-
req = urllib.request.Request(f"
|
|
599
|
+
req = urllib.request.Request(f"{srv_ip}/peers")
|
|
572
600
|
with urllib.request.urlopen(req, timeout=3) as resp:
|
|
573
601
|
data = json.loads(resp.read())
|
|
574
602
|
peers = data.get("peers", [])
|
|
@@ -3978,7 +4006,7 @@ Env: VSSH_SECRET
|
|
|
3978
4006
|
import urllib.request as _ureq
|
|
3979
4007
|
for _srv_ip in WIRE_SERVERS:
|
|
3980
4008
|
try:
|
|
3981
|
-
with _ureq.urlopen(f"
|
|
4009
|
+
with _ureq.urlopen(f"{_srv_ip}/peers", timeout=3) as _r:
|
|
3982
4010
|
_peers = json.loads(_r.read()).get("peers", [])
|
|
3983
4011
|
for _p in _peers:
|
|
3984
4012
|
_nn = _p.get("node_name", "")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|