Skip to content

Commit 8c9c60b

Browse files
authored
Revert "Revert "🐛 Cache the NSX LogicalSwitchUUID to DPVG lookups""
1 parent d594d0b commit 8c9c60b

File tree

1 file changed

+58
-18
lines changed
  • pkg/providers/vsphere/network

1 file changed

+58
-18
lines changed

pkg/providers/vsphere/network/nsxt.go

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ package network
77
import (
88
"context"
99
"fmt"
10+
"sync"
11+
"time"
12+
13+
ctrl "sigs.k8s.io/controller-runtime"
1014

1115
"github.com/vmware/govmomi/object"
1216
"github.com/vmware/govmomi/property"
@@ -55,15 +59,60 @@ func (n nsxOpaqueBacking) Summary(_ context.Context) (*vimtypes.OpaqueNetworkSum
5559
}, nil
5660
}
5761

58-
// searchNsxtNetworkReference takes in NSX-T LogicalSwitchUUID and returns the reference of the network.
62+
var (
63+
// uuidToDVPGCache contains the cache used look up the CCR's DPVG for a
64+
// given LogicalSwitchUUID.
65+
uuidToDVPGCache sync.Map
66+
67+
clearUUIDToDVPGCache sync.Once
68+
)
69+
5970
func searchNsxtNetworkReference(
6071
ctx context.Context,
6172
ccr *object.ClusterComputeResource,
6273
networkID string) (object.NetworkReference, error) {
6374

64-
// This is more or less how the old code did it. We could save repeated work by moving this
65-
// into the callers since it will always be for the same CCR, but the common case is one NIC,
66-
// or at most a handful, so that's for later.
75+
clearUUIDToDVPGCache.Do(func() {
76+
// Start goroutine to periodically clear the cache.
77+
go func() {
78+
logger := ctrl.Log.WithName("nsx-dvpg-cache-clearer")
79+
ticker := time.NewTicker(time.Minute * 60)
80+
for range ticker.C {
81+
logger.Info("Clearing NSX LogicalSwitchUUID to DVPG cache")
82+
uuidToDVPGCache.Clear()
83+
}
84+
}()
85+
})
86+
87+
key := ccr.Reference().Value
88+
89+
if c, ok := uuidToDVPGCache.Load(key); ok {
90+
cc := c.(map[string]vimtypes.ManagedObjectReference)
91+
if dvpg, ok := cc[networkID]; ok {
92+
return object.NewDistributedVirtualPortgroup(ccr.Client(), dvpg), nil
93+
}
94+
}
95+
96+
// On either miss - CCR or UUID not found - try to refresh the DVPGs for the CCR,
97+
// and always store the latest results in the cache. We could CompareAndSwap()
98+
// instead but let's have the latest win.
99+
uuidsToDPVG, err := getDVPGsForCCR(ctx, ccr)
100+
if err != nil {
101+
return nil, err
102+
}
103+
uuidToDVPGCache.Store(key, uuidsToDPVG)
104+
105+
if dvpg, ok := uuidsToDPVG[networkID]; ok {
106+
return object.NewDistributedVirtualPortgroup(ccr.Client(), dvpg), nil
107+
}
108+
109+
return nil, fmt.Errorf("no DVPG with NSX network ID %q found", networkID)
110+
}
111+
112+
func getDVPGsForCCR(
113+
ctx context.Context,
114+
ccr *object.ClusterComputeResource) (map[string]vimtypes.ManagedObjectReference, error) {
115+
67116
var obj mo.ClusterComputeResource
68117
if err := ccr.Properties(ctx, ccr.Reference(), []string{"network"}, &obj); err != nil {
69118
return nil, err
@@ -77,7 +126,7 @@ func searchNsxtNetworkReference(
77126
}
78127

79128
if len(dvpgsMoRefs) == 0 {
80-
return nil, fmt.Errorf("ClusterComputeResource %s has no DVPGs", ccr.Reference().Value)
129+
return nil, nil
81130
}
82131

83132
var dvpgs []mo.DistributedVirtualPortgroup
@@ -86,21 +135,12 @@ func searchNsxtNetworkReference(
86135
return nil, err
87136
}
88137

89-
var dvpgMoRefs []vimtypes.ManagedObjectReference
138+
uuidToDPVG := make(map[string]vimtypes.ManagedObjectReference, len(dvpgs))
90139
for _, dvpg := range dvpgs {
91-
if dvpg.Config.LogicalSwitchUuid == networkID {
92-
dvpgMoRefs = append(dvpgMoRefs, dvpg.Reference())
140+
if uuid := dvpg.Config.LogicalSwitchUuid; uuid != "" {
141+
uuidToDPVG[uuid] = dvpg.Reference()
93142
}
94143
}
95144

96-
switch len(dvpgMoRefs) {
97-
case 1:
98-
return object.NewDistributedVirtualPortgroup(ccr.Client(), dvpgMoRefs[0]), nil
99-
case 0:
100-
return nil, fmt.Errorf("no DVPG with NSX network ID %q found", networkID)
101-
default:
102-
// The LogicalSwitchUuid is supposed to be unique per CCR, so this is likely an NCP
103-
// misconfiguration, and we don't know which one to pick.
104-
return nil, fmt.Errorf("multiple DVPGs (%d) with NSX network ID %q found", len(dvpgMoRefs), networkID)
105-
}
145+
return uuidToDPVG, nil
106146
}

0 commit comments

Comments
 (0)