github.com/vmware/govmomi@v0.43.0/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 }