stack_master 2.17.0 → 2.18.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -6
  3. data/bin/stack_master +3 -5
  4. data/lib/stack_master/aws_driver/cloud_formation.rb +25 -23
  5. data/lib/stack_master/aws_driver/s3.rb +24 -17
  6. data/lib/stack_master/change_set.rb +11 -15
  7. data/lib/stack_master/cli.rb +53 -32
  8. data/lib/stack_master/command.rb +1 -5
  9. data/lib/stack_master/commands/apply.rb +39 -20
  10. data/lib/stack_master/commands/delete.rb +6 -7
  11. data/lib/stack_master/commands/drift.rb +11 -12
  12. data/lib/stack_master/commands/events.rb +4 -6
  13. data/lib/stack_master/commands/init.rb +21 -20
  14. data/lib/stack_master/commands/lint.rb +1 -1
  15. data/lib/stack_master/commands/list_stacks.rb +1 -1
  16. data/lib/stack_master/commands/nag.rb +0 -1
  17. data/lib/stack_master/commands/outputs.rb +1 -1
  18. data/lib/stack_master/commands/resources.rb +9 -1
  19. data/lib/stack_master/commands/status.rb +4 -4
  20. data/lib/stack_master/commands/terminal_helper.rb +3 -3
  21. data/lib/stack_master/commands/tidy.rb +14 -13
  22. data/lib/stack_master/config.rb +23 -21
  23. data/lib/stack_master/diff.rb +2 -2
  24. data/lib/stack_master/identity.rb +2 -1
  25. data/lib/stack_master/parameter_loader.rb +3 -5
  26. data/lib/stack_master/parameter_resolver.rb +18 -18
  27. data/lib/stack_master/parameter_resolvers/acm_certificate.rb +4 -1
  28. data/lib/stack_master/parameter_resolvers/ami_finder.rb +2 -3
  29. data/lib/stack_master/parameter_resolvers/ejson.rb +9 -6
  30. data/lib/stack_master/parameter_resolvers/env.rb +1 -2
  31. data/lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb +1 -1
  32. data/lib/stack_master/parameter_resolvers/latest_container.rb +9 -7
  33. data/lib/stack_master/parameter_resolvers/one_password.rb +11 -7
  34. data/lib/stack_master/parameter_resolvers/parameter_store.rb +1 -5
  35. data/lib/stack_master/parameter_resolvers/security_group.rb +1 -1
  36. data/lib/stack_master/parameter_resolvers/sso_group_id.rb +3 -2
  37. data/lib/stack_master/parameter_resolvers/stack_output.rb +7 -9
  38. data/lib/stack_master/parameter_validator.rb +2 -5
  39. data/lib/stack_master/prompter.rb +11 -10
  40. data/lib/stack_master/resolver_array.rb +2 -3
  41. data/lib/stack_master/role_assumer.rb +7 -5
  42. data/lib/stack_master/security_group_finder.rb +7 -5
  43. data/lib/stack_master/sns_topic_finder.rb +4 -3
  44. data/lib/stack_master/sparkle_formation/compile_time/allowed_pattern_validator.rb +2 -3
  45. data/lib/stack_master/sparkle_formation/compile_time/allowed_values_validator.rb +2 -3
  46. data/lib/stack_master/sparkle_formation/compile_time/definitions_validator.rb +6 -6
  47. data/lib/stack_master/sparkle_formation/compile_time/empty_validator.rb +0 -2
  48. data/lib/stack_master/sparkle_formation/compile_time/max_length_validator.rb +1 -2
  49. data/lib/stack_master/sparkle_formation/compile_time/max_size_validator.rb +1 -2
  50. data/lib/stack_master/sparkle_formation/compile_time/min_length_validator.rb +2 -3
  51. data/lib/stack_master/sparkle_formation/compile_time/min_size_validator.rb +2 -3
  52. data/lib/stack_master/sparkle_formation/compile_time/number_validator.rb +1 -2
  53. data/lib/stack_master/sparkle_formation/compile_time/parameters_validator.rb +0 -1
  54. data/lib/stack_master/sparkle_formation/compile_time/state_builder.rb +0 -2
  55. data/lib/stack_master/sparkle_formation/compile_time/string_validator.rb +2 -3
  56. data/lib/stack_master/sparkle_formation/compile_time/value_builder.rb +7 -9
  57. data/lib/stack_master/sparkle_formation/compile_time/value_validator.rb +3 -6
  58. data/lib/stack_master/sparkle_formation/compile_time/value_validator_factory.rb +11 -13
  59. data/lib/stack_master/sparkle_formation/template_file.rb +2 -4
  60. data/lib/stack_master/sso_group_id_finder.rb +15 -12
  61. data/lib/stack_master/stack.rb +51 -18
  62. data/lib/stack_master/stack_definition.rb +6 -5
  63. data/lib/stack_master/stack_differ.rb +36 -9
  64. data/lib/stack_master/stack_events/fetcher.rb +3 -1
  65. data/lib/stack_master/stack_events/presenter.rb +6 -1
  66. data/lib/stack_master/stack_events/streamer.rb +3 -1
  67. data/lib/stack_master/stack_status.rb +1 -0
  68. data/lib/stack_master/template_compilers/json.rb +1 -1
  69. data/lib/stack_master/template_compilers/sparkle_formation.rb +12 -9
  70. data/lib/stack_master/template_utils.rb +8 -4
  71. data/lib/stack_master/test_driver/cloud_formation.rb +34 -9
  72. data/lib/stack_master/test_driver/s3.rb +2 -3
  73. data/lib/stack_master/utils.rb +4 -6
  74. data/lib/stack_master/validator.rb +7 -6
  75. data/lib/stack_master/version.rb +1 -1
  76. data/lib/stack_master.rb +3 -1
  77. metadata +21 -10
  78. data/lib/stack_master/parameter_resolvers/accounts_by_tags.rb +0 -60
@@ -2,7 +2,6 @@ module StackMaster
2
2
  module SparkleFormation
3
3
  module CompileTime
4
4
  class ValueValidator
5
-
6
5
  attr_reader :is_valid, :error
7
6
 
8
7
  def validate
@@ -28,13 +27,11 @@ module StackMaster
28
27
  private
29
28
 
30
29
  def convert_to_array(definition, parameter)
31
- if definition[:multiple] && parameter.is_a?(String)
32
- return parameter.split(',').map(&:strip)
33
- end
30
+ return parameter.split(',').map(&:strip) if definition[:multiple] && parameter.is_a?(String)
31
+
34
32
  parameter.is_a?(Array) ? parameter : [parameter]
35
33
  end
36
-
37
34
  end
38
35
  end
39
36
  end
40
- end
37
+ end
@@ -12,17 +12,16 @@ module StackMaster
12
12
  module SparkleFormation
13
13
  module CompileTime
14
14
  class ValueValidatorFactory
15
-
16
15
  VALIDATORS_TYPES = [
17
- EmptyValidator,
18
- StringValidator,
19
- NumberValidator,
20
- AllowedValuesValidator,
21
- AllowedPatternValidator,
22
- MaxLengthValidator,
23
- MinLengthValidator,
24
- MaxSizeValidator,
25
- MinSizeValidator
16
+ EmptyValidator,
17
+ StringValidator,
18
+ NumberValidator,
19
+ AllowedValuesValidator,
20
+ AllowedPatternValidator,
21
+ MaxLengthValidator,
22
+ MinLengthValidator,
23
+ MaxSizeValidator,
24
+ MinSizeValidator
26
25
  ]
27
26
 
28
27
  def initialize(name, definition, parameter)
@@ -32,10 +31,9 @@ module StackMaster
32
31
  end
33
32
 
34
33
  def build
35
- VALIDATORS_TYPES.map { |validator| validator.new(@name, @definition, @parameter)}
34
+ VALIDATORS_TYPES.map { |validator| validator.new(@name, @definition, @parameter) }
36
35
  end
37
-
38
36
  end
39
37
  end
40
38
  end
41
- end
39
+ end
@@ -17,7 +17,6 @@ module StackMaster
17
17
  value
18
18
  end
19
19
  end
20
-
21
20
  end.new(vars, prefix)
22
21
  end
23
22
 
@@ -50,18 +49,17 @@ module StackMaster
50
49
  def _joined_file(file_name, vars = {})
51
50
  join!(Template.render('joined_file', file_name, vars))
52
51
  end
53
- alias_method :joined_file!, :_joined_file
52
+ alias joined_file! _joined_file
54
53
  end
55
54
 
56
55
  module UserDataFile
57
56
  def _user_data_file(file_name, vars = {})
58
57
  base64!(join!(Template.render('user_data', file_name, vars)))
59
58
  end
60
- alias_method :user_data_file!, :_user_data_file
59
+ alias user_data_file! _user_data_file
61
60
  end
62
61
  end
63
62
  end
64
63
 
65
64
  SparkleFormation::SparkleAttribute::Aws.send(:include, StackMaster::SparkleFormation::UserDataFile)
66
65
  SparkleFormation::SparkleAttribute::Aws.send(:include, StackMaster::SparkleFormation::JoinedFile)
67
-
@@ -6,28 +6,31 @@ module StackMaster
6
6
  output_regex = %r{(?:(?<region>[^:]+):)?(?<identity_store_id>[^:/]+)/(?<group_name>.+)}
7
7
 
8
8
  if !reference.is_a?(String) || !(match = output_regex.match(reference))
9
- raise ArgumentError, 'Sso group lookup parameter must be in the form of [region:]identity-store-id/group_name'
9
+ raise ArgumentError, 'Sso group lookup parameter must be in the form of [region:]identity-store-id/group_name'
10
10
  end
11
11
 
12
12
  region = match[:region] || StackMaster.cloud_formation_driver.region
13
13
  client = Aws::IdentityStore::Client.new({ region: region })
14
14
 
15
15
  begin
16
- response = client.get_group_id({
17
- identity_store_id: match[:identity_store_id],
18
- alternate_identifier: {
19
- unique_attribute: {
20
- attribute_path: 'displayName',
21
- attribute_value: match[:group_name],
22
- },
23
- },
24
- })
16
+ response = client.get_group_id(
17
+ {
18
+ identity_store_id: match[:identity_store_id],
19
+ alternate_identifier: {
20
+ unique_attribute: {
21
+ attribute_path: 'displayName',
22
+ attribute_value: match[:group_name]
23
+ }
24
+ }
25
+ }
26
+ )
25
27
  return response.group_id
26
28
  rescue Aws::IdentityStore::Errors::ServiceError => e
27
- puts "Error calling GetGroupId: #{e.message}"
29
+ puts "Error calling GetGroupId: #{e.message}"
28
30
  end
29
31
 
30
- raise SsoGroupNotFound, "No group with name #{match[:group_name]} found in identity store #{match[:identity_store_id]} in #{region}"
32
+ raise SsoGroupNotFound,
33
+ "No group with name #{match[:group_name]} found in identity store #{match[:identity_store_id]} in #{region}"
31
34
  end
32
35
  end
33
36
  end
@@ -17,10 +17,12 @@ module StackMaster
17
17
  include Utils::Initializable
18
18
 
19
19
  def template_default_parameters
20
- TemplateUtils.template_hash(template).fetch('Parameters', {}).inject({}) do |result, (parameter_name, description)|
21
- result[parameter_name] = description['Default']
22
- result
23
- end
20
+ TemplateUtils
21
+ .template_hash(template)
22
+ .fetch('Parameters', {})
23
+ .each_with_object({}) do |(parameter_name, description), result|
24
+ result[parameter_name] = description['Default']&.to_s
25
+ end
24
26
  end
25
27
 
26
28
  def parameters_with_defaults
@@ -31,19 +33,23 @@ module StackMaster
31
33
  cf = StackMaster.cloud_formation_driver
32
34
  cf_stack = cf.describe_stacks({ stack_name: stack_name }).stacks.first
33
35
  return unless cf_stack
34
- parameters = cf_stack.parameters.inject({}) do |params_hash, param_struct|
36
+
37
+ parameters = cf_stack.parameters.each_with_object({}) do |param_struct, params_hash|
35
38
  params_hash[param_struct.parameter_key] = param_struct.parameter_value
36
- params_hash
37
39
  end
38
40
  template_body ||= cf.get_template({ stack_name: stack_name, template_stage: 'Original' }).template_body
39
41
  template_format = TemplateUtils.identify_template_format(template_body)
40
42
  stack_policy_body ||= cf.get_stack_policy({ stack_name: stack_name }).stack_policy_body
41
43
  outputs = cf_stack.outputs
44
+ tags = cf_stack.tags&.each_with_object({}) do |tag_struct, tags_hash|
45
+ tags_hash[tag_struct.key] = tag_struct.value
46
+ end || {}
42
47
 
43
48
  new(region: region,
44
49
  stack_name: stack_name,
45
50
  stack_id: cf_stack.stack_id,
46
51
  parameters: parameters,
52
+ tags: tags,
47
53
  template_body: template_body,
48
54
  template_format: template_format,
49
55
  outputs: outputs,
@@ -56,14 +62,27 @@ module StackMaster
56
62
  end
57
63
 
58
64
  def self.generate(stack_definition, config)
59
- parameter_hash = ParameterLoader.load(parameter_files: stack_definition.all_parameter_files, parameters: stack_definition.parameters)
65
+ parameter_hash = ParameterLoader.load(
66
+ parameter_files: stack_definition.all_parameter_files,
67
+ parameters: stack_definition.parameters
68
+ )
60
69
  template_parameters = ParameterResolver.resolve(config, stack_definition, parameter_hash[:template_parameters])
61
- compile_time_parameters = ParameterResolver.resolve(config, stack_definition, parameter_hash[:compile_time_parameters])
62
- template_body = TemplateCompiler.compile(config, stack_definition.compiler, stack_definition.template_dir, stack_definition.template, compile_time_parameters, stack_definition.compiler_options)
70
+ compile_time_parameters = ParameterResolver.resolve(
71
+ config,
72
+ stack_definition,
73
+ parameter_hash[:compile_time_parameters]
74
+ )
75
+ template_body = TemplateCompiler.compile(
76
+ config,
77
+ stack_definition.compiler,
78
+ stack_definition.template_dir,
79
+ stack_definition.template,
80
+ compile_time_parameters,
81
+ stack_definition.compiler_options
82
+ )
63
83
  template_format = TemplateUtils.identify_template_format(template_body)
64
- stack_policy_body = if stack_definition.stack_policy_file_path
65
- File.read(stack_definition.stack_policy_file_path)
66
- end
84
+ stack_policy_body =
85
+ (File.read(stack_definition.stack_policy_file_path) if stack_definition.stack_policy_file_path)
67
86
  new(region: stack_definition.region,
68
87
  stack_name: stack_definition.stack_name,
69
88
  tags: stack_definition.tags,
@@ -76,13 +95,26 @@ module StackMaster
76
95
  end
77
96
 
78
97
  def self.generate_without_parameters(stack_definition, config)
79
- parameter_hash = ParameterLoader.load(parameter_files: stack_definition.all_parameter_files, parameters: stack_definition.parameters)
80
- compile_time_parameters = ParameterResolver.resolve(config, stack_definition, parameter_hash[:compile_time_parameters])
81
- template_body = TemplateCompiler.compile(config, stack_definition.compiler, stack_definition.template_dir, stack_definition.template, compile_time_parameters, stack_definition.compiler_options)
98
+ parameter_hash = ParameterLoader.load(
99
+ parameter_files: stack_definition.all_parameter_files,
100
+ parameters: stack_definition.parameters
101
+ )
102
+ compile_time_parameters = ParameterResolver.resolve(
103
+ config,
104
+ stack_definition,
105
+ parameter_hash[:compile_time_parameters]
106
+ )
107
+ template_body = TemplateCompiler.compile(
108
+ config,
109
+ stack_definition.compiler,
110
+ stack_definition.template_dir,
111
+ stack_definition.template,
112
+ compile_time_parameters,
113
+ stack_definition.compiler_options
114
+ )
82
115
  template_format = TemplateUtils.identify_template_format(template_body)
83
- stack_policy_body = if stack_definition.stack_policy_file_path
84
- File.read(stack_definition.stack_policy_file_path)
85
- end
116
+ stack_policy_body =
117
+ (File.read(stack_definition.stack_policy_file_path) if stack_definition.stack_policy_file_path)
86
118
  new(region: stack_definition.region,
87
119
  stack_name: stack_definition.stack_name,
88
120
  tags: stack_definition.tags,
@@ -96,6 +128,7 @@ module StackMaster
96
128
 
97
129
  def max_template_size(use_s3)
98
130
  return TemplateUtils::MAX_S3_TEMPLATE_SIZE if use_s3
131
+
99
132
  TemplateUtils::MAX_TEMPLATE_SIZE
100
133
  end
101
134
 
@@ -35,7 +35,7 @@ module StackMaster
35
35
  @compiler = nil
36
36
  super
37
37
  @additional_parameter_lookup_dirs ||= []
38
- @base_dir ||= ""
38
+ @base_dir ||= ''
39
39
  @template_dir ||= File.join(@base_dir, 'templates')
40
40
  @parameters_dir ||= File.join(@base_dir, 'parameters')
41
41
  @allowed_accounts = Array(@allowed_accounts)
@@ -44,7 +44,7 @@ module StackMaster
44
44
  end
45
45
 
46
46
  def ==(other)
47
- self.class === other &&
47
+ other.is_a?(self.class) &&
48
48
  @region == other.region &&
49
49
  @stack_name == other.stack_name &&
50
50
  @template == other.template &&
@@ -65,6 +65,7 @@ module StackMaster
65
65
 
66
66
  def template_file_path
67
67
  return unless template
68
+
68
69
  File.expand_path(template, template_dir)
69
70
  end
70
71
 
@@ -73,18 +74,18 @@ module StackMaster
73
74
  end
74
75
 
75
76
  def s3_files
76
- files.inject({}) do |hash, file|
77
+ files.each_with_object({}) do |file, hash|
77
78
  path = File.join(files_dir, file)
78
79
  hash[file] = {
79
80
  path: path,
80
81
  body: File.read(path)
81
82
  }
82
- hash
83
83
  end
84
84
  end
85
85
 
86
86
  def s3_template_file_name
87
87
  return template if ['.json', '.yaml', '.yml'].include?(File.extname(template))
88
+
88
89
  Utils.change_extension(template, 'json')
89
90
  end
90
91
 
@@ -101,7 +102,7 @@ module StackMaster
101
102
  end
102
103
 
103
104
  def parameter_file_globs
104
- [ default_parameter_glob, region_parameter_glob ] + additional_parameter_lookup_globs
105
+ [default_parameter_glob, region_parameter_glob] + additional_parameter_lookup_globs
105
106
  end
106
107
 
107
108
  def stack_policy_file_path
@@ -1,5 +1,5 @@
1
- require "diffy"
2
- require "hashdiff"
1
+ require 'diffy'
2
+ require 'hashdiff'
3
3
 
4
4
  module StackMaster
5
5
  class StackDiffer
@@ -10,12 +10,14 @@ module StackMaster
10
10
 
11
11
  def proposed_template
12
12
  return @proposed_stack.template_body unless @proposed_stack.template_format == :json
13
+
13
14
  JSON.pretty_generate(JSON.parse(@proposed_stack.template_body)) + "\n"
14
15
  end
15
16
 
16
17
  def current_template
17
18
  return '' unless @current_stack
18
19
  return @current_stack.template_body unless @current_stack.template_format == :json
20
+
19
21
  JSON.pretty_generate(TemplateUtils.template_hash(@current_stack.template_body)) + "\n"
20
22
  end
21
23
 
@@ -32,7 +34,7 @@ module StackMaster
32
34
  params = @proposed_stack.parameters_with_defaults
33
35
  if @current_stack
34
36
  noecho_keys.each do |key|
35
- params[key] = "****"
37
+ params[key] = '****'
36
38
  end
37
39
  end
38
40
  YAML.dump(sort_params(params))
@@ -59,20 +61,43 @@ module StackMaster
59
61
  after: proposed_parameters)
60
62
  end
61
63
 
64
+ def tags_different?
65
+ tags_diff.different?
66
+ end
67
+
68
+ def tags_diff
69
+ @tags_diff ||= Diff.new(name: 'Tags',
70
+ before: current_tags,
71
+ after: proposed_tags)
72
+ end
73
+
74
+ def current_tags
75
+ tags_hash = @current_stack&.tags
76
+ return '' if tags_hash.nil? || tags_hash.empty?
77
+
78
+ YAML.dump(sort_params(tags_hash))
79
+ end
80
+
81
+ def proposed_tags
82
+ tags_hash = @proposed_stack.tags
83
+ return '' if tags_hash.nil? || tags_hash.empty?
84
+
85
+ YAML.dump(sort_params(tags_hash))
86
+ end
87
+
62
88
  def output_diff
63
89
  body_diff.display
64
90
  parameters_diff.display
91
+ tags_diff.display
65
92
 
66
- unless noecho_keys.empty?
67
- StackMaster.stdout.puts " * can not tell if NoEcho parameters are different."
68
- end
69
- StackMaster.stdout.puts "No stack found" if @current_stack.nil?
93
+ StackMaster.stdout.puts ' * can not tell if NoEcho parameters are different.' unless noecho_keys.empty?
94
+ StackMaster.stdout.puts 'No stack found' if @current_stack.nil?
70
95
  end
71
96
 
72
97
  def noecho_keys
73
98
  if @current_stack
74
99
  @current_stack.parameters_with_defaults.select do |key, value|
75
- value == "****"
100
+ value == '****'
76
101
  end.keys
77
102
  else
78
103
  []
@@ -81,10 +106,12 @@ module StackMaster
81
106
 
82
107
  def single_param_update?(param_name)
83
108
  return false if param_name.blank? || @current_stack.blank? || body_different?
109
+
84
110
  differences = Hashdiff.diff(@current_stack.parameters_with_defaults, @proposed_stack.parameters_with_defaults)
85
111
  return false if differences.count != 1
112
+
86
113
  diff = differences[0]
87
- diff[0] == "~" && diff[1] == param_name
114
+ diff[0] == '~' && diff[1] == param_name
88
115
  end
89
116
 
90
117
  private
@@ -31,7 +31,9 @@ module StackMaster
31
31
  end
32
32
 
33
33
  def fetch_events
34
- PagedResponseAccumulator.call(cf, :describe_stack_events, { stack_name: @stack_name }, :stack_events).stack_events
34
+ PagedResponseAccumulator
35
+ .call(cf, :describe_stack_events, { stack_name: @stack_name }, :stack_events)
36
+ .stack_events
35
37
  end
36
38
  end
37
39
  end
@@ -10,7 +10,12 @@ module StackMaster
10
10
  end
11
11
 
12
12
  def print_event(event)
13
- @io.puts Rainbow("#{event.timestamp.localtime} #{event.logical_resource_id} #{event.resource_type} #{event.resource_status} #{event.resource_status_reason}").color(event_colour(event))
13
+ @io.puts(
14
+ Rainbow(
15
+ "#{event.timestamp.localtime} #{event.logical_resource_id} #{event.resource_type} " \
16
+ "#{event.resource_status} #{event.resource_status_reason}"
17
+ ).color(event_colour(event))
18
+ )
14
19
  end
15
20
 
16
21
  def event_colour(event)
@@ -7,7 +7,8 @@ module StackMaster
7
7
  new(stack_name, region, **args, &block).stream
8
8
  end
9
9
 
10
- def initialize(stack_name, region, from: Time.now, break_on_finish_state: true, sleep_between_fetches: 1, io: nil, &block)
10
+ def initialize(stack_name, region, from: Time.now, break_on_finish_state: true, sleep_between_fetches: 1,
11
+ io: nil, &block)
11
12
  @stack_name = stack_name
12
13
  @region = region
13
14
  @block = block
@@ -42,6 +43,7 @@ module StackMaster
42
43
  [].tap do |unseen_events|
43
44
  events.each do |event|
44
45
  next if @seen_events.include?(event.event_id)
46
+
45
47
  @seen_events << event.event_id
46
48
  unseen_events << event
47
49
  end
@@ -39,6 +39,7 @@ module StackMaster
39
39
 
40
40
  def stack
41
41
  return @stack if defined?(@stack)
42
+
42
43
  StackMaster.cloud_formation_driver.set_region(stack_definition.region)
43
44
  @stack = find_stack
44
45
  end
@@ -1,6 +1,6 @@
1
1
  module StackMaster::TemplateCompilers
2
2
  class Json
3
- MAX_TEMPLATE_SIZE = 51200
3
+ MAX_TEMPLATE_SIZE = 51_200
4
4
  private_constant :MAX_TEMPLATE_SIZE
5
5
 
6
6
  def self.require_dependencies
@@ -4,7 +4,6 @@ require 'stack_master/sparkle_formation/compile_time/state_builder'
4
4
 
5
5
  module StackMaster::TemplateCompilers
6
6
  class SparkleFormation
7
-
8
7
  CompileTime = StackMaster::SparkleFormation::CompileTime
9
8
 
10
9
  def self.require_dependencies
@@ -28,27 +27,31 @@ module StackMaster::TemplateCompilers
28
27
  private
29
28
 
30
29
  def self.compile_sparkle_template(template_dir, template, compiler_options)
31
- sparkle_path = if compiler_options['sparkle_path']
32
- File.expand_path(compiler_options['sparkle_path'])
33
- else
34
- template_dir
35
- end
30
+ sparkle_path =
31
+ if compiler_options['sparkle_path']
32
+ File.expand_path(compiler_options['sparkle_path'])
33
+ else
34
+ template_dir
35
+ end
36
36
 
37
37
  collection = ::SparkleFormation::SparkleCollection.new
38
38
  root_pack = ::SparkleFormation::Sparkle.new(
39
- :root => sparkle_path,
39
+ root: sparkle_path
40
40
  )
41
41
  collection.set_root(root_pack)
42
42
  if compiler_options['sparkle_packs']
43
43
  compiler_options['sparkle_packs'].each do |pack_name|
44
44
  require pack_name
45
- pack = ::SparkleFormation::SparklePack.new(:name => pack_name)
45
+ pack = ::SparkleFormation::SparklePack.new(name: pack_name)
46
46
  collection.add_sparkle(pack)
47
47
  end
48
48
  end
49
49
 
50
50
  if compiler_options['sparkle_pack_template']
51
- raise ArgumentError.new("Template #{template.inspect} not found in any sparkle pack") unless collection.templates['aws'].include? template
51
+ unless collection.templates['aws'].include? template
52
+ raise ArgumentError.new("Template #{template.inspect} not found in any sparkle pack")
53
+ end
54
+
52
55
  template_file_path = collection.templates['aws'][template].top['path']
53
56
  else
54
57
  template_file_path = File.join(template_dir, template)
@@ -1,7 +1,7 @@
1
1
  module StackMaster
2
2
  module TemplateUtils
3
- MAX_TEMPLATE_SIZE = 51200
4
- MAX_S3_TEMPLATE_SIZE = 460800
3
+ MAX_TEMPLATE_SIZE = 51_200
4
+ MAX_S3_TEMPLATE_SIZE = 460_800
5
5
  # Matches if the first non-whitespace character is a '{', handling cases
6
6
  # with leading whitespace and extra (whitespace-only) lines.
7
7
  JSON_IDENTIFICATION_PATTERN = Regexp.new('\A\s*{', Regexp::MULTILINE)
@@ -16,8 +16,9 @@ module StackMaster
16
16
  end
17
17
  end
18
18
 
19
- def template_hash(template_body=nil)
19
+ def template_hash(template_body = nil)
20
20
  return unless template_body
21
+
21
22
  template_format = identify_template_format(template_body)
22
23
  case template_format
23
24
  when :json
@@ -30,7 +31,10 @@ module StackMaster
30
31
  def maybe_compressed_template_body(template_body)
31
32
  # Do not compress the template if it's not JSON because parsing YAML as a hash ignores
32
33
  # CloudFormation-specific tags such as !Ref
33
- return template_body if template_body.size <= MAX_TEMPLATE_SIZE || identify_template_format(template_body) != :json
34
+ if template_body.size <= MAX_TEMPLATE_SIZE || identify_template_format(template_body) != :json
35
+ return template_body
36
+ end
37
+
34
38
  JSON.dump(template_hash(template_body))
35
39
  end
36
40
  end
@@ -28,6 +28,14 @@ module StackMaster
28
28
  parameter_value: hash[:parameter_value])
29
29
  end
30
30
  end
31
+
32
+ def tags
33
+ return [] if @tags.nil?
34
+
35
+ @tags.map do |hash|
36
+ OpenStruct.new(key: hash[:key], value: hash[:value])
37
+ end
38
+ end
31
39
  end
32
40
 
33
41
  class StackEvent
@@ -99,11 +107,27 @@ module StackMaster
99
107
  change_set_id = options.fetch(:change_set_name)
100
108
  change_set = @change_sets.fetch(change_set_id)
101
109
  change_details = [
102
- OpenStruct.new(evaluation: 'Static', change_source: 'ResourceReference', target: OpenStruct.new(attribute: 'Properties', requires_recreation: 'Always', name: 'blah'))
110
+ OpenStruct.new(
111
+ evaluation: 'Static',
112
+ change_source: 'ResourceReference',
113
+ target: OpenStruct.new(
114
+ attribute: 'Properties',
115
+ requires_recreation: 'Always',
116
+ name: 'blah'
117
+ )
118
+ )
103
119
  ]
104
- change = OpenStruct.new(action: 'Modify', replacement: 'True', scope: ['Properties'], details: change_details)
120
+ change = OpenStruct.new(
121
+ action: 'Modify',
122
+ replacement: 'True',
123
+ scope: ['Properties'],
124
+ details: change_details
125
+ )
105
126
  changes = [
106
- OpenStruct.new(type: 'AWS::Resource', resource_change: change)
127
+ OpenStruct.new(
128
+ type: 'AWS::Resource',
129
+ resource_change: change
130
+ )
107
131
  ]
108
132
  OpenStruct.new(change_set.merge(changes: changes, status: 'CREATE_COMPLETE'))
109
133
  end
@@ -121,15 +145,16 @@ module StackMaster
121
145
 
122
146
  def describe_stacks(options = {})
123
147
  stack_name = options[:stack_name]
124
- stacks = if stack_name
125
- if @stacks[stack_name]
148
+ stacks =
149
+ if stack_name
150
+ unless @stacks[stack_name]
151
+ raise Aws::CloudFormation::Errors::ValidationError.new('', 'Stack does not exist')
152
+ end
153
+
126
154
  [@stacks[stack_name]]
127
155
  else
128
- raise Aws::CloudFormation::Errors::ValidationError.new('', 'Stack does not exist')
156
+ @stacks.values
129
157
  end
130
- else
131
- @stacks.values
132
- end
133
158
  OpenStruct.new(stacks: stacks, next_token: nil)
134
159
  end
135
160
 
@@ -5,11 +5,10 @@ module StackMaster
5
5
  reset
6
6
  end
7
7
 
8
- def set_region(_)
9
- end
8
+ def set_region(_); end
10
9
 
11
10
  def reset
12
- @files = Hash.new { |hash, key| hash[key] = Hash.new }
11
+ @files = Hash.new { |hash, key| hash[key] = {} }
13
12
  end
14
13
 
15
14
  def upload_files(bucket: nil, prefix: nil, region: nil, files: {})
@@ -22,17 +22,16 @@ module StackMaster
22
22
  end
23
23
 
24
24
  def hash_to_aws_parameters(params)
25
- params.inject([]) do |params, (key, value)|
25
+ params.each_with_object([]) do |(key, value), params|
26
26
  params << { parameter_key: key, parameter_value: value }
27
- params
28
27
  end
29
28
  end
30
29
 
31
30
  def hash_to_aws_tags(tags)
32
31
  return [] if tags.nil?
33
- tags.inject([]) do |aws_tags, (key, value)|
32
+
33
+ tags.each_with_object([]) do |(key, value), aws_tags|
34
34
  aws_tags << { key: key, value: value }
35
- aws_tags
36
35
  end
37
36
  end
38
37
 
@@ -41,9 +40,8 @@ module StackMaster
41
40
  end
42
41
 
43
42
  def underscore_keys_to_hyphen(hash)
44
- hash.inject({}) do |hash, (key, value)|
43
+ hash.each_with_object({}) do |(key, value), hash|
45
44
  hash[underscore_to_hyphen(key)] = value
46
- hash
47
45
  end
48
46
  end
49
47
  end