github.com/vmware/govmomi@v0.37.2/govc/dvs/add.go (about)

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