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
@@ -6,16 +6,17 @@ module StackMaster
6
6
  include Command
7
7
  include Commander::UI
8
8
 
9
- DETECTION_COMPLETE_STATES = [
10
- 'DETECTION_COMPLETE',
11
- 'DETECTION_FAILED'
9
+ DETECTION_COMPLETE_STATES = %w[
10
+ DETECTION_COMPLETE
11
+ DETECTION_FAILED
12
12
  ]
13
13
 
14
14
  def perform
15
15
  detect_stack_drift_result = cf.detect_stack_drift(stack_name: stack_name)
16
16
  drift_results = wait_for_drift_results(detect_stack_drift_result.stack_drift_detection_id)
17
17
 
18
- puts colorize("Drift Status: #{drift_results.stack_drift_status}", stack_drift_status_color(drift_results.stack_drift_status))
18
+ puts colorize("Drift Status: #{drift_results.stack_drift_status}",
19
+ stack_drift_status_color(drift_results.stack_drift_status))
19
20
  return if drift_results.stack_drift_status == 'IN_SYNC'
20
21
 
21
22
  failed
@@ -40,9 +41,7 @@ module StackMaster
40
41
  drift.physical_resource_id].join(' '), color)
41
42
  return unless drift.stack_resource_drift_status == 'MODIFIED'
42
43
 
43
- unless drift.property_differences.empty?
44
- puts colorize(' Property differences:', color)
45
- end
44
+ puts colorize(' Property differences:', color) unless drift.property_differences.empty?
46
45
  drift.property_differences.each do |property_difference|
47
46
  puts colorize(" - #{property_difference.difference_type} #{property_difference.property_path}", color)
48
47
  end
@@ -51,8 +50,10 @@ module StackMaster
51
50
  end
52
51
 
53
52
  def display_resource_drift(drift)
54
- diff = ::StackMaster::Diff.new(before: prettify_json(drift.expected_properties),
55
- after: prettify_json(drift.actual_properties))
53
+ diff = ::StackMaster::Diff.new(
54
+ before: prettify_json(drift.expected_properties),
55
+ after: prettify_json(drift.actual_properties)
56
+ )
56
57
  diff.display_colorized_diff
57
58
  end
58
59
 
@@ -95,9 +96,7 @@ module StackMaster
95
96
  break if DETECTION_COMPLETE_STATES.include?(resp.detection_status)
96
97
 
97
98
  elapsed_time = Time.now - start_time
98
- if elapsed_time > @options.timeout
99
- raise "Timeout waiting for stack drift detection"
100
- end
99
+ raise 'Timeout waiting for stack drift detection' if elapsed_time > @options.timeout
101
100
 
102
101
  sleep SLEEP_SECONDS
103
102
  end
@@ -9,9 +9,9 @@ module StackMaster
9
9
  filter_events(events).each do |event|
10
10
  StackEvents::Presenter.print_event(StackMaster.stdout, event)
11
11
  end
12
- if @options.tail
13
- StackEvents::Streamer.stream(@stack_definition.stack_name, @stack_definition.region, io: StackMaster.stdout)
14
- end
12
+ return unless @options.tail
13
+
14
+ StackEvents::Streamer.stream(@stack_definition.stack_name, @stack_definition.region, io: StackMaster.stdout)
15
15
  end
16
16
 
17
17
  private
@@ -22,9 +22,7 @@ module StackMaster
22
22
  else
23
23
  n = @options.number || 25
24
24
  from = events.count - n
25
- if from < 0
26
- from = 0
27
- end
25
+ from = 0 if from < 0
28
26
  events[from..-1]
29
27
  end
30
28
  end
@@ -1,4 +1,4 @@
1
- require "erb"
1
+ require 'erb'
2
2
 
3
3
  module StackMaster
4
4
  module Commands
@@ -12,27 +12,28 @@ module StackMaster
12
12
  end
13
13
 
14
14
  def perform
15
- if check_files
16
- create_stack_master_yml
17
- create_stack_json_yml
18
- create_parameters_yml
19
- end
15
+ return unless check_files
16
+
17
+ create_stack_master_yml
18
+ create_stack_json_yml
19
+ create_parameters_yml
20
20
  end
21
21
 
22
22
  private
23
23
 
24
24
  def check_files
25
- @stack_master_filename = "stack_master.yml"
25
+ @stack_master_filename = 'stack_master.yml'
26
26
  @stack_json_filename = "templates/#{@stack_name}.json"
27
- @parameters_filename = File.join("parameters", "#{@stack_name}.yml")
28
- @region_parameters_filename = File.join("parameters", @region, "#{@stack_name}.yml")
29
-
30
- if !@options.overwrite
31
- [@stack_master_filename, @stack_json_filename, @parameters_filename, @region_parameters_filename].each do |filename|
32
- if File.exist?(filename)
33
- StackMaster.stderr.puts("Aborting: #{filename} already exists. Use --overwrite to force overwriting file.")
34
- return false
35
- end
27
+ @parameters_filename = File.join('parameters', "#{@stack_name}.yml")
28
+ @region_parameters_filename = File.join('parameters', @region, "#{@stack_name}.yml")
29
+
30
+ unless @options.overwrite
31
+ [@stack_master_filename, @stack_json_filename, @parameters_filename,
32
+ @region_parameters_filename].each do |filename|
33
+ next unless File.exist?(filename)
34
+
35
+ StackMaster.stderr.puts("Aborting: #{filename} already exists. Use --overwrite to force overwriting file.")
36
+ return false
36
37
  end
37
38
  end
38
39
  true
@@ -49,7 +50,7 @@ module StackMaster
49
50
  end
50
51
 
51
52
  def stack_json_template
52
- File.join(StackMaster.base_dir, "stacktemplates", "stack.json.erb")
53
+ File.join(StackMaster.base_dir, 'stacktemplates', 'stack.json.erb')
53
54
  end
54
55
 
55
56
  def create_stack_master_yml
@@ -62,7 +63,7 @@ module StackMaster
62
63
  end
63
64
 
64
65
  def stack_master_template
65
- File.join(StackMaster.base_dir, "stacktemplates", "stack_master.yml.erb")
66
+ File.join(StackMaster.base_dir, 'stacktemplates', 'stack_master.yml.erb')
66
67
  end
67
68
 
68
69
  def create_parameters_yml
@@ -82,11 +83,11 @@ module StackMaster
82
83
  end
83
84
 
84
85
  def parameter_stack_name_template
85
- File.join(StackMaster.base_dir, "stacktemplates", "parameter_stack_name.yml")
86
+ File.join(StackMaster.base_dir, 'stacktemplates', 'parameter_stack_name.yml')
86
87
  end
87
88
 
88
89
  def parameter_region_template
89
- File.join(StackMaster.base_dir, "stacktemplates", "parameter_region.yml")
90
+ File.join(StackMaster.base_dir, 'stacktemplates', 'parameter_region.yml')
90
91
  end
91
92
 
92
93
  def render(renderer)
@@ -19,7 +19,7 @@ module StackMaster
19
19
  f.write(proposed_stack.template_body)
20
20
  f.flush
21
21
  system('cfn-lint', f.path)
22
- puts "cfn-lint run complete"
22
+ puts 'cfn-lint run complete'
23
23
  end
24
24
  end
25
25
 
@@ -8,7 +8,7 @@ module StackMaster
8
8
  include StackMaster::Commands::TerminalHelper
9
9
 
10
10
  def perform
11
- tp.set :max_width, self.window_size
11
+ tp.set :max_width, window_size
12
12
  tp @config.stacks, :region, :stack_name
13
13
  end
14
14
  end
@@ -24,7 +24,6 @@ module StackMaster
24
24
  def proposed_stack
25
25
  @proposed_stack ||= Stack.generate(stack_definition, @config)
26
26
  end
27
-
28
27
  end
29
28
  end
30
29
  end
@@ -9,7 +9,7 @@ module StackMaster
9
9
 
10
10
  def perform
11
11
  if stack
12
- tp.set :max_width, self.window_size
12
+ tp.set :max_width, window_size
13
13
  tp stack.outputs, :output_key, :output_value, :description
14
14
  else
15
15
  failed("Stack doesn't exist")
@@ -8,7 +8,15 @@ module StackMaster
8
8
 
9
9
  def perform
10
10
  if stack_resources
11
- tp stack_resources, :logical_resource_id, :resource_type, :timestamp, :resource_status, :resource_status_reason, :description
11
+ tp(
12
+ stack_resources,
13
+ :logical_resource_id,
14
+ :resource_type,
15
+ :timestamp,
16
+ :resource_status,
17
+ :resource_status_reason,
18
+ :description
19
+ )
12
20
  else
13
21
  failed("Stack doesn't exist")
14
22
  end
@@ -21,11 +21,11 @@ module StackMaster
21
21
  {
22
22
  region: stack_definition.region,
23
23
  stack_name: stack_definition.stack_name,
24
- stack_status: running_in_allowed_account?(allowed_accounts) ? stack_status.status : "Disallowed account",
25
- different: running_in_allowed_account?(allowed_accounts) ? stack_status.changed_message : "N/A",
24
+ stack_status: running_in_allowed_account?(allowed_accounts) ? stack_status.status : 'Disallowed account',
25
+ different: running_in_allowed_account?(allowed_accounts) ? stack_status.changed_message : 'N/A'
26
26
  }
27
27
  end
28
- tp.set :max_width, self.window_size
28
+ tp.set :max_width, window_size
29
29
  tp.set :io, StackMaster.stdout
30
30
  tp status
31
31
  StackMaster.stdout.puts " * No echo parameters can't be diffed"
@@ -34,7 +34,7 @@ module StackMaster
34
34
  private
35
35
 
36
36
  def progress
37
- @progress ||= ProgressBar.create(title: "Fetching stack information",
37
+ @progress ||= ProgressBar.create(title: 'Fetching stack information',
38
38
  total: @config.stacks.size,
39
39
  output: StackMaster.stdout)
40
40
  end
@@ -4,9 +4,9 @@ module StackMaster
4
4
  module Commands
5
5
  module TerminalHelper
6
6
  def window_size
7
- size = ENV.fetch("COLUMNS") { OS.windows? ? windows_window_size : unix_window_size }
7
+ size = ENV.fetch('COLUMNS') { OS.windows? ? windows_window_size : unix_window_size }
8
8
 
9
- if size.nil? || size == ""
9
+ if size.nil? || size == ''
10
10
  80
11
11
  else
12
12
  size.to_i
@@ -18,7 +18,7 @@ module StackMaster
18
18
  end
19
19
 
20
20
  def windows_window_size
21
- columns_regex = %r{^\s+Columns:\s+([0-9]+)$}
21
+ columns_regex = /^\s+Columns:\s+([0-9]+)$/
22
22
  output = `mode con`
23
23
  columns_line = output.split("\n").select { |line| line.match(columns_regex) }.last
24
24
  columns_line.match(columns_regex)[1]
@@ -8,20 +8,23 @@ module StackMaster
8
8
  used_templates = []
9
9
  used_parameter_files = []
10
10
 
11
- templates = Set.new(find_templates())
12
- parameter_files = Set.new(find_parameter_files())
11
+ templates = Set.new(find_templates)
12
+ parameter_files = Set.new(find_parameter_files)
13
13
 
14
14
  status = @config.stacks.each do |stack_definition|
15
15
  parameter_files.subtract(stack_definition.parameter_files_from_globs)
16
16
  template = File.absolute_path(stack_definition.template_file_path)
17
17
 
18
- if template
19
- templates.delete(template)
18
+ next unless template
20
19
 
21
- if !File.exist?(template)
22
- StackMaster.stdout.puts "Stack \"#{stack_definition.stack_name}\" in \"#{stack_definition.region}\" missing template \"#{rel_path(template)}\""
23
- end
24
- end
20
+ templates.delete(template)
21
+
22
+ next if File.exist?(template)
23
+
24
+ StackMaster.stdout.puts(
25
+ "Stack \"#{stack_definition.stack_name}\" in \"#{stack_definition.region}\" " \
26
+ "missing template \"#{rel_path(template)}\""
27
+ )
25
28
  end
26
29
 
27
30
  templates.each do |path|
@@ -43,21 +46,19 @@ module StackMaster
43
46
  # template directories) this won't find the right directory.
44
47
  template_dir = @config.template_dir || File.join(@config.base_dir, 'templates')
45
48
 
46
- templates = Dir.glob(File.absolute_path(File.join(template_dir, '**', "*.{rb,yaml,yml,json}")))
49
+ templates = Dir.glob(File.absolute_path(File.join(template_dir, '**', '*.{rb,yaml,yml,json}')))
47
50
  dynamics_dir = File.join(template_dir, 'dynamics')
48
51
 
49
52
  # Exclude sparkleformation dynamics
50
53
  # TODO: Should this filter out anything with 'dynamics', not just the first
51
54
  # subdirectory?
52
- templates = templates.select do |path|
55
+ templates.select do |path|
53
56
  !path.start_with?(dynamics_dir)
54
57
  end
55
-
56
- templates
57
58
  end
58
59
 
59
60
  def find_parameter_files
60
- Dir.glob(File.absolute_path(File.join(@config.base_dir, "parameters", "*.{yml,yaml}")))
61
+ Dir.glob(File.absolute_path(File.join(@config.base_dir, 'parameters', '*.{yml,yaml}')))
61
62
  end
62
63
  end
63
64
  end
@@ -14,23 +14,25 @@ module StackMaster
14
14
  raise ConfigParseError, "Unable to parse #{resolved_config_file}: #{error}"
15
15
  end
16
16
 
17
- attr_accessor :stacks,
18
- :base_dir,
19
- :template_dir,
20
- :parameters_dir,
21
- :stack_defaults,
22
- :region_defaults,
23
- :region_aliases,
24
- :template_compilers,
17
+ attr_accessor(
18
+ :stacks,
19
+ :base_dir,
20
+ :template_dir,
21
+ :parameters_dir,
22
+ :stack_defaults,
23
+ :region_defaults,
24
+ :region_aliases,
25
+ :template_compilers
26
+ )
25
27
 
26
28
  def self.search_up_and_chdir(config_file)
27
- return config_file unless File.dirname(config_file) == "."
29
+ return config_file unless File.dirname(config_file) == '.'
28
30
 
29
31
  dir = Dir.pwd
30
- parent_dir = File.expand_path("..", Dir.pwd)
32
+ parent_dir = File.expand_path('..', Dir.pwd)
31
33
  while parent_dir != dir && !File.exist?(File.join(dir, config_file))
32
34
  dir = parent_dir
33
- parent_dir = File.expand_path("..", dir)
35
+ parent_dir = File.expand_path('..', dir)
34
36
  end
35
37
 
36
38
  File.join(dir, config_file)
@@ -43,15 +45,15 @@ module StackMaster
43
45
  @parameters_dir = config.fetch('parameters_dir', nil)
44
46
  @stack_defaults = config.fetch('stack_defaults', {})
45
47
  @region_aliases = Utils.underscore_keys_to_hyphen(config.fetch('region_aliases', {}))
46
- @region_to_aliases = @region_aliases.inject({}) do |hash, (key, value)|
48
+ @region_to_aliases = @region_aliases.each_with_object({}) do |(key, value), hash|
47
49
  hash[value] ||= []
48
50
  hash[value] << key
49
- hash
50
51
  end
51
52
  @region_defaults = normalise_region_defaults(config.fetch('region_defaults', {}))
52
53
  @stacks = []
53
54
 
54
55
  raise ConfigParseError.new("Stack defaults can't be undefined") if @stack_defaults.nil?
56
+
55
57
  load_template_compilers(config)
56
58
  load_config
57
59
  end
@@ -72,6 +74,7 @@ module StackMaster
72
74
  end
73
75
 
74
76
  private
77
+
75
78
  def load_template_compilers(config)
76
79
  @template_compilers = {}
77
80
  populate_template_compilers(config.fetch('template_compilers', {}))
@@ -82,7 +85,7 @@ module StackMaster
82
85
  @template_compilers = default_template_compilers.merge(@template_compilers)
83
86
  end
84
87
 
85
- def populate_template_compilers user_defined_compilers
88
+ def populate_template_compilers(user_defined_compilers)
86
89
  user_defined_compilers.each do |key, val|
87
90
  @template_compilers[key.to_sym] = val.to_sym
88
91
  end
@@ -92,9 +95,9 @@ module StackMaster
92
95
  {
93
96
  rb: :sparkle_formation,
94
97
  json: :json,
95
- yml: :yaml,
98
+ yml: :yaml,
96
99
  yaml: :yaml,
97
- erb: :yaml_erb,
100
+ erb: :yaml_erb
98
101
  }
99
102
  end
100
103
 
@@ -104,9 +107,8 @@ module StackMaster
104
107
  end
105
108
 
106
109
  def resolve_region_aliases(stacks)
107
- stacks.inject({}) do |hash, (region, attributes)|
110
+ stacks.each_with_object({}) do |(region, attributes), hash|
108
111
  hash[unalias_region(region)] = attributes
109
- hash
110
112
  end
111
113
  end
112
114
 
@@ -123,7 +125,8 @@ module StackMaster
123
125
  'base_dir' => @base_dir,
124
126
  'template_dir' => @template_dir,
125
127
  'parameters_dir' => @parameters_dir,
126
- 'additional_parameter_lookup_dirs' => @region_to_aliases[region])
128
+ 'additional_parameter_lookup_dirs' => @region_to_aliases[region]
129
+ )
127
130
  stack_attributes['allowed_accounts'] = attributes['allowed_accounts'] if attributes['allowed_accounts']
128
131
  @stacks << StackDefinition.new(stack_attributes)
129
132
  end
@@ -136,10 +139,9 @@ module StackMaster
136
139
  end
137
140
 
138
141
  def normalise_region_defaults(region_defaults)
139
- region_defaults.inject({}) do |normalised_aliases, (region_or_alias, value)|
142
+ region_defaults.each_with_object({}) do |(region_or_alias, value), normalised_aliases|
140
143
  region = unalias_region(region_or_alias)
141
144
  normalised_aliases[Utils.underscore_to_hyphen(region)] = value
142
- normalised_aliases
143
145
  end
144
146
  end
145
147
  end
@@ -1,6 +1,6 @@
1
1
  module StackMaster
2
2
  class Diff
3
- def initialize(name: nil, before:, after:, context: 10_000)
3
+ def initialize(before:, after:, name: nil, context: 10_000)
4
4
  @name = name
5
5
  @before = before
6
6
  @after = after
@@ -10,7 +10,7 @@ module StackMaster
10
10
  def display
11
11
  stdout.print "#{@name} diff: "
12
12
  if diff == ''
13
- stdout.puts "No changes"
13
+ stdout.puts 'No changes'
14
14
  else
15
15
  stdout.puts
16
16
  display_colorized_diff
@@ -21,7 +21,8 @@ module StackMaster
21
21
  def account_aliases
22
22
  @aliases ||= iam.list_account_aliases.account_aliases
23
23
  rescue Aws::IAM::Errors::AccessDenied
24
- raise MissingIamPermissionsError, 'Failed to retrieve account aliases. Missing required IAM permission: iam:ListAccountAliases'
24
+ raise MissingIamPermissionsError,
25
+ 'Failed to retrieve account aliases. Missing required IAM permission: iam:ListAccountAliases'
25
26
  end
26
27
 
27
28
  private
@@ -2,19 +2,17 @@ require 'active_support/core_ext/object/deep_dup'
2
2
 
3
3
  module StackMaster
4
4
  class ParameterLoader
5
-
6
5
  COMPILE_TIME_PARAMETERS_KEY = 'compile_time_parameters'
7
6
 
8
7
  def self.load(parameter_files: [], parameters: {})
9
8
  StackMaster.debug 'Searching for parameter files...'
10
9
  all_parameters = parameter_files.map { |file_name| load_parameters(file_name) } + [parameters]
11
- all_parameters.reduce({template_parameters: {}, compile_time_parameters: {}}) do |hash, parameters|
10
+ all_parameters.each_with_object({ template_parameters: {}, compile_time_parameters: {} }) do |parameters, hash|
12
11
  template_parameters = create_template_parameters(parameters)
13
12
  compile_time_parameters = create_compile_time_parameters(parameters)
14
13
 
15
14
  merge_and_camelize(hash[:template_parameters], template_parameters)
16
15
  merge_and_camelize(hash[:compile_time_parameters], compile_time_parameters)
17
- hash
18
16
  end
19
17
  end
20
18
 
@@ -32,7 +30,8 @@ module StackMaster
32
30
 
33
31
  def self.create_template_parameters(parameters)
34
32
  parameters.deep_dup.tap do |parameters_clone|
35
- parameters_clone.delete(COMPILE_TIME_PARAMETERS_KEY) || parameters_clone.delete(COMPILE_TIME_PARAMETERS_KEY.camelize)
33
+ parameters_clone.delete(COMPILE_TIME_PARAMETERS_KEY) ||
34
+ parameters_clone.delete(COMPILE_TIME_PARAMETERS_KEY.camelize)
36
35
  end
37
36
  end
38
37
 
@@ -43,6 +42,5 @@ module StackMaster
43
42
  def self.merge_and_camelize(hash, parameters)
44
43
  parameters.each { |key, value| hash[key.camelize] = value }
45
44
  end
46
-
47
45
  end
48
46
  end
@@ -15,13 +15,12 @@ module StackMaster
15
15
  end
16
16
 
17
17
  def resolve
18
- @parameters.reduce({}) do |parameters, (key, value)|
18
+ @parameters.each_with_object({}) do |(key, value), parameters|
19
19
  begin
20
20
  parameters[key] = resolve_parameter_value(key, value)
21
21
  rescue InvalidParameter
22
22
  raise InvalidParameter, "Unable to resolve parameter #{key.inspect} value causing error: #{$!.message}"
23
23
  end
24
- parameters
25
24
  end
26
25
  end
27
26
 
@@ -30,11 +29,9 @@ module StackMaster
30
29
  def require_parameter_resolver(file_name)
31
30
  require "stack_master/parameter_resolvers/#{file_name}"
32
31
  rescue LoadError
33
- if file_name == file_name.singularize
34
- raise ResolverNotFound.new(file_name)
35
- else
36
- require_parameter_resolver(file_name.singularize)
37
- end
32
+ raise ResolverNotFound.new(file_name) if file_name == file_name.singularize
33
+
34
+ require_parameter_resolver(file_name.singularize)
38
35
  end
39
36
 
40
37
  def load_parameter_resolver(class_name)
@@ -46,9 +43,12 @@ module StackMaster
46
43
  end
47
44
 
48
45
  def resolve_parameter_value(key, parameter_value)
49
- return parameter_value.to_s if Numeric === parameter_value || parameter_value == true || parameter_value == false
50
- return resolve_array_parameter_values(key, parameter_value).join(',') if Array === parameter_value
51
- return parameter_value unless Hash === parameter_value
46
+ if parameter_value.is_a?(Numeric) || parameter_value == true || parameter_value == false
47
+ return parameter_value.to_s
48
+ end
49
+ return resolve_array_parameter_values(key, parameter_value).join(',') if parameter_value.is_a?(Array)
50
+ return parameter_value unless parameter_value.is_a?(Hash)
51
+
52
52
  resolve_parameter_resolver_hash(key, parameter_value)
53
53
  rescue Aws::CloudFormation::Errors::ValidationError
54
54
  raise InvalidParameter, $!.message
@@ -72,14 +72,13 @@ module StackMaster
72
72
  end
73
73
  end
74
74
 
75
- def assume_role_if_present(account, role, key)
75
+ def assume_role_if_present(account, role, key, &block)
76
76
  return yield if account.nil? && role.nil?
77
77
  if account.nil? || role.nil?
78
78
  raise InvalidParameter, "Both 'account' and 'role' are required to assume role for parameter '#{key}'"
79
79
  end
80
- role_assumer.assume_role(account, role) do
81
- yield
82
- end
80
+
81
+ role_assumer.assume_role(account, role, &block)
83
82
  end
84
83
 
85
84
  def resolve_array_parameter_values(key, parameter_values)
@@ -105,15 +104,16 @@ module StackMaster
105
104
  begin
106
105
  @resolvers[class_name] = resolver_class_const(class_name).new(@config, @stack_definition)
107
106
  rescue NameError
108
- raise ResolverNotFound, "Could not find parameter resolver called #{class_name}, please double check your configuration"
107
+ raise ResolverNotFound,
108
+ "Could not find parameter resolver called #{class_name}, please double check your configuration"
109
109
  end
110
110
  end
111
111
  end
112
112
 
113
113
  def validate_parameter_value!(key, parameter_value)
114
- if parameter_value.keys.size != 1
115
- raise InvalidParameter, "#{key} hash contained more than one key: #{parameter_value.inspect}"
116
- end
114
+ return if parameter_value.keys.size == 1
115
+
116
+ raise InvalidParameter, "#{key} hash contained more than one key: #{parameter_value.inspect}"
117
117
  end
118
118
 
119
119
  def role_assumer
@@ -10,7 +10,10 @@ module StackMaster
10
10
 
11
11
  def resolve(domain_name)
12
12
  cert_arn = find_cert_arn_by_domain_name(domain_name)
13
- raise CertificateNotFound, "Could not find certificate #{domain_name} in #{@stack_definition.region}" unless cert_arn
13
+ unless cert_arn
14
+ raise CertificateNotFound, "Could not find certificate #{domain_name} in #{@stack_definition.region}"
15
+ end
16
+
14
17
  cert_arn
15
18
  end
16
19
 
@@ -6,16 +6,15 @@ module StackMaster
6
6
  end
7
7
 
8
8
  def build_filters_from_string(value, prefix = nil)
9
- filters = value.split(',').map do |name_with_value|
9
+ value.split(',').map do |name_with_value|
10
10
  name, value = name_with_value.strip.split('=')
11
11
  name = prefix ? "#{prefix}:#{name}" : name
12
12
  { name: name, values: [value] }
13
13
  end
14
- filters
15
14
  end
16
15
 
17
16
  def build_filters_from_hash(hash)
18
- hash.map { |key, value| {name: key, values: Array(value.to_s)}}
17
+ hash.map { |key, value| { name: key, values: Array(value.to_s) } }
19
18
  end
20
19
 
21
20
  def find_latest_ami(filters, owners = ['self'])
@@ -22,17 +22,20 @@ module StackMaster
22
22
  private
23
23
 
24
24
  def validate_ejson_file_specified
25
- if @stack_definition.ejson_file.nil?
26
- raise ArgumentError, "No ejson_file defined for stack definition #{@stack_definition.stack_name} in #{@stack_definition.region}"
27
- end
25
+ return unless @stack_definition.ejson_file.nil?
26
+
27
+ raise ArgumentError, 'No ejson_file defined for stack definition ' \
28
+ "#{@stack_definition.stack_name} in #{@stack_definition.region}"
28
29
  end
29
30
 
30
31
  def decrypt_ejson_file
31
32
  ejson_file_key = credentials_key
32
33
  @decrypted_ejson_files.fetch(ejson_file_key) do
33
- @decrypted_ejson_files[ejson_file_key] = EJSONWrapper.decrypt(ejson_file_path,
34
- use_kms: @stack_definition.ejson_file_kms,
35
- region: ejson_file_region)
34
+ @decrypted_ejson_files[ejson_file_key] = EJSONWrapper.decrypt(
35
+ ejson_file_path,
36
+ use_kms: @stack_definition.ejson_file_kms,
37
+ region: ejson_file_region
38
+ )
36
39
  end
37
40
  end
38
41