@@ -61,6 +61,13 @@ type vmssMetaInfo struct {
61
61
resourceGroup string
62
62
}
63
63
64
+ // nodeIdentity identifies a node within a subscription.
65
+ type nodeIdentity struct {
66
+ resourceGroup string
67
+ vmssName string
68
+ nodeName string
69
+ }
70
+
64
71
// scaleSet implements VMSet interface for Azure scale set.
65
72
type scaleSet struct {
66
73
* Cloud
@@ -70,7 +77,7 @@ type scaleSet struct {
70
77
availabilitySet VMSet
71
78
72
79
vmssCache * azcache.TimedCache
73
- vmssVMCache * azcache.TimedCache
80
+ vmssVMCache * sync. Map // [resourcegroup/vmssname]* azcache.TimedCache
74
81
availabilitySetNodesCache * azcache.TimedCache
75
82
}
76
83
@@ -80,6 +87,7 @@ func newScaleSet(az *Cloud) (VMSet, error) {
80
87
ss := & scaleSet {
81
88
Cloud : az ,
82
89
availabilitySet : newAvailabilitySet (az ),
90
+ vmssVMCache : & sync.Map {},
83
91
}
84
92
85
93
if ! ss .DisableAvailabilitySetNodes {
@@ -94,11 +102,6 @@ func newScaleSet(az *Cloud) (VMSet, error) {
94
102
return nil , err
95
103
}
96
104
97
- ss .vmssVMCache , err = ss .newVMSSVirtualMachinesCache ()
98
- if err != nil {
99
- return nil , err
100
- }
101
-
102
105
return ss , nil
103
106
}
104
107
@@ -139,12 +142,17 @@ func (ss *scaleSet) getVMSS(vmssName string, crt azcache.AzureCacheReadType) (*c
139
142
return vmss , nil
140
143
}
141
144
142
- // getVmssVM gets virtualMachineScaleSetVM by nodeName from cache.
143
- // It returns cloudprovider.InstanceNotFound if node does not belong to any scale sets.
144
- func (ss * scaleSet ) getVmssVM (nodeName string , crt azcache.AzureCacheReadType ) (string , string , * compute.VirtualMachineScaleSetVM , error ) {
145
+ // getVmssVMByNodeIdentity find virtualMachineScaleSetVM by nodeIdentity, using node's parent VMSS cache.
146
+ // Returns cloudprovider.InstanceNotFound if the node does not belong to the scale set named in nodeIdentity.
147
+ func (ss * scaleSet ) getVmssVMByNodeIdentity (node * nodeIdentity , crt azcache.AzureCacheReadType ) (string , string , * compute.VirtualMachineScaleSetVM , error ) {
148
+ cacheKey , cache , err := ss .getVMSSVMCache (node .resourceGroup , node .vmssName )
149
+ if err != nil {
150
+ return "" , "" , nil , err
151
+ }
152
+
145
153
getter := func (nodeName string , crt azcache.AzureCacheReadType ) (string , string , * compute.VirtualMachineScaleSetVM , bool , error ) {
146
154
var found bool
147
- cached , err := ss . vmssVMCache . Get (vmssVirtualMachinesKey , crt )
155
+ cached , err := cache . Get (cacheKey , crt )
148
156
if err != nil {
149
157
return "" , "" , nil , found , err
150
158
}
@@ -159,19 +167,19 @@ func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) (
159
167
return "" , "" , nil , found , nil
160
168
}
161
169
162
- _ , err : = getScaleSetVMInstanceID (nodeName )
170
+ _ , err = getScaleSetVMInstanceID (node . nodeName )
163
171
if err != nil {
164
172
return "" , "" , nil , err
165
173
}
166
174
167
- vmssName , instanceID , vm , found , err := getter (nodeName , crt )
175
+ vmssName , instanceID , vm , found , err := getter (node . nodeName , crt )
168
176
if err != nil {
169
177
return "" , "" , nil , err
170
178
}
171
179
172
180
if ! found {
173
- klog .V (2 ).Infof ("Couldn't find VMSS VM with nodeName %s, refreshing the cache" , nodeName )
174
- vmssName , instanceID , vm , found , err = getter (nodeName , azcache .CacheReadTypeForceRefresh )
181
+ klog .V (2 ).Infof ("Couldn't find VMSS VM with nodeName %s, refreshing the cache" , node . nodeName )
182
+ vmssName , instanceID , vm , found , err = getter (node . nodeName , azcache .CacheReadTypeForceRefresh )
175
183
if err != nil {
176
184
return "" , "" , nil , err
177
185
}
@@ -187,6 +195,17 @@ func (ss *scaleSet) getVmssVM(nodeName string, crt azcache.AzureCacheReadType) (
187
195
return vmssName , instanceID , vm , nil
188
196
}
189
197
198
+ // getVmssVM gets virtualMachineScaleSetVM by nodeName from cache.
199
+ // Returns cloudprovider.InstanceNotFound if nodeName does not belong to any scale set.
200
+ func (ss * scaleSet ) getVmssVM (nodeName string , crt azcache.AzureCacheReadType ) (string , string , * compute.VirtualMachineScaleSetVM , error ) {
201
+ node , err := ss .getNodeIdentityByNodeName (nodeName , crt )
202
+ if err != nil {
203
+ return "" , "" , nil , err
204
+ }
205
+
206
+ return ss .getVmssVMByNodeIdentity (node , crt )
207
+ }
208
+
190
209
// GetPowerStatusByNodeName returns the power state of the specified node.
191
210
func (ss * scaleSet ) GetPowerStatusByNodeName (name string ) (powerState string , err error ) {
192
211
managedByAS , err := ss .isNodeManagedByAvailabilitySet (name , azcache .CacheReadTypeUnsafe )
@@ -222,8 +241,13 @@ func (ss *scaleSet) GetPowerStatusByNodeName(name string) (powerState string, er
222
241
// getCachedVirtualMachineByInstanceID gets scaleSetVMInfo from cache.
223
242
// The node must belong to one of scale sets.
224
243
func (ss * scaleSet ) getVmssVMByInstanceID (resourceGroup , scaleSetName , instanceID string , crt azcache.AzureCacheReadType ) (* compute.VirtualMachineScaleSetVM , error ) {
244
+ cacheKey , cache , err := ss .getVMSSVMCache (resourceGroup , scaleSetName )
245
+ if err != nil {
246
+ return nil , err
247
+ }
248
+
225
249
getter := func (crt azcache.AzureCacheReadType ) (vm * compute.VirtualMachineScaleSetVM , found bool , err error ) {
226
- cached , err := ss . vmssVMCache . Get (vmssVirtualMachinesKey , crt )
250
+ cached , err := cache . Get (cacheKey , crt )
227
251
if err != nil {
228
252
return nil , false , err
229
253
}
@@ -590,6 +614,66 @@ func (ss *scaleSet) listScaleSets(resourceGroup string) ([]string, error) {
590
614
return ssNames , nil
591
615
}
592
616
617
+ // getNodeIdentityByNodeName use the VMSS cache to find a node's resourcegroup and vmss, returned in a nodeIdentity.
618
+ func (ss * scaleSet ) getNodeIdentityByNodeName (nodeName string , crt azcache.AzureCacheReadType ) (* nodeIdentity , error ) {
619
+ getter := func (nodeName string , crt azcache.AzureCacheReadType ) (* nodeIdentity , error ) {
620
+ node := & nodeIdentity {
621
+ nodeName : nodeName ,
622
+ }
623
+
624
+ cached , err := ss .vmssCache .Get (vmssKey , crt )
625
+ if err != nil {
626
+ return nil , err
627
+ }
628
+
629
+ vmsses := cached .(* sync.Map )
630
+ vmsses .Range (func (key , value interface {}) bool {
631
+ v := value .(* vmssEntry )
632
+ if v .vmss .Name == nil {
633
+ return true
634
+ }
635
+
636
+ vmssPrefix := * v .vmss .Name
637
+ if v .vmss .VirtualMachineProfile != nil &&
638
+ v .vmss .VirtualMachineProfile .OsProfile != nil &&
639
+ v .vmss .VirtualMachineProfile .OsProfile .ComputerNamePrefix != nil {
640
+ vmssPrefix = * v .vmss .VirtualMachineProfile .OsProfile .ComputerNamePrefix
641
+ }
642
+
643
+ if strings .EqualFold (vmssPrefix , nodeName [:len (nodeName )- 6 ]) {
644
+ node .vmssName = * v .vmss .Name
645
+ node .resourceGroup = v .resourceGroup
646
+ return false
647
+ }
648
+
649
+ return true
650
+ })
651
+ return node , nil
652
+ }
653
+
654
+ if _ , err := getScaleSetVMInstanceID (nodeName ); err != nil {
655
+ return nil , err
656
+ }
657
+
658
+ node , err := getter (nodeName , crt )
659
+ if err != nil {
660
+ return nil , err
661
+ }
662
+ if node .vmssName != "" {
663
+ return node , nil
664
+ }
665
+
666
+ klog .V (2 ).Infof ("Couldn't find VMSS for node %s, refreshing the cache" , nodeName )
667
+ node , err = getter (nodeName , azcache .CacheReadTypeForceRefresh )
668
+ if err != nil {
669
+ return nil , err
670
+ }
671
+ if node .vmssName == "" {
672
+ return nil , cloudprovider .InstanceNotFound
673
+ }
674
+ return node , nil
675
+ }
676
+
593
677
// listScaleSetVMs lists VMs belonging to the specified scale set.
594
678
func (ss * scaleSet ) listScaleSetVMs (scaleSetName , resourceGroup string ) ([]compute.VirtualMachineScaleSetVM , error ) {
595
679
ctx , cancel := getContextWithCancel ()
0 commit comments