refactor: clean up code from comments

This commit is contained in:
Patryk Hegenberg 2025-04-02 14:21:33 +02:00
parent 4ceed6f301
commit 29bdd3a2a4
8 changed files with 150 additions and 252 deletions

84
app.go
View file

@ -15,7 +15,7 @@ import (
type App struct {
cfg Config
flags Flags
timeStore *TimeStore // Datenbank-Handler hinzugefügt
timeStore *TimeStore
}
func NewApp() (*App, error) {
@ -31,7 +31,7 @@ func NewApp() (*App, error) {
return &App{
cfg: cfg,
timeStore: ts, // TimeStore initialisiert
timeStore: ts,
}, nil
}
@ -47,7 +47,7 @@ func (a *App) connect() {
log.Printf("WARN: Failed to start time tracking for '%s': %v", TagWork, err)
}
a.wakeWorkstation() // Versuche, Workstation zu wecken
a.wakeWorkstation()
sshCon, err := a.newSSHConnection()
if err != nil {
@ -60,7 +60,6 @@ func (a *App) connect() {
go func() {
log.Println("INFO: Starting SSH forwarder (local :2048 -> remote workstation:22)")
if err := sshForwarder.forward(); err != nil {
// Logge Fehler, wenn der Listener nicht gestartet werden kann oder abbricht
log.Printf("ERROR: SSH forwarder failed: %v", err)
}
log.Println("INFO: SSH forwarder stopped.")
@ -84,7 +83,7 @@ func (a *App) runCommand(name string, args ...string) error {
cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin // Wichtig für interaktive Befehle wie ssh
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Printf("ERROR: Command failed: %s %s -> %v", name, strings.Join(args, " "), err)
@ -97,15 +96,15 @@ func (a *App) runCommand(name string, args ...string) error {
func (a *App) wakeWorkstation() {
log.Println("INFO: Attempting to wake workstation...")
innerSSHCmd := fmt.Sprintf("ssh -tt %s@%s \"wakeonlan %s && echo 'Wake-on-LAN packet sent.' && exit\"",
a.cfg.JumpUser, // Benutzer auf dem Jump-Host
a.cfg.JumpHost, // Jump-Host
a.cfg.WorkstationMac) // MAC-Adresse der Workstation
a.cfg.JumpUser,
a.cfg.JumpHost,
a.cfg.WorkstationMac)
outerSSHCmd := []string{
"-tt", // TTY für die äußere Verbindung
"-p", fmt.Sprintf("%d", a.cfg.SSHPort), // Port für den ersten Host
fmt.Sprintf("%s@%s", a.cfg.SSHUser, a.cfg.SSHHost), // user@host für den ersten Host
innerSSHCmd, // Der gesamte innere SSH-Befehl als einzelnes Argument
"-tt",
"-p", fmt.Sprintf("%d", a.cfg.SSHPort),
fmt.Sprintf("%s@%s", a.cfg.SSHUser, a.cfg.SSHHost),
innerSSHCmd,
}
if err := a.runCommand("ssh", outerSSHCmd...); err != nil {
@ -118,23 +117,22 @@ func (a *App) wakeWorkstation() {
func (a *App) connectToJump() {
log.Println("INFO: Connecting to Jump Host with Port Forwarding...")
sshArgs := []string{
"-tt", // TTY Allokation
"-L", fmt.Sprintf("2048:%s:22", a.cfg.WorkstationHost), // Forwarding
"-p", fmt.Sprintf("%d", a.cfg.SSHPort), // Port für den Jump-Host
fmt.Sprintf("%s@%s", a.cfg.SSHUser, a.cfg.SSHHost), // user@jumphost
"-tt",
"-L", fmt.Sprintf("2048:%s:22", a.cfg.WorkstationHost),
"-p", fmt.Sprintf("%d", a.cfg.SSHPort),
fmt.Sprintf("%s@%s", a.cfg.SSHUser, a.cfg.SSHHost),
}
if err := a.runCommand("ssh", sshArgs...); err != nil {
// Fehler wird bereits in runCommand geloggt
}
}
func (a *App) connectToWorkstation() {
log.Println("INFO: Connecting to Workstation via local tunnel (localhost:2048)...")
sshArgs := []string{
"-tt", // TTY
"-L", fmt.Sprintf("6000:%s:3389", a.cfg.WorkstationHost), // RDP Tunnel via Workstation SSH
"-p", "2048", // Verbinde zum lokalen Port des ersten Tunnels
fmt.Sprintf("%s@127.0.0.1", a.cfg.WorkstationUser), // Benutzer@localhost (geht durch den Tunnel)
"-tt",
"-L", fmt.Sprintf("6000:%s:3389", a.cfg.WorkstationHost),
"-p", "2048",
fmt.Sprintf("%s@127.0.0.1", a.cfg.WorkstationUser),
}
if err := a.runCommand("ssh", sshArgs...); err != nil {
}
@ -144,7 +142,7 @@ func (a *App) startRDPConnection() {
log.Println("INFO: Starting RDP connection to localhost:6000...")
rdpCommand := fmt.Sprintf("xfreerdp /u:%s /p:%s /v:127.0.0.1:6000 /size:3000x1350 +clipboard /dynamic-resolution",
a.cfg.RDPUser,
a.cfg.RDPPassword, // SICHERHEITSRISIKO!
a.cfg.SSHPassword,
)
if err := a.runCommand("bash", "-c", rdpCommand); err != nil {
}
@ -158,25 +156,22 @@ func (a *App) makeChoice() {
huh.NewSelect[string]().
Title("What would you like to do?").
Options(
huh.NewOption("Start Work & Connect", "start work"), // Kombinierte Aktion
huh.NewOption("Start Work & Connect", "start work"),
huh.NewOption("Stop Work", "stop work"),
huh.NewOption("Start Break", "start break"),
huh.NewOption("Stop Break", "stop break"),
// huh.NewOption("--- Summaries ---", "").Disabled(true), // Trenner
huh.NewOption("Show Today Summary", "show day summary"),
huh.NewOption("Show Week Summary", "show week summary"),
huh.NewOption("Show Month Summary", "show month summary"),
huh.NewOption("Export Yearly Timetable", "export"),
// huh.NewOption("--- Connections ---", "").Disabled(true), // Trenner
huh.NewOption("Connect to Jump Host (Tunnel to Workstation)", "connect to jump"),
huh.NewOption("Connect to Workstation (via Tunnel)", "connect to workstation"),
huh.NewOption("Start RDP Connection (via Tunnel)", "start rdp connection"),
huh.NewOption("Wake Workstation", "wake workstation"),
// huh.NewOption("--- Maintenance ---", "").Disabled(true), // Trenner
huh.NewOption("Kill Active Tunnels (Ports 2048, 6000)", "kill tunnels"),
huh.NewOption("Exit", "exit"),
).
Value(&choice), // Speichere die Auswahl in 'choice'
Value(&choice),
),
)
@ -192,7 +187,7 @@ func (a *App) makeChoice() {
switch choice {
case "start work":
a.connect() // Startet Zeit, weckt Rechner, baut Tunnel auf
a.connect()
case "stop work":
if err := a.timeStore.StopTracking(); err != nil {
log.Printf("ERROR: Failed to stop time tracking: %v", err)
@ -222,18 +217,18 @@ func (a *App) makeChoice() {
}
case "export":
filename := "Arbeitszeiten_" + time.Now().Format("2006") + ".xlsx"
if a.flags.ExportName != "" && a.flags.ExportName != "Arbeitszeiten.xlsx" { // Check ob Flag von CLI kommt
if a.flags.ExportName != "" && a.flags.ExportName != "Arbeitszeiten.xlsx" {
filename = a.flags.ExportName
}
if err := a.timeStore.ExportSummary(filename); err != nil {
log.Printf("ERROR: Failed to export summary to '%s': %v", filename, err)
}
case "connect to jump":
a.connectToJump() // Blockiert
a.connectToJump()
case "connect to workstation":
a.connectToWorkstation() // Blockiert
a.connectToWorkstation()
case "start rdp connection":
a.startRDPConnection() // Blockiert
a.startRDPConnection()
case "wake workstation":
a.wakeWorkstation()
case "kill tunnels":
@ -244,20 +239,20 @@ func (a *App) makeChoice() {
}
case "exit":
fmt.Println("Exiting.")
return // Beendet die Funktion, was zum Programmende führt
return
default:
log.Printf("WARN: Unhandled choice '%s'", choice)
}
if choice != "exit" && choice != "connect to jump" && choice != "connect to workstation" && choice != "start rdp connection" {
fmt.Println("\nPress Enter to continue...")
fmt.Scanln() // Warte auf Enter
a.makeChoice() // Rufe Menü erneut auf
fmt.Scanln()
a.makeChoice()
}
}
func (a *App) getSSHAuth() ssh.AuthMethod {
keyPath := os.ExpandEnv("$HOME/.ssh/hegenberg") // Sicherer Standard
keyPath := os.ExpandEnv("$HOME/.ssh/hegenberg")
keyBytes, err := os.ReadFile(keyPath)
if err != nil {
@ -292,10 +287,8 @@ func (a *App) newSSHConnection() (*SSHConnection, error) {
}
sshConfig := &ssh.ClientConfig{
User: a.cfg.SSHUser,
Auth: []ssh.AuthMethod{authMethod},
// ACHTUNG: InsecureIgnoreHostKey ist unsicher für Produktionsumgebungen!
// Besser: Known Hosts verwenden.
User: a.cfg.SSHUser,
Auth: []ssh.AuthMethod{authMethod},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 10 * time.Second, // Etwas längerer Timeout
}
@ -318,7 +311,6 @@ func (a *App) newSSHConnection() (*SSHConnection, error) {
return &SSHConnection{
client: client,
// session: session, // Session wird für Forwarding nicht direkt gebraucht
}, nil
}
@ -330,8 +322,6 @@ func (a *App) killForwardings() error {
log.Println("INFO: Attempting to kill processes listening on ports:", strings.Join(ports, ", "))
for _, port := range ports {
// Finde Prozess-ID (PID), die auf dem TCP-Port lauscht
// lsof -i tcp:<port> -t gibt nur die PID aus
cmd := exec.Command("lsof", "-i", "tcp:"+port, "-t")
output, err := cmd.Output()
if err != nil {
@ -339,9 +329,9 @@ func (a *App) killForwardings() error {
log.Printf("INFO: No process found listening on port %s.", port)
} else {
log.Printf("WARN: 'lsof' command failed for port %s: %v", port, err)
lastErr = fmt.Errorf("lsof failed for port %s: %w", port, err) // Letzten Fehler merken
lastErr = fmt.Errorf("lsof failed for port %s: %w", port, err)
}
continue // Gehe zum nächsten Port
continue
}
pids := strings.SplitSeq(strings.TrimSpace(string(output)), "\n")
@ -351,7 +341,7 @@ func (a *App) killForwardings() error {
continue
}
log.Printf("INFO: Found process PID %s on port %s. Attempting to kill...", pid, port)
killCmd := exec.Command("kill", pid) // SIGTERM senden
killCmd := exec.Command("kill", pid)
if err := killCmd.Run(); err != nil {
log.Printf("WARN: Failed to kill PID %s (port %s): %v. Trying kill -9...", pid, port, err)
forceKillCmd := exec.Command("kill", "-9", pid)
@ -375,5 +365,5 @@ func (a *App) killForwardings() error {
log.Println("INFO: No forwarding processes found or killed.")
}
return lastErr // Gibt den letzten aufgetretenen Fehler zurück
return lastErr
}