93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|