esxi-monitor/cmd/watchdog/main.go

93 lines
1.8 KiB
Go
Executable File

package main
import (
"context"
"fmt"
"os"
"time"
"github.com/go-ping/ping"
_ "github.com/go-ping/ping"
"github.com/tursom/esxi-monitor/vmomi"
)
func main() {
cfg, err := parseConfig("config.yaml")
if err != nil {
panic(err)
}
watchTargets := make(map[string]*watchVm)
for _, watch := range cfg.Watch {
watchTargets[watch.Name] = watch
}
client, err := vmomi.Connect("https://esxi/sdk", cfg.User, cfg.Password)
if err != nil {
panic(err)
}
vms, err := vmomi.ListVms(client.Client)
if err != nil {
panic(err)
}
// ip -> vm instance
watches := make(map[string]*vmomi.VirtualMachine)
for _, vm := range vms {
target, contains := watchTargets[vm.Name()]
if !contains {
continue
}
fmt.Printf("watching virtual machine: addr=%s, name=%s\n", target.Addr, vm.Name())
watches[target.Addr] = vm
}
doWatch(watches)
}
// watches map ip -> vm instance
func doWatch(watches map[string]*vmomi.VirtualMachine) {
t := time.NewTicker(time.Minute)
for {
<-t.C
for ip, vm := range watches {
pinger, err := ping.NewPinger(ip)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "ping to target failed: %s\n", err)
continue
}
pinger.Count = 4
err = pinger.Run()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "ping to target failed: %s\n", err)
continue
}
statistics := pinger.Statistics()
if statistics.PacketsRecv == 0 {
fmt.Printf("restarting vm %s(%s)", ip, vm.Name())
task, err := vm.Reset()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "restart vm failed: %s\n", err)
continue
}
ctx, _ := context.WithTimeout(context.Background(), time.Minute)
err = task.Wait(ctx)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "restart vm failed: %s\n", err)
continue
}
}
}
}
}