Skip to content

Commit

Permalink
network, namescheme: Consolidate pod interface names
Browse files Browse the repository at this point in the history
There is a need to consolidate the pod-interface name scheme of networks
given in the VMI spec, so that they can be approached in consistent way
in different times in the VMI's lifecycle.
Introducing NameScheme that maps network names to
their appropriate network/pod interface name.

Signed-off-by: Ram Lavi <ralavi@redhat.com>
  • Loading branch information
RamLavi committed Sep 7, 2022
1 parent 1bd2e3c commit d1638ca
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 39 deletions.
12 changes: 11 additions & 1 deletion pkg/network/namescheme/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ go_library(
srcs = ["networknamescheme.go"],
importpath = "kubevirt.io/kubevirt/pkg/network/namescheme",
visibility = ["//visibility:public"],
deps = [
"//pkg/network/vmispec:go_default_library",
"//staging/src/kubevirt.io/api/core/v1:go_default_library",
],
)

go_test(
Expand All @@ -13,5 +17,11 @@ go_test(
"networknamescheme_suite_test.go",
"networknamescheme_test.go",
],
deps = ["//staging/src/kubevirt.io/client-go/testutils:go_default_library"],
deps = [
":go_default_library",
"//staging/src/kubevirt.io/api/core/v1:go_default_library",
"//staging/src/kubevirt.io/client-go/testutils:go_default_library",
"//vendor/github.com/onsi/ginkgo/v2:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
],
)
34 changes: 34 additions & 0 deletions pkg/network/namescheme/networknamescheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,38 @@

package namescheme

import (
"fmt"

v1 "kubevirt.io/api/core/v1"

"kubevirt.io/kubevirt/pkg/network/vmispec"
)

const PrimaryPodInterfaceName = "eth0"

// CreateNetworkNameScheme iterates over the VMI's Networks, and creates for each a pod interface name.
// The returned map associates between the network name and the generated pod interface name.
// Primary network will use "eth0" and the secondary ones will use "net<id>" format, where id is an enumeration
// from 1 to n.
func CreateNetworkNameScheme(vmiNetworks []v1.Network) map[string]string {
networkNameSchemeMap := mapMultusNonDefaultNetworksToPodInterfaceName(vmiNetworks)

if multusDefaultNetwork := vmispec.LookUpDefaultNetwork(vmiNetworks); multusDefaultNetwork != nil {
networkNameSchemeMap[multusDefaultNetwork.Name] = PrimaryPodInterfaceName
}

return networkNameSchemeMap
}

func mapMultusNonDefaultNetworksToPodInterfaceName(networks []v1.Network) map[string]string {
networkNameSchemeMap := map[string]string{}
for i, network := range vmispec.FilterMultusNonDefaultNetworks(networks) {
networkNameSchemeMap[network.Name] = secondaryInterfaceName(i + 1)
}
return networkNameSchemeMap
}

func secondaryInterfaceName(idx int) string {
return fmt.Sprintf("net%d", idx)
}
70 changes: 70 additions & 0 deletions pkg/network/namescheme/networknamescheme_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,73 @@
*/

package namescheme_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

virtv1 "kubevirt.io/api/core/v1"

"kubevirt.io/kubevirt/pkg/network/namescheme"
)

var _ = Describe("Network Name Scheme", func() {
Context("CreateNetworkNameScheme", func() {
DescribeTable("should return the expected NetworkNameSchemeMap",
func(networkList []virtv1.Network, expectedNetworkNameSchemeMap map[string]string) {
podIfacesNameScheme := namescheme.CreateNetworkNameScheme(networkList)

Expect(podIfacesNameScheme).To(Equal(expectedNetworkNameSchemeMap))
},
Entry("when network list is nil", nil, map[string]string{}),
Entry("when no multus networks exist",
[]virtv1.Network{
newPodNetwork("default"),
},
map[string]string{
"default": namescheme.PrimaryPodInterfaceName,
}),
Entry("when default multus networks exist",
[]virtv1.Network{
createMultusDefaultNetwork("network0", "default/nad0"),
createMultusSecondaryNetwork("network1", "default/nad1"),
createMultusSecondaryNetwork("network2", "default/nad2"),
},
map[string]string{
"network0": namescheme.PrimaryPodInterfaceName,
"network1": "net1",
"network2": "net2",
}),
)
})
})

func createMultusSecondaryNetwork(name, networkName string) virtv1.Network {
return createMultusNetwork(name, networkName)
}

func createMultusDefaultNetwork(name, networkName string) virtv1.Network {
multusNetwork := createMultusNetwork(name, networkName)
multusNetwork.Multus.Default = true
return multusNetwork
}

func createMultusNetwork(name, networkName string) virtv1.Network {
return virtv1.Network{
Name: name,
NetworkSource: virtv1.NetworkSource{
Multus: &virtv1.MultusNetwork{
NetworkName: networkName,
},
},
}
}

func newPodNetwork(name string) virtv1.Network {
return virtv1.Network{
Name: name,
NetworkSource: virtv1.NetworkSource{
Pod: &virtv1.PodNetwork{},
},
}
}
36 changes: 4 additions & 32 deletions pkg/network/setup/podnic.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ func newPodNIC(vmi *v1.VirtualMachineInstance, network *v1.Network, handler netd
return nil, fmt.Errorf("no iface matching with network %s", network.Name)
}

podInterfaceName, err := composePodInterfaceName(vmi, network)
if err != nil {
return nil, err
networkNameScheme := namescheme.CreateNetworkNameScheme(vmi.Spec.Networks)
podInterfaceName, exists := networkNameScheme[network.Name]
if !exists {
return nil, fmt.Errorf("pod interface name not found for network %s", network.Name)
}

return &podNIC{
Expand Down Expand Up @@ -361,35 +362,6 @@ func generateInPodBridgeInterfaceName(podInterfaceName string) string {
return fmt.Sprintf("k6t-%s", podInterfaceName)
}

func composePodInterfaceName(vmi *v1.VirtualMachineInstance, network *v1.Network) (string, error) {
if isSecondaryMultusNetwork(*network) {
multusIndex := findMultusIndex(vmi, network)
if multusIndex == -1 {
return "", fmt.Errorf("Network name %s not found", network.Name)
}
return fmt.Sprintf("net%d", multusIndex), nil
}
return namescheme.PrimaryPodInterfaceName, nil
}

func findMultusIndex(vmi *v1.VirtualMachineInstance, networkToFind *v1.Network) int {
idxMultus := 0
for _, network := range vmi.Spec.Networks {
if isSecondaryMultusNetwork(network) {
// multus pod interfaces start from 1
idxMultus++
if network.Name == networkToFind.Name {
return idxMultus
}
}
}
return -1
}

func isSecondaryMultusNetwork(net v1.Network) bool {
return net.Multus != nil && !net.Multus.Default
}

func getPIDString(pid *int) string {
if pid != nil {
return fmt.Sprintf("%d", *pid)
Expand Down
13 changes: 11 additions & 2 deletions pkg/network/vmispec/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@ func lookupPodNetwork(networks []v1.Network) *v1.Network {
func FilterMultusNonDefaultNetworks(networks []v1.Network) []v1.Network {
var multusNetworks []v1.Network
for _, network := range networks {
if isSecondaryMultusNetwork(network) {
if IsSecondaryMultusNetwork(network) {
multusNetworks = append(multusNetworks, network)
}
}
return multusNetworks
}

func isSecondaryMultusNetwork(net v1.Network) bool {
func LookUpDefaultNetwork(networks []v1.Network) *v1.Network {
for i, network := range networks {
if !IsSecondaryMultusNetwork(network) {
return &networks[i]
}
}
return nil
}

func IsSecondaryMultusNetwork(net v1.Network) bool {
return net.Multus != nil && !net.Multus.Default
}
27 changes: 27 additions & 0 deletions pkg/network/vmispec/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ var _ = Describe("Network", func() {
multusSecondaryNetwork3,
}),
)

DescribeTable("should fail to return the default network", func(inputNetworks []v1.Network) {
Expect(vmispec.LookUpDefaultNetwork(inputNetworks)).To(BeNil())
},
Entry("when there are no networks", []v1.Network{}),
Entry("when there are no default networks", []v1.Network{multusSecondaryNetwork1, multusSecondaryNetwork2}),
)
DescribeTable("should succeed to return the default network", func(inputNetworks []v1.Network, expectNetwork *v1.Network) {
Expect(vmispec.LookUpDefaultNetwork(inputNetworks)).To(Equal(expectNetwork))
},
Entry("when there is a default pod network",
[]v1.Network{
podNetwork,
multusSecondaryNetwork1,
multusSecondaryNetwork2,
},
&podNetwork,
),
Entry("when there is a multus default network",
[]v1.Network{
multusDefaultNetwork,
multusSecondaryNetwork1,
multusSecondaryNetwork2,
},
&multusDefaultNetwork,
),
)
})

func createMultusSecondaryNetwork(name, networkName string) v1.Network {
Expand Down
1 change: 1 addition & 0 deletions pkg/virt-controller/services/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ go_library(
"//pkg/hooks:go_default_library",
"//pkg/host-disk:go_default_library",
"//pkg/network/istio:go_default_library",
"//pkg/network/namescheme:go_default_library",
"//pkg/network/vmispec:go_default_library",
"//pkg/util:go_default_library",
"//pkg/util/hardware:go_default_library",
Expand Down
12 changes: 8 additions & 4 deletions pkg/virt-controller/services/multus_annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

v1 "kubevirt.io/api/core/v1"

"kubevirt.io/kubevirt/pkg/network/namescheme"
"kubevirt.io/kubevirt/pkg/network/vmispec"
)

Expand Down Expand Up @@ -58,10 +59,13 @@ func (mnap multusNetworkAnnotationPool) toString() (string, error) {
func generateMultusCNIAnnotation(vmi *v1.VirtualMachineInstance) (string, error) {
multusNetworkAnnotationPool := multusNetworkAnnotationPool{}

multusNonDefaultNetworks := vmispec.FilterMultusNonDefaultNetworks(vmi.Spec.Networks)
for i, network := range multusNonDefaultNetworks {
multusNetworkAnnotationPool.add(
newMultusAnnotationData(vmi, network, fmt.Sprintf("net%d", i+1)))
networkNameScheme := namescheme.CreateNetworkNameScheme(vmi.Spec.Networks)
for _, network := range vmi.Spec.Networks {
if vmispec.IsSecondaryMultusNetwork(network) {
podInterfaceName := networkNameScheme[network.Name]
multusNetworkAnnotationPool.add(
newMultusAnnotationData(vmi, network, podInterfaceName))
}
}

if !multusNetworkAnnotationPool.isEmpty() {
Expand Down

0 comments on commit d1638ca

Please sign in to comment.