Skip to content

Commit cd068e6

Browse files
change how network name lookup is perform when importing vmware based vm's to allow importing of VM's using Dswitch backed networks
1 parent 5288366 commit cd068e6

File tree

2 files changed

+85
-10
lines changed

2 files changed

+85
-10
lines changed

pkg/source/vmware/client.go

+84-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/vmware/govmomi/nfc"
1515
"github.com/vmware/govmomi/object"
1616
"github.com/vmware/govmomi/session"
17+
"github.com/vmware/govmomi/view"
1718
"github.com/vmware/govmomi/vim25"
1819
"github.com/vmware/govmomi/vim25/mo"
1920
"github.com/vmware/govmomi/vim25/soap"
@@ -31,8 +32,9 @@ import (
3132
type Client struct {
3233
ctx context.Context
3334
*govmomi.Client
34-
tmpCerts string
35-
dc string
35+
tmpCerts string
36+
dc string
37+
networkMapping map[string]string
3638
}
3739

3840
func NewClient(ctx context.Context, endpoint string, dc string, secret *corev1.Secret) (*Client, error) {
@@ -91,6 +93,11 @@ func NewClient(ctx context.Context, endpoint string, dc string, secret *corev1.S
9193
vmwareClient.ctx = ctx
9294
vmwareClient.Client = c
9395
vmwareClient.dc = dc
96+
networkMap, err := GenerateNetworkMapByRef(ctx, c.Client)
97+
if err != nil {
98+
return nil, fmt.Errorf("error generating network map during client initialisation: %v", err)
99+
}
100+
vmwareClient.networkMapping = networkMap
94101
return vmwareClient, nil
95102

96103
}
@@ -316,7 +323,7 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
316323
}
317324

318325
// Need CPU, Socket, Memory, VirtualNIC information to perform the mapping
319-
networkInfo := identifyNetworkCards(o.Config.Hardware.Device)
326+
networkInfo := identifyNetworkCards(c.networkMapping, o.Config.Hardware.Device)
320327

321328
vmSpec := kubevirt.VirtualMachineSpec{
322329
RunStrategy: &[]kubevirt.VirtualMachineRunStrategy{kubevirt.RunStrategyRerunOnFailure}[0],
@@ -438,38 +445,58 @@ type networkInfo struct {
438445
MappedNetwork string
439446
}
440447

441-
func identifyNetworkCards(devices []types.BaseVirtualDevice) []networkInfo {
448+
func identifyNetworkCards(networkMap map[string]string, devices []types.BaseVirtualDevice) []networkInfo {
442449
var resp []networkInfo
443450
for _, d := range devices {
444451
switch d := d.(type) {
445452
case *types.VirtualVmxnet:
446453
obj := d
454+
summary := identifyNetworkName(networkMap, *obj.GetVirtualDevice())
455+
if summary == "" {
456+
summary = obj.DeviceInfo.GetDescription().Summary
457+
}
447458
resp = append(resp, networkInfo{
448-
NetworkName: obj.DeviceInfo.GetDescription().Summary,
459+
NetworkName: summary,
449460
MAC: obj.MacAddress,
450461
})
451462
case *types.VirtualE1000e:
452463
obj := d
464+
summary := identifyNetworkName(networkMap, *obj.GetVirtualDevice())
465+
if summary == "" {
466+
summary = obj.DeviceInfo.GetDescription().Summary
467+
}
453468
resp = append(resp, networkInfo{
454-
NetworkName: obj.DeviceInfo.GetDescription().Summary,
469+
NetworkName: summary,
455470
MAC: obj.MacAddress,
456471
})
457472
case *types.VirtualE1000:
458473
obj := d
474+
summary := identifyNetworkName(networkMap, *obj.GetVirtualDevice())
475+
if summary == "" {
476+
summary = obj.DeviceInfo.GetDescription().Summary
477+
}
459478
resp = append(resp, networkInfo{
460-
NetworkName: obj.DeviceInfo.GetDescription().Summary,
479+
NetworkName: summary,
461480
MAC: obj.MacAddress,
462481
})
463482
case *types.VirtualVmxnet3:
464483
obj := d
484+
summary := identifyNetworkName(networkMap, *obj.GetVirtualDevice())
485+
if summary == "" {
486+
summary = obj.DeviceInfo.GetDescription().Summary
487+
}
465488
resp = append(resp, networkInfo{
466-
NetworkName: obj.DeviceInfo.GetDescription().Summary,
489+
NetworkName: summary,
467490
MAC: obj.MacAddress,
468491
})
469492
case *types.VirtualVmxnet2:
470493
obj := d
494+
summary := identifyNetworkName(networkMap, *obj.GetVirtualDevice())
495+
if summary == "" {
496+
summary = obj.DeviceInfo.GetDescription().Summary
497+
}
471498
resp = append(resp, networkInfo{
472-
NetworkName: obj.DeviceInfo.GetDescription().Summary,
499+
NetworkName: summary,
473500
MAC: obj.MacAddress,
474501
})
475502
}
@@ -510,3 +537,51 @@ func (c *Client) SanitizeVirtualMachineImport(vm *migration.VirtualMachineImport
510537

511538
return nil
512539
}
540+
541+
// GenerateNetworkMayByRef lists all networks defined in the DC and converts them to
542+
// network id: network name
543+
// this subsequently used to map a network id to network name if needed based on the type
544+
// of backing device for a nic
545+
func GenerateNetworkMapByRef(ctx context.Context, c *vim25.Client) (map[string]string, error) {
546+
networks, err := generateNetworkList(ctx, c)
547+
if err != nil {
548+
return nil, err
549+
}
550+
returnMap := make(map[string]string, len(networks))
551+
for _, v := range networks {
552+
returnMap[v.Reference().Value] = v.Name
553+
}
554+
return returnMap, nil
555+
}
556+
557+
func generateNetworkList(ctx context.Context, c *vim25.Client) ([]mo.Network, error) {
558+
var networks []mo.Network
559+
manager := view.NewManager(c)
560+
networkView, err := manager.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{"Network"}, true)
561+
if err != nil {
562+
return networks, fmt.Errorf("error generating network container view: %v", err)
563+
}
564+
defer networkView.Destroy(ctx)
565+
if err := networkView.Retrieve(ctx, []string{"Network"}, nil, &networks); err != nil {
566+
return networks, fmt.Errorf("error retreiving networks: %v", err)
567+
}
568+
return networks, nil
569+
}
570+
571+
// identifyNetworkName uses the backing device for a nic to identify network name correctly
572+
// in case of a nic using a Distributed VSwitch the summary returned from device is of the form
573+
// DVSwitch : HEX NUMBER which breaks network lookup. As a result we need to identify the network name
574+
// from the PortGroupKey
575+
func identifyNetworkName(networkMap map[string]string, device types.VirtualDevice) string {
576+
var summary string
577+
backing := device.Backing
578+
switch b := backing.(type) {
579+
case *types.VirtualEthernetCardDistributedVirtualPortBackingInfo:
580+
obj := b
581+
summary = networkMap[obj.Port.PortgroupKey]
582+
case *types.VirtualEthernetCardNetworkBackingInfo:
583+
obj := b
584+
summary = obj.DeviceName
585+
}
586+
return summary
587+
}

pkg/source/vmware/client_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func Test_identifyNetworkCards(t *testing.T) {
284284
err = vmObj.Properties(c.ctx, vmObj.Reference(), []string{}, &o)
285285
assert.NoError(err, "expected no error looking up vmObj properties")
286286

287-
networkInfo := identifyNetworkCards(o.Config.Hardware.Device)
287+
networkInfo := identifyNetworkCards(c.networkMapping, o.Config.Hardware.Device)
288288
assert.Len(networkInfo, 1, "expected to find only 1 item in the networkInfo")
289289
networkMapping := []migration.NetworkMapping{
290290
{

0 commit comments

Comments
 (0)