diff --git a/go.mod b/go.mod index 71793b554..32ec8954a 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.7.1 github.com/ubccr/kerby v0.0.0-20170626144437-201a958fc453 - github.com/vmware/govmomi v0.27.4 + github.com/vmware/govmomi v0.28.0 golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220412211240-33da011f77ad diff --git a/go.sum b/go.sum index 868acffa9..aa9d2ee54 100644 --- a/go.sum +++ b/go.sum @@ -166,16 +166,18 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +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/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -470,12 +472,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI= github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= @@ -621,10 +625,13 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rasky/go-xdr v0.0.0-20170217172119-4930550ba2e2/go.mod h1:Nfe4efndBz4TibWycNE+lqyJZiMX4ycx+QKV8Ta0f/o= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -685,8 +692,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmware/govmomi v0.27.4 h1:5kY8TAkhB20lsjzrjE073eRb8+HixBI29PVMG5lxq6I= -github.com/vmware/govmomi v0.27.4/go.mod h1:daTuJEcQosNMXYJOeku0qdBJP9SOLLWB3Mqz8THtv6o= +github.com/vmware/govmomi v0.28.0 h1:VgeQ/Rvz79U9G8QIKLdgpsN9AndHJL+5iMJLgYIrBGI= +github.com/vmware/govmomi v0.28.0/go.mod h1:F7adsVewLNHsW/IIm7ziFURaXDaHEwcc+ym4r3INMdY= github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/vendor/github.com/kr/pretty/.gitignore b/vendor/github.com/dougm/pretty/.gitignore similarity index 100% rename from vendor/github.com/kr/pretty/.gitignore rename to vendor/github.com/dougm/pretty/.gitignore diff --git a/vendor/github.com/kr/pretty/License b/vendor/github.com/dougm/pretty/License similarity index 97% rename from vendor/github.com/kr/pretty/License rename to vendor/github.com/dougm/pretty/License index 480a32805..05c783ccf 100644 --- a/vendor/github.com/kr/pretty/License +++ b/vendor/github.com/dougm/pretty/License @@ -1,3 +1,5 @@ +The MIT License (MIT) + Copyright 2012 Keith Rarick Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/vendor/github.com/kr/pretty/Readme b/vendor/github.com/dougm/pretty/Readme similarity index 100% rename from vendor/github.com/kr/pretty/Readme rename to vendor/github.com/dougm/pretty/Readme diff --git a/vendor/github.com/kr/pretty/diff.go b/vendor/github.com/dougm/pretty/diff.go similarity index 100% rename from vendor/github.com/kr/pretty/diff.go rename to vendor/github.com/dougm/pretty/diff.go diff --git a/vendor/github.com/kr/pretty/formatter.go b/vendor/github.com/dougm/pretty/formatter.go similarity index 88% rename from vendor/github.com/kr/pretty/formatter.go rename to vendor/github.com/dougm/pretty/formatter.go index bf4b598d0..4941b0cf4 100644 --- a/vendor/github.com/kr/pretty/formatter.go +++ b/vendor/github.com/dougm/pretty/formatter.go @@ -6,10 +6,15 @@ import ( "reflect" "strconv" "text/tabwriter" + "time" "github.com/kr/text" ) +var ( + timeType = reflect.TypeOf(time.Time{}) +) + type formatter struct { v reflect.Value force bool @@ -37,7 +42,7 @@ func (fo formatter) passThrough(f fmt.State, c rune) { s := "%" for i := 0; i < 128; i++ { if f.Flag(i) { - s += string(rune(i)) + s += string(i) } } if w, ok := f.Width(); ok { @@ -125,6 +130,7 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { } keys := v.MapKeys() for i := 0; i < v.Len(); i++ { + showTypeInStruct := true k := keys[i] mv := v.MapIndex(k) pp.printValue(k, false, true) @@ -132,7 +138,7 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { if expand { writeByte(pp, '\t') } - showTypeInStruct := t.Elem().Kind() == reflect.Interface + showTypeInStruct = t.Elem().Kind() == reflect.Interface pp.printValue(mv, showTypeInStruct, true) if expand { io.WriteString(pp, ",\n") @@ -147,6 +153,11 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { writeByte(p, '}') case reflect.Struct: t := v.Type() + if t == timeType { + io.WriteString(p, "time.Now()") + break + } + if v.CanAddr() { addr := v.UnsafeAddr() vis := visit{addr, t} @@ -171,6 +182,9 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { for i := 0; i < v.NumField(); i++ { showTypeInStruct := true if f := t.Field(i); f.Name != "" { + if f.Name == "DynamicData" { + continue + } io.WriteString(pp, f.Name) writeByte(pp, ':') if expand { @@ -215,6 +229,10 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { io.WriteString(p, "nil") break } + if !showType { + // we always want the type for slices + io.WriteString(p, t.String()) + } writeByte(p, '{') expand := !canInline(v.Type()) pp := p @@ -242,10 +260,23 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { io.WriteString(p, v.Type().String()) io.WriteString(p, ")(nil)") } else { - pp := *p - pp.depth++ - writeByte(pp, '&') - pp.printValue(e, true, true) + switch e.Kind() { + case reflect.Bool: + io.WriteString(p, fmt.Sprintf("types.NewBool(%v)", e.Bool())) + case reflect.Int32: + io.WriteString(p, fmt.Sprintf("types.NewInt32(%v)", e.Int())) + case reflect.Int64: + io.WriteString(p, fmt.Sprintf("types.NewInt64(%v)", e.Int())) + default: + if e.Kind() == reflect.Struct && e.Type() == timeType { + io.WriteString(p, "types.NewTime(time.Now())") + } else { + pp := *p + pp.depth++ + writeByte(pp, '&') + pp.printValue(e, true, true) + } + } } case reflect.Chan: x := v.Pointer() diff --git a/vendor/github.com/kr/pretty/pretty.go b/vendor/github.com/dougm/pretty/pretty.go similarity index 98% rename from vendor/github.com/kr/pretty/pretty.go rename to vendor/github.com/dougm/pretty/pretty.go index b4ca583c0..49423ec7f 100644 --- a/vendor/github.com/kr/pretty/pretty.go +++ b/vendor/github.com/dougm/pretty/pretty.go @@ -75,7 +75,7 @@ func Printf(format string, a ...interface{}) (n int, errno error) { // Println pretty-prints its operands and writes to standard output. // -// Calling Println(x, y) is equivalent to +// Calling Print(x, y) is equivalent to // fmt.Println(Formatter(x), Formatter(y)), but each operand is // formatted with "%# v". func Println(a ...interface{}) (n int, errno error) { diff --git a/vendor/github.com/kr/pretty/zero.go b/vendor/github.com/dougm/pretty/zero.go similarity index 100% rename from vendor/github.com/kr/pretty/zero.go rename to vendor/github.com/dougm/pretty/zero.go diff --git a/vendor/github.com/kr/pretty/go.mod b/vendor/github.com/kr/pretty/go.mod deleted file mode 100644 index 9a27b6e96..000000000 --- a/vendor/github.com/kr/pretty/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/kr/pretty - -go 1.12 - -require github.com/kr/text v0.1.0 diff --git a/vendor/github.com/kr/pretty/go.sum b/vendor/github.com/kr/pretty/go.sum deleted file mode 100644 index 714f82a20..000000000 --- a/vendor/github.com/kr/pretty/go.sum +++ /dev/null @@ -1,3 +0,0 @@ -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= diff --git a/vendor/github.com/kr/text/go.mod b/vendor/github.com/kr/text/go.mod index fa0528b9a..91d6b986a 100644 --- a/vendor/github.com/kr/text/go.mod +++ b/vendor/github.com/kr/text/go.mod @@ -1,3 +1,3 @@ module "github.com/kr/text" -require "github.com/kr/pty" v1.1.1 +require "github.com/creack/pty" v1.1.9 diff --git a/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go b/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go index 3f2343c30..d73f36a81 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go @@ -203,6 +203,10 @@ func (flag *DatacenterFlag) ManagedObjects(ctx context.Context, args []string) ( continue } + if !strings.Contains(arg, "/") { + return nil, fmt.Errorf("%q must be qualified with a path", arg) + } + elements, err := finder.ManagedObjectList(ctx, arg) if err != nil { return nil, err diff --git a/vendor/github.com/vmware/govmomi/govc/flags/debug.go b/vendor/github.com/vmware/govmomi/govc/flags/debug.go index 809ec1182..3f5aff87f 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/debug.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/debug.go @@ -31,7 +31,7 @@ import ( "text/tabwriter" "time" - "github.com/kr/pretty" + "github.com/dougm/pretty" "github.com/vmware/govmomi/vim25/debug" "github.com/vmware/govmomi/vim25/soap" diff --git a/vendor/github.com/vmware/govmomi/govc/flags/output.go b/vendor/github.com/vmware/govmomi/govc/flags/output.go index aaa3d1bbc..565bdd15a 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/output.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/output.go @@ -29,7 +29,7 @@ import ( "sync" "time" - "github.com/kr/pretty" + "github.com/dougm/pretty" "github.com/vmware/govmomi/task" "github.com/vmware/govmomi/vim25/progress" diff --git a/vendor/github.com/vmware/govmomi/govc/importx/spec.go b/vendor/github.com/vmware/govmomi/govc/importx/spec.go index 514f338c9..e425fe622 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/spec.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/spec.go @@ -107,7 +107,7 @@ func (cmd *spec) Run(ctx context.Context, f *flag.FlagSet) error { return fmt.Errorf("invalid file extension %s", path.Ext(fpath)) } - if isRemotePath(fpath) { + if isRemotePath(f.Arg(0)) { client, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/change.go b/vendor/github.com/vmware/govmomi/govc/vm/change.go index f986a51b4..bf223aa81 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/change.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/change.go @@ -77,6 +77,7 @@ type change struct { extraConfig extraConfig extraConfigFile extraConfigFile Latency string + hwUpgradePolicy string } func init() { @@ -105,6 +106,28 @@ func (cmd *change) setLatency() error { return fmt.Errorf("latency must be one of: %s", strings.Join(latencyLevels, "|")) } +var hwUpgradePolicies = []string{ + string(types.ScheduledHardwareUpgradeInfoHardwareUpgradePolicyOnSoftPowerOff), + string(types.ScheduledHardwareUpgradeInfoHardwareUpgradePolicyNever), + string(types.ScheduledHardwareUpgradeInfoHardwareUpgradePolicyAlways), +} + +// setHwUpgradePolicy validates hwUpgradePolicy if set +func (cmd *change) setHwUpgradePolicy() error { + if cmd.hwUpgradePolicy == "" { + return nil + } + for _, l := range hwUpgradePolicies { + if l == cmd.hwUpgradePolicy { + cmd.ScheduledHardwareUpgradeInfo = &types.ScheduledHardwareUpgradeInfo{ + UpgradePolicy: string(types.ScheduledHardwareUpgradeInfoHardwareUpgradePolicy(cmd.hwUpgradePolicy)), + } + return nil + } + } + return fmt.Errorf("Hardware upgrade policy must be one of: %s", strings.Join(hwUpgradePolicies, "|")) +} + // setAllocation sets *info=nil if none of the fields have been set. // We need non-nil fields for use with flag.FlagSet, but we want the // VirtualMachineConfigSpec fields to be nil if none of the related flags were given. @@ -155,6 +178,8 @@ func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { f.Var(flags.NewOptionalBool(&cmd.MemoryHotAddEnabled), "memory-hot-add-enabled", "Enable memory hot add") f.Var(flags.NewOptionalBool(&cmd.MemoryReservationLockedToMax), "memory-pin", "Reserve all guest memory") f.Var(flags.NewOptionalBool(&cmd.CpuHotAddEnabled), "cpu-hot-add-enabled", "Enable CPU hot add") + + f.StringVar(&cmd.hwUpgradePolicy, "scheduled-hw-upgrade-policy", "", fmt.Sprintf("Schedule hardware upgrade policy (%s)", strings.Join(hwUpgradePolicies, "|"))) } func (cmd *change) Description() string { @@ -174,7 +199,8 @@ Examples: vmware-rpctool "info-get guestinfo.vmname" govc vm.change -vm $vm -latency high govc vm.change -vm $vm -latency normal - govc vm.change -vm $vm -uuid 4139c345-7186-4924-a842-36b69a24159b` + govc vm.change -vm $vm -uuid 4139c345-7186-4924-a842-36b69a24159b + govc vm.change -vm $vm -scheduled-hw-upgrade-policy always` } func (cmd *change) Process(ctx context.Context) error { @@ -206,6 +232,10 @@ func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { return err } + if err = cmd.setHwUpgradePolicy(); err != nil { + return err + } + task, err := vm.Reconfigure(ctx, cmd.VirtualMachineConfigSpec) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/destroy.go b/vendor/github.com/vmware/govmomi/govc/vm/destroy.go index a0800a2be..a27b3b763 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/destroy.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/destroy.go @@ -101,7 +101,9 @@ func (cmd *destroy) Run(ctx context.Context, f *flag.FlagSet) error { return err } - return task.Wait(ctx) + if err = task.Wait(ctx); err != nil { + return err + } } return nil diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go index b0c344a00..b87672479 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go @@ -56,9 +56,9 @@ func (flag *AuthFlag) Register(ctx context.Context, f *flag.FlagSet) { value := os.Getenv(env) err := flag.Set(value) if err != nil { - fmt.Printf("couldn't set guest login values: %v", err) + fmt.Printf("could not set guest login values: %v", err) } - usage := fmt.Sprintf("Guest VM credentials [%s]", env) + usage := fmt.Sprintf("Guest VM credentials (:) [%s]", env) f.Var(flag, "l", usage) if flag.proc { f.BoolVar(&flag.auth.GuestAuthentication.InteractiveSession, "i", false, "Interactive session") @@ -66,6 +66,10 @@ func (flag *AuthFlag) Register(ctx context.Context, f *flag.FlagSet) { } func (flag *AuthFlag) Process(ctx context.Context) error { + if flag.auth.Username == "" { + return fmt.Errorf("guest login username must not be empty") + } + return nil } diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go index cbfc4c3af..66650e1d0 100644 --- a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go @@ -102,3 +102,17 @@ func (s DistributedVirtualSwitch) ReconfigureDVPort(ctx context.Context, spec [] return NewTask(s.Client(), res.Returnval), nil } + +func (s DistributedVirtualSwitch) ReconfigureLACP(ctx context.Context, spec []types.VMwareDvsLacpGroupSpec) (*Task, error) { + req := types.UpdateDVSLacpGroupConfig_Task{ + This: s.Reference(), + LacpGroupSpec: spec, + } + + res, err := methods.UpdateDVSLacpGroupConfig_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/tenant_manager.go b/vendor/github.com/vmware/govmomi/object/tenant_manager.go new file mode 100644 index 000000000..4dda196e3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/tenant_manager.go @@ -0,0 +1,78 @@ +/* +Copyright (c) 2021 VMware, Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package object + +import ( + "context" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" +) + +type TenantManager struct { + Common +} + +func NewTenantManager(c *vim25.Client) *TenantManager { + t := TenantManager{ + Common: NewCommon(c, *c.ServiceContent.TenantManager), + } + + return &t +} + +func (t TenantManager) MarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error { + req := types.MarkServiceProviderEntities{ + This: t.Reference(), + Entity: entities, + } + + _, err := methods.MarkServiceProviderEntities(ctx, t.Client(), &req) + if err != nil { + return err + } + + return nil +} + +func (t TenantManager) UnmarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error { + req := types.UnmarkServiceProviderEntities{ + This: t.Reference(), + Entity: entities, + } + + _, err := methods.UnmarkServiceProviderEntities(ctx, t.Client(), &req) + if err != nil { + return err + } + + return nil +} + +func (t TenantManager) RetrieveServiceProviderEntities(ctx context.Context) ([]types.ManagedObjectReference, error) { + req := types.RetrieveServiceProviderEntities{ + This: t.Reference(), + } + + res, err := methods.RetrieveServiceProviderEntities(ctx, t.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go index c45f553ab..30bd17054 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go @@ -64,6 +64,7 @@ func EthernetCardTypes() VirtualDeviceList { &types.VirtualE1000e{}, &types.VirtualVmxnet2{}, &types.VirtualVmxnet3{}, + &types.VirtualVmxnet3Vrdma{}, &types.VirtualPCNet32{}, &types.VirtualSriovEthernetCard{}, }).Select(func(device types.BaseVirtualDevice) bool { @@ -156,6 +157,25 @@ func (l VirtualDeviceList) SelectByBackingInfo(backing types.BaseVirtualDeviceBa case types.BaseVirtualDeviceFileBackingInfo: b := backing.(types.BaseVirtualDeviceFileBackingInfo) return a.GetVirtualDeviceFileBackingInfo().FileName == b.GetVirtualDeviceFileBackingInfo().FileName + case *types.VirtualPCIPassthroughVmiopBackingInfo: + b := backing.(*types.VirtualPCIPassthroughVmiopBackingInfo) + return a.Vgpu == b.Vgpu + case *types.VirtualPCIPassthroughDynamicBackingInfo: + b := backing.(*types.VirtualPCIPassthroughDynamicBackingInfo) + if b.CustomLabel != "" && b.CustomLabel != a.CustomLabel { + return false + } + if len(b.AllowedDevice) == 0 { + return true + } + for _, x := range a.AllowedDevice { + for _, y := range b.AllowedDevice { + if x.DeviceId == y.DeviceId && x.VendorId == y.VendorId { + return true + } + } + } + return false default: return false } @@ -919,25 +939,9 @@ func (l VirtualDeviceList) ConfigSpec(op types.VirtualDeviceConfigSpecOperation) var res []types.BaseVirtualDeviceConfigSpec for _, device := range l { config := &types.VirtualDeviceConfigSpec{ - Device: device, - Operation: op, - } - - if disk, ok := device.(*types.VirtualDisk); ok { - config.FileOperation = fop - - // Special case to attach an existing disk - if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 { - childDisk := false - if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { - childDisk = b.Parent != nil - } - - if !childDisk { - // Existing disk, clear file operation - config.FileOperation = "" - } - } + Device: device, + Operation: op, + FileOperation: diskFileOperation(op, fop, device), } res = append(res, config) diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go index bb731800c..eeffc19fd 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -461,29 +461,33 @@ func (v VirtualMachine) ResourcePool(ctx context.Context) (*ResourcePool, error) return NewResourcePool(v.c, *rp), nil } +func diskFileOperation(op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, device types.BaseVirtualDevice) types.VirtualDeviceConfigSpecFileOperation { + if disk, ok := device.(*types.VirtualDisk); ok { + // Special case to attach an existing disk + if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 && disk.CapacityInBytes == 0 { + childDisk := false + if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { + childDisk = b.Parent != nil + } + + if !childDisk { + fop = "" // existing disk + } + } + return fop + } + + return "" +} + func (v VirtualMachine) configureDevice(ctx context.Context, op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, devices ...types.BaseVirtualDevice) error { spec := types.VirtualMachineConfigSpec{} for _, device := range devices { config := &types.VirtualDeviceConfigSpec{ - Device: device, - Operation: op, - } - - if disk, ok := device.(*types.VirtualDisk); ok { - config.FileOperation = fop - - // Special case to attach an existing disk - if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 { - childDisk := false - if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { - childDisk = b.Parent != nil - } - - if !childDisk { - config.FileOperation = "" // existing disk - } - } + Device: device, + Operation: op, + FileOperation: diskFileOperation(op, fop, device), } spec.DeviceChange = append(spec.DeviceChange, config) @@ -1063,3 +1067,16 @@ func (v VirtualMachine) QueryChangedDiskAreas(ctx context.Context, baseSnapshot, return res.Returnval, nil } + +// ExportSnapshot exports all VMDK-files up to (but not including) a specified snapshot. This +// is useful when exporting a running VM. +func (v *VirtualMachine) ExportSnapshot(ctx context.Context, snapshot *types.ManagedObjectReference) (*nfc.Lease, error) { + req := types.ExportSnapshot{ + This: *snapshot, + } + resp, err := methods.ExportSnapshot(ctx, v.Client(), &req) + if err != nil { + return nil, err + } + return nfc.NewLease(v.c, resp.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/vapi/library/finder/README.md b/vendor/github.com/vmware/govmomi/vapi/library/finder/README.md index 12d243f82..1e2b90030 100644 --- a/vendor/github.com/vmware/govmomi/vapi/library/finder/README.md +++ b/vendor/github.com/vmware/govmomi/vapi/library/finder/README.md @@ -38,7 +38,8 @@ While a system that has few content library objects benefits from wildcard searc ## `govc library.ls` ### Listing all the objects in the content library -```shell + +```console $ govc library.ls '*/*/' /ISOs/CentOS-7-x86_64-Minimal-1804/CentOS-7-x86_64-Minimal-1804.iso /ISOs/CoreOS Production/coreos_production_iso_image.iso @@ -72,7 +73,8 @@ $ govc library.ls '*/*/' ## `govc library.info` ### Getting the info for all the objects in the content library -```shell + +```console $ govc library.info '*/*/' Name: CentOS-7-x86_64-Minimal-1804.iso Path: /ISOs/CentOS-7-x86_64-Minimal-1804/CentOS-7-x86_64-Minimal-1804.iso diff --git a/vendor/github.com/vmware/govmomi/vapi/rest/client.go b/vendor/github.com/vmware/govmomi/vapi/rest/client.go index 3c4b148d4..b1cefd0e2 100644 --- a/vendor/github.com/vmware/govmomi/vapi/rest/client.go +++ b/vendor/github.com/vmware/govmomi/vapi/rest/client.go @@ -164,7 +164,7 @@ type RawResponse struct { // Do sends the http.Request, decoding resBody if provided. func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{}) error { switch req.Method { - case http.MethodPost, http.MethodPatch: + case http.MethodPost, http.MethodPatch, http.MethodPut: req.Header.Set("Content-Type", "application/json") } diff --git a/vendor/github.com/vmware/govmomi/vapi/rest/resource.go b/vendor/github.com/vmware/govmomi/vapi/rest/resource.go index 3004abb85..e6e627492 100644 --- a/vendor/github.com/vmware/govmomi/vapi/rest/resource.go +++ b/vendor/github.com/vmware/govmomi/vapi/rest/resource.go @@ -51,12 +51,36 @@ func (r *Resource) WithAction(action string) *Resource { // WithParam adds one parameter on the URL.RawQuery func (r *Resource) WithParam(name string, value string) *Resource { // ParseQuery handles empty case, and we control access to query string so shouldn't encounter an error case - params, _ := url.ParseQuery(r.u.RawQuery) + params, err := url.ParseQuery(r.u.RawQuery) + if err != nil { + panic(err) + } params[name] = append(params[name], value) r.u.RawQuery = params.Encode() return r } +// WithPathEncodedParam appends a parameter on the URL.RawQuery, +// For special cases where URL Path-style encoding is needed +func (r *Resource) WithPathEncodedParam(name string, value string) *Resource { + t := &url.URL{Path: value} + encodedValue := t.String() + t = &url.URL{Path: name} + encodedName := t.String() + // ParseQuery handles empty case, and we control access to query string so shouldn't encounter an error case + params, err := url.ParseQuery(r.u.RawQuery) + if err != nil { + panic(err) + } + // Values.Encode() doesn't escape exactly how we want, so we need to build the query string ourselves + if len(params) >= 1 { + r.u.RawQuery = r.u.RawQuery + "&" + encodedName + "=" + encodedValue + } else { + r.u.RawQuery = r.u.RawQuery + encodedName + "=" + encodedValue + } + return r +} + // Request returns a new http.Request for the given method. // An optional body can be provided for POST and PATCH methods. func (r *Resource) Request(method string, body ...interface{}) *http.Request { diff --git a/vendor/github.com/vmware/govmomi/vim25/types/fault.go b/vendor/github.com/vmware/govmomi/vim25/types/fault.go index c2503fa5c..813ea9ec6 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/fault.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/fault.go @@ -30,3 +30,14 @@ func IsFileNotFound(err error) bool { return false } + +func IsAlreadyExists(err error) bool { + if f, ok := err.(HasFault); ok { + switch f.Fault().(type) { + case *AlreadyExists: + return true + } + } + + return false +} diff --git a/vendor/github.com/vmware/govmomi/vim25/types/helpers.go b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go index 5e6245e51..67d9793fa 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/helpers.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go @@ -1,5 +1,5 @@ /* -Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved. +Copyright (c) 2015-2022 VMware, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -94,6 +94,149 @@ func DefaultResourceConfigSpec() ResourceConfigSpec { } } +// ToConfigSpec returns a VirtualMachineConfigSpec based on the +// VirtualMachineConfigInfo. +func (ci VirtualMachineConfigInfo) ToConfigSpec() VirtualMachineConfigSpec { + cs := VirtualMachineConfigSpec{ + ChangeVersion: ci.ChangeVersion, + Name: ci.Name, + Version: ci.Version, + CreateDate: ci.CreateDate, + Uuid: ci.Uuid, + InstanceUuid: ci.InstanceUuid, + NpivNodeWorldWideName: ci.NpivNodeWorldWideName, + NpivPortWorldWideName: ci.NpivPortWorldWideName, + NpivWorldWideNameType: ci.NpivWorldWideNameType, + NpivDesiredNodeWwns: ci.NpivDesiredNodeWwns, + NpivDesiredPortWwns: ci.NpivDesiredPortWwns, + NpivTemporaryDisabled: ci.NpivTemporaryDisabled, + NpivOnNonRdmDisks: ci.NpivOnNonRdmDisks, + LocationId: ci.LocationId, + GuestId: ci.GuestId, + AlternateGuestName: ci.AlternateGuestName, + Annotation: ci.Annotation, + Files: &ci.Files, + Tools: ci.Tools, + Flags: &ci.Flags, + ConsolePreferences: ci.ConsolePreferences, + PowerOpInfo: &ci.DefaultPowerOps, + NumCPUs: ci.Hardware.NumCPU, + VcpuConfig: ci.VcpuConfig, + NumCoresPerSocket: ci.Hardware.NumCoresPerSocket, + MemoryMB: int64(ci.Hardware.MemoryMB), + MemoryHotAddEnabled: ci.MemoryHotAddEnabled, + CpuHotAddEnabled: ci.CpuHotAddEnabled, + CpuHotRemoveEnabled: ci.CpuHotRemoveEnabled, + VirtualICH7MPresent: ci.Hardware.VirtualICH7MPresent, + VirtualSMCPresent: ci.Hardware.VirtualSMCPresent, + DeviceChange: make([]BaseVirtualDeviceConfigSpec, len(ci.Hardware.Device)), + CpuAllocation: ci.CpuAllocation, + MemoryAllocation: ci.MemoryAllocation, + LatencySensitivity: ci.LatencySensitivity, + CpuAffinity: ci.CpuAffinity, + MemoryAffinity: ci.MemoryAffinity, + NetworkShaper: ci.NetworkShaper, + CpuFeatureMask: make([]VirtualMachineCpuIdInfoSpec, len(ci.CpuFeatureMask)), + ExtraConfig: ci.ExtraConfig, + SwapPlacement: ci.SwapPlacement, + BootOptions: ci.BootOptions, + FtInfo: ci.FtInfo, + RepConfig: ci.RepConfig, + VAssertsEnabled: ci.VAssertsEnabled, + ChangeTrackingEnabled: ci.ChangeTrackingEnabled, + Firmware: ci.Firmware, + MaxMksConnections: ci.MaxMksConnections, + GuestAutoLockEnabled: ci.GuestAutoLockEnabled, + ManagedBy: ci.ManagedBy, + MemoryReservationLockedToMax: ci.MemoryReservationLockedToMax, + NestedHVEnabled: ci.NestedHVEnabled, + VPMCEnabled: ci.VPMCEnabled, + MessageBusTunnelEnabled: ci.MessageBusTunnelEnabled, + MigrateEncryption: ci.MigrateEncryption, + FtEncryptionMode: ci.FtEncryptionMode, + SevEnabled: ci.SevEnabled, + PmemFailoverEnabled: ci.PmemFailoverEnabled, + Pmem: ci.Pmem, + } + + // Unassign the Files field if all of its fields are empty. + if ci.Files.FtMetadataDirectory == "" && ci.Files.LogDirectory == "" && + ci.Files.SnapshotDirectory == "" && ci.Files.SuspendDirectory == "" && + ci.Files.VmPathName == "" { + cs.Files = nil + } + + // Unassign the Flags field if all of its fields are empty. + if ci.Flags.CbrcCacheEnabled == nil && + ci.Flags.DisableAcceleration == nil && + ci.Flags.DiskUuidEnabled == nil && + ci.Flags.EnableLogging == nil && + ci.Flags.FaultToleranceType == "" && + ci.Flags.HtSharing == "" && + ci.Flags.MonitorType == "" && + ci.Flags.RecordReplayEnabled == nil && + ci.Flags.RunWithDebugInfo == nil && + ci.Flags.SnapshotDisabled == nil && + ci.Flags.SnapshotLocked == nil && + ci.Flags.SnapshotPowerOffBehavior == "" && + ci.Flags.UseToe == nil && + ci.Flags.VbsEnabled == nil && + ci.Flags.VirtualExecUsage == "" && + ci.Flags.VirtualMmuUsage == "" && + ci.Flags.VvtdEnabled == nil { + cs.Flags = nil + } + + // Unassign the PowerOps field if all of its fields are empty. + if ci.DefaultPowerOps.DefaultPowerOffType == "" && + ci.DefaultPowerOps.DefaultResetType == "" && + ci.DefaultPowerOps.DefaultSuspendType == "" && + ci.DefaultPowerOps.PowerOffType == "" && + ci.DefaultPowerOps.ResetType == "" && + ci.DefaultPowerOps.StandbyAction == "" && + ci.DefaultPowerOps.SuspendType == "" { + cs.PowerOpInfo = nil + } + + for i := 0; i < len(cs.CpuFeatureMask); i++ { + cs.CpuFeatureMask[i] = VirtualMachineCpuIdInfoSpec{ + ArrayUpdateSpec: ArrayUpdateSpec{ + Operation: ArrayUpdateOperationAdd, + }, + Info: &HostCpuIdInfo{ + // TODO: Does DynamicData need to be copied? + // It is an empty struct... + Level: ci.CpuFeatureMask[i].Level, + Vendor: ci.CpuFeatureMask[i].Vendor, + Eax: ci.CpuFeatureMask[i].Eax, + Ebx: ci.CpuFeatureMask[i].Ebx, + Ecx: ci.CpuFeatureMask[i].Ecx, + Edx: ci.CpuFeatureMask[i].Edx, + }, + } + } + + for i := 0; i < len(cs.DeviceChange); i++ { + cs.DeviceChange[i] = &VirtualDeviceConfigSpec{ + // TODO: Does DynamicData need to be copied? + // It is an empty struct... + Operation: VirtualDeviceConfigSpecOperationAdd, + FileOperation: VirtualDeviceConfigSpecFileOperationCreate, + Device: ci.Hardware.Device[i], + // TODO: It is unclear how the profiles associated with the VM or + // its hardware can be reintroduced/persisted in the + // ConfigSpec. + Profile: nil, + // The backing will come from the device. + Backing: nil, + // TODO: Investigate futher. + FilterSpec: nil, + } + } + + return cs +} + func init() { // Known 6.5 issue where this event type is sent even though it is internal. // This workaround allows us to unmarshal and avoid NPEs. diff --git a/vendor/github.com/vmware/govmomi/vim25/types/unreleased.go b/vendor/github.com/vmware/govmomi/vim25/types/unreleased.go index 167184e8d..ee1c09f33 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/unreleased.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/unreleased.go @@ -115,3 +115,15 @@ type PlaceVmsXClusterSpecVmPlacementSpec struct { func init() { t["PlaceVmsXClusterSpecVmPlacementSpec"] = reflect.TypeOf((*PlaceVmsXClusterSpecVmPlacementSpec)(nil)).Elem() } + +const RecommendationReasonCodeXClusterPlacement = RecommendationReasonCode("xClusterPlacement") + +type ClusterClusterInitialPlacementAction struct { + ClusterInitialPlacementAction + + ConfigSpec *VirtualMachineConfigSpec `xml:"configSpec,omitempty"` +} + +func init() { + t["ClusterClusterInitialPlacementAction"] = reflect.TypeOf((*ClusterClusterInitialPlacementAction)(nil)).Elem() +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6043a6069..0fb784ee8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -151,6 +151,8 @@ github.com/deepmap/oapi-codegen/pkg/types github.com/deepmap/oapi-codegen/pkg/util # github.com/dimchansky/utfbom v1.1.1 github.com/dimchansky/utfbom +# github.com/dougm/pretty v0.0.0-20171025230240-2ee9d7453c02 +github.com/dougm/pretty # github.com/getkin/kin-openapi v0.61.0 ## explicit github.com/getkin/kin-openapi/jsoninfo @@ -261,9 +263,7 @@ github.com/julienschmidt/httprouter # github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b ## explicit github.com/kolo/xmlrpc -# github.com/kr/pretty v0.2.1 -github.com/kr/pretty -# github.com/kr/text v0.1.0 +# github.com/kr/text v0.2.0 github.com/kr/text # github.com/labstack/echo/v4 v4.7.2 ## explicit @@ -358,7 +358,7 @@ github.com/ubccr/kerby/khttp github.com/valyala/bytebufferpool # github.com/valyala/fasttemplate v1.2.1 github.com/valyala/fasttemplate -# github.com/vmware/govmomi v0.27.4 +# github.com/vmware/govmomi v0.28.0 ## explicit github.com/vmware/govmomi/cns github.com/vmware/govmomi/cns/methods