253 lines
6 KiB
Go
253 lines
6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/charmbracelet/huh"
|
|
"github.com/spf13/viper"
|
|
"golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
type Config struct {
|
|
SSHUser string `mapstructure:"SSH_USER"`
|
|
SSHHost string `mapstructure:"SSH_HOST"`
|
|
JumpUser string `mapstructure:"JUMP_USER"`
|
|
JumpHost string `mapstructure:"JUMP_HOST"`
|
|
WorkstationHost string `mapstructure:"WORKSTATION_HOST"`
|
|
WorkstationUser string `mapstructure:"WWORKSTATION_USER"`
|
|
WorkstationMac string `mapstructure:"WORKSTATION_MAC"`
|
|
RDPUser string `mapstructure:"RDP_USER"`
|
|
RDPPassword string `mapstructure:"RDP_PASSWORD"`
|
|
WorkstationIP string `mapstructure:"WORKSTATION_IP"`
|
|
SSHPort int `mapstructure:"SSH_PORT"`
|
|
}
|
|
|
|
var cfg Config
|
|
|
|
func init() {
|
|
log.Println("Loading Config File")
|
|
configPath, err := os.UserConfigDir()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
workConfigPath := filepath.Join(configPath, "work")
|
|
configFile := filepath.Join(workConfigPath, "config.toml")
|
|
viper.SetConfigFile(configFile)
|
|
viper.SetConfigType("toml")
|
|
viper.AddConfigPath(".")
|
|
viper.AutomaticEnv()
|
|
|
|
err = viper.ReadInConfig()
|
|
if err != nil {
|
|
log.Printf("error loading config file: %v", err)
|
|
}
|
|
allSettings := viper.AllSettings()
|
|
log.Printf("All loaded settings: %+v", allSettings)
|
|
|
|
err = viper.UnmarshalKey("default", &cfg)
|
|
if err != nil {
|
|
log.Printf("unable to decode into struct: %v", err)
|
|
}
|
|
}
|
|
|
|
func connect() {
|
|
runCommand("timew", "start", "work")
|
|
wakeLou()
|
|
sshClient, err := ssh.Dial("tcp", cfg.SSHHost+":"+fmt.Sprintf("%v", cfg.SSHPort), makeSSHClient())
|
|
if err != nil {
|
|
log.Fatal("Failed to dial: ", err)
|
|
}
|
|
defer sshClient.Close()
|
|
|
|
session, err := sshClient.NewSession()
|
|
if err != nil {
|
|
log.Fatal("Failed to create session: ", err)
|
|
}
|
|
defer session.Close()
|
|
|
|
go forwardPort(sshClient, "2048", cfg.WorkstationIP, "22")
|
|
|
|
go forwardPort(sshClient, "6000", cfg.WorkstationIP, "3389")
|
|
|
|
connectToLou()
|
|
}
|
|
|
|
func forwardPort(sshConn *ssh.Client, localPort, remoteHost, remotePort string) {
|
|
listener, err := net.Listen("tcp", "127.0.0.1:"+localPort)
|
|
if err != nil {
|
|
log.Printf("Fehler beim Öffnen des lokalen Ports %s: %v", localPort, err)
|
|
return
|
|
}
|
|
defer listener.Close()
|
|
|
|
for {
|
|
localConn, err := listener.Accept()
|
|
if err != nil {
|
|
log.Printf("Fehler beim Akzeptieren der Verbindung: %v", err)
|
|
continue
|
|
}
|
|
|
|
remoteConn, err := sshConn.Dial("tcp", remoteHost+":"+remotePort)
|
|
if err != nil {
|
|
log.Printf("Fehler beim Verbinden zum Remote-Host %s:%s: %v", remoteHost, remotePort, err)
|
|
localConn.Close()
|
|
continue
|
|
}
|
|
|
|
go copyConn(localConn, remoteConn)
|
|
go copyConn(remoteConn, localConn)
|
|
}
|
|
}
|
|
|
|
func copyConn(dst, src net.Conn) {
|
|
defer dst.Close()
|
|
defer src.Close()
|
|
io.Copy(dst, src)
|
|
}
|
|
|
|
func makeSSHClient() *ssh.ClientConfig {
|
|
keypath := os.ExpandEnv("$HOME/.ssh/hegenberg")
|
|
keyBytes, err := os.ReadFile(keypath)
|
|
if err != nil {
|
|
log.Fatalf("Failed to read private key: %s", err)
|
|
}
|
|
|
|
key, err := ssh.ParsePrivateKeyWithPassphrase(keyBytes, []byte(cfg.RDPPassword))
|
|
if err != nil {
|
|
log.Fatalf("Failed to parse private key: %s", err)
|
|
}
|
|
|
|
return &ssh.ClientConfig{
|
|
User: cfg.SSHUser,
|
|
Auth: []ssh.AuthMethod{
|
|
ssh.PublicKeys(key),
|
|
},
|
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
}
|
|
|
|
func runCommand(name string, args ...string) {
|
|
cmd := exec.Command(name, args...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdin = os.Stdin
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
fmt.Println("Error:", err)
|
|
}
|
|
}
|
|
|
|
func startSequence() {
|
|
runCommand("timew", "start", "work")
|
|
wakeLou()
|
|
connectToVarda()
|
|
}
|
|
|
|
func wakeLou() {
|
|
sshCommand := fmt.Sprintf("ssh -tt -p %s %s@%s ssh -tt %s@%s \"wakeonlan %s && exit\"",
|
|
fmt.Sprintf("%v", cfg.SSHPort),
|
|
cfg.SSHUser,
|
|
cfg.SSHHost,
|
|
cfg.JumpUser,
|
|
cfg.JumpHost,
|
|
cfg.WorkstationMac)
|
|
args := strings.Split(sshCommand, " ")
|
|
log.Println(args)
|
|
runCommand("ssh", args[1:]...)
|
|
}
|
|
|
|
func connectToVarda() {
|
|
sshCommand := fmt.Sprintf("ssh -tt -L 2048:%s:22 %s@%s",
|
|
cfg.WorkstationHost,
|
|
cfg.SSHUser,
|
|
cfg.SSHHost)
|
|
args := strings.Split(sshCommand, " ")
|
|
runCommand("ssh", args[1:]...)
|
|
}
|
|
|
|
func connectToLou() {
|
|
sshCommand := fmt.Sprintf("ssh -tt -L 6000:%s:3389 -p 2048 %s@127.0.0.1",
|
|
cfg.WorkstationHost,
|
|
cfg.SSHUser)
|
|
args := strings.Split(sshCommand, " ")
|
|
runCommand("ssh", args[1:]...)
|
|
}
|
|
|
|
func startRDPConnection() {
|
|
rdpCommand := fmt.Sprintf("xfreerdp /u:%s /p:%s /v:127.0.0.1:6000 /size:3000x1350",
|
|
cfg.RDPUser,
|
|
cfg.RDPPassword)
|
|
runCommand("bash", "-c", rdpCommand)
|
|
}
|
|
|
|
func makeChoice() {
|
|
var choice string
|
|
form := huh.NewForm(
|
|
huh.NewGroup(
|
|
huh.NewSelect[string]().
|
|
Title("What would you like to do?").
|
|
Options(
|
|
huh.NewOption("Start", "Start"),
|
|
huh.NewOption("Stop Work", "stop Work"),
|
|
huh.NewOption("Show Week Summary", "show week summary"),
|
|
huh.NewOption("Show Month Summary", "show month summary"),
|
|
huh.NewOption("Start Break", "start break"),
|
|
huh.NewOption("Stop Break", "stop break"),
|
|
huh.NewOption("Export Timetable", "export"),
|
|
huh.NewOption("Wake Lou", "wake lou"),
|
|
huh.NewOption("Connect to Varda", "connect to varda"),
|
|
huh.NewOption("Connect to Lou", "connect to lou"),
|
|
huh.NewOption("Start RDP Connection", "start rdp connection"),
|
|
).
|
|
Value(&choice),
|
|
),
|
|
)
|
|
|
|
err := form.Run()
|
|
if err != nil {
|
|
fmt.Println("Error:", err)
|
|
return
|
|
}
|
|
|
|
switch choice {
|
|
case "Start":
|
|
connect()
|
|
// startSequence()
|
|
case "stop Work":
|
|
runCommand("timew", "stop", "work")
|
|
case "start break":
|
|
runCommand("timew", "stop", "work")
|
|
runCommand("timew", "start", "break")
|
|
case "stop break":
|
|
runCommand("timew", "stop", "break")
|
|
runCommand("timew", "start", "work")
|
|
case "show week summary":
|
|
runCommand("timew", "summary", ":week", "work")
|
|
case "show month summary":
|
|
runCommand("timew", "summary", ":month", "work")
|
|
case "wake lou":
|
|
wakeLou()
|
|
case "connect to varda":
|
|
connectToVarda()
|
|
case "connect to lou":
|
|
connectToLou()
|
|
case "start rdp connection":
|
|
startRDPConnection()
|
|
case "export":
|
|
fmt.Println("Exporting Work times")
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
makeChoice()
|
|
}
|