github.com/vmware/govmomi@v0.51.0/cli/dvs/add.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package dvs
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  	"os"
    12  	"strings"
    13  
    14  	"github.com/vmware/govmomi/cli"
    15  	"github.com/vmware/govmomi/cli/flags"
    16  	"github.com/vmware/govmomi/object"
    17  	"github.com/vmware/govmomi/vim25/mo"
    18  	"github.com/vmware/govmomi/vim25/types"
    19  )
    20  
    21  type add struct {
    22  	*flags.HostSystemFlag
    23  
    24  	path string
    25  	pnic string
    26  }
    27  
    28  func init() {
    29  	cli.Register("dvs.add", &add{})
    30  }
    31  
    32  func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
    33  	cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
    34  	cmd.HostSystemFlag.Register(ctx, f)
    35  
    36  	f.StringVar(&cmd.path, "dvs", "", "DVS path")
    37  	f.StringVar(&cmd.pnic, "pnic", "vmnic0", "Name of the host physical NIC")
    38  }
    39  
    40  func (cmd *add) Process(ctx context.Context) error {
    41  	if err := cmd.HostSystemFlag.Process(ctx); err != nil {
    42  		return err
    43  	}
    44  	return nil
    45  }
    46  
    47  func (cmd *add) Usage() string {
    48  	return "HOST..."
    49  }
    50  
    51  func (cmd *add) Description() string {
    52  	return `Add hosts to DVS.
    53  
    54  Examples:
    55    govc dvs.add -dvs dvsName -pnic vmnic1 hostA hostB hostC`
    56  }
    57  
    58  func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
    59  	if f.NArg() == 0 {
    60  		return flag.ErrHelp
    61  	}
    62  
    63  	finder, err := cmd.Finder()
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	net, err := finder.Network(ctx, cmd.path)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	dvs, ok := net.(*object.DistributedVirtualSwitch)
    74  	if !ok {
    75  		return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs)
    76  	}
    77  
    78  	var s mo.DistributedVirtualSwitch
    79  	err = dvs.Properties(ctx, dvs.Reference(), []string{"config"}, &s)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	backing := new(types.DistributedVirtualSwitchHostMemberPnicBacking)
    85  
    86  	for _, vmnic := range strings.Split(cmd.pnic, ",") {
    87  		backing.PnicSpec = append(backing.PnicSpec, types.DistributedVirtualSwitchHostMemberPnicSpec{
    88  			PnicDevice: strings.TrimSpace(vmnic),
    89  		})
    90  	}
    91  
    92  	config := &types.DVSConfigSpec{
    93  		ConfigVersion: s.Config.GetDVSConfigInfo().ConfigVersion,
    94  	}
    95  
    96  	hosts, err := cmd.HostSystems(f.Args())
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	existing := make(map[string]bool)
   102  	// TODO: host.pnic.info command
   103  	for _, member := range s.Config.GetDVSConfigInfo().Host {
   104  		existing[member.Config.Host.Value] = true
   105  	}
   106  
   107  	for _, host := range hosts {
   108  		ref := host.Reference()
   109  		if existing[ref.Value] {
   110  			fmt.Fprintf(os.Stderr, "%s is already a member of %s\n", host.InventoryPath, dvs.InventoryPath)
   111  			continue
   112  		}
   113  
   114  		config.Host = append(config.Host, types.DistributedVirtualSwitchHostMemberConfigSpec{
   115  			Operation: "add",
   116  			Host:      ref,
   117  			Backing:   backing,
   118  		})
   119  	}
   120  
   121  	if len(config.Host) == 0 {
   122  		return nil
   123  	}
   124  
   125  	task, err := dvs.Reconfigure(ctx, config)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	logger := cmd.ProgressLogger(fmt.Sprintf("adding %d hosts to dvs %s... ", len(config.Host), dvs.InventoryPath))
   131  	defer logger.Wait()
   132  
   133  	_, err = task.WaitForResult(ctx, logger)
   134  	return err
   135  }