@@ -31,8 +31,10 @@ import (
31
31
"k8s.io/klog/v2"
32
32
"k8s.io/utils/pointer"
33
33
"sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader"
34
+ azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
34
35
azure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
35
36
providerconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
37
+ "sigs.k8s.io/cloud-provider-azure/pkg/retry"
36
38
)
37
39
38
40
var (
@@ -181,9 +183,10 @@ func (d *Driver) getKeyvaultToken() (authorizer autorest.Authorizer, err error)
181
183
return authorizer , nil
182
184
}
183
185
184
- func (d * Driver ) updateSubnetServiceEndpoints (ctx context.Context , vnetResourceGroup , vnetName , subnetName string ) error {
186
+ func (d * Driver ) updateSubnetServiceEndpoints (ctx context.Context , vnetResourceGroup , vnetName , subnetName string ) ([]string , error ) {
187
+ var vnetResourceIDs []string
185
188
if d .cloud .SubnetsClient == nil {
186
- return fmt .Errorf ("SubnetsClient is nil" )
189
+ return vnetResourceIDs , fmt .Errorf ("SubnetsClient is nil" )
187
190
}
188
191
189
192
if vnetResourceGroup == "" {
@@ -197,56 +200,89 @@ func (d *Driver) updateSubnetServiceEndpoints(ctx context.Context, vnetResourceG
197
200
if vnetName == "" {
198
201
vnetName = d .cloud .VnetName
199
202
}
200
- if subnetName == "" {
201
- subnetName = d .cloud .SubnetName
202
- }
203
203
204
204
klog .V (2 ).Infof ("updateSubnetServiceEndpoints on vnetName: %s, subnetName: %s, location: %s" , vnetName , subnetName , location )
205
- if subnetName == "" || vnetName == "" || location == "" {
206
- return fmt .Errorf ("value of subnetName, vnetName or location is empty" )
205
+ if vnetName == "" || location == "" {
206
+ return vnetResourceIDs , fmt .Errorf ("vnetName or location is empty" )
207
207
}
208
208
209
209
lockKey := vnetResourceGroup + vnetName + subnetName
210
- d .subnetLockMap .LockEntry (lockKey )
211
- defer d .subnetLockMap .UnlockEntry (lockKey )
212
-
213
- subnet , err := d .cloud .SubnetsClient .Get (ctx , vnetResourceGroup , vnetName , subnetName , "" )
210
+ cache , err := d .subnetCache .Get (lockKey , azcache .CacheReadTypeDefault )
214
211
if err != nil {
215
- return fmt .Errorf ("failed to get the subnet %s under vnet %s: %v" , subnetName , vnetName , err )
216
- }
217
- endpointLocaions := []string {location }
218
- storageServiceEndpoint := network.ServiceEndpointPropertiesFormat {
219
- Service : & storageService ,
220
- Locations : & endpointLocaions ,
221
- }
222
- storageServiceExists := false
223
- if subnet .SubnetPropertiesFormat == nil {
224
- subnet .SubnetPropertiesFormat = & network.SubnetPropertiesFormat {}
212
+ return nil , err
225
213
}
226
- if subnet .SubnetPropertiesFormat .ServiceEndpoints == nil {
227
- subnet .SubnetPropertiesFormat .ServiceEndpoints = & []network.ServiceEndpointPropertiesFormat {}
214
+ if cache != nil {
215
+ vnetResourceIDs = cache .([]string )
216
+ klog .V (2 ).Infof ("subnet %s under vnet %s in rg %s is already updated, vnetResourceIDs: %v" , subnetName , vnetName , vnetResourceGroup , vnetResourceIDs )
217
+ return vnetResourceIDs , nil
228
218
}
229
- serviceEndpoints := * subnet .SubnetPropertiesFormat .ServiceEndpoints
230
- for _ , v := range serviceEndpoints {
231
- if strings .HasPrefix (pointer .StringDeref (v .Service , "" ), storageService ) {
232
- storageServiceExists = true
233
- klog .V (4 ).Infof ("serviceEndpoint(%s) is already in subnet(%s)" , storageService , subnetName )
234
- break
219
+
220
+ d .subnetLockMap .LockEntry (lockKey )
221
+ defer d .subnetLockMap .UnlockEntry (lockKey )
222
+
223
+ var subnets []network.Subnet
224
+ if subnetName != "" {
225
+ // list multiple subnets separated by comma
226
+ subnetNames := strings .Split (subnetName , "," )
227
+ for _ , sn := range subnetNames {
228
+ sn = strings .TrimSpace (sn )
229
+ subnet , rerr := d .cloud .SubnetsClient .Get (ctx , vnetResourceGroup , vnetName , sn , "" )
230
+ if rerr != nil {
231
+ return vnetResourceIDs , fmt .Errorf ("failed to get the subnet %s under rg %s vnet %s: %v" , subnetName , vnetResourceGroup , vnetName , rerr .Error ())
232
+ }
233
+ subnets = append (subnets , subnet )
234
+ }
235
+ } else {
236
+ var rerr * retry.Error
237
+ subnets , rerr = d .cloud .SubnetsClient .List (ctx , vnetResourceGroup , vnetName )
238
+ if rerr != nil {
239
+ return vnetResourceIDs , fmt .Errorf ("failed to list the subnets under rg %s vnet %s: %v" , vnetResourceGroup , vnetName , rerr .Error ())
235
240
}
236
241
}
237
242
238
- if ! storageServiceExists {
239
- serviceEndpoints = append (serviceEndpoints , storageServiceEndpoint )
240
- subnet .SubnetPropertiesFormat .ServiceEndpoints = & serviceEndpoints
243
+ for _ , subnet := range subnets {
244
+ if subnet .Name == nil {
245
+ return vnetResourceIDs , fmt .Errorf ("subnet name is nil" )
246
+ }
247
+ sn := * subnet .Name
248
+ vnetResourceID := d .getSubnetResourceID (vnetResourceGroup , vnetName , sn )
249
+ klog .V (2 ).Infof ("set vnetResourceID %s" , vnetResourceID )
250
+ vnetResourceIDs = append (vnetResourceIDs , vnetResourceID )
251
+
252
+ endpointLocaions := []string {location }
253
+ storageServiceEndpoint := network.ServiceEndpointPropertiesFormat {
254
+ Service : & storageService ,
255
+ Locations : & endpointLocaions ,
256
+ }
257
+ storageServiceExists := false
258
+ if subnet .SubnetPropertiesFormat == nil {
259
+ subnet .SubnetPropertiesFormat = & network.SubnetPropertiesFormat {}
260
+ }
261
+ if subnet .SubnetPropertiesFormat .ServiceEndpoints == nil {
262
+ subnet .SubnetPropertiesFormat .ServiceEndpoints = & []network.ServiceEndpointPropertiesFormat {}
263
+ }
264
+ serviceEndpoints := * subnet .SubnetPropertiesFormat .ServiceEndpoints
265
+ for _ , v := range serviceEndpoints {
266
+ if strings .HasPrefix (pointer .StringDeref (v .Service , "" ), storageService ) {
267
+ storageServiceExists = true
268
+ klog .V (4 ).Infof ("serviceEndpoint(%s) is already in subnet(%s)" , storageService , sn )
269
+ break
270
+ }
271
+ }
272
+
273
+ if ! storageServiceExists {
274
+ serviceEndpoints = append (serviceEndpoints , storageServiceEndpoint )
275
+ subnet .SubnetPropertiesFormat .ServiceEndpoints = & serviceEndpoints
241
276
242
- klog .V (2 ).Infof ("begin to update the subnet %s under vnet %s rg %s" , subnetName , vnetName , vnetResourceGroup )
243
- if err := d .cloud .SubnetsClient .CreateOrUpdate (ctx , vnetResourceGroup , vnetName , subnetName , subnet ); err != nil {
244
- return fmt .Errorf ("failed to update the subnet %s under vnet %s: %v" , subnetName , vnetName , err )
277
+ klog .V (2 ).Infof ("begin to update the subnet %s under vnet %s in rg %s" , sn , vnetName , vnetResourceGroup )
278
+ if err := d .cloud .SubnetsClient .CreateOrUpdate (ctx , vnetResourceGroup , vnetName , sn , subnet ); err != nil {
279
+ return vnetResourceIDs , fmt .Errorf ("failed to update the subnet %s under vnet %s: %v" , sn , vnetName , err )
280
+ }
245
281
}
246
- klog .V (2 ).Infof ("serviceEndpoint(%s) is appended in subnet(%s)" , storageService , subnetName )
247
282
}
248
-
249
- return nil
283
+ // cache the subnet update
284
+ d .subnetCache .Set (lockKey , vnetResourceIDs )
285
+ return vnetResourceIDs , nil
250
286
}
251
287
252
288
func (d * Driver ) getStorageEndPointSuffix () string {
0 commit comments