diff --git a/cmd/metal-api/internal/ipam/ipam.go b/cmd/metal-api/internal/ipam/ipam.go index 8a9479f37..5cbe97a59 100644 --- a/cmd/metal-api/internal/ipam/ipam.go +++ b/cmd/metal-api/internal/ipam/ipam.go @@ -2,6 +2,7 @@ package ipam import ( "fmt" + "net/netip" "github.com/metal-stack/metal-api/cmd/metal-api/internal/metal" @@ -42,13 +43,20 @@ func (i *Ipam) AllocateChildPrefix(parentPrefix metal.Prefix, childLength uint8) // ReleaseChildPrefix release a child prefix from a parent prefix in the IPAM. func (i *Ipam) ReleaseChildPrefix(childPrefix metal.Prefix) error { - ipamChildPrefix := i.ip.PrefixFrom(childPrefix.String()) + _, err := netip.ParsePrefix(childPrefix.String()) + if err != nil { + return fmt.Errorf("invalid child prefix: %w", err) + } + ipamChildPrefix := i.ip.PrefixFrom(childPrefix.String()) if ipamChildPrefix == nil { - return fmt.Errorf("error finding child prefix in ipam: %s", childPrefix.String()) + // FIXME: unfortunately, go-ipam does not return a proper error here so we cannot deduce if the prefix + // was already deleted or not, so if the database is down or something we continue with network deletion + // even though there could be remainings in the go-ipam db + return nil } - err := i.ip.ReleaseChildPrefix(ipamChildPrefix) + err = i.ip.ReleaseChildPrefix(ipamChildPrefix) if err != nil { return fmt.Errorf("error releasing child prefix in ipam: %w", err) } diff --git a/cmd/metal-api/internal/service/network-service.go b/cmd/metal-api/internal/service/network-service.go index de9778b1f..727a83ee9 100644 --- a/cmd/metal-api/internal/service/network-service.go +++ b/cmd/metal-api/internal/service/network-service.go @@ -550,21 +550,6 @@ func (r *networkResource) freeNetwork(request *restful.Request, response *restfu return } - for _, prefix := range nw.Prefixes { - usage, err := r.ipamer.PrefixUsage(prefix.String()) - if err != nil { - r.sendError(request, response, defaultError(err)) - return - } - - if usage.UsedIPs > 2 { - if err != nil { - r.sendError(request, response, defaultError(fmt.Errorf("cannot release child prefix %s because IPs in the prefix are still in use: %v", prefix.String(), usage.UsedIPs-2))) - return - } - } - } - for _, prefix := range nw.Prefixes { err = r.ipamer.ReleaseChildPrefix(prefix) if err != nil { @@ -767,6 +752,7 @@ func getNetworkUsage(nw *metal.Network, ipamer ipam.IPAMer) *metal.NetworkUsage for _, prefix := range nw.Prefixes { u, err := ipamer.PrefixUsage(prefix.String()) if err != nil { + // FIXME: the error should not be swallowed here as this can return wrong usage information to the clients continue } usage.AvailableIPs = usage.AvailableIPs + u.AvailableIPs