github.com/vmware/govmomi@v0.43.0/govc/host/esxcli/command.go (about)

     1  /*
     2  Copyright (c) 2014-2023 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package esxcli
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"strings"
    23  
    24  	"github.com/vmware/govmomi/govc/flags"
    25  	"github.com/vmware/govmomi/internal"
    26  )
    27  
    28  type Command struct {
    29  	name []string
    30  	args []string
    31  }
    32  
    33  type CommandInfoItem struct {
    34  	Name        string `xml:"name" json:"name"`
    35  	DisplayName string `xml:"displayName" json:"displayName"`
    36  	Help        string `xml:"help" json:"help"`
    37  }
    38  
    39  type CommandInfoParam struct {
    40  	CommandInfoItem
    41  	Aliases []string `xml:"aliases" json:"aliases"`
    42  	Flag    bool     `xml:"flag" json:"flag"`
    43  }
    44  
    45  type CommandInfoHint struct {
    46  	Key   string `xml:"key" json:"key"`
    47  	Value string `xml:"value" json:"value"`
    48  }
    49  
    50  type CommandInfoHints []CommandInfoHint
    51  
    52  type CommandInfoMethod struct {
    53  	CommandInfoItem
    54  	Param []CommandInfoParam `xml:"param" json:"param"`
    55  	Hints CommandInfoHints   `xml:"hints" json:"hints"`
    56  }
    57  
    58  type CommandInfo struct {
    59  	CommandInfoItem
    60  	Method []*CommandInfoMethod `xml:"method" json:"method"`
    61  }
    62  
    63  func NewCommand(args []string) *Command {
    64  	c := &Command{}
    65  
    66  	for i, arg := range args {
    67  		if strings.HasPrefix(arg, "-") {
    68  			c.args = args[i:]
    69  			break
    70  		} else {
    71  			c.name = append(c.name, arg)
    72  		}
    73  	}
    74  
    75  	return c
    76  }
    77  
    78  func (c *Command) Namespace() string {
    79  	return strings.Join(c.name[:len(c.name)-1], ".")
    80  }
    81  
    82  func (c *Command) Name() string {
    83  	return c.name[len(c.name)-1]
    84  }
    85  
    86  func (c *Command) Method() string {
    87  	return "vim.EsxCLI." + strings.Join(c.name, ".")
    88  }
    89  
    90  func (c *Command) Moid() string {
    91  	return "ha-cli-handler-" + strings.Join(c.name[:len(c.name)-1], "-")
    92  }
    93  
    94  // Parse generates a flag.FlagSet based on the given []CommandInfoParam and
    95  // returns arguments for use with methods.ExecuteSoap
    96  func (c *Command) Parse(params []CommandInfoParam) ([]internal.ReflectManagedMethodExecuterSoapArgument, error) {
    97  	fs := flag.NewFlagSet(strings.Join(c.name, " "), flag.ExitOnError)
    98  	vals := make([]flags.StringList, len(params))
    99  
   100  	for i, p := range params {
   101  		v := &vals[i]
   102  		for _, a := range p.Aliases {
   103  			a = strings.TrimPrefix(a[1:], "-")
   104  			fs.Var(v, a, p.Help)
   105  		}
   106  	}
   107  
   108  	err := fs.Parse(c.args)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	args := []internal.ReflectManagedMethodExecuterSoapArgument{}
   114  
   115  	for i, p := range params {
   116  		if len(vals[i]) != 0 {
   117  			args = append(args, c.Argument(p.Name, vals[i]...))
   118  		}
   119  	}
   120  
   121  	return args, nil
   122  }
   123  
   124  func (c *Command) Argument(name string, args ...string) internal.ReflectManagedMethodExecuterSoapArgument {
   125  	var vars []string
   126  	for _, arg := range args {
   127  		vars = append(vars, fmt.Sprintf("<%s>%s</%s>", name, arg, name))
   128  	}
   129  	return internal.ReflectManagedMethodExecuterSoapArgument{
   130  		Name: name,
   131  		Val:  strings.Join(vars, ""),
   132  	}
   133  }
   134  
   135  func (h CommandInfoHints) Formatter() string {
   136  	for _, hint := range h {
   137  		if hint.Key == "formatter" {
   138  			return hint.Value
   139  		}
   140  	}
   141  
   142  	return "simple"
   143  }
   144  
   145  func (h CommandInfoHints) Fields() []string {
   146  	for _, hint := range h {
   147  		if strings.HasPrefix(hint.Key, "fields:") {
   148  			return strings.Split(hint.Value, ",")
   149  		}
   150  	}
   151  
   152  	return nil
   153  }