tfwrapper 0.4.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -59,6 +59,8 @@ describe TFWrapper::RakeTasks do
59
59
  expect(cls.instance_variable_get('@tf_dir')).to eq('/rake/dir/tfdir')
60
60
  expect(cls.instance_variable_get('@consul_env_vars_prefix')).to eq(nil)
61
61
  expect(cls.instance_variable_get('@tf_vars_from_env')).to eq({})
62
+ expect(cls.instance_variable_get('@allowed_empty_vars')).to eq([])
63
+ expect(cls.instance_variable_get('@tf_sensitive_vars')).to eq([])
62
64
  expect(cls.instance_variable_get('@tf_extra_vars')).to eq({})
63
65
  expect(cls.instance_variable_get('@backend_config')).to eq({})
64
66
  expect(cls.instance_variable_get('@consul_url')).to eq(nil)
@@ -66,6 +68,8 @@ describe TFWrapper::RakeTasks do
66
68
  .to eq(Gem::Version.new('0.0.0'))
67
69
  expect(cls.instance_variable_get('@before_proc')).to eq(nil)
68
70
  expect(cls.instance_variable_get('@after_proc')).to eq(nil)
71
+ expect(cls.instance_variable_get('@disable_landscape')).to eq(false)
72
+ expect(cls.instance_variable_get('@landscape_progress')).to eq(nil)
69
73
  end
70
74
  it 'sets options' do
71
75
  allow(ENV).to receive(:[])
@@ -85,10 +89,14 @@ describe TFWrapper::RakeTasks do
85
89
  'tf/dir',
86
90
  consul_env_vars_prefix: 'cvprefix',
87
91
  tf_vars_from_env: { 'foo' => 'bar' },
92
+ allowed_empty_vars: %w[bar blam],
93
+ tf_sensitive_vars: %w[secret],
88
94
  tf_extra_vars: { 'baz' => 'blam' },
89
95
  consul_url: 'foobar',
90
96
  before_proc: bproc,
91
- after_proc: aproc
97
+ after_proc: aproc,
98
+ disable_landscape: true,
99
+ landscape_progress: :dots
92
100
  )
93
101
  expect(cls.instance_variable_get('@tf_dir'))
94
102
  .to eq('/path/to/tf/dir')
@@ -96,12 +104,18 @@ describe TFWrapper::RakeTasks do
96
104
  .to eq('cvprefix')
97
105
  expect(cls.instance_variable_get('@tf_vars_from_env'))
98
106
  .to eq('foo' => 'bar')
107
+ expect(cls.instance_variable_get('@allowed_empty_vars'))
108
+ .to eq(%w[bar blam])
109
+ expect(cls.instance_variable_get('@tf_sensitive_vars'))
110
+ .to eq(%w[secret])
99
111
  expect(cls.instance_variable_get('@tf_extra_vars'))
100
112
  .to eq('baz' => 'blam')
101
113
  expect(cls.instance_variable_get('@backend_config')).to eq({})
102
114
  expect(cls.instance_variable_get('@consul_url')).to eq('foobar')
103
115
  expect(cls.instance_variable_get('@before_proc')).to eq(bproc)
104
116
  expect(cls.instance_variable_get('@after_proc')).to eq(aproc)
117
+ expect(cls.instance_variable_get('@disable_landscape')).to eq(true)
118
+ expect(cls.instance_variable_get('@landscape_progress')).to eq(:dots)
105
119
  end
106
120
  context 'when before_proc is not a proc or nil' do
107
121
  it 'raises an error' do
@@ -120,6 +134,23 @@ describe TFWrapper::RakeTasks do
120
134
  )
121
135
  end
122
136
  end
137
+ context 'when landscape_progress is an invalid value' do
138
+ it 'raises an error' do
139
+ allow(ENV).to receive(:[])
140
+ allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
141
+ allow(ENV).to receive(:[]).with('ENVIRONMENT').and_return('myenv')
142
+ allow(ENV).to receive(:[]).with('PROJECT').and_return('myproj')
143
+ allow(Rake.application).to receive(:rakefile)
144
+ .and_return('/rake/dir/Rakefile')
145
+ allow(File).to receive(:realpath) { |p| p.sub('../', '') }
146
+ allow(File).to receive(:file?).and_return(true)
147
+ expect { TFWrapper::RakeTasks.new('tfdir', landscape_progress: :foo) }
148
+ .to raise_error(
149
+ ArgumentError,
150
+ /landscape_progress option must be one of:/
151
+ )
152
+ end
153
+ end
123
154
  context 'when after_proc is not a proc or nil' do
124
155
  it 'raises an error' do
125
156
  allow(Rake.application).to receive(:original_dir)
@@ -294,6 +325,7 @@ describe TFWrapper::RakeTasks do
294
325
  .to eq(Gem::Version.new('0.0.0'))
295
326
  vars = { foo: 'bar', baz: 'blam' }
296
327
  subject.instance_variable_set('@tf_vars_from_env', vars)
328
+ subject.instance_variable_set('@allowed_empty_vars', ['bar'])
297
329
  allow(TFWrapper::Helpers).to receive(:check_env_vars)
298
330
  allow(ENV).to receive(:[])
299
331
  subject.instance_variable_set(
@@ -306,7 +338,7 @@ describe TFWrapper::RakeTasks do
306
338
  allow(subject).to receive(:check_tf_version)
307
339
  .and_return(Gem::Version.new('0.9.5'))
308
340
  expect(TFWrapper::Helpers)
309
- .to receive(:check_env_vars).once.ordered.with(vars.values)
341
+ .to receive(:check_env_vars).once.ordered.with(vars.values, ['bar'])
310
342
  expect(subject).to receive(:check_tf_version).once.ordered
311
343
  expect(subject).to receive(:terraform_runner).once.ordered
312
344
  .with('terraform init -input=false '\
@@ -328,7 +360,7 @@ describe TFWrapper::RakeTasks do
328
360
  allow(subject).to receive(:check_tf_version)
329
361
  .and_return(Gem::Version.new('0.10.2'))
330
362
  expect(TFWrapper::Helpers)
331
- .to receive(:check_env_vars).once.ordered.with(vars.values)
363
+ .to receive(:check_env_vars).once.ordered.with(vars.values, [])
332
364
  expect(subject).to receive(:check_tf_version).once.ordered
333
365
  expect(subject).to receive(:terraform_runner).once.ordered
334
366
  .with('terraform init -input=false')
@@ -377,6 +409,7 @@ describe TFWrapper::RakeTasks do
377
409
  before(:each) do
378
410
  Rake::Task.clear
379
411
  Rake.application = Rake::Application.new
412
+ allow(subject).to receive(:landscape_format)
380
413
  end
381
414
  after(:each) do
382
415
  Rake.application = rake_application
@@ -392,33 +425,107 @@ describe TFWrapper::RakeTasks do
392
425
  expect(Rake.application['tf:plan'].arg_names).to eq([:target])
393
426
  end
394
427
  it 'runs the plan command with no targets' do
428
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
395
429
  Rake.application['tf:plan'].clear_prerequisites
396
430
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
397
431
  allow(subject).to receive(:terraform_runner)
398
432
  expect(subject).to receive(:terraform_runner).once
399
- .with('terraform plan -var-file file.tfvars.json')
433
+ .with('terraform plan -var-file file.tfvars.json', progress: nil)
400
434
  Rake.application['tf:plan'].invoke
401
435
  end
402
436
  it 'runs the plan command with one target' do
437
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
403
438
  Rake.application['tf:plan'].clear_prerequisites
404
439
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
405
440
  allow(subject).to receive(:terraform_runner)
406
441
  expect(subject).to receive(:terraform_runner).once
407
442
  .with('terraform plan -var-file file.tfvars.json ' \
408
- '-target tar.get[1]')
443
+ '-target tar.get[1]', progress: nil)
409
444
  Rake.application['tf:plan'].invoke('tar.get[1]')
410
445
  end
411
446
  it 'runs the plan command with three targets' do
447
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
412
448
  Rake.application['tf:plan'].clear_prerequisites
413
449
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
414
450
  allow(subject).to receive(:terraform_runner)
415
451
  expect(subject).to receive(:terraform_runner).once
416
452
  .with('terraform plan -var-file file.tfvars.json ' \
417
- '-target tar.get[1] -target t.gt[2] -target my.target[3]')
453
+ '-target tar.get[1] -target t.gt[2] -target my.target[3]',
454
+ progress: nil)
418
455
  Rake.application['tf:plan'].invoke(
419
456
  'tar.get[1]', 't.gt[2]', 'my.target[3]'
420
457
  )
421
458
  end
459
+ context 'with terraform_landscape available and enabled' do
460
+ before(:each) do
461
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
462
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
463
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
464
+ end
465
+ it 'runs plan with default progress type' do
466
+ Rake.application['tf:plan'].clear_prerequisites
467
+ expect(subject).to receive(:terraform_runner).once
468
+ .with('terraform plan -var-file file.tfvars.json', progress: nil)
469
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
470
+ Rake.application['tf:plan'].invoke
471
+ end
472
+ it 'runs plan with dots progress type' do
473
+ Rake.application['tf:plan'].clear_prerequisites
474
+ subject.instance_variable_set('@landscape_progress', :dots)
475
+ expect(subject).to receive(:terraform_runner).once
476
+ .with('terraform plan -var-file file.tfvars.json', progress: :dots)
477
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
478
+ Rake.application['tf:plan'].invoke
479
+ end
480
+ it 'runs plan with lines progress type' do
481
+ Rake.application['tf:plan'].clear_prerequisites
482
+ subject.instance_variable_set('@landscape_progress', :lines)
483
+ expect(subject).to receive(:terraform_runner).once
484
+ .with('terraform plan -var-file file.tfvars.json', progress: :lines)
485
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
486
+ Rake.application['tf:plan'].invoke
487
+ end
488
+ it 'runs plan with stream progress type' do
489
+ Rake.application['tf:plan'].clear_prerequisites
490
+ subject.instance_variable_set('@landscape_progress', :stream)
491
+ expect(subject).to receive(:terraform_runner).once
492
+ .with('terraform plan -var-file file.tfvars.json',
493
+ progress: :stream)
494
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
495
+ Rake.application['tf:plan'].invoke
496
+ end
497
+ end
498
+ context 'with terraform_landscape unavailable' do
499
+ it 'runs plan with stream progress and does not run landscape' do
500
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', false)
501
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
502
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
503
+
504
+ Rake.application['tf:plan'].clear_prerequisites
505
+ expect(subject).to receive(:terraform_runner).once
506
+ .with(
507
+ 'terraform plan -var-file file.tfvars.json', progress: :stream
508
+ )
509
+ expect(subject).to_not receive(:landscape_format)
510
+ Rake.application['tf:plan'].invoke
511
+ end
512
+ end
513
+ context 'with terraform_landscape available but disabled' do
514
+ it 'runs plan with stream progress and does not run landscape' do
515
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
516
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
517
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
518
+
519
+ subject.instance_variable_set('@disable_landscape', true)
520
+ Rake.application['tf:plan'].clear_prerequisites
521
+ expect(subject).to receive(:terraform_runner).once
522
+ .with(
523
+ 'terraform plan -var-file file.tfvars.json', progress: :stream
524
+ )
525
+ expect(subject).to_not receive(:landscape_format)
526
+ Rake.application['tf:plan'].invoke
527
+ end
528
+ end
422
529
  it 'calls before_proc if not nil' do
423
530
  Rake.application['tf:plan'].clear_prerequisites
424
531
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
@@ -729,6 +836,7 @@ describe TFWrapper::RakeTasks do
729
836
  Rake.application = rake_application
730
837
  end
731
838
  before do
839
+ subject.instance_variable_set('@tf_sensitive_vars', ['secret'])
732
840
  subject.install_write_tf_vars
733
841
  end
734
842
 
@@ -741,7 +849,8 @@ describe TFWrapper::RakeTasks do
741
849
  vars = {
742
850
  'foo' => 'bar',
743
851
  'baz' => 'blam',
744
- 'aws_access_key' => 'ak'
852
+ 'aws_access_key' => 'ak',
853
+ 'secret' => 'abc'
745
854
  }
746
855
  allow(subject).to receive(:terraform_vars).and_return(vars)
747
856
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
@@ -753,6 +862,8 @@ describe TFWrapper::RakeTasks do
753
862
  expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
754
863
  expect(STDOUT).to receive(:puts)
755
864
  .once.with('aws_access_key => (redacted)')
865
+ expect(STDOUT).to receive(:puts)
866
+ .once.with('secret => (redacted)')
756
867
  expect(STDOUT).to receive(:puts).once.with('baz => blam')
757
868
  expect(STDOUT).to receive(:puts).once.with('foo => bar')
758
869
  expect(File).to receive(:open).once.with('file.tfvars.json', 'w')
@@ -814,6 +925,7 @@ describe TFWrapper::RakeTasks do
814
925
  Rake.application = rake_application
815
926
  end
816
927
  before do
928
+ subject.instance_variable_set('@tf_sensitive_vars', ['secret'])
817
929
  subject.instance_variable_set('@ns_prefix', 'foo')
818
930
  subject.install_write_tf_vars
819
931
  end
@@ -827,7 +939,8 @@ describe TFWrapper::RakeTasks do
827
939
  vars = {
828
940
  'foo' => 'bar',
829
941
  'baz' => 'blam',
830
- 'aws_access_key' => 'ak'
942
+ 'aws_access_key' => 'ak',
943
+ 'secret' => 'abc'
831
944
  }
832
945
  allow(subject).to receive(:terraform_vars).and_return(vars)
833
946
  allow(subject).to receive(:var_file_path)
@@ -840,6 +953,8 @@ describe TFWrapper::RakeTasks do
840
953
  expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
841
954
  expect(STDOUT).to receive(:puts)
842
955
  .once.with('aws_access_key => (redacted)')
956
+ expect(STDOUT).to receive(:puts)
957
+ .once.with('secret => (redacted)')
843
958
  expect(STDOUT).to receive(:puts).once.with('baz => blam')
844
959
  expect(STDOUT).to receive(:puts).once.with('foo => bar')
845
960
  expect(File).to receive(:open).once.with('foo_file.tfvars.json', 'w')
@@ -1003,20 +1118,102 @@ describe TFWrapper::RakeTasks do
1003
1118
  )
1004
1119
  end
1005
1120
  end
1121
+ describe '#landscape_format', if: HAVE_LANDSCAPE do
1122
+ before(:each) do
1123
+ allow(STDERR).to receive(:puts)
1124
+ allow(STDOUT).to receive(:puts)
1125
+ end
1126
+ context 'when no exception is raised' do
1127
+ it 'processes the string through TerraformLandscape' do
1128
+ dbl_printer = double
1129
+ dbl_output = double
1130
+ allow(TerraformLandscape::Printer)
1131
+ .to receive(:new).and_return(dbl_printer)
1132
+ allow(TerraformLandscape::Output)
1133
+ .to receive(:new).and_return(dbl_output)
1134
+ allow(dbl_printer).to receive(:process_string)
1135
+
1136
+ expect(TerraformLandscape::Output)
1137
+ .to receive(:new).once.with(STDOUT)
1138
+ expect(TerraformLandscape::Printer)
1139
+ .to receive(:new).once.with(dbl_output)
1140
+ expect(dbl_printer).to receive(:process_string).once.with('PlanOutput')
1141
+ expect(STDERR).to_not receive(:puts)
1142
+ expect(STDOUT).to_not receive(:puts)
1143
+ subject.landscape_format('PlanOutput')
1144
+ end
1145
+ end
1146
+ context 'when an exception is raised' do
1147
+ context 'and landscape_progress is :stream' do
1148
+ it 'prints an error message' do
1149
+ dbl_printer = double
1150
+ dbl_output = double
1151
+ allow(TerraformLandscape::Printer)
1152
+ .to receive(:new).and_return(dbl_printer)
1153
+ allow(TerraformLandscape::Output)
1154
+ .to receive(:new).and_return(dbl_output)
1155
+ allow(dbl_printer).to receive(:process_string)
1156
+ .and_raise(RuntimeError, 'FooError')
1157
+
1158
+ expect(TerraformLandscape::Output)
1159
+ .to receive(:new).once.with(STDOUT)
1160
+ expect(TerraformLandscape::Printer)
1161
+ .to receive(:new).once.with(dbl_output)
1162
+ expect(dbl_printer)
1163
+ .to receive(:process_string).once.with('PlanOutput')
1164
+ expect(STDERR).to receive(:puts).once
1165
+ .with(
1166
+ 'Exception calling terraform_landscape to reformat output: ' \
1167
+ 'RuntimeError: FooError'
1168
+ )
1169
+ expect(STDOUT).to_not receive(:puts)
1170
+ subject.instance_variable_set('@landscape_progress', :stream)
1171
+ subject.landscape_format('PlanOutput')
1172
+ end
1173
+ end
1174
+ context 'and landscape_progress is not :stream' do
1175
+ it 'prints an error message and then the output' do
1176
+ dbl_printer = double
1177
+ dbl_output = double
1178
+ allow(TerraformLandscape::Printer)
1179
+ .to receive(:new).and_return(dbl_printer)
1180
+ allow(TerraformLandscape::Output)
1181
+ .to receive(:new).and_return(dbl_output)
1182
+ allow(dbl_printer).to receive(:process_string)
1183
+ .and_raise(RuntimeError, 'FooError')
1184
+
1185
+ expect(TerraformLandscape::Output)
1186
+ .to receive(:new).once.with(STDOUT)
1187
+ expect(TerraformLandscape::Printer)
1188
+ .to receive(:new).once.with(dbl_output)
1189
+ expect(dbl_printer)
1190
+ .to receive(:process_string).once.with('PlanOutput')
1191
+ expect(STDERR).to receive(:puts).once
1192
+ .with(
1193
+ 'Exception calling terraform_landscape to reformat output: ' \
1194
+ 'RuntimeError: FooError'
1195
+ )
1196
+ expect(STDOUT).to receive(:puts).once.with('PlanOutput')
1197
+ subject.instance_variable_set('@landscape_progress', nil)
1198
+ subject.landscape_format('PlanOutput')
1199
+ end
1200
+ end
1201
+ end
1202
+ end
1006
1203
  describe '#terraform_runner' do
1007
1204
  before do
1008
1205
  Retries.sleep_enabled = false
1009
1206
  end
1010
1207
  it 'outputs nothing and succeeds when command succeeds' do
1011
1208
  allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1012
- .with(any_args).and_return(['', 0])
1209
+ .with(any_args).and_return(['MyOutput', 0])
1013
1210
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1014
- .once.with('foo', 'tfdir')
1211
+ .once.with('foo', 'tfdir', progress: :stream)
1015
1212
  expect(STDERR).to receive(:puts).once
1016
1213
  .with("terraform_runner command: 'foo' (in tfdir)")
1017
1214
  expect(STDERR).to receive(:puts).once
1018
1215
  .with("terraform_runner command 'foo' finished and exited 0")
1019
- subject.terraform_runner('foo')
1216
+ expect(subject.terraform_runner('foo')).to eq('MyOutput')
1020
1217
  end
1021
1218
  it 'retries if needed' do
1022
1219
  @times_called = 0
@@ -1027,7 +1224,7 @@ describe TFWrapper::RakeTasks do
1027
1224
  end
1028
1225
 
1029
1226
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1030
- .exactly(2).times.with('foo', 'tfdir')
1227
+ .exactly(2).times.with('foo', 'tfdir', progress: :stream)
1031
1228
  expect(STDERR).to receive(:puts).once
1032
1229
  .with("terraform_runner command: 'foo' (in tfdir)")
1033
1230
  expect(STDERR).to receive(:puts).once
@@ -1044,23 +1241,25 @@ describe TFWrapper::RakeTasks do
1044
1241
  if @times_called < 3
1045
1242
  ['foo Throttling bar', 2]
1046
1243
  else
1047
- ['', 0]
1244
+ ['out', 0]
1048
1245
  end
1049
1246
  end
1050
1247
 
1051
1248
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1052
- .exactly(3).times.with('foo', 'tfdir')
1249
+ .exactly(3).times.with('foo', 'tfdir', progress: :stream)
1053
1250
  expect(STDERR).to receive(:puts).once
1054
1251
  .with("terraform_runner command: 'foo' (in tfdir)")
1055
1252
  expect(STDERR).to receive(:puts).once
1056
- .with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
1253
+ .with(/terraform_runner\sfailed\swith\sfoo\sThrottling\sbar\s+
1254
+ Terraform\shit\sAWS\sAPI\srate\s
1057
1255
  limiting;\sretry\sattempt\s1;\s.+\sseconds\shave\spassed\./x)
1058
1256
  expect(STDERR).to receive(:puts).once
1059
- .with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
1257
+ .with(/terraform_runner\sfailed\swith\sfoo\sThrottling\sbar\s+
1258
+ Terraform\shit\sAWS\sAPI\srate\s
1060
1259
  limiting;\sretry\sattempt\s2;\s.+\sseconds\shave\spassed\./x)
1061
1260
  expect(STDERR).to receive(:puts).once
1062
1261
  .with("terraform_runner command 'foo' finished and exited 0")
1063
- subject.terraform_runner('foo')
1262
+ expect(subject.terraform_runner('foo')).to eq('out')
1064
1263
  end
1065
1264
  it 'retries if status code 403' do
1066
1265
  @times_called = 0
@@ -1074,20 +1273,22 @@ describe TFWrapper::RakeTasks do
1074
1273
  end
1075
1274
 
1076
1275
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1077
- .exactly(3).times.with('foo', 'tfdir')
1276
+ .exactly(3).times.with('foo', 'tfdir', progress: :dots)
1078
1277
  expect(STDERR).to receive(:puts).once
1079
1278
  .with("terraform_runner command: 'foo' (in tfdir)")
1080
1279
  expect(STDERR).to receive(:puts).once
1081
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
1280
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s403\sbar\s+
1281
+ Terraform\scommand\sgot\s403\s
1082
1282
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1083
1283
  attempt\s1;\s.+\sseconds\shave\spassed\./x)
1084
1284
  expect(STDERR).to receive(:puts).once
1085
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
1285
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s403\sbar\s+
1286
+ Terraform\scommand\sgot\s403\s
1086
1287
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1087
1288
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1088
1289
  expect(STDERR).to receive(:puts).once
1089
1290
  .with("terraform_runner command 'foo' finished and exited 0")
1090
- subject.terraform_runner('foo')
1291
+ subject.terraform_runner('foo', progress: :dots)
1091
1292
  end
1092
1293
  it 'retries if status code 401' do
1093
1294
  @times_called = 0
@@ -1101,31 +1302,54 @@ describe TFWrapper::RakeTasks do
1101
1302
  end
1102
1303
 
1103
1304
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1104
- .exactly(3).times.with('foo', 'tfdir')
1305
+ .exactly(3).times.with('foo', 'tfdir', progress: nil)
1105
1306
  expect(STDERR).to receive(:puts).once
1106
1307
  .with("terraform_runner command: 'foo' (in tfdir)")
1107
1308
  expect(STDERR).to receive(:puts).once
1108
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
1309
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s401\sbar\s+
1310
+ Terraform\scommand\sgot\s401\s
1109
1311
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1110
1312
  attempt\s1;\s.+\sseconds\shave\spassed\./x)
1111
1313
  expect(STDERR).to receive(:puts).once
1112
- .with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
1314
+ .with(/terraform_runner\sfailed\swith\sfoo\sstatus\scode:\s401\sbar\s+
1315
+ Terraform\scommand\sgot\s401\s
1113
1316
  error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
1114
1317
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1115
1318
  expect(STDERR).to receive(:puts).once
1116
1319
  .with("terraform_runner command 'foo' finished and exited 0")
1117
- subject.terraform_runner('foo')
1320
+ subject.terraform_runner('foo', progress: nil)
1118
1321
  end
1119
1322
  it 'raises an error if the command exits non-zero' do
1120
1323
  allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1121
1324
  .and_return(['', 1])
1122
1325
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
1123
- .with('foo', 'tfdir')
1326
+ .with('foo', 'tfdir', progress: :stream)
1124
1327
  expect(STDERR).to receive(:puts).once
1125
1328
  .with('terraform_runner command: \'foo\' (in tfdir)')
1126
1329
  expect { subject.terraform_runner('foo') }
1127
1330
  .to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
1128
1331
  end
1332
+ it 'prints output to STDERR if plan exits non-zero and not :stream' do
1333
+ allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1334
+ .and_return(['myoutput', 1])
1335
+ expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
1336
+ .with('foo', 'tfdir', progress: :dots)
1337
+ expect(STDERR).to receive(:puts).once
1338
+ .with('terraform_runner command: \'foo\' (in tfdir)')
1339
+ expect(STDERR).to receive(:puts).once
1340
+ .with('myoutput')
1341
+ expect { subject.terraform_runner('foo', progress: :dots) }
1342
+ .to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
1343
+ end
1344
+ it 'raises an error if the progress option is invalid' do
1345
+ allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1346
+ .and_return(['', 1])
1347
+ expect(TFWrapper::Helpers).to_not receive(:run_cmd_stream_output)
1348
+ expect { subject.terraform_runner('foo', progress: :foo) }
1349
+ .to raise_error(
1350
+ 'progress option must be one of: [:dots, :lines, :stream, nil]'
1351
+ )
1352
+ end
1129
1353
  end
1130
1354
  describe '#check_tf_version' do
1131
1355
  it 'fails if the command exits non-zero' do