mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
fix: flip flop on ordering when reading and writing the annotation
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -56,14 +57,14 @@ func ParseLeaseVIPs(value string) (LeaseVIPsValue, error) {
|
||||
if err != nil {
|
||||
return LeaseVIPsValue{}, fmt.Errorf("invalid %s VIP at index %d: %w", LeaseVIPs, vip.Index, err)
|
||||
}
|
||||
parsed.VIPs[index].Value = address
|
||||
parsed.VIPs[index].Value = address.String()
|
||||
}
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func normalizeLeaseVIPs(values []string) []LeaseVIP {
|
||||
unique := make(map[string]struct{})
|
||||
result := make([]LeaseVIP, 0, len(values))
|
||||
unique := make(map[netip.Addr]struct{})
|
||||
addresses := make([]netip.Addr, 0, len(values))
|
||||
for _, value := range values {
|
||||
for candidate := range strings.SplitSeq(value, ",") {
|
||||
candidate = strings.TrimSpace(candidate)
|
||||
@@ -75,20 +76,27 @@ func normalizeLeaseVIPs(values []string) []LeaseVIP {
|
||||
continue
|
||||
}
|
||||
unique[address] = struct{}{}
|
||||
result = append(result, LeaseVIP{Index: len(result), Value: address})
|
||||
addresses = append(addresses, address)
|
||||
}
|
||||
}
|
||||
// Sorting keeps the annotation byte-identical however callers happen to order VIPs.
|
||||
slices.SortFunc(addresses, netip.Addr.Compare)
|
||||
|
||||
result := make([]LeaseVIP, 0, len(addresses))
|
||||
for _, address := range addresses {
|
||||
result = append(result, LeaseVIP{Index: len(result), Value: address.String()})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func parseLeaseVIP(value string) (string, error) {
|
||||
func parseLeaseVIP(value string) (netip.Addr, error) {
|
||||
address, err := netip.ParseAddr(value)
|
||||
if err == nil {
|
||||
return address.Unmap().String(), nil
|
||||
return address.Unmap(), nil
|
||||
}
|
||||
prefix, prefixErr := netip.ParsePrefix(value)
|
||||
if prefixErr != nil {
|
||||
return "", fmt.Errorf("parse address %q: %w", value, err)
|
||||
return netip.Addr{}, fmt.Errorf("parse address %q: %w", value, err)
|
||||
}
|
||||
return prefix.Addr().Unmap().String(), nil
|
||||
return prefix.Addr().Unmap(), nil
|
||||
}
|
||||
|
||||
@@ -25,9 +25,43 @@ func TestWithLeaseVIPsEncodesVersionedInstanceOwnership(t *testing.T) {
|
||||
t.Fatalf("Lease VIP metadata = %+v", value)
|
||||
}
|
||||
if len(value.VIPs) != 2 ||
|
||||
value.VIPs[0] != (LeaseVIP{Index: 0, Value: "2001:db8::10"}) ||
|
||||
value.VIPs[1] != (LeaseVIP{Index: 1, Value: "192.0.2.10"}) {
|
||||
t.Fatalf("Lease VIPs = %v, want indexed VIPs in configuration order", value.VIPs)
|
||||
value.VIPs[0] != (LeaseVIP{Index: 0, Value: "192.0.2.10"}) ||
|
||||
value.VIPs[1] != (LeaseVIP{Index: 1, Value: "2001:db8::10"}) {
|
||||
t.Fatalf("Lease VIPs = %v, want indexed VIPs in canonical address order", value.VIPs)
|
||||
}
|
||||
}
|
||||
|
||||
// The annotation is rewritten whenever a node starts campaigning, so the encoding
|
||||
// has to be stable even when callers collect the same VIPs in a different order.
|
||||
func TestWithLeaseVIPsIsIndependentOfInputOrder(t *testing.T) {
|
||||
first, err := WithLeaseVIPs(nil, "release_a", 248, []string{
|
||||
"2001:db8::10", "192.0.2.10", "10.0.0.2", "10.0.0.10",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("WithLeaseVIPs() error = %v", err)
|
||||
}
|
||||
second, err := WithLeaseVIPs(nil, "release_a", 248, []string{
|
||||
"10.0.0.10", "192.0.2.10", "2001:db8::10", "10.0.0.2",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("WithLeaseVIPs() error = %v", err)
|
||||
}
|
||||
if first[LeaseVIPs] != second[LeaseVIPs] {
|
||||
t.Fatalf("annotation changed with input order:\n%s\n%s", first[LeaseVIPs], second[LeaseVIPs])
|
||||
}
|
||||
|
||||
value, err := ParseLeaseVIPs(first[LeaseVIPs])
|
||||
if err != nil {
|
||||
t.Fatalf("ParseLeaseVIPs() error = %v", err)
|
||||
}
|
||||
want := []string{"10.0.0.2", "10.0.0.10", "192.0.2.10", "2001:db8::10"}
|
||||
if len(value.VIPs) != len(want) {
|
||||
t.Fatalf("Lease VIPs = %v, want %v", value.VIPs, want)
|
||||
}
|
||||
for index, address := range want {
|
||||
if value.VIPs[index] != (LeaseVIP{Index: index, Value: address}) {
|
||||
t.Fatalf("Lease VIPs = %v, want %v", value.VIPs, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user