Skip to content

Commit

Permalink
api: move cli/host/esxcli.Command to cli/esx package
Browse files Browse the repository at this point in the history
The cli/esx package is free of govc dependencies.
Cleaner to use from the simulator package and externally.

BREAKING: Package "github.com/vmware/govmomi/govc/host/esxcli" is now "github.com/vmware/govmomi/cli/esx"
A 'context.Context' param has also been added to the package's methods.
See cli/esx/example_test.go for usage.

Signed-off-by: Doug MacEachern <[email protected]>
  • Loading branch information
dougm committed Nov 25, 2024
1 parent 9322377 commit 05482c0
Show file tree
Hide file tree
Showing 18 changed files with 325 additions and 252 deletions.
18 changes: 14 additions & 4 deletions cli/host/esxcli/command.go → cli/esx/command.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2024 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.
Expand All @@ -14,14 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import (
"flag"
"fmt"
"strings"

"github.com/vmware/govmomi/cli/flags"
"github.com/vmware/govmomi/internal"
)

Expand Down Expand Up @@ -91,11 +90,22 @@ func (c *Command) Moid() string {
return "ha-cli-handler-" + strings.Join(c.name[:len(c.name)-1], "-")
}

type stringList []string

func (l *stringList) String() string {
return fmt.Sprint(*l)
}

func (l *stringList) Set(value string) error {
*l = append(*l, value)
return nil
}

// Parse generates a flag.FlagSet based on the given []CommandInfoParam and
// returns arguments for use with methods.ExecuteSoap
func (c *Command) Parse(params []CommandInfoParam) ([]internal.ReflectManagedMethodExecuterSoapArgument, error) {
fs := flag.NewFlagSet(strings.Join(c.name, " "), flag.ExitOnError)
vals := make([]flags.StringList, len(params))
vals := make([]stringList, len(params))

for i, p := range params {
v := &vals[i]
Expand Down
6 changes: 3 additions & 3 deletions cli/host/esxcli/command_test.go → cli/esx/command_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2024 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
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,
Expand All @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import (
"reflect"
Expand Down
55 changes: 55 additions & 0 deletions cli/esx/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright (c) 2024-2024 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 esx_test

import (
"context"
"fmt"

"github.com/vmware/govmomi/cli/esx"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/vim25"
)

func ExampleExecutor_Run() {
simulator.Run(func(ctx context.Context, c *vim25.Client) error {
host, err := find.NewFinder(c).HostSystem(ctx, "DC0_H0")
if err != nil {
return err
}

x, err := esx.NewExecutor(ctx, c, host)
if err != nil {
return err
}

res, err := x.Run(ctx, []string{"software", "vib", "list"})
if err != nil {
return err
}

for _, vib := range res.Values {
fmt.Println(vib.Value("Name"))
}

return nil
})
// Output:
// esx-ui
// intelgpio
}
43 changes: 25 additions & 18 deletions cli/host/esxcli/executor.go → cli/esx/executor.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2024 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.
Expand All @@ -14,15 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import (
"context"
"fmt"

"github.com/vmware/govmomi/internal"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/xml"
)

Expand All @@ -35,7 +36,7 @@ func (f Fault) Error() string {
return f.Message
}

func (f Fault) messageDetail() string {
func (f Fault) MessageDetail() string {
if f.Detail != "" {
return fmt.Sprintf("%s %s", f.Message, f.Detail)
}
Expand All @@ -45,16 +46,15 @@ func (f Fault) messageDetail() string {

type Executor struct {
c *vim25.Client
host *object.HostSystem
host mo.Reference
mme *internal.ReflectManagedMethodExecuter
dtm *internal.InternalDynamicTypeManager
info map[string]*CommandInfo

Trace func(*internal.ExecuteSoapRequest, *internal.ExecuteSoapResponse)
}

func NewExecutor(c *vim25.Client, host *object.HostSystem) (*Executor, error) {
ctx := context.TODO()
func NewExecutor(ctx context.Context, c *vim25.Client, host mo.Reference) (*Executor, error) {
e := &Executor{
c: c,
host: host,
Expand Down Expand Up @@ -90,7 +90,15 @@ func NewExecutor(c *vim25.Client, host *object.HostSystem) (*Executor, error) {
return e, nil
}

func (e *Executor) CommandInfo(ns string) (*CommandInfo, error) {
func (e *Executor) Client() *vim25.Client {
return e.c
}

func (e *Executor) DynamicTypeManager() types.ManagedObjectReference {
return e.dtm.ManagedObjectReference
}

func (e *Executor) CommandInfo(ctx context.Context, ns string) (*CommandInfo, error) {
info, ok := e.info[ns]
if ok {
return info, nil
Expand All @@ -105,7 +113,7 @@ func (e *Executor) CommandInfo(ns string) (*CommandInfo, error) {
}

info = new(CommandInfo)
if err := e.Execute(&req, info); err != nil {
if err := e.Execute(ctx, &req, info); err != nil {
return nil, err
}

Expand All @@ -114,10 +122,10 @@ func (e *Executor) CommandInfo(ns string) (*CommandInfo, error) {
return info, nil
}

func (e *Executor) CommandInfoMethod(c *Command) (*CommandInfoMethod, error) {
func (e *Executor) CommandInfoMethod(ctx context.Context, c *Command) (*CommandInfoMethod, error) {
ns := c.Namespace()

info, err := e.CommandInfo(ns)
info, err := e.CommandInfo(ctx, ns)
if err != nil {
return nil, err
}
Expand All @@ -132,10 +140,10 @@ func (e *Executor) CommandInfoMethod(c *Command) (*CommandInfoMethod, error) {
return nil, fmt.Errorf("method '%s' not found in name space '%s'", name, c.Namespace())
}

func (e *Executor) NewRequest(args []string) (*internal.ExecuteSoapRequest, *CommandInfoMethod, error) {
func (e *Executor) NewRequest(ctx context.Context, args []string) (*internal.ExecuteSoapRequest, *CommandInfoMethod, error) {
c := NewCommand(args)

info, err := e.CommandInfoMethod(c)
info, err := e.CommandInfoMethod(ctx, c)
if err != nil {
return nil, nil, err
}
Expand All @@ -154,8 +162,7 @@ func (e *Executor) NewRequest(args []string) (*internal.ExecuteSoapRequest, *Com
return &sreq, info, nil
}

func (e *Executor) Execute(req *internal.ExecuteSoapRequest, res interface{}) error {
ctx := context.TODO()
func (e *Executor) Execute(ctx context.Context, req *internal.ExecuteSoapRequest, res interface{}) error {
req.This = e.mme.ManagedObjectReference
req.Version = "urn:vim25/5.0"

Expand Down Expand Up @@ -184,8 +191,8 @@ func (e *Executor) Execute(req *internal.ExecuteSoapRequest, res interface{}) er
return nil
}

func (e *Executor) Run(args []string) (*Response, error) {
req, info, err := e.NewRequest(args)
func (e *Executor) Run(ctx context.Context, args []string) (*Response, error) {
req, info, err := e.NewRequest(ctx, args)
if err != nil {
return nil, err
}
Expand All @@ -194,7 +201,7 @@ func (e *Executor) Run(args []string) (*Response, error) {
Info: info,
}

if err := e.Execute(req, res); err != nil {
if err := e.Execute(ctx, req, res); err != nil {
return nil, err
}

Expand Down
15 changes: 5 additions & 10 deletions cli/host/esxcli/firewall_info.go → cli/esx/firewall_info.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2015-2023 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-2024 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.
Expand All @@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import "github.com/vmware/govmomi/object"
import "context"

type FirewallInfo struct {
Loaded bool `json:"loaded"`
Expand All @@ -27,13 +27,8 @@ type FirewallInfo struct {
// GetFirewallInfo via 'esxcli network firewall get'
// The HostFirewallSystem type does not expose this data.
// This helper can be useful in particular to determine if the firewall is enabled or disabled.
func GetFirewallInfo(s *object.HostSystem) (*FirewallInfo, error) {
x, err := NewExecutor(s.Client(), s)
if err != nil {
return nil, err
}

res, err := x.Run([]string{"network", "firewall", "get"})
func (x *Executor) GetFirewallInfo(ctx context.Context) (*FirewallInfo, error) {
res, err := x.Run(ctx, []string{"network", "firewall", "get"})
if err != nil {
return nil, err
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
22 changes: 9 additions & 13 deletions cli/host/esxcli/guest_info.go → cli/esx/guest_info.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2024 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
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,
Expand All @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import (
"context"
"strings"

"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
Expand All @@ -44,20 +43,18 @@ func NewGuestInfo(c *vim25.Client) *GuestInfo {
}
}

func (g *GuestInfo) hostInfo(ref *types.ManagedObjectReference) (*hostInfo, error) {
func (g *GuestInfo) hostInfo(ctx context.Context, ref *types.ManagedObjectReference) (*hostInfo, error) {
// cache exectuor and uuid -> worldid map
if h, ok := g.hosts[ref.Value]; ok {
return h, nil
}

host := object.NewHostSystem(g.c, *ref)

e, err := NewExecutor(g.c, host)
e, err := NewExecutor(ctx, g.c, ref)
if err != nil {
return nil, err
}

res, err := e.Run([]string{"vm", "process", "list"})
res, err := e.Run(ctx, []string{"vm", "process", "list"})
if err != nil {
return nil, err
}
Expand All @@ -82,8 +79,7 @@ func (g *GuestInfo) hostInfo(ref *types.ManagedObjectReference) (*hostInfo, erro
// ESX hosts must be configured with the /Net/GuestIPHack enabled.
// For example:
// $ govc host.esxcli -- system settings advanced set -o /Net/GuestIPHack -i 1
func (g *GuestInfo) IpAddress(vm *object.VirtualMachine) (string, error) {
ctx := context.TODO()
func (g *GuestInfo) IpAddress(ctx context.Context, vm mo.Reference) (string, error) {
const any = "0.0.0.0"
var mvm mo.VirtualMachine

Expand All @@ -93,7 +89,7 @@ func (g *GuestInfo) IpAddress(vm *object.VirtualMachine) (string, error) {
return "", err
}

h, err := g.hostInfo(mvm.Runtime.Host)
h, err := g.hostInfo(ctx, mvm.Runtime.Host)
if err != nil {
return "", err
}
Expand All @@ -102,7 +98,7 @@ func (g *GuestInfo) IpAddress(vm *object.VirtualMachine) (string, error) {
uuid := strings.Replace(mvm.Config.Uuid, "-", "", -1)

if wid, ok := h.wids[uuid]; ok {
res, err := h.Run([]string{"network", "vm", "port", "list", "--world-id", wid})
res, err := h.Run(ctx, []string{"network", "vm", "port", "list", "--world-id", wid})
if err != nil {
return "", err
}
Expand Down
4 changes: 2 additions & 2 deletions cli/host/esxcli/response.go → cli/esx/response.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2024 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.
Expand All @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package esxcli
package esx

import (
"io"
Expand Down
Loading

0 comments on commit 05482c0

Please sign in to comment.