stack_master 0.5.0 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e9fbbd483a550665172b60c679b887fcad750ac
4
- data.tar.gz: 6be2fc55ee1c3bdb20b54f8e807b7482ac6000a1
3
+ metadata.gz: 462256c45f5be50e9afe763ac0bd7dc8a466ce98
4
+ data.tar.gz: d2feec3d48f34397eef2e26223c15e9745fd5bcb
5
5
  SHA512:
6
- metadata.gz: 6c26185a54b4b9ee4a3e1d092f51139884b8089c60679ef67334b1a1ff241b0a0ef35d24410ea2776df3b74e4ef8cdc086b230941466e0132ff22d79d649a238
7
- data.tar.gz: 2b30a1899670f668df76ec2c4ee6135ced4cfb40c553d4b7cf69c7ce0942600c82d1fccc79f3d8e160cf9ae73468816c5f5427a63a456d1996afbffc4a35edf6
6
+ metadata.gz: c78d5094529357d8e17581d46092a7b8f5ff155cf8ffb2081be549fb081c331bf96d97f35e6cb6f6de208fd6edb79baba2f2766b459667a87acf05de0c08525b
7
+ data.tar.gz: ddc6dae60758049e6b01a538254e29e14c048d5c82fc63ef3afa59c897f1e7575531c124db1e2fc702aae803ead82a7e3b28d85aabd14f1ca7af0e94cbfa1f41
data/README.md CHANGED
@@ -64,21 +64,35 @@ stacks:
64
64
  production:
65
65
  myapp-vpc:
66
66
  template: myapp_vpc.rb
67
+ tags:
68
+ purpose: front-end
67
69
  myapp-db:
68
70
  template: myapp_db.rb
69
71
  stack_policy_file: db_stack_policy.json
72
+ tags:
73
+ purpose: back-end
70
74
  myapp-web:
71
75
  template: myapp_web.rb
76
+ tags:
77
+ purpose: front-end
72
78
  staging:
73
79
  myapp-vpc:
74
80
  template: myapp_vpc.rb
81
+ tags:
82
+ purpose: front-end
75
83
  myapp-db:
76
84
  template: myapp_db.rb
85
+ tags:
86
+ purpose: back-end
77
87
  myapp-web:
78
88
  template: myapp_web.rb
89
+ tags:
90
+ purpose: front-end
79
91
  eu-central-1:
80
92
  myapp-vpc:
81
93
  template: myapp_vpc.rb
94
+ tags:
95
+ purpose: vpc
82
96
  ```
83
97
 
84
98
  ## Directories
@@ -197,7 +211,7 @@ Looks up an SNS topic by name and returns the ARN.
197
211
 
198
212
  ```yaml
199
213
  notification_topic:
200
- sns_topic: PagerDuty
214
+ sns_topic_name: PagerDuty
201
215
  ```
202
216
 
203
217
  ### Latest AMI by Tag
@@ -293,6 +307,23 @@ my_parameter:
293
307
  - value2
294
308
  ```
295
309
 
310
+ ## User Data Files in SparkleFormation templates
311
+
312
+ An extension to SparkleFormation is the `user_data_file!` method, which evaluates templates in `templates/user_data/[file_name]`. Most of the usual SparkleFormation methods are available in user data templates. Example:
313
+
314
+ ```
315
+ # templates/user_data/app.erb
316
+ REGION=<%= region! %>
317
+ ROLE=<%= role %>
318
+ ```
319
+
320
+ And used like this in SparkleFormation templates:
321
+
322
+ ```
323
+ # templates/app.rb
324
+ user_data user_data_file!('app.erb', role: :worker)
325
+ ```
326
+
296
327
  ## Commands
297
328
 
298
329
  ```bash
@@ -12,6 +12,7 @@ require 'dotgpg'
12
12
  require 'ruby-progressbar'
13
13
 
14
14
  require "stack_master/ctrl_c"
15
+ require "stack_master/sparkle_formation/user_data_file"
15
16
  require "stack_master/command"
16
17
  require "stack_master/version"
17
18
  require "stack_master/stack"
@@ -0,0 +1,94 @@
1
+ require 'sparkle_formation'
2
+ require 'erubis'
3
+
4
+ module StackMaster
5
+ module SparkleFormation
6
+ UserDataFileNotFound = ::Class.new(StandardError)
7
+
8
+ class SfEruby < Erubis::Eruby
9
+ include Erubis::ArrayEnhancer
10
+
11
+ def add_expr(src, code, indicator)
12
+ case indicator
13
+ when '='
14
+ src << " #{@bufvar} << (" << code << ');'
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+
21
+ class TemplateContext < AttributeStruct
22
+ include ::SparkleFormation::SparkleAttribute
23
+ include ::SparkleFormation::SparkleAttribute::Aws
24
+ include ::SparkleFormation::Utils::TypeCheckers
25
+
26
+ def self.build(vars)
27
+ ::Class.new(self).tap do |klass|
28
+ vars.each do |key, value|
29
+ klass.send(:define_method, key) do
30
+ value
31
+ end
32
+ end
33
+ end.new(vars)
34
+ end
35
+
36
+ def initialize(vars)
37
+ self._camel_keys = true
38
+ @vars = vars
39
+ end
40
+
41
+ def has_var?(var_key)
42
+ @vars.include?(var_key)
43
+ end
44
+ end
45
+
46
+ # Splits up long strings with multiple lines in them to multiple strings
47
+ # in the CF array. Makes the compiled template and diffs more readable.
48
+ class CloudFormationLineFormatter
49
+ def self.format(template)
50
+ new(template).format
51
+ end
52
+
53
+ def initialize(template)
54
+ @template = template
55
+ end
56
+
57
+ def format
58
+ @template.flat_map do |lines|
59
+ lines = lines.to_s if Symbol === lines
60
+ if String === lines
61
+ newlines = []
62
+ lines.count("\n").times do
63
+ newlines << "\n"
64
+ end
65
+ newlines = lines.split("\n").map do |line|
66
+ "#{line}#{newlines.pop}"
67
+ end
68
+ if lines.starts_with?("\n")
69
+ newlines.insert(0, "\n")
70
+ end
71
+ newlines
72
+ else
73
+ lines
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ module UserDataFile
80
+ def _user_data_file(file_name, vars = {})
81
+ file_path = File.join(::SparkleFormation.sparkle_path, 'user_data', file_name)
82
+ template = File.read(file_path)
83
+ template_context = TemplateContext.build(vars)
84
+ compiled_template = SfEruby.new(template).evaluate(template_context)
85
+ base64!(join!(CloudFormationLineFormatter.format(compiled_template)))
86
+ rescue Errno::ENOENT => e
87
+ Kernel.raise UserDataFileNotFound, "Could not find user data file at path: #{file_path}"
88
+ end
89
+ alias_method :user_data_file!, :_user_data_file
90
+ end
91
+ end
92
+ end
93
+
94
+ SparkleFormation::SparkleAttribute::Aws.send(:include, StackMaster::SparkleFormation::UserDataFile)
@@ -1,3 +1,3 @@
1
1
  module StackMaster
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
File without changes
@@ -0,0 +1,70 @@
1
+ RSpec.describe SparkleFormation::SparkleAttribute::Aws, '#user_data_file!' do
2
+ let(:user_data) do
3
+ <<-EOS
4
+ #!/bin/bash
5
+
6
+ REGION=<%= region! %>
7
+ echo $REGION
8
+ <%= ref!(:test) %> <%= ref!(:test_2) %>
9
+ <%= has_var?(:test) ? "echo 'yes'" : "echo 'no'" %>
10
+ EOS
11
+ end
12
+ let(:expected_hash) do
13
+ {"Fn::Base64"=>{"Fn::Join"=>["", ["#!/bin/bash\n", "\n", "REGION=", {"Ref"=>"AWS::Region"}, "\n", "echo $REGION\n", {"Ref"=>"Test"}, " ", {"Ref"=>"Test2"}, "\n", "echo 'no'", "\n"]]}}
14
+ end
15
+
16
+ before do
17
+ allow(SparkleFormation).to receive(:sparkle_path).and_return('/templates_dir')
18
+ klass = Class.new(AttributeStruct)
19
+ klass.include(SparkleFormation::SparkleAttribute)
20
+ klass.include(SparkleFormation::SparkleAttribute::Aws)
21
+ klass.include(SparkleFormation::Utils::TypeCheckers)
22
+ @attr = klass.new
23
+ @attr._camel_keys = true
24
+ end
25
+
26
+ it 'reads from the user_data dir in templates' do
27
+ expect(File).to receive(:read).with('/templates_dir/user_data/test.erb').and_return(user_data)
28
+ @attr.user_data_file!('test.erb')
29
+ end
30
+
31
+ context 'when the file exists' do
32
+ before do
33
+ allow(File).to receive(:read).and_return(user_data)
34
+ end
35
+
36
+ it 'compiles the file and returns a joined version' do
37
+ expect(@attr.user_data_file!('test.erb')).to eq expected_hash
38
+ end
39
+
40
+ context 'with custom vars' do
41
+ let(:user_data) do
42
+ <<-EOS
43
+ #!/bin/bash
44
+ <%= my_custom_var %>
45
+ <%= has_var?(:my_custom_var) ? "yes" : "no" %>
46
+ EOS
47
+ end
48
+ let(:expected_hash) do
49
+ {"Fn::Base64"=>{"Fn::Join"=>["", ["#!/bin/bash\n", "test_var", "\n", "yes", "\n"]]}}
50
+ end
51
+
52
+ it 'compiles the file and returns a joined version' do
53
+ expect(@attr.user_data_file!('test.erb', my_custom_var: :test_var)).to eq expected_hash
54
+ expect(@attr.user_data_file!('test.erb', my_custom_var: 'test_var')).to eq expected_hash
55
+ end
56
+ end
57
+ end
58
+
59
+ context "when the file doesn't exist" do
60
+ before do
61
+ allow(File).to receive(:read).and_raise(Errno::ENOENT)
62
+ end
63
+
64
+ it 'raises a specific error' do
65
+ expect {
66
+ @attr.user_data_file!('test.erb')
67
+ }.to raise_error(StackMaster::SparkleFormation::UserDataFileNotFound)
68
+ end
69
+ end
70
+ end
@@ -28,10 +28,11 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "ruby-progressbar"
29
29
  spec.add_dependency "commander"
30
30
  spec.add_dependency "virtus"
31
- spec.add_dependency "aws-sdk", "~> 2.1"
31
+ spec.add_dependency "aws-sdk", "~> 2.2.31"
32
32
  spec.add_dependency "diffy"
33
+ spec.add_dependency "erubis"
33
34
  spec.add_dependency "colorize"
34
- spec.add_dependency "activesupport"
35
+ spec.add_dependency "activesupport", "~> 4.2"
35
36
  spec.add_dependency "sparkle_formation", "~> 1.1"
36
37
  spec.add_dependency "table_print"
37
38
  spec.add_dependency "dotgpg"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stack_master
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Hodgkiss
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-09 00:00:00.000000000 Z
12
+ date: 2016-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -157,14 +157,14 @@ dependencies:
157
157
  requirements:
158
158
  - - "~>"
159
159
  - !ruby/object:Gem::Version
160
- version: '2.1'
160
+ version: 2.2.31
161
161
  type: :runtime
162
162
  prerelease: false
163
163
  version_requirements: !ruby/object:Gem::Requirement
164
164
  requirements:
165
165
  - - "~>"
166
166
  - !ruby/object:Gem::Version
167
- version: '2.1'
167
+ version: 2.2.31
168
168
  - !ruby/object:Gem::Dependency
169
169
  name: diffy
170
170
  requirement: !ruby/object:Gem::Requirement
@@ -180,7 +180,7 @@ dependencies:
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  - !ruby/object:Gem::Dependency
183
- name: colorize
183
+ name: erubis
184
184
  requirement: !ruby/object:Gem::Requirement
185
185
  requirements:
186
186
  - - ">="
@@ -194,7 +194,7 @@ dependencies:
194
194
  - !ruby/object:Gem::Version
195
195
  version: '0'
196
196
  - !ruby/object:Gem::Dependency
197
- name: activesupport
197
+ name: colorize
198
198
  requirement: !ruby/object:Gem::Requirement
199
199
  requirements:
200
200
  - - ">="
@@ -207,6 +207,20 @@ dependencies:
207
207
  - - ">="
208
208
  - !ruby/object:Gem::Version
209
209
  version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: activesupport
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - "~>"
215
+ - !ruby/object:Gem::Version
216
+ version: '4.2'
217
+ type: :runtime
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - "~>"
222
+ - !ruby/object:Gem::Version
223
+ version: '4.2'
210
224
  - !ruby/object:Gem::Dependency
211
225
  name: sparkle_formation
212
226
  requirement: !ruby/object:Gem::Requirement
@@ -346,6 +360,7 @@ files:
346
360
  - lib/stack_master/resolver_array.rb
347
361
  - lib/stack_master/security_group_finder.rb
348
362
  - lib/stack_master/sns_topic_finder.rb
363
+ - lib/stack_master/sparkle_formation/user_data_file.rb
349
364
  - lib/stack_master/stack.rb
350
365
  - lib/stack_master/stack_definition.rb
351
366
  - lib/stack_master/stack_differ.rb
@@ -375,6 +390,7 @@ files:
375
390
  - spec/fixtures/templates/rb/cfndsl/sample.json
376
391
  - spec/fixtures/templates/rb/cfndsl/sample.rb
377
392
  - spec/fixtures/templates/yml/valid_myapp_vpc.yml
393
+ - spec/fixtures/test/.gitkeep
378
394
  - spec/spec_helper.rb
379
395
  - spec/stack_master/change_set_spec.rb
380
396
  - spec/stack_master/command_spec.rb
@@ -399,6 +415,7 @@ files:
399
415
  - spec/stack_master/resolver_array_spec.rb
400
416
  - spec/stack_master/security_group_finder_spec.rb
401
417
  - spec/stack_master/sns_topic_finder_spec.rb
418
+ - spec/stack_master/sparkle_formation/user_data_file_spec.rb
402
419
  - spec/stack_master/stack_definition_spec.rb
403
420
  - spec/stack_master/stack_differ_spec.rb
404
421
  - spec/stack_master/stack_events/fetcher_spec.rb
@@ -439,7 +456,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
439
456
  version: '0'
440
457
  requirements: []
441
458
  rubyforge_project:
442
- rubygems_version: 2.2.2
459
+ rubygems_version: 2.5.1
443
460
  signing_key:
444
461
  specification_version: 4
445
462
  summary: StackMaster is a sure-footed way of creating, updating and keeping track
@@ -465,6 +482,7 @@ test_files:
465
482
  - spec/fixtures/templates/rb/cfndsl/sample.json
466
483
  - spec/fixtures/templates/rb/cfndsl/sample.rb
467
484
  - spec/fixtures/templates/yml/valid_myapp_vpc.yml
485
+ - spec/fixtures/test/.gitkeep
468
486
  - spec/spec_helper.rb
469
487
  - spec/stack_master/change_set_spec.rb
470
488
  - spec/stack_master/command_spec.rb
@@ -489,6 +507,7 @@ test_files:
489
507
  - spec/stack_master/resolver_array_spec.rb
490
508
  - spec/stack_master/security_group_finder_spec.rb
491
509
  - spec/stack_master/sns_topic_finder_spec.rb
510
+ - spec/stack_master/sparkle_formation/user_data_file_spec.rb
492
511
  - spec/stack_master/stack_definition_spec.rb
493
512
  - spec/stack_master/stack_differ_spec.rb
494
513
  - spec/stack_master/stack_events/fetcher_spec.rb