tfwrapper 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -66,6 +66,8 @@ describe TFWrapper::RakeTasks do
66
66
  .to eq(Gem::Version.new('0.0.0'))
67
67
  expect(cls.instance_variable_get('@before_proc')).to eq(nil)
68
68
  expect(cls.instance_variable_get('@after_proc')).to eq(nil)
69
+ expect(cls.instance_variable_get('@disable_landscape')).to eq(false)
70
+ expect(cls.instance_variable_get('@landscape_progress')).to eq(nil)
69
71
  end
70
72
  it 'sets options' do
71
73
  allow(ENV).to receive(:[])
@@ -88,7 +90,9 @@ describe TFWrapper::RakeTasks do
88
90
  tf_extra_vars: { 'baz' => 'blam' },
89
91
  consul_url: 'foobar',
90
92
  before_proc: bproc,
91
- after_proc: aproc
93
+ after_proc: aproc,
94
+ disable_landscape: true,
95
+ landscape_progress: :dots
92
96
  )
93
97
  expect(cls.instance_variable_get('@tf_dir'))
94
98
  .to eq('/path/to/tf/dir')
@@ -102,6 +106,8 @@ describe TFWrapper::RakeTasks do
102
106
  expect(cls.instance_variable_get('@consul_url')).to eq('foobar')
103
107
  expect(cls.instance_variable_get('@before_proc')).to eq(bproc)
104
108
  expect(cls.instance_variable_get('@after_proc')).to eq(aproc)
109
+ expect(cls.instance_variable_get('@disable_landscape')).to eq(true)
110
+ expect(cls.instance_variable_get('@landscape_progress')).to eq(:dots)
105
111
  end
106
112
  context 'when before_proc is not a proc or nil' do
107
113
  it 'raises an error' do
@@ -120,6 +126,23 @@ describe TFWrapper::RakeTasks do
120
126
  )
121
127
  end
122
128
  end
129
+ context 'when landscape_progress is an invalid value' do
130
+ it 'raises an error' do
131
+ allow(ENV).to receive(:[])
132
+ allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
133
+ allow(ENV).to receive(:[]).with('ENVIRONMENT').and_return('myenv')
134
+ allow(ENV).to receive(:[]).with('PROJECT').and_return('myproj')
135
+ allow(Rake.application).to receive(:rakefile)
136
+ .and_return('/rake/dir/Rakefile')
137
+ allow(File).to receive(:realpath) { |p| p.sub('../', '') }
138
+ allow(File).to receive(:file?).and_return(true)
139
+ expect { TFWrapper::RakeTasks.new('tfdir', landscape_progress: :foo) }
140
+ .to raise_error(
141
+ ArgumentError,
142
+ /landscape_progress option must be one of:/
143
+ )
144
+ end
145
+ end
123
146
  context 'when after_proc is not a proc or nil' do
124
147
  it 'raises an error' do
125
148
  allow(Rake.application).to receive(:original_dir)
@@ -377,6 +400,7 @@ describe TFWrapper::RakeTasks do
377
400
  before(:each) do
378
401
  Rake::Task.clear
379
402
  Rake.application = Rake::Application.new
403
+ allow(subject).to receive(:landscape_format)
380
404
  end
381
405
  after(:each) do
382
406
  Rake.application = rake_application
@@ -392,33 +416,107 @@ describe TFWrapper::RakeTasks do
392
416
  expect(Rake.application['tf:plan'].arg_names).to eq([:target])
393
417
  end
394
418
  it 'runs the plan command with no targets' do
419
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
395
420
  Rake.application['tf:plan'].clear_prerequisites
396
421
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
397
422
  allow(subject).to receive(:terraform_runner)
398
423
  expect(subject).to receive(:terraform_runner).once
399
- .with('terraform plan -var-file file.tfvars.json')
424
+ .with('terraform plan -var-file file.tfvars.json', progress: nil)
400
425
  Rake.application['tf:plan'].invoke
401
426
  end
402
427
  it 'runs the plan command with one target' do
428
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
403
429
  Rake.application['tf:plan'].clear_prerequisites
404
430
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
405
431
  allow(subject).to receive(:terraform_runner)
406
432
  expect(subject).to receive(:terraform_runner).once
407
433
  .with('terraform plan -var-file file.tfvars.json ' \
408
- '-target tar.get[1]')
434
+ '-target tar.get[1]', progress: nil)
409
435
  Rake.application['tf:plan'].invoke('tar.get[1]')
410
436
  end
411
437
  it 'runs the plan command with three targets' do
438
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
412
439
  Rake.application['tf:plan'].clear_prerequisites
413
440
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
414
441
  allow(subject).to receive(:terraform_runner)
415
442
  expect(subject).to receive(:terraform_runner).once
416
443
  .with('terraform plan -var-file file.tfvars.json ' \
417
- '-target tar.get[1] -target t.gt[2] -target my.target[3]')
444
+ '-target tar.get[1] -target t.gt[2] -target my.target[3]',
445
+ progress: nil)
418
446
  Rake.application['tf:plan'].invoke(
419
447
  'tar.get[1]', 't.gt[2]', 'my.target[3]'
420
448
  )
421
449
  end
450
+ context 'with terraform_landscape available and enabled' do
451
+ before(:each) do
452
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
453
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
454
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
455
+ end
456
+ it 'runs plan with default progress type' do
457
+ Rake.application['tf:plan'].clear_prerequisites
458
+ expect(subject).to receive(:terraform_runner).once
459
+ .with('terraform plan -var-file file.tfvars.json', progress: nil)
460
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
461
+ Rake.application['tf:plan'].invoke
462
+ end
463
+ it 'runs plan with dots progress type' do
464
+ Rake.application['tf:plan'].clear_prerequisites
465
+ subject.instance_variable_set('@landscape_progress', :dots)
466
+ expect(subject).to receive(:terraform_runner).once
467
+ .with('terraform plan -var-file file.tfvars.json', progress: :dots)
468
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
469
+ Rake.application['tf:plan'].invoke
470
+ end
471
+ it 'runs plan with lines progress type' do
472
+ Rake.application['tf:plan'].clear_prerequisites
473
+ subject.instance_variable_set('@landscape_progress', :lines)
474
+ expect(subject).to receive(:terraform_runner).once
475
+ .with('terraform plan -var-file file.tfvars.json', progress: :lines)
476
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
477
+ Rake.application['tf:plan'].invoke
478
+ end
479
+ it 'runs plan with stream progress type' do
480
+ Rake.application['tf:plan'].clear_prerequisites
481
+ subject.instance_variable_set('@landscape_progress', :stream)
482
+ expect(subject).to receive(:terraform_runner).once
483
+ .with('terraform plan -var-file file.tfvars.json',
484
+ progress: :stream)
485
+ expect(subject).to receive(:landscape_format).once.with('TFoutput')
486
+ Rake.application['tf:plan'].invoke
487
+ end
488
+ end
489
+ context 'with terraform_landscape unavailable' do
490
+ it 'runs plan with stream progress and does not run landscape' do
491
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', false)
492
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
493
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
494
+
495
+ Rake.application['tf:plan'].clear_prerequisites
496
+ expect(subject).to receive(:terraform_runner).once
497
+ .with(
498
+ 'terraform plan -var-file file.tfvars.json', progress: :stream
499
+ )
500
+ expect(subject).to_not receive(:landscape_format)
501
+ Rake.application['tf:plan'].invoke
502
+ end
503
+ end
504
+ context 'with terraform_landscape available but disabled' do
505
+ it 'runs plan with stream progress and does not run landscape' do
506
+ stub_const('TFWrapper::RakeTasks::HAVE_LANDSCAPE', true)
507
+ allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
508
+ allow(subject).to receive(:terraform_runner).and_return('TFoutput')
509
+
510
+ subject.instance_variable_set('@disable_landscape', true)
511
+ Rake.application['tf:plan'].clear_prerequisites
512
+ expect(subject).to receive(:terraform_runner).once
513
+ .with(
514
+ 'terraform plan -var-file file.tfvars.json', progress: :stream
515
+ )
516
+ expect(subject).to_not receive(:landscape_format)
517
+ Rake.application['tf:plan'].invoke
518
+ end
519
+ end
422
520
  it 'calls before_proc if not nil' do
423
521
  Rake.application['tf:plan'].clear_prerequisites
424
522
  allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
@@ -1003,20 +1101,102 @@ describe TFWrapper::RakeTasks do
1003
1101
  )
1004
1102
  end
1005
1103
  end
1104
+ describe '#landscape_format', if: HAVE_LANDSCAPE do
1105
+ before(:each) do
1106
+ allow(STDERR).to receive(:puts)
1107
+ allow(STDOUT).to receive(:puts)
1108
+ end
1109
+ context 'when no exception is raised' do
1110
+ it 'processes the string through TerraformLandscape' do
1111
+ dbl_printer = double
1112
+ dbl_output = double
1113
+ allow(TerraformLandscape::Printer)
1114
+ .to receive(:new).and_return(dbl_printer)
1115
+ allow(TerraformLandscape::Output)
1116
+ .to receive(:new).and_return(dbl_output)
1117
+ allow(dbl_printer).to receive(:process_string)
1118
+
1119
+ expect(TerraformLandscape::Output)
1120
+ .to receive(:new).once.with(STDOUT)
1121
+ expect(TerraformLandscape::Printer)
1122
+ .to receive(:new).once.with(dbl_output)
1123
+ expect(dbl_printer).to receive(:process_string).once.with('PlanOutput')
1124
+ expect(STDERR).to_not receive(:puts)
1125
+ expect(STDOUT).to_not receive(:puts)
1126
+ subject.landscape_format('PlanOutput')
1127
+ end
1128
+ end
1129
+ context 'when an exception is raised' do
1130
+ context 'and landscape_progress is :stream' do
1131
+ it 'prints an error message' do
1132
+ dbl_printer = double
1133
+ dbl_output = double
1134
+ allow(TerraformLandscape::Printer)
1135
+ .to receive(:new).and_return(dbl_printer)
1136
+ allow(TerraformLandscape::Output)
1137
+ .to receive(:new).and_return(dbl_output)
1138
+ allow(dbl_printer).to receive(:process_string)
1139
+ .and_raise(RuntimeError, 'FooError')
1140
+
1141
+ expect(TerraformLandscape::Output)
1142
+ .to receive(:new).once.with(STDOUT)
1143
+ expect(TerraformLandscape::Printer)
1144
+ .to receive(:new).once.with(dbl_output)
1145
+ expect(dbl_printer)
1146
+ .to receive(:process_string).once.with('PlanOutput')
1147
+ expect(STDERR).to receive(:puts).once
1148
+ .with(
1149
+ 'Exception calling terraform_landscape to reformat output: ' \
1150
+ 'RuntimeError: FooError'
1151
+ )
1152
+ expect(STDOUT).to_not receive(:puts)
1153
+ subject.instance_variable_set('@landscape_progress', :stream)
1154
+ subject.landscape_format('PlanOutput')
1155
+ end
1156
+ end
1157
+ context 'and landscape_progress is not :stream' do
1158
+ it 'prints an error message and then the output' do
1159
+ dbl_printer = double
1160
+ dbl_output = double
1161
+ allow(TerraformLandscape::Printer)
1162
+ .to receive(:new).and_return(dbl_printer)
1163
+ allow(TerraformLandscape::Output)
1164
+ .to receive(:new).and_return(dbl_output)
1165
+ allow(dbl_printer).to receive(:process_string)
1166
+ .and_raise(RuntimeError, 'FooError')
1167
+
1168
+ expect(TerraformLandscape::Output)
1169
+ .to receive(:new).once.with(STDOUT)
1170
+ expect(TerraformLandscape::Printer)
1171
+ .to receive(:new).once.with(dbl_output)
1172
+ expect(dbl_printer)
1173
+ .to receive(:process_string).once.with('PlanOutput')
1174
+ expect(STDERR).to receive(:puts).once
1175
+ .with(
1176
+ 'Exception calling terraform_landscape to reformat output: ' \
1177
+ 'RuntimeError: FooError'
1178
+ )
1179
+ expect(STDOUT).to receive(:puts).once.with('PlanOutput')
1180
+ subject.instance_variable_set('@landscape_progress', nil)
1181
+ subject.landscape_format('PlanOutput')
1182
+ end
1183
+ end
1184
+ end
1185
+ end
1006
1186
  describe '#terraform_runner' do
1007
1187
  before do
1008
1188
  Retries.sleep_enabled = false
1009
1189
  end
1010
1190
  it 'outputs nothing and succeeds when command succeeds' do
1011
1191
  allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1012
- .with(any_args).and_return(['', 0])
1192
+ .with(any_args).and_return(['MyOutput', 0])
1013
1193
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1014
- .once.with('foo', 'tfdir')
1194
+ .once.with('foo', 'tfdir', progress: :stream)
1015
1195
  expect(STDERR).to receive(:puts).once
1016
1196
  .with("terraform_runner command: 'foo' (in tfdir)")
1017
1197
  expect(STDERR).to receive(:puts).once
1018
1198
  .with("terraform_runner command 'foo' finished and exited 0")
1019
- subject.terraform_runner('foo')
1199
+ expect(subject.terraform_runner('foo')).to eq('MyOutput')
1020
1200
  end
1021
1201
  it 'retries if needed' do
1022
1202
  @times_called = 0
@@ -1027,7 +1207,7 @@ describe TFWrapper::RakeTasks do
1027
1207
  end
1028
1208
 
1029
1209
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1030
- .exactly(2).times.with('foo', 'tfdir')
1210
+ .exactly(2).times.with('foo', 'tfdir', progress: :stream)
1031
1211
  expect(STDERR).to receive(:puts).once
1032
1212
  .with("terraform_runner command: 'foo' (in tfdir)")
1033
1213
  expect(STDERR).to receive(:puts).once
@@ -1044,12 +1224,12 @@ describe TFWrapper::RakeTasks do
1044
1224
  if @times_called < 3
1045
1225
  ['foo Throttling bar', 2]
1046
1226
  else
1047
- ['', 0]
1227
+ ['out', 0]
1048
1228
  end
1049
1229
  end
1050
1230
 
1051
1231
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1052
- .exactly(3).times.with('foo', 'tfdir')
1232
+ .exactly(3).times.with('foo', 'tfdir', progress: :stream)
1053
1233
  expect(STDERR).to receive(:puts).once
1054
1234
  .with("terraform_runner command: 'foo' (in tfdir)")
1055
1235
  expect(STDERR).to receive(:puts).once
@@ -1060,7 +1240,7 @@ describe TFWrapper::RakeTasks do
1060
1240
  limiting;\sretry\sattempt\s2;\s.+\sseconds\shave\spassed\./x)
1061
1241
  expect(STDERR).to receive(:puts).once
1062
1242
  .with("terraform_runner command 'foo' finished and exited 0")
1063
- subject.terraform_runner('foo')
1243
+ expect(subject.terraform_runner('foo')).to eq('out')
1064
1244
  end
1065
1245
  it 'retries if status code 403' do
1066
1246
  @times_called = 0
@@ -1074,7 +1254,7 @@ describe TFWrapper::RakeTasks do
1074
1254
  end
1075
1255
 
1076
1256
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1077
- .exactly(3).times.with('foo', 'tfdir')
1257
+ .exactly(3).times.with('foo', 'tfdir', progress: :dots)
1078
1258
  expect(STDERR).to receive(:puts).once
1079
1259
  .with("terraform_runner command: 'foo' (in tfdir)")
1080
1260
  expect(STDERR).to receive(:puts).once
@@ -1087,7 +1267,7 @@ describe TFWrapper::RakeTasks do
1087
1267
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1088
1268
  expect(STDERR).to receive(:puts).once
1089
1269
  .with("terraform_runner command 'foo' finished and exited 0")
1090
- subject.terraform_runner('foo')
1270
+ subject.terraform_runner('foo', progress: :dots)
1091
1271
  end
1092
1272
  it 'retries if status code 401' do
1093
1273
  @times_called = 0
@@ -1101,7 +1281,7 @@ describe TFWrapper::RakeTasks do
1101
1281
  end
1102
1282
 
1103
1283
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1104
- .exactly(3).times.with('foo', 'tfdir')
1284
+ .exactly(3).times.with('foo', 'tfdir', progress: nil)
1105
1285
  expect(STDERR).to receive(:puts).once
1106
1286
  .with("terraform_runner command: 'foo' (in tfdir)")
1107
1287
  expect(STDERR).to receive(:puts).once
@@ -1114,18 +1294,27 @@ describe TFWrapper::RakeTasks do
1114
1294
  attempt\s2;\s.+\sseconds\shave\spassed\./x)
1115
1295
  expect(STDERR).to receive(:puts).once
1116
1296
  .with("terraform_runner command 'foo' finished and exited 0")
1117
- subject.terraform_runner('foo')
1297
+ subject.terraform_runner('foo', progress: nil)
1118
1298
  end
1119
1299
  it 'raises an error if the command exits non-zero' do
1120
1300
  allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1121
1301
  .and_return(['', 1])
1122
1302
  expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
1123
- .with('foo', 'tfdir')
1303
+ .with('foo', 'tfdir', progress: :stream)
1124
1304
  expect(STDERR).to receive(:puts).once
1125
1305
  .with('terraform_runner command: \'foo\' (in tfdir)')
1126
1306
  expect { subject.terraform_runner('foo') }
1127
1307
  .to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
1128
1308
  end
1309
+ it 'raises an error if the progress option is invalid' do
1310
+ allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
1311
+ .and_return(['', 1])
1312
+ expect(TFWrapper::Helpers).to_not receive(:run_cmd_stream_output)
1313
+ expect { subject.terraform_runner('foo', progress: :foo) }
1314
+ .to raise_error(
1315
+ 'progress option must be one of: [:dots, :lines, :stream, nil]'
1316
+ )
1317
+ end
1129
1318
  end
1130
1319
  describe '#check_tf_version' do
1131
1320
  it 'fails if the command exits non-zero' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tfwrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jantman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-22 00:00:00.000000000 Z
11
+ date: 2018-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: retries
@@ -366,6 +366,14 @@ files:
366
366
  - spec/acceptance/acceptance_spec.rb
367
367
  - spec/acceptance/consulserver.rb
368
368
  - spec/fixtures/Rakefile
369
+ - spec/fixtures/landscapeTest/Rakefile
370
+ - spec/fixtures/landscapeTest/main.tf
371
+ - spec/fixtures/landscapeTest/state.json
372
+ - spec/fixtures/landscapeTest/with_landscape_default.out
373
+ - spec/fixtures/landscapeTest/with_landscape_dots.out
374
+ - spec/fixtures/landscapeTest/with_landscape_lines.out
375
+ - spec/fixtures/landscapeTest/with_landscape_stream.out
376
+ - spec/fixtures/landscapeTest/without_landscape.out
369
377
  - spec/fixtures/testOne.tf
370
378
  - spec/fixtures/testThree/Rakefile
371
379
  - spec/fixtures/testThree/bar/testThreeBar.tf
@@ -407,6 +415,14 @@ test_files:
407
415
  - spec/acceptance/acceptance_spec.rb
408
416
  - spec/acceptance/consulserver.rb
409
417
  - spec/fixtures/Rakefile
418
+ - spec/fixtures/landscapeTest/Rakefile
419
+ - spec/fixtures/landscapeTest/main.tf
420
+ - spec/fixtures/landscapeTest/state.json
421
+ - spec/fixtures/landscapeTest/with_landscape_default.out
422
+ - spec/fixtures/landscapeTest/with_landscape_dots.out
423
+ - spec/fixtures/landscapeTest/with_landscape_lines.out
424
+ - spec/fixtures/landscapeTest/with_landscape_stream.out
425
+ - spec/fixtures/landscapeTest/without_landscape.out
410
426
  - spec/fixtures/testOne.tf
411
427
  - spec/fixtures/testThree/Rakefile
412
428
  - spec/fixtures/testThree/bar/testThreeBar.tf