Skip to content

Commit 40f0567

Browse files
committed
azure: Track resources by ID during deletion
1 parent 93d0bed commit 40f0567

File tree

2 files changed

+109
-108
lines changed

2 files changed

+109
-108
lines changed

pkg/resources/azure/azure.go

Lines changed: 63 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
2324
authz "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3"
2425
compute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
2526
network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
@@ -138,7 +139,7 @@ func (g *resourceGetter) toResourceGroupResource(rg *azureresources.ResourceGrou
138139
return &resources.Resource{
139140
Obj: rg,
140141
Type: typeResourceGroup,
141-
ID: *rg.Name,
142+
ID: *rg.ID,
142143
Name: *rg.Name,
143144
Deleter: g.deleteResourceGroup,
144145
Shared: g.clusterInfo.AzureResourceGroupShared,
@@ -166,7 +167,7 @@ func (g *resourceGetter) listVirtualNetworksAndSubnets(ctx context.Context) ([]*
166167
}
167168
rs = append(rs, r)
168169
// Add all subnets belonging to the virtual network.
169-
subnets, err := g.listSubnets(ctx, *vnet.Name)
170+
subnets, err := g.listSubnets(ctx, *vnet.ID)
170171
if err != nil {
171172
return nil, err
172173
}
@@ -177,19 +178,15 @@ func (g *resourceGetter) listVirtualNetworksAndSubnets(ctx context.Context) ([]*
177178

178179
func (g *resourceGetter) toVirtualNetworkResource(vnet *network.VirtualNetwork) (*resources.Resource, error) {
179180
var blocks []string
180-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
181+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
181182

182183
nsgs := set.New[string]()
183184
if vnet.Properties != nil && vnet.Properties.Subnets != nil {
184185
for _, sn := range vnet.Properties.Subnets {
185186
if sn.Properties == nil || sn.Properties.NetworkSecurityGroup == nil || sn.Properties.NetworkSecurityGroup.ID == nil {
186187
continue
187188
}
188-
nsgID, err := azure.ParseNetworkSecurityGroupID(*sn.Properties.NetworkSecurityGroup.ID)
189-
if err != nil {
190-
return nil, fmt.Errorf("parsing network security group ID: %s", err)
191-
}
192-
nsgs.Insert(nsgID.NetworkSecurityGroupName)
189+
nsgs.Insert(*sn.Properties.NetworkSecurityGroup.ID)
193190
}
194191
}
195192
for nsg := range nsgs {
@@ -199,7 +196,7 @@ func (g *resourceGetter) toVirtualNetworkResource(vnet *network.VirtualNetwork)
199196
return &resources.Resource{
200197
Obj: vnet,
201198
Type: typeVirtualNetwork,
202-
ID: *vnet.Name,
199+
ID: *vnet.ID,
203200
Name: *vnet.Name,
204201
Deleter: g.deleteVirtualNetwork,
205202
Blocks: blocks,
@@ -211,35 +208,44 @@ func (g *resourceGetter) deleteVirtualNetwork(_ fi.Cloud, r *resources.Resource)
211208
return g.cloud.VirtualNetwork().Delete(context.TODO(), g.resourceGroupName(), r.Name)
212209
}
213210

214-
func (g *resourceGetter) listSubnets(ctx context.Context, vnetName string) ([]*resources.Resource, error) {
215-
subnets, err := g.cloud.Subnet().List(ctx, g.resourceGroupName(), vnetName)
211+
func (g *resourceGetter) listSubnets(ctx context.Context, vnetID string) ([]*resources.Resource, error) {
212+
vnet, err := arm.ParseResourceID(vnetID)
213+
if err != nil {
214+
return nil, err
215+
}
216+
subnets, err := g.cloud.Subnet().List(ctx, g.resourceGroupName(), vnet.Name)
216217
if err != nil {
217218
return nil, err
218219
}
219220

220221
var rs []*resources.Resource
221222
for _, sn := range subnets {
222-
rs = append(rs, g.toSubnetResource(sn, vnetName))
223+
rs = append(rs, g.toSubnetResource(sn, vnetID))
223224
}
224225
return rs, nil
225226
}
226227

227-
func (g *resourceGetter) toSubnetResource(subnet *network.Subnet, vnetName string) *resources.Resource {
228+
func (g *resourceGetter) toSubnetResource(subnet *network.Subnet, vnetID string) *resources.Resource {
228229
var blocks []string
229-
blocks = append(blocks, toKey(typeVirtualNetwork, vnetName))
230-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
230+
blocks = append(blocks, toKey(typeVirtualNetwork, vnetID))
231+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
231232

232233
if subnet.Properties != nil && subnet.Properties.NatGateway != nil && subnet.Properties.NatGateway.ID != nil {
233234
blocks = append(blocks, toKey(typeNatGateway, *subnet.Properties.NatGateway.ID))
234235
}
235236

237+
vnet, err := arm.ParseResourceID(vnetID)
238+
if err != nil {
239+
return nil
240+
}
241+
236242
return &resources.Resource{
237243
Obj: subnet,
238244
Type: typeSubnet,
239-
ID: *subnet.Name,
245+
ID: *subnet.ID,
240246
Name: *subnet.Name,
241247
Deleter: func(_ fi.Cloud, r *resources.Resource) error {
242-
return g.deleteSubnet(vnetName, r)
248+
return g.deleteSubnet(vnet.Name, r)
243249
},
244250
Blocks: blocks,
245251
Shared: g.clusterInfo.AzureNetworkShared,
@@ -269,27 +275,19 @@ func (g *resourceGetter) listNetworkSecurityGroups(ctx context.Context) ([]*reso
269275

270276
func (g *resourceGetter) toNetworkSecurityGroupResource(NetworkSecurityGroup *network.SecurityGroup) (*resources.Resource, error) {
271277
var blocks []string
272-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
278+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
273279

274280
asgs := set.New[string]()
275281
if NetworkSecurityGroup.Properties.SecurityRules != nil {
276282
for _, nsr := range NetworkSecurityGroup.Properties.SecurityRules {
277283
if nsr.Properties.SourceApplicationSecurityGroups != nil {
278284
for _, sasg := range nsr.Properties.SourceApplicationSecurityGroups {
279-
asgID, err := azure.ParseApplicationSecurityGroupID(*sasg.ID)
280-
if err != nil {
281-
return nil, fmt.Errorf("parsing application security group ID: %w", err)
282-
}
283-
asgs.Insert(asgID.ApplicationSecurityGroupName)
285+
asgs.Insert(*sasg.ID)
284286
}
285287
}
286288
if nsr.Properties.DestinationApplicationSecurityGroups != nil {
287289
for _, dasg := range nsr.Properties.DestinationApplicationSecurityGroups {
288-
asgID, err := azure.ParseApplicationSecurityGroupID(*dasg.ID)
289-
if err != nil {
290-
return nil, fmt.Errorf("parsing application security group ID: %w", err)
291-
}
292-
asgs.Insert(asgID.ApplicationSecurityGroupName)
290+
asgs.Insert(*dasg.ID)
293291
}
294292
}
295293
}
@@ -301,7 +299,7 @@ func (g *resourceGetter) toNetworkSecurityGroupResource(NetworkSecurityGroup *ne
301299
return &resources.Resource{
302300
Obj: NetworkSecurityGroup,
303301
Type: typeNetworkSecurityGroup,
304-
ID: *NetworkSecurityGroup.Name,
302+
ID: *NetworkSecurityGroup.ID,
305303
Name: *NetworkSecurityGroup.Name,
306304
Deleter: func(_ fi.Cloud, r *resources.Resource) error {
307305
return g.deleteNetworkSecurityGroup(r)
@@ -331,13 +329,13 @@ func (g *resourceGetter) toApplicationSecurityGroupResource(ApplicationSecurityG
331329
return &resources.Resource{
332330
Obj: ApplicationSecurityGroup,
333331
Type: typeApplicationSecurityGroup,
334-
ID: *ApplicationSecurityGroup.Name,
332+
ID: *ApplicationSecurityGroup.ID,
335333
Name: *ApplicationSecurityGroup.Name,
336334
Deleter: func(_ fi.Cloud, r *resources.Resource) error {
337335
return g.deleteApplicationSecurityGroup(r)
338336
},
339337
Blocks: []string{
340-
toKey(typeResourceGroup, g.resourceGroupName()),
338+
toKey(typeResourceGroup, g.resourceGroupID()),
341339
},
342340
}
343341
}
@@ -366,10 +364,10 @@ func (g *resourceGetter) toRouteTableResource(rt *network.RouteTable) *resources
366364
return &resources.Resource{
367365
Obj: rt,
368366
Type: typeRouteTable,
369-
ID: *rt.Name,
367+
ID: *rt.ID,
370368
Name: *rt.Name,
371369
Deleter: g.deleteRouteTable,
372-
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupName())},
370+
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupID())},
373371
Shared: g.clusterInfo.AzureRouteTableShared,
374372
}
375373
}
@@ -423,36 +421,32 @@ func (g *resourceGetter) listVMScaleSetsAndRoleAssignments(ctx context.Context)
423421
func (g *resourceGetter) toVMScaleSetResource(vmss *compute.VirtualMachineScaleSet, vms []*compute.VirtualMachineScaleSetVM) (*resources.Resource, error) {
424422
// Add resources whose deletion is blocked by this VMSS.
425423
var blocks []string
426-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
424+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
427425

428426
vnets := set.New[string]()
429427
subnets := set.New[string]()
430428
asgs := set.New[string]()
431429
lbs := set.New[string]()
432430
for _, iface := range vmss.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations {
433431
for _, ip := range iface.Properties.IPConfigurations {
434-
subnetID, err := azure.ParseSubnetID(*ip.Properties.Subnet.ID)
432+
subnet, err := arm.ParseResourceID(*ip.Properties.Subnet.ID)
435433
if err != nil {
436-
return nil, fmt.Errorf("parsing subnet ID: %w", err)
434+
return nil, err
437435
}
438-
vnets.Insert(subnetID.VirtualNetworkName)
439-
subnets.Insert(subnetID.SubnetName)
436+
vnets.Insert(subnet.Parent.String())
437+
subnets.Insert(subnet.String())
440438
if ip.Properties.ApplicationSecurityGroups != nil {
441439
for _, asg := range ip.Properties.ApplicationSecurityGroups {
442-
asgID, err := azure.ParseApplicationSecurityGroupID(*asg.ID)
443-
if err != nil {
444-
return nil, fmt.Errorf("parsing application security group ID: %w", err)
445-
}
446-
asgs.Insert(asgID.ApplicationSecurityGroupName)
440+
asgs.Insert(*asg.ID)
447441
}
448442
}
449443
if ip.Properties.LoadBalancerBackendAddressPools != nil {
450-
for _, lb := range ip.Properties.LoadBalancerBackendAddressPools {
451-
lbID, err := azure.ParseLoadBalancerID(*lb.ID)
444+
for _, lbbap := range ip.Properties.LoadBalancerBackendAddressPools {
445+
pool, err := arm.ParseResourceID(*lbbap.ID)
452446
if err != nil {
453-
return nil, fmt.Errorf("parsing load balancer ID: %w", err)
447+
return nil, err
454448
}
455-
lbs.Insert(lbID.LoadBalancerName)
449+
lbs.Insert(pool.Parent.String())
456450
}
457451
}
458452
}
@@ -470,18 +464,10 @@ func (g *resourceGetter) toVMScaleSetResource(vmss *compute.VirtualMachineScaleS
470464
blocks = append(blocks, toKey(typeLoadBalancer, lb))
471465
}
472466

473-
for _, vm := range vms {
474-
if disks := vm.Properties.StorageProfile.DataDisks; disks != nil {
475-
for _, d := range disks {
476-
blocks = append(blocks, toKey(typeDisk, *d.Name))
477-
}
478-
}
479-
}
480-
481467
return &resources.Resource{
482468
Obj: vmss,
483469
Type: typeVMScaleSet,
484-
ID: *vmss.Name,
470+
ID: *vmss.ID,
485471
Name: *vmss.Name,
486472
Deleter: g.deleteVMScaleSet,
487473
Blocks: blocks,
@@ -509,13 +495,22 @@ func (g *resourceGetter) listDisks(ctx context.Context) ([]*resources.Resource,
509495
}
510496

511497
func (g *resourceGetter) toDiskResource(disk *compute.Disk) *resources.Resource {
498+
var blocked []string
499+
if disk.ManagedBy != nil {
500+
vm, err := arm.ParseResourceID(*disk.ManagedBy)
501+
if err == nil {
502+
blocked = append(blocked, toKey(typeVMScaleSet, vm.Parent.String()))
503+
}
504+
}
505+
512506
return &resources.Resource{
513507
Obj: disk,
514508
Type: typeDisk,
515-
ID: *disk.Name,
509+
ID: *disk.ID,
516510
Name: *disk.Name,
517511
Deleter: g.deleteDisk,
518-
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupName())},
512+
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupID())},
513+
Blocked: blocked,
519514
}
520515
}
521516

@@ -548,12 +543,12 @@ func (g *resourceGetter) toRoleAssignmentResource(ra *authz.RoleAssignment, vmss
548543
return &resources.Resource{
549544
Obj: ra,
550545
Type: typeRoleAssignment,
551-
ID: *ra.Name,
546+
ID: *ra.ID,
552547
Name: *ra.Name,
553548
Deleter: g.deleteRoleAssignment,
554549
Blocks: []string{
555-
toKey(typeResourceGroup, g.resourceGroupName()),
556-
toKey(typeVMScaleSet, *vmss.Name),
550+
toKey(typeResourceGroup, g.resourceGroupID()),
551+
toKey(typeVMScaleSet, *vmss.ID),
557552
},
558553
}
559554
}
@@ -588,19 +583,15 @@ func (g *resourceGetter) listLoadBalancers(ctx context.Context) ([]*resources.Re
588583

589584
func (g *resourceGetter) toLoadBalancerResource(loadBalancer *network.LoadBalancer) (*resources.Resource, error) {
590585
var blocks []string
591-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
586+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
592587

593588
pips := set.New[string]()
594589
if loadBalancer.Properties != nil {
595590
for _, fip := range loadBalancer.Properties.FrontendIPConfigurations {
596591
if fip.Properties == nil || fip.Properties.PublicIPAddress == nil {
597592
continue
598593
}
599-
pipID, err := azure.ParsePublicIPAddressID(*fip.Properties.PublicIPAddress.ID)
600-
if err != nil {
601-
return nil, fmt.Errorf("parsing public IP address ID: %s", err)
602-
}
603-
pips.Insert(pipID.PublicIPAddressName)
594+
pips.Insert(*fip.Properties.PublicIPAddress.ID)
604595
}
605596
}
606597
for pip := range pips {
@@ -610,7 +601,7 @@ func (g *resourceGetter) toLoadBalancerResource(loadBalancer *network.LoadBalanc
610601
return &resources.Resource{
611602
Obj: loadBalancer,
612603
Type: typeLoadBalancer,
613-
ID: *loadBalancer.Name,
604+
ID: *loadBalancer.ID,
614605
Name: *loadBalancer.Name,
615606
Deleter: g.deleteLoadBalancer,
616607
Blocks: blocks,
@@ -641,10 +632,10 @@ func (g *resourceGetter) toPublicIPAddressResource(publicIPAddress *network.Publ
641632
return &resources.Resource{
642633
Obj: publicIPAddress,
643634
Type: typePublicIPAddress,
644-
ID: *publicIPAddress.Name,
635+
ID: *publicIPAddress.ID,
645636
Name: *publicIPAddress.Name,
646637
Deleter: g.deletePublicIPAddress,
647-
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupName())},
638+
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupID())},
648639
}
649640
}
650641

@@ -674,16 +665,12 @@ func (g *resourceGetter) listNatGateways(ctx context.Context) ([]*resources.Reso
674665

675666
func (g *resourceGetter) toNatGatewayResource(natGateway *network.NatGateway) (*resources.Resource, error) {
676667
var blocks []string
677-
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))
668+
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupID()))
678669

679670
pips := set.New[string]()
680671
if natGateway.Properties != nil && natGateway.Properties.PublicIPAddresses != nil {
681672
for _, pip := range natGateway.Properties.PublicIPAddresses {
682-
pipID, err := azure.ParsePublicIPAddressID(*pip.ID)
683-
if err != nil {
684-
return nil, fmt.Errorf("parsing public IP address ID: %s", err)
685-
}
686-
pips.Insert(pipID.PublicIPAddressName)
673+
pips.Insert(*pip.ID)
687674
}
688675
}
689676
for pip := range pips {

0 commit comments

Comments
 (0)