Skip to content

Commit d289163

Browse files
Skip updating node status address if already set (#195)
If node status addresses field has already been set, we want to skip updating it again. This is to work around sporadic API issues that don't guarantee in the ordering between learned IPs based on source i.e DHCP assigned IP priority before loadbalancer ARP-ed IP. --------- Co-authored-by: Daniel Lipovetsky <daniel.lipovetsky@nutanix.com>
1 parent 514c3e8 commit d289163

File tree

2 files changed

+110
-3
lines changed

2 files changed

+110
-3
lines changed

pkg/provider/manager.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,12 @@ func (n *nutanixManager) getInstanceMetadata(ctx context.Context, node *v1.Node)
132132
}
133133

134134
klog.V(1).Infof("fetching nodeAddresses for node %s", nodeName)
135-
nodeAddresses, err := n.getNodeAddresses(ctx, vm)
136-
if err != nil {
137-
return nil, err
135+
nodeAddresses := node.Status.Addresses
136+
if !n.isNodeAddressesSet(node) {
137+
nodeAddresses, err = n.getNodeAddresses(ctx, vm)
138+
if err != nil {
139+
return nil, err
140+
}
138141
}
139142

140143
topologyInfo, err := n.getTopologyInfo(ctx, nClient, vm)
@@ -297,6 +300,27 @@ func (n *nutanixManager) generateProviderID(ctx context.Context, vmUUID string)
297300
return fmt.Sprintf("%s://%s", constants.ProviderName, strings.ToLower(vmUUID)), nil
298301
}
299302

303+
func (n *nutanixManager) isNodeAddressesSet(node *v1.Node) bool {
304+
if node == nil {
305+
return false
306+
}
307+
308+
var hasHostname, hasInternalIP bool
309+
for _, address := range node.Status.Addresses {
310+
if address.Type == v1.NodeHostName {
311+
hasHostname = true
312+
}
313+
314+
if address.Type == v1.NodeInternalIP {
315+
hasInternalIP = true
316+
}
317+
}
318+
319+
// We always set at least two address types: one internal IP and one hostname.
320+
// If either type is not found, then we have not set the node addresses.
321+
return hasHostname && hasInternalIP
322+
}
323+
300324
func (n *nutanixManager) getNodeAddresses(_ context.Context, vm *prismclientv3.VMIntentResponse) ([]v1.NodeAddress, error) {
301325
if vm == nil {
302326
return nil, fmt.Errorf("vm cannot be nil when getting node addresses")

pkg/provider/manager_unit_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package provider
2+
3+
import (
4+
"testing"
5+
6+
v1 "k8s.io/api/core/v1"
7+
)
8+
9+
func TestIsNodeAddressesSet(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
node *v1.Node
13+
want bool
14+
}{
15+
{
16+
name: "found an internalIP and a hostname",
17+
node: &v1.Node{
18+
Status: v1.NodeStatus{
19+
Addresses: []v1.NodeAddress{
20+
{
21+
Type: v1.NodeHostName,
22+
Address: "example.com",
23+
},
24+
{
25+
Type: v1.NodeInternalIP,
26+
Address: "1.2.3.4",
27+
},
28+
},
29+
},
30+
},
31+
want: true,
32+
},
33+
{
34+
name: "found only internalIPs",
35+
node: &v1.Node{
36+
Status: v1.NodeStatus{
37+
Addresses: []v1.NodeAddress{
38+
{
39+
Type: v1.NodeInternalIP,
40+
Address: "1.2.3.4",
41+
},
42+
{
43+
Type: v1.NodeInternalIP,
44+
Address: "5.6.7.8",
45+
},
46+
},
47+
},
48+
},
49+
want: false,
50+
},
51+
{
52+
name: "found only a hostname",
53+
node: &v1.Node{
54+
Status: v1.NodeStatus{
55+
Addresses: []v1.NodeAddress{
56+
{
57+
Type: v1.NodeHostName,
58+
Address: "example.com",
59+
},
60+
},
61+
},
62+
},
63+
want: false,
64+
},
65+
{
66+
name: "found no addresses",
67+
node: &v1.Node{
68+
Status: v1.NodeStatus{
69+
Addresses: []v1.NodeAddress{},
70+
},
71+
},
72+
want: false,
73+
},
74+
}
75+
for _, tt := range tests {
76+
t.Run(tt.name, func(t *testing.T) {
77+
n := &nutanixManager{}
78+
if got := n.isNodeAddressesSet(tt.node); got != tt.want {
79+
t.Errorf("nutanixManager.isNodeAddressesSet() = %v, want %v", got, tt.want)
80+
}
81+
})
82+
}
83+
}

0 commit comments

Comments
 (0)