@@ -200,7 +200,124 @@ def push(self, resource: "Resource", *args: "Resource") -> "ResourceBundle":
200
200
self ._resources .append (self ._conform_resource (r ))
201
201
return self
202
202
203
- def unshift (self , resource : "Resource" ) -> "ResourceBundle" :
203
+ def insert (
204
+ self ,
205
+ index : int ,
206
+ resource : "Resource" ,
207
+ * args : "Resource" ,
208
+ ) -> "ResourceBundle" :
209
+ """
210
+ Inserts the specified resource(s) into the bundle's resources starting at
211
+ the specified index. Operates in the same fashion as `list.insert()` except
212
+ that multiple resources can be inserted in a single call.
213
+
214
+ :param index:
215
+ Index where the resource(s) should be inserted.
216
+ :param resource:
217
+ Resource to insert into the bundle at the specified index.
218
+ :param args:
219
+ Additional resources to insert into the bundle after the first specified
220
+ resource.
221
+ """
222
+ new_resources = [
223
+ self ._conform_resource (r )
224
+ for r in ([resource ] + list (args ))
225
+ if r not in self ._resources
226
+ ]
227
+
228
+ start_index = len (self ._resources ) + index if index < 0 else index
229
+ for i , r in enumerate (new_resources ):
230
+ self ._resources .insert (start_index + i , r )
231
+ return self
232
+
233
+ def insert_after (
234
+ self ,
235
+ previous_resource : typing .Optional ["Resource" ],
236
+ resource : "Resource" ,
237
+ * args : "Resource" ,
238
+ ) -> "ResourceBundle" :
239
+ """
240
+ Inserts the specified resource(s) into the bundle's resources after the
241
+ specified previous_resource, which should be a resource already within the
242
+ bundle or an IndexError will be raised. Like the `BundleResource.insert()`
243
+ method, multiple resources can be added.
244
+
245
+ :param previous_resource:
246
+ A resource already in this resource bundle that the new resources should
247
+ be added after. If this value is None the resource(s) will be added to
248
+ the top of the bundle.
249
+ :param resource:
250
+ Resource to insert into the bundle after the previous_resource.
251
+ :param args:
252
+ Additional resources to insert into the bundle after the first specified
253
+ resources.
254
+ """
255
+ if previous_resource is None :
256
+ return self .insert (0 , resource , * args )
257
+
258
+ index = self ._resources .index (previous_resource )
259
+ return self .insert (index + 1 , resource , * args )
260
+
261
+ def move_to (
262
+ self ,
263
+ index : int ,
264
+ resource : "Resource" ,
265
+ * args : "Resource" ,
266
+ ) -> "ResourceBundle" :
267
+ """
268
+ Moves the specified resource(s) already in the bundle to the index in the
269
+ same fashion as the `ResourceBundle.insert()` does for resources not
270
+ currently in the bundle.
271
+
272
+ :param index:
273
+ Index where the resource(s) should be re-inserted.
274
+ :param resource:
275
+ Resource to move within the bundle to the specified index.
276
+ :param args:
277
+ Additional resources to move within the bundle after the first specified
278
+ resource.
279
+ """
280
+ movers = [r for r in ([resource ] + list (args )) if r in self ._resources ]
281
+ target_position_resource = self ._resources [index ]
282
+ if target_position_resource in movers :
283
+ looker = (r for r in reversed (self ._resources [:index ]) if r not in movers )
284
+ target_position_resource = next (looker , None )
285
+
286
+ for m in movers :
287
+ self ._resources .remove (m )
288
+
289
+ if target_position_resource is None :
290
+ new_index = 0
291
+ else :
292
+ new_index = self ._resources .index (target_position_resource )
293
+ return self .insert (new_index , * movers )
294
+
295
+ def move_after (
296
+ self ,
297
+ previous_resource : "Resource" ,
298
+ resource : "Resource" ,
299
+ * args : "Resource" ,
300
+ ) -> "ResourceBundle" :
301
+ """
302
+ Moves the specified resource(s) already in the bundle to the position after the
303
+ specified previous_resource, which must also be a resource already within the
304
+ bundle or an IndexError will be raised. Like the `BundleResource.move_to()`
305
+ method, multiple resources can be added.
306
+
307
+ :param previous_resource:
308
+ A resource already in this resource bundle that the new resources should
309
+ be added after. If this value is None the resource(s) will be added to
310
+ the top of the bundle.
311
+ :param resource:
312
+ Resource to move within the bundle to the specified index.
313
+ :param args:
314
+ Additional resources to move within the bundle after the first specified
315
+ resource.
316
+ """
317
+ index = self ._resources .index (previous_resource )
318
+ return self .move_to (index + 1 , resource , * args )
319
+
320
+ def unshift (self , resource : "Resource" , * args : "Resource" ) -> "ResourceBundle" :
204
321
"""
205
322
Adds the specified resource to the beginning of the bundle's
206
323
resource list.
@@ -209,8 +326,12 @@ def unshift(self, resource: "Resource") -> "ResourceBundle":
209
326
Resource object to add to the bundle. It will be conformed to
210
327
the bundle's specifications and constraints upon insertion.
211
328
"""
212
- if resource not in self ._resources :
213
- self ._resources .insert (0 , self ._conform_resource (resource ))
329
+ resources = [r for r in ([resource ] + list (args )) if r not in self ._resources ]
330
+ # Reverse the list so we can add one after another to the top of the list
331
+ # to get the expected result.
332
+ resources .reverse ()
333
+ for r in resources :
334
+ self ._resources .insert (0 , self ._conform_resource (r ))
214
335
return self
215
336
216
337
def add (
@@ -220,6 +341,58 @@ def add(
220
341
Adds an empty resource of the specified type as the last entry
221
342
to the bundle's resources list.
222
343
344
+ :param api_version:
345
+ A standard Kubernetes configuration api version, e.g. "apps/v1".
346
+ :param kind:
347
+ The type of resource, e.g. "Deployment".
348
+ :param name:
349
+ Name to give the resource.
350
+ :param kwargs:
351
+ Labels to assign to the metadata of the new resource.
352
+ """
353
+ return self .add_at (0 , api_version , kind , name , ** kwargs )
354
+
355
+ def add_after (
356
+ self ,
357
+ previous_resource : "Resource" ,
358
+ api_version : str ,
359
+ kind : str ,
360
+ name : str ,
361
+ ** kwargs : str ,
362
+ ) -> "ResourceBundle" :
363
+ """
364
+ Adds an empty resource of the specified type after the specified
365
+ previous_resource, which must be a resource already in the bundle.
366
+
367
+ :param previous_resource:
368
+ A resource already in this resource bundle that the new resources should
369
+ be added after.
370
+ :param api_version:
371
+ A standard Kubernetes configuration api version, e.g. "apps/v1".
372
+ :param kind:
373
+ The type of resource, e.g. "Deployment".
374
+ :param name:
375
+ Name to give the resource.
376
+ :param kwargs:
377
+ Labels to assign to the metadata of the new resource.
378
+ """
379
+ index = self ._resources .index (previous_resource )
380
+ return self .add_at (index + 1 , api_version , kind , name , ** kwargs )
381
+
382
+ def add_at (
383
+ self ,
384
+ index : int ,
385
+ api_version : str ,
386
+ kind : str ,
387
+ name : str ,
388
+ ** kwargs : str ,
389
+ ) -> "ResourceBundle" :
390
+ """
391
+ Adds an empty resource of the specified type at the specified index within
392
+ the bundle.
393
+
394
+ :param index:
395
+ Index at which the resource should be added to the bundle's resources.
223
396
:param api_version:
224
397
A standard Kubernetes configuration api version, e.g. "apps/v1".
225
398
:param kind:
@@ -236,16 +409,70 @@ def add(
236
409
kubernetes_version = self .kubernetes_version ,
237
410
** kwargs ,
238
411
)
239
- if resource is None :
412
+ if resource is None : # pragma: no cover
240
413
raise ValueError (f"Unknown resource type { api_version } /{ kind } ." )
241
- return self .push ( resource )
414
+ return self .insert ( index , resource )
242
415
243
416
def new (self , api_version : str , kind : str , name : str , ** kwargs : str ) -> "Resource" :
244
417
"""
245
418
Adds an empty resource of the specified type as the last entry
246
419
to the bundle's resources list and returns that new Resource
247
420
for immediate configuration.
248
421
422
+ :param api_version:
423
+ A standard Kubernetes configuration api version, e.g. "apps/v1".
424
+ :param kind:
425
+ The type of resource, e.g. "Deployment".
426
+ :param name:
427
+ Name to give the resource.
428
+ :param kwargs:
429
+ Labels to assign to the metadata of the new resource.
430
+ """
431
+ return self .new_at (- 1 , api_version , kind , name , ** kwargs )
432
+
433
+ def new_after (
434
+ self ,
435
+ previous_resource : "Resource" ,
436
+ api_version : str ,
437
+ kind : str ,
438
+ name : str ,
439
+ ** kwargs : str ,
440
+ ) -> "Resource" :
441
+ """
442
+ Adds an empty resource of the specified type after the specified
443
+ previous_resource to the bundle's resources list and returns that new Resource
444
+ for immediate configuration.
445
+
446
+ :param previous_resource:
447
+ A resource already in this resource bundle that the new resources should
448
+ be added after.
449
+ :param api_version:
450
+ A standard Kubernetes configuration api version, e.g. "apps/v1".
451
+ :param kind:
452
+ The type of resource, e.g. "Deployment".
453
+ :param name:
454
+ Name to give the resource.
455
+ :param kwargs:
456
+ Labels to assign to the metadata of the new resource.
457
+ """
458
+ index = self ._resources .index (previous_resource )
459
+ return self .new_at (index + 1 , api_version , kind , name , ** kwargs )
460
+
461
+ def new_at (
462
+ self ,
463
+ index : int ,
464
+ api_version : str ,
465
+ kind : str ,
466
+ name : str ,
467
+ ** kwargs : str ,
468
+ ) -> "Resource" :
469
+ """
470
+ Adds an empty resource of the specified type at the specified index
471
+ within the bundle's resources list and returns that new Resource
472
+ for immediate configuration.
473
+
474
+ :param index:
475
+ Index within the bundle's resources to add the new resource.
249
476
:param api_version:
250
477
A standard Kubernetes configuration api version, e.g. "apps/v1".
251
478
:param kind:
@@ -262,9 +489,10 @@ def new(self, api_version: str, kind: str, name: str, **kwargs: str) -> "Resourc
262
489
kubernetes_version = self .kubernetes_version ,
263
490
** kwargs ,
264
491
)
265
- if resource is None :
492
+ if resource is None : # pragma: no cover
266
493
raise ValueError (f"Unknown resource type { api_version } /{ kind } ." )
267
- self .push (resource )
494
+
495
+ self .insert (index , resource )
268
496
return resource
269
497
270
498
def add_from_yaml (self , resource_definition : str ) -> "ResourceBundle" :
0 commit comments