github.com/vmware/govmomi@v0.43.0/govc/flags/network.go (about) 1 /* 2 Copyright (c) 2014-2016 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 flags 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "os" 24 25 "github.com/vmware/govmomi/object" 26 "github.com/vmware/govmomi/vim25/types" 27 ) 28 29 type NetworkFlag struct { 30 common 31 32 *DatacenterFlag 33 34 name string 35 net object.NetworkReference 36 adapter string 37 address string 38 isset bool 39 proto string 40 } 41 42 var networkFlagKey = flagKey("network") 43 44 func NewNetworkFlag(ctx context.Context) (*NetworkFlag, context.Context) { 45 if v := ctx.Value(networkFlagKey); v != nil { 46 return v.(*NetworkFlag), ctx 47 } 48 49 v := &NetworkFlag{} 50 v.DatacenterFlag, ctx = NewDatacenterFlag(ctx) 51 ctx = context.WithValue(ctx, networkFlagKey, v) 52 return v, ctx 53 } 54 55 func (flag *NetworkFlag) Register(ctx context.Context, f *flag.FlagSet) { 56 flag.RegisterOnce(func() { 57 flag.DatacenterFlag.Register(ctx, f) 58 59 env := "GOVC_NETWORK" 60 value := os.Getenv(env) 61 flag.name = value 62 usage := fmt.Sprintf("Network [%s]", env) 63 f.Var(flag, "net", usage) 64 f.StringVar(&flag.adapter, "net.adapter", "e1000", "Network adapter type") 65 f.StringVar(&flag.address, "net.address", "", "Network hardware address") 66 f.StringVar(&flag.proto, "net.protocol", "", fmt.Sprintf("Network device protocol. Applicable to vmxnet3vrdma. Default to '%s'", string(types.VirtualVmxnet3VrdmaOptionDeviceProtocolsRocev2))) 67 }) 68 } 69 70 func (flag *NetworkFlag) Process(ctx context.Context) error { 71 return flag.ProcessOnce(func() error { 72 if err := flag.DatacenterFlag.Process(ctx); err != nil { 73 return err 74 } 75 return nil 76 }) 77 } 78 79 func (flag *NetworkFlag) String() string { 80 return flag.name 81 } 82 83 func (flag *NetworkFlag) Set(name string) error { 84 flag.name = name 85 flag.isset = true 86 return nil 87 } 88 89 func (flag *NetworkFlag) IsSet() bool { 90 return flag.isset 91 } 92 93 func (flag *NetworkFlag) Network() (object.NetworkReference, error) { 94 if flag.net != nil { 95 return flag.net, nil 96 } 97 98 finder, err := flag.Finder() 99 if err != nil { 100 return nil, err 101 } 102 103 if flag.net, err = finder.NetworkOrDefault(context.TODO(), flag.name); err != nil { 104 return nil, err 105 } 106 107 return flag.net, nil 108 } 109 110 func (flag *NetworkFlag) Device() (types.BaseVirtualDevice, error) { 111 net, err := flag.Network() 112 if err != nil { 113 return nil, err 114 } 115 116 backing, err := net.EthernetCardBackingInfo(context.TODO()) 117 if err != nil { 118 return nil, err 119 } 120 121 device, err := object.EthernetCardTypes().CreateEthernetCard(flag.adapter, backing) 122 if err != nil { 123 return nil, err 124 } 125 126 if a, ok := device.(*types.VirtualVmxnet3Vrdma); ok { 127 if flag.proto != "" { 128 if flag.proto != string(types.VirtualVmxnet3VrdmaOptionDeviceProtocolsRocev2) && 129 flag.proto != string(types.VirtualVmxnet3VrdmaOptionDeviceProtocolsRocev1) { 130 return nil, fmt.Errorf("invalid device protocol '%s'", flag.proto) 131 } 132 a.DeviceProtocol = flag.proto 133 } 134 } else if flag.proto != "" { 135 return nil, fmt.Errorf("device protocol is only supported for vmxnet3vrdma at the moment") 136 } 137 138 if flag.address == "-" { 139 card := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() 140 card.AddressType = string(types.VirtualEthernetCardMacTypeGenerated) 141 card.MacAddress = "" 142 } else if flag.address != "" { 143 card := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() 144 card.AddressType = string(types.VirtualEthernetCardMacTypeManual) 145 card.MacAddress = flag.address 146 } 147 148 return device, nil 149 } 150 151 // Change applies update backing and hardware address changes to the given network device. 152 func (flag *NetworkFlag) Change(device types.BaseVirtualDevice, update types.BaseVirtualDevice) { 153 current := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() 154 changed := update.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() 155 156 current.Backing = changed.Backing 157 158 if changed.MacAddress != "" { 159 current.MacAddress = changed.MacAddress 160 } 161 162 if changed.AddressType != "" { 163 current.AddressType = changed.AddressType 164 } 165 }