mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
helpers/subnetmap: allow to use IP addresses
They will be considered as /32 or /128.
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/kentik/patricia"
|
||||
tree "github.com/kentik/patricia/generics_tree"
|
||||
@@ -55,22 +56,35 @@ func SubnetMapUnmarshallerHook[V any]() mapstructure.DecodeHookFunc {
|
||||
return nil, fmt.Errorf("key %d is not a string (%s)", i, k.Kind())
|
||||
}
|
||||
// Parse key
|
||||
_, ipNet, err := net.ParseCIDR(k.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert key to IPv6
|
||||
ones, bits := ipNet.Mask.Size()
|
||||
if bits != 32 && bits != 128 {
|
||||
return nil, fmt.Errorf("key %d has an invalid netmask", i)
|
||||
}
|
||||
var key string
|
||||
if bits == 32 {
|
||||
key = fmt.Sprintf("::ffff:%s/%d", ipNet.IP.String(), ones+96)
|
||||
if strings.Contains(k.String(), "/") {
|
||||
// Subnet
|
||||
_, ipNet, err := net.ParseCIDR(k.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert key to IPv6
|
||||
ones, bits := ipNet.Mask.Size()
|
||||
if bits != 32 && bits != 128 {
|
||||
return nil, fmt.Errorf("key %d has an invalid netmask", i)
|
||||
}
|
||||
if bits == 32 {
|
||||
key = fmt.Sprintf("::ffff:%s/%d", ipNet.IP.String(), ones+96)
|
||||
} else {
|
||||
key = ipNet.String()
|
||||
}
|
||||
} else {
|
||||
key = ipNet.String()
|
||||
// IP
|
||||
ip := net.ParseIP(k.String())
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("key %d is not a valid subnet", i)
|
||||
}
|
||||
if ipv4 := ip.To4(); ipv4 != nil {
|
||||
key = fmt.Sprintf("::ffff:%s/128", ipv4.String())
|
||||
} else {
|
||||
key = fmt.Sprintf("%s/128", ip.String())
|
||||
}
|
||||
}
|
||||
|
||||
output[key] = v.Interface()
|
||||
}
|
||||
} else if from.Type() == reflect.TypeOf(zero) || from.Type().ConvertibleTo(reflect.TypeOf(zero)) {
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestSubnetMapUnmarshalHook(t *testing.T) {
|
||||
"203.0.113.1": "",
|
||||
},
|
||||
}, {
|
||||
Description: "IPv4",
|
||||
Description: "IPv4 subnet",
|
||||
Input: gin.H{"203.0.113.0/24": "customer1"},
|
||||
Tests: map[string]string{
|
||||
"::ffff:203.0.113.18": "customer1",
|
||||
@@ -46,13 +46,31 @@ func TestSubnetMapUnmarshalHook(t *testing.T) {
|
||||
"2001:db8:1::12": "",
|
||||
},
|
||||
}, {
|
||||
Description: "IPv6",
|
||||
Description: "IPv4 IP",
|
||||
Input: gin.H{"203.0.113.1": "customer1"},
|
||||
Tests: map[string]string{
|
||||
"::ffff:203.0.113.1": "customer1",
|
||||
"203.0.113.1": "customer1",
|
||||
"2001:db8:1::12": "",
|
||||
},
|
||||
YAML: gin.H{"203.0.113.1/32": "customer1"},
|
||||
}, {
|
||||
Description: "IPv6 subnet",
|
||||
Input: gin.H{"2001:db8:1::/64": "customer2"},
|
||||
Tests: map[string]string{
|
||||
"2001:db8:1::1": "customer2",
|
||||
"2001:db8:1::2": "customer2",
|
||||
"2001:db8:2::2": "",
|
||||
},
|
||||
}, {
|
||||
Description: "IPv6 IP",
|
||||
Input: gin.H{"2001:db8:1::1": "customer2"},
|
||||
Tests: map[string]string{
|
||||
"2001:db8:1::1": "customer2",
|
||||
"2001:db8:1::2": "",
|
||||
"2001:db8:2::2": "",
|
||||
},
|
||||
YAML: gin.H{"2001:db8:1::1/128": "customer2"},
|
||||
}, {
|
||||
Description: "Invalid subnet (1)",
|
||||
Input: gin.H{"192.0.2.1/38": "customer"},
|
||||
@@ -65,6 +83,10 @@ func TestSubnetMapUnmarshalHook(t *testing.T) {
|
||||
Description: "Invalid subnet (3)",
|
||||
Input: gin.H{"2001:db8::/1000": "customer"},
|
||||
Error: true,
|
||||
}, {
|
||||
Description: "Invalid IP",
|
||||
Input: gin.H{"200.33.300.1": "customer"},
|
||||
Error: true,
|
||||
}, {
|
||||
Description: "Single value",
|
||||
Input: "customer",
|
||||
|
||||
Reference in New Issue
Block a user