stack_master 2.7.0 → 2.12.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 +4 -4
- data/README.md +56 -6
- data/lib/stack_master.rb +16 -0
- data/lib/stack_master/aws_driver/cloud_formation.rb +4 -1
- data/lib/stack_master/cli.rb +31 -0
- data/lib/stack_master/commands/drift.rb +118 -0
- data/lib/stack_master/commands/nag.rb +30 -0
- data/lib/stack_master/config.rb +1 -0
- data/lib/stack_master/diff.rb +45 -0
- data/lib/stack_master/sparkle_formation/compile_time/empty_validator.rb +1 -1
- data/lib/stack_master/stack_differ.rb +15 -39
- data/lib/stack_master/template_compilers/yaml_erb.rb +20 -0
- data/lib/stack_master/version.rb +1 -1
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02eda4742884cf2aa48568ad0e330b375f7548f12f3077be3167bd782a51868d
|
4
|
+
data.tar.gz: 6f3159eb1b681bda06e4c128d4746f05484a75f91c1a2119d9c02523f912b48f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4670acd897af5bd58083f65187c23c7e7add969ca1d906899ce18065bcc24287d78854bd67baa82a1225dab4277b3392fa03cc3a5ffe49c13cffd3665ca2ea99
|
7
|
+
data.tar.gz: 8ea47d21747c13e9685f0f5cacbb12663c28df649823981c5e1a94e982bc7798bd2b93828be921e7e2e4267e3c3aa3d1f246aeb8f99f0eb91d34d2ce24594263
|
data/README.md
CHANGED
@@ -143,7 +143,8 @@ stacks:
|
|
143
143
|
## Templates
|
144
144
|
|
145
145
|
StackMaster supports CloudFormation templates in plain JSON or YAML. Any `.yml` or `.yaml` file will be processed as
|
146
|
-
YAML, while any `.json` file will be processed as JSON.
|
146
|
+
YAML, while any `.json` file will be processed as JSON. Additionally, YAML files can be pre-processed using ERB and
|
147
|
+
compile-time parameters.
|
147
148
|
|
148
149
|
### Ruby DSLs
|
149
150
|
By default, any template ending with `.rb` will be processed as a [SparkleFormation](https://github.com/sparkleformation/sparkle_formation)
|
@@ -199,12 +200,13 @@ stacks:
|
|
199
200
|
|
200
201
|
### Compile Time Parameters
|
201
202
|
|
202
|
-
Compile time parameters can be
|
203
|
-
|
203
|
+
Compile time parameters can be defined in a stack's parameters file, using the key `compile_time_parameters`. Keys in
|
204
|
+
parameter files are automatically converted to camel case.
|
204
205
|
|
205
|
-
|
206
|
+
As an example:
|
206
207
|
|
207
208
|
```yaml
|
209
|
+
# parameters/some_stack.yml
|
208
210
|
vpc_cidr: 10.0.0.0/16
|
209
211
|
compile_time_parameters:
|
210
212
|
subnet_cidrs:
|
@@ -212,7 +214,37 @@ compile_time_parameters:
|
|
212
214
|
- 10.0.2.0/28
|
213
215
|
```
|
214
216
|
|
215
|
-
|
217
|
+
#### SparkleFormation
|
218
|
+
|
219
|
+
Compile time parameters can be used for [SparkleFormation](http://www.sparkleformation.io) templates. It conforms and
|
220
|
+
allows you to use the [Compile Time Parameters](http://www.sparkleformation.io/docs/sparkle_formation/compile-time-parameters.html) feature.
|
221
|
+
|
222
|
+
#### CloudFormation YAML ERB
|
223
|
+
|
224
|
+
Compile time parameters can be used to pre-process YAML CloudFormation templates. An example template:
|
225
|
+
|
226
|
+
```yaml
|
227
|
+
# templates/some_stack_template.yml.erb
|
228
|
+
Parameters:
|
229
|
+
VpcCidr:
|
230
|
+
Type: String
|
231
|
+
Resources:
|
232
|
+
Vpc:
|
233
|
+
Type: AWS::EC2::VPC
|
234
|
+
Properties:
|
235
|
+
CidrBlock: !Ref VpcCidr
|
236
|
+
# Given the two subnet_cidrs parameters, this creates two resources:
|
237
|
+
# SubnetPrivate0 with a CidrBlock of 10.0.0.0/28, and
|
238
|
+
# SubnetPrivate1 with a CidrBlock of 10.0.2.0/28
|
239
|
+
<% params["SubnetCidrs"].each_with_index do |cidr, index| %>
|
240
|
+
SubnetPrivate<%= index %>:
|
241
|
+
Type: AWS::EC2::Subnet
|
242
|
+
Properties:
|
243
|
+
VpcId: !Ref Vpc
|
244
|
+
AvailabilityZone: ap-southeast-2
|
245
|
+
CidrBlock: <%= cidr %>
|
246
|
+
<% end %>
|
247
|
+
```
|
216
248
|
|
217
249
|
## Parameter Resolvers
|
218
250
|
|
@@ -688,6 +720,7 @@ stacks:
|
|
688
720
|
|
689
721
|
In the cases where you want to bypass the account check, there is the StackMaster flag `--skip-account-check` that can be used.
|
690
722
|
|
723
|
+
|
691
724
|
## Commands
|
692
725
|
|
693
726
|
```bash
|
@@ -701,15 +734,20 @@ stack_master apply # Create or update all stacks
|
|
701
734
|
stack_master --changed apply # Create or update all stacks that have changed
|
702
735
|
stack_master --yes apply [region-or-alias] [stack-name] # Create or update a stack non-interactively (forcing yes)
|
703
736
|
stack_master diff [region-or-alias] [stack-name] # Display a stack template and parameter diff
|
737
|
+
stack_master drift [region-or-alias] [stack-name] # Detects and displays stack drift using the CloudFormation Drift API
|
704
738
|
stack_master delete [region-or-alias] [stack-name] # Delete a stack
|
705
739
|
stack_master events [region-or-alias] [stack-name] # Display events for a stack
|
706
740
|
stack_master outputs [region-or-alias] [stack-name] # Display outputs for a stack
|
707
741
|
stack_master resources [region-or-alias] [stack-name] # Display outputs for a stack
|
708
742
|
stack_master status # Displays the status of each stack
|
709
743
|
stack_master tidy # Find missing or extra templates or parameter files
|
744
|
+
stack_master compile # Print the compiled version of a given stack
|
745
|
+
stack_master validate # Validate a template
|
746
|
+
stack_master lint # Check the stack definition locally using cfn-lint
|
747
|
+
stack_master nag # Check the stack template with cfn_nag
|
710
748
|
```
|
711
749
|
|
712
|
-
## Applying updates
|
750
|
+
## Applying updates - `stack_master apply`
|
713
751
|
|
714
752
|
The apply command does the following:
|
715
753
|
|
@@ -726,6 +764,18 @@ Demo:
|
|
726
764
|
|
727
765
|

|
728
766
|
|
767
|
+
## Drift Detection - `stack_master drift`
|
768
|
+
|
769
|
+
`stack_master drift us-east-1 mystack` uses the CloudFormation APIs to trigger drift detection and display resources
|
770
|
+
that have changed outside of the CloudFormation stack. This can happen if a resource has been updated via the console or
|
771
|
+
CLI directly rather than via a stack update.
|
772
|
+
|
773
|
+
## Diff - `stack_master diff`
|
774
|
+
|
775
|
+
`stack_master diff us-east-1 mystack` displays whether the computed parameters or template differ to what was last
|
776
|
+
applied in CloudFormation. This can happen if the template or computed parameters have changed in code and the change
|
777
|
+
hasn't been applied to this stack.
|
778
|
+
|
729
779
|
## Maintainers
|
730
780
|
|
731
781
|
- [Steve Hodgkiss](https://github.com/stevehodgkiss)
|
data/lib/stack_master.rb
CHANGED
@@ -24,6 +24,7 @@ module StackMaster
|
|
24
24
|
autoload :CLI, 'stack_master/cli'
|
25
25
|
autoload :CtrlC, 'stack_master/ctrl_c'
|
26
26
|
autoload :Command, 'stack_master/command'
|
27
|
+
autoload :Diff, 'stack_master/diff'
|
27
28
|
autoload :VERSION, 'stack_master/version'
|
28
29
|
autoload :Stack, 'stack_master/stack'
|
29
30
|
autoload :Prompter, 'stack_master/prompter'
|
@@ -51,11 +52,13 @@ module StackMaster
|
|
51
52
|
require 'stack_master/template_compilers/sparkle_formation'
|
52
53
|
require 'stack_master/template_compilers/json'
|
53
54
|
require 'stack_master/template_compilers/yaml'
|
55
|
+
require 'stack_master/template_compilers/yaml_erb'
|
54
56
|
require 'stack_master/template_compilers/cfndsl'
|
55
57
|
|
56
58
|
module Commands
|
57
59
|
autoload :TerminalHelper, 'stack_master/commands/terminal_helper'
|
58
60
|
autoload :Apply, 'stack_master/commands/apply'
|
61
|
+
autoload :Drift, 'stack_master/commands/drift'
|
59
62
|
autoload :Events, 'stack_master/commands/events'
|
60
63
|
autoload :Outputs, 'stack_master/commands/outputs'
|
61
64
|
autoload :Init, 'stack_master/commands/init'
|
@@ -68,6 +71,7 @@ module StackMaster
|
|
68
71
|
autoload :Delete, 'stack_master/commands/delete'
|
69
72
|
autoload :Status, 'stack_master/commands/status'
|
70
73
|
autoload :Tidy, 'stack_master/commands/tidy'
|
74
|
+
autoload :Nag, 'stack_master/commands/nag'
|
71
75
|
end
|
72
76
|
|
73
77
|
module ParameterResolvers
|
@@ -198,4 +202,16 @@ module StackMaster
|
|
198
202
|
def stderr=(io)
|
199
203
|
@stderr = io
|
200
204
|
end
|
205
|
+
|
206
|
+
def colorize(text, color)
|
207
|
+
if colorize?
|
208
|
+
Rainbow(text).color(color)
|
209
|
+
else
|
210
|
+
text
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def colorize?
|
215
|
+
ENV.fetch('COLORIZE') { 'true' } == 'true'
|
216
|
+
end
|
201
217
|
end
|
data/lib/stack_master/cli.rb
CHANGED
@@ -146,6 +146,17 @@ module StackMaster
|
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
|
+
command :nag do |c|
|
150
|
+
c.syntax = 'stack_master nag [region_or_alias] [stack_name]'
|
151
|
+
c.summary = "Check this stack's template with cfn_nag"
|
152
|
+
c.description = "Runs SAST scan cfn_nag on the template"
|
153
|
+
c.example 'run cfn_nag on stack myapp-vpc with us-east-1 settings', 'stack_master nag us-east-1 myapp-vpc'
|
154
|
+
c.action do |args, options|
|
155
|
+
options.default config: default_config_file
|
156
|
+
execute_stacks_command(StackMaster::Commands::Nag, args, options)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
149
160
|
command :compile do |c|
|
150
161
|
c.syntax = 'stack_master compile [region_or_alias] [stack_name]'
|
151
162
|
c.summary = "Print the compiled version of a given stack"
|
@@ -215,6 +226,18 @@ module StackMaster
|
|
215
226
|
end
|
216
227
|
end
|
217
228
|
|
229
|
+
command :drift do |c|
|
230
|
+
c.syntax = 'stack_master drift [region_or_alias] [stack_name]'
|
231
|
+
c.summary = 'Detects and displays stack drift using the CloudFormation Drift API'
|
232
|
+
c.description = 'Detects and displays stack drift'
|
233
|
+
c.option '--timeout SECONDS', Integer, "The number of seconds to wait for drift detection to complete"
|
234
|
+
c.example 'view stack drift for a stack named myapp-vpc in us-east-1', 'stack_master drift us-east-1 myapp-vpc'
|
235
|
+
c.action do |args, options|
|
236
|
+
options.default config: default_config_file, timeout: 120
|
237
|
+
execute_stacks_command(StackMaster::Commands::Drift, args, options)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
218
241
|
run!
|
219
242
|
end
|
220
243
|
|
@@ -242,6 +265,7 @@ module StackMaster
|
|
242
265
|
stack_definitions = config.filter(region, stack_name)
|
243
266
|
if stack_definitions.empty?
|
244
267
|
StackMaster.stdout.puts "Could not find stack definition #{stack_name} in region #{region}"
|
268
|
+
show_other_region_candidates(config, stack_name)
|
245
269
|
success = false
|
246
270
|
end
|
247
271
|
stack_definitions = stack_definitions.select do |stack_definition|
|
@@ -258,6 +282,13 @@ module StackMaster
|
|
258
282
|
@kernel.exit false unless success
|
259
283
|
end
|
260
284
|
|
285
|
+
def show_other_region_candidates(config, stack_name)
|
286
|
+
candidates = config.filter(region="", stack_name=stack_name)
|
287
|
+
return if candidates.empty?
|
288
|
+
|
289
|
+
StackMaster.stdout.puts "Stack name #{stack_name} exists in regions: #{candidates.map(&:region).join(', ')}"
|
290
|
+
end
|
291
|
+
|
261
292
|
def execute_if_allowed_account(allowed_accounts, &block)
|
262
293
|
raise ArgumentError, "Block required to execute this method" unless block_given?
|
263
294
|
if running_in_allowed_account?(allowed_accounts)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'diffy'
|
2
|
+
|
3
|
+
module StackMaster
|
4
|
+
module Commands
|
5
|
+
class Drift
|
6
|
+
include Command
|
7
|
+
include Commander::UI
|
8
|
+
|
9
|
+
DETECTION_COMPLETE_STATES = [
|
10
|
+
'DETECTION_COMPLETE',
|
11
|
+
'DETECTION_FAILED'
|
12
|
+
]
|
13
|
+
|
14
|
+
def perform
|
15
|
+
detect_stack_drift_result = cf.detect_stack_drift(stack_name: stack_name)
|
16
|
+
drift_results = wait_for_drift_results(detect_stack_drift_result.stack_drift_detection_id)
|
17
|
+
|
18
|
+
puts colorize("Drift Status: #{drift_results.stack_drift_status}", stack_drift_status_color(drift_results.stack_drift_status))
|
19
|
+
return if drift_results.stack_drift_status == 'IN_SYNC'
|
20
|
+
|
21
|
+
failed
|
22
|
+
|
23
|
+
resp = cf.describe_stack_resource_drifts(stack_name: stack_name)
|
24
|
+
resp.stack_resource_drifts.each do |drift|
|
25
|
+
display_drift(drift)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def cf
|
32
|
+
@cf ||= StackMaster.cloud_formation_driver
|
33
|
+
end
|
34
|
+
|
35
|
+
def display_drift(drift)
|
36
|
+
color = drift_color(drift)
|
37
|
+
puts colorize([drift.stack_resource_drift_status,
|
38
|
+
drift.resource_type,
|
39
|
+
drift.logical_resource_id,
|
40
|
+
drift.physical_resource_id].join(' '), color)
|
41
|
+
return unless drift.stack_resource_drift_status == 'MODIFIED'
|
42
|
+
|
43
|
+
unless drift.property_differences.empty?
|
44
|
+
puts colorize(' Property differences:', color)
|
45
|
+
end
|
46
|
+
drift.property_differences.each do |property_difference|
|
47
|
+
puts colorize(" - #{property_difference.difference_type} #{property_difference.property_path}", color)
|
48
|
+
end
|
49
|
+
puts colorize(' Resource diff:', color)
|
50
|
+
display_resource_drift(drift)
|
51
|
+
end
|
52
|
+
|
53
|
+
def display_resource_drift(drift)
|
54
|
+
diff = ::StackMaster::Diff.new(before: prettify_json(drift.expected_properties),
|
55
|
+
after: prettify_json(drift.actual_properties))
|
56
|
+
diff.display_colorized_diff
|
57
|
+
end
|
58
|
+
|
59
|
+
def prettify_json(string)
|
60
|
+
JSON.pretty_generate(JSON.parse(string)) + "\n"
|
61
|
+
rescue StandardError => e
|
62
|
+
puts "Failed to prettify drifted resource: #{e.message}"
|
63
|
+
string
|
64
|
+
end
|
65
|
+
|
66
|
+
def stack_drift_status_color(stack_drift_status)
|
67
|
+
case stack_drift_status
|
68
|
+
when 'IN_SYNC'
|
69
|
+
:green
|
70
|
+
when 'DRIFTED'
|
71
|
+
:yellow
|
72
|
+
else
|
73
|
+
:blue
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def drift_color(drift)
|
78
|
+
case drift.stack_resource_drift_status
|
79
|
+
when 'IN_SYNC'
|
80
|
+
:green
|
81
|
+
when 'MODIFIED'
|
82
|
+
:yellow
|
83
|
+
when 'DELETED'
|
84
|
+
:red
|
85
|
+
else
|
86
|
+
:blue
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def wait_for_drift_results(detection_id)
|
91
|
+
resp = nil
|
92
|
+
start_time = Time.now
|
93
|
+
loop do
|
94
|
+
resp = cf.describe_stack_drift_detection_status(stack_drift_detection_id: detection_id)
|
95
|
+
break if DETECTION_COMPLETE_STATES.include?(resp.detection_status)
|
96
|
+
|
97
|
+
elapsed_time = Time.now - start_time
|
98
|
+
if elapsed_time > @options.timeout
|
99
|
+
raise "Timeout waiting for stack drift detection"
|
100
|
+
end
|
101
|
+
|
102
|
+
sleep SLEEP_SECONDS
|
103
|
+
end
|
104
|
+
resp
|
105
|
+
end
|
106
|
+
|
107
|
+
def puts(string)
|
108
|
+
StackMaster.stdout.puts(string)
|
109
|
+
end
|
110
|
+
|
111
|
+
extend Forwardable
|
112
|
+
def_delegators :@stack_definition, :stack_name, :region
|
113
|
+
def_delegators :StackMaster, :colorize
|
114
|
+
|
115
|
+
SLEEP_SECONDS = 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module StackMaster
|
2
|
+
module Commands
|
3
|
+
class Nag
|
4
|
+
include Command
|
5
|
+
include Commander::UI
|
6
|
+
|
7
|
+
def perform
|
8
|
+
rv = Tempfile.open(['stack', "___#{stack_definition.stack_name}.#{proposed_stack.template_format}"]) do |f|
|
9
|
+
f.write(proposed_stack.template_body)
|
10
|
+
f.flush
|
11
|
+
system('cfn_nag', f.path)
|
12
|
+
$?.exitstatus
|
13
|
+
end
|
14
|
+
|
15
|
+
failed!("cfn_nag check failed with exit status #{rv}") if rv > 0
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def stack_definition
|
21
|
+
@stack_definition ||= @config.find_stack(@region, @stack_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def proposed_stack
|
25
|
+
@proposed_stack ||= Stack.generate(stack_definition, @config)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/stack_master/config.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module StackMaster
|
2
|
+
class Diff
|
3
|
+
def initialize(name: nil, before:, after:, context: 10_000)
|
4
|
+
@name = name
|
5
|
+
@before = before
|
6
|
+
@after = after
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def display
|
11
|
+
stdout.print "#{@name} diff: "
|
12
|
+
if diff == ''
|
13
|
+
stdout.puts "No changes"
|
14
|
+
else
|
15
|
+
stdout.puts
|
16
|
+
display_colorized_diff
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def display_colorized_diff
|
21
|
+
diff.each_line do |line|
|
22
|
+
if line.start_with?('+')
|
23
|
+
stdout.print colorize(line, :green)
|
24
|
+
elsif line.start_with?('-')
|
25
|
+
stdout.print colorize(line, :red)
|
26
|
+
else
|
27
|
+
stdout.print line
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def different?
|
33
|
+
diff != ''
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def diff
|
39
|
+
@diff ||= Diffy::Diff.new(@before, @after, context: @context).to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
extend Forwardable
|
43
|
+
def_delegators :StackMaster, :colorize, :stdout
|
44
|
+
end
|
45
|
+
end
|
@@ -10,13 +10,13 @@ module StackMaster
|
|
10
10
|
|
11
11
|
def proposed_template
|
12
12
|
return @proposed_stack.template_body unless @proposed_stack.template_format == :json
|
13
|
-
JSON.pretty_generate(JSON.parse(@proposed_stack.template_body))
|
13
|
+
JSON.pretty_generate(JSON.parse(@proposed_stack.template_body)) + "\n"
|
14
14
|
end
|
15
15
|
|
16
16
|
def current_template
|
17
17
|
return '' unless @current_stack
|
18
18
|
return @current_stack.template_body unless @current_stack.template_format == :json
|
19
|
-
JSON.pretty_generate(TemplateUtils.template_hash(@current_stack.template_body))
|
19
|
+
JSON.pretty_generate(TemplateUtils.template_hash(@current_stack.template_body)) + "\n"
|
20
20
|
end
|
21
21
|
|
22
22
|
def current_parameters
|
@@ -39,24 +39,30 @@ module StackMaster
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def body_different?
|
42
|
-
body_diff
|
42
|
+
body_diff.different?
|
43
43
|
end
|
44
44
|
|
45
45
|
def body_diff
|
46
|
-
@body_diff ||=
|
46
|
+
@body_diff ||= Diff.new(name: 'Stack',
|
47
|
+
before: current_template,
|
48
|
+
after: proposed_template,
|
49
|
+
context: 7)
|
47
50
|
end
|
48
51
|
|
49
52
|
def params_different?
|
50
|
-
|
53
|
+
parameters_diff.different?
|
51
54
|
end
|
52
55
|
|
53
|
-
def
|
54
|
-
@param_diff ||=
|
56
|
+
def parameters_diff
|
57
|
+
@param_diff ||= Diff.new(name: 'Parameters',
|
58
|
+
before: current_parameters,
|
59
|
+
after: proposed_parameters)
|
55
60
|
end
|
56
61
|
|
57
62
|
def output_diff
|
58
|
-
|
59
|
-
|
63
|
+
body_diff.display
|
64
|
+
parameters_diff.display
|
65
|
+
|
60
66
|
unless noecho_keys.empty?
|
61
67
|
StackMaster.stdout.puts " * can not tell if NoEcho parameters are different."
|
62
68
|
end
|
@@ -83,38 +89,8 @@ module StackMaster
|
|
83
89
|
|
84
90
|
private
|
85
91
|
|
86
|
-
def display_diff(thing, diff)
|
87
|
-
StackMaster.stdout.print "#{thing} diff: "
|
88
|
-
if diff == ''
|
89
|
-
StackMaster.stdout.puts "No changes"
|
90
|
-
else
|
91
|
-
StackMaster.stdout.puts
|
92
|
-
diff.each_line do |line|
|
93
|
-
if line.start_with?('+')
|
94
|
-
StackMaster.stdout.print colorize(line, :green)
|
95
|
-
elsif line.start_with?('-')
|
96
|
-
StackMaster.stdout.print colorize(line, :red)
|
97
|
-
else
|
98
|
-
StackMaster.stdout.print line
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
92
|
def sort_params(hash)
|
105
93
|
hash.sort.to_h
|
106
94
|
end
|
107
|
-
|
108
|
-
def colorize(text, color)
|
109
|
-
if colorize?
|
110
|
-
Rainbow(text).color(color)
|
111
|
-
else
|
112
|
-
text
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def colorize?
|
117
|
-
ENV.fetch('COLORIZE') { 'true' } == 'true'
|
118
|
-
end
|
119
95
|
end
|
120
96
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StackMaster::TemplateCompilers
|
4
|
+
class YamlErb
|
5
|
+
def self.require_dependencies
|
6
|
+
require 'erubis'
|
7
|
+
require 'yaml'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.compile(template_dir, template, compile_time_parameters, _compiler_options = {})
|
11
|
+
template_file_path = File.join(template_dir, template)
|
12
|
+
template = Erubis::Eruby.new(File.read(template_file_path))
|
13
|
+
template.filename = template_file_path
|
14
|
+
|
15
|
+
template.result(params: compile_time_parameters)
|
16
|
+
end
|
17
|
+
|
18
|
+
StackMaster::TemplateCompiler.register(:yaml_erb, self)
|
19
|
+
end
|
20
|
+
end
|
data/lib/stack_master/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.12.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: 2020-
|
12
|
+
date: 2020-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -437,6 +437,20 @@ dependencies:
|
|
437
437
|
- - ">="
|
438
438
|
- !ruby/object:Gem::Version
|
439
439
|
version: '0'
|
440
|
+
- !ruby/object:Gem::Dependency
|
441
|
+
name: cfn-nag
|
442
|
+
requirement: !ruby/object:Gem::Requirement
|
443
|
+
requirements:
|
444
|
+
- - "~>"
|
445
|
+
- !ruby/object:Gem::Version
|
446
|
+
version: 0.6.7
|
447
|
+
type: :runtime
|
448
|
+
prerelease: false
|
449
|
+
version_requirements: !ruby/object:Gem::Requirement
|
450
|
+
requirements:
|
451
|
+
- - "~>"
|
452
|
+
- !ruby/object:Gem::Version
|
453
|
+
version: 0.6.7
|
440
454
|
description: ''
|
441
455
|
email:
|
442
456
|
- steve@hodgkiss.me
|
@@ -459,10 +473,12 @@ files:
|
|
459
473
|
- lib/stack_master/commands/compile.rb
|
460
474
|
- lib/stack_master/commands/delete.rb
|
461
475
|
- lib/stack_master/commands/diff.rb
|
476
|
+
- lib/stack_master/commands/drift.rb
|
462
477
|
- lib/stack_master/commands/events.rb
|
463
478
|
- lib/stack_master/commands/init.rb
|
464
479
|
- lib/stack_master/commands/lint.rb
|
465
480
|
- lib/stack_master/commands/list_stacks.rb
|
481
|
+
- lib/stack_master/commands/nag.rb
|
466
482
|
- lib/stack_master/commands/outputs.rb
|
467
483
|
- lib/stack_master/commands/resources.rb
|
468
484
|
- lib/stack_master/commands/status.rb
|
@@ -471,6 +487,7 @@ files:
|
|
471
487
|
- lib/stack_master/commands/validate.rb
|
472
488
|
- lib/stack_master/config.rb
|
473
489
|
- lib/stack_master/ctrl_c.rb
|
490
|
+
- lib/stack_master/diff.rb
|
474
491
|
- lib/stack_master/identity.rb
|
475
492
|
- lib/stack_master/paged_response_accumulator.rb
|
476
493
|
- lib/stack_master/parameter_loader.rb
|
@@ -522,6 +539,7 @@ files:
|
|
522
539
|
- lib/stack_master/template_compilers/json.rb
|
523
540
|
- lib/stack_master/template_compilers/sparkle_formation.rb
|
524
541
|
- lib/stack_master/template_compilers/yaml.rb
|
542
|
+
- lib/stack_master/template_compilers/yaml_erb.rb
|
525
543
|
- lib/stack_master/template_utils.rb
|
526
544
|
- lib/stack_master/test_driver/cloud_formation.rb
|
527
545
|
- lib/stack_master/test_driver/s3.rb
|
@@ -539,8 +557,8 @@ licenses:
|
|
539
557
|
metadata:
|
540
558
|
bug_tracker_uri: https://github.com/envato/stack_master/issues
|
541
559
|
changelog_uri: https://github.com/envato/stack_master/blob/master/CHANGELOG.md
|
542
|
-
documentation_uri: https://www.rubydoc.info/gems/stack_master/2.
|
543
|
-
source_code_uri: https://github.com/envato/stack_master/tree/v2.
|
560
|
+
documentation_uri: https://www.rubydoc.info/gems/stack_master/2.12.0
|
561
|
+
source_code_uri: https://github.com/envato/stack_master/tree/v2.12.0
|
544
562
|
post_install_message:
|
545
563
|
rdoc_options: []
|
546
564
|
require_paths:
|
@@ -556,7 +574,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
556
574
|
- !ruby/object:Gem::Version
|
557
575
|
version: '0'
|
558
576
|
requirements: []
|
559
|
-
rubygems_version: 3.
|
577
|
+
rubygems_version: 3.1.2
|
560
578
|
signing_key:
|
561
579
|
specification_version: 4
|
562
580
|
summary: StackMaster is a sure-footed way of creating, updating and keeping track
|