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 } } } } }