34
34
import weakref
35
35
import re
36
36
37
- __version__ = '1.5.4 '
37
+ __version__ = '1.5.5 '
38
38
39
39
_LOGGER = logging .getLogger ('tftest' )
40
40
@@ -52,11 +52,13 @@ class TerraformTestError(Exception):
52
52
53
53
def parse_args (init_vars = None , tf_vars = None , targets = None , ** kw ):
54
54
"""Convert method arguments for use in Terraform commands.
55
+
55
56
Args:
56
57
init_vars: dict of key/values converted to -backend-config='k=v' form, or
57
58
string argument converted to -backend-config=arg
58
59
tf_vars: dict of key/values converted to -var k=v form.
59
60
**kw: converted to the appropriate Terraform flag.
61
+
60
62
Returns:
61
63
A list of command arguments for use with subprocess.
62
64
"""
@@ -140,6 +142,7 @@ def parse_args(init_vars=None, tf_vars=None, targets=None, **kw):
140
142
141
143
return cmd_args
142
144
145
+
143
146
class TerraformJSONBase (object ):
144
147
"Base class for JSON wrappers."
145
148
@@ -302,7 +305,7 @@ def _cleanup(cls, tfdir, filenames, binary, deep=True):
302
305
os .unlink (path )
303
306
if not deep :
304
307
return
305
-
308
+
306
309
if binary == 'terraform' :
307
310
path = os .path .join (tfdir , '.terraform' )
308
311
if os .path .isdir (path ):
@@ -315,51 +318,15 @@ def _cleanup(cls, tfdir, filenames, binary, deep=True):
315
318
if os .path .isdir (path ):
316
319
shutil .rmtree (path )
317
320
318
- def tg_global_doc (tg_func ):
319
- doc = """
320
- all: Runs Terragrunt command on all subfolders if True
321
- tg_config: Path to the Terragrunt config file. Default is terragrunt.hcl.
322
- tg_tfpath: Path to the Terraform binary. Default is terraform (on PATH).
323
- tg_no_auto_init: Don't automatically run 'terraform init' during other terragrunt commands.
324
- You must run 'terragrunt init' manually.
325
- tg_no_auto_retry: Don't automatically re-run command in case of transient errors.
326
- tg_non_interactive: Assume "yes" for all prompts.
327
- tg_working_dir: The path to the Terraform templates. Default is current directory.
328
- tg_download_dir: The path where to download Terraform code. Default is .terragrunt_cache in
329
- the working directory.
330
- tg_source: Download Terraform configurations from the specified source into a temporary folder,
331
- and run Terraform in that temporary folder.
332
- tg_source_update: Delete the contents of the temporary folder to clear out any old, cached
333
- source code before downloading new source code into it.
334
- tg_iam_role: Assume the specified IAM role before executing Terraform. Can also be set via the
335
- TERRAGRUNT_IAM_ROLE environment variable.
336
- tg_ignore_dependency_errors: *-all commands continue processing components even if a dependency
337
- fails.
338
- tg_ignore_dependency_order: *-all commands will be run disregarding the dependencies
339
- tg_ignore_external_dependencies: *-all commands will not attempt to include external
340
- dependencies
341
- tg_include_external_dependencies: *-all commands will include external dependencies
342
- tg_parallelism: *-all commands parallelism set to at most N modules
343
- tg_exclude_dir: Unix-style glob of directories to exclude when running *-all commands
344
- tg_include_dir: Unix-style glob of directories to include when running *-all commands
345
- tg_check: Enable check mode in the hclfmt command.
346
- tg_hclfmt_file: The path to a single terragrunt.hcl file that the hclfmt command should run on.
347
- tg_override_attr: A key=value attribute to override in a provider block as part of the
348
- aws-provider-patch command. May be specified multiple times.
349
- tg_debug: Write terragrunt_debug.tfvars to working folder to help root-cause issues.
350
- """
351
- tg_func .__doc__ += doc
352
- return tg_func
353
-
354
321
def _plan (self , all = False , output = False , ** kw ):
355
322
"""
356
- Run Terragrunt or Terraform plan command and optionally returning the plan output.
323
+ Run Terragrunt or Terraform plan and optionally return the plan output.
357
324
358
325
Args:
359
326
all: Runs Terragrunt command on all subfolders if True
360
327
output: Returns the output of the plan command
361
328
"""
362
-
329
+
363
330
cmd_args = parse_args (** kw )
364
331
365
332
if 'out' not in kw :
@@ -380,13 +347,13 @@ def _plan(self, all=False, output=False, **kw):
380
347
381
348
def _abspath (self , path ):
382
349
"""Make relative path absolute from base dir."""
383
-
350
+
384
351
# print(inspect.getdoc(self.setup))
385
352
return path if path .startswith ('/' ) else os .path .join (self ._basedir , path )
386
353
387
354
def setup (self , all = False , extra_files = None , plugin_dir = None , init_vars = None ,
388
- backend = True , cleanup_on_exit = True , tg_non_interactive = False ,
389
- tg_source_update = False , tg_config = None , tg_working_dir = None ,
355
+ backend = True , cleanup_on_exit = True , tg_non_interactive = False ,
356
+ tg_source_update = False , tg_config = None , tg_working_dir = None ,
390
357
** kw ):
391
358
"""Setup method to use in test fixtures.
392
359
@@ -423,29 +390,28 @@ def setup(self, all=False, extra_files=None, plugin_dir=None, init_vars=None,
423
390
_LOGGER .warning ('no such file {}' .format (link_src ))
424
391
self ._finalizer = weakref .finalize (
425
392
self , self ._cleanup , self .tfdir , filenames , self .binary , deep = cleanup_on_exit )
426
-
393
+
427
394
if self .binary == 'terragrunt' :
428
395
return self .tg_init (all = all , init_vars = init_vars ,
429
396
backend = backend , plugin_dir = plugin_dir ,
430
- tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
397
+ tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
431
398
tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
432
399
433
400
return self .tf_init (plugin_dir = plugin_dir , init_vars = init_vars , backend = backend )
434
-
401
+
435
402
def tf_init (self , input = False , no_color = True , plugin_dir = None ,
436
- init_vars = None , backend = True ):
403
+ init_vars = None , backend = True ):
437
404
"""Run Terraform or Terragrunt init command."""
438
- cmd_args = parse_args (input = input , no_color = no_color ,
405
+ cmd_args = parse_args (input = input , no_color = no_color ,
439
406
backend = backend , plugin_dir = plugin_dir ,
440
407
init_vars = init_vars )
441
408
return self .execute_command ('init' , * cmd_args ).out
442
409
443
- @tg_global_doc
444
410
def tg_init (self , all = False , input = False , no_color = True , plugin_dir = None ,
445
- init_vars = None , backend = True , tg_non_interactive = True ,
411
+ init_vars = None , backend = True , tg_non_interactive = True ,
446
412
tg_source_update = False , tg_config = None , tg_working_dir = None , ** kw ):
447
413
"""Run Terragrunt init command."""
448
- cmd_args = parse_args (input = input , no_color = no_color ,
414
+ cmd_args = parse_args (input = input , no_color = no_color ,
449
415
backend = backend , plugin_dir = plugin_dir ,
450
416
init_vars = init_vars , tg_non_interactive = tg_non_interactive ,
451
417
tg_source_update = tg_source_update , tg_config = tg_config ,
@@ -455,48 +421,47 @@ def tg_init(self, all=False, input=False, no_color=True, plugin_dir=None,
455
421
else :
456
422
return self .execute_command ('init' , * cmd_args ).out
457
423
458
- def tf_validate (self , no_color = True , json = None ):
424
+ def validate (self , no_color = True , json = None ):
459
425
"""Run Terraform or Terragrunt validate command."""
460
426
cmd_args = parse_args (no_color = True , json = None )
461
427
return self .execute_command ('validate' , * cmd_args ).out
462
428
463
- @tg_global_doc
464
- def tg_validate (self , no_color = True , json = None , tg_non_interactive = True ,
429
+ def tg_validate (self , no_color = True , json = None , tg_non_interactive = True ,
465
430
tg_source_update = False , tg_config = None , tg_working_dir = None , ** kw ):
466
431
"""Run Terragrunt validate command."""
467
- cmd_args = parse_args (no_color = no_color , json = json , tg_non_interactive = tg_non_interactive ,
468
- tg_source_update = tg_source_update , tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
432
+ cmd_args = parse_args (no_color = no_color , json = json , tg_non_interactive = tg_non_interactive ,
433
+ tg_source_update = tg_source_update , tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
469
434
if all :
470
435
return self .execute_command ('run-all' , 'validate' , * cmd_args ).out
471
436
else :
472
437
return self .execute_command ('validate' , * cmd_args ).out
473
438
474
- def tf_plan (self , input = False , no_color = True , refresh = True , tf_vars = None , targets = None , output = False , tf_var_file = None ):
439
+ def plan (self , input = False , no_color = True , refresh = True , tf_vars = None ,
440
+ targets = None , output = False , tf_var_file = None ):
475
441
"""
476
442
Run Terraform plan command, optionally returning parsed plan output.
477
443
478
444
Args:
479
445
input: Ask for input for variables if not directly set.
480
446
no_color: If specified, output won't contain any color.
481
447
refresh: Update state prior to checking for differences.
482
- tf_vars: Dict of variables in the Terraform configuration.
483
- targets: List of resources to target. Operation will be limited to this resource
448
+ tf_vars: Dict of variables in the Terraform configuration.
449
+ targets: List of resources to target. Operation will be limited to this resource
484
450
and its dependencies
485
- output: Determines if output will be returned.
451
+ output: Determines if output will be returned.
486
452
tf_var_file: Path to terraform variable configuration file relative to `self.tfdir`.
487
- """
488
- result = self ._plan ('plan' , input = input , no_color = no_color , refresh = refresh ,
453
+ """
454
+ result = self ._plan ('plan' , input = input , no_color = no_color , refresh = refresh ,
489
455
tf_vars = tf_vars , targets = targets , output = output , tf_var_file = tf_var_file )
490
456
491
457
try :
492
458
return TerraformPlanOutput (json .loads (result .out ))
493
459
except json .JSONDecodeError as e :
494
460
raise TerraformTestError ('Error decoding plan output: {}' .format (e ))
495
-
496
- @tg_global_doc
461
+
497
462
def tg_plan (self , all = False , input = False , no_color = True , refresh = True ,
498
- tf_vars = None , targets = None , output = False , tf_var_file = None ,
499
- tg_non_interactive = True , tg_source_update = False , tg_config = None ,
463
+ tf_vars = None , targets = None , output = False , tf_var_file = None ,
464
+ tg_non_interactive = True , tg_source_update = False , tg_config = None ,
500
465
tg_working_dir = None , ** kw ):
501
466
"""
502
467
Run Terragrunt plan command, optionally returning parsed plan output.
@@ -505,29 +470,29 @@ def tg_plan(self, all=False, input=False, no_color=True, refresh=True,
505
470
input: Ask for input for variables if not directly set.
506
471
no_color: If specified, output won't contain any color.
507
472
refresh: Update state prior to checking for differences.
508
- tf_vars: Dict of variables in the Terraform configuration.
509
- targets: List of resources to target. Operation will be limited to this resource
473
+ tf_vars: Dict of variables in the Terraform configuration.
474
+ targets: List of resources to target. Operation will be limited to this resource
510
475
and its dependencies
511
- output: Determines if output will be returned.
476
+ output: Determines if output will be returned.
512
477
tf_var_file: Path to terraform variable configuration file relative to `self.tfdir`.
513
478
"""
514
479
result = self ._plan (all = all , output = output ,
515
- input = input , no_color = no_color ,
516
- refresh = refresh , tf_vars = tf_vars ,
480
+ input = input , no_color = no_color ,
481
+ refresh = refresh , tf_vars = tf_vars ,
517
482
targets = targets , tf_var_file = tf_var_file ,
518
- tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
483
+ tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
519
484
tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
520
485
if not output :
521
486
return result
522
487
523
488
if all :
524
- #TODO: Find better way to parse result other than regex
489
+ # TODO: Find better way to parse result other than regex
525
490
plans = re .split ('\n (?=\\ {"format_version"\\ :)' , result .out )
526
491
plan_output = []
527
492
for plan in plans :
528
493
try :
529
- out = TerraformPlanOutput (json .loads (plan ))
530
- #TODO: Find a way to distinguish each plan from each other (couldn't find an attr in `out` to use as a key to pair with `out` value)
494
+ out = TerraformPlanOutput (json .loads (plan ))
495
+ # TODO: Find a way to distinguish each plan from each other (couldn't find an attr in `out` to use as a key to pair with `out` value)
531
496
# for now returns list of tftest.TerraformPlanModule objects
532
497
plan_output .append (out )
533
498
except json .JSONDecodeError as e :
@@ -539,44 +504,44 @@ def tg_plan(self, all=False, input=False, no_color=True, refresh=True,
539
504
except json .JSONDecodeError as e :
540
505
raise TerraformTestError ('Error decoding plan output: {}' .format (e ))
541
506
542
- def tf_apply (self , input = False , no_color = True , auto_approve = True , tf_vars = None , targets = None , tf_var_file = None ):
507
+ def apply (self , input = False , no_color = True , auto_approve = True ,
508
+ tf_vars = None , targets = None , tf_var_file = None ):
543
509
"""
544
510
Run Terraform apply command.
545
-
511
+
546
512
Args:
547
513
input: Ask for input for variables if not directly set.
548
514
no_color: If specified, output won't contain any color.
549
515
auto_approve: Skip interactive approval of plan before applying.
550
- tf_vars: Dict of variables in the Terraform configuration.
551
- targets: List of resources to target. Operation will be limited to this resource
516
+ tf_vars: Dict of variables in the Terraform configuration.
517
+ targets: List of resources to target. Operation will be limited to this resource
552
518
and its dependencies
553
519
tf_var_file: Path to terraform variable configuration file relative to `self.tfdir`.
554
520
"""
555
- cmd_args = parse_args (input = input , no_color = no_color ,
556
- auto_approve = auto_approve , tf_vars = tf_vars ,
521
+ cmd_args = parse_args (input = input , no_color = no_color ,
522
+ auto_approve = auto_approve , tf_vars = tf_vars ,
557
523
targets = targets , tf_var_file = tf_var_file )
558
524
return self .execute_command ('apply' , * cmd_args ).out
559
525
560
- @tg_global_doc
561
- def tg_apply (self , all = False , input = False , no_color = True , auto_approve = True , tf_vars = None ,
562
- targets = None , tf_var_file = None , tg_non_interactive = True ,
526
+ def tg_apply (self , all = False , input = False , no_color = True , auto_approve = True , tf_vars = None ,
527
+ targets = None , tf_var_file = None , tg_non_interactive = True ,
563
528
tg_source_update = False , tg_config = None , tg_working_dir = None , ** kw ):
564
529
"""
565
530
Run Terragrunt apply command.
566
-
531
+
567
532
Args:
568
533
input: Ask for input for variables if not directly set.
569
534
no_color: If specified, output won't contain any color.
570
535
auto_approve: Skip interactive approval of plan before applying.
571
- tf_vars: Dict of variables in the Terraform configuration.
572
- targets: List of resources to target. Operation will be limited to this resource
536
+ tf_vars: Dict of variables in the Terraform configuration.
537
+ targets: List of resources to target. Operation will be limited to this resource
573
538
and its dependencies
574
539
tf_var_file: Path to terraform variable configuration file relative to `self.tfdir`.
575
540
"""
576
- cmd_args = parse_args (input = input , no_color = no_color ,
577
- auto_approve = auto_approve , tf_vars = tf_vars ,
541
+ cmd_args = parse_args (input = input , no_color = no_color ,
542
+ auto_approve = auto_approve , tf_vars = tf_vars ,
578
543
targets = targets , tf_var_file = tf_var_file ,
579
- tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
544
+ tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
580
545
tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
581
546
582
547
if all :
@@ -588,33 +553,35 @@ def _output(self, all=False, name=None, **kw):
588
553
cmd_args = parse_args (** kw )
589
554
if name :
590
555
cmd_args .append (name )
591
-
556
+
592
557
if all :
593
558
output = self .execute_command ('run-all' , 'output' , * cmd_args ).out
594
559
else :
595
560
output = self .execute_command ('output' , * cmd_args ).out
596
561
return output
597
562
598
- def tf_output (self , name = None , no_color = True , json_format = True ):
563
+ def output (self , name = None , no_color = True , json_format = True ):
599
564
"""Run Terraform output command."""
600
- output = self ._output (name = name , no_color = no_color , json_format = json_format )
565
+ output = self ._output (name = name , no_color = no_color ,
566
+ json_format = json_format )
601
567
_LOGGER .debug ('output %s' , output )
602
568
if json_format :
603
569
try :
604
570
output = TerraformValueDict (json .loads (output ))
605
571
except json .JSONDecodeError as e :
606
572
_LOGGER .warning ('error decoding output: {}' .format (e ))
607
573
return output
608
-
609
- def tg_output (self , all = False , name = None , no_color = True , json_format = True ,
610
- tg_non_interactive = True , tg_source_update = False , tg_config = None ,
574
+
575
+ def tg_output (self , all = False , name = None , no_color = True , json_format = True ,
576
+ tg_non_interactive = True , tg_source_update = False , tg_config = None ,
611
577
tg_working_dir = None , ** kw ):
612
578
"""Run Terragrunt output command."""
613
579
output = self ._output (all = all , name = name , no_color = no_color , json_format = json_format ,
614
- tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
580
+ tg_non_interactive = tg_non_interactive , tg_source_update = tg_source_update ,
615
581
tg_config = tg_config , tg_working_dir = tg_working_dir , ** kw )
616
-
617
- # TODO: Figure out how to parse terragrunt run-all output command to return dict of {directory: output}
582
+
583
+ # TODO: Figure out how to parse terragrunt run-all output command to return
584
+ # dict of {directory: output}
618
585
_LOGGER .debug ('output %s' , output )
619
586
try :
620
587
output = TerraformValueDict (json .loads (output ))
0 commit comments