|
41 | 41 | key3 = wgtypes.Key{'k', 'e', 'y', '3'} |
42 | 42 | key4 = wgtypes.Key{'k', 'e', 'y', '4'} |
43 | 43 | key5 = wgtypes.Key{'k', 'e', 'y', '5'} |
| 44 | + key6 = wgtypes.Key{'k', 'e', 'y', '6'} |
44 | 45 | ) |
45 | 46 |
|
46 | 47 | func setup(t *testing.T) (map[string]*Node, map[string]*Peer, wgtypes.Key, int) { |
@@ -854,6 +855,208 @@ func TestNewTopology(t *testing.T) { |
854 | 855 | } |
855 | 856 | } |
856 | 857 |
|
| 858 | +func TestNewTopologyEmptyLocation(t *testing.T) { |
| 859 | + nodes, peers, key, port := setup(t) |
| 860 | + |
| 861 | + e5 := &net.IPNet{IP: net.ParseIP("10.1.0.5").To4(), Mask: net.CIDRMask(16, 32)} |
| 862 | + i5 := &net.IPNet{IP: net.ParseIP("10.1.0.5").To4(), Mask: net.CIDRMask(32, 32)} |
| 863 | + nodes["e"] = &Node{ |
| 864 | + Name: "e", |
| 865 | + Endpoint: wireguard.NewEndpoint(e5.IP, DefaultKiloPort), |
| 866 | + InternalIP: i5, |
| 867 | + Location: "", |
| 868 | + Subnet: &net.IPNet{IP: net.ParseIP("10.2.5.0"), Mask: net.CIDRMask(24, 32)}, |
| 869 | + Key: key6, |
| 870 | + } |
| 871 | + |
| 872 | + // LogicalGranularity: node e has empty Location and a valid InternalIP. |
| 873 | + // Because Location == "", it is grouped under "location:" (logicalLocationPrefix + ""). |
| 874 | + // |
| 875 | + // Segment sort order (location string): |
| 876 | + // location: → node e → w1 (Location="" with InternalIP set) |
| 877 | + // location:1 → node a → w2 |
| 878 | + // location:2 → nodes b, c → w3 |
| 879 | + // node:d → node d → w4 (Location="1" but InternalIP==nil) |
| 880 | + w1 := net.ParseIP("10.4.0.1").To4() |
| 881 | + w2 := net.ParseIP("10.4.0.2").To4() |
| 882 | + w3 := net.ParseIP("10.4.0.3").To4() |
| 883 | + w4 := net.ParseIP("10.4.0.4").To4() |
| 884 | + w5 := net.ParseIP("10.4.0.5").To4() |
| 885 | + |
| 886 | + for _, tc := range []struct { |
| 887 | + name string |
| 888 | + granularity Granularity |
| 889 | + hostname string |
| 890 | + result *Topology |
| 891 | + }{ |
| 892 | + { |
| 893 | + name: "logical from e (empty location)", |
| 894 | + granularity: LogicalGranularity, |
| 895 | + hostname: nodes["e"].Name, |
| 896 | + result: &Topology{ |
| 897 | + hostname: nodes["e"].Name, |
| 898 | + leader: true, |
| 899 | + location: logicalLocationPrefix + nodes["e"].Location, |
| 900 | + subnet: nodes["e"].Subnet, |
| 901 | + privateIP: nodes["e"].InternalIP, |
| 902 | + wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)}, |
| 903 | + segments: []*segment{ |
| 904 | + { |
| 905 | + allowedIPs: []net.IPNet{*nodes["e"].Subnet, *nodes["e"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}}, |
| 906 | + endpoint: nodes["e"].Endpoint, |
| 907 | + key: nodes["e"].Key, |
| 908 | + persistentKeepalive: nodes["e"].PersistentKeepalive, |
| 909 | + location: logicalLocationPrefix + nodes["e"].Location, |
| 910 | + cidrs: []*net.IPNet{nodes["e"].Subnet}, |
| 911 | + hostnames: []string{"e"}, |
| 912 | + privateIPs: []net.IP{nodes["e"].InternalIP.IP}, |
| 913 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 914 | + wireGuardIP: w1, |
| 915 | + }, |
| 916 | + { |
| 917 | + allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}}, |
| 918 | + endpoint: nodes["a"].Endpoint, |
| 919 | + key: nodes["a"].Key, |
| 920 | + persistentKeepalive: nodes["a"].PersistentKeepalive, |
| 921 | + location: logicalLocationPrefix + nodes["a"].Location, |
| 922 | + cidrs: []*net.IPNet{nodes["a"].Subnet}, |
| 923 | + hostnames: []string{"a"}, |
| 924 | + privateIPs: []net.IP{nodes["a"].InternalIP.IP}, |
| 925 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 926 | + wireGuardIP: w2, |
| 927 | + }, |
| 928 | + { |
| 929 | + allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, *nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}}, |
| 930 | + endpoint: nodes["b"].Endpoint, |
| 931 | + key: nodes["b"].Key, |
| 932 | + persistentKeepalive: nodes["b"].PersistentKeepalive, |
| 933 | + location: logicalLocationPrefix + nodes["b"].Location, |
| 934 | + cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet}, |
| 935 | + hostnames: []string{"b", "c"}, |
| 936 | + privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP}, |
| 937 | + cniCompatibilityIPs: []*net.IPNet{nil, nil}, |
| 938 | + wireGuardIP: w3, |
| 939 | + allowedLocationIPs: nodes["b"].AllowedLocationIPs, |
| 940 | + }, |
| 941 | + { |
| 942 | + allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}}, |
| 943 | + endpoint: nodes["d"].Endpoint, |
| 944 | + key: nodes["d"].Key, |
| 945 | + persistentKeepalive: nodes["d"].PersistentKeepalive, |
| 946 | + location: nodeLocationPrefix + nodes["d"].Name, |
| 947 | + cidrs: []*net.IPNet{nodes["d"].Subnet}, |
| 948 | + hostnames: []string{"d"}, |
| 949 | + privateIPs: nil, |
| 950 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 951 | + wireGuardIP: w4, |
| 952 | + }, |
| 953 | + }, |
| 954 | + peers: []*Peer{peers["a"], peers["b"]}, |
| 955 | + logger: log.NewNopLogger(), |
| 956 | + }, |
| 957 | + }, |
| 958 | + { |
| 959 | + // CrossGranularity: every node gets its own segment keyed by node name. |
| 960 | + // For node e with empty Location, nodeLocation must be "location:" (logicalLocationPrefix + ""). |
| 961 | + // |
| 962 | + // Segment sort order (location = node:<name>): |
| 963 | + // node:a → w1, node:b → w2, node:c → w3, node:d → w4, node:e → w5 |
| 964 | + name: "cross from e (empty location)", |
| 965 | + granularity: CrossGranularity, |
| 966 | + hostname: nodes["e"].Name, |
| 967 | + result: &Topology{ |
| 968 | + hostname: nodes["e"].Name, |
| 969 | + leader: true, |
| 970 | + location: nodeLocationPrefix + nodes["e"].Name, |
| 971 | + nodeLocation: logicalLocationPrefix + nodes["e"].Location, |
| 972 | + subnet: nodes["e"].Subnet, |
| 973 | + privateIP: nodes["e"].InternalIP, |
| 974 | + wireGuardCIDR: &net.IPNet{IP: w5, Mask: net.CIDRMask(16, 32)}, |
| 975 | + segments: []*segment{ |
| 976 | + { |
| 977 | + allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}}, |
| 978 | + endpoint: nodes["a"].Endpoint, |
| 979 | + key: nodes["a"].Key, |
| 980 | + persistentKeepalive: nodes["a"].PersistentKeepalive, |
| 981 | + location: nodeLocationPrefix + nodes["a"].Name, |
| 982 | + nodeLocation: logicalLocationPrefix + nodes["a"].Location, |
| 983 | + cidrs: []*net.IPNet{nodes["a"].Subnet}, |
| 984 | + hostnames: []string{"a"}, |
| 985 | + privateIPs: []net.IP{nodes["a"].InternalIP.IP}, |
| 986 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 987 | + wireGuardIP: w1, |
| 988 | + }, |
| 989 | + { |
| 990 | + allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}}, |
| 991 | + endpoint: nodes["b"].Endpoint, |
| 992 | + key: nodes["b"].Key, |
| 993 | + persistentKeepalive: nodes["b"].PersistentKeepalive, |
| 994 | + location: nodeLocationPrefix + nodes["b"].Name, |
| 995 | + nodeLocation: logicalLocationPrefix + nodes["b"].Location, |
| 996 | + cidrs: []*net.IPNet{nodes["b"].Subnet}, |
| 997 | + hostnames: []string{"b"}, |
| 998 | + privateIPs: []net.IP{nodes["b"].InternalIP.IP}, |
| 999 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 1000 | + wireGuardIP: w2, |
| 1001 | + allowedLocationIPs: nodes["b"].AllowedLocationIPs, |
| 1002 | + }, |
| 1003 | + { |
| 1004 | + allowedIPs: []net.IPNet{*nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}}, |
| 1005 | + endpoint: nodes["c"].Endpoint, |
| 1006 | + key: nodes["c"].Key, |
| 1007 | + persistentKeepalive: nodes["c"].PersistentKeepalive, |
| 1008 | + location: nodeLocationPrefix + nodes["c"].Name, |
| 1009 | + nodeLocation: logicalLocationPrefix + nodes["c"].Location, |
| 1010 | + cidrs: []*net.IPNet{nodes["c"].Subnet}, |
| 1011 | + hostnames: []string{"c"}, |
| 1012 | + privateIPs: []net.IP{nodes["c"].InternalIP.IP}, |
| 1013 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 1014 | + wireGuardIP: w3, |
| 1015 | + }, |
| 1016 | + { |
| 1017 | + allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}}, |
| 1018 | + endpoint: nodes["d"].Endpoint, |
| 1019 | + key: nodes["d"].Key, |
| 1020 | + persistentKeepalive: nodes["d"].PersistentKeepalive, |
| 1021 | + location: nodeLocationPrefix + nodes["d"].Name, |
| 1022 | + nodeLocation: logicalLocationPrefix + nodes["d"].Location, |
| 1023 | + cidrs: []*net.IPNet{nodes["d"].Subnet}, |
| 1024 | + hostnames: []string{"d"}, |
| 1025 | + privateIPs: nil, |
| 1026 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 1027 | + wireGuardIP: w4, |
| 1028 | + }, |
| 1029 | + { |
| 1030 | + allowedIPs: []net.IPNet{*nodes["e"].Subnet, *nodes["e"].InternalIP, {IP: w5, Mask: net.CIDRMask(32, 32)}}, |
| 1031 | + endpoint: nodes["e"].Endpoint, |
| 1032 | + key: nodes["e"].Key, |
| 1033 | + persistentKeepalive: nodes["e"].PersistentKeepalive, |
| 1034 | + location: nodeLocationPrefix + nodes["e"].Name, |
| 1035 | + nodeLocation: logicalLocationPrefix + nodes["e"].Location, |
| 1036 | + cidrs: []*net.IPNet{nodes["e"].Subnet}, |
| 1037 | + hostnames: []string{"e"}, |
| 1038 | + privateIPs: []net.IP{nodes["e"].InternalIP.IP}, |
| 1039 | + cniCompatibilityIPs: []*net.IPNet{nil}, |
| 1040 | + wireGuardIP: w5, |
| 1041 | + }, |
| 1042 | + }, |
| 1043 | + peers: []*Peer{peers["a"], peers["b"]}, |
| 1044 | + logger: log.NewNopLogger(), |
| 1045 | + }, |
| 1046 | + }, |
| 1047 | + } { |
| 1048 | + tc.result.key = key |
| 1049 | + tc.result.port = port |
| 1050 | + topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, DefaultKiloSubnet, nil, 0, nil) |
| 1051 | + if err != nil { |
| 1052 | + t.Errorf("test case %q: failed to generate Topology: %v", tc.name, err) |
| 1053 | + } |
| 1054 | + if diff := pretty.Compare(topo, tc.result); diff != "" { |
| 1055 | + t.Errorf("test case %q: got diff: %v", tc.name, diff) |
| 1056 | + } |
| 1057 | + } |
| 1058 | +} |
| 1059 | + |
857 | 1060 | func mustTopo(t *testing.T, nodes map[string]*Node, peers map[string]*Peer, granularity Granularity, hostname string, port int, key wgtypes.Key, subnet *net.IPNet, persistentKeepalive time.Duration) *Topology { |
858 | 1061 | topo, err := NewTopology(nodes, peers, granularity, hostname, port, key, subnet, nil, persistentKeepalive, nil) |
859 | 1062 | if err != nil { |
|
0 commit comments