mirror of
https://github.com/harvester/vm-import-controller.git
synced 2025-06-03 01:44:51 +00:00
Add option to select network interface model while importing VM to Harvester using the vm-import-controller (#78)
Add the field `DefaultNetworkInterfaceModel` to `VirtualMachineImportSpec` and `NetworkInterfaceModel` to `NetworkMapping`. With this new fields it is possible to customize the interface models of the VM NICs. Related to: https://github.com/harvester/harvester/issues/7999 Signed-off-by: Volker Theile <vtheile@suse.com>
This commit is contained in:
parent
8d4b8a01d9
commit
d3ad44e039
2
go.mod
2
go.mod
@ -20,6 +20,7 @@ require (
|
||||
k8s.io/apiextensions-apiserver v0.31.3
|
||||
k8s.io/apimachinery v0.31.3
|
||||
k8s.io/client-go v12.0.0+incompatible
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
|
||||
kubevirt.io/api v1.1.0
|
||||
kubevirt.io/kubevirt v1.1.0
|
||||
sigs.k8s.io/cluster-api v1.9.4
|
||||
@ -110,7 +111,6 @@ require (
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-aggregator v0.26.4 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
kubevirt.io/client-go v1.1.0 // indirect
|
||||
kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect
|
||||
kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/rancher/wrangler/pkg/condition"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
kubevirtv1 "kubevirt.io/api/core/v1"
|
||||
|
||||
"github.com/harvester/vm-import-controller/pkg/apis/common"
|
||||
@ -30,9 +31,17 @@ type VirtualMachineImportSpec struct {
|
||||
// Examples: "vm-1234", "my-VM" or "5649cac7-3871-4bb5-aab6-c72b8c18d0a2"
|
||||
VirtualMachineName string `json:"virtualMachineName"`
|
||||
|
||||
Folder string `json:"folder,omitempty"`
|
||||
Mapping []NetworkMapping `json:"networkMapping,omitempty"` //If empty new VirtualMachineImport will be mapped to Management Network
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
Folder string `json:"folder,omitempty"`
|
||||
|
||||
// If empty new VirtualMachineImport will be mapped to Management Network.
|
||||
Mapping []NetworkMapping `json:"networkMapping,omitempty"`
|
||||
// The default network interface model. This is always used when:
|
||||
// - Auto-detection fails (OpenStack source client does not have auto-detection, therefore this field is used for every network interface).
|
||||
// - No network mapping is provided and a "pod-network" is auto-created.
|
||||
// Defaults to "virtio".
|
||||
DefaultNetworkInterfaceModel *string `json:"defaultNetworkInterfaceModel,omitempty" wrangler:"type=string,options=e1000|e1000e|ne2k_pci|pcnet|rtl8139|virtio"`
|
||||
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualMachineImportStatus tracks the status of the VirtualMachineImport export from migration and import into the Harvester cluster
|
||||
@ -70,6 +79,9 @@ type DiskInfo struct {
|
||||
type NetworkMapping struct {
|
||||
SourceNetwork string `json:"sourceNetwork"`
|
||||
DestinationNetwork string `json:"destinationNetwork"`
|
||||
// Override the network interface model that is auto-detected (VMware)
|
||||
// or defaulted (OpenStack).
|
||||
NetworkInterfaceModel *string `json:"networkInterfaceModel,omitempty" wrangler:"type=string,options=e1000|e1000e|ne2k_pci|pcnet|rtl8139|virtio"`
|
||||
}
|
||||
|
||||
type ImportStatus string
|
||||
@ -93,3 +105,23 @@ const (
|
||||
VirtualMachineExportFailed condition.Cond = "VMExportFailed"
|
||||
VirtualMachineMigrationFailed ImportStatus = "VMMigrationFailed"
|
||||
)
|
||||
|
||||
// The supported network interface models.
|
||||
// This can be: e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio.
|
||||
// See https://kubevirt.io/user-guide/network/interfaces_and_networks/#interfaces
|
||||
const (
|
||||
NetworkInterfaceModelE1000 = "e1000"
|
||||
NetworkInterfaceModelE1000e = "e1000e"
|
||||
NetworkInterfaceModelNe2kPci = "ne2k_pci"
|
||||
NetworkInterfaceModelPcnet = "pcnet"
|
||||
NetworkInterfaceModelRtl8139 = "rtl8139"
|
||||
NetworkInterfaceModelVirtio = "virtio"
|
||||
)
|
||||
|
||||
func (in *VirtualMachineImport) GetDefaultNetworkInterfaceModel() string {
|
||||
return ptr.Deref[string](in.Spec.DefaultNetworkInterfaceModel, NetworkInterfaceModelVirtio)
|
||||
}
|
||||
|
||||
func (in *NetworkMapping) GetNetworkInterfaceModel() string {
|
||||
return ptr.Deref[string](in.NetworkInterfaceModel, NetworkInterfaceModelVirtio)
|
||||
}
|
||||
|
83
pkg/source/network.go
Normal file
83
pkg/source/network.go
Normal file
@ -0,0 +1,83 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
kubevirt "kubevirt.io/api/core/v1"
|
||||
|
||||
migration "github.com/harvester/vm-import-controller/pkg/apis/migration.harvesterhci.io/v1beta1"
|
||||
)
|
||||
|
||||
type NetworkInfo struct {
|
||||
NetworkName string
|
||||
MAC string
|
||||
MappedNetwork string
|
||||
Model string
|
||||
}
|
||||
|
||||
func MapNetworks(networkInfos []NetworkInfo, networkMappings []migration.NetworkMapping) []NetworkInfo {
|
||||
result := make([]NetworkInfo, 0)
|
||||
|
||||
for _, ni := range networkInfos {
|
||||
for _, nm := range networkMappings {
|
||||
if nm.SourceNetwork == ni.NetworkName {
|
||||
ni.MappedNetwork = nm.DestinationNetwork
|
||||
|
||||
// Override the auto-detected interface model if it is
|
||||
// customized by the user via the `NetworkMapping`.
|
||||
if nm.NetworkInterfaceModel != nil {
|
||||
ni.Model = nm.GetNetworkInterfaceModel()
|
||||
}
|
||||
|
||||
result = append(result, ni)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func GenerateNetworkInterfaceConfigs(networkInfos []NetworkInfo, defaultNetworkInterfaceModel string) ([]kubevirt.Network, []kubevirt.Interface) {
|
||||
networks := make([]kubevirt.Network, 0, len(networkInfos))
|
||||
interfaces := make([]kubevirt.Interface, 0, len(networkInfos))
|
||||
|
||||
for i, ni := range networkInfos {
|
||||
networks = append(networks, kubevirt.Network{
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Multus: &kubevirt.MultusNetwork{
|
||||
NetworkName: ni.MappedNetwork,
|
||||
},
|
||||
},
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
})
|
||||
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
MacAddress: ni.MAC,
|
||||
Model: ni.Model,
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Bridge: &kubevirt.InterfaceBridge{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// If there is no network, attach to Pod network. Essential for VM to
|
||||
// be booted up.
|
||||
if len(networks) == 0 {
|
||||
networks = append(networks, kubevirt.Network{
|
||||
Name: "pod-network",
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Pod: &kubevirt.PodNetwork{},
|
||||
},
|
||||
})
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: "pod-network",
|
||||
Model: defaultNetworkInterfaceModel,
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Masquerade: &kubevirt.InterfaceMasquerade{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return networks, interfaces
|
||||
}
|
@ -435,7 +435,7 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
return nil, fmt.Errorf("error getting firware settings: %v", err)
|
||||
}
|
||||
|
||||
networkInfos, err := generateNetworkInfo(vmObj.Addresses)
|
||||
networkInfos, err := generateNetworkInfos(vmObj.Addresses, vm.GetDefaultNetworkInterfaceModel())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -488,46 +488,8 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
},
|
||||
}
|
||||
|
||||
mappedNetwork := mapNetworkCards(networkInfos, vm.Spec.Mapping)
|
||||
networkConfig := make([]kubevirt.Network, 0, len(mappedNetwork))
|
||||
for i, v := range mappedNetwork {
|
||||
networkConfig = append(networkConfig, kubevirt.Network{
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Multus: &kubevirt.MultusNetwork{
|
||||
NetworkName: v.MappedNetwork,
|
||||
},
|
||||
},
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
})
|
||||
}
|
||||
|
||||
interfaces := make([]kubevirt.Interface, 0, len(mappedNetwork))
|
||||
for i, v := range mappedNetwork {
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
MacAddress: v.MAC,
|
||||
Model: "virtio",
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Bridge: &kubevirt.InterfaceBridge{},
|
||||
},
|
||||
})
|
||||
}
|
||||
// if there is no network, attach to Pod network. Essential for VM to be booted up
|
||||
if len(networkConfig) == 0 {
|
||||
networkConfig = append(networkConfig, kubevirt.Network{
|
||||
Name: "pod-network",
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Pod: &kubevirt.PodNetwork{},
|
||||
},
|
||||
})
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: "pod-network",
|
||||
Model: "virtio",
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Masquerade: &kubevirt.InterfaceMasquerade{},
|
||||
},
|
||||
})
|
||||
}
|
||||
mappedNetwork := source.MapNetworks(networkInfos, vm.Spec.Mapping)
|
||||
networkConfig, interfaceConfig := source.GenerateNetworkInterfaceConfigs(mappedNetwork, vm.GetDefaultNetworkInterfaceModel())
|
||||
|
||||
// Setup BIOS/EFI, SecureBoot and TPM settings.
|
||||
if uefi {
|
||||
@ -535,7 +497,7 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
}
|
||||
|
||||
vmSpec.Template.Spec.Networks = networkConfig
|
||||
vmSpec.Template.Spec.Domain.Devices.Interfaces = interfaces
|
||||
vmSpec.Template.Spec.Domain.Devices.Interfaces = interfaceConfig
|
||||
newVM.Spec = vmSpec
|
||||
|
||||
// disk attachment needs query by core controller for storage classes, so will be added by the migration controller
|
||||
@ -663,26 +625,6 @@ func (c *Client) findVM(name string) (*ExtendedServer, error) {
|
||||
return &s, err
|
||||
}
|
||||
|
||||
type networkInfo struct {
|
||||
NetworkName string
|
||||
MAC string
|
||||
MappedNetwork string
|
||||
}
|
||||
|
||||
func mapNetworkCards(networkCards []networkInfo, mapping []migration.NetworkMapping) []networkInfo {
|
||||
var retNetwork []networkInfo
|
||||
for _, nc := range networkCards {
|
||||
for _, m := range mapping {
|
||||
if m.SourceNetwork == nc.NetworkName {
|
||||
nc.MappedNetwork = m.DestinationNetwork
|
||||
retNetwork = append(retNetwork, nc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retNetwork
|
||||
}
|
||||
|
||||
func (c *Client) ImageFirmwareSettings(instance *servers.Server) (bool, bool, bool, error) {
|
||||
var imageID string
|
||||
var uefiType, tpmEnabled, secureBoot bool
|
||||
@ -721,9 +663,10 @@ func (c *Client) ImageFirmwareSettings(instance *servers.Server) (bool, bool, bo
|
||||
return uefiType, tpmEnabled, secureBoot, nil
|
||||
}
|
||||
|
||||
func generateNetworkInfo(info map[string]interface{}) ([]networkInfo, error) {
|
||||
networkInfos := make([]networkInfo, 0)
|
||||
uniqueNetworks := make([]networkInfo, 0)
|
||||
func generateNetworkInfos(info map[string]interface{}, defaultInterfaceModel string) ([]source.NetworkInfo, error) {
|
||||
networkInfos := make([]source.NetworkInfo, 0)
|
||||
uniqueNetworks := make([]source.NetworkInfo, 0)
|
||||
|
||||
for network, values := range info {
|
||||
valArr, ok := values.([]interface{})
|
||||
if !ok {
|
||||
@ -734,15 +677,19 @@ func generateNetworkInfo(info map[string]interface{}) ([]networkInfo, error) {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error asserting network array element into map[string]string")
|
||||
}
|
||||
networkInfos = append(networkInfos, networkInfo{
|
||||
networkInfos = append(networkInfos, source.NetworkInfo{
|
||||
NetworkName: network,
|
||||
MAC: valMap["OS-EXT-IPS-MAC:mac_addr"].(string),
|
||||
// Note, the interface model is not provided via the OpenStack
|
||||
// Nova API, therefore we need to set it ourselves.
|
||||
Model: defaultInterfaceModel,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// in case of interfaces with ipv6 and ipv4 addresses they are reported twice, so we need to dedup them
|
||||
// based on a mac address
|
||||
networksMap := make(map[string]networkInfo)
|
||||
networksMap := make(map[string]source.NetworkInfo)
|
||||
for _, v := range networkInfos {
|
||||
networksMap[v.MAC] = v
|
||||
}
|
||||
@ -750,6 +697,7 @@ func generateNetworkInfo(info map[string]interface{}) ([]networkInfo, error) {
|
||||
for _, v := range networksMap {
|
||||
uniqueNetworks = append(uniqueNetworks, v)
|
||||
}
|
||||
|
||||
return uniqueNetworks, nil
|
||||
}
|
||||
|
||||
|
@ -126,8 +126,9 @@ func Test_GenerateVirtualMachine(t *testing.T) {
|
||||
assert.NoError(err, "expected no error during GenerateVirtualMachine")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Domain.CPU, "expected CPU's to not be empty")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Domain.Resources.Limits.Memory(), "expected memory limit to not be empty")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Networks, "expected to find atleast 1 network as pod network should have been applied")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Domain.Devices.Interfaces, "expected to find atleast 1 interface for pod-network")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Networks, "expected to find at least 1 network as pod network should have been applied")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Domain.Devices.Interfaces, "expected to find at least 1 interface for pod-network")
|
||||
assert.Equal(newVM.Spec.Template.Spec.Domain.Devices.Interfaces[0].Model, migration.NetworkInterfaceModelVirtio, "expected to have a NIC with virtio model")
|
||||
}
|
||||
|
||||
func Test_generateNetworkInfo(t *testing.T) {
|
||||
@ -137,10 +138,11 @@ func Test_generateNetworkInfo(t *testing.T) {
|
||||
err := json.Unmarshal(networkInfoByte, &networkInfoMap)
|
||||
assert.NoError(err, "expected no error while unmarshalling network info")
|
||||
|
||||
vmInterfaceDetails, err := generateNetworkInfo(networkInfoMap)
|
||||
vmInterfaceDetails, err := generateNetworkInfos(networkInfoMap, migration.NetworkInterfaceModelVirtio)
|
||||
assert.NoError(err, "expected no error while generating network info")
|
||||
assert.Len(vmInterfaceDetails, 2, "expected to find 2 interfaces only")
|
||||
|
||||
assert.Equal(vmInterfaceDetails[0].Model, migration.NetworkInterfaceModelVirtio, "expected to have a NIC with virtio model")
|
||||
assert.Equal(vmInterfaceDetails[1].Model, migration.NetworkInterfaceModelVirtio, "expected to have a NIC with virtio model")
|
||||
}
|
||||
|
||||
func Test_ClientOptions(t *testing.T) {
|
||||
|
@ -323,8 +323,7 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
"spec": o,
|
||||
}, []string{"spec"})).Info("Origin spec of the VM to be imported")
|
||||
|
||||
// Need CPU, Socket, Memory, VirtualNIC information to perform the mapping
|
||||
networkInfo := identifyNetworkCards(o.Config.Hardware.Device)
|
||||
networkInfos := generateNetworkInfos(o.Config.Hardware.Device)
|
||||
|
||||
vmSpec := kubevirt.VirtualMachineSpec{
|
||||
RunStrategy: &[]kubevirt.VirtualMachineRunStrategy{kubevirt.RunStrategyRerunOnFailure}[0],
|
||||
@ -360,46 +359,8 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
},
|
||||
}
|
||||
|
||||
mappedNetwork := mapNetworkCards(networkInfo, vm.Spec.Mapping)
|
||||
networkConfig := make([]kubevirt.Network, 0, len(mappedNetwork))
|
||||
for i, v := range mappedNetwork {
|
||||
networkConfig = append(networkConfig, kubevirt.Network{
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Multus: &kubevirt.MultusNetwork{
|
||||
NetworkName: v.MappedNetwork,
|
||||
},
|
||||
},
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
})
|
||||
}
|
||||
|
||||
interfaces := make([]kubevirt.Interface, 0, len(mappedNetwork))
|
||||
for i, v := range mappedNetwork {
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: fmt.Sprintf("migrated-%d", i),
|
||||
MacAddress: v.MAC,
|
||||
Model: "virtio",
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Bridge: &kubevirt.InterfaceBridge{},
|
||||
},
|
||||
})
|
||||
}
|
||||
// if there is no network, attach to Pod network. Essential for VM to be booted up
|
||||
if len(networkConfig) == 0 {
|
||||
networkConfig = append(networkConfig, kubevirt.Network{
|
||||
Name: "pod-network",
|
||||
NetworkSource: kubevirt.NetworkSource{
|
||||
Pod: &kubevirt.PodNetwork{},
|
||||
},
|
||||
})
|
||||
interfaces = append(interfaces, kubevirt.Interface{
|
||||
Name: "pod-network",
|
||||
Model: "virtio",
|
||||
InterfaceBindingMethod: kubevirt.InterfaceBindingMethod{
|
||||
Masquerade: &kubevirt.InterfaceMasquerade{},
|
||||
},
|
||||
})
|
||||
}
|
||||
mappedNetwork := source.MapNetworks(networkInfos, vm.Spec.Mapping)
|
||||
networkConfig, interfaceConfig := source.GenerateNetworkInterfaceConfigs(mappedNetwork, vm.GetDefaultNetworkInterfaceModel())
|
||||
|
||||
// Setup BIOS/EFI, SecureBoot and TPM settings.
|
||||
uefi := strings.EqualFold(o.Config.Firmware, string(types.GuestOsDescriptorFirmwareTypeEfi))
|
||||
@ -413,7 +374,7 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
|
||||
}
|
||||
|
||||
vmSpec.Template.Spec.Networks = networkConfig
|
||||
vmSpec.Template.Spec.Domain.Devices.Interfaces = interfaces
|
||||
vmSpec.Template.Spec.Domain.Devices.Interfaces = interfaceConfig
|
||||
newVM.Spec = vmSpec
|
||||
|
||||
// disk attachment needs query by core controller for storage classes, so will be added by the migration controller
|
||||
@ -430,64 +391,57 @@ func (c *Client) findVM(path, name string) (*object.VirtualMachine, error) {
|
||||
return f.VirtualMachine(c.ctx, vmPath)
|
||||
}
|
||||
|
||||
type networkInfo struct {
|
||||
NetworkName string
|
||||
MAC string
|
||||
MappedNetwork string
|
||||
}
|
||||
func generateNetworkInfos(devices []types.BaseVirtualDevice) []source.NetworkInfo {
|
||||
result := make([]source.NetworkInfo, 0, len(devices))
|
||||
|
||||
func identifyNetworkCards(devices []types.BaseVirtualDevice) []networkInfo {
|
||||
var resp []networkInfo
|
||||
for _, d := range devices {
|
||||
switch d := d.(type) {
|
||||
case *types.VirtualVmxnet:
|
||||
obj := d
|
||||
resp = append(resp, networkInfo{
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelVirtio,
|
||||
})
|
||||
case *types.VirtualE1000e:
|
||||
obj := d
|
||||
resp = append(resp, networkInfo{
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelE1000e,
|
||||
})
|
||||
case *types.VirtualE1000:
|
||||
obj := d
|
||||
resp = append(resp, networkInfo{
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelE1000,
|
||||
})
|
||||
case *types.VirtualVmxnet3:
|
||||
obj := d
|
||||
resp = append(resp, networkInfo{
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelVirtio,
|
||||
})
|
||||
case *types.VirtualVmxnet2:
|
||||
obj := d
|
||||
resp = append(resp, networkInfo{
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelVirtio,
|
||||
})
|
||||
case *types.VirtualPCNet32:
|
||||
obj := d
|
||||
result = append(result, source.NetworkInfo{
|
||||
NetworkName: obj.DeviceInfo.GetDescription().Summary,
|
||||
MAC: obj.MacAddress,
|
||||
Model: migration.NetworkInterfaceModelPcnet,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func mapNetworkCards(networkCards []networkInfo, mapping []migration.NetworkMapping) []networkInfo {
|
||||
var retNetwork []networkInfo
|
||||
for _, nc := range networkCards {
|
||||
for _, m := range mapping {
|
||||
if m.SourceNetwork == nc.NetworkName {
|
||||
nc.MappedNetwork = m.DestinationNetwork
|
||||
retNetwork = append(retNetwork, nc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retNetwork
|
||||
return result
|
||||
}
|
||||
|
||||
// adapterType tries to identify the disk bus type from vmware
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
|
||||
migration "github.com/harvester/vm-import-controller/pkg/apis/migration.harvesterhci.io/v1beta1"
|
||||
"github.com/harvester/vm-import-controller/pkg/server"
|
||||
"github.com/harvester/vm-import-controller/pkg/source"
|
||||
)
|
||||
|
||||
var vcsimPort string
|
||||
@ -256,7 +257,7 @@ func Test_GenerateVirtualMachine(t *testing.T) {
|
||||
assert.Len(newVM.Spec.Template.Spec.Domain.Devices.Interfaces, 1, "should have found a network map")
|
||||
assert.Equal(newVM.Spec.Template.Spec.Domain.Memory.Guest.String(), "32M", "expected VM to have 32M memory")
|
||||
assert.NotEmpty(newVM.Spec.Template.Spec.Domain.Resources.Limits, "expect to find resource requests to be present")
|
||||
|
||||
assert.Equal(newVM.Spec.Template.Spec.Domain.Devices.Interfaces[0].Model, migration.NetworkInterfaceModelE1000, "expected to have a NIC with e1000 model")
|
||||
}
|
||||
|
||||
func Test_GenerateVirtualMachine_secureboot(t *testing.T) {
|
||||
@ -365,7 +366,7 @@ func Test_identifyNetworkCards(t *testing.T) {
|
||||
err = vmObj.Properties(c.ctx, vmObj.Reference(), []string{}, &o)
|
||||
assert.NoError(err, "expected no error looking up vmObj properties")
|
||||
|
||||
networkInfo := identifyNetworkCards(o.Config.Hardware.Device)
|
||||
networkInfo := generateNetworkInfos(o.Config.Hardware.Device)
|
||||
assert.Len(networkInfo, 1, "expected to find only 1 item in the networkInfo")
|
||||
networkMapping := []migration.NetworkMapping{
|
||||
{
|
||||
@ -373,15 +374,17 @@ func Test_identifyNetworkCards(t *testing.T) {
|
||||
DestinationNetwork: "harvester1",
|
||||
},
|
||||
{
|
||||
SourceNetwork: "DVSwitch: fea97929-4b2d-5972-b146-930c6d0b4014",
|
||||
DestinationNetwork: "pod-network",
|
||||
SourceNetwork: "DVSwitch: fea97929-4b2d-5972-b146-930c6d0b4014",
|
||||
DestinationNetwork: "pod-network",
|
||||
NetworkInterfaceModel: pointer.String(migration.NetworkInterfaceModelRtl8139),
|
||||
},
|
||||
}
|
||||
|
||||
mappedInfo := mapNetworkCards(networkInfo, networkMapping)
|
||||
mappedInfo := source.MapNetworks(networkInfo, networkMapping)
|
||||
assert.Len(mappedInfo, 1, "expected to find only 1 item in the mapped networkinfo")
|
||||
assert.Equal(mappedInfo[0].Model, "rtl8139", "expected to have a NIC with rtl8139 model")
|
||||
|
||||
noNetworkMapping := []migration.NetworkMapping{}
|
||||
noMappedInfo := mapNetworkCards(networkInfo, noNetworkMapping)
|
||||
noMappedInfo := source.MapNetworks(networkInfo, noNetworkMapping)
|
||||
assert.Len(noMappedInfo, 0, "expected to find no item in the mapped networkinfo")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user