Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,15 @@ func (vpcHandler *KTVpcVPCHandler) RemoveSubnet(vpcIID irs.IID, subnetIID irs.II

// ### Need NetworkId, not TierId.
delErr := subnets.Delete(vpcHandler.NetworkClient, *networkId).ExtractErr()
if err != nil {
if delErr != nil {
newErr := fmt.Errorf("Failed to Remove the Subnet : [%v]", delErr)
cblogger.Error(newErr.Error())
loggingError(callLogInfo, newErr)
return false, newErr
}
cblogger.Infof("\n### Waiting for Deleting the Subnet!! Subnet NetworkId: %s", *networkId)
vpcHandler.waitForSubnetDeletion(*networkId)
if err != nil {
newErr := fmt.Errorf("Failed to wait for the subnet creation: %v", err)
if waitErr := vpcHandler.waitForSubnetDeletion(*networkId); waitErr != nil {
newErr := fmt.Errorf("Failed to wait for the subnet deletion: %v", waitErr)
cblogger.Error(newErr.Error())
loggingError(callLogInfo, newErr)
return false, newErr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,26 @@ func (vpcHandler *OpenStackVPCHandler) RemoveSubnet(vpcIID irs.IID, subnetIID ir
hiscallInfo := GetCallLogScheme(vpcHandler.NetworkClient.IdentityEndpoint, call.VPCSUBNET, subnetIID.NameId, "RemoveSubnet()")

start := call.Start()
err := subnets.Delete(context.TODO(), vpcHandler.NetworkClient, subnetIID.SystemId).ExtractErr()

// Detach the subnet from the VPC's router before deleting it.
// Otherwise the delete fails with 409 SubnetInUse, since the router
// interface still holds an IP allocation from the subnet.
routerId, err := vpcHandler.GetRouter(vpcIID.NameId)
if err == nil {
if _, ifaceErr := vpcHandler.DeleteInterface(subnetIID.SystemId, *routerId); ifaceErr != nil {
cblogger.Warn(fmt.Sprintf("Failed to detach router interface for subnet %s: %s", subnetIID.SystemId, ifaceErr.Error()))
}
} else if err.Error() != ResourceNotFound {
cblogger.Warn(fmt.Sprintf("Failed to get router for VPC %s: %s", vpcIID.NameId, err.Error()))
}

// Remove any remaining non-VM ports (e.g. DHCP) still holding an IP
// allocation from this subnet, which would also block the delete.
if err := vpcHandler.cleanupSubnetPorts(vpcIID.SystemId, subnetIID.SystemId); err != nil {
cblogger.Warn(fmt.Sprintf("Failed to cleanup remaining ports on subnet %s: %s", subnetIID.SystemId, err.Error()))
}

err = subnets.Delete(context.TODO(), vpcHandler.NetworkClient, subnetIID.SystemId).ExtractErr()
if err != nil {
delErr := errors.New(fmt.Sprintf("Failed to Remove Subnet err = %s", err.Error()))
cblogger.Error(delErr.Error())
Expand Down Expand Up @@ -585,6 +604,34 @@ func (vpcHandler *OpenStackVPCHandler) cleanupNetworkPorts(networkID string) err
return nil
}

// cleanupSubnetPorts deletes non-VM ports (e.g. DHCP) still holding an IP
// allocation from the given subnet, which would otherwise block its deletion.
func (vpcHandler *OpenStackVPCHandler) cleanupSubnetPorts(networkID string, subnetID string) error {
portPages, err := ports.List(vpcHandler.NetworkClient, ports.ListOpts{NetworkID: networkID}).AllPages(context.TODO())
if err != nil {
return err
}
portList, err := ports.ExtractPorts(portPages)
if err != nil {
return err
}
for _, p := range portList {
// Skip ports that are owned by compute (VMs) - should not exist at this point
if p.DeviceOwner == "compute:nova" || p.DeviceOwner == "compute:None" {
continue
}
for _, fixedIP := range p.FixedIPs {
if fixedIP.SubnetID == subnetID {
if delErr := ports.Delete(context.TODO(), vpcHandler.NetworkClient, p.ID).ExtractErr(); delErr != nil {
cblogger.Warn(fmt.Sprintf("Failed to delete port %s (device_owner=%s): %v", p.ID, p.DeviceOwner, delErr))
}
break
}
}
}
return nil
}

func (vpcHandler *OpenStackVPCHandler) vpcCleaner(vpcIId irs.IID) error {
// VPC
vpc, err := vpcHandler.GetVPC(vpcIId)
Expand Down
Loading