diff --git a/cmd/metal-api/internal/metal/network.go b/cmd/metal-api/internal/metal/network.go index 0a2da7c8..aa5b702d 100644 --- a/cmd/metal-api/internal/metal/network.go +++ b/cmd/metal-api/internal/metal/network.go @@ -1,6 +1,7 @@ package metal import ( + "fmt" "net" "net/netip" "strconv" @@ -266,12 +267,25 @@ type AddressFamily string type AddressFamilies []AddressFamily const ( + // InvalidAddressFamily identifies a invalid Addressfamily + InvalidAddressFamily = AddressFamily("invalid") // IPv4AddressFamily identifies IPv4 IPv4AddressFamily = AddressFamily("IPv4") // IPv6AddressFamily identifies IPv6 IPv6AddressFamily = AddressFamily("IPv6") ) +// Validate a string if it is a addressfamily and returns an error if it is not. +func ValidateAddressFamily(af string) (AddressFamily, error) { + switch strings.ToLower(af) { + case "ipv4": + return IPv4AddressFamily, nil + case "ipv6": + return IPv6AddressFamily, nil + } + return InvalidAddressFamily, fmt.Errorf("given addressfamily:%q is invalid", af) +} + // ToAddressFamily will convert a string af to a AddressFamily func ToAddressFamily(af string) AddressFamily { switch strings.ToLower(af) { diff --git a/cmd/metal-api/internal/service/ip-service.go b/cmd/metal-api/internal/service/ip-service.go index 7d246feb..294ba37c 100644 --- a/cmd/metal-api/internal/service/ip-service.go +++ b/cmd/metal-api/internal/service/ip-service.go @@ -285,7 +285,12 @@ func (r *ipResource) allocateIP(request *restful.Request, response *restful.Resp } if requestPayload.AddressFamily != nil { - if !slices.Contains(nw.AddressFamilies, metal.ToAddressFamily(string(*requestPayload.AddressFamily))) { + af, err := metal.ValidateAddressFamily(string(*requestPayload.AddressFamily)) + if err != nil { + r.sendError(request, response, defaultError(err)) + return + } + if !slices.Contains(nw.AddressFamilies, af) { r.sendError(request, response, httperrors.BadRequest( fmt.Errorf("there is no prefix for the given addressfamily:%s present in network:%s", string(*requestPayload.AddressFamily), requestPayload.NetworkID)), ) diff --git a/cmd/metal-api/internal/service/network-service.go b/cmd/metal-api/internal/service/network-service.go index 7355e992..15be8d93 100644 --- a/cmd/metal-api/internal/service/network-service.go +++ b/cmd/metal-api/internal/service/network-service.go @@ -284,7 +284,12 @@ func (r *networkResource) createNetwork(request *restful.Request, response *rest var childPrefixLength = metal.ChildPrefixLength{} for af, length := range requestPayload.DefaultChildPrefixLength { - childPrefixLength[metal.ToAddressFamily(string(af))] = length + addressfamily, err := metal.ValidateAddressFamily(string(af)) + if err != nil { + r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily of defaultchildprefixlength is invalid %w", err))) + return + } + childPrefixLength[addressfamily] = length } prefixes, destPrefixes, addressFamilies, err := validatePrefixesAndAddressFamilies(requestPayload.Prefixes, requestPayload.DestinationPrefixes, childPrefixLength, privateSuper) @@ -627,21 +632,30 @@ func (r *networkResource) allocateNetwork(request *restful.Request, response *re length := superNetwork.DefaultChildPrefixLength if len(requestPayload.Length) > 0 { for af, l := range requestPayload.Length { - length[metal.ToAddressFamily(string(af))] = l + addressfamily, err := metal.ValidateAddressFamily(string(af)) + if err != nil { + r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily of length is invalid %w", err))) + return + } + length[addressfamily] = l } } if requestPayload.AddressFamily != nil { - af := metal.ToAddressFamily(string(*requestPayload.AddressFamily)) - bits, ok := length[af] + addressfamily, err := metal.ValidateAddressFamily(string(*requestPayload.AddressFamily)) + if err != nil { + r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamily is invalid %w", err))) + return + } + bits, ok := length[addressfamily] if !ok { r.sendError(request, response, httperrors.BadRequest(fmt.Errorf("addressfamiliy %s specified, but no childprefixlength for this addressfamily", *requestPayload.AddressFamily))) return } length = metal.ChildPrefixLength{ - af: bits, + addressfamily: bits, } - nwSpec.AddressFamilies = metal.AddressFamilies{af} + nwSpec.AddressFamilies = metal.AddressFamilies{addressfamily} } r.log.Info("network allocate", "supernetwork", superNetwork.ID, "defaultchildprefixlength", superNetwork.DefaultChildPrefixLength, "length", length)