Address order: sequential, reverse or random, per subnet and pool
- Which never-used pool address a new client gets: sequential (the lowest, as before), reverse or random, in the settings, a subnet or a single pool (FIRST-LAST:ORDER). When no never-used address is left, the one free the longest, whatever the order; returning clients keep theirs. - A subnet's pools are used in the order listed, or one at random weighted by its never-used addresses. Pools now keep the order they are given in (no more sorting by address). - CLI --address-order and --pool-order; --add-pool of an existing range changes its order in place. Web UI: per-pool order and a move-up button, pool and address order on the subnet and settings pages. - Kea's allocator: random is imported. Schema migration 5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
29fc991ce1
commit
8ee430276c
29 files changed
+653
-79
No files matched your search
@@ -405,3 +405,32 @@ func TestInterfacesExclude(t *testing.T) {
|
||||
t.Errorf("interfaces: %+v", ifs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddressOrderAPI(t *testing.T) {
|
||||
e := newEnv(t)
|
||||
var mr api.MutationResponse
|
||||
in := api.SubnetInput{Prefix: ptr("10.0.20.0/24"), Interface: ptr("eth0.20"), PoolOrder: ptr("random"), AddressOrder: ptr("Reverse"),
|
||||
Pools: &[]string{"10.0.20.100-10.0.20.110:random", "10.0.20.10-10.0.20.20"}}
|
||||
if code := e.call(e.token, "POST", "/subnets", in, &mr); code != 201 {
|
||||
t.Fatalf("create: %d %+v", code, mr)
|
||||
}
|
||||
sn := e.eng.State().Subnets[0]
|
||||
// The pools keep the order given.
|
||||
if sn.PoolOrder != "random" || sn.AddressOrder != "reverse" || sn.Pools[0].String() != "10.0.20.100-10.0.20.110:random" || sn.Pools[1].Order != "" {
|
||||
t.Errorf("subnet %+v", sn)
|
||||
}
|
||||
// "listed" and "default" are the defaults, stored as "".
|
||||
if code := e.call(e.token, "PATCH", "/subnets/"+itoa(sn.ID), api.SubnetInput{PoolOrder: ptr("listed"), AddressOrder: ptr("default")}, nil); code != 200 {
|
||||
t.Errorf("patch: %d", code)
|
||||
}
|
||||
if sn = e.eng.State().Subnets[0]; sn.PoolOrder != "" || sn.AddressOrder != "" {
|
||||
t.Errorf("defaults %+v", sn)
|
||||
}
|
||||
var eb api.ErrorBody
|
||||
if code := e.call(e.token, "PATCH", "/settings", api.SettingsInput{AddressOrder: ptr("lowest")}, &eb); code != 422 || eb.Error.Problems[0].Code != "address_order" {
|
||||
t.Errorf("bad order: %d %+v", code, eb)
|
||||
}
|
||||
if code := e.call(e.token, "PATCH", "/subnets/"+itoa(sn.ID), api.SubnetInput{Pools: &[]string{"10.0.20.10-10.0.20.20:lowest"}}, nil); code != 400 {
|
||||
t.Errorf("bad pool order: %d", code)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user