From b74e28a479fc0642396d584cae127867a4a0f6f1 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 9 Jul 2020 15:59:15 +0200 Subject: [PATCH] match network to host when multiple networks are found --- builder/vsphere/driver/network.go | 24 ++++++++++++++++++++++++ builder/vsphere/driver/vm.go | 28 ++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/builder/vsphere/driver/network.go b/builder/vsphere/driver/network.go index 89f491c12..ff1dba678 100644 --- a/builder/vsphere/driver/network.go +++ b/builder/vsphere/driver/network.go @@ -31,6 +31,21 @@ func (d *Driver) FindNetwork(name string) (*Network, error) { }, nil } +func (d *Driver) FindNetworks(name string) ([]*Network, error) { + ns, err := d.finder.NetworkList(d.ctx, name) + if err != nil { + return nil, err + } + var networks []*Network + for _, n := range ns { + networks = append(networks, &Network{ + network: n, + driver: d, + }) + } + return networks, nil +} + func (n *Network) Info(params ...string) (*mo.Network, error) { var p []string if len(params) == 0 { @@ -51,3 +66,12 @@ func (n *Network) Info(params ...string) (*mo.Network, error) { } return &info, nil } + +type MultipleNetworkFoundError struct { + path string + append string +} + +func (e *MultipleNetworkFoundError) Error() string { + return fmt.Sprintf("path '%s' resolves to multiple networks. %s", e.path, e.append) +} diff --git a/builder/vsphere/driver/vm.go b/builder/vsphere/driver/vm.go index cae885e1e..f00e3f894 100644 --- a/builder/vsphere/driver/vm.go +++ b/builder/vsphere/driver/vm.go @@ -753,11 +753,35 @@ func addNetwork(d *Driver, devices object.VirtualDeviceList, config *CreateConfi func findNetwork(network string, host string, d *Driver) (object.NetworkReference, error) { if network != "" { var err error - network, err := d.finder.Network(d.ctx, network) + networks, err := d.FindNetworks(network) if err != nil { return nil, err } - return network, nil + if len(networks) == 1 { + return networks[0].network, nil + } + + // If there are multiple networks then try to match the host + if host != "" { + h, err := d.FindHost(host) + if err != nil { + return nil, &MultipleNetworkFoundError{network, fmt.Sprintf("unable to match a network to the host %s: %s", host, err.Error())} + } + for _, n := range networks { + info, err := n.Info("host") + if err != nil { + continue + } + for _, host := range info.Host { + if h.host.Reference().Value == host.Reference().Value { + return n.network, nil + } + } + } + return nil, &MultipleNetworkFoundError{network, fmt.Sprintf("unable to match a network to the host %s", host)} + } + + return nil, &MultipleNetworkFoundError{network, "please provide a host to match or the network full path"} } if host != "" {