Skip to content

Commit

Permalink
address openstack network duplication when interface may have both ip…
Browse files Browse the repository at this point in the history
…v6 and ipv4 addresses and add preflight check to identify duplicate source network definitions

(cherry picked from commit 03a8ef0)
  • Loading branch information
ibrokethecloud authored and starbops committed Dec 9, 2024
1 parent f1b101c commit 44248a3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
11 changes: 11 additions & 0 deletions pkg/controllers/migration/virtualmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ func (h *virtualMachineHandler) preFlightChecks(vm *migration.VirtualMachineImpo
}
}

// dedup source network names as the same source network name cannot appear twice
sourceNetworkMap := make(map[string]bool)
for _, network := range vm.Spec.Mapping {
_, ok := sourceNetworkMap[network.SourceNetwork]
if !ok {
sourceNetworkMap[network.SourceNetwork] = true
continue
}
return fmt.Errorf("source network %s appears multiple times in vm spec", network.SourceNetwork)
}

return nil
}

Expand Down
52 changes: 36 additions & 16 deletions pkg/source/openstack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,23 +334,11 @@ func (c *Client) GenerateVirtualMachine(vm *migration.VirtualMachineImport) (*ku
return nil, fmt.Errorf("error getting firware settings: %v", err)
}

var networks []networkInfo
for network, values := range vmObj.Addresses {
valArr, ok := values.([]interface{})
if !ok {
return nil, fmt.Errorf("error asserting interface []interface")
}
for _, v := range valArr {
valMap, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("error asserting network array element into map[string]string")
}
networks = append(networks, networkInfo{
NetworkName: network,
MAC: valMap["OS-EXT-IPS-MAC:mac_addr"].(string),
})
}
networks, err := generateNetworkInfo(vmObj.Addresses)
if err != nil {
return nil, err
}

newVM := &kubevirt.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Name: vm.Spec.VirtualMachineName,
Expand Down Expand Up @@ -637,3 +625,35 @@ func (c *Client) ImageFirmwareSettings(instance *servers.Server) (bool, bool, bo
}
return uefiType, tpmEnabled, secureBoot, nil
}

func generateNetworkInfo(info map[string]interface{}) ([]networkInfo, error) {
networks := make([]networkInfo, 0)
uniqueNetworks := make([]networkInfo, 0)
for network, values := range info {
valArr, ok := values.([]interface{})
if !ok {
return nil, fmt.Errorf("error asserting interface []interface")
}
for _, v := range valArr {
valMap, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("error asserting network array element into map[string]string")
}
networks = append(networks, networkInfo{
NetworkName: network,
MAC: valMap["OS-EXT-IPS-MAC:mac_addr"].(string),
})
}
}
// 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)
for _, v := range networks {
networksMap[v.MAC] = v
}

for _, v := range networksMap {
uniqueNetworks = append(uniqueNetworks, v)
}
return uniqueNetworks, nil
}
14 changes: 14 additions & 0 deletions pkg/source/openstack/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package openstack

import (
"context"
"encoding/json"
"os"
"testing"

Expand Down Expand Up @@ -124,3 +125,16 @@ func Test_GenerateVirtualMachine(t *testing.T) {
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")
}

func Test_generateNetworkInfo(t *testing.T) {
networkInfoByte := []byte(`{"private":[{"OS-EXT-IPS-MAC:mac_addr":"fa:16:3e:92:5f:45","OS-EXT-IPS:type":"fixed","addr":"fd5b:731d:94e1:0:f816:3eff:fe92:5f45","version":6},{"OS-EXT-IPS-MAC:mac_addr":"fa:16:3e:92:5f:45","OS-EXT-IPS:type":"fixed","addr":"10.0.0.38","version":4}],"shared":[{"OS-EXT-IPS-MAC:mac_addr":"fa:16:3e:ec:49:11","OS-EXT-IPS:type":"fixed","addr":"192.168.233.233","version":4}]}`)
var networkInfoMap map[string]interface{}
assert := require.New(t)
err := json.Unmarshal(networkInfoByte, &networkInfoMap)
assert.NoError(err, "expected no error while unmarshalling network info")

vmInterfaceDetails, err := generateNetworkInfo(networkInfoMap)
assert.NoError(err, "expected no error while generating network info")
assert.Len(vmInterfaceDetails, 2, "expected to find 2 interfaces only")

}

0 comments on commit 44248a3

Please sign in to comment.