utils/tunnel-go/main.go
2024-08-16 11:02:24 -05:00

74 lines
2 KiB
Go

package main
import (
"fmt"
"log"
"os"
"os/exec"
"github.com/bitfield/script"
"github.com/spf13/cobra"
)
func logFail(cond bool, s string, args ...interface{}) {
if !cond {
log.Fatalf(s, args...)
}
}
func ok(cmd *exec.Cmd) bool { err := cmd.Run(); return err == nil }
func portString() string { return fmt.Sprintf("%[1]d:localhost:%[1]d", port) }
func checkControl() bool { return ok(exec.Command("ssh", "-O", "check", host)) }
func activateSshControl() bool { return ok(exec.Command("ssh", "-M", "-f", "-N", host)) }
func connectPort() bool { return ok(exec.Command("ssh", "-fNL", portString(), host)) }
func deactivateSshControl() bool { return ok(exec.Command("ssh", "-O", "exit", host)) }
func genSubCmd(use string, short string, run func()) *cobra.Command {
return &cobra.Command{
Use: use, Short: short, Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
host = args[0]
run()
},
}
}
func tunnelUp() {
if !checkControl() {
logFail(activateSshControl(), "failed to activate ssh for host: %s", host)
}
logFail(connectPort(), "failed to connect to host: %s with port: %d", host, port)
}
func tunnelDown() { logFail(deactivateSshControl(), "failed to disable ssh control %s", host) }
func tunnelShow() {
script.ListFiles("/home/daylin/.ssh").Stdout()
}
var (
rootCmd = &cobra.Command{Use: "tunnel", Short: "control ssh tunnels"}
upCmd = genSubCmd("up hostname [flags]", "activate ssh tunnel", tunnelUp)
downCmd = genSubCmd("down hostname [flags]", "deactivate ssh tunnel", tunnelDown)
showCmd = &cobra.Command{Use: "show", Short: "show activate tunnels", Run: func(cmd *cobra.Command, args []string) { tunnelShow() }}
)
var (
port uint64
host string
)
func init() {
rootCmd.CompletionOptions.HiddenDefaultCmd = true
rootCmd.AddCommand(upCmd)
rootCmd.AddCommand(downCmd)
rootCmd.AddCommand(showCmd)
upCmd.Flags().Uint64VarP(&port, "port", "p", 0, "port number")
upCmd.MarkFlagRequired("port")
}
func main() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}