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  }