feat: Initial commit of the server management tool
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
package serveractions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func WakeServer(name string, servers []Server) {
|
||||
for _, s := range servers {
|
||||
if s.Name == name {
|
||||
fmt.Printf("Sending Wake-on-LAN packet to %s (%s)...\n", s.Name, s.Mac)
|
||||
err := sendMagicPacket(s.Mac)
|
||||
if err != nil {
|
||||
fmt.Printf("Error sending packet: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Packet sent successfully.")
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Printf("Server '%s' not found in configuration.\n", name)
|
||||
}
|
||||
|
||||
func WakeAllServers(servers []Server) {
|
||||
fmt.Println("Waking all servers...")
|
||||
for _, s := range servers {
|
||||
fmt.Printf("Sending Wake-on-LAN packet to %s (%s)...\n", s.Name, s.Mac)
|
||||
err := sendMagicPacket(s.Mac)
|
||||
if err != nil {
|
||||
fmt.Printf(" - Error for %s: %v\n", s.Name, err)
|
||||
} else {
|
||||
fmt.Printf(" - Packet sent to %s.\n", s.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CheckServersStatus(servers []Server) {
|
||||
fmt.Println("Checking server status...")
|
||||
for _, s := range servers {
|
||||
if s.IP == "" {
|
||||
fmt.Printf(" - %-20s [SKIPPED] (No IP configured)\n", s.Name)
|
||||
continue
|
||||
}
|
||||
online := PingHost(s.IP)
|
||||
status := "Offline"
|
||||
if online {
|
||||
status = "Online"
|
||||
}
|
||||
fmt.Printf(" - %-20s [%s]\n", s.Name, status)
|
||||
}
|
||||
}
|
||||
|
||||
func PingHost(host string) bool {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(ctx, "ping", "-c", "1", "-W", "1", host)
|
||||
|
||||
err := cmd.Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Creates and sends a magic packet to the specified MAC address.
|
||||
func sendMagicPacket(macAddr string) error {
|
||||
hwAddr, err := net.ParseMAC(macAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid mac address '%s': %w", macAddr, err)
|
||||
}
|
||||
|
||||
magicPacket := make([]byte, 102)
|
||||
for i := 0; i < 6; i++ {
|
||||
magicPacket[i] = 0xFF
|
||||
}
|
||||
for i := 1; i <= 16; i++ {
|
||||
copy(magicPacket[i*6:], hwAddr)
|
||||
}
|
||||
|
||||
conn, err := net.Dial("udp", "255.255.255.255:9")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Write(magicPacket)
|
||||
return err
|
||||
}
|
||||
|
||||
func ShutdownServer(name string, servers []Server) {
|
||||
for _, s := range servers {
|
||||
if s.Name == name {
|
||||
fmt.Printf("Attempting to shutdown %s...\n", s.Name)
|
||||
err := executeSSHCommand(s, "sudo shutdown -h now")
|
||||
if err != nil {
|
||||
fmt.Printf("Error shutting down %s: %v\n", s.Name, err)
|
||||
} else {
|
||||
fmt.Printf("%s is shutting down.\n", s.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Printf("Server '%s' not found in configuration.\n", name)
|
||||
}
|
||||
|
||||
func RebootServer(name string, servers []Server) {
|
||||
for _, s := range servers {
|
||||
if s.Name == name {
|
||||
fmt.Printf("Attempting to reboot %s...\n", s.Name)
|
||||
err := executeSSHCommand(s, "sudo reboot")
|
||||
if err != nil {
|
||||
fmt.Printf("Error rebooting %s: %v\n", s.Name, err)
|
||||
} else {
|
||||
fmt.Printf("%s is rebooting.\n", s.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Printf("Server '%s' not found in configuration.\n", name)
|
||||
}
|
||||
|
||||
func executeSSHCommand(server Server, command string) error {
|
||||
config := &ssh.ClientConfig{
|
||||
User: server.SSHUser,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password(server.SSHPass),
|
||||
},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
Timeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
client, err := ssh.Dial("tcp", server.IP+":22", config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dial: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
session, err := client.NewSession()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create session: %w", err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
_, err = session.CombinedOutput(command)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run command: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package serveractions
|
||||
|
||||
// Server struct to hold server information
|
||||
type Server struct {
|
||||
Name string `json:"name"`
|
||||
Mac string `json:"mac"`
|
||||
IP string `json:"ip"`
|
||||
SSHUser string `json:"ssh_user"`
|
||||
SSHPass string `json:"ssh_pass"`
|
||||
}
|
||||
Reference in New Issue
Block a user