Skip to content

Commit 37201f6

Browse files
authored
Merge pull request #381 from orenc1/fix_getNodeAddresses
Fix dual-stack IP support in getNodeAddresses
2 parents 82caab5 + f9eeb4d commit 37201f6

File tree

2 files changed

+101
-18
lines changed

2 files changed

+101
-18
lines changed

pkg/provider/instances_v2.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,22 @@ func (i *instancesV2) getNodeAddresses(ifs []kubevirtv1.VirtualMachineInstanceNe
136136
var addrs []corev1.NodeAddress
137137

138138
foundInternalIP := false
139-
// TODO: detect type of all addresses, right now pick only the default
140-
for _, i := range ifs {
141-
// Only change the IP if it is known, not if it is empty
142-
if i.Name == "default" && i.IP != "" {
143-
v1helper.AddToNodeAddresses(&addrs, corev1.NodeAddress{
144-
Type: corev1.NodeInternalIP,
145-
Address: i.IP,
146-
})
147-
foundInternalIP = true
148-
break
139+
// Find the default interface and add all its IP addresses (supports dual-stack)
140+
for _, iface := range ifs {
141+
if iface.Name != "default" {
142+
continue
143+
}
144+
145+
for _, ip := range iface.IPs {
146+
if ip != "" {
147+
v1helper.AddToNodeAddresses(&addrs, corev1.NodeAddress{
148+
Type: corev1.NodeInternalIP,
149+
Address: ip,
150+
})
151+
foundInternalIP = true
152+
}
149153
}
154+
break
150155
}
151156

152157
// fall back to the previously known internal IP on the node

pkg/provider/instances_v2_test.go

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ var _ = Describe("Instances V2", func() {
238238
Interfaces: []kubevirtv1.VirtualMachineInstanceNetworkInterface{
239239
{
240240
IP: "10.244.0.1",
241+
IPs: []string{"10.244.0.1"},
241242
Name: "default",
242243
},
243244
{
@@ -298,6 +299,90 @@ var _ = Describe("Instances V2", func() {
298299
}))
299300
})
300301

302+
It("Should return dual-stack IPs when VMI has both IPv4 and IPv6 addresses", func() {
303+
vmiName := "test-vm-dualstack"
304+
namespace := "cluster-qwedas"
305+
i := instancesV2{
306+
namespace: namespace,
307+
client: mockClient,
308+
config: &InstancesV2Config{
309+
Enabled: true,
310+
ZoneAndRegionEnabled: true,
311+
},
312+
}
313+
314+
infraNode := corev1.Node{
315+
ObjectMeta: metav1.ObjectMeta{
316+
Name: "infra-node",
317+
Labels: map[string]string{
318+
corev1.LabelTopologyRegion: "region-a",
319+
corev1.LabelTopologyZone: "zone-1",
320+
},
321+
},
322+
}
323+
324+
vmi := kubevirtv1.VirtualMachineInstance{
325+
ObjectMeta: metav1.ObjectMeta{
326+
Name: vmiName,
327+
Namespace: namespace,
328+
Annotations: map[string]string{
329+
kubevirtv1.InstancetypeAnnotation: "highPerformance",
330+
},
331+
},
332+
Status: kubevirtv1.VirtualMachineInstanceStatus{
333+
Interfaces: []kubevirtv1.VirtualMachineInstanceNetworkInterface{
334+
{
335+
IP: "10.129.0.209",
336+
IPs: []string{"10.129.0.209", "fd02:0:0:2::13c2"},
337+
Name: "default",
338+
},
339+
},
340+
NodeName: infraNode.Name,
341+
},
342+
}
343+
344+
tenantNode := corev1.Node{
345+
ObjectMeta: metav1.ObjectMeta{
346+
Name: vmiName,
347+
},
348+
}
349+
350+
gomock.InOrder(
351+
mockClient.EXPECT().
352+
Get(ctx, types.NamespacedName{Name: vmiName, Namespace: namespace}, gomock.AssignableToTypeOf(&kubevirtv1.VirtualMachineInstance{})).
353+
SetArg(2, vmi).
354+
Times(1),
355+
mockClient.EXPECT().
356+
Get(ctx, client.ObjectKey{Name: infraNode.Name}, gomock.AssignableToTypeOf(&corev1.Node{})).
357+
SetArg(2, infraNode).
358+
Times(1),
359+
)
360+
361+
metadata, err := i.InstanceMetadata(ctx, &tenantNode)
362+
Expect(err).To(BeNil())
363+
364+
idFn := func(index int, element interface{}) string {
365+
return strconv.Itoa(index)
366+
}
367+
Expect(*metadata).To(MatchAllFields(Fields{
368+
"ProviderID": Equal("kubevirt://test-vm-dualstack"),
369+
"NodeAddresses": MatchAllElementsWithIndex(idFn, Elements{
370+
"0": MatchAllFields(Fields{
371+
"Address": Equal("10.129.0.209"),
372+
"Type": Equal(corev1.NodeInternalIP),
373+
}),
374+
"1": MatchAllFields(Fields{
375+
"Address": Equal("fd02:0:0:2::13c2"),
376+
"Type": Equal(corev1.NodeInternalIP),
377+
}),
378+
}),
379+
"InstanceType": Equal("highPerformance"),
380+
"Region": Equal("region-a"),
381+
"Zone": Equal("zone-1"),
382+
"AdditionalLabels": BeEmpty(),
383+
}))
384+
})
385+
301386
It("Should fetch a vmi by node name and return a complete metadata object - zone and region disabled", func() {
302387
vmiName := "test-vm"
303388
namespace := "cluster-qwedas"
@@ -331,16 +416,9 @@ var _ = Describe("Instances V2", func() {
331416
Status: kubevirtv1.VirtualMachineInstanceStatus{
332417
Interfaces: []kubevirtv1.VirtualMachineInstanceNetworkInterface{
333418
{
334-
IP: "10.244.0.1",
419+
IPs: []string{"10.244.0.1"},
335420
Name: "default",
336421
},
337-
{
338-
IP: "10.245.0.1",
339-
Name: "unknown",
340-
},
341-
{
342-
IP: "10.246.0.1",
343-
},
344422
},
345423
NodeName: infraNode.Name,
346424
},

0 commit comments

Comments
 (0)