@@ -73,6 +73,20 @@ func (w *testEIPWatcher) assertNoChanges() error {
73
73
return w .assertChanges ()
74
74
}
75
75
76
+ func (w * testEIPWatcher ) flushChanges () {
77
+ w .changes = []string {}
78
+ }
79
+
80
+ func (w * testEIPWatcher ) assertUpdateEgressCIDRsNotification () error {
81
+ for _ , change := range w .changes {
82
+ if change == "update egress CIDRs" {
83
+ w .flushChanges ()
84
+ return nil
85
+ }
86
+ }
87
+ return fmt .Errorf ("expected change \" update egress CIDRs\" , got %#v" , w .changes )
88
+ }
89
+
76
90
func setupEgressIPTracker (t * testing.T ) (* EgressIPTracker , * testEIPWatcher ) {
77
91
watcher := & testEIPWatcher {}
78
92
return NewEgressIPTracker (watcher ), watcher
@@ -864,9 +878,6 @@ func TestEgressCIDRAllocation(t *testing.T) {
864
878
t .Fatalf ("%v" , err )
865
879
}
866
880
allocation = eit .ReallocateEgressIPs ()
867
- if len (allocation ) != 0 {
868
- t .Fatalf ("Unexpected allocation: %#v" , allocation )
869
- }
870
881
updateAllocations (eit , allocation )
871
882
err = w .assertNoChanges ()
872
883
if err != nil {
@@ -947,31 +958,41 @@ func TestEgressCIDRAllocation(t *testing.T) {
947
958
t .Fatalf ("%v" , err )
948
959
}
949
960
950
- // Changing the EgressIPs of a namespace should drop the old allocation and create a new one
961
+ // Changing/Removing the EgressIPs of a namespace should drop the old allocation and create a new one
951
962
updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
952
963
NetID : 46 ,
953
964
EgressIPs : []string {"172.17.0.202" }, // was 172.17.0.200
954
965
})
966
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
967
+ NetID : 44 ,
968
+ EgressIPs : []string {}, // was 172.17.1.1
969
+ })
955
970
err = w .assertChanges (
956
971
"release 172.17.0.200 on 172.17.0.4" ,
957
972
"namespace 46 dropped" ,
958
973
"update egress CIDRs" ,
974
+ "release 172.17.1.1 on 172.17.0.3" ,
975
+ "namespace 44 normal" ,
976
+ "update egress CIDRs" ,
959
977
)
960
978
if err != nil {
961
979
t .Fatalf ("%v" , err )
962
980
}
963
981
964
982
allocation = eit .ReallocateEgressIPs ()
965
- for _ , ip := range allocation ["node-4" ] {
966
- if ip == "172.17.0.200" {
967
- t .Fatalf ("reallocation failed to drop unused egress IP 172.17.0.200: %#v" , allocation )
983
+ for _ , nodeAllocation := range allocation {
984
+ for _ , ip := range nodeAllocation {
985
+ if ip == "172.17.1.1" || ip == "172.17.0.200" {
986
+ t .Fatalf ("reallocation failed to drop unused egress IP %s: %#v" , ip , allocation )
987
+ }
968
988
}
969
989
}
970
990
updateAllocations (eit , allocation )
971
991
err = w .assertChanges (
972
992
"claim 172.17.0.202 on 172.17.0.4 for namespace 46" ,
973
993
"namespace 46 via 172.17.0.202 on 172.17.0.4" ,
974
994
"update egress CIDRs" ,
995
+ "update egress CIDRs" ,
975
996
)
976
997
if err != nil {
977
998
t .Fatalf ("%v" , err )
@@ -1031,3 +1052,132 @@ func TestEgressNodeRenumbering(t *testing.T) {
1031
1052
t .Fatalf ("%v" , err )
1032
1053
}
1033
1054
}
1055
+
1056
+ func TestEgressCIDRAllocationOffline (t * testing.T ) {
1057
+ eit , w := setupEgressIPTracker (t )
1058
+
1059
+ // Create nodes...
1060
+ updateHostSubnetEgress (eit , & networkapi.HostSubnet {
1061
+ HostIP : "172.17.0.3" ,
1062
+ EgressIPs : []string {},
1063
+ EgressCIDRs : []string {"172.17.0.0/24" , "172.17.1.0/24" },
1064
+ })
1065
+ updateHostSubnetEgress (eit , & networkapi.HostSubnet {
1066
+ HostIP : "172.17.0.4" ,
1067
+ EgressIPs : []string {},
1068
+ EgressCIDRs : []string {"172.17.0.0/24" },
1069
+ })
1070
+ updateHostSubnetEgress (eit , & networkapi.HostSubnet {
1071
+ HostIP : "172.17.0.5" ,
1072
+ EgressIPs : []string {},
1073
+ EgressCIDRs : []string {"172.17.1.0/24" },
1074
+ })
1075
+
1076
+ // Create namespaces
1077
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1078
+ NetID : 100 ,
1079
+ EgressIPs : []string {"172.17.0.100" },
1080
+ })
1081
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1082
+ NetID : 101 ,
1083
+ EgressIPs : []string {"172.17.0.101" },
1084
+ })
1085
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1086
+ NetID : 102 ,
1087
+ EgressIPs : []string {"172.17.0.102" },
1088
+ })
1089
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1090
+ NetID : 200 ,
1091
+ EgressIPs : []string {"172.17.1.200" },
1092
+ })
1093
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1094
+ NetID : 201 ,
1095
+ EgressIPs : []string {"172.17.1.201" },
1096
+ })
1097
+ updateNetNamespaceEgress (eit , & networkapi.NetNamespace {
1098
+ NetID : 202 ,
1099
+ EgressIPs : []string {"172.17.1.202" },
1100
+ })
1101
+
1102
+ // In a perfect world, we'd get 2 IPs on each node, but depending on processing
1103
+ // order, this isn't guaranteed. Eg, if the three 172.17.0.x IPs get processed
1104
+ // first, we could get two of them on node-3 and one on node-4. Then the first two
1105
+ // 172.17.1.x IPs get assigned to node-5, and the last one could go to either
1106
+ // node-3 or node-5. Regardless of order, node-3 is guaranteed to get at least
1107
+ // two IPs since there's no way either node-4 or node-5 could be assigned a
1108
+ // third IP if node-3 still only had one.
1109
+ allocation := eit .ReallocateEgressIPs ()
1110
+ node3ips := allocation ["node-3" ]
1111
+ node4ips := allocation ["node-4" ]
1112
+ node5ips := allocation ["node-5" ]
1113
+ if len (node3ips ) < 2 || len (node4ips ) == 0 || len (node5ips ) == 0 ||
1114
+ len (node3ips )+ len (node4ips )+ len (node5ips ) != 6 {
1115
+ t .Fatalf ("Bad IP allocation: %#v" , allocation )
1116
+ }
1117
+ updateAllocations (eit , allocation )
1118
+
1119
+ w .flushChanges ()
1120
+
1121
+ // Now take node-3 offline
1122
+ eit .SetNodeOffline ("172.17.0.3" , true )
1123
+ err := w .assertUpdateEgressCIDRsNotification ()
1124
+ if err != nil {
1125
+ t .Fatalf ("%v" , err )
1126
+ }
1127
+
1128
+ // First reallocation should empty out node-3
1129
+ allocation = eit .ReallocateEgressIPs ()
1130
+ if node3ips , ok := allocation ["node-3" ]; ! ok || len (node3ips ) != 0 {
1131
+ t .Fatalf ("Bad IP allocation: %#v" , allocation )
1132
+ }
1133
+ updateAllocations (eit , allocation )
1134
+
1135
+ err = w .assertUpdateEgressCIDRsNotification ()
1136
+ if err != nil {
1137
+ t .Fatalf ("%v" , err )
1138
+ }
1139
+
1140
+ // Next reallocation should reassign egress IPs to node-4 and node-5
1141
+ allocation = eit .ReallocateEgressIPs ()
1142
+ node3ips = allocation ["node-3" ]
1143
+ node4ips = allocation ["node-4" ]
1144
+ node5ips = allocation ["node-5" ]
1145
+ if len (node3ips ) != 0 || len (node4ips ) != 3 || len (node5ips ) != 3 {
1146
+ t .Fatalf ("Bad IP allocation: %#v" , allocation )
1147
+ }
1148
+ updateAllocations (eit , allocation )
1149
+
1150
+ // Bring node-3 back
1151
+ eit .SetNodeOffline ("172.17.0.3" , false )
1152
+ err = w .assertUpdateEgressCIDRsNotification ()
1153
+ if err != nil {
1154
+ t .Fatalf ("%v" , err )
1155
+ }
1156
+
1157
+ // First reallocation should remove some IPs from node-4 and node-5 but not add
1158
+ // them to node-3. As above, the "balanced" allocation we're aiming for may not
1159
+ // be perfect, but it has to be planning to assign at least 2 IPs to node-3.
1160
+ allocation = eit .ReallocateEgressIPs ()
1161
+ node3ips = allocation ["node-3" ]
1162
+ node4ips = allocation ["node-4" ]
1163
+ node5ips = allocation ["node-5" ]
1164
+ if len (node3ips ) != 0 || len (node4ips )+ len (node5ips ) > 4 {
1165
+ t .Fatalf ("Bad IP allocation: %#v" , allocation )
1166
+ }
1167
+ updateAllocations (eit , allocation )
1168
+
1169
+ err = w .assertUpdateEgressCIDRsNotification ()
1170
+ if err != nil {
1171
+ t .Fatalf ("%v" , err )
1172
+ }
1173
+
1174
+ // Next reallocation should reassign egress IPs to node-3
1175
+ allocation = eit .ReallocateEgressIPs ()
1176
+ node3ips = allocation ["node-3" ]
1177
+ node4ips = allocation ["node-4" ]
1178
+ node5ips = allocation ["node-5" ]
1179
+ if len (node3ips ) < 2 || len (node4ips ) == 0 || len (node5ips ) == 0 {
1180
+ t .Fatalf ("Bad IP allocation: %#v" , allocation )
1181
+ }
1182
+ updateAllocations (eit , allocation )
1183
+ }
0 commit comments