github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/fleetmanager/hypervisors/notifier.go (about) 1 package hypervisors 2 3 import ( 4 "bytes" 5 "flag" 6 "fmt" 7 "net/smtp" 8 "time" 9 ) 10 11 var ( 12 emailDomain = flag.String("emailDomain", "", 13 "Email domain to sent notifications to") 14 smtpServer = flag.String("smtpServer", "", "Address of SMTP server") 15 ) 16 17 func sendEmail(user string, vms []*vmInfoType) error { 18 fromAddress := "DoNotReply@" + *emailDomain 19 toAddress := user + "@" + *emailDomain 20 buffer := &bytes.Buffer{} 21 fmt.Fprintf(buffer, "From: %s\n", fromAddress) 22 fmt.Fprintf(buffer, "To: %s\n", toAddress) 23 fmt.Fprintln(buffer, "Subject: Please migrate your VMs") 24 fmt.Fprintln(buffer) 25 fmt.Fprintln(buffer, 26 "You own the following VMs which are on unhealthy Hypervisors.") 27 fmt.Fprintln(buffer, 28 "Please migrate your VMs to healthy Hypervisors ASAP.") 29 fmt.Fprintln(buffer, "Below is the list of your VMs which are affected:") 30 fmt.Fprintln(buffer) 31 for _, vm := range vms { 32 fmt.Fprintf(buffer, "IP: %s name: %s Hypervisor: %s status: %s\n", 33 vm.Address.IpAddress, vm.Tags["Name"], 34 vm.hypervisor.machine.Hostname, vm.hypervisor.getHealthStatus()) 35 } 36 return smtp.SendMail(*smtpServer, nil, fromAddress, []string{toAddress}, 37 buffer.Bytes()) 38 } 39 40 func (h *hypervisorType) addVmsToMap(vmsPerOwner map[string][]*vmInfoType) { 41 h.mutex.RLock() 42 defer h.mutex.RUnlock() 43 for _, vm := range h.vms { 44 for _, owner := range vm.OwnerUsers { 45 vmsPerOwner[owner] = append(vmsPerOwner[owner], vm) 46 } 47 } 48 } 49 50 func (m *Manager) getBadHypervisors() []*hypervisorType { 51 m.mutex.RLock() 52 defer m.mutex.RUnlock() 53 badHypervisors := make([]*hypervisorType, 0) 54 for _, hypervisor := range m.hypervisors { 55 switch hypervisor.probeStatus { 56 case probeStatusNotYetProbed: 57 continue 58 case probeStatusConnected: 59 if hypervisor.healthStatus == "" { 60 continue 61 } 62 if hypervisor.healthStatus == "healthy" { 63 continue 64 } 65 badHypervisors = append(badHypervisors, hypervisor) 66 default: 67 badHypervisors = append(badHypervisors, hypervisor) 68 } 69 } 70 return badHypervisors 71 } 72 73 func (m *Manager) notifierLoop() { 74 if *emailDomain == "" || *smtpServer == "" { 75 return 76 } 77 for time.Sleep(time.Minute); ; time.Sleep(time.Hour * 48) { 78 m.notify() 79 } 80 } 81 82 func (m *Manager) notify() { 83 badHypervisors := m.getBadHypervisors() 84 if len(badHypervisors) < 1 { 85 return 86 } 87 vmsPerOwner := make(map[string][]*vmInfoType) 88 for _, hypervisor := range badHypervisors { 89 hypervisor.addVmsToMap(vmsPerOwner) 90 } 91 for user, vms := range vmsPerOwner { 92 if err := sendEmail(user, vms); err != nil { 93 m.logger.Printf("error sending email for %s: %s\n", user, err) 94 } 95 } 96 }