package main import ( "flag" "fmt" "os" serveractions "manage-servers/server-actions" "manage-servers/webserver" "github.com/spf13/viper" ) func main() { debug := flag.Bool("debug", false, "Enable debug logging") flag.Parse() if *debug { serveractions.Debug = true serveractions.LogDebug("Debug mode enabled") } args := flag.Args() if len(args) < 1 { printUsage() return } servers, err := loadConfig() if err != nil { fmt.Printf("Error loading servers: %v\n", err) return } serveractions.LogDebug("Loaded %d servers from config", len(servers)) command := args[0] switch command { case "list": listServers(servers) case "wake": if len(args) < 2 { fmt.Println("Please specify a server name to wake.") printUsage() return } serverName := args[1] serveractions.WakeServer(serverName, servers) case "wakeall": serveractions.WakeAllServers(servers) case "status": serveractions.CheckServersStatus(servers) case "shutdown": if len(args) < 2 { fmt.Println("Please specify a server name to shutdown.") printUsage() return } serverName := args[1] serveractions.ShutdownServer(serverName, servers) case "reboot": if len(args) < 2 { fmt.Println("Please specify a server name to reboot.") printUsage() return } serverName := args[1] serveractions.RebootServer(serverName, servers) case "serve": webserver.StartWebServer(servers) default: fmt.Printf("Unknown command: %s\n", command) printUsage() } } func printUsage() { fmt.Println("Usage: go run . [--debug] ") fmt.Println("Options:") fmt.Println(" --debug - Enable debug logging") fmt.Println("Commands:") fmt.Println(" list - List all configured servers") fmt.Println(" wake - Wake a specific server") fmt.Println(" wakeall - Wake all configured servers") fmt.Println(" status - Check the status of all servers") fmt.Println(" shutdown - Shutdown a specific server") fmt.Println(" reboot - Reboot a specific server") fmt.Println(" serve - Start a web server to manage servers") } func loadConfig() ([]serveractions.Server, error) { viper.SetConfigName("servers") // name of config file (without extension) viper.SetConfigType("json") // or viper.SetConfigType("YAML") viper.AddConfigPath("./config") // path to look for the config file in viper.AddConfigPath(".") // optionally look for config in the working directory err := viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file // Check if the error is that the file doesn't exist if _, ok := err.(viper.ConfigFileNotFoundError); ok { os.WriteFile("debug_config.log", []byte("Config file not found\n"), 0644) // Config file not found; ignore error and return empty server list return []serveractions.Server{}, nil } return nil, fmt.Errorf("fatal error config file: %w", err) } var servers []serveractions.Server err = viper.UnmarshalKey("servers", &servers) if err != nil { return nil, fmt.Errorf("unable to decode into struct, %v", err) } return servers, nil } func listServers(servers []serveractions.Server) { fmt.Println("Configured Servers:") for _, s := range servers { fmt.Printf(" - %s (%s) - %s - User: %s\n", s.Name, s.IP, s.Mac, s.SSHUser) } }