first commit
This commit is contained in:
11
go.mod
Normal file
11
go.mod
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module nathan/go-events
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require github.com/vmware/govmomi v0.30.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/dougm/pretty v0.0.0-20171025230240-2ee9d7453c02 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||||
|
)
|
11
go.sum
Normal file
11
go.sum
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/dougm/pretty v0.0.0-20171025230240-2ee9d7453c02 h1:tR3jsKPiO/mb6ntzk/dJlHZtm37CPfVp1C9KIo534+4=
|
||||||
|
github.com/dougm/pretty v0.0.0-20171025230240-2ee9d7453c02/go.mod h1:7NQ3kWOx2cZOSjtcveTa5nqupVr2s6/83sG+rTlI7uA=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
|
github.com/vmware/govmomi v0.30.4 h1:BCKLoTmiBYRuplv3GxKEMBLtBaJm8PA56vo9bddIpYQ=
|
||||||
|
github.com/vmware/govmomi v0.30.4/go.mod h1:F7adsVewLNHsW/IIm7ziFURaXDaHEwcc+ym4r3INMdY=
|
242
main.go
Normal file
242
main.go
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi"
|
||||||
|
"github.com/vmware/govmomi/event"
|
||||||
|
"github.com/vmware/govmomi/vim25/methods"
|
||||||
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var c *govmomi.Client
|
||||||
|
var ctx context.Context
|
||||||
|
var cancel context.CancelFunc
|
||||||
|
|
||||||
|
func exit(err error) {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEvents(eventTypes []string, begin time.Duration, end time.Duration) []types.Event {
|
||||||
|
var returnEvents []types.Event
|
||||||
|
// Refer https://github.com/vmware/govmomi/blob/main/examples/events/main.go
|
||||||
|
now, err := methods.GetCurrentTime(ctx, c) // vCenter server time (UTC)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error getting vCenter time: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("vCenter time is '%v'\n", now)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := event.NewManager(c.Client)
|
||||||
|
root := c.ServiceContent.RootFolder
|
||||||
|
|
||||||
|
// configure the event stream filter (begin of stream)
|
||||||
|
filter := types.EventFilterSpec{
|
||||||
|
EventTypeId: eventTypes, // only stream specific types, e.g. VmEvent
|
||||||
|
Entity: &types.EventFilterSpecByEntity{
|
||||||
|
Entity: root,
|
||||||
|
Recursion: types.EventFilterSpecRecursionOptionAll,
|
||||||
|
},
|
||||||
|
Time: &types.EventFilterSpecByTime{
|
||||||
|
BeginTime: types.NewTime(now.Add(begin * -1)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if end != 0 {
|
||||||
|
filter.Time.EndTime = types.NewTime(now.Add(end * -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
collector, err := m.CreateCollectorForEvents(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error creating event collector: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer collector.Destroy(ctx)
|
||||||
|
|
||||||
|
for {
|
||||||
|
events, err := collector.ReadNextEvents(ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error reading events: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(events) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range events {
|
||||||
|
event := events[i].GetEvent()
|
||||||
|
returnEvents = append(returnEvents, *event)
|
||||||
|
kind := reflect.TypeOf(events[i]).Elem().Name()
|
||||||
|
fmt.Printf("%d [%s] [%s] %s\n", event.Key, event.CreatedTime.Format(time.ANSIC), kind, event.FullFormattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Command line flags for the vCenter connection
|
||||||
|
vURL := flag.String("url", "", "The URL of a vCenter server, eg https://server.domain.example/sdk")
|
||||||
|
vUser := flag.String("user", "", "The username to use when connecting to vCenter")
|
||||||
|
vPass := flag.String("password", "", "The password to use when connecting to vCenter")
|
||||||
|
vInsecure := flag.Bool("insecure", true, "Allow insecure connections to vCenter")
|
||||||
|
begin := flag.Duration("b", time.Hour, "Begin time") // default BeginTime is 1h ago
|
||||||
|
end := flag.Duration("e", 0, "End time")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
u, err := url.Parse(*vURL)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error parsing url %s : %s\n", *vURL, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Printf("Connecting to vCenter %s\n", u)
|
||||||
|
u.User = url.UserPassword(*vUser, *vPass)
|
||||||
|
|
||||||
|
ctx, cancel = context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Login to vcenter
|
||||||
|
c, err = govmomi.NewClient(ctx, u, *vInsecure)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Logging in error: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer c.Logout(ctx)
|
||||||
|
|
||||||
|
getEvents([]string{"com.vmware.vc.HA.DasHostFailedEvent"}, *begin, *end)
|
||||||
|
|
||||||
|
// Selecting default datacenter
|
||||||
|
/*
|
||||||
|
finder := find.NewFinder(c.Client, true)
|
||||||
|
dc, err := finder.DefaultDatacenter(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
//refs := []types.ManagedObjectReference{dc.Reference()}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Refer https://github.com/vmware/govmomi/blob/main/examples/events/main.go
|
||||||
|
now, err := methods.GetCurrentTime(ctx, c) // vCenter server time (UTC)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error getting vCenter time: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := event.NewManager(c.Client)
|
||||||
|
root := c.ServiceContent.RootFolder
|
||||||
|
|
||||||
|
// configure the event stream filter (begin of stream)
|
||||||
|
filter := types.EventFilterSpec{
|
||||||
|
EventTypeId: []string{"com.vmware.vc.HA.DasHostFailedEvent"}, // only stream specific types, e.g. VmEvent
|
||||||
|
Entity: &types.EventFilterSpecByEntity{
|
||||||
|
Entity: root,
|
||||||
|
Recursion: types.EventFilterSpecRecursionOptionAll,
|
||||||
|
},
|
||||||
|
Time: &types.EventFilterSpecByTime{
|
||||||
|
BeginTime: types.NewTime(now.Add(*begin * -1)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if *end != 0 {
|
||||||
|
filter.Time.EndTime = types.NewTime(now.Add(*end * -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
collector, err := m.CreateCollectorForEvents(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error creating event collector: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer collector.Destroy(ctx)
|
||||||
|
|
||||||
|
for {
|
||||||
|
events, err := collector.ReadNextEvents(ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error reading events: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(events) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range events {
|
||||||
|
event := events[i].GetEvent()
|
||||||
|
kind := reflect.TypeOf(events[i]).Elem().Name()
|
||||||
|
fmt.Printf("%d [%s] [%s] %s\n", event.Key, event.CreatedTime.Format(time.ANSIC), kind, event.FullFormattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// **************
|
||||||
|
// previous code here
|
||||||
|
/*
|
||||||
|
// Do a recursive search for all the ESXi hosts (which have a type of HostSystem)
|
||||||
|
m := view.NewManager(c.Client)
|
||||||
|
v, _ := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{"HostSystem"}, true)
|
||||||
|
|
||||||
|
// Specify what properties we want to retrieve
|
||||||
|
var hs []mo.HostSystem
|
||||||
|
err = v.Retrieve(ctx, []string{"HostSystem"}, []string{"summary", "runtime"}, &hs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "error: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the actual esxcli command on each host
|
||||||
|
finder := find.NewFinder(c.Client)
|
||||||
|
for _, host := range hs {
|
||||||
|
//fmt.Printf("Host name %s is %s\n", host.Summary.Config.Name, host.Runtime.ConnectionState)
|
||||||
|
|
||||||
|
// Make sure that the host is connected before we try running an esxcli command
|
||||||
|
if host.Runtime.ConnectionState == "connected" {
|
||||||
|
// Get a reference to the host object so that we can check the ramdisk values
|
||||||
|
objRef, err := finder.ObjectReference(ctx, host.Reference())
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error getting reference to host : %s\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the HostSystem object
|
||||||
|
hs, ok := objRef.(*object.HostSystem)
|
||||||
|
if !ok {
|
||||||
|
fmt.Fprintf(os.Stderr, "Couldn't find Hostsytem : %s\n", host.Reference())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a reference to the esxcli executor
|
||||||
|
// https://gowalker.org/github.com/dhawalseth/govc-autocomplete/govc/host/esxcli
|
||||||
|
// https://pkg.go.dev/github.com/vmware/govmomi/govc/host/esxcli
|
||||||
|
// https://github.com/vmware/govmomi/blob/f4c5c4a58e445ba31393795c7e678fa05fb3452a/govc/host/esxcli/esxcli.go
|
||||||
|
// https://golang.hotexamples.com/examples/github.com.vmware.govmomi.object/HostSystem/-/golang-hostsystem-class-examples.html
|
||||||
|
// https://golang.hotexamples.com/examples/github.com.vmware.govmomi.govc.host.esxcli/-/GetFirewallInfo/golang-getfirewallinfo-function-examples.html
|
||||||
|
e, err := esxcli.NewExecutor(c.Client, hs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error getting esxcli executor: %s\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the desired esxcli command
|
||||||
|
result, err := e.Run([]string{"system", "visorfs", "ramdisk", "list"})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error running esxcli command: %s\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print out all the values
|
||||||
|
for _, values := range result.Values {
|
||||||
|
fmt.Printf("%s;%s;%s\n", host.Summary.Config.Name, values["RamdiskName"][0], values["Free"][0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
Reference in New Issue
Block a user