github.com/vmware/govmomi@v0.37.2/govc/option/set.go (about)

     1  /*
     2  Copyright (c) 2017 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 option
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"strconv"
    24  
    25  	"github.com/vmware/govmomi/govc/cli"
    26  	"github.com/vmware/govmomi/govc/flags"
    27  	"github.com/vmware/govmomi/object"
    28  	"github.com/vmware/govmomi/vim25/soap"
    29  	"github.com/vmware/govmomi/vim25/types"
    30  )
    31  
    32  type Set struct {
    33  	*flags.ClientFlag
    34  }
    35  
    36  func init() {
    37  	cli.Register("option.set", &Set{})
    38  }
    39  
    40  func (cmd *Set) Register(ctx context.Context, f *flag.FlagSet) {
    41  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    42  	cmd.ClientFlag.Register(ctx, f)
    43  }
    44  
    45  func (cmd *Set) Process(ctx context.Context) error {
    46  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    47  		return err
    48  	}
    49  	return nil
    50  }
    51  
    52  func (cmd *Set) Usage() string {
    53  	return "NAME VALUE"
    54  }
    55  
    56  var SetDescription = `Set option NAME to VALUE.`
    57  
    58  func (cmd *Set) Description() string {
    59  	return SetDescription + `
    60  
    61  Examples:
    62    govc option.set log.level info
    63    govc option.set logger.Vsan verbose`
    64  }
    65  
    66  func isInvalidName(err error) bool {
    67  	if soap.IsSoapFault(err) {
    68  		soapFault := soap.ToSoapFault(err)
    69  		if _, ok := soapFault.VimFault().(types.InvalidName); ok {
    70  			return ok
    71  		}
    72  	}
    73  
    74  	return false
    75  }
    76  
    77  func (cmd *Set) Update(ctx context.Context, f *flag.FlagSet, m *object.OptionManager) error {
    78  	if f.NArg() != 2 {
    79  		return flag.ErrHelp
    80  	}
    81  
    82  	name := f.Arg(0)
    83  	val := f.Arg(1)
    84  
    85  	opts, err := m.Query(ctx, name)
    86  	if err != nil {
    87  		if isInvalidName(err) {
    88  			// If the option doesn't exist, creating one can only have a string Value.
    89  			// The Key prefix is limited in this case too, it seems to the config.* namespace.
    90  			return m.Update(ctx, []types.BaseOptionValue{&types.OptionValue{
    91  				Key:   name,
    92  				Value: val,
    93  			}})
    94  		}
    95  		return err
    96  	}
    97  
    98  	if len(opts) != 1 {
    99  		return flag.ErrHelp
   100  	}
   101  
   102  	var set types.AnyType
   103  
   104  	switch x := opts[0].GetOptionValue().Value.(type) {
   105  	case string:
   106  		set = val
   107  	case bool:
   108  		set, err = strconv.ParseBool(val)
   109  		if err != nil {
   110  			return err
   111  		}
   112  	case int32:
   113  		s, err := strconv.ParseInt(val, 10, 32)
   114  		if err != nil {
   115  			return err
   116  		}
   117  		set = int32(s)
   118  	case int64:
   119  		set, err = strconv.ParseInt(val, 10, 64)
   120  		if err != nil {
   121  			return err
   122  		}
   123  	default:
   124  		return fmt.Errorf("type %T conversion not supported", x)
   125  	}
   126  
   127  	opts[0].GetOptionValue().Value = set
   128  
   129  	return m.Update(ctx, opts)
   130  }
   131  
   132  func (cmd *Set) Run(ctx context.Context, f *flag.FlagSet) error {
   133  	c, err := cmd.Client()
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	m := object.NewOptionManager(c, *c.ServiceContent.Setting)
   139  
   140  	return cmd.Update(ctx, f, m)
   141  }