@@ -25,7 +25,9 @@ import (
25
25
"k8s.io/apimachinery/pkg/util/sets"
26
26
"k8s.io/apimachinery/pkg/util/validation/field"
27
27
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
28
+ kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
28
29
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
30
+ "k8s.io/kubernetes/cmd/kubeadm/app/features"
29
31
)
30
32
31
33
func TestValidateToken (t * testing.T ) {
@@ -231,6 +233,91 @@ func TestValidateIPNetFromString(t *testing.T) {
231
233
}
232
234
}
233
235
236
+ func TestValidatePodSubnetNodeMask (t * testing.T ) {
237
+ var tests = []struct {
238
+ name string
239
+ subnet string
240
+ cmExtraArgs map [string ]string
241
+ checkDualStack bool
242
+ expected bool
243
+ }{
244
+ {"single IPv4, but mask too small. Default node-mask" , "10.0.0.16/29" , nil , false , false },
245
+ {"single IPv4, but mask too small. Configured node-mask" , "10.0.0.16/24" , map [string ]string {"node-cidr-mask-size" : "23" }, false , false },
246
+ {"single IPv6, but mask too small. Default node-mask" , "2001:db8::1/112" , nil , false , false },
247
+ {"single IPv6, but mask too small. Configured node-mask" , "2001:db8::1/64" , map [string ]string {"node-cidr-mask-size" : "24" }, false , false },
248
+ {"single IPv6, but mask difference greater than 16. Default node-mask" , "2001:db8::1/12" , nil , false , false },
249
+ {"single IPv6, but mask difference greater than 16. Configured node-mask" , "2001:db8::1/64" , map [string ]string {"node-cidr-mask-size" : "120" }, false , false },
250
+ {"single IPv4 CIDR" , "10.0.0.16/12" , nil , false , true },
251
+ {"single IPv6 CIDR" , "2001:db8::/48" , nil , false , true },
252
+ // dual-stack:
253
+ {"dual IPv4 only, but mask too small. Default node-mask" , "10.0.0.16/29" , nil , true , false },
254
+ {"dual IPv4 only, but mask too small. Configured node-mask" , "10.0.0.16/24" , map [string ]string {"node-cidr-mask-size-ipv4" : "23" }, true , false },
255
+ {"dual IPv6 only, but mask too small. Default node-mask" , "2001:db8::1/112" , nil , true , false },
256
+ {"dual IPv6 only, but mask too small. Configured node-mask" , "2001:db8::1/64" , map [string ]string {"node-cidr-mask-size-ipv6" : "24" }, true , false },
257
+ {"dual IPv6 only, but mask difference greater than 16. Default node-mask" , "2001:db8::1/12" , nil , true , false },
258
+ {"dual IPv6 only, but mask difference greater than 16. Configured node-mask" , "2001:db8::1/64" , map [string ]string {"node-cidr-mask-size-ipv6" : "120" }, true , false },
259
+ {"dual IPv4 only CIDR" , "10.0.0.16/12" , nil , true , true },
260
+ {"dual IPv6 only CIDR" , "2001:db8::/48" , nil , true , true },
261
+ {"dual, but IPv4 mask too small. Default node-mask" , "10.0.0.16/29,2001:db8::/48" , nil , true , false },
262
+ {"dual, but IPv4 mask too small. Configured node-mask" , "10.0.0.16/24,2001:db8::/48" , map [string ]string {"node-cidr-mask-size-ipv4" : "23" }, true , false },
263
+ {"dual, but IPv6 mask too small. Default node-mask" , "2001:db8::1/112,10.0.0.16/16" , nil , true , false },
264
+ {"dual, but IPv6 mask too small. Configured node-mask" , "10.0.0.16/16,2001:db8::1/64" , map [string ]string {"node-cidr-mask-size-ipv6" : "24" }, true , false },
265
+ {"dual, but mask difference greater than 16. Default node-mask" , "2001:db8::1/12,10.0.0.16/16" , nil , true , false },
266
+ {"dual, but mask difference greater than 16. Configured node-mask" , "10.0.0.16/16,2001:db8::1/64" , map [string ]string {"node-cidr-mask-size-ipv6" : "120" }, true , false },
267
+ {"dual IPv4 IPv6" , "2001:db8::/48,10.0.0.16/12" , nil , true , true },
268
+ {"dual IPv6 IPv4" , "2001:db8::/48,10.0.0.16/12" , nil , true , true },
269
+ }
270
+ for _ , rt := range tests {
271
+ cfg := & kubeadmapi.ClusterConfiguration {
272
+ FeatureGates : map [string ]bool {features .IPv6DualStack : rt .checkDualStack },
273
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
274
+ ExtraArgs : rt .cmExtraArgs ,
275
+ },
276
+ }
277
+ actual := ValidatePodSubnetNodeMask (rt .subnet , cfg , nil )
278
+ if (len (actual ) == 0 ) != rt .expected {
279
+ t .Errorf (
280
+ "%s test case failed :\n \t expected: %t\n \t actual: %t\n \t err(s): %v\n \t " ,
281
+ rt .name ,
282
+ rt .expected ,
283
+ (len (actual ) == 0 ),
284
+ actual ,
285
+ )
286
+ }
287
+ }
288
+ }
289
+
290
+ func TestValidateServiceSubnetSize (t * testing.T ) {
291
+ var tests = []struct {
292
+ name string
293
+ subnet string
294
+ expected bool
295
+ }{
296
+ {"single IPv4, but mask too large." , "10.0.0.16/2" , false },
297
+ {"single IPv6, but mask too large." , "2001:db8::1/64" , false },
298
+ {"single IPv4 CIDR" , "10.0.0.16/12" , true },
299
+ {"single IPv6 CIDR" , "2001:db8::/112" , true },
300
+ // dual-stack:
301
+ {"dual, but IPv4 mask too large." , "2001:db8::1/112,10.0.0.16/6" , false },
302
+ {"dual, but IPv6 mask too large." , "2001:db8::1/12,10.0.0.16/16" , false },
303
+ {"dual IPv4 IPv6" , "10.0.0.16/12,2001:db8::/112" , true },
304
+ {"dual IPv6 IPv4" , "2001:db8::/112,10.0.0.16/12" , true },
305
+ }
306
+ for _ , rt := range tests {
307
+
308
+ actual := ValidateServiceSubnetSize (rt .subnet , nil )
309
+ if (len (actual ) == 0 ) != rt .expected {
310
+ t .Errorf (
311
+ "%s test case failed :\n \t expected: %t\n \t actual: %t\n \t err(s): %v\n \t " ,
312
+ rt .name ,
313
+ rt .expected ,
314
+ (len (actual ) == 0 ),
315
+ actual ,
316
+ )
317
+ }
318
+ }
319
+ }
320
+
234
321
func TestValidateHostPort (t * testing.T ) {
235
322
var tests = []struct {
236
323
name string
@@ -465,7 +552,7 @@ func TestValidateInitConfiguration(t *testing.T) {
465
552
},
466
553
},
467
554
Networking : kubeadm.Networking {
468
- ServiceSubnet : "2001:db8::1/98 " ,
555
+ ServiceSubnet : "2001:db8::1/112 " ,
469
556
DNSDomain : "cluster.local" ,
470
557
},
471
558
CertificatesDir : "/some/other/cert/dir" ,
@@ -1040,3 +1127,160 @@ func TestValidateEtcd(t *testing.T) {
1040
1127
}
1041
1128
}
1042
1129
}
1130
+
1131
+ func TestGetClusterNodeMask (t * testing.T ) {
1132
+ tests := []struct {
1133
+ name string
1134
+ cfg * kubeadmapi.ClusterConfiguration
1135
+ isIPv6 bool
1136
+ expectedMask int
1137
+ expectedError bool
1138
+ }{
1139
+ {
1140
+ name : "ipv4 default mask" ,
1141
+ cfg : & kubeadmapi.ClusterConfiguration {},
1142
+ isIPv6 : false ,
1143
+ expectedMask : 24 ,
1144
+ },
1145
+ {
1146
+ name : "ipv4 custom mask" ,
1147
+ cfg : & kubeadmapi.ClusterConfiguration {
1148
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1149
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "23" },
1150
+ },
1151
+ },
1152
+ isIPv6 : false ,
1153
+ expectedMask : 23 ,
1154
+ },
1155
+ {
1156
+ name : "ipv4 wrong mask" ,
1157
+ cfg : & kubeadmapi.ClusterConfiguration {
1158
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1159
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "aa23" },
1160
+ },
1161
+ },
1162
+ isIPv6 : false ,
1163
+ expectedError : true ,
1164
+ },
1165
+ {
1166
+ name : "ipv6 default mask" ,
1167
+ cfg : & kubeadmapi.ClusterConfiguration {},
1168
+ isIPv6 : true ,
1169
+ expectedMask : 64 ,
1170
+ },
1171
+ {
1172
+ name : "ipv6 custom mask" ,
1173
+ cfg : & kubeadmapi.ClusterConfiguration {
1174
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1175
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "83" },
1176
+ },
1177
+ },
1178
+ isIPv6 : true ,
1179
+ expectedMask : 83 ,
1180
+ },
1181
+ {
1182
+ name : "dual ipv4 default mask" ,
1183
+ cfg : & kubeadmapi.ClusterConfiguration {
1184
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1185
+ },
1186
+ isIPv6 : false ,
1187
+ expectedMask : 24 ,
1188
+ },
1189
+ {
1190
+ name : "dual ipv4 custom mask" ,
1191
+ cfg : & kubeadmapi.ClusterConfiguration {
1192
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1193
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1194
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "21" , "node-cidr-mask-size-ipv4" : "23" },
1195
+ },
1196
+ },
1197
+ isIPv6 : false ,
1198
+ expectedMask : 23 ,
1199
+ },
1200
+ {
1201
+ name : "dual ipv6 default mask" ,
1202
+ cfg : & kubeadmapi.ClusterConfiguration {
1203
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1204
+ },
1205
+ isIPv6 : true ,
1206
+ expectedMask : 64 ,
1207
+ },
1208
+ {
1209
+ name : "dual ipv6 custom mask" ,
1210
+ cfg : & kubeadmapi.ClusterConfiguration {
1211
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1212
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1213
+ ExtraArgs : map [string ]string {"node-cidr-mask-size-ipv6" : "83" },
1214
+ },
1215
+ },
1216
+ isIPv6 : true ,
1217
+ expectedMask : 83 ,
1218
+ },
1219
+ {
1220
+ name : "dual ipv4 custom mask" ,
1221
+ cfg : & kubeadmapi.ClusterConfiguration {
1222
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1223
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1224
+ ExtraArgs : map [string ]string {"node-cidr-mask-size-ipv4" : "23" },
1225
+ },
1226
+ },
1227
+ isIPv6 : false ,
1228
+ expectedMask : 23 ,
1229
+ },
1230
+ {
1231
+ name : "dual ipv4 wrong mask" ,
1232
+ cfg : & kubeadmapi.ClusterConfiguration {
1233
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1234
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1235
+ ExtraArgs : map [string ]string {"node-cidr-mask-size-ipv4" : "aa" },
1236
+ },
1237
+ },
1238
+ isIPv6 : false ,
1239
+ expectedError : true ,
1240
+ },
1241
+ {
1242
+ name : "dual ipv6 default mask and legacy flag" ,
1243
+ cfg : & kubeadmapi.ClusterConfiguration {
1244
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1245
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1246
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "23" },
1247
+ },
1248
+ },
1249
+ isIPv6 : true ,
1250
+ expectedMask : 64 ,
1251
+ },
1252
+ {
1253
+ name : "dual ipv6 custom mask and legacy flag" ,
1254
+ cfg : & kubeadmapi.ClusterConfiguration {
1255
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1256
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1257
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "23" , "node-cidr-mask-size-ipv6" : "83" },
1258
+ },
1259
+ },
1260
+ isIPv6 : true ,
1261
+ expectedMask : 83 ,
1262
+ },
1263
+ {
1264
+ name : "dual ipv6 custom mask and wrong flag" ,
1265
+ cfg : & kubeadmapi.ClusterConfiguration {
1266
+ FeatureGates : map [string ]bool {features .IPv6DualStack : true },
1267
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
1268
+ ExtraArgs : map [string ]string {"node-cidr-mask-size" : "23" , "node-cidr-mask-size-ipv6" : "a83" },
1269
+ },
1270
+ },
1271
+ isIPv6 : true ,
1272
+ expectedError : true ,
1273
+ },
1274
+ }
1275
+ for _ , test := range tests {
1276
+ t .Run (test .name , func (t * testing.T ) {
1277
+ mask , err := getClusterNodeMask (test .cfg , test .isIPv6 )
1278
+ if (err == nil ) == test .expectedError {
1279
+ t .Errorf ("expected error: %v, got %v" , test .expectedError , err )
1280
+ }
1281
+ if mask != test .expectedMask {
1282
+ t .Errorf ("expected mask: %d, got %d" , test .expectedMask , mask )
1283
+ }
1284
+ })
1285
+ }
1286
+ }
0 commit comments