2024-08-16 14:07:25 -05:00
|
|
|
import std/[os, osproc, sequtils, strformat, strutils, sugar]
|
2024-10-08 12:15:53 -05:00
|
|
|
import hwylterm
|
|
|
|
|
2024-08-16 14:07:25 -05:00
|
|
|
|
|
|
|
proc checkHost(host: seq[string]): string =
|
|
|
|
case host.len:
|
|
|
|
of 1: return host[0]
|
2024-10-08 12:15:53 -05:00
|
|
|
of 0: quit $bb"[red]expected hostname"
|
|
|
|
else: quit $bb"[red]expected one positional argument"
|
2024-08-16 14:07:25 -05:00
|
|
|
|
2024-08-16 15:39:21 -05:00
|
|
|
proc check(name: string): bool = (execCmd &"ssh -O check {name}") == 0
|
|
|
|
proc startSsh(name: string) = discard execCmd &"ssh -M -f -N {name}"
|
|
|
|
proc activateTunnel(name: string, port: int): int = execCmd &"""ssh -fNL "{port}:localhost:{port}" {name}"""
|
|
|
|
proc exitSsh(name: string):int = execCmd &"ssh -O exit {name}"
|
2024-08-16 14:07:25 -05:00
|
|
|
|
2024-08-16 15:39:21 -05:00
|
|
|
proc up(port: int, host: seq[string]) =
|
2024-08-16 14:07:25 -05:00
|
|
|
## activate a tunnel
|
|
|
|
let name = checkHost host
|
2024-08-27 13:18:05 -05:00
|
|
|
echo "activating connection to: ", name
|
2024-08-16 14:07:25 -05:00
|
|
|
if not check(name):
|
|
|
|
startSsh(name)
|
|
|
|
quit activateTunnel(name, port)
|
|
|
|
|
2024-08-16 15:39:21 -05:00
|
|
|
proc down(host: seq[string]) =
|
2024-10-12 10:58:46 -05:00
|
|
|
## disable all tunnels for a host
|
2024-08-16 14:07:25 -05:00
|
|
|
let name = checkHost host
|
2024-08-27 13:18:05 -05:00
|
|
|
echo "deactivating connection to: ", name
|
2024-08-16 14:07:25 -05:00
|
|
|
quit exitSsh(name)
|
|
|
|
|
2024-10-12 10:58:46 -05:00
|
|
|
proc collectControllers(): seq[string] =
|
2024-08-16 14:07:25 -05:00
|
|
|
let sshDir = (getEnv "HOME") / ".ssh"
|
2024-10-12 10:58:46 -05:00
|
|
|
collect(for _,p in walkDir(sshDir): p)
|
2024-08-16 14:07:25 -05:00
|
|
|
.map(extractFilename)
|
|
|
|
.filterIt(it.startsWith("control"))
|
2024-10-12 10:58:46 -05:00
|
|
|
|
|
|
|
proc killCmd() =
|
|
|
|
## kill all open tunnels
|
|
|
|
let controllers = collectControllers()
|
|
|
|
if controllers.len == 0: quit 0
|
|
|
|
for c in controllers:
|
2024-10-31 11:18:23 -05:00
|
|
|
let host = c.lastPathPart().split("-")[2]
|
|
|
|
let code = exitSsh(host)
|
|
|
|
if code != 0:
|
|
|
|
quit $bb"[red][[Error]failed to exit connection for host: " & host
|
2024-10-12 10:58:46 -05:00
|
|
|
|
|
|
|
proc show() =
|
|
|
|
## show active connections
|
|
|
|
let controllers = collectControllers()
|
2024-10-11 12:10:07 -05:00
|
|
|
echo bbfmt"[yellow]{controllers.len}[/] active connections"
|
2024-08-16 14:07:25 -05:00
|
|
|
if controllers.len == 0: quit 0
|
|
|
|
echo "hosts:"
|
|
|
|
echo controllers.mapIt(" " & it.split('-')[1]).join("\n")
|
2024-08-16 15:39:21 -05:00
|
|
|
|
2024-10-08 12:15:53 -05:00
|
|
|
when isMainModule:
|
|
|
|
import cligen, hwylterm/cligen
|
|
|
|
hwylCli(clCfg)
|
2024-10-12 10:58:46 -05:00
|
|
|
let hostUse =
|
|
|
|
$bb("$command [green]hostname[/] [[[i]flags[/]]\n${doc}[b]Options[/]:\n$options")
|
|
|
|
dispatchMulti(
|
|
|
|
[up , usage=hostUse ],
|
|
|
|
[down , usage=hostUse ],
|
|
|
|
[show , usage=clCfg.use ],
|
|
|
|
[killCmd, usage=clCfg.use, cmdName = "kill"],
|
|
|
|
)
|
|
|
|
|