@@ -199,6 +199,177 @@ func TestEnsureMultipleInstanceGroups(t *testing.T) {
199
199
}
200
200
}
201
201
202
+ func TestEnsureInstanceGroupFromDefaultNetworkMultiSubnetClusterMode (t * testing.T ) {
203
+ t .Parallel ()
204
+
205
+ vals := DefaultTestClusterValues ()
206
+ vals .SubnetworkURL = "https://www.googleapis.com/compute/v1/projects/project/regions/us-central1/subnetworks/defaultSubnet"
207
+ gce , err := fakeGCECloud (vals )
208
+ require .NoError (t , err )
209
+
210
+ nodes , err := createAndInsertNodes (gce , []string {"n1" , "n2" , "n3" , "n4" , "n5" }, vals .ZoneName )
211
+ require .NoError (t , err )
212
+ // node with a matching subnet
213
+ nodes [0 ].Labels [labelGKESubnetworkName ] = "defaultSubnet"
214
+ // node with a label of a non-matching subnet
215
+ nodes [1 ].Labels [labelGKESubnetworkName ] = "anotherSubnet"
216
+ // node with no label but a PodCIDR
217
+ nodes [2 ].Spec .PodCIDR = "10.0.5.0/24"
218
+ // node[3] has no label nor PodCIDR
219
+ nodes [3 ].Spec .PodCIDR = ""
220
+ // node[4] has a label that contains an empty string (this indicates the default network).
221
+ nodes [4 ].Spec .PodCIDR = ""
222
+ nodes [4 ].Labels [labelGKESubnetworkName ] = ""
223
+
224
+ baseName := makeInstanceGroupName (vals .ClusterID )
225
+
226
+ igsFromCloud , err := gce .ensureInternalInstanceGroups (baseName , nodes )
227
+ require .NoError (t , err )
228
+
229
+ url , err := cloud .ParseResourceURL (igsFromCloud [0 ])
230
+ require .NoError (t , err )
231
+ instances , err := gce .ListInstancesInInstanceGroup (url .Key .Name , url .Key .Zone , "ALL" )
232
+ require .NoError (t , err )
233
+ assert .Len (t , instances , 3 , "Incorrect number of Instances in the group" )
234
+ var instanceURLs []string
235
+ for _ , inst := range instances {
236
+ instanceURLs = append (instanceURLs , inst .Instance )
237
+ }
238
+ if ! hasInstanceForNode (instances , nodes [0 ]) {
239
+ t .Errorf ("expected n1 to be in instances but it contained %+v" , instanceURLs )
240
+ }
241
+ if hasInstanceForNode (instances , nodes [1 ]) {
242
+ t .Errorf ("expected n2 to NOT be in instances but it was included %+v" , instanceURLs )
243
+ }
244
+ if ! hasInstanceForNode (instances , nodes [2 ]) {
245
+ t .Errorf ("expected n3 to be in instances but it contained %+v" , instanceURLs )
246
+ }
247
+ if hasInstanceForNode (instances , nodes [3 ]) {
248
+ t .Errorf ("expected n4 to NOT be in instances but it was included %+v" , instanceURLs )
249
+ }
250
+ if ! hasInstanceForNode (instances , nodes [4 ]) {
251
+ t .Errorf ("expected n5 to be in instances but it contained %+v" , instanceURLs )
252
+ }
253
+ }
254
+
255
+ // Test that the node filtering will not be done if the cluster subnetwork value is not set properly.
256
+ func TestEnsureInstanceGroupFromDefaultNetworkMultiSubnetClusterModeIfSubnetworkValueIsInvalid (t * testing.T ) {
257
+ t .Parallel ()
258
+
259
+ vals := DefaultTestClusterValues ()
260
+ vals .SubnetworkURL = "invalid"
261
+ gce , err := fakeGCECloud (vals )
262
+ require .NoError (t , err )
263
+
264
+ nodes , err := createAndInsertNodes (gce , []string {"n1" , "n2" }, vals .ZoneName )
265
+ require .NoError (t , err )
266
+ // node with a matching subnet
267
+ nodes [0 ].Labels [labelGKESubnetworkName ] = "defaultSubnet"
268
+ // node with a label of a non-matching subnet
269
+ nodes [1 ].Labels [labelGKESubnetworkName ] = "anotherSubnet"
270
+
271
+ baseName := makeInstanceGroupName (vals .ClusterID )
272
+
273
+ igsFromCloud , err := gce .ensureInternalInstanceGroups (baseName , nodes )
274
+ require .NoError (t , err )
275
+
276
+ url , err := cloud .ParseResourceURL (igsFromCloud [0 ])
277
+ require .NoError (t , err )
278
+ instances , err := gce .ListInstancesInInstanceGroup (url .Key .Name , url .Key .Zone , "ALL" )
279
+ require .NoError (t , err )
280
+ assert .Len (t , instances , 2 , "Incorrect number of Instances in the group" )
281
+ var instanceURLs []string
282
+ for _ , inst := range instances {
283
+ instanceURLs = append (instanceURLs , inst .Instance )
284
+ }
285
+ if ! hasInstanceForNode (instances , nodes [0 ]) {
286
+ t .Errorf ("expected n1 to be in instances but it contained %+v" , instanceURLs )
287
+ }
288
+ if ! hasInstanceForNode (instances , nodes [1 ]) {
289
+ t .Errorf ("expected n2 to be in instances but it contained %+v" , instanceURLs )
290
+ }
291
+ }
292
+
293
+ func hasInstanceForNode (instances []* compute.InstanceWithNamedPorts , node * v1.Node ) bool {
294
+ for _ , instance := range instances {
295
+ if strings .HasSuffix (instance .Instance , node .Name ) {
296
+ return true
297
+ }
298
+ }
299
+ return false
300
+ }
301
+
302
+ func TestRemoveNodesInNonDefaultNetworks (t * testing.T ) {
303
+ t .Parallel ()
304
+
305
+ testInput := []struct {
306
+ node * v1.Node
307
+ shouldBeInDefaultSubnet bool
308
+ }{
309
+ {
310
+ node : & v1.Node {
311
+ ObjectMeta : metav1.ObjectMeta {
312
+ Name : "defaultSubnetNodeWithLabel" ,
313
+ Labels : map [string ]string {labelGKESubnetworkName : "defaultSubnet" },
314
+ },
315
+ },
316
+ shouldBeInDefaultSubnet : true ,
317
+ },
318
+ {
319
+ node : & v1.Node {
320
+ ObjectMeta : metav1.ObjectMeta {
321
+ Name : "nonDefaultSubnetNode" ,
322
+ Labels : map [string ]string {labelGKESubnetworkName : "secondarySubnet" },
323
+ },
324
+ },
325
+ shouldBeInDefaultSubnet : false ,
326
+ },
327
+ {
328
+ node : & v1.Node {
329
+ ObjectMeta : metav1.ObjectMeta {
330
+ Name : "defaultSubnetNodeWithEmptyLabel" ,
331
+ Labels : map [string ]string {labelGKESubnetworkName : "" },
332
+ },
333
+ },
334
+ shouldBeInDefaultSubnet : true ,
335
+ },
336
+ {
337
+ node : & v1.Node {
338
+ ObjectMeta : metav1.ObjectMeta {
339
+ Name : "defaultSubnetNodeWithoutLabel" ,
340
+ },
341
+ Spec : v1.NodeSpec {PodCIDR : "10.0.0.0/28" },
342
+ },
343
+ shouldBeInDefaultSubnet : true ,
344
+ },
345
+ {
346
+ node : & v1.Node {
347
+ ObjectMeta : metav1.ObjectMeta {
348
+ Name : "nodeInUnknownSubnet" ,
349
+ },
350
+ },
351
+ shouldBeInDefaultSubnet : false ,
352
+ },
353
+ }
354
+ var nodes []* v1.Node
355
+ for _ , testNode := range testInput {
356
+ nodes = append (nodes , testNode .node )
357
+ }
358
+
359
+ onlyDefaultSubnetNodes := removeNodesInNonDefaultNetworks (nodes , "defaultSubnet" )
360
+
361
+ defaultSubnetNodesSet := make (map [string ]struct {})
362
+ for _ , node := range onlyDefaultSubnetNodes {
363
+ defaultSubnetNodesSet [node .Name ] = struct {}{}
364
+ }
365
+ for _ , testNode := range testInput {
366
+ _ , hasNode := defaultSubnetNodesSet [testNode .node .Name ]
367
+ if testNode .shouldBeInDefaultSubnet != hasNode {
368
+ t .Errorf ("Node %s should not be in the default subnet but it was present in %v" , testNode .node .Name , defaultSubnetNodesSet )
369
+ }
370
+ }
371
+ }
372
+
202
373
func TestEnsureInternalLoadBalancer (t * testing.T ) {
203
374
t .Parallel ()
204
375
@@ -2017,3 +2188,48 @@ func TestEnsureInternalLoadBalancerAllPorts(t *testing.T) {
2017
2188
}
2018
2189
assertInternalLbResourcesDeleted (t , gce , svc , vals , true )
2019
2190
}
2191
+
2192
+ func TestSubnetNameFromURL (t * testing.T ) {
2193
+ cases := []struct {
2194
+ desc string
2195
+ url string
2196
+ wantName string
2197
+ wantErr bool
2198
+ }{
2199
+ {
2200
+ desc : "full URL" ,
2201
+ url : "https://www.googleapis.com/compute/v1/projects/project/regions/us-central1/subnetworks/defaultSubnet" ,
2202
+ wantName : "defaultSubnet" ,
2203
+ },
2204
+ {
2205
+ desc : "project path" ,
2206
+ url : "projects/project/regions/us-central1/subnetworks/defaultSubnet" ,
2207
+ wantName : "defaultSubnet" ,
2208
+ },
2209
+ {
2210
+ desc : "missing name" ,
2211
+ url : "projects/project/regions/us-central1/subnetworks" ,
2212
+ wantErr : true ,
2213
+ },
2214
+ {
2215
+ desc : "invalid" ,
2216
+ url : "invalid" ,
2217
+ wantErr : true ,
2218
+ },
2219
+ }
2220
+ for _ , tc := range cases {
2221
+ t .Run (tc .desc , func (t * testing.T ) {
2222
+ subnetName , err := subnetNameFromURL (tc .url )
2223
+ if err != nil && ! tc .wantErr {
2224
+ t .Errorf ("unexpected error %v" , err )
2225
+ }
2226
+ if err == nil && tc .wantErr {
2227
+ t .Errorf ("wanted an error but got none" )
2228
+ }
2229
+ if ! tc .wantErr && subnetName != tc .wantName {
2230
+ t .Errorf ("invalid name extracted from URL %s, want=%s, got=%s" , tc .url , tc .wantName , subnetName )
2231
+ }
2232
+ })
2233
+ }
2234
+
2235
+ }
0 commit comments