Skip to content

Commit

Permalink
azure: Add mode dependency logic to deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
hakman committed Jul 11, 2023
1 parent 1a1055f commit 344d5b3
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 16 deletions.
75 changes: 67 additions & 8 deletions pkg/resources/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ func (g *resourceGetter) listVirtualNetworksAndSubnets(ctx context.Context) ([]*
if !g.isOwnedByCluster(vnet.Tags) {
continue
}
rs = append(rs, g.toVirtualNetworkResource(vnet))
r, err := g.toVirtualNetworkResource(vnet)
if err != nil {
return nil, err
}
rs = append(rs, r)
// Add all subnets belonging to the virtual network.
subnets, err := g.listSubnets(ctx, *vnet.Name)
if err != nil {
Expand All @@ -161,16 +165,35 @@ func (g *resourceGetter) listVirtualNetworksAndSubnets(ctx context.Context) ([]*
return rs, nil
}

func (g *resourceGetter) toVirtualNetworkResource(vnet *network.VirtualNetwork) *resources.Resource {
func (g *resourceGetter) toVirtualNetworkResource(vnet *network.VirtualNetwork) (*resources.Resource, error) {
var blocks []string
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))

nsgs := map[string]struct{}{}
if vnet.Subnets != nil {
for _, sn := range *vnet.Subnets {
if sn.NetworkSecurityGroup != nil {
nsgID, err := azuretasks.ParseNetworkSecurityGroupID(*sn.NetworkSecurityGroup.ID)
if err != nil {
return nil, fmt.Errorf("parsing network security group ID: %s", err)
}
nsgs[nsgID.NetworkSecurityGroupName] = struct{}{}
}
}
}
for nsg := range nsgs {
blocks = append(blocks, toKey(typeNetworkSecurityGroup, nsg))
}

return &resources.Resource{
Obj: vnet,
Type: typeVirtualNetwork,
ID: *vnet.Name,
Name: *vnet.Name,
Deleter: g.deleteVirtualNetwork,
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupName())},
Blocks: blocks,
Shared: g.clusterInfo.AzureNetworkShared,
}
}, nil
}

func (g *resourceGetter) deleteVirtualNetwork(_ fi.Cloud, r *resources.Resource) error {
Expand Down Expand Up @@ -321,6 +344,7 @@ func (g *resourceGetter) toVMScaleSetResource(vmss *compute.VirtualMachineScaleS

vnets := map[string]struct{}{}
subnets := map[string]struct{}{}
lbs := map[string]struct{}{}
for _, iface := range *vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations {
for _, ip := range *iface.IPConfigurations {
subnetID, err := azuretasks.ParseSubnetID(*ip.Subnet.ID)
Expand All @@ -329,6 +353,15 @@ func (g *resourceGetter) toVMScaleSetResource(vmss *compute.VirtualMachineScaleS
}
vnets[subnetID.VirtualNetworkName] = struct{}{}
subnets[subnetID.SubnetName] = struct{}{}
if ip.LoadBalancerBackendAddressPools != nil {
for _, lb := range *ip.LoadBalancerBackendAddressPools {
lbID, err := azuretasks.ParseLoadBalancerID(*lb.ID)
if err != nil {
return nil, fmt.Errorf("parsing load balancer ID: %s", err)
}
lbs[lbID.LoadBalancerName] = struct{}{}
}
}
}
}
for vnet := range vnets {
Expand All @@ -337,6 +370,9 @@ func (g *resourceGetter) toVMScaleSetResource(vmss *compute.VirtualMachineScaleS
for subnet := range subnets {
blocks = append(blocks, toKey(typeSubnet, subnet))
}
for lb := range lbs {
blocks = append(blocks, toKey(typeLoadBalancer, lb))
}

for _, vm := range vms {
if disks := vm.StorageProfile.DataDisks; disks != nil {
Expand Down Expand Up @@ -448,20 +484,43 @@ func (g *resourceGetter) listLoadBalancers(ctx context.Context) ([]*resources.Re
if !g.isOwnedByCluster(lb.Tags) {
continue
}
rs = append(rs, g.toLoadBalancerResource(lb))
r, err := g.toLoadBalancerResource(lb)
if err != nil {
return nil, err
}
rs = append(rs, r)
}
return rs, nil
}

func (g *resourceGetter) toLoadBalancerResource(loadBalancer *network.LoadBalancer) *resources.Resource {
func (g *resourceGetter) toLoadBalancerResource(loadBalancer *network.LoadBalancer) (*resources.Resource, error) {
var blocks []string
blocks = append(blocks, toKey(typeResourceGroup, g.resourceGroupName()))

pips := map[string]struct{}{}
if loadBalancer.FrontendIPConfigurations != nil {
for _, fip := range *loadBalancer.FrontendIPConfigurations {
if fip.PublicIPAddress != nil {
pipID, err := azuretasks.ParsePublicIPAddressID(*fip.PublicIPAddress.ID)
if err != nil {
return nil, fmt.Errorf("parsing public IP address ID: %s", err)
}
pips[pipID.PublicIPAddressName] = struct{}{}
}
}
}
for pip := range pips {
blocks = append(blocks, toKey(typePublicIPAddress, pip))
}

return &resources.Resource{
Obj: loadBalancer,
Type: typeLoadBalancer,
ID: *loadBalancer.Name,
Name: *loadBalancer.Name,
Deleter: g.deleteLoadBalancer,
Blocks: []string{toKey(typeResourceGroup, g.resourceGroupName())},
}
Blocks: blocks,
}, nil
}

func (g *resourceGetter) deleteLoadBalancer(_ fi.Cloud, r *resources.Resource) error {
Expand Down
10 changes: 6 additions & 4 deletions pkg/resources/azure/azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ func TestListResourcesAzure(t *testing.T) {

vnets := cloud.VirtualNetworksClient.VNets
vnets[vnetName] = network.VirtualNetwork{
Name: to.StringPtr(vnetName),
Tags: clusterTags,
Name: to.StringPtr(vnetName),
Tags: clusterTags,
VirtualNetworkPropertiesFormat: &network.VirtualNetworkPropertiesFormat{},
}
vnets[irrelevantName] = network.VirtualNetwork{
Name: to.StringPtr(irrelevantName),
Expand Down Expand Up @@ -164,8 +165,9 @@ func TestListResourcesAzure(t *testing.T) {

lbs := cloud.LoadBalancersClient.LBs
lbs[lbName] = network.LoadBalancer{
Name: to.StringPtr(lbName),
Tags: clusterTags,
Name: to.StringPtr(lbName),
Tags: clusterTags,
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{},
}
lbs[irrelevantName] = network.LoadBalancer{
Name: to.StringPtr(irrelevantName),
Expand Down
62 changes: 59 additions & 3 deletions upup/pkg/fi/cloudup/azuretasks/vmscaleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ func ParseSubnetID(s string) (*SubnetID, error) {
}, nil
}

// NetworkSecurityGroupID contains the resource ID/names required to construct a NetworkSecurityGroup ID.
type NetworkSecurityGroupID struct {
SubscriptionID string
ResourceGroupName string
NetworkSecurityGroupName string
}

// String returns the NetworkSecurityGroup ID in the path format.
func (s *NetworkSecurityGroupID) String() string {
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s",
s.SubscriptionID,
s.ResourceGroupName,
s.NetworkSecurityGroupName)
}

// ParseNetworkSecurityGroupID parses a given NetworkSecurityGroup ID string and returns a NetworkSecurityGroup ID.
func ParseNetworkSecurityGroupID(s string) (*NetworkSecurityGroupID, error) {
l := strings.Split(s, "/")
if len(l) != 9 {
return nil, fmt.Errorf("malformed format of NetworkSecurityGroup ID: %s, %d", s, len(l))
}
return &NetworkSecurityGroupID{
SubscriptionID: l[2],
ResourceGroupName: l[4],
NetworkSecurityGroupName: l[8],
}, nil
}

// loadBalancerID contains the resource ID/names required to construct a loadbalancer ID.
type loadBalancerID struct {
SubscriptionID string
Expand All @@ -76,8 +104,8 @@ func (lb *loadBalancerID) String() string {
)
}

// parseLoadBalancerID parses a given loadbalancer ID string and returns a loadBalancerID.
func parseLoadBalancerID(lb string) (*loadBalancerID, error) {
// ParseLoadBalancerID parses a given loadbalancer ID string and returns a loadBalancerID.
func ParseLoadBalancerID(lb string) (*loadBalancerID, error) {
l := strings.Split(lb, "/")
if len(l) != 11 {
return nil, fmt.Errorf("malformed format of loadbalancer ID: %s, %d", lb, len(l))
Expand All @@ -89,6 +117,34 @@ func parseLoadBalancerID(lb string) (*loadBalancerID, error) {
}, nil
}

// PublicIPAddressID contains the resource ID/names required to construct a PublicIPAddress ID.
type PublicIPAddressID struct {
SubscriptionID string
ResourceGroupName string
PublicIPAddressName string
}

// String returns the PublicIPAddress ID in the path format.
func (s *PublicIPAddressID) String() string {
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/publicIPAddresss/%s",
s.SubscriptionID,
s.ResourceGroupName,
s.PublicIPAddressName)
}

// ParsePublicIPAddressID parses a given PublicIPAddress ID string and returns a PublicIPAddress ID.
func ParsePublicIPAddressID(s string) (*PublicIPAddressID, error) {
l := strings.Split(s, "/")
if len(l) != 9 {
return nil, fmt.Errorf("malformed format of PublicIPAddress ID: %s, %d", s, len(l))
}
return &PublicIPAddressID{
SubscriptionID: l[2],
ResourceGroupName: l[4],
PublicIPAddressName: l[8],
}, nil
}

// VMScaleSet is an Azure VM Scale Set.
// +kops:fitask
type VMScaleSet struct {
Expand Down Expand Up @@ -184,7 +240,7 @@ func (s *VMScaleSet) Find(c *fi.CloudupContext) (*VMScaleSet, error) {
if !strings.Contains(*i.ID, "api") {
continue
}
loadBalancerID, err = parseLoadBalancerID(*i.ID)
loadBalancerID, err = ParseLoadBalancerID(*i.ID)
if err != nil {
return nil, fmt.Errorf("failed to parse loadbalancer ID %s", *ipConfig.Subnet.ID)
}
Expand Down
2 changes: 1 addition & 1 deletion upup/pkg/fi/cloudup/azuretasks/vmscaleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestLoadBalancerIDParse(t *testing.T) {
ResourceGroupName: "rg",
LoadBalancerName: "lb",
}
actual, err := parseLoadBalancerID(loadBalancerID.String())
actual, err := ParseLoadBalancerID(loadBalancerID.String())
if err != nil {
t.Fatalf("unexpected error %s", err)
}
Expand Down

0 comments on commit 344d5b3

Please sign in to comment.